Automated PR for spec 426 exchange teams core evidence identity readiness. Includes service changes and coverage/requirement/spec updates from commit fb4dc20c.
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #493
30 KiB
Implementation Plan: Spec 426 - Exchange / Teams Core Evidence & Stable Identity Readiness
Branch: 426-exchange-teams-core-evidence-identity-readiness | Date: 2026-07-02 | Spec: spec.md
Input: Feature specification from specs/426-exchange-teams-core-evidence-identity-readiness/spec.md
Summary
Prepare Exchange/Teams core evidence and stable identity readiness for later certification without overclaiming source support. Post-review correction found that the initially proposed Graph v1.0 endpoints for transportRule, acceptedDomain, appPermissionPolicy, and meetingPolicy are not production-safe source contracts. The implementation must therefore keep those four types fail-closed as missing contracts, prove no provider call/resource/evidence is created for blocked capture, and harden identity strategies for future valid source payloads. The work remains a prerequisite unblocker only. It must not certify Exchange/Teams, introduce restore/apply, activate customer claims, add routes/navigation/dashboards, create Exchange/Teams table families, or introduce tenant_id.
Post-Review Correction
- Remove unverified
mailFlowRule,acceptedDomains,teamsAppPermissionPolicy, andteamsMeetingPolicyGraph contract entries. - Keep
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicyblocked ascapture_blocked_missing_contractuntil a verified repo-canonical provider contract exists. - Preserve typed normalization/hash/redaction tests as helper proof only; do not claim source-backed evidence or compare/render readiness from fixtures.
- Harden identity strategies so
Identity/display-name-like values do not become stable identity. - Final readiness gate for source-backed evidence is
FAILby design; no certification follow-up may proceed from this branch.
Technical Context
Language/Version: PHP 8.4, Laravel 12, Filament v5, Livewire v4
Primary Dependencies: Existing Coverage v2 Tenant Configuration services: CoverageSourceContractResolver, GraphContractRegistry, ProviderGateway, GraphClientInterface, GenericContentEvidenceCaptureService, CoverageResourceUpserter, CoverageEvidenceWriter, CoverageIdentityStrategyRegistry, CanonicalIdentityResolver, ExchangeTeamsComparablePayloadNormalizer, ExchangeTeamsCoverageComparator, ExchangeTeamsRenderableSummaryBuilder, ClaimGuard, OperationRunService
Storage: PostgreSQL through existing Coverage v2 resource/evidence/supported-scope tables; no new table planned; readiness labels are derived report assertions over existing states, not new persisted booleans/statuses
Testing: Pest 4, PHPUnit 12, focused Unit/Feature; Browser only if UI changes
Validation Lanes: fast-feedback for unit/feature; browser conditional; Pint dirty; diff check
Target Platform: Laravel Sail locally, Dokploy container deployment
Project Type: Laravel web monolith under apps/platform
Performance Goals: Capture remains bounded to four selected resource types, remote work is OperationRun-backed, and compare/render readiness is deterministic over persisted evidence
Constraints: no endpoint guessing, no direct HTTP, no provider bypass, no certification, no restore/apply, no customer output, no new route/navigation/dashboard, no tenant_id, no v1 compatibility, no completed-spec rewrites
Scale/Scope: exactly four mandatory resource types; no optional Exchange/Teams/M365 expansion
Preparation Preflight Result
- Current branch before Spec Kit creation:
platform-dev. - Current branch after Spec Kit creation:
426-exchange-teams-core-evidence-identity-readiness. - Current HEAD before creation:
33e496c1 feat: complete spec 425 enta certified compare pack (#492). - Initial dirty state: clean.
- Existing
426-*spec/branch check: no existing local branch or spec package found before creation. - Auto-prep queue:
docs/product/spec-candidates.mdcurrently says no safe automatic next-best-prep target remains. This package is a direct manual promotion from the user-provided candidate. - Related completed/read-only dependency specs: 414, 415, 417, 418, 419, 420, 422, and 425.
- Source contract gaps confirmed during preparation before implementation:
transportRule: no explicit mapping inCoverageSourceContractResolver.acceptedDomain: was explicitly blocked asmissing_source_contract_mappingbefore Spec 426 implementation.appPermissionPolicy: was explicitly blocked asmissing_source_contract_mappingbefore Spec 426 implementation.meetingPolicy: no explicit mapping inCoverageSourceContractResolver.
- Identity strategy gaps confirmed during preparation before implementation:
- No
CoverageIdentityStrategyRegistrystable strategy fortransportRule. - No stable strategy for
acceptedDomain. - No stable strategy for
appPermissionPolicy. - No stable strategy for
meetingPolicy.
- No
- Current compare/render evidence:
ExchangeTeamsComparablePayloadNormalizer,ExchangeTeamsCoverageComparator, andExchangeTeamsRenderableSummaryBuildersupport the four resource types.- Spec 422 proof is compare/render for content-backed existing/synthetic rows, not live/source-backed capture proof.
- Current capture architecture:
GenericContentEvidenceCaptureServiceusesProviderGateway::listPolicies()through the repo provider abstraction.CoverageEvidenceWriterpersists raw payload, normalized payload, payload hash, OperationRun link, source metadata, and content-backed evidence state.CoverageResourceUpserterusesCanonicalIdentityResolver.- Implementation must align source-backed Exchange/Teams payloads with the typed Spec 422 normalizer before claiming compare/render readiness.
- Current enum/vocabulary alignment:
- Use repo-canonical values such as
capture_blocked_missing_contract,capture_blocked_permission,capture_blocked_beta,capture_blocked_unsupported,capture_failed,content_backed,stable,derived,identity_conflict,missing_external_id, andunsupported_identity. - Do not introduce parallel wording such as
capture_blocked_unsupported_sourceunless the enum/status family is deliberately amended with tests and proportionality review.
- Use repo-canonical values such as
UI / Surface Guardrail Plan
- Guardrail scope: no operator-facing surface change by default.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces: none by default. Existing Coverage v2 readiness/operator surface only if implementation amends artifacts first.
- No-impact class, if applicable: service/config/test-only.
- Native vs custom classification summary: N/A - no UI change.
- Shared-family relevance: evidence capture, identity, source contracts, claim safety, redaction, compare/render readiness.
- State layers in scope: none in UI; service/evidence state only.
- Audience modes in scope: internal/operator proof only; no customer/read-only output.
- Decision/diagnostic/raw hierarchy plan: evidence and readiness proof remain implementation-report/test proof; raw/support details never default-render.
- Raw/support gating plan: raw payloads, raw provider responses, source keys, OperationRun internals, provider diagnostics, and permission context stay hidden from default UI and excluded from customer output.
- One-primary-action / duplicate-truth control: no new action.
- Handling modes by drift class or surface: runtime UI changes require spec/plan/tasks amendment, Product Surface completion, focused browser proof, and Human Product Sanity. New route/navigation/customer/restore/certify scope is a hard stop.
- Repository-signal treatment: review-mandatory for evidence/status presentation only if UI is amended; hard-stop for customer output, restore/apply, certification, or mini-platform drift.
- Special surface test profiles: N/A by default; existing Coverage v2 Technical Annex browser smoke only if UI changes.
- Required tests or manual smoke: focused Unit/Feature always; Browser conditional.
- Exception path and spread control: none.
- Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
- UI/Productization coverage decision:
N/A - no rendered UI surface changedby default. - Coverage artifacts to update: none unless implementation amends runtime UI scope.
- No-impact rationale: Missing-contract blockers, identity hardening, no-fake-evidence behavior, and no-overclaim guards can be proven by existing shared services and tests without rendered UI changes.
- Navigation / Filament provider-panel handling: no panel, provider registration, route, or navigation change.
- Screenshot or page-report need: none unless runtime UI is amended into scope.
Product Surface Contract Plan
- Product Surface Contract reference:
docs/product/standards/product-surface-contract.md. - No-legacy posture: canonical Coverage v2 extension; no compatibility exception.
- Page archetype and surface budget plan: N/A by default. If amended into existing UI, classify as Technical Annex and preserve existing surface budgets.
- Technical Annex and deep-link demotion plan: OperationRun, evidence IDs, source endpoints, source keys, raw payloads, permission context, provider diagnostics, unsupported internals, and raw compare values remain hidden/collapsed/internal-only.
- Canonical status vocabulary plan: N/A by default. If rendered, product-facing labels map to canonical vocabulary and never say certified, restore-ready, customer-ready, full Exchange, full Teams, or M365 certified.
- Product Surface exceptions: none.
- Browser verification plan:
N/A - no rendered UI surface changedunless UI files change; otherwise focused existing Coverage v2 route smoke. - Human Product Sanity plan: N/A unless UI changes.
- Visible complexity outcome target: neutral by default.
- Implementation report target:
specs/426-exchange-teams-core-evidence-identity-readiness/implementation-report.md.
Filament / Livewire / Deployment Posture
- Livewire v4 compliance: unchanged; platform remains Filament v5 on Livewire v4. Must be stated in close-out.
- Panel provider registration location: no panel change planned. Laravel 12 provider registration remains
apps/platform/bootstrap/providers.php. - Global search posture: no Resource/global search change planned.
- Destructive/high-impact action posture: none. No restore/apply/certify/start action may be introduced. Existing capture workflow may be reused only if already authorized and OperationRun-backed.
- Asset strategy: no new assets planned.
filament:assetsis not newly required unless implementation unexpectedly registers assets, which would require spec amendment. - Testing plan: Unit/Feature for source contracts, capture eligibility, evidence persistence, identity, normalization/hash, claim guard, redaction, no certification/restore/customer/tenant_id/mini-platform; Browser only if UI changes.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, or assets expected. If graph contracts/resource defaults change, existing deployment/sync steps must be documented in the implementation report.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes.
- Systems touched: Coverage v2 resource type registry, source contract resolver, graph contract config, provider gateway, generic capture, resource upsert/evidence write, identity strategy registry/resolver, Exchange/Teams typed normalizer/comparator/summary builder, Claim Guard, redaction, operation capture tests.
- Shared abstractions reused:
CoverageSourceContractResolver,GraphContractRegistry,ProviderGateway,GraphClientInterface,GenericContentEvidenceCaptureService,CoverageResourceUpserter,CoverageEvidenceWriter,CoverageIdentityStrategyRegistry,CanonicalIdentityResolver,ExchangeTeamsComparablePayloadNormalizer,ExchangeTeamsCoverageComparator,ExchangeTeamsRenderableSummaryBuilder,ClaimGuard,OperationRunService. - New abstraction introduced? why?: none expected. A small adapter for typed normalization during capture is allowed only if the existing generic normalizer cannot safely persist deterministic Spec 422-compatible payloads.
- Why the existing abstraction was sufficient or insufficient: Existing Coverage v2 paths provide scope, evidence, identity, and claim safety. They lack the exact four source contracts, identity strategies, and source-backed typed normalization alignment required for later certification.
- Bounded deviation / spread control: Exchange/Teams-specific logic must remain bounded to typed helpers/contract mappings inside the Tenant Configuration service boundary. No Exchange/Teams platform or generic provider framework.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no new UX.
- Central contract reused: existing OperationRun-backed capture path only.
- Delegated UX behaviors: N/A - no new start surface.
- Surface-owned behavior kept local: none.
- Queued DB-notification policy: no new policy.
- Terminal notification path: existing central lifecycle mechanism only.
- Exception path: none.
Remote/provider capture must continue to use existing OperationRun service-owned lifecycle and sanitized summary counts. No new operation type is required unless implementation proves the existing tenant_configuration.capture cannot represent the capture safely; that would require spec amendment.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes.
- Provider-owned seams: Exchange/Teams source contracts, Microsoft Graph/TCM source payload fields, provider IDs/natural keys, provider permission metadata.
- Platform-core seams: Coverage v2 evidence state, capture outcome, identity state, coverage level, claim state, payload hash, workspace/managed-environment/provider scope.
- Neutral platform terms / contracts preserved: resource type, evidence, identity, source contract, provider connection, managed environment, claim, compare/render readiness.
- Retained provider-specific semantics and why:
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicyare Microsoft 365 resource semantics required by the exact denominator. - Bounded extraction or follow-up path: document-in-feature. Spec 427 should verify/enable production-safe source contracts for the four mandatory Exchange/Teams types or keep each type explicitly blocked. Spec 428 should promote content-backed evidence only after verified contracts exist. Spec 429 should promote compare/render only after source-backed evidence exists. Certification remains a later separate spec.
Constitution Check
- Inventory-first / evidence truth: FAIL-safe. This branch does not capture observed Exchange/Teams provider configuration evidence because verified source contracts are missing; blocked outcomes prevent fake evidence.
- Read/write separation: PASS with controls. No provider write, restore, apply, destructive UI action, or fake internal evidence write is introduced.
- Graph contract path: FAIL-safe. No unverified contracts are added to
config/graph_contracts.php; future source contracts must useGraphClientInterface/provider gateway only. - Deterministic capabilities: PASS. Readiness criteria and claim blockers are testable.
- RBAC-UX: PASS with implementation requirement. Non-member/wrong scope is 404; member missing capability is 403; readonly cannot start capture.
- Workspace isolation: PASS with implementation requirement. Same workspace/managed environment/provider connection is required.
- Tenant isolation: PASS in current repo vocabulary; no
tenant_idownership truth. - Run observability: PASS. Blocked capture is OperationRun-backed and records sanitized missing-contract outcomes; readiness evaluation is DB/service-only.
- OperationRun start UX: N/A unless existing start workflow is reused; no new start surface.
- Data minimization: PASS. No raw Exchange/Teams provider payload is captured while contracts are missing; future raw payloads must remain evidence-only and never default-rendered/logged/customer-published.
- Test governance: PASS. Unit/Feature lane is sufficient unless UI changes.
- Proportionality: PASS. Four concrete source/identity gaps justify narrow missing-contract guards, identity strategies, and helper tests.
- No premature abstraction: PASS only if implementation avoids a generic Exchange/Teams framework.
- Persisted truth: PASS. Uses existing evidence/resource tables.
- Behavioral state: PASS if existing enum/status families are reused.
- UI semantics: PASS by no-UI default.
- Shared pattern first: PASS. Existing Coverage v2 services are the path.
- Provider boundary: PASS with provider-specific fields bounded to contracts/typed adapters.
- V1 explicitness / few layers: PASS. Explicit four-type implementation only.
- Spec discipline / bloat check: PASS. Certification, restore, customer output, and optional types are split out.
- Filament-native UI: N/A unless existing UI changes.
- Product Surface Contract: PASS with no-rendered-surface rationale.
Test Governance Check
- Test purpose / classification by changed surface: Unit for resolver, eligibility, identity, normalization, hash, Claim Guard, redaction. Feature for blocked capture with no fake DB evidence, OperationRun, provider scope, authorization, no certification/restore/customer/tenant_id/mini-platform. Browser only if UI changes.
- Affected validation lanes: fast-feedback; browser conditional.
- Why this lane mix is the narrowest sufficient proof: Missing-contract decisions, identity hardening, no-fake-evidence behavior, and claim safety are deterministic service/DB behavior. Browser proof is only meaningful when rendered UI changes.
- Narrowest proving command(s):
cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ExchangeTeamsSourceContractResolverTestcd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ExchangeTeamsIdentityStrategyRegistryTestcd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec426ExchangeTeamsCoreEvidenceReadinessTestcd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec426ExchangeTeamsStableIdentityReadinessTestcd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec426ExchangeTeamsClaimGuardFeatureTest
- Fixture / helper / factory / seed / context cost risks: Add minimal fake provider payloads for four resource types; avoid full workspace/provider setup defaults outside feature tests.
- Expensive defaults or shared helper growth introduced?: no.
- Heavy-family additions, promotions, or visibility changes: none unless UI changes.
- Surface-class relief / special coverage rule:
N/A - no rendered UI surface changedby default. - Closing validation and reviewer handoff: verify missing-contract blockers, no fake evidence persistence, stable identity strategy hardening, no compare/render overclaim, claim blocking, redaction, no restore/customer/tenant_id/mini-platform.
- Budget / baseline / trend follow-up: none expected.
- Review-stop questions: Did any type rely on beta-only source, display-name identity, fake evidence, direct HTTP, endpoint guessing, customer claim, restore path, or
tenant_id? If yes, fail or split. - Escalation path: reject-or-split for certification/restore/customer/mini-platform scope; document-in-feature for bounded source/identity limitations.
- Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
- Why no dedicated follow-up spec is needed: This is the dedicated fail-safe readiness unblocker. Source-contract verification, content-backed evidence promotion, compare/render promotion, and certification are intentionally split into later specs.
Risk Controls And Rollout Considerations
- Rollout shape: Service/config/test-only by default. No migration, env var, route, navigation, asset, queue, scheduler, storage, or customer-output rollout is planned.
- Staging gate: Later implementation must validate source contracts, capture outcomes, redaction, provider scope, and no-certification/no-restore/no-customer claims on staging before production promotion.
- Provider-contract risk control: New source contracts must be explicit registry entries with source class, source version/schema metadata where available, permission metadata where supported, and fake-provider tests. Runtime endpoint guessing is a stop condition.
- Evidence integrity risk control: Missing contract, missing permission, unsupported source, beta-only source, unavailable source, and provider failure must remain blocked/failed states, not empty evidence.
- Identity risk control: Any type that cannot produce stable source-backed identity fails readiness instead of falling back to display-name, order, payload-hash, operation-run, or generated identity.
- Claim risk control: Claim Guard must keep certification, restore-ready, full workload/M365, and customer-ready wording blocked until a later spec.
- Operational risk control: OperationRun summaries remain numeric-only and sanitized; compare/render readiness evaluation must not call the provider.
- Rollback/forward note: Because no schema or customer surface is planned, rollback is reverting the source/identity/normalization code and tests. If implementation discovers schema or UI changes are necessary, artifacts must be amended before proceeding.
Project Structure
Documentation (this feature)
specs/426-exchange-teams-core-evidence-identity-readiness/
├── checklists/
│ └── requirements.md
├── plan.md
├── spec.md
└── tasks.md
Source Code (repository root)
Likely affected runtime/test paths for later implementation:
apps/platform/config/
└── graph_contracts.php
apps/platform/app/Services/TenantConfiguration/
├── CoverageSourceContractResolver.php
├── CoverageIdentityStrategyRegistry.php
├── GenericContentEvidenceCaptureService.php # only if typed capture normalization hook is needed
├── GenericPayloadNormalizer.php # only if deterministic collection/hash behavior must be generalized
├── CoverageEvidenceWriter.php # only if typed normalized payload promotion requires writer support
├── ExchangeTeamsComparablePayloadNormalizer.php
├── ExchangeTeamsCoverageComparator.php
├── ExchangeTeamsRenderableSummaryBuilder.php
└── ClaimGuard.php
apps/platform/tests/Unit/Support/TenantConfiguration/
└── ExchangeTeams*.php
apps/platform/tests/Feature/TenantConfiguration/
└── Spec426ExchangeTeams*.php
apps/platform/tests/Fixtures/TenantConfiguration/Spec426/
└── exchange-teams/
apps/platform/tests/Browser/
└── Spec426ExchangeTeamsCoreEvidenceReadinessSmokeTest.php # only if UI changes
Structure Decision: Use existing TenantConfiguration/Coverage v2 service and test directories. Do not create new base folders, migrations, routes, Filament resources/pages/widgets, commands, jobs, dashboards, reports, exports, PDFs, or customer-output surfaces.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| Fail-closed source contract blockers | Later certification needs real source-backed capture for the exact denominator, but no verified contracts exist yet | Registering guessed Graph endpoints would allow fake certification readiness |
| Four stable identity strategies | Stable canonical identity is required to compare, track, and later certify resource instances | Display-name or payload-hash identity is unstable and unsafe |
| Typed source normalization alignment | Source-backed payloads must enter the existing Spec 422 compare/render pipeline deterministically | Generic raw-payload hashing alone does not prove comparable/renderable shape |
Proportionality Review
- Current operator problem: Exchange/Teams certification remains blocked because the denominator lacks source-backed evidence and stable identity.
- Existing structure is insufficient because: Current source resolver and identity registry do not cover the four mandatory types; Spec 422 does not prove live/source-backed capture.
- Narrowest correct implementation: Keep missing source contracts blocked, remove unverified mappings, extend identity/normalization tests for exactly four concrete types, and document the source blocker.
- Ownership cost created: Four identity strategies and focused tests must track future provider contract changes.
- Alternative intentionally rejected: Certify based on row-level compare/render support or display names. That would weaken evidence integrity and create unsafe claims.
- Release truth: Current-release prerequisite for later source-contract verification, evidence promotion, compare/render promotion, and eventual certification.
Technical Approach
Phase 0 - Hard Preflight
- Confirm branch, HEAD, dirty state, active spec path, and activated skills/gates.
- Confirm completed dependency specs are read-only context.
- Re-check current source contract and identity gaps.
- Confirm Coverage v2 capture/identity/evidence infrastructure exists.
- Stop if generic capture or canonical identity infrastructure is missing.
Phase 1 - Source Contract Gap Map
- Inspect
CoverageSourceContractResolver,config/graph_contracts.php,GraphContractRegistry,ProviderGateway, andGraphClientInterfacepatterns. - Record current resolver state for
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicy. - Determine source class, contract key, production-safety, permission metadata, response shape, volatile fields, and empty collection semantics.
- Identify whether any type is beta/experimental-only; if yes, mark certification readiness blocked.
Phase 2 - Block Unverified Source Contracts
- Do not add resolver mappings or contract definitions for the four mandatory types until verified source contracts exist.
- Prove blocked capture makes no
ProviderGateway/GraphClientInterfacecalls. - Add contract tests proving no endpoint guessing, no direct HTTP, and missing-contract fail-closed behavior.
- Preserve missing-permission and unsupported-source outcomes.
Phase 3 - Block Fake Content-Backed Evidence
- Route all four types through existing generic/shared capture path until the source contract decision blocks them.
- Persist no resource rows or evidence rows while contracts are missing.
- Preserve typed helper payload normalization for future valid source payloads, without claiming readiness/hash proof from blocked capture.
- Represent empty successful collections only as safe source-contract capture proof unless an existing repo-approved type-level evidence artifact can carry an explicit empty normalized payload/hash; do not create fake resource instances.
- Prevent fake/synthetic evidence from counting as source-backed.
Phase 4 - Stable Identity
- Add identity strategies for the four mandatory types.
- Require stable provider/source ID or proven immutable natural key/composite.
- Reject display-name-only, array-index, priority/order, payload-hash, random UUID, and operation-run identity.
- Use
CanonicalIdentityResolverand block identity conflicts.
Phase 5 - Normalization And Compare/Render Helper Proof
- Align helper payload fixtures with
ExchangeTeamsComparablePayloadNormalizer,ExchangeTeamsCoverageComparator, andExchangeTeamsRenderableSummaryBuilderso future real source-backed payloads have a bounded path. - Preserve material fields, exclude volatile fields, and record unsupported fields diagnostically.
- Mark readiness as compare/render-ready only when source-backed evidence and stable identity both exist; this branch does not satisfy that gate.
- Do not assign certified coverage.
Phase 6 - Claim Guard / Safety
- Allow internal evidence-ready and stable-identity-ready wording only when proven.
- Block certification, restore-ready, full Exchange/Teams/M365, and customer-ready claims.
- Add redaction tests for secrets, tokens, cookies, authorization headers, raw payloads, raw permission context, mail content, and Teams content.
Phase 7 - Product Surface Decision
- Confirm no runtime UI change.
- If implementation proves UI is needed, stop, amend spec/plan/tasks with exact affected surfaces, then run Product Surface/browser/Human Product Sanity proof.
- Do not add route, navigation, dashboard, certify action, restore action, report, customer output, Review Pack, export, or PDF.
Phase 8 - Validation
- Run Pint dirty.
- Run focused unit tests.
- Run focused feature tests.
- Run browser test only if UI changed.
- Run
git diff --check. - Document exact validation results in implementation report.
Phase 9 - Implementation Report
- Produce required matrices and final candidate gate result.
- Record no certification, no restore, no customer claim, no
tenant_id, no mini-platform, and Product Surface no-impact proof.
Stop Conditions
- Any mandatory type lacks source contract support and is treated as source-backed or compare/render-ready.
- Any mandatory type lacks stable source-backed identity.
- Any type is beta/experimental-only but treated as certification-ready.
- Synthetic/fake evidence is counted as source-backed.
- Display name, order, payload hash, or operation run ID is used as stable identity.
- Capture bypasses provider gateway/GraphClientInterface or guesses endpoints.
- Certification, restore/apply, customer output, full workload/M365 claim, new route/navigation/dashboard, or mini-platform appears.
tenant_idis introduced as platform-core ownership truth or compatibility/fallback path.- Raw payload, secrets, mail content, Teams content, or raw permission context leak into logs/UI/output.
- Tests cannot prove evidence + identity readiness.