TenantAtlas/specs/281-provider-connection-scope/plan.md
Ahmed Darrazi 19132dc433
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m28s
feat: normalize provider connection scope contracts
2026-05-07 21:27:15 +02:00

289 lines
30 KiB
Markdown

# Implementation Plan: Provider Connection Scope & Microsoft Profile Extraction
**Branch**: `281-provider-connection-scope` | **Date**: 2026-05-07 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `specs/281-provider-connection-scope/spec.md`
## Summary
Prepare the next reserved provider-boundary slice that keeps `ProviderConnection` as the existing managed-environment-scoped binding record but extracts one provider-neutral target-scope and effective-client-identity contract across the current platform-core seams. The narrow implementation path reuses `ProviderConnectionTargetScopeDescriptor`, `ProviderConnectionTargetScopeNormalizer`, `ProviderConnectionSurfaceSummary`, `ProviderConnectionResolver`, `ProviderIdentityResolver`, `ProviderIdentityResolution`, `PlatformProviderIdentityResolver`, `ProviderOperationStartGate`, `CredentialManager`, `ProviderConnectionResource`, `ManagedTenantOnboardingWizard`, and `config/provider_boundaries.php` while explicitly deferring Specs `282` through `287`.
This plan stays intentionally bounded. Filament remains v5 on Livewire v4, provider registration remains in `apps/platform/bootstrap/providers.php`, `ProviderConnectionResource` stays non-globally-searchable, no `tenant_id` to `managed_environment_id` migration is reintroduced, no provider-profile table or registry appears, no routing cutover from Spec `280` is absorbed, no RBAC redesign or taxonomy work is introduced, and no compatibility alias such as shared `tenantContext` or shared `target_scope.entra_tenant_id` survives as platform-core truth.
## Inherited Baseline / Explicit Delta
### Inherited baseline
- Spec `279` already completed the core managed-environment cutover and is completed historical context only.
- Spec `280` already prepared the adjacent workspace-first routing shell and remains separate prepared context only.
- `apps/platform/app/Models/ProviderConnection.php` already anchors provider connections by `workspace_id` plus `managed_environment_id`; no `tenant_id` migration remains for this feature.
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` already exists with `List`, `Create`, `View`, and `Edit` pages, remains `protected static bool $isGloballySearchable = false;`, and already groups mutating actions behind confirmation-protected Filament actions.
- `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php` and `apps/platform/config/provider_boundaries.php` already classify `provider.identity_resolution`, `provider.connection_resolution`, and `provider.operation_start_gate` as platform-core seams with retained Microsoft-specific exceptions that still need follow-through.
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php`, `ProviderConnectionTargetScopeNormalizer.php`, and `ProviderConnectionSurfaceSummary.php` already expose neutral field names such as `scope_kind`, `scope_identifier`, and `scope_display_name`, but they still derive those values directly from `ProviderConnection::entra_tenant_id` and still emit Microsoft contextual detail.
- `apps/platform/app/Services/Providers/ProviderIdentityResolver.php`, `ProviderIdentityResolution.php`, and `PlatformProviderIdentityResolver.php` still use `tenantContext` as the shared identity field name even though the same path already exposes `credentialSource`, `effectiveClientId`, `targetScope`, and contextual detail lists.
- `apps/platform/app/Services/Providers/ProviderOperationStartGate.php` still writes `target_scope.entra_tenant_id` for both started and blocked run context.
- `apps/platform/app/Services/Providers/CredentialManager.php` still validates credential payload scope against `entra_tenant_id` and still reports a Microsoft-shaped mismatch message from a platform-core seam.
- `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php` and `apps/platform/app/Filament/Resources/TenantResource.php` already reuse provider-connection summary and related-context seams, so they are the existing consumers that must converge on one contract rather than new surfaces that need to be invented.
### Explicit delta in this plan
- Keep `ProviderConnection`, `ProviderCredential`, `OperationRun`, and current route ownership intact; the slice is contract extraction only.
- Make `ProviderConnectionTargetScopeDescriptor` plus `ProviderConnectionTargetScopeNormalizer` the canonical shared `target_scope` contract across connection resolution, identity resolution, audit metadata, provider-operation start context, resource summaries, onboarding readiness, and related-context summaries.
- Reshape `ProviderIdentityResolution` around neutral effective-client-identity and target-scope language while confining Microsoft-specific tenant, authority, redirect, and consent semantics to nested provider-owned profile or context detail.
- Update `ProviderOperationStartGate` and the associated audit metadata path so shared `OperationRun` context no longer depends on `target_scope.entra_tenant_id` as the primary contract.
- Keep `ProviderConnectionSurfaceSummary` as the one summary adapter reused by `ProviderConnectionResource`, `ManagedTenantOnboardingWizard`, and managed-environment related-context provider summaries.
- Keep provider-owned Microsoft behavior such as admin-consent URL shaping, Graph runtime option mapping, and Microsoft profile disclosure explicit and secondary instead of turning them into platform-core vocabulary.
- Keep all provider registration, asset handling, routing, RBAC, taxonomy, capability-registry, and broader copy-neutralization work deferred to adjacent specs.
## Technical Context
**Language/Version**: PHP 8.4.15, Laravel 12.52
**Primary Dependencies**: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, existing provider-boundary config and target-scope helper seams
**Storage**: PostgreSQL, no new persistence or schema change in this slice
**Testing**: Pest feature tests, one Pest browser smoke, and focused guard coverage for Microsoft-shaped shared-contract regressions
**Validation Lanes**: fast-feedback, confidence, browser
**Target Platform**: Laravel monolith in `apps/platform`
**Project Type**: web application
**Performance Goals**: preserve current provider-connection resource, onboarding readiness, and provider-operation start responsiveness while changing only contract shaping and shared summaries; no new remote inline work or new asset load path
**Constraints**: no new table or persisted provider-profile truth, no registry or capability engine, no reintroduction of the stale `tenant_id` migration candidate, no routing cutover absorption from Spec `280`, provider registration stays in `apps/platform/bootstrap/providers.php`, `ProviderConnectionResource` stays non-globally-searchable, destructive actions stay confirmation-protected, asset strategy remains unchanged, and preparation work must stay spec-only
**Scale/Scope**: one provider-neutral target-scope and identity contract across the existing provider resolution, summary, onboarding, and operation-start seams for the single current Microsoft provider implementation
## Likely Affected Repo Surfaces
- `apps/platform/app/Models/ProviderConnection.php`
- `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`
- `apps/platform/app/Services/Providers/ProviderConnectionResolution.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/Services/Providers/CredentialManager.php`
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeDescriptor.php`
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionTargetScopeNormalizer.php`
- `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php`
- `apps/platform/app/Support/Providers/TargetScope/ProviderIdentityContextMetadata.php`
- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`
- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php`
- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php`
- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php`
- `apps/platform/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php`
- `apps/platform/app/Filament/Resources/TenantResource.php`
- `apps/platform/app/Support/Providers/RequiredPermissionsLinks.php`
- `apps/platform/app/Services/Providers/AdminConsentUrlFactory.php`
- `apps/platform/app/Services/Providers/ProviderGateway.php`
- `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`
- `apps/platform/config/provider_boundaries.php`
- feature, browser, and guard coverage under `apps/platform/tests/Feature` and `apps/platform/tests/Browser`
## Filament v5 / Provider Resource Notes
- **Livewire v4.0+ compliance**: all touched Filament work remains on Filament v5 with Livewire v4; the slice changes summary and contract shaping only.
- **Provider registration location**: provider registration stays in `apps/platform/bootstrap/providers.php`; nothing moves to `bootstrap/app.php`.
- **Global search rule**: `ProviderConnectionResource` already remains `isGloballySearchable = false` and still has `View` plus `Edit` pages. No new searchable resource is introduced by this slice. If a touched searchable consumer such as `TenantResource` continues to surface provider summaries, it must keep its existing valid view destination unchanged.
- **Destructive actions**: the touched provider-connection mutations already use `Actions\Action::make(...)->action(...)` with `->requiresConfirmation()` and server-side capability checks. The relevant confirmation-protected actions currently include `set_default`, `enable_dedicated_override`, `rotate_dedicated_credential`, `delete_dedicated_credential`, `revert_to_platform`, `enable_connection`, and `disable_connection`; this slice preserves that behavior.
- **Asset strategy**: no new panel or shared asset registration is planned. Deployment guidance remains unchanged: `cd apps/platform && php artisan filament:assets` is only needed when registered assets change, and this slice adds none.
## Neutral Target-Scope & Identity Contract Fit
- Treat `ProviderConnectionTargetScopeDescriptor` as the canonical shared `target_scope` object with `provider`, `scope_kind`, `scope_identifier`, `scope_display_name`, `shared_label`, and `shared_help_text`.
- Treat `ProviderIdentityResolution` as the canonical shared identity-result object for `resolved`, `connection_type`, `effective client identity`, blocked reason, target scope, and provider-context details.
- Treat `ProviderConnectionSurfaceSummary` as the only shared summary adapter for provider-connection list/detail surfaces, onboarding readiness, and managed-environment related context.
- Treat `ProviderOperationStartGate` as the only platform-core seam allowed to shape `OperationRun` context for provider-start flows.
- Treat `ProviderIdentityContextMetadata` as provider-owned disclosure metadata. Microsoft-specific items such as `microsoft_tenant_id`, `authority_tenant`, and `redirect_uri` stay nested there or in provider-owned profile blocks instead of becoming new shared top-level contract keys.
- Treat `AdminConsentUrlFactory` and `ProviderGateway` as downstream provider-owned consumers that must adapt to the neutral shared identity result if field names change.
## UI / Surface Guardrail Plan
- **Guardrail scope**: changed surfaces
- **Native vs custom classification summary**: mixed native Filament resource plus existing custom onboarding wizard
- **Shared-family relevance**: provider-connections resource family, managed-environment related context, onboarding readiness/provider summary, shared provider-operation feedback
- **State layers in scope**: page, detail, modal, Livewire state, related-context summaries
- **Audience modes in scope**: operator-MSP, support-platform
- **Decision/diagnostic/raw hierarchy plan**: decision-first shared target-scope summary, diagnostics-second readiness and blocked-reason detail, provider-raw/profile detail third and explicitly nested
- **Raw/support gating plan**: capability-gated or contextual-only provider profile detail using existing provider-context metadata visibility
- **One-primary-action / duplicate-truth control**: `ProviderConnectionSurfaceSummary` stays the one shared summary contract so provider-connections, onboarding, and related context do not invent parallel identity stories
- **Handling modes by drift class or surface**: review-mandatory
- **Repository-signal treatment**: review-mandatory until shared seams stop exposing Microsoft field names as primary contract truth
- **Special surface test profiles**: standard-native-filament, workflow-hub, global-context-shell
- **Required tests or manual smoke**: functional-core, state-contract, manual-smoke
- **Exception path and spread control**: none; the slice removes Microsoft-shaped spread from platform-core seams instead of adding a new exception
- **Active feature PR close-out entry**: Guardrail
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: yes
- **Systems touched**: provider connection resolution, identity resolution, target-scope normalization, provider-connection surface summaries, onboarding readiness summaries, provider-operation start context, provider boundary catalog, and provider-owned consent/runtime consumers
- **Shared abstractions reused**: `ProviderConnectionTargetScopeDescriptor`, `ProviderConnectionTargetScopeNormalizer`, `ProviderConnectionSurfaceSummary`, `ProviderConnectionResolution`, `ProviderIdentityResolution`, `ProviderOperationStartGate`, `ProviderOperationStartResultPresenter`, `OperationUxPresenter`, and the existing `ProviderConnectionResource` surface contract
- **New abstraction introduced? why?**: none planned; the existing target-scope and identity seams are sufficient once their field ownership and vocabulary are corrected
- **Why the existing abstraction was sufficient or insufficient**: the repo already has the right seams and summary objects. What is insufficient is the Microsoft-shaped payload and naming that still flows through them.
- **Bounded deviation / spread control**: Microsoft-specific consent URL, authority, redirect, and profile identifiers may remain in provider-owned nested metadata and provider-runtime seams only; they must not remain the primary shared contract fields
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: yes, start and blocked context only
- **Central contract reused**: `ProviderOperationStartGate`, `ProviderOperationStartResultPresenter`, `OperationUxPresenter`, and the existing `OperationRunService` lifecycle path
- **Delegated UX behaviors**: queued or blocked start-state messaging, dedupe-or-scope-busy outcomes, run creation identity, and start-result presentation remain on the shared provider-operation path
- **Surface-owned behavior kept local**: `ProviderConnectionResource` and `ManagedTenantOnboardingWizard` continue to own only connection selection, initiation inputs, and follow-up link placement
- **Queued DB-notification policy**: `N/A` - unchanged shared policy
- **Terminal notification path**: existing central lifecycle mechanism
- **Exception path**: none
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: yes
- **Provider-owned seams**: Microsoft admin-consent URL shaping, Microsoft portal or profile disclosure, Graph runtime option mapping, and provider-context detail visibility
- **Platform-core seams**: `provider.connection_resolution`, `provider.identity_resolution`, `provider.operation_start_gate`, target-scope descriptor/normalizer, surface-summary reuse, and shared run or audit context
- **Neutral platform terms / contracts preserved**: `provider connection`, `target scope`, `scope kind`, `scope identifier`, `scope display name`, `effective client identity`, `credential source`, `provider profile`, `provider context`, `workspace`, and `managed environment`
- **Retained provider-specific semantics and why**: Microsoft tenant identifiers, authority tenant, redirect URI, required consent flow, and Graph runtime details remain necessary for the current provider implementation. They stay nested under provider-owned metadata or provider-runtime seams rather than becoming platform-core contract keys.
- **Bounded extraction or follow-up path**: Specs `282` through `287` remain the follow-up path for artifact retargeting, capability registry, taxonomy, RBAC, copy neutralization, and cutover quality gates
## Constitution Check
*GATE: Must pass before implementation begins and again after the design artifacts are complete.*
- Inventory-first / snapshot truth: PASS. The slice changes shared provider-boundary contracts only; inventory and snapshot truth are unchanged.
- Read/write separation: PASS. No new write workflow is introduced; existing provider operations keep their current confirmation, audit, and run-observability path.
- Graph contract path: PASS. No Graph endpoint or contract-registry work is added; provider-owned Graph option shaping remains behind the current provider runtime seam.
- Deterministic capabilities: PASS. Capability requirements remain the current registry-backed provider capabilities.
- RBAC-UX plane separation: PASS. `/admin` versus `/system` remains unchanged.
- Workspace isolation: PASS. `ProviderConnection` remains workspace-owned and environment-scoped; no access-boundary change is planned.
- Managed-environment isolation: PASS. Provider-connection resolution and onboarding continue to require the current managed-environment boundary.
- Destructive action discipline: PASS by preservation. Existing confirmation-protected provider-connection mutations remain confirmation-protected and server-authorized.
- Global search safety: PASS. `ProviderConnectionResource` already remains non-globally-searchable and keeps valid view/edit pages.
- OperationRun / Ops-UX: PASS. The slice reuses the shared provider-operation start path and changes only the context contract it records.
- Data minimization: PASS. No new persistence or provider-profile table is introduced; provider-specific detail remains nested metadata.
- Test governance: PASS. Proof remains bounded to focused feature coverage, one browser smoke, and one leak-guard family.
- Proportionality / no premature abstraction: PASS. The plan reuses the current seams instead of introducing a new provider framework, registry, or profile entity.
- Persisted truth / behavioral state: PASS. No new table, enum family, or taxonomy is introduced.
- UI semantics / shared pattern first / Filament-native UI: PASS. Existing resource and wizard surfaces remain the first path and keep one shared summary adapter.
- Provider boundary: PASS with implementation condition. Platform-core seams must stop treating `tenantContext` and `target_scope.entra_tenant_id` as shared truth; Microsoft detail remains explicit and nested.
**Gate evaluation**: PASS.
**Post-design re-check**: PASS while `research.md`, `data-model.md`, `quickstart.md`, `contracts/provider-connection-scope.logical.openapi.yaml`, and `checklists/requirements.md` stay aligned on the same neutral `target_scope`, effective-client-identity, provider-profile disclosure, and proving-command contract.
## Test Governance Check
- **Test purpose / classification by changed surface**: Feature, Browser
- **Affected validation lanes**: fast-feedback, confidence, browser
- **Why this lane mix is the narrowest sufficient proof**: the change is a shared-contract extraction across resolvers, start-gate context, and two operator-facing summary consumers. Focused feature coverage proves the contract and guard behavior, and one browser smoke proves the resource plus onboarding surfaces still tell the same connection story in the live shell.
- **Narrowest proving command(s)**:
- `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)`
- **Fixture / helper / factory / seed / context cost risks**: moderate because proof needs workspace, managed environment, provider connection, optional provider credential, and operation-run fixtures without broadening shared defaults
- **Expensive defaults or shared helper growth introduced?**: no; any new provider fixture helper should remain opt-in and feature-local
- **Heavy-family additions, promotions, or visibility changes**: none beyond one slice-specific browser smoke already justified in the spec
- **Surface-class relief / special coverage rule**: standard-native-filament relief for the resource and one workflow-hub browser proof for onboarding continuity
- **Closing validation and reviewer handoff**: rerun the exact commands above, verify that shared contract outputs now use neutral `target_scope` keys, verify that `ProviderIdentityResolution` no longer uses a shared `tenantContext` field name for platform-core truth, verify that `ProviderOperationStartGate` stopped writing shared `target_scope.entra_tenant_id`, verify that Microsoft detail appears only inside provider-owned context or profile blocks, verify that `ProviderConnectionResource` stays non-globally-searchable with View/Edit pages intact, confirm the existing destructive actions still require confirmation plus server authorization, and confirm provider registration plus asset strategy remain unchanged
- **Budget / baseline / trend follow-up**: contained feature-local increase only
- **Review-stop questions**: did a new provider-profile table or registry appear, did shared seams keep `tenantContext` or `target_scope.entra_tenant_id` as primary truth, did provider-specific profile detail escape nested metadata, did onboarding and provider-connections diverge into separate summary contracts, did the slice absorb deferred Specs `282` through `287`
- **Escalation path**: `reject-or-split` if implementation introduces new persistence, shared compatibility aliases, routing cutover work, RBAC redesign, or provider-framework machinery
- **Active feature PR close-out entry**: Guardrail
- **Why no dedicated follow-up spec is needed**: the adjacent follow-up work is already reserved as Specs `282` through `287`; 281 only needs the bounded contract extraction itself
## Review Checklist Status
- **Review checklist artifact**: `checklists/requirements.md`
- **Review outcome class**: `implementation-ready`
- **Workflow outcome**: `keep`
- **Test-governance outcome**: `keep`
- **Escalation rule**: if implementation preserves shared Microsoft-shaped contract fields, adds new provider persistence, or absorbs routing, registry, taxonomy, RBAC, or copy-neutralization work, flip the workflow outcome to `split` or `reject-or-split`
## Rollout Considerations
- Land target-scope extraction, identity-result reshaping, surface-summary convergence, and provider-operation context updates as one bounded implementation slice so platform-core truth changes atomically.
- Retarget provider-owned consumers such as admin-consent URL shaping only after the shared identity result is finalized, not as a separate second contract.
- Keep managed-environment related-context summaries and onboarding readiness on the same shared summary adapter before polishing any additional copy.
- Keep Spec `280` route work separate; `281` should consume the existing surfaces and not redefine their route ownership.
## Risk Controls
- Reject any implementation that reintroduces the stale `tenant_id` to `managed_environment_id` candidate work on `ProviderConnection`.
- Reject any implementation that adds a provider-profile table, registry, capability engine, package abstraction, or artifact taxonomy.
- Reject any implementation that leaves shared `tenantContext` or shared `target_scope.entra_tenant_id` in platform-core contracts as compatibility aliases.
- Reject any implementation that duplicates summary logic outside `ProviderConnectionSurfaceSummary` for provider-connections, onboarding, or related context.
- Reject any implementation that moves provider registration out of `apps/platform/bootstrap/providers.php` or adds new Filament asset registration for this slice.
## Research & Design Outputs
- `research.md` records the bounded extraction decisions for persisted truth, shared target-scope ownership, shared identity-result ownership, provider-owned Microsoft profile disclosure, start-gate context shape, and proof strategy.
- `data-model.md` captures the unchanged persisted truth plus the derived `target_scope`, effective-client-identity, provider-context, surface-summary, onboarding-readiness, and run-context contracts.
- `quickstart.md` gives reviewers the bounded package review flow and the exact proving commands.
- `contracts/provider-connection-scope.logical.openapi.yaml` captures the conceptual summary, provider-profile, onboarding-readiness, and operation-start contracts with the neutral shared `target_scope` schema.
- `checklists/requirements.md` records package readiness, boundedness, and outcome state.
## Project Structure
### Documentation (this feature)
```text
specs/281-provider-connection-scope/
├── checklists/
│ └── requirements.md
├── contracts/
│ └── provider-connection-scope.logical.openapi.yaml
├── data-model.md
├── plan.md
├── quickstart.md
├── research.md
├── spec.md
└── tasks.md
```
### Source Code (expected implementation surfaces)
```text
apps/platform/
├── app/
│ ├── Filament/
│ │ ├── Pages/
│ │ │ └── Workspaces/
│ │ │ └── ManagedTenantOnboardingWizard.php
│ │ └── Resources/
│ │ ├── ProviderConnectionResource.php
│ │ ├── TenantResource.php
│ │ └── ProviderConnectionResource/
│ │ └── Pages/
│ ├── Models/
│ │ └── ProviderConnection.php
│ ├── Services/
│ │ └── Providers/
│ │ ├── AdminConsentUrlFactory.php
│ │ ├── CredentialManager.php
│ │ ├── PlatformProviderIdentityResolver.php
│ │ ├── ProviderConnectionResolution.php
│ │ ├── ProviderConnectionResolver.php
│ │ ├── ProviderGateway.php
│ │ ├── ProviderIdentityResolution.php
│ │ ├── ProviderIdentityResolver.php
│ │ └── ProviderOperationStartGate.php
│ └── Support/
│ └── Providers/
│ ├── Boundary/
│ │ └── ProviderBoundaryCatalog.php
│ └── TargetScope/
│ ├── ProviderConnectionSurfaceSummary.php
│ ├── ProviderConnectionTargetScopeDescriptor.php
│ ├── ProviderConnectionTargetScopeNormalizer.php
│ └── ProviderIdentityContextMetadata.php
├── bootstrap/
│ └── providers.php
└── config/
└── provider_boundaries.php
```
**Structure decision**: keep the documentation package self-contained under `specs/281-provider-connection-scope/`; later implementation should update the existing provider resolution, summary, onboarding, and operation-start seams in place instead of introducing a parallel provider-contract subsystem.
## Complexity Tracking
No constitution violation or bloat exception is introduced by the plan. The slice removes Microsoft-shaped leakage from existing platform-core seams and adds no new persistence, abstraction family, taxonomy, or framework.
## Proportionality Review
- **Current operator problem**: the platform-core provider boundary still forces operators, audit consumers, and operation-run context to rely on Microsoft-shaped identity and scope fields even though provider connections are already modeled as managed-environment-scoped records.
- **Existing structure is insufficient because**: the current repo already has target-scope and summary helpers, but the remaining shared field names and run-context keys still encode Microsoft semantics as generic truth.
- **Narrowest correct implementation**: reuse the existing descriptor, normalizer, identity result, resource summary, onboarding readiness, and start-gate seams while replacing the Microsoft-shaped shared contract fields with neutral `target_scope` and effective-client-identity outputs.
- **Ownership cost created**: focused contract, summary, and proof updates across the listed provider seams and their tests.
- **Alternative intentionally rejected**: a new provider-profile table, provider registry, capability engine, or broader multi-provider identity framework, because none are required by current-release truth.
- **Release truth**: current-release truth; this is a bounded extraction of an already-verified hotspot, not future-provider platform preparation.