TenantAtlas/specs/237-provider-boundary-hardening/tasks.md
ahmido bd26e209de
Some checks failed
Main Confidence / confidence (push) Failing after 57s
feat: harden provider boundaries (#273)
## Summary
- add the provider boundary catalog, boundary support types, and guardrails for platform-core versus provider-owned seams
- harden provider gateway, identity resolution, operation registry, and start-gate behavior to require explicit provider bindings
- add unit and feature coverage for boundary classification, runtime preservation, unsupported paths, and platform-core leakage guards
- add the full Spec Kit artifact set for spec 237 and update roadmap/spec-candidate tracking

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderBoundaryClassificationTest.php tests/Unit/Providers/ProviderBoundaryGuardrailTest.php tests/Feature/Providers/ProviderBoundaryHardeningTest.php tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Providers/ProviderGatewayTest.php tests/Unit/Providers/ProviderIdentityResolverTest.php tests/Unit/Providers/ProviderOperationStartGateTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- browser smoke: `http://localhost/admin/provider-connections?tenant_id=18000000-0000-4000-8000-000000000180` loaded with the local smoke user, the empty-state CTA reached the canonical create route, and cancel returned to the scoped list

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #273
2026-04-24 21:05:37 +00:00

227 lines
16 KiB
Markdown

---
description: "Task list for Provider Boundary Hardening"
---
# Tasks: Provider Boundary Hardening
**Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/`
**Prerequisites**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/plan.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/spec.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/research.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/data-model.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/contracts/`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/237-provider-boundary-hardening/quickstart.md`
**Tests**: REQUIRED (Pest) for runtime behavior changes; keep proof in the narrow `Unit` and `Feature` lanes named in the plan
**Operations**: No new `OperationRun` type or new monitoring surface is introduced; preserve current `ProviderOperationStartGate` behavior while making provider binding explicit
**RBAC**: No authorization plane changes are planned; preserve existing tenant and workspace enforcement on touched provider-backed flows
**Provider Boundary**: Every touched seam must be classified as `provider_owned` or `platform_core`, and any retained Microsoft-shaped behavior must remain explicitly bounded as documented seam metadata rather than a third ownership class
**Organization**: Tasks are grouped by user story so the seam-classification slice, runtime hardening slice, and guardrail slice can be delivered and validated incrementally.
## Test Governance Checklist
- [X] Lane assignment stays `Unit` plus `Feature` and remains the narrowest sufficient proof for the changed behavior.
- [X] New or changed tests stay in the existing provider test families; no browser or heavy-governance lane is added.
- [X] Shared helpers, factories, fixtures, and provider context defaults must stay cheap by default; do not introduce a default multi-provider harness.
- [X] Planned validation commands must cover the boundary catalog, runtime preservation, unsupported-path handling, and registry split without widening scope.
- [X] Surface test profile remains `N/A` because this slice adds no new operator-facing screen.
- [X] Any remaining Microsoft-first hotspot must resolve as `document-in-feature` or `follow-up-spec`, not as silent platform-core truth.
## Phase 1: Setup (Shared Context)
**Purpose**: Confirm the baseline hotspots, current proof lanes, and existing guard patterns before implementation starts.
- [X] T001 Review the current hotspot seams in `apps/platform/app/Services/Providers/ProviderGateway.php`, `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`, `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`, and `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`
- [X] T002 Run the existing provider baseline tests for `apps/platform/tests/Unit/Providers/ProviderGatewayTest.php` and `apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php`
- [X] T003 [P] Review the existing boundary-guard patterns in `apps/platform/tests/Feature/Guards/NoLegacyTenantGraphOptionsTest.php` and `apps/platform/tests/Feature/Guards/NoLegacyTenantProviderFallbackTest.php`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Add the shared boundary catalog primitives that every user story depends on.
**⚠️ CRITICAL**: No user story work should start until these tasks are complete.
- [X] T004 Create the seam ownership catalog scaffold in `apps/platform/config/provider_boundaries.php`
- [X] T005 [P] Add the ownership enum in `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryOwner.php`
- [X] T006 [P] Add the seam descriptor value object in `apps/platform/app/Support/Providers/Boundary/ProviderBoundarySeam.php`
- [X] T007 Implement deterministic catalog lookup in `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`
**Checkpoint**: Shared boundary primitives exist; user story work can now build on one explicit source of truth.
---
## Phase 3: User Story 1 - Classify Shared Seams Before Extending Them (Priority: P1) 🎯 MVP
**Goal**: Make the first high-risk shared provider seams explicitly classifiable so contributors can tell where Microsoft-specific semantics are allowed.
**Independent Test**: Run `tests/Unit/Providers/ProviderBoundaryClassificationTest.php` and verify the authoritative seam keys `provider.gateway_runtime`, `provider.identity_resolution`, `provider.connection_resolution`, `provider.operation_registry`, and `provider.operation_start_gate` resolve to the intended owner classification and exception metadata.
### Tests for User Story 1
- [X] T008 [P] [US1] Add seam classification coverage in `apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php`
### Implementation for User Story 1
- [X] T009 [US1] Populate the authoritative first-slice seam entries `provider.gateway_runtime`, `provider.identity_resolution`, `provider.connection_resolution`, `provider.operation_registry`, and `provider.operation_start_gate` in `apps/platform/config/provider_boundaries.php`
- [X] T010 [US1] Implement seam hydration and ownership assertions in `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`
- [X] T011 [US1] Encode neutral terms, retained provider semantics, and follow-up actions in `apps/platform/config/provider_boundaries.php` and `apps/platform/app/Support/Providers/Boundary/ProviderBoundarySeam.php`
- [X] T012 [US1] Align the seam catalog shape with `specs/237-provider-boundary-hardening/contracts/provider-boundary-hardening.logical.openapi.yaml` through `apps/platform/config/provider_boundaries.php` and `apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php`
- [X] T013 [US1] Run the story proof lane for `apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php`
**Checkpoint**: The seam catalog is explicit, deterministic, and independently testable.
---
## Phase 4: User Story 2 - Keep Microsoft Truth Bounded Without Breaking Current Behavior (Priority: P1)
**Goal**: Move Graph-shaped runtime behavior behind provider-owned seams while preserving current Microsoft-backed flows and making unsupported paths explicit.
**Independent Test**: Run the runtime regression and unsupported-path tests to confirm current Microsoft behavior still succeeds and platform-core seams no longer own Graph option shaping.
### Tests for User Story 2
- [X] T014 [P] [US2] Extend provider runtime regression coverage in `apps/platform/tests/Unit/Providers/ProviderGatewayTest.php` and `apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php`
- [X] T015 [P] [US2] Add Microsoft runtime preservation coverage in `apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php`
- [X] T016 [P] [US2] Add explicit unsupported-path coverage in `apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php`
### Implementation for User Story 2
- [X] T017 [US2] Remove Graph request-option shaping from `apps/platform/app/Services/Providers/ProviderIdentityResolution.php`
- [X] T018 [US2] Move Graph option assembly into `apps/platform/app/Services/Providers/ProviderGateway.php` and `apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php`
- [X] T019 [US2] Preserve bounded Microsoft-first identity exceptions in `apps/platform/app/Services/Providers/ProviderIdentityResolver.php`, `apps/platform/app/Services/Providers/PlatformProviderIdentityResolver.php`, `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`, and `apps/platform/app/Services/Providers/ProviderConnectionResolution.php`
- [X] T020 [US2] Make the current-release exception metadata explicit in `apps/platform/config/provider_boundaries.php` and `apps/platform/app/Support/Providers/Boundary/ProviderBoundarySeam.php`
- [X] T021 [US2] Run the story proof lane for `apps/platform/tests/Unit/Providers/ProviderGatewayTest.php`, `apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php`, `apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php`, and `apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php`
**Checkpoint**: Current Microsoft-backed runtime behavior still works, and the shared identity path no longer emits Graph-shaped platform-core truth.
---
## Phase 5: User Story 3 - Catch New Provider Leakage in Review and CI (Priority: P2)
**Goal**: Split shared operation definition from provider binding and add focused guardrails that fail when provider-specific semantics leak back into platform-core seams.
**Independent Test**: Run the guardrail and start-gate tests to confirm platform-core/provider-owned boundaries are enforced and unsupported bindings fail explicitly.
### Tests for User Story 3
- [X] T022 [P] [US3] Add a CI boundary leak guard in `apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php`
- [X] T023 [P] [US3] Add boundary leak and exception guard coverage in `apps/platform/tests/Unit/Providers/ProviderBoundaryGuardrailTest.php`
- [X] T024 [P] [US3] Extend provider binding and unsupported-start coverage in `apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php`
### Implementation for User Story 3
- [X] T025 [US3] Split platform-core operation definition from provider binding in `apps/platform/app/Services/Providers/ProviderOperationRegistry.php`
- [X] T026 [US3] Consume explicit bindings and unsupported outcomes in `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`
- [X] T027 [US3] Re-use existing unsupported-path reason handling, or add one narrow boundary violation and unsupported-binding reason in `apps/platform/app/Support/Providers/ProviderReasonCodes.php` only if the explicit shared-boundary outcome cannot be expressed without it
- [X] T028 [US3] Record binding status, handler notes, and exception notes for first-slice operations in `apps/platform/app/Services/Providers/ProviderOperationRegistry.php` and `apps/platform/config/provider_boundaries.php`
- [X] T029 [US3] Align the operation definition and binding split with `specs/237-provider-boundary-hardening/contracts/provider-boundary-hardening.logical.openapi.yaml` through `apps/platform/app/Services/Providers/ProviderOperationRegistry.php` and `apps/platform/app/Services/Providers/ProviderOperationStartGate.php`
- [X] T030 [US3] Run the story proof lane for `apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php`, `apps/platform/tests/Unit/Providers/ProviderBoundaryGuardrailTest.php`, `apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php`, and `apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php`
**Checkpoint**: Provider binding is explicit, guardrails fail on new leakage, and shared orchestration no longer silently defaults to Microsoft-first behavior.
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Finalize validation, formatting, and guardrail close-out across the full slice.
- [X] T031 [P] Refresh the implementation notes, validation commands, and bounded follow-up status in `specs/237-provider-boundary-hardening/quickstart.md`
- [X] T032 Run formatting for `apps/platform/app/Support/Providers/Boundary/`, `apps/platform/app/Services/Providers/`, `apps/platform/tests/Unit/Providers/`, and `apps/platform/tests/Feature/Guards/` with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- [X] T033 Run the final narrow validation lane for `apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php`, `apps/platform/tests/Unit/Providers/ProviderBoundaryGuardrailTest.php`, `apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php`, `apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php`, and `apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php`
- [X] T034 Record the guardrail close-out, `document-in-feature` decision, and deferred identity-neutrality follow-up in `specs/237-provider-boundary-hardening/quickstart.md`
---
## Dependencies & Execution Order
### User Story Dependency Graph
```text
Phase 1 (Setup)
Phase 2 (Foundation: seam catalog primitives)
US1 (Seam classification)
US2 (Runtime hardening and explicit exceptions)
US3 (Registry split and guardrails)
Phase 6 (Polish)
```
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies; starts immediately.
- **Foundational (Phase 2)**: Depends on Setup; blocks all user story work.
- **User Story 1 (Phase 3)**: Depends on the boundary catalog primitives from Phase 2.
- **User Story 2 (Phase 4)**: Depends on US1 because runtime hardening consumes the explicit seam ownership catalog.
- **User Story 3 (Phase 5)**: Depends on US1 and US2 because registry guardrails must reflect the classified seams and the hardened runtime path.
- **Polish (Phase 6)**: Depends on all desired user stories being complete.
### Parallel Opportunities
- Phase 2 tasks `T005` and `T006` can run in parallel because they touch different support classes.
- US1 tasks `T008` and `T010` can run in parallel after the catalog scaffold exists because the test file and catalog service are separate files.
- US2 tasks `T014`, `T015`, and `T016` can run in parallel because they cover different test files.
- US3 tasks `T022`, `T023`, and `T024` can run in parallel because they extend separate guard and unit test files.
- Phase 6 tasks `T031` and `T032` can run in parallel because they touch documentation and formatting independently.
---
## Parallel Example: User Story 1
```bash
Task: "Add seam classification coverage in apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php"
Task: "Implement seam hydration and ownership assertions in apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php"
```
## Parallel Example: User Story 2
```bash
Task: "Extend provider runtime regression coverage in apps/platform/tests/Unit/Providers/ProviderGatewayTest.php and apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php"
Task: "Add Microsoft runtime preservation coverage in apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php"
Task: "Add explicit unsupported-path coverage in apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php"
```
## Parallel Example: User Story 3
```bash
Task: "Add boundary leak and exception guard coverage in apps/platform/tests/Unit/Providers/ProviderBoundaryGuardrailTest.php"
Task: "Extend provider binding and unsupported-start coverage in apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php"
Task: "Add a CI boundary leak guard in apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php"
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational seam catalog primitives.
3. Complete Phase 3: User Story 1.
4. Stop and validate `apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php`.
5. Review whether the first-slice seam catalog is explicit enough before widening into runtime cleanup.
### Incremental Delivery
1. Setup + Foundation establish one explicit boundary source of truth.
2. US1 delivers seam classification and explicit exception metadata documentation.
3. US2 hardens the shared runtime path while preserving current Microsoft-backed behavior.
4. US3 makes provider binding explicit and adds CI-proof guardrails.
5. Polish closes formatting, validation, and the documented follow-up boundary.
### Suggested MVP Scope
The narrowest shippable increment is Phase 1, Phase 2, and Phase 3 only.
---
## Notes
- `[P]` tasks touch different files and can be worked independently.
- `[US1]`, `[US2]`, and `[US3]` map directly to the user stories in `spec.md`.
- Keep provider-specific semantics bounded to provider-owned seams; do not introduce a second-provider runtime while completing these tasks.
- Use the Sail-prefixed validation commands from `specs/237-provider-boundary-hardening/quickstart.md` when executing the proof lanes.