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

16 KiB

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

  • Lane assignment stays Unit plus Feature and remains the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in the existing provider test families; no browser or heavy-governance lane is added.
  • Shared helpers, factories, fixtures, and provider context defaults must stay cheap by default; do not introduce a default multi-provider harness.
  • Planned validation commands must cover the boundary catalog, runtime preservation, unsupported-path handling, and registry split without widening scope.
  • Surface test profile remains N/A because this slice adds no new operator-facing screen.
  • 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.

  • 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
  • T002 Run the existing provider baseline tests for apps/platform/tests/Unit/Providers/ProviderGatewayTest.php and apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php
  • 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.

  • T004 Create the seam ownership catalog scaffold in apps/platform/config/provider_boundaries.php
  • T005 [P] Add the ownership enum in apps/platform/app/Support/Providers/Boundary/ProviderBoundaryOwner.php
  • T006 [P] Add the seam descriptor value object in apps/platform/app/Support/Providers/Boundary/ProviderBoundarySeam.php
  • 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

  • T008 [P] [US1] Add seam classification coverage in apps/platform/tests/Unit/Providers/ProviderBoundaryClassificationTest.php

Implementation for User Story 1

  • 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
  • T010 [US1] Implement seam hydration and ownership assertions in apps/platform/app/Support/Providers/Boundary/ProviderBoundaryCatalog.php
  • 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
  • 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
  • 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

  • T014 [P] [US2] Extend provider runtime regression coverage in apps/platform/tests/Unit/Providers/ProviderGatewayTest.php and apps/platform/tests/Unit/Providers/ProviderIdentityResolverTest.php
  • T015 [P] [US2] Add Microsoft runtime preservation coverage in apps/platform/tests/Feature/Providers/ProviderBoundaryHardeningTest.php
  • T016 [P] [US2] Add explicit unsupported-path coverage in apps/platform/tests/Feature/Providers/UnsupportedProviderBoundaryPathTest.php

Implementation for User Story 2

  • T017 [US2] Remove Graph request-option shaping from apps/platform/app/Services/Providers/ProviderIdentityResolution.php
  • T018 [US2] Move Graph option assembly into apps/platform/app/Services/Providers/ProviderGateway.php and apps/platform/app/Services/Providers/MicrosoftGraphOptionsResolver.php
  • 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
  • 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
  • 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

  • T022 [P] [US3] Add a CI boundary leak guard in apps/platform/tests/Feature/Guards/ProviderBoundaryPlatformCoreGuardTest.php
  • T023 [P] [US3] Add boundary leak and exception guard coverage in apps/platform/tests/Unit/Providers/ProviderBoundaryGuardrailTest.php
  • T024 [P] [US3] Extend provider binding and unsupported-start coverage in apps/platform/tests/Unit/Providers/ProviderOperationStartGateTest.php

Implementation for User Story 3

  • T025 [US3] Split platform-core operation definition from provider binding in apps/platform/app/Services/Providers/ProviderOperationRegistry.php
  • T026 [US3] Consume explicit bindings and unsupported outcomes in apps/platform/app/Services/Providers/ProviderOperationStartGate.php
  • 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
  • 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
  • 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
  • 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.

  • T031 [P] Refresh the implementation notes, validation commands, and bounded follow-up status in specs/237-provider-boundary-hardening/quickstart.md
  • 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
  • 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
  • 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

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

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

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

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.