# 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