TenantAtlas/specs/422-exchange-teams-comparable-renderable-pack/implementation-report.md
Ahmed Darrazi 4c1e14c6bc
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 6m9s
feat: complete spec 422 exchange teams comparable renderable pack
2026-06-30 06:18:15 +02:00

16 KiB

Implementation Report: Spec 422 - Exchange & Teams Comparable / Renderable Pack

Preflight

  • Active spec: specs/422-exchange-teams-comparable-renderable-pack/
  • Branch: 422-exchange-teams-comparable-renderable-pack
  • HEAD: 69d4ecbb feat: complete spec 421 Entra comparable/renderable pack (#488)
  • Initial dirty state: untracked active spec directory only.
  • Activated skills: spec-kit-implementation-loop, pest-testing, .agent/workflows/spec-readiness-gate, .agent/repo-contracts/workspace-scope-safety, .agent/repo-contracts/rbac-action-safety, .agent/repo-contracts/evidence-anchor-contract, .agent/repo-contracts/product-surface-gate, .agent/workflows/filament-livewire-v5-change-loop.
  • Hard-gate stop conditions checked: no unrelated dirty files; no completed spec rewrite; no new capture/source contract; no restore/apply/certification/customer output; no new route/navigation/action/table; no OperationRun lifecycle change; no tenant_id ownership path; no raw payload/default customer proof; no render-time Graph/TCM/provider/HTTP call.

Completed-Spec Guardrail

Specs 414, 415, 417, 418, 419, 420, and 421 were used as read-only dependency context. No files under their spec directories were edited.

Exchange/Teams Evidence Matrix

Canonical type Workload Current repo source truth Spec 422 result
transportRule Exchange Registry-only M365 representative entry; no source contract mapping; capture stays blocked/deferred. Typed compare/render support for content-backed rows only; live capture deferred.
acceptedDomain Exchange Explicit Spec 420 missing-contract blocker in CoverageSourceContractResolver. Typed compare/render support for content-backed rows only; live capture deferred as missing contract.
remoteDomain Exchange Registry-only M365 representative entry; no source contract mapping. Deferred.
organizationConfig Exchange Registry-only M365 representative entry; no source contract mapping. Deferred.
sharedMailbox Exchange Registry-only M365 representative entry; no source contract mapping. Deferred.
mailboxPlan Exchange Registry-only M365 representative entry; no source contract mapping. Deferred.
appPermissionPolicy Teams Explicit Spec 420 missing-contract blocker in CoverageSourceContractResolver. Typed compare/render support for content-backed rows only; live capture deferred as missing contract.
appSetupPolicy Teams Registry-only M365 representative entry; no source contract mapping. Deferred.
meetingPolicy Teams Registry-only M365 representative entry; no source contract mapping; capture stays blocked/deferred. Typed compare/render support for content-backed rows only; live capture deferred.
messagingPolicy Teams Registry-only M365 representative entry; no source contract mapping. Deferred.
teamsUpdateManagementPolicy Teams Registry-only M365 representative entry; no source contract mapping. Deferred.
voiceRoute Teams Registry-only M365 representative entry; no source contract mapping. Deferred.

Implementation Summary

  • Added bounded typed Exchange/Teams services under apps/platform/app/Services/TenantConfiguration/:
    • ExchangeTeamsComparablePayloadNormalizer
    • ExchangeTeamsCoverageComparator
    • ExchangeTeamsRenderableSummaryBuilder
  • Integrated renderable promotion in CoverageEvidenceWriter for content-backed typed rows only.
  • Integrated typed Exchange/Teams summaries and compare summaries into CoverageV2ReadinessReadModel.
  • Updated the existing Coverage v2 inspect modal to render generic summary_fields while preserving the Entra-specific fallback shape.
  • Extended ClaimGuard so strictly scoped internal comparable/renderable wording is allowed for selected Exchange and Teams resources, while broad Exchange/Teams/M365 claims remain blocked.
  • Hardened transport-rule redaction so content-bearing condition/action keys such as subject/body or attachment content matchers are diagnostics-only and never render values or material compare before/after data.
  • Hardened Claim Guard so broad Exchange/Teams/M365 comparable/renderable wording is blocked unless it is explicitly scoped to selected internal/operator review.
  • Hardened transport-rule redaction again for header matchers, HTML disclaimer text, subject/header mutation actions, and attachment filename/pattern matchers after review found additional content-bearing keys could still render.
  • Hardened Claim Guard again so terse full, complete, or all workload-only Exchange/Teams/M365 claims are blocked instead of downgraded to limited.
  • Hardened Claim Guard a third time so plain broad workload coverage/support wording such as Exchange coverage, Teams supported, or M365 coverage is blocked while selected internal comparable/renderable wording and registry-scoped internal denominator wording remain internal-only.
  • Productized the shared Coverage v2 resource inspect surface after review: resource tables no longer show canonical keys as default row descriptions; the inspect slide-over shows operator-safe summary/context by default; source class, canonical type/key, evidence hash, source contract/schema, identity reason, and OperationRun links are hidden behind View technical details; duplicate claim/identity/capture rows were removed from typed Exchange/Teams summaries; Teams app permission summaries no longer display provider app IDs by default.
  • Added focused Pest unit, feature, and browser coverage for normalization, compare, render, redaction, claims, promotion, no-restore/no-certification, scope/provider boundaries, no tenant_id, and no mini-platform drift.

Promoted Types

Canonical type Normalizer Compare Render Promotion path
transportRule display name, enabled/state, priority/order, mode, conditions, actions, exceptions, diagnostics enabled critical; actions/conditions/exceptions/priority/mode material; volatile ignored summary fields for display/enabled/priority/mode/conditions/actions/exceptions Content-backed synthetic/existing evidence rows can become renderable.
acceptedDomain domain name, domain type, default indicator, state, diagnostics domain/default critical; type/state material summary fields for domain/type/default/state Content-backed synthetic/existing evidence rows can become renderable.
appPermissionPolicy display name, policy mode, allowed/blocked apps, targets, diagnostics allowed/blocked apps critical; policy mode/targets material summary fields for policy mode, apps, targets Content-backed synthetic/existing evidence rows can become renderable.
meetingPolicy display name, state, external access, recording/transcription, lobby/admission, content sharing, diagnostics external/recording critical; lobby/content sharing/state material summary fields for external/recording/lobby/content sharing Content-backed synthetic/existing evidence rows can become renderable.

Deferred Types

remoteDomain, organizationConfig, sharedMailbox, mailboxPlan, appSetupPolicy, messagingPolicy, teamsUpdateManagementPolicy, and voiceRoute remain deferred because this implementation did not add source contracts or content-backed evidence capture for those types.

Product Surface Close-Out

  • Runtime UI files changed: apps/platform/resources/views/filament/modals/tenant-configuration/coverage-v2-resource-inspect.blade.php.
  • UI impact decision: Existing Coverage v2 Technical Annex inspect rendering only if typed summaries are present.
  • Product Surface exceptions: none.
  • No-legacy posture: no legacy UI, route, navigation, action, dashboard, or report surface added; existing Coverage v2 page/modal reused.
  • Product Surface Impact: Technical Annex detail disclosure only. No customer-facing output, restore/certify/export/download flow, or management-report content changed.
  • UI Surface Impact: Inspect modal can now show typed summary_fields for Exchange/Teams renderable evidence; existing Entra rendering remains compatible through fallback fields.
  • Page archetype: existing read-only registry/report page with read-only inspect slide-over.
  • Surface budgets: no new page/header/row actions, no new navigation, no new table, no new dashboard, no new asset bundle.
  • Technical Annex / deep-link demotion: raw technical evidence remains demoted; default modal content exposes operator-safe summary fields, material compare context, resource type, provider connection, capture time, and capture outcome only. Source class, canonical keys, hashes, source contracts, identity reason codes, and OperationRun links require explicit View technical details disclosure.
  • Canonical status vocabulary: reused detected, content_backed, comparable, renderable, claim/identity/evidence badge vocabulary; no new persisted status family.
  • Browser proof: ./vendor/bin/sail artisan test tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php passed, including assertions that technical proof is hidden by default and still available in the disclosure.
  • Human Product Sanity: passed after Productization fix loop. The 768px screenshot shows a focused operator summary, material changes, and a quiet technical disclosure instead of default-visible hashes, canonical keys, source contracts, or OperationRun links.
  • Visible complexity outcome: decreased. One existing inspect section gained typed rows only when data exists, while technical proof moved out of the default visual hierarchy.
  • Livewire v4: unchanged and compliant with current Filament v5 baseline.
  • Provider registration: unchanged; Laravel panel providers remain in bootstrap/providers.php.
  • Global search: unchanged; no Filament Resource was added or modified.
  • Destructive/high-impact actions: none added or modified.
  • Asset strategy: no new assets registered; no new filament:assets requirement beyond existing deployment practice.

Validation

  • ./vendor/bin/sail bin pint --dirty --format agent - passed.
  • ./vendor/bin/sail artisan test tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRedactionTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsClaimGuardTest.php - failed before the second hardening pass, then passed after the third Claim Guard hardening, 37 tests / 79 assertions.
  • ./vendor/bin/sail artisan test tests/Unit/Support/TenantConfiguration/Spec421EntraClaimGuardTest.php tests/Unit/Support/TenantConfiguration/ClaimGuardTest.php tests/Unit/Support/TenantConfiguration/Spec419M365ClaimGuardTest.php tests/Unit/Support/TenantConfiguration/Spec420M365CaptureClaimGuardTest.php - passed after the third Claim Guard hardening, 80 tests / 84 assertions.
  • ./vendor/bin/sail artisan test tests/Unit/Support/TenantConfiguration/Spec422ExchangeTransportRuleNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeAcceptedDomainNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec422TeamsAppPermissionPolicyNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec422TeamsMeetingPolicyNormalizerTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsComparableDiffTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRenderableSummaryTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRedactionTest.php tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsClaimGuardTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsCoverageLevelPromotionTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsComparableRenderableTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoRestoreNoCertificationTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoTenantIdTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsNoMiniPlatformTest.php - passed after the third Claim Guard hardening, 70 tests / 280 assertions.
  • ./vendor/bin/sail artisan test tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php - passed, 1 test / 53 assertions.
  • ./vendor/bin/sail artisan test tests/Unit/Support/TenantConfiguration/Spec421EntraClaimGuardTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraComparableDiffTest.php tests/Unit/Support/TenantConfiguration/Spec421EntraRenderableSummaryTest.php tests/Feature/TenantConfiguration/Spec421EntraComparableRenderableTest.php tests/Feature/TenantConfiguration/Spec421EntraCoverageLevelPromotionTest.php tests/Feature/Filament/CoverageV2ReadinessPageTest.php - passed, 28 tests / 193 assertions.
  • ./vendor/bin/sail artisan test tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php - passed, 1 test / 54 assertions.
  • Combined Spec 421/422 focused regression run passed after the third Claim Guard hardening, 98 tests / 473 assertions.
  • Full smoke lane passed after the third Claim Guard hardening: Spec 422 focused unit/feature, Spec 421 comparable/renderable/readiness regression, and Spec 419/420/shared Claim Guard regression, 136 tests / 515 assertions.
  • Manual Claim Guard probe passed: plain broad Exchange coverage, Teams supported, and M365 coverage evaluate to claim_blocked; selected internal comparable/renderable and registry-scoped internal denominator wording evaluate to internal_only.
  • Combined Spec 421/422 browser smoke passed, 2 tests / 107 assertions.
  • Productization fix loop validation:
    • ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRenderableSummaryTest.php tests/Feature/Filament/CoverageV2ReadinessPageTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsComparableRenderableTest.php - passed, 19 tests / 178 assertions.
    • ./vendor/bin/sail artisan test --compact tests/Browser/Spec418CoverageV2OperatorSurfaceSmokeTest.php tests/Browser/Spec420M365GenericEvidenceOperatorSurfaceSmokeTest.php tests/Browser/Spec421EntraComparableRenderableOperatorSurfaceSmokeTest.php tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php - passed, 4 tests / 206 assertions.
    • Final focused rerun after duplicate-status pruning: ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration/Spec422ExchangeTeamsRenderableSummaryTest.php tests/Feature/Filament/CoverageV2ReadinessPageTest.php tests/Feature/TenantConfiguration/Spec422ExchangeTeamsComparableRenderableTest.php - passed, 19 tests / 178 assertions; ./vendor/bin/sail artisan test --compact tests/Browser/Spec422ExchangeTeamsComparableRenderableOperatorSurfaceSmokeTest.php - passed, 1 test / 64 assertions.
    • ./vendor/bin/sail bin pint --dirty --format agent - passed.
  • git diff --check - passed.

Deployment Impact

  • No migrations.
  • No environment variables.
  • No queues/cron changes.
  • No storage/volume changes.
  • No frontend asset registration or bundling changes.
  • Existing deployment command posture remains sufficient; no additional filament:assets work is introduced by this spec.

Residual Risks / Follow-Up Candidates

  • Live capture/source contracts for Exchange/Teams remain intentionally deferred.
  • Optional Exchange/Teams types remain registry-only until content-backed evidence and explicit tests exist.
  • Restore/apply/certification/customer output remain out of scope and blocked from this implementation.
  • Content-backed rows from future capture work must continue to pass through redaction before typed render/compare.
  • Final dirty state after implementation: active Spec 422 runtime/test/spec changes only; no completed historical spec directories edited.