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
26 KiB
Tasks: Spec 426 - Exchange / Teams Core Evidence & Stable Identity Readiness
Input: Design documents from specs/426-exchange-teams-core-evidence-identity-readiness/
Prerequisites: spec.md, plan.md, checklists/requirements.md
Tests: Required. This spec changes runtime source-contract, capture/evidence, identity, readiness, and claim-safety behavior. Use focused Pest Unit/Feature tests first. Browser proof is required only if rendered UI changes.
Implementation note: Post-review correction removed unverified Graph source contracts for the four mandatory types. Fake provider payloads remain only in unit-level normalization/hash/redaction tests; capture/evidence feature tests now prove missing-contract fail-closed behavior, no provider call, and no fake resource/evidence rows. OperationRun blocked proof is covered inside Spec426ExchangeTeamsCoreEvidenceReadinessTest.php; no separate OperationRun test file was needed.
Test Governance Checklist
- Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
- Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- Planned validation commands cover the change without pulling in unrelated lane cost.
- Browser proof is explicitly
N/A - no rendered UI surface changedunless rendered UI changes. - Human Product Sanity and Product Surface implementation-report close-out are planned if UI changes.
- Any material budget, baseline, trend, or escalation note is recorded in the implementation report.
Phase 1: Hard Preflight
Purpose: Re-check the prerequisite gate before runtime implementation. Stop before code changes if this phase fails.
- T001 Capture current branch, HEAD, and
git status --shortinspecs/426-exchange-teams-core-evidence-identity-readiness/implementation-report.md. - T002 Record activated skills/gates and hard-gate stop condition status in the implementation report.
- T003 Confirm Specs 414, 415, 417, 418, 419, 420, 422, and 425 remain completed/read-only dependency context; do not edit their artifacts.
- T004 Confirm current Coverage v2 infrastructure exists:
CoverageSourceContractResolver,CoverageIdentityStrategyRegistry,GenericContentEvidenceCaptureService,CoverageResourceUpserter,CoverageEvidenceWriter,CanonicalIdentityResolver,SupportedScopeResolver,ClaimGuard,OperationRunService, andGraphClientInterface/provider gateway. - T005 Confirm current source contract gaps for
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicy. - T006 Confirm current identity strategy gaps for
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicy. - T007 Confirm Coverage v2 ownership paths use
workspace_id,managed_environment_id, and same-scopeprovider_connection_id, nottenant_id. - T008 Stop and report the blocker before implementation if generic capture, canonical identity, source contract resolution, or provider-scope infrastructure is missing.
Checkpoint: Source/capture/identity foundation exists or implementation stops.
Phase 2: Fixtures And Failing Tests
Purpose: Add focused proof before or alongside runtime changes.
- T009 [P] Cover
transportRulenormal, volatile, unsupported-field, missing/display-only identity, material-change, and redaction cases with inline fake provider payloads in Spec 426 tests. - T010 [P] Cover
acceptedDomainnormal, volatile, natural-key identity, display-only identity, and redaction cases with inline fake provider payloads in Spec 426 tests. - T011 [P] Cover
appPermissionPolicynormal, unsupported-field, missing/display-only stable ID, app-list material changes, and redaction cases with inline fake provider payloads in Spec 426 tests. - T012 [P] Cover
meetingPolicynormal, volatile, missing/display-only stable ID, recording/transcription material changes, and redaction cases with inline fake provider payloads in Spec 426 tests. - T013 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsSourceContractResolverTest.phpproving all four mandatory types fail closed as missing contracts and non-selected missing contracts also fail closed. - T014 [P] Cover capture eligibility through
Spec426ExchangeTeamsCoreEvidenceReadinessTest.php,Spec426ExchangeTeamsProviderScopeTest.php, and updated Spec 420 missing-contract tests. - T015 [P] Cover identity strategy registration in
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsCanonicalIdentityTest.phpand updatedSpec417CoverageIdentityStrategyRegistryTest.php. - T016 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsCanonicalIdentityTest.phpprovingCanonicalIdentityResolverproduces stable identity for valid source payloads and blocks missing/unsupported identity. - T017 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsPayloadNormalizationFromSourceTest.phpproving typed helper payloads normalize into the Spec 422 shape with material fields and unsupported-field diagnostics, without claiming source-backed readiness. - T018 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsEvidenceHashTest.phpproving deterministic payload hashes, volatile-field exclusion, and material-change hash changes. - T019 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsClaimGuardReadinessTest.phpproving evidence-ready/stable-identity-ready/internal compare-render wording is allowed only when proven and certification/restore/customer/full coverage claims are blocked. - T020 [P] Add
apps/platform/tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsRedactionTest.phpproving provider/raw/content leakage is removed from normalized/readiness output. - T021 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsCoreEvidenceReadinessTest.phpproving blocked capture for all four types creates no provider call, no resource rows, and no evidence rows. - T022 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsStableIdentityReadinessTest.phpproving blocked source types cannot create stable identity readiness rows from fake/display-only payloads. - T023 [P] Cover operation run linkage, sanitized context, numeric summary counts, and no raw/secrets/content in run context in
Spec426ExchangeTeamsCoreEvidenceReadinessTest.php. - T024 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsProviderScopeTest.phpproving outsider 404, readonly/capability denial 403, and cross-workspace/cross-environment provider connection rejection. - T025 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsClaimGuardFeatureTest.phpproving internal readiness claims are bounded and certification/restore/customer claims remain blocked. - T026 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoCertificationTest.phpproving no certified level, certified supported scope, or certification evaluator/result is introduced. - T027 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoRestoreTest.phpproving no restore/apply/assisted restore/action/restorable state is introduced. - T028 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoTenantIdTest.phpproving Spec 426 runtime changes do not introducetenant_id. - T029 [P] Add
apps/platform/tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoMiniPlatformTest.phpproving no Exchange/Teams migration, table family, model, route, navigation, Filament Resource/Page, dashboard, report, export, PDF, or customer surface is added. - T030 [P] Add fail-hard provider/HTTP assertions proving readiness/compare/render evaluation makes no remote call and capture calls provider only through the repo provider abstraction.
Checkpoint: New focused tests fail for missing implementation and pass after later phases.
Phase 3: Source Contract Mappings
Purpose: Keep the exact four resource types fail-closed until production-safe source contracts exist.
- T031 Remove unverified
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicysource contracts fromapps/platform/config/graph_contracts.php. - T032 Do not invent source class metadata, Graph version, resource path, response shape, or read permission metadata for unverified endpoints.
- T033 Update
apps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.phpso all four canonical types explicitly fail closed as missing source contracts. - T034 Keep
acceptedDomainandappPermissionPolicyin the missing-contract blocker list until verified contracts exist and tests prove resolution. - T035 Ensure
transportRuleandmeetingPolicyalso fail closed as missing source contracts. - T036 Preserve fail-closed behavior for missing contracts, unsupported sources, beta-only sources, and missing Graph contract resources.
- T037 Ensure no implementation builds URLs by resource type string concatenation, bypasses
GraphClientInterface, uses direct HTTP, or calls Microsoft documentation/runtime discovery. - T038 If any mandatory type is beta/experimental-only, mark it
certification_blocked_experimental_sourceor repo-equivalent in readiness output and fail the final certification-readiness gate.
Checkpoint: Source contract resolver tests pass for all four mandatory types by proving blocked missing-contract behavior.
Phase 4: Capture Eligibility And Content-Backed Evidence
Purpose: Preserve shared Coverage v2 capture behavior without fake source-backed evidence.
- T039 Update
apps/platform/app/Services/TenantConfiguration/GenericContentEvidenceCaptureService.phponly if needed to route the four types through existing capture with correct contract options and empty collection handling. - T040 Ensure missing permission returns repo-canonical
capture_blocked_permissionand does not record fake captured evidence. - T041 Ensure missing contract returns
capture_blocked_missing_contractand does not silently skip or treat empty as no configuration. - T042 Ensure unsupported or beta-disabled source returns repo-canonical blocked outcome and cannot mark certification-ready.
- T043 Persist no source-backed
raw_payload, source metadata,operation_run_id,capture_outcome,evidence_state, orcaptured_atrows while contracts are missing. - T044 Represent successful empty collections as OperationRun/source-contract capture proof, and only persist explicit empty normalized payload/hash when an existing repo-approved type-level evidence artifact can safely carry it; do not create fake resource instances or fake per-resource evidence.
- T045 Ensure
operation_runs.summary_countsremains flat numeric-only and no raw payload, secrets, permission context, mail content, Teams content, or provider response body enters run context/messages. - T046 Ensure capture remains scoped to same workspace, managed environment, and provider connection.
Checkpoint: Blocked capture feature tests pass for all four mandatory types and prove no fake evidence.
Phase 5: Typed Normalization And Hashing
Purpose: Preserve typed helper normalization and hashing for future verified source payloads without claiming source-backed readiness.
- T047 Verify
apps/platform/app/Services/TenantConfiguration/ExchangeTeamsComparablePayloadNormalizer.phphelper coverage for selected Exchange/Teams fields without adding unverified source contracts. - T048 Add a typed normalization handoff from capture to evidence persistence if generic normalized payloads cannot satisfy Spec 426 hashing/readiness requirements.
- T049 Ensure normalized payloads include or deterministically derive
canonical_type, workload, source identity, safe display label, source contract, source class, material fields, unsupported fields, and volatile fields excluded; keep capture timestamps in evidence metadata such ascaptured_at, outside the normalized material payload and payload hash. - T050 Ensure
transportRulepreserves enabled/state, priority/order, conditions, actions, exceptions, mode/enforcement state, and scope where present. - T051 Ensure
acceptedDomainpreserves domain name, domain type, default-domain flag, and state where present. - T052 Ensure
appPermissionPolicypreserves policy ID, display name, allowed apps, blocked apps, policy mode, and assignment/target summary when available from the same approved source. - T053 Ensure
meetingPolicypreserves policy ID, display name, external/anonymous access, recording/transcription, lobby/admission, content sharing, and meeting chat/settings where present. - T054 Ensure unsupported helper/source fields are recorded as diagnostics and cannot be used to claim readiness while contracts are missing.
- T055 Ensure deterministic payload hashing is based on normalized material truth, excludes configured volatile fields, and handles semantically unordered collections consistently.
Checkpoint: Normalization and evidence-hash unit tests pass.
Phase 6: Stable Identity Strategies
Purpose: Add stable identity for the four mandatory types.
- T056 Update
apps/platform/app/Services/TenantConfiguration/CoverageIdentityStrategyRegistry.phpwith a stable identity strategy fortransportRule. - T057 Update
CoverageIdentityStrategyRegistry.phpwith a stable identity strategy foracceptedDomain. - T058 Update
CoverageIdentityStrategyRegistry.phpwith a stable identity strategy forappPermissionPolicy. - T059 Update
CoverageIdentityStrategyRegistry.phpwith a stable identity strategy formeetingPolicy. - T060 Prefer stable source/provider ID fields. Use an immutable natural key or stable composite only when source-backed and proven unique within provider/environment scope.
- T061 Reject display name, localized label, array index, priority/order, payload hash, operation run ID, random UUID, description, settings hash, domain type, default flag, conditions/actions hash, or enabled state as sole stable identity.
- T062 Ensure
CanonicalIdentityResolverremains the only identity resolution path and identity conflicts block readiness. - T063 Ensure derived, missing external ID, unsupported identity, or identity conflict blocks certification readiness for any mandatory type.
Checkpoint: Identity registry and canonical identity tests pass.
Phase 7: Compare / Render Readiness
Purpose: Prove typed helper compatibility while preventing source-backed compare/render overclaims.
- T064 Ensure typed
transportRulepayload fixtures can be compared and rendered by existing Exchange/Teams services without claiming source-backed readiness. - T065 Ensure typed
acceptedDomainpayload fixtures can be compared and rendered without claiming source-backed readiness. - T066 Ensure typed
appPermissionPolicypayload fixtures can be compared and rendered without claiming source-backed readiness. - T067 Ensure typed
meetingPolicypayload fixtures can be compared and rendered without claiming source-backed readiness. - T068 Derive compare/render readiness only from existing Coverage v2 evidence, identity, and compare/render states/services when source-backed content evidence and stable identity exist; do not add a new persisted readiness boolean/status family.
- T069 Ensure derived compare/render readiness does not set
CoverageLevel::Certified, does not create a certified supported scope, and does not allow customer claims.
Checkpoint: Compare/render readiness tests pass and no certification appears.
Phase 8: Claim Guard And Redaction
Purpose: Keep claims conservative and evidence safe.
- T070 Update
apps/platform/app/Services/TenantConfiguration/ClaimGuard.phponly as needed to allow internal/operator readiness wording after proof. - T071 Block Certified Exchange / Teams Core Compare Pack wording until Spec 427.
- T072 Block Certified Exchange, Certified Teams, full Exchange coverage, full Teams coverage, certified Microsoft 365 coverage, Exchange restore-ready, Teams restore-ready, and customer-ready Exchange/Teams proof.
- T073 Ensure claim state for the four types remains internal/operator-only, non-customer-claimable, and non-restorable.
- T074 Ensure redaction removes access tokens, refresh tokens, ID tokens, client secrets, passwords, private keys, certificates, authorization headers, cookies, bearer tokens, raw payload markers, raw permission context, mail content, and Teams content from logs/render/readiness output.
Checkpoint: Claim Guard and redaction tests pass.
Phase 9: Product Surface Decision
Purpose: Keep UI scope bounded.
- T075 Determine whether implementation changed any runtime UI file, route, navigation, action, Filament page/resource/widget, Blade view, report, export, or customer output.
- T076 If no UI changed, record
N/A - no rendered UI surface changedand Product Surface exceptionsnonein the implementation report. - T077 If UI change is needed, stop before editing runtime UI files and amend
spec.md,plan.md, andtasks.mdwith exact affected surfaces, Product Surface decisions, browser proof path, and Human Product Sanity criteria. - T078 If amended UI work proceeds, update only the existing Coverage v2 internal/operator surface; do not add new route, navigation, Exchange/Teams dashboard, customer page, certify action, restore action, report, export, Review Pack, or PDF.
- T079 If UI changes proceed, add
apps/platform/tests/Browser/Spec426ExchangeTeamsCoreEvidenceReadinessSmokeTest.phpproving evidence readiness visible, identity readiness visible, certification absent, restore-ready absent, customer-ready absent, raw payload absent, mail/chat/content absent, secrets absent, and no console/Livewire/Filament errors.
Checkpoint: Product Surface decision is explicit and not contradicted by changed files.
Phase 10: Architecture And Safety Guards
Purpose: Prove no hidden scope expansion or ownership drift.
- T080 Ensure no migration creates Exchange-specific or Teams-specific table families.
- T081 Ensure no code introduces
tenant_idas Coverage v2 ownership truth, compatibility alias, fallback reader, dual-write target, or parallel scope key. - T082 Ensure no restore/apply, preview restore, assisted restore, or restore-readiness code path is introduced.
- T083 Ensure no customer output, Review Pack, rendered report, management PDF, export/download, legal/regulatory attestation, or customer-ready proof path is introduced.
- T084 Ensure no new Filament Resource/Page/Widget, route, navigation item, dashboard, or primary Exchange/Teams surface is introduced.
- T085 Ensure no v1-to-v2 adapter, old gap taxonomy dependency, fallback reader, or dual truth path is introduced.
- T086 Ensure no additional Exchange/Teams resource type is silently registered as in-scope readiness/certification work.
Checkpoint: No-overreach feature/static tests pass.
Phase 11: Implementation Report And Validation
Purpose: Close the evidence/identity readiness contract.
- T087 Create
specs/426-exchange-teams-core-evidence-identity-readiness/implementation-report.md. - T088 Record candidate gate result, dirty state before/after, branch, HEAD, activated skills, files changed, and completed-spec rewrite assertion.
- T089 Complete the source contract matrix for
transportRule,acceptedDomain,appPermissionPolicy, andmeetingPolicy. - T090 Complete the evidence matrix, including capture outcome, raw payload, normalized payload, payload hash, source metadata, empty collection behavior, and OperationRun linkage.
- T091 Complete the identity matrix, including strategy identifier, identity state, source identity field/key kind, conflict behavior, and blocker status.
- T092 Complete the compare/render readiness matrix and prove
compare_render_ready = Noandcertified = Nofor all four types while contracts are missing. - T093 Complete the Claim Guard matrix from
spec.md. - T094 Record redaction proof, no certification proof, no restore proof, no customer claim proof, no
tenant_idproof, no mini-platform proof, Product Surface decision, tests run, and deferred work. - T095 Run
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent. - T096 Run focused unit tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsSourceContractResolverTest.php. - T097 Run focused unit tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsCanonicalIdentityTest.php. - T098 Run focused unit tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsPayloadNormalizationFromSourceTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsEvidenceHashTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsClaimGuardReadinessTest.php tests/Unit/Support/TenantConfiguration/Spec426ExchangeTeamsRedactionTest.php. - T099 Run focused feature tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsCoreEvidenceReadinessTest.php. - T100 Run focused feature tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsProviderScopeTest.php. - T101 Run focused feature tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsStableIdentityReadinessTest.php. - T102 Run focused feature/static tests:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoCertificationTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoRestoreTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsNoMiniPlatformTest.php tests/Feature/TenantConfiguration/Spec426ExchangeTeamsClaimGuardFeatureTest.php. - T103 Run regression tests for superseded expectations:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec420M365GenericEvidenceCaptureTest.php tests/Feature/TenantConfiguration/Spec420M365CaptureOperationRunTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureSourceContractResolverTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureEligibilityTest.php tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php. - T104 Record combined
--filter=Spec426Signal 9 and equivalent direct-file Spec 426 passing after the post-review correction in the implementation report. - T105 Confirm browser proof is
N/A - no rendered UI surface changed. - T106 Confirm no separate Spec 426 browser smoke file is required because no runtime UI changed.
- T107 Confirm Product Surface exceptions are
none. - T108 Confirm no Livewire/Filament provider registration, global search, destructive action, or asset strategy changed.
- T109 Confirm no migration/env/queue/scheduler/storage/deployment action beyond normal config deploy is required.
- T110 Confirm updated Spec 420/417 runtime tests pass against current semantics.
- T111 Confirm active spec/plan/tasks/report state the no-browser/no-UI decision.
- T112 Confirm all focused Spec 426 source, identity, capture, claim, redaction, no-certification, no-restore, no-tenant-id, and no-mini-platform checks pass in split runs.
- T113 Browser validation:
N/A - no rendered UI surface changed. - T114 Run
git diff --check. - T115 Record any failed validation exactly in the implementation report; do not weaken source, evidence, identity, claim, redaction, ownership, no-certification, no-restore, or no-mini-platform criteria to make tests pass.
Checkpoint: Focused validation passes or exact failures are documented.
Dependencies & Execution Order
- Phase 1 blocks all runtime implementation.
- Phase 2 tests should be added before or alongside implementation phases.
- Phase 3 source contract blockers prevent Phase 4 captured evidence until verified contracts exist.
- Phase 4 captured evidence blocks Phase 5 typed hash/readiness proof.
- Phase 6 identity strategies block final readiness pass.
- Phase 7 compare/render readiness depends on evidence + identity.
- Phase 9 must complete before any runtime UI edits.
- Phase 11 completes after implementation and validation.
Parallel Opportunities
- T009-T012 can run in parallel because they cover separate inline fake payload categories.
- T013-T020 can run in parallel after preflight because they touch separate unit test files.
- T021-T030 can run in parallel after preflight because they touch separate feature/static guard tests.
- T056-T059 should be coordinated because they share
CoverageIdentityStrategyRegistry.php. - T095-T114 validation commands should run after implementation stabilizes.
Stop Conditions
- A mandatory resource type lacks production-safe source contract support and is treated as source-backed or compare/render-ready.
- A mandatory resource type lacks stable source-backed identity.
- A source is beta/experimental-only but is treated as certification-ready.
- Synthetic/fake evidence is counted as source-backed.
- Display name, order, payload hash, operation run ID, random UUID, or array index is used as stable identity.
- Capture bypasses provider gateway/GraphClientInterface or guesses endpoints.
- Certification, restore/apply, customer output, Review Pack/report/PDF/export, 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.