TenantAtlas/specs/427-exchange-teams-verified-source-contract-enablement/spec.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

410 lines
38 KiB
Markdown

# Feature Specification: Spec 427 - Exchange / Teams Verified Source Contract Enablement
**Feature Branch**: `427-exchange-teams-verified-source-contract-enablement`
**Created**: 2026-07-03
**Status**: Draft
**Input**: Direct user-provided draft: "Spec 427 - Exchange/Teams Verified Source Contract Enablement"
## Selection And Preflight
- **Selected candidate**: Spec 427 - Exchange / Teams Verified Source Contract Enablement.
- **Source**: Direct user-provided draft attached in the 2026-07-03 session.
- **Why selected**: The active automatic candidate queue in `docs/product/spec-candidates.md` explicitly has no safe auto-prep target, but the user provided a manual/direct P0 candidate. Completed Spec 426 proves the four Exchange/Teams target types fail closed until verified source contracts exist, making this the next narrow unblocker.
- **Roadmap relationship**: Continues the Coverage v2 / Microsoft 365 sequence after Specs 414, 415, 417, 419, 420, and 426. It preserves the intended sequence: Spec 426 fail-safe proof -> Spec 427 verified source contracts -> later content-backed evidence promotion -> later compare/render promotion -> later certification.
- **Close alternatives deferred**: content-backed Exchange/Teams evidence promotion, compare/render promotion, certified compare pack, customer reports, Review Pack output, management PDF output, restore/apply flows, provider permission productization, broad Exchange/Teams coverage claims, optional resource expansion, Exchange/Teams dashboards, and customer-facing pages.
- **Completed-spec guardrail result**: Specs 414, 415, 417, 419, 420, and 426 are completed/validated dependency context only. Their implementation close-out, validation results, browser proof, and completed task markers must not be rewritten by this spec.
- **Current branch before Spec Kit execution**: `platform-dev`.
- **Spec Kit branch created**: `427-exchange-teams-verified-source-contract-enablement`.
- **Baseline HEAD**: `f7d06621 feat: implement Exchange Teams evidence identity readiness (#493)`.
- **Dirty state before Spec Kit execution**: clean.
- **Activated skills / repo gates**: `spec-kit-next-best-prep`, `tenantpilot-spec-readiness-gate`, `tenantpilot-tcm-cutover-guard`, `tenantpilot-provider-freshness-semantics`, and `tenantpilot-evidence-anchor-contract`.
- **Hard-gate stop conditions preserved**: no remote capture, no rendered UI/customer proof, no evidence promotion, no legacy adapter/fallback/dual truth, no `tenant_id` ownership truth, no raw payload/default proof exposure, and no provider permission widening without an explicit blocked/productization state.
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
- **Problem**: Spec 426 proved the safe failure mode for Exchange/Teams source-backed evidence, but the four target types still lack verified source contracts that later capture/evidence work can rely on.
- **Today's failure**: TenantPilot can currently say these types are blocked by missing contracts, but it cannot distinguish whether the blocker is missing source, unclear permissions, beta-only source, unsafe response shape, missing adapter, unsafe identity, or unsafe redaction. Without that precision, later evidence/certification work risks endpoint guessing or false readiness.
- **User-visible improvement**: Release reviewers and platform operators get a precise, test-proven contract state per target type before any evidence, compare/render, restore, or customer claim is allowed. The product remains honest about what is blocked and why.
- **Smallest enterprise-capable version**: Verify exactly four target types, record a deterministic source-contract state or exact blocker reason for each, update the existing resolver/registry path only, and prove no evidence or readiness promotion occurs.
- **Explicit non-goals**: No real provider capture, no raw evidence persistence, no normalized evidence persistence, no content-backed promotion, no compare/render promotion, no certification, no restore readiness, no customer claim, no provider OAuth/scope productization, no UI route/navigation/page/action, no Review Pack/report/PDF output, no Exchange/Teams mini-platform, no optional resource expansion, no `tenant_id`, and no v1 compatibility.
- **Permanent complexity imported**: A bounded contract-state/blocker vocabulary for four concrete resource types, resolver/registry metadata where the existing path needs it, and focused tests. No new table, no new provider subsystem, no new UI framework, and no customer-facing taxonomy are allowed.
- **Why now**: Spec 426 ended in a deliberate fail-safe state and names verified source contracts as the next blocker before content-backed evidence or certification can proceed.
- **Why not local**: A page-local or test-local contract marker would bypass the shared Coverage v2 resolver, provider boundary, identity handoff, redaction, and claim-safety rules. The contract decision must live in the existing source-contract infrastructure.
- **Approval class**: Core Enterprise.
- **Red flags triggered**: New status/reason vocabulary and resolver metadata. Defense: each value has a concrete fail-safe behavior and distinct follow-up action; the scope is exactly four existing resource types and avoids a generalized Exchange/Teams framework.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 1 | Wiederverwendung: 2 | **Gesamt: 10/12**
- **Decision**: approve as a narrow prerequisite unblocker.
## Spec Scope Fields *(mandatory)*
- **Scope**: Coverage v2 source-contract verification for exactly four Microsoft 365 Exchange/Teams resource types.
- **Primary Routes**: None. No rendered route, page, navigation entry, action, dashboard, report, or customer surface is in scope.
- **Data Ownership**: Existing Coverage v2 definitions/metadata only. Any environment-owned runtime rows touched by future implementation remain scoped by `workspace_id`, `managed_environment_id`, and same-scope `provider_connection_id`. No new persisted evidence rows are created by this spec.
- **RBAC**: No new UI or mutation surface. If resolver access includes provider context in implementation, provider connections must remain same workspace + managed environment, non-members must receive 404, and members missing capability must receive 403 through existing policy/gate paths.
For canonical-view specs:
- **Default filter behavior when tenant-context is active**: N/A - no canonical route or rendered filter is added.
- **Explicit entitlement checks preventing cross-tenant leakage**: Any provider-context verification must use workspace + managed-environment + provider-connection scope, never provider-native tenant identifiers as ownership truth.
## No Legacy / No Backward Compatibility Constraint *(mandatory)*
TenantPilot is pre-production unless this spec explicitly records a compatibility exception.
- **Compatibility posture**: canonical Coverage v2 source-contract extension; no compatibility exception.
- **Legacy aliases, fallback readers, hidden routes, duplicate UI, old labels, or historical fixtures kept?**: no.
- **Why clean replacement is safe now**: This is a blocked/prerequisite source-contract slice over active Coverage v2 services. No production data or external API consumer requires Coverage v1 adapters, fallback readers, dual writes, or old customer-facing coverage vocabulary.
## Target Resource Mapping
The attached draft used spec/product labels with workload prefixes. The runtime implementation must use repo-canonical resource type keys already registered in Coverage v2.
| Spec Label | Repo Canonical Type | Workload | Initial Required Result |
| --- | --- | --- | --- |
| `exchange.transportRule` | `transportRule` | Exchange | explicit verified-or-blocked contract state |
| `exchange.acceptedDomain` | `acceptedDomain` | Exchange | explicit verified-or-blocked contract state |
| `teams.appPermissionPolicy` | `appPermissionPolicy` | Teams | explicit verified-or-blocked contract state |
| `teams.meetingPolicy` | `meetingPolicy` | Teams | explicit verified-or-blocked contract state |
No additional resource type may be added unless it is already in the registry and is directly necessary to verify one of these four contracts. Forbidden expansion includes `remoteDomain`, `organizationConfig`, `messagingPolicy`, `appSetupPolicy`, `voiceRoute`, `updateManagementPolicy`, all Exchange settings, all Teams policies, and all Microsoft 365 resources.
## Source Class Mapping
The draft's source-class labels are contract-review labels. Runtime implementation must use repo-canonical values where they already exist.
| Spec Label | Repo Canonical Equivalent |
| --- | --- |
| `tcm` | existing `tcm` source class |
| `graph_v1` | existing `graph_v1_fallback` source class unless the repo already has a narrower canonical value |
| `graph_beta_experimental` | existing `graph_beta_experimental` source class |
| `repo_existing_provider_adapter` | existing provider abstraction / adapter path, not a new provider subsystem |
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Release Reviewer Gets Exact Contract State (Priority: P1)
As a release reviewer, I need each target resource type to resolve to a precise source-contract state so I can tell whether a later evidence spec may proceed or must stay blocked.
**Why this priority**: This is the smallest proof needed before content-backed capture can be attempted safely.
**Independent Test**: Resolver/registry tests prove every target type has one explicit final state and no target falls back to a generic or guessed source.
**Acceptance Scenarios**:
1. **Given** the four target resource types, **When** the source-contract resolver evaluates them, **Then** each receives either `contract_verified_pending_capture` or an exact blocked state.
2. **Given** a missing or unverifiable source contract, **When** the resolver evaluates the type, **Then** it fails closed with a specific blocker and does not call a provider.
### User Story 2 - Platform Operator Cannot See False Evidence Readiness (Priority: P1)
As a platform operator, I need verified source contracts to remain prerequisites rather than evidence/readiness claims.
**Why this priority**: A verified contract is not evidence, not comparison support, and not certification.
**Independent Test**: No-promotion tests prove no raw evidence, normalized evidence, content-backed level, comparable level, renderable level, certification, restore-ready state, or customer claim appears.
**Acceptance Scenarios**:
1. **Given** a target type marked verified pending capture, **When** readiness/claim paths are inspected, **Then** it remains pending capture only and not content-backed or customer claimable.
2. **Given** a blocked contract, **When** readiness/claim paths are inspected, **Then** it remains blocked with no fake evidence rows.
### User Story 3 - Security Reviewer Confirms Permission, Identity, And Redaction Safety (Priority: P1)
As a security reviewer, I need source contracts to include permission model, response shape, identity handoff, and redaction metadata before any future capture uses them.
**Why this priority**: Unsafe permissions, identity, response shape, or redaction would turn a source contract into misleading proof.
**Independent Test**: Focused tests prove verified contracts include permission metadata, response shape, identity handoff, and redaction rules; unsafe contracts stay blocked.
**Acceptance Scenarios**:
1. **Given** a contract candidate lacks clear permissions, **When** it is evaluated, **Then** it resolves to `contract_blocked_permission_unclear` or an equivalent exact blocked state.
2. **Given** a contract candidate depends on display names as identity, **When** it is evaluated, **Then** it resolves to `contract_blocked_identity_unsafe`.
3. **Given** a contract candidate exposes sensitive fields without redaction rules, **When** it is evaluated, **Then** it resolves to `contract_blocked_redaction_unsafe`.
### User Story 4 - Implementation Reviewer Preserves Spec 426 Fail-Safe Behavior (Priority: P2)
As an implementation reviewer, I need Spec 427 to prove it did not weaken Spec 426 fail-safe behavior.
**Why this priority**: Spec 427 must unblock only safe contracts, not silently reopen fake capture.
**Independent Test**: Spec 426, Spec 417, and Spec 420 regressions pass with all four Exchange/Teams target types still fail-safe where verification is not complete.
**Acceptance Scenarios**:
1. **Given** Spec 426 missing-contract behavior, **When** Spec 427 is implemented, **Then** unverifiable contracts still fail closed and create no provider call, resource row, or evidence row.
2. **Given** existing identity and generic evidence services, **When** Spec 427 adds contract metadata, **Then** existing Coverage v2 regressions remain green.
### Edge Cases
- Repo-canonical names differ from spec labels: use repo-canonical names and document the mapping.
- A source is Graph beta only: mark experimental/not-certifiable and blocked from customer/restore/certification claims.
- Required provider permission is not currently productized: do not widen scopes; block with a permission/productization reason.
- Response shape cannot distinguish empty, denied, unsupported, unavailable, and malformed responses: block as response-shape unsafe.
- Identity is display-name-only or order/hash based: block as identity unsafe.
- Redaction rules cannot keep secrets/raw provider payloads out of logs/default output: block as redaction unsafe.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-427-001**: The implementation MUST evaluate exactly `transportRule`, `acceptedDomain`, `appPermissionPolicy`, and `meetingPolicy`, using the mapping in this spec.
- **FR-427-002**: Each target type MUST receive one explicit final source-contract state or exact blocker reason; no target may remain an unclassified generic missing-contract outcome.
- **FR-427-003**: Allowed final states are `contract_verified_pending_capture`, `contract_blocked_missing_source`, `contract_blocked_permission_unclear`, `contract_blocked_beta_only`, `contract_blocked_response_shape_unsafe`, `contract_blocked_repo_adapter_missing`, `contract_blocked_identity_unsafe`, and `contract_blocked_redaction_unsafe`. If implementation uses repo-canonical enums instead, it MUST map these states one-to-one in source metadata/tests and MUST NOT create ambiguous or parallel truth.
- **FR-427-004**: Allowed source class labels are `tcm`, `graph_v1`, `graph_beta_experimental`, and `repo_existing_provider_adapter`, but implementation MUST map them to repo-canonical source-class values such as existing `graph_v1_fallback` where applicable. `graph_beta_experimental` MUST be marked experimental, not certifiable, not customer claimable, and not restore ready.
- **FR-427-005**: Forbidden source classes are guessed endpoint, manual export, operator upload, browser scrape, admin portal scrape, direct HTTP bypass, and temporary stub.
- **FR-427-006**: A verified contract MUST include resource type, workload, source class, source version, source contract name, source contract version, request shape, response shape, collection/singleton semantics, pagination model, identity fields, permission model, permission failure mode, redaction rules, normalization handoff shape, capture eligibility state, and documentation reference or repo-proof note.
- **FR-427-007**: Verified contracts MUST resolve deterministically through the existing `CoverageSourceContractResolver` / source-contract infrastructure or repo-canonical equivalent.
- **FR-427-008**: Missing, beta-only, permission-unclear, response-shape-unsafe, adapter-missing, identity-unsafe, and redaction-unsafe contracts MUST remain fail-closed with a specific blocker.
- **FR-427-009**: Implementation MUST NOT guess endpoints from resource type names, hardcode direct HTTP calls, bypass `GraphClientInterface` or the repo provider abstraction, perform runtime Microsoft docs fetches, or mark fake/test-only contracts as verified.
- **FR-427-010**: Each verified contract MUST declare required application permissions, delegated permissions where applicable, least-privilege note, admin-consent requirement, permission failure mode, and redacted permission context. New OAuth/provider scopes MUST NOT be added unless an existing approved mechanism already productizes them; otherwise the contract remains blocked.
- **FR-427-011**: Each verified contract MUST declare response semantics: collection/singleton, primary identity field, secondary identity fields, display-safe fields, sensitive fields, volatile fields, pagination model, empty response meaning, permission-denied response meaning, unsupported response meaning, and malformed response meaning.
- **FR-427-012**: The contract state model MUST distinguish empty collection, permission denied, source unavailable, unsupported contract, and malformed response. These must not collapse into generic "missing data".
- **FR-427-013**: Identity handoff metadata MUST include preferred identity fields, fallback identity fields, identity stability class, singleton/collection identity rule, known identity risks, and confirmation that display name is not stable identity.
- **FR-427-014**: A contract may be verified pending capture only when identity handoff is `stable_candidate` or `singleton_resource_with_source_contract_identity`. Otherwise it MUST be blocked as identity unsafe.
- **FR-427-015**: Normalization handoff metadata MUST include resource type, source class, source contract name, source version, raw payload shape, expected normalized shape, identity fields, volatile fields, sensitive fields, collection item path, and pagination cursor path where applicable.
- **FR-427-016**: Spec 427 MUST NOT persist raw provider payloads, normalized evidence, or evidence rows except local test fixtures. It must not promote target types to `content_backed`, `comparable`, `renderable`, `certified`, `restore_ready`, or `customer_claimable`.
- **FR-427-017**: Allowed registry/metadata updates are source contract state, source class, source contract name/version, capture eligibility state, blocker reason, experimental flag, not-certifiable flag, and not-customer-claimable flag. Forbidden updates include content-backed/comparable/renderable/certified coverage levels, assisted/automatic restore tiers, and customer-claimable truth.
- **FR-427-018**: Restore tier for the target types MUST remain current repo truth or stricter; this spec MUST NOT make any Exchange/Teams type restore ready.
- **FR-427-019**: No `tenant_id` platform-core ownership field, compatibility alias, fallback reader, dual write, or parallel ownership truth may be introduced.
- **FR-427-020**: No new Exchange-specific or Teams-specific table family, model family, dashboard, route, navigation item, report, export, Review Pack output, PDF output, or mini-platform may be introduced.
- **FR-427-021**: Safe contract metadata may be logged or displayed only when it contains no raw provider payloads, secrets, tokens, credentials, raw permission context, mail content, Teams chat/message/file/recording/transcript content, or private key/certificate material.
- **FR-427-022**: Tests MUST prove verified contracts resolve, blocked contracts remain blocked, permission metadata is present, response shape is safe, identity handoff is safe, redaction metadata is present, no evidence is created, no coverage/claim/restore promotion occurs, no `tenant_id` appears, and Spec 426/417/420 regressions still pass.
### Non-Functional Requirements
- **NFR-427-001 Security and privacy**: Logs, audit metadata, OperationRun context, diagnostics, and test output must not expose secrets, tokens, authorization headers, cookies, raw provider responses, raw payloads, permission context, mail content, Teams content, private keys, certificates, or passwords.
- **NFR-427-002 Determinism**: The same resource type and contract metadata must always resolve to the same contract state and blocker reason.
- **NFR-427-003 No provider cost**: No real Microsoft tenant calls, remote provider calls, or network-dependent tests are allowed in this spec.
- **NFR-427-004 Maintainability**: The implementation must extend existing Coverage v2 source-contract, identity, redaction, and claim-safety paths. New abstractions are allowed only when the proportionality review remains satisfied.
- **NFR-427-005 Auditability**: Implementation reports must include per-type source contract matrix, blocker matrix, permission summary, response-shape summary, identity handoff summary, redaction proof, and no-promotion proof.
## UI Surface Impact *(mandatory - UI-COV-001)*
Does this spec add, remove, rename, or materially change any reachable UI surface?
- [x] No UI surface impact
- [ ] Existing page changed
- [ ] New page/route added
- [ ] Navigation changed
- [ ] Filament panel/provider surface changed
- [ ] New modal/drawer/wizard/action added
- [ ] New table/form/state added
- [ ] Customer-facing surface changed
- [ ] Dangerous action changed
- [ ] Status/evidence/review presentation changed
- [ ] Workspace/environment context presentation changed
Default decision: no new runtime UI surface and no rendered UI change. New Exchange/Teams page, Teams page, customer route, navigation item, readiness badge, certified badge, restore action, report, export, Review Pack output, or PDF output is forbidden.
## UI/Productization Coverage *(mandatory when UI Surface Impact is not "No UI surface impact"; otherwise write `N/A - no reachable UI surface impact` plus rationale)*
- **Route/page/surface**: N/A - no reachable UI surface impact.
- **Current or new page archetype**: N/A.
- **Design depth**: N/A.
- **Repo-truth level**: N/A.
- **Existing pattern reused**: Existing Coverage v2 service/test paths only; no rendered surface change.
- **New pattern required**: none.
- **Screenshot required**: no.
- **Page audit required**: no.
- **Customer-safe review required**: negative proof only; no customer-facing output or claim may appear.
- **Dangerous-action review required**: no dangerous/high-impact UI action in scope.
- **Coverage files updated or explicitly not needed**:
- [ ] `docs/ui-ux-enterprise-audit/route-inventory.md`
- [ ] `docs/ui-ux-enterprise-audit/design-coverage-matrix.md`
- [ ] `docs/ui-ux-enterprise-audit/page-reports/...`
- [ ] `docs/ui-ux-enterprise-audit/strategic-surfaces.md`
- [ ] `docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md`
- [ ] `docs/ui-ux-enterprise-audit/unresolved-pages.md`
- [x] `N/A - no reachable UI surface impact`
- **No-impact rationale when applicable**: Source-contract enablement is internal contract metadata and resolver behavior only; no operator-facing surface is required to make the contract state truthful.
## Product Surface Impact *(mandatory for UI-affecting specs; otherwise write `N/A - no rendered product surface changed` plus rationale)*
Reference: `docs/product/standards/product-surface-contract.md`.
- **Product Surface Contract applies?**: no for default implementation; no rendered product surface changes.
- **Page archetype**: N/A.
- **Primary user question**: N/A.
- **Primary action**: N/A.
- **Surface budget result**: N/A.
- **Technical Annex / deep-link demotion**: N/A. Raw provider payloads, source keys, permission context, identities, blocker diagnostics, and contract proof remain internal/test/report evidence only.
- **Canonical status vocabulary**: N/A for no rendered UI. Runtime source-contract states are internal prerequisite states, not product badges.
- **Visible complexity impact**: neutral.
- **Product Surface exceptions**: none.
## Browser Verification Plan *(mandatory)*
- **Browser proof required?**: no.
- **No-browser rationale**: `N/A - no rendered UI surface changed`.
- **Focused path when required**: N/A.
- **Primary interaction to execute**: N/A.
- **Console, Livewire, Filament, network, and 500-error checks**: N/A.
- **Full-suite failure triage**: N/A unless future implementation amends UI into scope.
## Human Product Sanity Check *(mandatory)*
- **Required?**: no.
- **No-human-sanity rationale**: `N/A - no product surface changed`.
- **Reviewer questions**: N/A.
- **Planned result location**: N/A.
## Product Surface Merge Gate Checklist *(mandatory)*
- [x] No-legacy posture or approved exception recorded.
- [x] Product Surface Impact is completed or `N/A` is justified.
- [x] Browser proof is completed or `N/A - no rendered UI surface changed` is justified.
- [x] Human Product Sanity is completed or not applicable with rationale.
- [x] Product Surface exceptions are documented or `none`.
- [x] Implementation report will state Livewire v4 compliance, provider registration location, global search posture, destructive/high-impact action posture, asset strategy, tests/browser result, deployment impact, visible complexity outcome, and no completed-spec rewrite assertion.
## Cross-Cutting / Shared Pattern Reuse *(mandatory)*
- **Cross-cutting feature?**: yes.
- **Interaction class(es)**: Coverage v2 source contract resolution, provider contract metadata, permission/blocker semantics, identity handoff, redaction, claim safety.
- **Systems touched**: existing `CoverageSourceContractResolver`, `CoverageSourceContractDecision`, resource type registry, graph/provider contract registry, identity registry/resolver, generic capture fail-safe path, claim guard, redaction helpers, and focused tests.
- **Existing pattern(s) to extend**: Coverage v2 source-contract resolver and registry metadata; no Exchange/Teams-specific platform.
- **Shared contract / presenter / builder / renderer to reuse**: Existing Tenant Configuration/Coverage v2 services.
- **Why the existing shared path is sufficient or insufficient**: Existing paths already decide capture eligibility, provider boundary, identity, evidence, and claim safety. Spec 427 needs more precise contract states for four concrete types, not a new subsystem.
- **Allowed deviation and why**: A bounded source-contract state/reason metadata addition is allowed if existing `CaptureOutcome` values are too coarse to distinguish blocker reasons.
- **Consistency impact**: State names, blocker reasons, permission metadata, identity handoff, and no-promotion behavior must remain aligned across resolver, registry, tests, and implementation report.
- **Review focus**: No endpoint guessing, direct HTTP, real provider calls, permission widening, fake contract verification, evidence promotion, customer claim, restore claim, `tenant_id`, or mini-platform.
## OperationRun UX Impact *(mandatory)*
- **Touches OperationRun start/completion/link UX?**: no.
- **Shared OperationRun UX contract/layer reused**: N/A.
- **Delegated start/completion UX behaviors**: N/A.
- **Local surface-owned behavior that remains**: none.
- **Queued DB-notification policy**: N/A.
- **Terminal notification path**: N/A.
- **Exception required?**: none.
No remote capture or long-running provider work is allowed in this spec. If future implementation needs live provider checks or OperationRun creation, it must stop and amend this spec/plan/tasks first.
## Provider Boundary / Platform Core Check *(mandatory)*
- **Shared provider/platform boundary touched?**: yes.
- **Boundary classification**: mixed. Coverage v2 source-contract state and claim safety are platform-core; Microsoft Exchange/Teams source details, permission names, response shapes, and provider-native IDs are provider-owned metadata.
- **Seams affected**: source contract resolver, graph/provider contract registry, resource type registry metadata, permission metadata, identity handoff metadata, redaction metadata, and capture eligibility.
- **Neutral platform terms preserved or introduced**: `resource type`, `source contract`, `capture eligibility`, `blocker reason`, `provider connection`, `managed environment`, `workspace`, `evidence`, and `claim state`.
- **Provider-specific semantics retained and why**: Exchange/Teams labels, Microsoft permission names, endpoint/contract names, and provider-native IDs are retained only as provider-owned source metadata needed to decide whether a contract is safe.
- **Why this does not deepen provider coupling accidentally**: The runtime canonical keys already exist; this spec adds bounded contract metadata and blocker states for four concrete Microsoft resource types without spreading Microsoft names into platform ownership truth.
- **Follow-up path**: later specs may promote content-backed evidence only after this spec passes; no speculative multi-provider framework is introduced here.
## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*
`N/A - no operator-facing surface change.`
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
| --- | --- | --- | --- | --- | --- | --- |
| Source contract resolver/registry metadata | no | N/A | Coverage v2 contract family | none | no | `N/A - backend/internal contract metadata only` |
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface changed.
## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface changed.
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface changed.
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
N/A - no operator-facing surface changed.
## Proportionality Review *(mandatory when structural complexity is introduced)*
- **New source of truth?**: no. The source of truth remains the existing Coverage v2 source-contract resolver/registry path.
- **New persisted entity/table/artifact?**: no.
- **New abstraction?**: no new subsystem is allowed; update existing resolver/registry paths unless implementation proves a smaller helper is necessary.
- **New enum/state/reason family?**: yes, bounded source-contract states or blocker reasons may be added if existing repo outcomes are too coarse.
- **New cross-domain UI framework/taxonomy?**: no.
- **Current operator problem**: Later evidence/certification work needs exact contract blockers so reviewers do not mistake generic fail-safe behavior for readiness.
- **Existing structure is insufficient because**: Current `capture_blocked_missing_contract`-style outcomes do not distinguish missing source, unclear permission, beta-only, unsafe response, missing adapter, unsafe identity, or unsafe redaction.
- **Narrowest correct implementation**: Add exact contract-state metadata for exactly four existing resource types and keep it inside the existing Coverage v2 resolver/registry path.
- **Ownership cost**: Focused resolver/registry tests, per-type contract matrix maintenance, and implementation-report proof for each target type.
- **Alternative intentionally rejected**: Keep generic missing-contract blockers only. Rejected because later specs would not know which blocker is actionable or whether a type can safely attempt capture.
- **Release truth**: Current-release prerequisite truth for the immediate Coverage v2 Exchange/Teams sequence, not future speculative provider frameworking.
### 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.
## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*
- **Test purpose / classification**: Unit and Feature.
- **Validation lane(s)**: fast-feedback / confidence focused files; no browser lane by default.
- **Why this classification and these lanes are sufficient**: Resolver, metadata, permission, response-shape, identity, redaction, and no-promotion behavior can be proven through focused unit/feature tests without rendered UI or real provider calls.
- **New or expanded test families**: focused Spec 427 unit/feature files under `apps/platform/tests/Unit/Support/TenantConfiguration/` and `apps/platform/tests/Feature/TenantConfiguration/`.
- **Fixture / helper cost impact**: local fake contract metadata and payload-shape fixtures only; no real provider setup and no heavy default factories.
- **Heavy-family visibility / justification**: none.
- **Special surface test profile**: N/A - no rendered UI surface changed.
- **Standard-native relief or required special coverage**: browser proof is `N/A`; ordinary resolver/feature coverage is sufficient.
- **Reviewer handoff**: Confirm lane fit, no hidden browser/heavy-governance cost, no real provider calls, and exact focused commands in the implementation report.
- **Budget / baseline / trend impact**: none expected.
- **Escalation needed**: document-in-feature if implementation discovers a contract cannot be verified; follow-up-spec if provider permission productization or live capture becomes necessary.
- **Active feature PR close-out entry**: Guardrail / Exception / Smoke Coverage: `N/A - no rendered UI surface changed`; no Product Surface exception.
- **Planned validation commands**:
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `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`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureSourceContractResolverTest.php tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php`
- `git diff --check`
## Acceptance Criteria
- **AC-427-001**: All four target types have explicit final contract states.
- **AC-427-002**: Any verified contract is pending capture only and includes required permission, response-shape, identity, normalization, and redaction metadata.
- **AC-427-003**: Any blocked contract has an exact blocker state and creates no provider call, resource row, evidence row, coverage promotion, claim promotion, or restore readiness.
- **AC-427-004**: No content-backed, comparable, renderable, certified, customer claim, restore-ready, or Review Pack/report/PDF output is created.
- **AC-427-005**: No direct HTTP bypass, endpoint guessing, runtime docs fetch, provider subsystem, `tenant_id`, Exchange mini-platform, or Teams mini-platform is introduced.
- **AC-427-006**: Focused Spec 427 tests and Spec 426/417/420 regressions pass or exact bounded failures are documented.
- **AC-427-007**: Product Surface result remains `N/A - no rendered UI surface changed`.
## Success Criteria
- **SC-427-001**: The implementation report includes a target resource type mapping table and final contract state per type.
- **SC-427-002**: Resolver tests prove every target type resolves deterministically to verified-pending-capture or an exact blocked state.
- **SC-427-003**: No-promotion tests prove evidence, compare/render, certification, restore, and customer claims remain absent.
- **SC-427-004**: Security tests/static proof confirm no `tenant_id`, no raw payload/default output, and no secret/token logging.
- **SC-427-005**: The package is ready for a later implementation loop without open questions blocking safe implementation.
## Risks
| Risk | Severity | Mitigation |
| --- | ---: | --- |
| Contract verification becomes fake readiness | High | pending-capture-only state and no-promotion tests |
| Endpoint guessed and marked verified | High | contract metadata, resolver tests, and no direct HTTP/static guards |
| Beta source treated as certifiable | High | beta-only blocker/not-certifiable tests |
| Permission model unclear | High | permission blocker state and no scope widening |
| Response shape unsafe | High | response-shape blocker and empty/denied/unsupported/malformed distinctions |
| Identity unsafe | High | identity handoff blocker and Spec 417 regressions |
| Evidence accidentally created | High | no-evidence tests |
| Customer/restore claim appears | High | Claim Guard/no-promotion tests |
| `tenant_id` returns | High | ownership/static tests |
| Exchange/Teams mini-platform appears | Medium | architecture/no-mini-platform tests |
## Assumptions
- Spec 426 is completed and remains valid as fail-safe prerequisite context.
- Current repo-canonical resource type keys are `transportRule`, `acceptedDomain`, `appPermissionPolicy`, and `meetingPolicy`.
- Existing Coverage v2 source-contract, identity, evidence, and claim-safety services remain the preferred path.
- Some target types may remain blocked after implementation; that is a valid safe outcome when the blocker is exact and test-proven.
## Open Questions
None blocking preparation. Implementation must document any discovered source-contract uncertainty as an exact blocked state rather than asking for permission to guess endpoints or widen provider permissions.
## Follow-up Spec Candidates
- Spec 428 - Exchange/Teams Content-Backed Evidence Promotion.
- Spec 429 - Exchange/Teams Comparable/Renderable Promotion.
- Later Exchange/Teams Certified Compare Pack.
- M365 Customer Reporting Claim Guard Pack.
- M365 Pilot Readiness Gate.
- Provider permission productization only if a verified contract requires scopes not already approved by repo mechanisms.