TenantAtlas/specs/283-provider-capability-registry/research.md
Ahmed Darrazi 74e75c3edf
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m25s
feat: implement provider capability registry
2026-05-08 11:25:53 +02:00

5.3 KiB

Research: Provider Capability Registry

Decision 1: Provider capability state stays derived, not persisted

  • Decision: keep provider capability truth derived from existing provider connection state, required-permissions evidence, consent posture, verification posture, and provider-binding metadata.
  • Why: the repo already stores the underlying truth in ProviderConnection, required-permissions evidence, and blocked-operation context. A provider-capability table would duplicate that truth without a current-release lifecycle need.
  • Alternatives considered:
    • provider-capability snapshot table: rejected because it introduces new persistence, drift risk, and lifecycle questions with no current-release benefit
    • page-local capability arrays: rejected because they preserve current explanation drift across provider-connections, onboarding, required-permissions diagnostics, and blocked-operation messaging

Decision 2: Use one small code-first registry plus evaluator

  • Decision: prefer one small support namespace for capability definitions, status enum, and evaluation over a new config-first framework or broad provider abstraction.
  • Why: the slice needs one shared capability concept across multiple existing consumers. A small code-first registry is easier to bound and test than another config namespace plus generic loader machinery.
  • Alternatives considered:
    • expand config/intune_permissions.php into the sole capability source: rejected because the file already models provider-owned raw permission detail, not shared workflow capability truth
    • use only ProviderOperationRegistry: rejected because required-permissions diagnostics and onboarding also need capability truth outside operation-start paths

Decision 3: Capability keys stay limited to current repo workflows

  • Decision: limit the initial provider capability inventory to current workflows already present in repo truth: provider connection checks, inventory sync, compliance snapshot, restore execution, directory groups sync, and directory role-definition sync.
  • Canonical initial key set:
    • provider_connection_check -> provider.connection.check
    • inventory_read -> inventory.sync
    • configuration_read -> compliance.snapshot
    • restore_execute -> restore.execute
    • directory_groups_read -> directory.groups.sync
    • directory_role_definitions_read -> directory.role_definitions.sync
  • Why: the candidate backlog listed broader future-facing examples, but current-release truth only justifies keys for existing workflows and diagnostics.
  • Alternatives considered:
    • future-facing keys such as review_publish or evidence_snapshot_write: rejected because they describe adjacent or not-yet-real provider workflows
    • capability keys copied directly from raw Graph permission names: rejected because that would keep provider-owned requirement detail as platform-core vocabulary

Decision 4: Existing provider reason codes remain blocking reason truth

  • Decision: keep current provider reason codes as the blocking or degraded reason truth and add capability keys or capability status as the workflow-level explanation layer.
  • Why: the repo already routes blocked outcomes, contextual help, and support diagnostics through provider reason codes. Replacing that system entirely would widen scope and duplicate responsibility.
  • Alternatives considered:
    • a second capability-specific reason-code family: rejected because it adds another semantic layer without replacing the existing one
    • no reason-code reference on capability results: rejected because blocked and unknown states still need stable downstream machine-readable reasons

Decision 5: Required Permissions stays the canonical diagnostic deep dive

  • Decision: keep TenantRequiredPermissions as the canonical diagnostic page and make it capability-aware by grouping or summarizing raw provider requirements under capability headings.
  • Why: the page already exists, already supports filtering and deep inspection, and already has safe links from onboarding and product knowledge.
  • Alternatives considered:
    • a new provider-capability diagnostic page: rejected because it duplicates an existing deep-dive surface
    • inline raw permission evidence on provider-connections or onboarding only: rejected because it would spread the diagnostic matrix across summary-first surfaces

Decision 6: Support and contextual-help consumers must adopt the same vocabulary

  • Decision: shared help and support-diagnostic consumers should adopt the capability-first explanation if they already consume the same provider blocker.
  • Why: otherwise the same provider blocker would still read differently on the main surfaces versus diagnostic surfaces.
  • Alternatives considered:
    • leave help and support surfaces untouched: rejected because it preserves one of the biggest remaining explanation drifts in the repo

Implementation prerequisite

  • Spec 281 must already be present on the implementation branch because 283 assumes the provider-neutral target-scope and provider-identity baseline prepared there.

Explicit non-goals carried into design

  • No provider-capability table or ledger
  • No broader provider-neutral artifact taxonomy
  • No user RBAC changes
  • No provider-profile table
  • No routing cutover
  • No copy-neutralization or no-legacy enforcement pack work