# Tasks: Spec 422 - Exchange & Teams Comparable / Renderable Pack **Input**: Design documents from `/specs/422-exchange-teams-comparable-renderable-pack/` **Prerequisites**: `spec.md`, `plan.md`, `checklists/requirements.md`, completed Specs 414, 415, 417, 418, 419, 420, and 421 as read-only context **Tests**: Required. Runtime compare/render behavior must be covered with focused Pest unit and feature tests. Browser proof is required if rendered Coverage v2 output changes. ## Test Governance Checklist - [x] Lane assignment is named and is the narrowest sufficient proof for typed normalization, compare/render, redaction, claims, scope, and Product Surface behavior. - [x] New or changed tests stay in the smallest honest family, and any browser coverage is explicit. - [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default. - [x] Planned validation commands cover the change without pulling unrelated lane cost. - [x] Browser proof is explicitly `N/A - no rendered UI surface changed` when no UI output changes, and required when rendered output changes. - [x] Human Product Sanity and Product Surface implementation-report close-out are planned where applicable. - [x] Any optional Exchange/Teams type blocker is documented in the active spec or implementation report. ## Phase 1: Preflight And Repo Truth **Purpose**: Confirm current repo truth before implementation and prevent completed-spec rewrite. - [x] T001 Capture branch, HEAD, dirty state, activated skills, and hard-gate stop conditions in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md`. - [x] T002 Verify Specs 414, 415, 417, 418, 419, 420, and 421 are completed dependency context only and do not edit any files under their spec directories. - [x] T003 Inspect `apps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.php`, `CoverageSourceContractResolver.php`, `GenericContentEvidenceCaptureService.php`, `CoverageIdentityStrategyRegistry.php`, `CanonicalIdentityResolver.php`, `ClaimGuard.php`, `CoverageEvidenceWriter.php`, and `CoverageV2ReadinessReadModel.php` to confirm current Coverage v2 service names before editing. - [x] T004 Build the Exchange/Teams evidence matrix in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md` for `transportRule`, `acceptedDomain`, `remoteDomain`, `organizationConfig`, `sharedMailbox`, `mailboxPlan`, `appPermissionPolicy`, `appSetupPolicy`, `meetingPolicy`, `messagingPolicy`, `teamsUpdateManagementPolicy`, and `voiceRoute`, classifying each as content-backed, missing-contract, unsupported, identity-blocked, or deferred. - [x] T005 Confirm no runtime task needs new capture/source contracts, restore/apply, certification, customer output, new OperationRun type, new route/navigation/action, new table, or `tenant_id`; stop and amend the spec if any is required. ## Phase 2: Tests First - Typed Semantics And Claim Safety **Purpose**: Lock the business truth before implementation. - [x] T006 [P] Add transport rule typed normalization tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeTransportRuleNormalizerTest.php`. - [x] T007 [P] Add accepted domain typed normalization tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeAcceptedDomainNormalizerTest.php`. - [x] T008 [P] Add Teams app permission policy typed normalization tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422TeamsAppPermissionPolicyNormalizerTest.php`. - [x] T009 [P] Add Teams meeting policy typed normalization tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422TeamsMeetingPolicyNormalizerTest.php`. - [x] T010 [P] Add deterministic compare tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsComparableDiffTest.php` covering volatile-only no-change, material Exchange changes, material Teams changes, stable ordering, null/empty handling, redacted values, and unsupported fields. - [x] T011 [P] Add render summary tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRenderableSummaryTest.php` covering operator-safe summaries and no raw payload dependency. - [x] T012 [P] Add redaction tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRedactionTest.php` proving secrets, credentials, tokens, authorization headers, cookies, raw payload, provider response bodies, mail content, Teams chat/file content, recordings, transcripts, unsafe OperationRun diagnostic context, and unsafe audit metadata do not appear in render/compare summaries or default-visible diagnostics. - [x] T013 [P] Add Claim Guard tests in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsClaimGuardTest.php` allowing scoped internal comparable/renderable wording and blocking certified, restore-ready, customer-ready, full, all-resource, and 100 percent Exchange/Teams/M365 claims. - [x] T014 [P] Add evidence-gated promotion tests in `apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsCoverageLevelPromotionTest.php` proving selected types can promote only with content-backed evidence and missing-evidence Exchange/Teams types remain unpromoted. - [x] T015 [P] Add no-restore/no-certification tests in `apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoRestoreNoCertificationTest.php`. - [x] T016 [P] Add no-tenant-id/no-mini-platform tests or static guards in `apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoTenantIdTest.php` and `apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoMiniPlatformTest.php`. - [x] T017 [P] Add read authorization, provider-scope, and no-remote-render tests in `apps/platform/tests/Feature/TenantConfiguration/Spec422ExchangeTeamsComparableRenderableTest.php` proving non-member/wrong-scope denial, member-missing-capability denial, same-scope provider connection requirements, no Graph/TCM/provider calls during render/compare, and no new per-row query or service loop outside the existing read model for typed summaries. ## Phase 3: Evidence-Gated Promotion Path **Purpose**: Promote only proven evidence-backed types. - [x] T018 Update or extend `apps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.php` only if needed to keep selected Exchange/Teams comparable/renderable support internal and claim-safe; do not set restore/certified/customer defaults. - [x] T019 Update or extend the existing Coverage v2 promotion/read path in `apps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.php` or repo-equivalent service so comparable/renderable state is derived only from content-backed typed evidence. - [x] T020 Update or extend `apps/platform/app/Services/TenantConfiguration/CoverageEvidenceWriter.php` only if needed so eligible content-backed Exchange/Teams evidence rows can receive renderable/comparable coverage level through bounded typed summary support. - [x] T021 Ensure optional Exchange/Teams types stay unpromoted unless Phase 1 proves content-backed evidence and corresponding tests exist; record blockers in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md`. - [x] T022 Confirm `apps/platform/app/Support/TenantConfiguration/CoverageLevel.php` existing values are reused and no new persisted coverage/status/importance enum is added. - [x] T023 Confirm `apps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.php` is not expanded with new Exchange/Teams capture/source mappings unless this spec is amended first. ## Phase 4: Typed Exchange/Teams Normalization **Purpose**: Produce deterministic typed payloads for evidence-backed Exchange/Teams types. - [x] T024 Add or extend a bounded typed normalizer in `apps/platform/app/Services/TenantConfiguration/ExchangeTeamsComparablePayloadNormalizer.php` or the repo-equivalent Tenant Configuration service path. - [x] T025 [P] Implement `transportRule` normalization for display name, enabled/state, priority/order, condition summary, action summary, exception summary, mode/enforcement state, source version/schema, redacted diagnostics, and unsupported fields in the normalizer path from T024. - [x] T026 [P] Implement `acceptedDomain` normalization for domain name, domain type, default-domain indicator, state, source version/schema, redacted diagnostics, and unsupported fields in the normalizer path from T024. - [x] T027 [P] Implement `appPermissionPolicy` normalization for display name, allowed/blocked app summary, policy mode, assignment/target summary if available, source version/schema, redacted diagnostics, and unsupported fields in the normalizer path from T024. - [x] T028 [P] Implement `meetingPolicy` normalization for display name, external/anonymous access, recording/transcription, lobby/admission, content sharing, source version/schema, redacted diagnostics, and unsupported fields in the normalizer path from T024. - [x] T029 [P] Implement optional Exchange/Teams normalization only if Phase 1 proves content-backed evidence and the scope remains bounded; otherwise defer them in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md`. - [x] T030 Ensure typed normalization reuses `apps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.php` or its repo-equivalent redaction path before render/compare output. ## Phase 5: Deterministic Compare **Purpose**: Compare selected Exchange/Teams evidence without volatile noise or unsafe claims. - [x] T031 Add or extend a bounded comparator in `apps/platform/app/Services/TenantConfiguration/ExchangeTeamsCoverageComparator.php` or the repo-equivalent Tenant Configuration service path. - [x] T032 Implement change classification `added`, `removed`, `changed`, `unchanged`, `ignored_volatile`, `redacted`, and `unsupported_field` in the comparator path from T031. - [x] T033 Implement `transportRule` material change rules for enabled/state, conditions, actions, exceptions, priority/order, and mode/enforcement in the comparator path from T031. - [x] T034 Implement `acceptedDomain` material change rules for domain added/removed, domain type, default indicator, and state in the comparator path from T031. - [x] T035 Implement `appPermissionPolicy` material change rules for app allow/block changes, policy mode, and assignment/target summary if available in the comparator path from T031. - [x] T036 Implement `meetingPolicy` material change rules for external/anonymous meeting access, recording/transcription, lobby/admission, and content sharing in the comparator path from T031. - [x] T037 Implement derived importance labels `critical`, `important`, and `informational` only inside compare output; do not add a persisted enum/status family. - [x] T038 Ensure compare ordering is deterministic for arrays where order is not semantically meaningful and null/empty handling is explicit. - [x] T039 Implement optional type compare rules only when corresponding evidence-backed normalization exists; otherwise leave documented blockers in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md`. ## Phase 6: Operator-Safe Render Summaries **Purpose**: Let operators understand selected Exchange/Teams resources without raw payloads. - [x] T040 Add or extend a render summary builder in `apps/platform/app/Services/TenantConfiguration/ExchangeTeamsRenderableSummaryBuilder.php` or the repo-equivalent Tenant Configuration service path. - [x] T041 Implement `transportRule` render summary fields: display name, enabled/state, priority/order, condition/action/exception summaries, mode/enforcement, claim state, identity state, last captured, unsupported fields, and redaction markers. - [x] T042 Implement `acceptedDomain` render summary fields: domain name, domain type, default-domain indicator, state, claim state, identity state, last captured, unsupported fields, and redaction markers. - [x] T043 Implement `appPermissionPolicy` render summary fields: display name, allowed/blocked apps summary, policy mode, assignment/target summary if available, claim state, identity state, last captured, unsupported fields, and redaction markers. - [x] T044 Implement `meetingPolicy` render summary fields: display name, external/anonymous meeting access, recording/transcription, lobby/admission, content sharing, claim state, identity state, last captured, unsupported fields, and redaction markers. - [x] T045 Ensure render summaries never expose raw payload, raw provider response, tokens, credential values, private keys, certificate material, authorization headers, cookies, mail/message content, Teams chat/file content, recordings, transcripts, or unneeded PII. - [x] T046 Implement optional type render summaries only when Phase 1 proves content-backed evidence and matching tests exist; otherwise keep blocker/deferred summaries in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md`. ## Phase 7: Existing Surface Integration And Product Safety **Purpose**: Reuse the existing read-only Coverage v2 surface without adding product-surface risk. - [x] T047 If rendered output changes, update `apps/platform/app/Services/TenantConfiguration/CoverageV2ReadinessReadModel.php` to expose typed summaries through existing inspect details while keeping raw/technical evidence demoted. - [x] T048 If rendered output changes, update existing inspect modal views under `apps/platform/resources/views/filament/modals/tenant-configuration/` only as needed to display typed summaries with native/shared Filament semantics. - [x] T049 Confirm `apps/platform/app/Filament/Pages/TenantConfiguration/CoverageV2Readiness.php`, `CoverageV2ResourceTypesTable.php`, and `CoverageV2ResourceInstancesTable.php` expose no new action, route, navigation, start/capture, restore, certify, export, report, or customer output. - [x] T050 Confirm global search posture is unchanged because no Filament Resource is added or changed for global search. - [x] T051 Confirm no new assets are registered and no `filament:assets` requirement is introduced beyond existing deployment practice. - [x] T052 Ensure rendered labels do not include `Exchange covered`, `Teams covered`, `certified`, `restore-ready`, `customer-ready`, `full Exchange coverage`, `100% Teams`, or broad M365 readiness wording. ## Phase 8: Browser Proof If Rendered Output Changes **Purpose**: Prove the existing surface remains safe when summaries render. - [x] T053 Add `apps/platform/tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php` if rendered output changes. - [x] T054 In the browser smoke, seed a workspace, managed environment, provider connection, and selected content-backed Exchange/Teams evidence rows with comparable/renderable summary data. - [x] T055 In the browser smoke, load the existing Coverage v2 readiness route, open the inspect flow, and assert comparable/renderable state, operator-readable Exchange/Teams summary, no raw payload, no secrets, no mail/message/chat/file/recording/transcript content, no unsafe OperationRun/audit diagnostic metadata if diagnostics render, no restore/certified/customer-ready claim, no new high-impact action, no provider/network call during render, and no console/Livewire/Filament errors. - [x] T056 If no rendered output changes, document `N/A - no rendered UI surface changed` proof in `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md` instead of adding a browser test. ## Phase 9: Validation And Close-Out **Purpose**: Complete the implementation loop with explicit proof. - [x] T057 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`. - [x] T058 Run focused Spec 422 unit tests for normalization, compare, render, redaction, and Claim Guard. - [x] T059 Run focused Spec 422 feature tests for promotion, RBAC/scope, no restore/certification, no tenant_id, no mini-platform, and no overclaim. - [x] T060 Run focused Spec 422 browser test if rendered output changed, or record no-browser proof if not. - [x] T061 Run `git diff --check`. - [x] T062 Complete `specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md` with candidate gate, dirty state before/after, files changed, Exchange/Teams evidence matrix, promoted/deferred types, normalizer matrix, compare matrix, render matrix, Claim Guard proof, redaction proof including OperationRun diagnostic context and audit metadata posture, no restore/certification proof, no tenant_id proof, no mini-platform proof, Product Surface proof, Human Product Sanity result, visible complexity outcome, tests run, browser/no-browser, deployment impact, and deferred work. - [x] T063 Confirm no completed historical spec was rewritten, normalized, reopened, or stripped of validation/task/browser/review history. ## Dependencies - Phase 1 blocks all implementation. - Phase 2 tests should be written before or alongside Phases 3-7. - Phase 3 promotion path depends on Phase 1 evidence matrix. - Phase 4 typed normalization blocks Phases 5 and 6. - Phase 7 depends on Phases 3-6 only if rendered output changes. - Phase 8 depends on Phase 7 rendered output changes. - Phase 9 closes after all relevant implementation and validation tasks. ## Stop Conditions - New capture/source contract work is needed for selected Exchange/Teams types. - Restore/apply, certification, customer output, report/download/export, or broad Exchange/Teams/M365 claim is proposed. - A new route, navigation entry, dashboard, action, OperationRun type, persisted compare table, or Exchange/Teams-specific table family is proposed without amending this spec. - Raw payloads, secrets, credentials, tokens, provider response bodies, source keys, provider IDs, mail content, Teams chat/file content, recordings, or transcripts become default-visible. - `tenant_id` appears as Coverage v2 ownership truth. - Render/compare performs provider/Graph/TCM/HTTP work during page render. ## Implementation Strategy Deliver the MVP first: typed compare/render support for content-backed `transportRule`, `acceptedDomain`, `appPermissionPolicy`, and `meetingPolicy` evidence rows, plus Claim Guard/redaction/no-overclaim proof. Treat every other Exchange/Teams type and live capture/source-contract work as evidence-gated follow-through, not required scope. Stop and split if the implementation needs new capture contracts or broader product-surface work.