# Feature Specification: Provider Connection, Provider Scope & Microsoft Profile Extraction **Feature Branch**: `281-provider-connection-scope` **Created**: 2026-05-07 **Status**: Ready **Input**: User description: "Work only in /Users/ahmeddarrazi/Documents/projects/wt-plattform on the already-created feature branch 281-provider-connection-scope. This is preparation-only work. Do not modify application/runtime code, tests, migrations, models, routes, views, or any non-spec artifacts. Task: fill /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/281-provider-connection-scope/spec.md as the implementation-ready spec for candidate `281 - Provider Connection, Provider Scope & Microsoft Profile Extraction` from docs/product/spec-candidates.md and docs/product/roadmap.md. Required repo truth and constraints: - Use the existing style and depth of specs/280-workspace-tenancy-environment-routing/spec.md. - Current branch/worktree safety is already checked and safe; stay on 281-provider-connection-scope. - 279 is completed historical context; 280 is an active/prepared adjacent spec but not the target. Do not edit any existing completed or adjacent spec packages. - The raw candidate text is partially stale: provider_connections already use managed_environment_id in repo truth, so do not claim 281 still needs the tenant_id -> managed_environment_id move. Document that as a candidate deviation. - Current repo seams show the real remaining 281 work lives around: - apps/platform/app/Models/ProviderConnection.php - apps/platform/config/provider_boundaries.php - apps/platform/app/Services/Providers/ProviderConnectionResolver.php - apps/platform/app/Services/Providers/ProviderIdentityResolver.php - apps/platform/app/Services/Providers/ProviderIdentityResolution.php - apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php - apps/platform/app/Services/Providers/ProviderOperationStartGate.php - apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php - apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php - apps/platform/app/Services/Providers/CredentialManager.php - Repo truth currently still hardcodes Microsoft-shaped identity/scope in platform-core seams via ProviderConnection::entra_tenant_id, tenantContext strings, and OperationRun context target_scope.entra_tenant_id. - There is already provider-boundary groundwork and target-scope normalization, but no dedicated provider-profile model/table yet. - Follow constitution rules: prefer bounded extraction over speculative multi-provider frameworks; no new persisted truth unless justified; provider-owned vs platform-core seams must be classified explicitly. - Keep the spec narrow and implementation-ready. Prefer the smallest honest slice that normalizes provider-neutral target-scope and identity contracts while confining Microsoft-specific profile semantics to provider-owned metadata/profile seams. - Preserve TenantPilot terminology where the repo still uses it, but make the platform-core/provider-boundary reasoning explicit. - Include the mandatory spec-template sections, candidate gate summary, completed-spec guardrail result, assumptions, risks, in-scope/non-goals, and deferred adjacent candidates. - Include explicit Candidate Selection Gate reasoning for why 281 is chosen now and why 282-287 are deferred. - Include the explicit agent-output contract details relevant at spec level: Livewire v4 compliance note, provider registration location bootstrap/providers.php, globally searchable resource note if any touched resource is mentioned, destructive action confirmation note if any UI mutation is referenced, asset strategy note, testing plan summary. - Make the final spec concrete enough that a later plan/tasks pass can generate research/data-model/quickstart/contracts without guesswork." ## Spec Candidate Check - **Problem**: Repo truth already moved `ProviderConnection` onto `managed_environment_id`, but shared platform-core seams still treat Microsoft tenant identity as the generic provider-scope truth. `ProviderIdentityResolver`, `ProviderIdentityResolution`, `PlatformProviderIdentityResolver`, `ProviderConnectionTargetScopeNormalizer`, `ProviderOperationStartGate`, and related operator summaries still lean on `entra_tenant_id`, `tenantContext`, and `target_scope.entra_tenant_id` as if they were neutral platform contracts. - **Today's failure**: Operators can reach provider connections and start provider-backed work, but the shared connection identity story still depends on Microsoft-shaped field names. Onboarding readiness, provider connection summaries, audit metadata, and `OperationRun` context can all describe the same connection differently, which makes the cutover pack look provider-neutral in naming while still being Microsoft-shaped in the seams that actually decide behavior. - **User-visible improvement**: Operators get one consistent provider-connection and target-scope story across provider connections, managed-environment detail summaries, onboarding readiness, and provider-operation follow-up. Microsoft consent, portal, and tenant-profile details remain available, but only inside clearly provider-owned profile/context disclosure instead of as the primary shared vocabulary. - **Smallest enterprise-capable version**: Reuse the current `ProviderConnection` record, `ProviderConnectionResource`, onboarding wizard, target-scope normalizer, identity resolution path, and provider-operation start gate; standardize provider-neutral target-scope and identity outputs across those seams; move Microsoft-specific profile semantics into provider-owned metadata/profile sections; and stop writing `target_scope.entra_tenant_id` as the shared run-context contract. No new table, registry, package engine, or multi-provider framework is introduced. - **Explicit non-goals**: No `tenant_id` -> `managed_environment_id` migration on `provider_connections`; no dedicated provider-profile table; no capability registry; no provider-neutral artifact taxonomy; no governance-artifact retargeting; no workspace-RBAC redesign; no broader copy/localization neutralization; no new provider implementation; no legacy fallback or backfill. - **Permanent complexity imported**: One refined provider-neutral target-scope and identity contract across existing seams, one provider-owned Microsoft profile disclosure pattern on existing surfaces, and focused feature/browser coverage. No new persisted truth, registry, or extension framework is added. - **Why now**: Spec `279` already completed the core managed-environment noun change, and Spec `280` prepares the workspace-first routing shell. The next verified blocker in the reserved cutover pack is the provider boundary itself: until `281` lands, later slices such as artifact retargeting and provider-neutral taxonomy would still inherit Microsoft-shaped shared connection and run context. - **Why not local**: A label-only or page-local fix would leave the deciding seams untouched. `ProviderConnectionResolver`, `ProviderIdentityResolver`, `ProviderIdentityResolution`, `PlatformProviderIdentityResolver`, `ProviderOperationStartGate`, and audit/run context are the real control points; if they stay Microsoft-shaped, the platform core remains Microsoft-shaped no matter how neutral the page copy becomes. - **Approval class**: Core Enterprise - **Red flags triggered**: Shared provider/platform boundary, provider-operation execution context, and temptation to introduce new persistence or a speculative provider framework. Defense: this slice explicitly rejects a new table, registry, or capability framework and instead reuses the existing target-scope, identity, resource, and onboarding seams as the narrowest current-release extraction path. - **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 10/12** - **Decision**: approve ## Spec Scope Fields - **Scope**: workspace - **Primary Routes**: - `/admin/provider-connections` - `/admin/provider-connections/create` with `managed_environment_id` query context - `/admin/provider-connections/{record}` - `/admin/provider-connections/{record}/edit` - named onboarding routes `admin.onboarding` and `admin.onboarding.draft` - managed-environment detail and related-context entry points that deep-link into provider connections under the surviving admin panel - **Data Ownership**: - `ProviderConnection` remains the existing workspace-owned, managed-environment-scoped provider binding record - `ProviderCredential` remains the existing provider-owned secret record attached to one `ProviderConnection` - Microsoft-specific profile semantics remain provider-owned metadata/profile detail; this slice does not introduce a dedicated provider-profile table or other new persisted truth - `OperationRun` remains execution truth and records provider-neutral target-scope fields plus provider-specific nested context only where provider-specific follow-up truly needs it - **RBAC**: - workspace membership remains the first isolation boundary - managed-environment access remains the second isolation boundary - `PROVIDER_VIEW`, `PROVIDER_MANAGE`, `PROVIDER_MANAGE_DEDICATED`, and `PROVIDER_RUN` remain the capability gates for the existing provider-connection surfaces - non-members stay `404`, and in-scope actors missing a capability stay `403` ## Cross-Cutting / Shared Pattern Reuse - **Cross-cutting feature?**: yes - **Interaction class(es)**: navigation entry points, list/detail summaries, onboarding readiness messaging, provider-operation start feedback, audit metadata, and provider-specific consent/navigation links - **Systems touched**: `ProviderConnectionResource`, `ProviderConnectionSurfaceSummary`, `TenantResource` related-context/provider summary entries, `ManagedTenantOnboardingWizard`, `ProviderConnectionResolver`, `ProviderIdentityResolver`, `ProviderIdentityResolution`, `PlatformProviderIdentityResolver`, `ProviderOperationStartGate`, `ProviderConnectionTargetScopeNormalizer`, `ProviderConnectionTargetScopeDescriptor`, `CredentialManager`, `RequiredPermissionsLinks`, `AdminConsentUrlFactory`, and `config/provider_boundaries.php` - **Existing pattern(s) to extend**: the current target-scope descriptor/normalizer path, the current provider-connection resource action family, the current onboarding readiness/provider summary path, and the shared provider-operation start gate/presenter contract - **Shared contract / presenter / builder / renderer to reuse**: `ProviderConnectionTargetScopeDescriptor`, `ProviderConnectionTargetScopeNormalizer`, `ProviderIdentityResolution`, `ProviderConnectionSurfaceSummary`, `ProviderOperationStartGate`, `ProviderOperationStartResultPresenter`, and the existing `ProviderConnectionResource` action group/view model helpers - **Why the existing shared path is sufficient or insufficient**: the repo already has the right shared seams. What is insufficient is not the absence of a framework, but the Microsoft-shaped payload and naming that still flows through those seams. Extending the existing path is sufficient; creating a new provider framework is not. - **Allowed deviation and why**: one bounded deviation is allowed: Microsoft-specific tenant-profile, consent, portal, and required-permissions details may remain inside a clearly provider-owned profile/context block or nested provider metadata where current support and consent workflows need them. They must not become the shared label set for target scope, provider identity, or run context. - **Consistency impact**: provider-connection list/detail pages, managed-environment summaries, onboarding readiness, audit metadata, and provider-operation follow-up must all describe the same connection with the same shared target-scope summary before any provider-specific detail is shown. - **Review focus**: reviewers must verify that the shared target-scope/identity contract is reused instead of a parallel helper, that Microsoft detail is nested inside provider-owned sections only, that the provider-connection resource and onboarding wizard show the same summary contract, and that no new table or registry quietly appears. ## OperationRun UX Impact - **Touches OperationRun start/completion/link UX?**: yes, start/block/link semantics only - **Shared OperationRun UX contract/layer reused**: `ProviderOperationStartGate`, `ProviderOperationStartResultPresenter`, `OperationUxPresenter`, `OperationRunLinks`, and the existing `OperationRunService` lifecycle path - **Delegated start/completion UX behaviors**: current shared start-gate and presenter paths remain responsible for queued/block/dedupe messaging, run links, and lifecycle semantics; this slice only changes the connection identity and target-scope data they carry - **Local surface-owned behavior that remains**: `ProviderConnectionResource` and `ManagedTenantOnboardingWizard` continue to own only initiation inputs, connection selection, and current-surface follow-up links - **Queued DB-notification policy**: `N/A` - unchanged shared policy - **Terminal notification path**: existing central lifecycle mechanism - **Exception required?**: none ## Provider Boundary / Platform Core Check - **Shared provider/platform boundary touched?**: yes - **Boundary classification**: mixed - **Seams affected**: - platform-core: `provider.connection_resolution`, `provider.identity_resolution`, `provider.operation_start_gate` - provider-owned: Microsoft consent URL shaping, Microsoft portal/profile details, and Microsoft Graph runtime option mapping - mixed UI bridge: provider-connection summaries, managed-environment related context, and onboarding readiness that expose shared target-scope truth plus provider-specific follow-up detail - **Neutral platform terms preserved or introduced**: `provider connection`, `target scope`, `scope kind`, `scope identifier`, `scope display name`, `effective client identity`, `credential source`, `provider profile`, `provider context`, `workspace`, and `managed environment` - **Provider-specific semantics retained and why**: Microsoft tenant directory ID, authority tenant, admin-consent callback/URL, required-permissions guidance, Graph client identity, domains, and portal links remain necessary for current consent and troubleshooting workflows. They stay provider-owned and must not be promoted into platform-core truth. - **Why this does not deepen provider coupling accidentally**: shared platform-core seams move toward neutral `target_scope` and identity language, while Microsoft-specific profile detail is explicitly nested under provider-owned metadata/profile seams. The feature removes a Microsoft-shaped hotspot instead of creating a new generalized provider platform. - **Follow-up path**: Spec `282` for governance-artifact retargeting consumers, Spec `283` for capability registry follow-through, Spec `284` for provider-neutral artifact taxonomy, Spec `285` for workspace-first RBAC follow-through, Spec `286` for broader operator-copy neutralization, and Spec `287` for the cutover quality-gate pack ## UI / Surface Guardrail Impact | Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note | |---|---|---|---|---|---|---| | Provider connections resource family (`List`, `View`, `Create`, `Edit`) | yes | Native Filament resource plus shared action/presenter primitives | list/detail summary, consent/action group, provider-operation feedback | page, table, detail, modal, Livewire state | no | Reuses the existing resource, action surface declaration, and view/edit pages; the slice changes shared connection/profile semantics, not the route family | | Managed-environment detail provider connection summary and related-context entry | yes | Native Filament resource detail plus existing related-context pattern | related navigation, summary chips, environment-scoped follow-up | detail, link state | no | Summary only; no new detail surface or action family is introduced | | Managed-environment onboarding provider-connection step | yes | Native Filament custom wizard using existing onboarding shell and shared provider summaries | workflow selection, readiness summary, supporting links | page, wizard, session, Livewire state | no | Reuses the onboarding wizard; no second onboarding framework or connection picker is introduced | ## Decision-First Surface Role | Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction | |---|---|---|---|---|---|---|---| | Provider connections resource family | Primary Decision Surface | Operator decides whether one provider connection is usable, default-worthy, or ready to run provider work | managed environment, provider, target scope, lifecycle, consent, verification | credential source, migration-review detail, provider-specific profile data, last error, and run follow-up | Primary because this is the configuration and execution surface where the operator chooses the active provider binding | Matches the existing integrations/settings workflow instead of inventing another workbench | Removes the need to jump between tenant detail, onboarding, and operations just to identify connection scope | | Managed-environment detail provider connection summary and related-context entry | Secondary Context Surface | Operator confirms an environment has a usable provider connection and decides whether to drill in | high-level provider-connection summary and direct link | full connection detail remains on the provider-connections resource | Secondary because it advertises context and next step rather than owning the decision itself | Keeps managed-environment overview calm while still exposing the next relevant integration step | Reduces navigation search and duplicate summary cards | | Managed-environment onboarding provider-connection step | Primary Decision Surface | Operator chooses or creates the connection that will unblock onboarding readiness | selected connection, target scope summary, consent/readiness state, next step | provider-specific profile detail, verification detail, and supporting links | Primary because onboarding cannot continue safely until the correct connection is chosen and understood | Matches the current onboarding workflow and keeps connection readiness inside it | Prevents operators from reconstructing connection identity from raw IDs or separate pages | ## Audience-Aware Disclosure | Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention | |---|---|---|---|---|---|---|---| | Provider connections resource family | operator-MSP, support-platform | provider, target scope, lifecycle, consent, verification, and current default-connection truth | credential source, migration review, blocked reason, recent operation follow-up | Microsoft-specific profile identifiers, portal links, required-permissions detail, and other provider-owned troubleshooting context | `Open`, `Check connection`, or one existing primary provider action depending on surface | dedicated credential secrets, provider-owned raw detail, and support-only context stay gated or nested | target scope is stated once in the shared summary and not re-explained in every provider-specific subsection | | Managed-environment detail provider connection summary and related-context entry | operator-MSP, support-platform | whether a connection exists, its high-level status, and where to go next | minimal summary only | none on this surface | `Open provider connections` | provider-specific profile detail stays on the provider-connections resource | the managed-environment page advertises the next step without duplicating the full connection detail card | | Managed-environment onboarding provider-connection step | operator-MSP, support-platform | selected connection, target scope summary, consent/readiness status, and the next unblock action | verification result, blocked reason, supporting links, and run continuity | provider-specific profile detail stays behind provider-owned disclosure or support links | `Select connection`, `Create connection`, or `Continue` depending on current state | raw provider profile detail and credential data stay hidden | the wizard uses the same target-scope summary as the resource instead of inventing a second identity story | ## UI/UX Surface Classification | Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification | |---|---|---|---|---|---|---|---|---|---|---|---|---|---| | Provider connections resource family | List / Detail / Integrations | CRUD / List-first Resource | Open one connection, verify it, or run provider work | clickable row to the View page | required | grouped under `More` on list/view surfaces | grouped under `More`, server-authorized, confirmation-required where mutating or dangerous | `/admin/provider-connections` | `/admin/provider-connections/{record}` and `/admin/provider-connections/{record}/edit` | managed-environment filter, workspace context, provider, target scope | Provider connection | target scope and connection health | none | | Managed-environment detail provider connection summary and related-context entry | Detail / Related Context / Navigation | Environment detail follow-up entry | Open provider connections for the current managed environment | explicit related-context `Open` link | forbidden | none beyond the explicit open affordance | none | managed-environment detail surface with provider-connections deep link | `/admin/provider-connections?managed_environment_id={environment}` | current workspace and current managed environment | Provider connections | whether the environment is wired to a usable provider connection | none | | Managed-environment onboarding provider-connection step | Workflow Hub / Wizard / Readiness | Workflow-step selector | Select or create the correct provider connection and continue onboarding | in-step selection and explicit create or manage actions | forbidden | supporting links and provider follow-up remain secondary | none added by this slice | named onboarding routes `admin.onboarding` and `admin.onboarding.draft` | same wizard step or draft route | current workspace, current managed environment, selected provider connection | Provider connection | selected connection and readiness state | none | ## Operator Surface Contract | Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions | |---|---|---|---|---|---|---|---|---|---|---| | Provider connections resource family | Workspace operator | Decide whether one provider connection is the right and healthy binding for this managed environment | List/detail resource | Is this the right provider connection and is it safe to use right now? | managed environment, provider, target scope, lifecycle, consent, verification, default state | migration review, last error, credential source, provider-specific profile detail, run follow-up | lifecycle, consent, verification, migration-review | `TenantPilot only` for connection metadata and credentials, `Microsoft tenant` only when admin consent or provider execution is triggered | Open, Check connection, Inventory sync, Compliance snapshot, Edit | Set default, enable or rotate dedicated credentials, revert or delete credentials, enable or disable connection | | Managed-environment detail provider connection summary and related-context entry | Workspace operator | Decide whether to inspect or fix provider connection state from the environment overview | Related-context summary | Do I need to drill into provider connections from this environment now? | high-level connection presence and status plus direct link | none beyond brief summary copy | lifecycle, verification | none | Open provider connections | none | | Managed-environment onboarding provider-connection step | Workspace operator | Choose the connection that will unblock onboarding and later provider operations | Wizard step | Which provider connection should this onboarding flow use, and is it ready? | selected connection, target scope summary, readiness and consent state, next step | blocked reason, supporting verification links, provider-specific profile detail on demand | readiness, consent, verification | `TenantPilot only` for selection and onboarding draft state; provider execution remains separate | Select connection, Create connection, Continue | none added by this slice | ## Proportionality Review - **New source of truth?**: no - **New persisted entity/table/artifact?**: no - **New abstraction?**: no - **New enum/state/reason family?**: no - **New cross-domain UI framework/taxonomy?**: no - **Current operator problem**: the platform-core provider boundary still forces operators and downstream run/audit consumers to rely on Microsoft-specific scope identity even though provider connections are already modeled as managed-environment-bound records. - **Existing structure is insufficient because**: the current structure already has shared target-scope and identity helpers, but those helpers still emit Microsoft-shaped fields and context. Leaving them untouched would keep the real platform-core contract Microsoft-specific even if page copy becomes more neutral. - **Narrowest correct implementation**: extend the existing target-scope descriptor, identity resolution, provider-connection summary, onboarding readiness, and provider-operation start seams so they emit one neutral shared contract while keeping Microsoft profile detail nested under provider-owned metadata/profile blocks. - **Ownership cost**: focused updates across provider resolution, run context, audit metadata, provider-connection resource summaries, onboarding readiness, and their tests. The cost stays bounded because no new table, registry, or framework is introduced. - **Alternative intentionally rejected**: a new provider-profile table, a generic provider profile registry, or a broader multi-provider identity framework. Those options add structure without a current-release source-of-truth need and violate the constitution's bounded-extraction bias. - **Release truth**: current-release truth; this slice closes an active platform-core/provider-boundary mismatch rather than preparing speculative future providers. ### Compatibility posture This feature assumes a pre-production environment. Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec. Canonical replacement is preferred over preservation. ## Testing / Lane / Runtime Impact - **Test purpose / classification**: Feature, Browser - **Validation lane(s)**: fast-feedback, confidence, browser - **Why this classification and these lanes are sufficient**: feature coverage is the narrowest honest proof for provider-boundary contract changes across target-scope normalization, identity resolution, provider-operation start context, resource semantics, and onboarding readiness. One browser smoke is justified because the operator-facing resource and onboarding flow must show the same summary and action semantics in the real shell. - **New or expanded test families**: one provider target-scope or identity feature family, one provider-operation start-gate context family, one provider-connection Filament resource behavior family, one onboarding provider-connection readiness family, and one narrow browser smoke covering the provider-connections plus onboarding path - **Fixture / helper cost impact**: moderate. Tests need workspace, managed environment, provider connection, optional provider credential, and focused run fixtures. No new global defaults, provider registries, or browser-wide setup should become implicit. - **Heavy-family visibility / justification**: one browser smoke only. No heavy-governance family is justified by this slice. - **Special surface test profile**: standard-native-filament, workflow-hub, global-context-shell - **Standard-native relief or required special coverage**: ordinary feature coverage is sufficient for the shared contract shifts; one browser smoke is required to prove that provider-connections and onboarding show the same target-scope summary and action affordances on real surfaces. - **Reviewer handoff**: reviewers must verify that Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, `ProviderConnectionResource` stays non-globally-searchable while continuing to offer View and Edit pages, touched destructive actions still use `->action(...)` plus `->requiresConfirmation()` and server authorization, no new asset registration appears, and the planned tests prove the shared neutral target-scope contract instead of page-local wording only. - **Budget / baseline / trend impact**: moderate feature-local increase only - **Escalation needed**: none - **Active feature PR close-out entry**: Guardrail - **Planned validation commands**: - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Providers/ProviderConnectionTargetScopeNeutralityTest.php tests/Feature/Providers/ProviderIdentityResolutionNeutralityTest.php tests/Feature/Providers/ProviderOperationStartGateTargetScopeContextTest.php tests/Feature/Filament/ProviderConnectionResourceScopeSummaryTest.php tests/Feature/Onboarding/ManagedTenantOnboardingProviderConnectionScopeTest.php tests/Feature/Guards/ProviderConnectionMicrosoftScopeLeakGuardTest.php)` - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php)` - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)` ## Scope Boundaries *(required for this slice)* ### In Scope - document the verified candidate deviation that `provider_connections` already use `managed_environment_id` - normalize the shared provider-connection target-scope contract across connection resolution, identity resolution, audit metadata, resource summaries, onboarding readiness, and provider-operation start context - normalize the shared provider-identity contract so platform-core seams talk about effective client identity, credential source, and target scope rather than Microsoft tenant context as generic truth - update provider-operation start context so the shared `target_scope` payload is provider-neutral and no longer relies on `target_scope.entra_tenant_id` - keep Microsoft-specific profile semantics in provider-owned metadata or profile detail, provider-specific links, and support-oriented disclosure - align `ProviderConnectionResource`, managed-environment related context, and onboarding readiness on one shared target-scope summary contract - keep current provider-connection actions, consent links, and capability boundaries intact while clarifying which ones are provider-owned versus platform-core - keep provider-boundary seam classification explicit in `config/provider_boundaries.php` and related review proof ### Non-Goals - repeating the already-completed `tenant_id` -> `managed_environment_id` move on `provider_connections` - introducing a dedicated provider-profile table or any other new persisted profile truth - introducing a provider capability registry, package engine, provider-neutral artifact taxonomy, or governance-artifact retargeting - widening the slice into workspace-first RBAC redesign, broader copy or localization neutralization, or cutover quality-gate work reserved for Specs `285`-`287` - enabling global search for `ProviderConnectionResource` - adding a second provider implementation, compatibility shim, backfill path, or speculative multi-provider identity framework ## Assumptions - Spec `279` already completed the managed-environment core cutover and is prerequisite context only. - Spec `280` already defines the adjacent workspace-first routing shell and remains separate prepared context; `281` must not absorb its route-cutover work. - `ProviderConnection` already remains anchored by `workspace_id` plus `managed_environment_id`, and the 281 problem is contract extraction rather than relationship migration. - The existing `ProviderConnectionTargetScopeNormalizer`, `ProviderConnectionTargetScopeDescriptor`, `ProviderIdentityResolution`, `ProviderConnectionSurfaceSummary`, and provider-connection resource or onboarding surfaces are the correct extension points for this slice. - Microsoft remains the only implemented provider today, but platform-core seams touched here must still use neutral terms so later provider work is not blocked. - `ProviderConnectionResource` remains non-globally-searchable; touched searchable resources such as `TenantResource` keep their existing valid view destinations. ## Risks - downstream run, audit, or support readers may still expect `target_scope.entra_tenant_id` even after the start gate writes the neutral shape - some operator surfaces may migrate to the new target-scope summary while others still read raw `entra_tenant_id`, leaving the same connection described differently - dedicated credential validation and blocked reason messaging may stay Microsoft-shaped if `CredentialManager` and identity-resolution seams are not updated together - the slice could sprawl into capability-registry, taxonomy, or copy-neutralization work if reviewers allow 283, 284, or 286 concerns to enter the implementation ## Candidate Selection Gate Summary - **Selected candidate**: `281 - Provider Connection, Provider Scope & Microsoft Profile Extraction` - **Source locations**: - `docs/product/spec-candidates.md` under the reserved workspace-first or provider-neutral cutover pack - `docs/product/roadmap.md` under the same cutover ordering - **Why selected now**: after the completed `279` core cutover and the prepared `280` routing cutover, the next verified blocker is the provider boundary itself. The repo already has target-scope groundwork, but shared provider connection and run identity still leak Microsoft semantics in the platform core. - **Why close alternatives were deferred**: - `282` depends on `281` because governance-artifact retargeting should inherit provider-neutral connection and run scope instead of another Microsoft-shaped shared contract - `283` is capability-registry follow-through and should not be pulled into this slice while the connection or profile contract is still being normalized - `284` is a broader artifact-source taxonomy and belongs after the provider-connection and run-scope boundary is neutralized - `285` is workspace-first RBAC follow-through and can remain on the current capability model while `281` closes the connection or profile hotspot - `286` is broader operator-copy and localization neutralization and should follow the concrete provider-boundary extraction rather than precede it - `287` is the cutover quality-gate pack and should harden the finished slices instead of expanding `281` - **Smallest viable implementation slice**: one neutral shared target-scope and identity contract across existing provider seams plus provider-owned Microsoft profile disclosure on the current resource and onboarding surfaces - **Documented deviations from raw candidate wording**: - the raw candidate still mentions replacing `provider_connections.tenant_id` with `provider_connections.managed_environment_id`, but repo truth already completed that move - the raw candidate also proposed a new shared field family around `provider_key`, `external_account_id`, `provider_metadata`, and explicit run-context workspace/environment keys; this package narrows that to existing repo truth by keeping `provider`, `workspace_id`, and `managed_environment_id` where they already exist, using the canonical shared `target_scope` plus `effective_client_identity`, and confining provider-specific identifiers or profile detail to nested `provider_context` and existing provider-owned metadata ## Completed-Spec Guardrail Result - `specs/279-workspace-managed-environment-core/spec.md` already exists with `Status: Ready with approved feature-local exception` and remains historical prerequisite context only - `specs/280-workspace-tenancy-environment-routing/spec.md` already exists with `Status: Ready` and remains an adjacent prepared package only; its route-cutover work must not be absorbed into `281` - the target package `specs/281-provider-connection-scope/spec.md` existed only as the raw template before this update and is the sole spec artifact edited in this package ## Deferred Adjacent Candidates - `282 - Governance Artifact Retargeting to ManagedEnvironment` - `283 - Provider Capability Registry v1` - `284 - Provider-neutral Artifact Source Taxonomy v1` - `285 - Workspace-first RBAC & Environment Access Scoping` - `286 - UI Copy, IA & Localization Neutralization` - `287 - Cutover Quality Gates & No-Legacy Enforcement` ## User Scenarios & Testing ### User Story 1 - Inspect a provider connection with one neutral target-scope summary (Priority: P1) As an operator, I want provider-connection list and detail surfaces to tell me immediately which managed environment and target scope a connection represents without forcing me to interpret a Microsoft-only field name before I can decide whether the connection is usable. **Why this priority**: this is the core operator-facing trust problem in the current seam. If the shared summary remains Microsoft-shaped, later provider-neutral cutover work keeps inheriting that drift. **Independent Test**: open the provider-connections list and one connection detail page for a managed environment, then confirm the shared summary shows provider, target scope, and health first while Microsoft profile detail stays nested under a provider-owned disclosure. **Acceptance Scenarios**: 1. **Given** a managed environment has a provider connection, **When** the operator opens the provider-connections list or detail page, **Then** the default-visible summary shows provider, target scope, lifecycle, consent, and verification without requiring a Microsoft-only field label to understand the connection identity. 2. **Given** the operator needs provider-specific consent or troubleshooting data, **When** they open the provider-owned profile or context disclosure on the connection detail surface, **Then** Microsoft-specific details appear there without replacing the shared target-scope label set. --- ### User Story 2 - Start provider work without Microsoft-shaped shared run context (Priority: P1) As an operator, I want connection checks and provider operations started from provider-connection or onboarding surfaces to record provider-neutral target-scope context so later run follow-up, audit, and support flows do not depend on Microsoft-only keys. **Why this priority**: `ProviderOperationStartGate` is one of the verified remaining hotspots, and later artifact and taxonomy work depends on this shared execution context becoming neutral first. **Independent Test**: start one provider-backed operation from a provider connection and verify that the resulting run can be identified by provider connection and target scope without relying on `target_scope.entra_tenant_id` as the shared contract. **Acceptance Scenarios**: 1. **Given** an operator starts `Check connection`, `Inventory sync`, or `Compliance snapshot` from a valid provider connection, **When** the run is created, **Then** the resulting run context identifies provider connection and target scope through provider-neutral shared fields, with any Microsoft-specific detail nested under provider-owned context only. 2. **Given** a provider operation is blocked because consent, scope, or credentials are invalid, **When** the blocked result is shown, **Then** the operator still sees a usable target-scope summary and blocked reason without the shared contract collapsing back to Microsoft-only field names. --- ### User Story 3 - See the same connection story in onboarding and provider settings (Priority: P2) As an operator, I want the onboarding wizard to describe provider connections with the same target-scope summary used on the provider-connections resource so I do not need to reinterpret the same connection differently just because I am in onboarding. **Why this priority**: onboarding is already one of the verified seams reusing provider-connection summaries and audit metadata. Drift here would immediately create a second identity language. **Independent Test**: select or create a provider connection from the onboarding wizard and confirm that the displayed target-scope summary matches the one shown on the provider-connections resource for the same record. **Acceptance Scenarios**: 1. **Given** onboarding lists multiple provider connections for the current managed environment, **When** the operator reviews the choices, **Then** each option uses the same target-scope summary contract as the provider-connections list and detail surfaces. 2. **Given** onboarding shows provider verification or supporting links for the selected connection, **When** the operator inspects that state, **Then** the readiness surface uses the same shared target-scope and provider-context labels as the provider-connections resource. --- ### User Story 4 - Jump from managed-environment detail into provider connections without duplicate truth (Priority: P3) As an operator, I want the managed-environment detail page to advertise provider-connection state and take me into the provider-connections resource without duplicating the full provider profile summary on the overview page. **Why this priority**: this is the boundary between context surfaces and primary decision surfaces. The environment overview should stay calm while still exposing the integration step. **Independent Test**: open one managed-environment detail page, use its provider-connections related-context entry, and verify that the overview stays summary-first while the provider-connections resource becomes the primary decision surface. **Acceptance Scenarios**: 1. **Given** a managed environment has an accessible provider connection, **When** the operator uses the provider-connections related-context entry from the environment view, **Then** the destination opens the provider-connections resource scoped to that environment and carries the same shared target-scope summary. 2. **Given** the operator stays on the managed-environment overview page, **When** they read the provider-connection summary there, **Then** the page shows only the minimal connection truth needed to decide whether to drill in and does not duplicate full provider-profile detail. ### Edge Cases - A provider connection with missing or invalid target-scope input must stay blocked explicitly and must not fall back to an implicit Microsoft tenant context. - An unsupported provider or scope combination must fail as an unsupported binding or invalid connection rather than being normalized into a Microsoft-shaped default. - A dedicated credential payload whose embedded environment or scope hint no longer matches the connection's normalized target scope must fail validation rather than silently reusing stale Microsoft identity. - Multiple default provider connections for the same managed environment and provider must remain blocked and clearly diagnosable. - A provider connection record or onboarding selection outside the current workspace or managed environment must resolve as `404` or unavailable, not as a leaked or silently widened option. - If provider-specific profile data such as domains or portal links are absent, the shared target-scope summary must still render truthfully without forcing a new persisted profile table into scope. ## Requirements **Constitution alignment (required):** This slice changes provider connection resolution, identity resolution, provider-operation start context, provider-connection admin surfaces, and onboarding readiness. It does not introduce new Microsoft Graph contract registry entries, new provider implementations, or new long-running workflow types. **Constitution alignment (PROP-001 / PROV-001 / BLOAT-001):** The slice must stay bounded to current provider-connection and run-context hotspots. No new table, registry, or generic provider framework is justified unless later planning can prove a current-release source-of-truth need. **Constitution alignment (XCUT-001 / UI-FIL-001 / DECIDE-001):** The slice must reuse the existing provider-connections resource, existing onboarding wizard, and existing provider-operation start path. It may refine shared summaries and provider-owned detail disclosure, but it must not invent a second provider workbench, a second onboarding picker, or ad-hoc status styling. **Constitution alignment (RBAC-UX):** Workspace and managed-environment membership remain the isolation boundaries. Provider manage or run mutations stay server-authorized and confirmation-protected where destructive or high-impact. Navigation-only actions such as `Grant admin consent` stay capability-gated but do not claim confirmation behavior. **Constitution alignment (TEST-GOV-001 / OPS-UX-START-001):** Proof must stay bounded to feature tests plus one browser smoke. Operation start behavior must continue to flow through the shared provider-operation gate or presenter path, with the only change being the shared target-scope and provider-context contract. ### Functional Requirements - **FR-001**: The system MUST preserve `ProviderConnection` as the existing workspace-owned, managed-environment-scoped provider binding record and MUST NOT reintroduce `tenant_id` semantics into `provider_connections`. - **FR-002**: Shared provider-connection target-scope output MUST use provider-neutral fields for provider, scope kind, scope identifier, and scope display name wherever the platform core records or renders connection scope. - **FR-003**: `ProviderConnectionResolver` and related validation paths MUST treat provider plus managed environment plus normalized target scope as the controlling scope contract, not `entra_tenant_id` as generic platform truth. - **FR-004**: Shared provider identity resolution MUST separate neutral identity semantics such as effective client identity, credential source, and target scope from provider-specific profile or context detail. - **FR-005**: `ProviderIdentityResolution` and `PlatformProviderIdentityResolver` MUST stop using `tenantContext` as the canonical shared contract term and MUST confine any remaining Microsoft tenant-context semantics to provider-owned profile or context detail. - **FR-006**: `CredentialManager` validation MUST align dedicated credentials with the connection's normalized target scope and provider binding rather than treating a Microsoft-specific field as the only source of truth. - **FR-007**: `ProviderConnectionTargetScopeNormalizer` and `ProviderConnectionTargetScopeDescriptor` MUST continue to block unsupported provider or scope combinations explicitly and MUST emit the same shared summary contract used by resource, onboarding, audit, and run surfaces. - **FR-008**: Provider-connection audit metadata MUST use the neutral target-scope descriptor fields in shared audit context and MUST keep Microsoft-specific identity context nested under provider-owned detail only. - **FR-009**: `ProviderOperationStartGate` MUST write provider-neutral `target_scope` fields into `OperationRun` context and MUST NOT use `target_scope.entra_tenant_id` as the shared contract key. - **FR-010**: Any Microsoft-specific scope or profile data still needed by provider-operation follow-up, consent, or support flows MUST live inside a clearly provider-owned nested context or metadata block rather than in the shared `target_scope` shape. - **FR-011**: `ProviderConnectionResource` list, create, view, and edit surfaces MUST show neutral target-scope labels and summaries in their shared columns, sections, and helper text while moving Microsoft-specific profile detail into provider-owned disclosure. - **FR-012**: `ProviderConnectionResource` MUST remain non-globally-searchable in this slice. Its existing View and Edit pages remain the canonical inspect and mutation surfaces. - **FR-013**: `TenantResource` managed-environment detail summaries and related-context entries that advertise provider connections MUST use the same shared target-scope summary contract as `ProviderConnectionResource`. - **FR-014**: `ManagedTenantOnboardingWizard` MUST use the same shared target-scope summary contract for provider-connection options, readiness state, and supporting audit metadata as the provider-connections resource. - **FR-015**: Provider-specific consent, required-permissions, portal, and troubleshooting detail MUST remain provider-owned guidance and MUST NOT redefine shared platform nouns such as `workspace`, `managed environment`, `provider connection`, or `target scope`. - **FR-016**: The implementation MUST NOT introduce a dedicated provider-profile table, a provider-profile registry, a capability registry, a provider-neutral artifact taxonomy, or any other framework work reserved for Specs `282`-`287`. - **FR-017**: The feature MUST preserve the existing provider-connection action family and provider-operation start entry points, changing only the shared connection or profile semantics they expose. - **FR-018**: `config/provider_boundaries.php` and any related review proof touched by implementation MUST classify the remaining Microsoft-specific exceptions explicitly instead of leaving them implicit in platform-core seams. ### Authorization and Safety Requirements - **AR-001**: Workspace membership MUST remain the first access boundary for provider-connections and onboarding provider-connection flows. - **AR-002**: Managed-environment entitlement MUST remain the second access boundary for provider-connections list, detail, create, or edit access and onboarding connection selection. - **AR-003**: Non-members or cross-workspace or cross-environment access attempts MUST resolve as `404`, while in-scope actors missing provider capabilities MUST resolve as `403`. - **AR-004**: Mutating provider-connection actions such as setting default, enabling dedicated override, rotating or deleting credentials, reverting to platform, and enabling or disabling the connection MUST remain server-authorized and use confirmation where the existing action contract requires it. - **AR-005**: Navigation-only consent actions such as `Grant admin consent` MUST remain capability-gated and truthful about being navigation, not mutation. - **AR-006**: Provider-operation starts triggered from the touched surfaces MUST continue to use the shared provider-operation gate and existing capability checks before any run is created. ### Non-Functional Requirements - **NFR-001**: Filament remains v5 on Livewire v4. - **NFR-002**: Provider registration remains in `apps/platform/bootstrap/providers.php`; this slice does not move any provider or panel registration into `bootstrap/app.php`. - **NFR-003**: Asset strategy remains unchanged. No new panel or shared asset registration is expected; if a later implementation registers assets unexpectedly, deployment continues to use `cd apps/platform && php artisan filament:assets`. - **NFR-004**: `ProviderConnectionResource` remains non-globally-searchable, and any touched searchable resource such as `TenantResource` must keep its valid view destination intact. - **NFR-005**: The feature must stay reviewable as one bounded slice and must not silently absorb route-cutover work from Spec `280` or capability, taxonomy, RBAC, copy, or quality-gate work from Specs `282`-`287`. - **NFR-006**: The touched Filament surfaces must continue to follow the current TenantPilot enterprise UI standard, existing action hierarchy, and native Filament semantics rather than introducing local card, button, or status styling. ## UI Action Matrix *(mandatory when Filament is changed)* | Surface | Location | Header Actions | Inspect Affordance (List or Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create or Edit Save+Cancel | Audit log? | Notes / Exemptions | |---|---|---|---|---|---|---|---|---|---|---| | Provider connections list | `ProviderConnectionResource` -> `ListProviderConnections` | `New connection` | `recordUrl()` clickable row to View | `More` group containing `Edit`, `Check connection`, `Inventory sync`, `Compliance snapshot`, `Set as default`, `Enable dedicated override`, `Rotate dedicated credential`, `Delete dedicated credential`, `Revert to platform`, `Enable connection`, `Disable connection` | none | `New connection` | `N/A` | `N/A` | existing mutation actions already write audit logs where required | Resource remains non-globally-searchable and keeps one inspect model via clickable row | | Provider connection view and edit surfaces | `ProviderConnectionResource` -> `ViewProviderConnection`, `EditProviderConnection`, `CreateProviderConnection` | `Grant admin consent` plus existing `More` action group on View; existing Edit or Create header behavior stays native | `N/A` | none beyond the shared `More` group on View or Edit | none | `N/A` | `Grant admin consent`, `More` | native save or cancel flow | existing mutation actions already write audit logs where required | `Grant admin consent` is navigation-only; mutating actions in `More` remain server-authorized and confirmation-protected where dangerous | | Managed-environment onboarding provider-connection step | `ManagedTenantOnboardingWizard` provider-connection selection or readiness step | none | explicit in-step selector and create or manage actions only | none | none | existing onboarding create or select affordances only | `N/A` | wizard save or continue semantics only | existing onboarding connection changes already write audit logs | This slice changes summary semantics and supporting links only; it does not introduce a second onboarding action family | ### Key Entities *(include if feature involves data)* - **Provider Connection**: the existing runtime binding between one managed environment and one provider, including connection type, default state, consent state, verification state, and attached credentials. - **Target Scope Descriptor**: the shared neutral summary of what platform scope a provider connection represents, including provider, scope kind, scope identifier, and scope display name. - **Provider Identity Resolution**: the shared runtime result that determines effective client identity, credential source, target scope, and blocked or resolved state for one provider connection. - **Provider Profile Detail**: provider-owned Microsoft-specific metadata and guidance such as tenant directory identity, consent or required-permissions links, domains, portal links, and similar follow-up detail that must remain secondary to the shared target-scope summary. - **Provider Operation Context**: the `OperationRun` identity and context payload created from a provider-backed start path, linking one run to one provider connection and one normalized target scope. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: 100% of affected default-visible provider-connection summaries use neutral target-scope wording instead of requiring a Microsoft-specific field label as the primary identity signal. - **SC-002**: An operator can move from managed-environment detail or onboarding to the correct provider-connection detail surface and identify the connection's target scope in 3 interactions or fewer. - **SC-003**: 100% of provider operations started from the affected surfaces carry enough shared provider-connection and target-scope information that follow-up run and audit surfaces can identify the target without reconstructing it from Microsoft-only context. - **SC-004**: Microsoft-specific consent and profile details remain accessible for troubleshooting and admin-consent follow-up without becoming the primary visible identity vocabulary on affected shared platform surfaces.