TenantAtlas/specs/427-exchange-teams-verified-source-contract-enablement/plan.md
ahmido bfb52b84d6 feat: implement spec 427 source contract enablement (#494)
Automated PR for spec 427 Exchange Teams verified source contract enablement.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #494
2026-07-03 23:12:45 +00:00

218 lines
16 KiB
Markdown

# Implementation Plan: Spec 427 - Exchange / Teams Verified Source Contract Enablement
**Branch**: `427-exchange-teams-verified-source-contract-enablement` | **Date**: 2026-07-03 | **Spec**: `specs/427-exchange-teams-verified-source-contract-enablement/spec.md`
**Input**: Feature specification from `/specs/427-exchange-teams-verified-source-contract-enablement/spec.md`
## Summary
Verify and enable precise source-contract states for exactly four Exchange/Teams Coverage v2 resource types: `transportRule`, `acceptedDomain`, `appPermissionPolicy`, and `meetingPolicy`. The implementation must use the existing Coverage v2 source-contract resolver/registry path, record verified-pending-capture or exact blocker reasons, and prove that no evidence, compare/render, certification, restore, customer output, UI, or provider capture is promoted by this spec.
## Technical Context
**Language/Version**: PHP 8.4.15, Laravel 12, Filament 5, Livewire 4
**Primary Dependencies**: Existing Coverage v2 Tenant Configuration services, `GraphClientInterface` / repo provider abstraction, Pest 4
**Storage**: PostgreSQL via existing Coverage v2 tables/metadata; no new table by default
**Testing**: Pest 4 unit and feature tests; browser N/A by default
**Validation Lanes**: focused fast-feedback/confidence files; no browser lane unless the spec is amended for UI
**Target Platform**: Laravel monolith under `apps/platform`
**Project Type**: Web application / Laravel monolith
**Performance Goals**: No real provider calls; resolver decisions must be deterministic and cheap
**Constraints**: no remote capture, no evidence promotion, no UI, no `tenant_id`, no endpoint guessing, no provider permission widening
**Scale/Scope**: exactly four repo-canonical resource types; no optional Exchange/Teams expansion
## UI / Surface Guardrail Plan
- **Guardrail scope**: no operator-facing surface change.
- **Affected routes/pages/actions/states/navigation/panel/provider surfaces**: N/A.
- **No-impact class, if applicable**: backend/internal contract metadata and tests only.
- **Native vs custom classification summary**: N/A.
- **Shared-family relevance**: Coverage v2 contract/metadata family only; no rendered shared detail family.
- **State layers in scope**: none for UI; internal source-contract state/reason metadata only.
- **Audience modes in scope**: N/A.
- **Decision/diagnostic/raw hierarchy plan**: N/A for UI; raw/support data stays out of default output/logs.
- **Raw/support gating plan**: raw payloads and secrets are not displayed/logged.
- **One-primary-action / duplicate-truth control**: N/A.
- **Handling modes by drift class or surface**: report-only N/A path for no rendered UI.
- **Repository-signal treatment**: no UI signal expected.
- **Special surface test profiles**: N/A.
- **Required tests or manual smoke**: functional core tests only; browser `N/A - no rendered UI surface changed`.
- **Exception path and spread control**: none.
- **Active feature PR close-out entry**: Guardrail / Exception / Smoke Coverage: `N/A - no rendered UI surface changed`.
- **UI/Productization coverage decision**: No UI surface impact.
- **Coverage artifacts to update**: none.
- **No-impact rationale**: Contract verification is internal prerequisite truth and requires no reachable rendered surface.
- **Navigation / Filament provider-panel handling**: no panel/provider change.
- **Screenshot or page-report need**: no.
## Product Surface Contract Plan
- **Product Surface Contract reference**: N/A - no rendered product surface changed.
- **No-legacy posture**: canonical replacement / no compatibility exception.
- **Page archetype and surface budget plan**: N/A.
- **Technical Annex and deep-link demotion plan**: N/A for UI. Contract proof stays in tests/implementation report; raw payloads, source keys, permissions, and blocker diagnostics are not product content.
- **Canonical status vocabulary plan**: N/A for rendered UI. Internal source-contract states are prerequisite states, not product badges.
- **Product Surface exceptions**: none.
- **Browser verification plan**: `N/A - no rendered UI surface changed`.
- **Human Product Sanity plan**: N/A.
- **Visible complexity outcome target**: neutral.
- **Implementation report target**: `specs/427-exchange-teams-verified-source-contract-enablement/implementation-report.md`.
## Filament / Livewire / Deployment Posture
- **Livewire v4 compliance**: Livewire v4.x confirmed; no Livewire code change planned.
- **Panel provider registration location**: no panel change; Laravel providers remain in `apps/platform/bootstrap/providers.php`.
- **Global search posture**: no Filament Resource/global search behavior changed.
- **Destructive/high-impact action posture**: none; no UI or mutation action added.
- **Asset strategy**: no assets; no new `filament:assets` requirement.
- **Testing plan**: resolver, contract metadata, fail-safe/no-promotion, identity, redaction, no-tenant-id, no-mini-platform, and regression tests.
- **Deployment impact**: no env vars, migrations, queues, scheduler, storage, or assets by default. If implementation discovers a required migration or provider permission productization, stop and amend this spec first.
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: yes.
- **Systems touched**: `apps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.php`, `CoverageSourceContractDecision`, `ResourceTypeRegistry`, `apps/platform/config/graph_contracts.php` only when verified repo-safe contracts exist, identity registry/resolver, claim guard, redaction helpers, and focused tests.
- **Shared abstractions reused**: existing Coverage v2 source-contract resolver/registry, `GraphClientInterface` / repo provider abstraction, identity strategy registry, and Claim Guard.
- **New abstraction introduced? why?**: none planned. A small value object/helper is allowed only if it replaces ambiguity in the existing resolver and remains proportional.
- **Why the existing abstraction was sufficient or insufficient**: Existing resolver decides captured vs blocked, but current generic missing-contract behavior is too coarse for the next Exchange/Teams evidence sequence. The plan adds precise metadata/state inside the existing path rather than a new platform.
- **Bounded deviation / spread control**: source-contract state/reason values are limited to four target types and must have direct behavior/test consequences.
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: no.
- **Central contract reused**: N/A.
- **Delegated UX behaviors**: N/A.
- **Surface-owned behavior kept local**: none.
- **Queued DB-notification policy**: N/A.
- **Terminal notification path**: N/A.
- **Exception path**: none.
No remote capture, provider operation, queued work, or OperationRun creation is in scope. If live provider verification becomes necessary, implementation must stop and the spec must be amended.
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: yes.
- **Provider-owned seams**: Exchange/Teams source contract names, Microsoft permission names, response shapes, provider-native IDs, and source versions.
- **Platform-core seams**: Coverage v2 contract state/blocker semantics, capture eligibility, claim safety, evidence promotion rules, workspace/managed-environment/provider-connection ownership.
- **Neutral platform terms / contracts preserved**: workspace, managed environment, provider connection, resource type, source contract, capture eligibility, blocker reason, evidence, claim state.
- **Retained provider-specific semantics and why**: Exchange/Teams labels and Microsoft contract metadata are necessary to verify these four concrete contracts, but remain provider-owned metadata.
- **Bounded extraction or follow-up path**: document-in-feature for any contained provider-specific blocker; follow-up-spec only if provider permission productization or contract verification requires a broader product decision.
## Constitution Check
- Inventory-first: no inventory/snapshot truth changes; source contracts remain prerequisites.
- Read/write separation: no write/change/provider capture action in scope.
- Graph contract path: any verified Graph source must be represented through existing contract registry/provider abstraction; direct HTTP and endpoint guessing are forbidden.
- Deterministic capabilities: contract states and blocker reasons must be testable.
- RBAC-UX: no new UI/action; provider-context checks must preserve existing workspace/environment/provider scope if touched.
- Workspace isolation: any provider-context verification must remain same workspace and managed environment.
- Tenant isolation / SCOPE-001: no `tenant_id`; provider-native tenant IDs remain metadata only.
- Run observability: no remote/queued work; OperationRun is N/A.
- Data minimization: no raw provider payload, secrets, or raw permission context in logs/default output.
- Test governance: focused Unit/Feature tests are the narrowest proof; browser N/A.
- Proportionality: bounded contract-state/reason metadata is justified by false-readiness prevention and immediate prerequisite value.
- No premature abstraction: extend existing resolver/registry; no Exchange/Teams mini-platform.
- Persisted truth: no new persisted entity by default.
- Behavioral state: every new state/reason changes a blocker/follow-up action; presentation-only labels are forbidden.
- Shared pattern first: reuse Coverage v2 resolver/registry and claim guard.
- Provider boundary: provider details remain provider-owned metadata.
- UI/Productization coverage: no rendered UI; Product Surface N/A.
## Test Governance Check
- **Test purpose / classification by changed surface**: Unit for resolver/metadata/state mapping; Feature for no-promotion, no-tenant-id, no-mini-platform, and regressions.
- **Affected validation lanes**: focused fast-feedback/confidence.
- **Why this lane mix is the narrowest sufficient proof**: No rendered UI and no real provider calls are in scope; service/config behavior can be proven with focused tests.
- **Narrowest proving command(s)**:
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec427ExchangeTeamsSourceContractStateTest.php tests/Unit/Support/TenantConfiguration/Spec427ExchangeTransportRuleContractTest.php tests/Unit/Support/TenantConfiguration/Spec427ExchangeAcceptedDomainContractTest.php tests/Unit/Support/TenantConfiguration/Spec427TeamsAppPermissionPolicyContractTest.php tests/Unit/Support/TenantConfiguration/Spec427TeamsMeetingPolicyContractTest.php tests/Unit/Support/TenantConfiguration/Spec427SourceContractPermissionMetadataTest.php tests/Unit/Support/TenantConfiguration/Spec427SourceContractResponseShapeTest.php tests/Unit/Support/TenantConfiguration/Spec427SourceContractIdentityHandoffTest.php tests/Unit/Support/TenantConfiguration/Spec427SourceContractRedactionTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec427ExchangeTeamsNoEvidencePromotionTest.php tests/Feature/TenantConfiguration/Spec427ExchangeTeamsNoCompareRenderCertificationTest.php tests/Feature/TenantConfiguration/Spec427ExchangeTeamsNoCustomerRestoreClaimTest.php tests/Feature/TenantConfiguration/Spec427ExchangeTeamsNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec427ExchangeTeamsNoMiniPlatformTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsSourceContractResolverTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsCoreEvidenceReadinessTest.php tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureSourceContractResolverTest.php tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php`
- **Fixture / helper / factory / seed / context cost risks**: local fake contract metadata/payload shapes only; no broader default setup.
- **Expensive defaults or shared helper growth introduced?**: no.
- **Heavy-family additions, promotions, or visibility changes**: none.
- **Surface-class relief / special coverage rule**: N/A - no rendered UI surface changed.
- **Closing validation and reviewer handoff**: implementation report must list exact commands, pass counts, and any Signal 9 direct-file fallback.
- **Budget / baseline / trend follow-up**: none expected.
- **Review-stop questions**: no endpoint guessing, no fake verified contract, no evidence promotion, no `tenant_id`, no hidden provider calls.
- **Escalation path**: document-in-feature for exact blocked contracts; follow-up-spec for provider permission productization or live capture.
- **Active feature PR close-out entry**: Guardrail / Exception / Smoke Coverage.
- **Why no dedicated follow-up spec is needed**: This spec is already the bounded source-contract prerequisite; broader promotions are listed as separate follow-ups.
## Project Structure
### Documentation (this feature)
```text
specs/427-exchange-teams-verified-source-contract-enablement/
|-- spec.md
|-- plan.md
|-- tasks.md
`-- checklists/
`-- requirements.md
```
### Source Code (likely affected during later implementation)
```text
apps/platform/
|-- app/
| |-- Services/TenantConfiguration/
| | |-- CoverageSourceContractResolver.php
| | |-- CoverageSourceContractDecision.php
| | |-- CoverageIdentityStrategyRegistry.php
| | `-- ClaimGuard.php
| `-- Support/TenantConfiguration/
| `-- CaptureOutcome.php
|-- config/
| `-- graph_contracts.php
`-- tests/
|-- Unit/Support/TenantConfiguration/
`-- Feature/TenantConfiguration/
```
**Structure Decision**: Keep all runtime work inside existing Coverage v2 Tenant Configuration services/config/tests. Do not create new base folders, Exchange/Teams table families, dashboards, routes, or provider subsystem.
## Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
| --- | --- | --- |
| Bounded source-contract state/reason vocabulary | Later evidence/certification specs need exact blockers and next actions | Generic `capture_blocked_missing_contract` cannot distinguish missing source, permission, beta-only, response shape, adapter, identity, or redaction blockers |
## Proportionality Review
- **Current operator problem**: Release reviewers need exact proof that Exchange/Teams contracts are verified or blocked before later evidence/certification claims.
- **Existing structure is insufficient because**: Existing generic blocked outcomes are safe but too coarse to unblock or intentionally defer later work.
- **Narrowest correct implementation**: Add precise state/reason metadata for four existing resource types in existing resolver/registry paths.
- **Ownership cost created**: Four per-type matrices, focused tests, and implementation-report proof.
- **Alternative intentionally rejected**: Leave all four as generic missing-contract blockers. Rejected because it would force future specs to rediscover blockers and risks endpoint guessing.
- **Release truth**: Current prerequisite truth for the immediate Coverage v2 Exchange/Teams sequence.
## Implementation Phases
### Phase 0 - Preflight
Confirm branch, dirty state, completed dependency status, target canonical names, current resolver behavior, no UI scope, no OperationRun scope, and no evidence promotion scope.
### Phase 1 - Target Mapping And Current-State Audit
Map spec labels to repo-canonical resource types and document current registry/source-contract/identity/readiness state for each.
### Phase 2 - Contract State Model
Add or confirm the bounded verified/blocker state model and mapping to repo-canonical outcomes/metadata, including the draft `graph_v1` label to repo-canonical `graph_v1_fallback` where applicable.
### Phase 3 - Per-Type Contract Verification
For each target type, verify source class, contract name/version, permission model, response shape, identity handoff, redaction rules, and final state. Block instead of guessing.
### Phase 4 - Resolver / Registry Integration
Integrate verified or blocked contract states through the existing resolver/registry path.
### Phase 5 - No-Promotion And Regression Proof
Prove no evidence, coverage promotion, compare/render, certification, restore, customer claim, `tenant_id`, or mini-platform appears. Re-run Spec 426/417/420 regressions.
### Phase 6 - Implementation Report
Record matrices, validation, Product Surface N/A, Filament/Livewire output contract, deployment impact, deferred work, and gate results.