TenantAtlas/specs/437-exchange-comparable-promotion-slice-1/tasks.md
ahmido ff1a545c31 Spec 437: Exchange comparable promotion slice 1 (#504)
## Summary
- add Spec 437 package for Exchange comparable promotion slice 1
- add ExchangePowerShellComparablePayloadBuilder for normalized-payload-only comparable artifacts
- add focused Pest unit/feature coverage for comparable safety, determinism, redaction, and no product-surface promotion

## Validation
- cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent: PASS
- cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec437 --compact: failed with Symfony Process signal 9
- cd apps/platform && php artisan test --filter=Spec437 --compact: PASS, 34 tests / 225 assertions
- git diff --check: PASS

## Product Surface / Deployment
- UI impact: N/A - no rendered UI surface changed
- Browser proof: N/A - no rendered UI surface changed
- Destructive/high-impact actions: none
- Assets: none; no filament:assets requirement introduced
- Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, routes, jobs, listeners, commands, or Dokploy runtime behavior changes

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #504
2026-07-09 20:32:52 +00:00

13 KiB

Tasks: Spec 437 - Exchange Comparable Promotion Slice 1

Input: Design documents from specs/437-exchange-comparable-promotion-slice-1/ Prerequisites: spec.md, plan.md, checklists/requirements.md Tests: Required. Backend runtime behavior changes must be covered with Pest unit/feature tests. Browser proof is N/A - no rendered UI surface changed.

Test Governance Checklist

  • Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in Unit/Feature families; any heavy-governance or browser addition is explicit.
  • Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default.
  • Planned validation commands cover the change without pulling in unrelated lane cost.
  • Browser proof is explicitly N/A - no rendered UI surface changed.
  • Human Product Sanity is explicitly N/A - no product surface changed.
  • No material budget, baseline, trend, or escalation note is required unless implementation expands scope.

Phase 1 - Preflight

Purpose: Prove the implementation branch and prerequisites are safe before runtime work.

  • T001 Capture current branch, HEAD, and git status --short in specs/437-exchange-comparable-promotion-slice-1/implementation-report.md.
  • T002 Confirm Spec 436 PASS/merge-ready or merged state from specs/436-exchange-content-backed-evidence-promotion-slice-1/implementation-report.md.
  • T003 Confirm target scope is exactly transportRule, remoteDomain, and inboundConnector.
  • T004 Confirm comparable-only scope and renderable deferred.
  • T005 Confirm no UI/routes/jobs/schedules/listeners/commands/migrations/customer output are in scope.
  • T006 Confirm no tenant_id ownership truth, Exchange-specific compare table, or new OperationRun type is in scope.
  • T007 Confirm hard-gate skills have no stop condition: evidence immutability, OperationRun context, customer output, product surface, and TCM/Coverage v2 guard.

Checkpoint: Stop if Spec 436 proof is missing or any forbidden expansion is required.

Phase 2 - Comparable Builder Foundation

Purpose: Add normalized-payload-only comparable derivation.

  • T008 Add apps/platform/tests/Unit/Support/TenantConfiguration/Spec437ExchangeComparablePayloadBuilderTest.php with failing tests for normalized-payload-only input.
  • T009 Add apps/platform/app/Services/TenantConfiguration/ExchangePowerShellComparablePayloadBuilder.php.
  • T010 Ensure the builder accepts resource type, Spec 436 normalized_payload, required valid SHA-256 payload_hash, required content-backed/captured provenance metadata, and no raw payload/stdout/stderr/transcript/context arguments; stable material identity must be derived from normalized_payload.source_identity, not externally supplied metadata.
  • T011 Ensure unsupported resource types return no comparable payload or explicit blocker.
  • T012 Ensure builder output includes workload exchange, resource type, stable identity field plus scoped HMAC anchor derived from normalized_payload.source_identity, value-policy-validated safe material fields, redacted markers/counts/states, and safe normalizer/source metadata.
  • T013 Ensure builder output excludes raw provider object, raw stdout/stderr/transcript, credentials, OperationRun context, customer prose, risk verdicts, restore instructions, and certification labels.

Checkpoint: Builder exists and cannot consume forbidden inputs by API shape or tests.

Phase 3 - transportRule Comparable Payload

Purpose: Prove safe deterministic transport rule comparable payloads.

  • T014 Add tests for transportRule stable identity and deterministic comparable output.
  • T015 Implement transportRule mapping for enabled/state/mode safe fields.
  • T016 Include priority/order when semantically material.
  • T017 Represent conditions/actions/exceptions through redacted deterministic structures.
  • T018 Exclude raw rule text, raw patterns, sensitive raw header values, sensitive raw email addresses, raw provider payload, and raw stdout/stderr.
  • T019 Add tests for material change, volatile-only change, and provider ordering change.

Checkpoint: transportRule comparable payload is safe and deterministic.

Phase 4 - remoteDomain Comparable Payload

Purpose: Prove safe deterministic remote domain comparable payloads.

  • T020 Add tests for stable source identity and deterministic remoteDomain comparable output.
  • T021 Block domain-only and display-only identity from comparable payload creation, including case and separator variants such as domain_name and DISPLAY_NAME.
  • T022 Represent safe settings and default/custom classification only where safe.
  • T023 Represent protected domain/settings values through redacted presence/count/state semantics.
  • T024 Exclude raw domain values if protected, raw provider payload, and raw stdout/stderr.
  • T025 Add tests for material change, volatile-only change, redacted-count hash change, missing/non-content-backed evidence, and unsafe identity.

Checkpoint: remoteDomain comparable payload is safe and deterministic.

Phase 5 - inboundConnector Comparable Payload

Purpose: Prove safe deterministic inbound connector comparable payloads.

  • T026 Add tests for stable connector identity and deterministic inboundConnector comparable output.
  • T027 Represent routing/TLS/protected config through safe presence/count/state categories.
  • T028 Exclude raw IPs, hosts, smart hosts, certificate names, comments, routing metadata, raw provider payload, and raw stdout/stderr.
  • T029 Add tests for protected config redaction, no exact-value exposure, and malformed exact safe field blockers.
  • T030 Add tests for material change, volatile-only change, provider ordering change, redacted-count hash change, missing/non-content-backed evidence, and unsafe identity.

Checkpoint: inboundConnector comparable payload is safe and deterministic.

Phase 6 - Determinism and Optional Delta Semantics

Purpose: Prove comparable behavior is stable and machine-oriented.

  • T031 Add tests proving same normalized material produces the same comparable payload.
  • T032 Add tests proving material changes change comparable payload.
  • T033 Add tests proving volatile changes do not change comparable payload.
  • T034 Add tests proving provider ordering does not change comparable payload when order is not meaningful.
  • T035 If repo architecture requires comparison output, add apps/platform/app/Services/TenantConfiguration/ExchangePowerShellCoverageComparator.php. Implementation note: N/A - repository architecture did not require a comparator for this comparable-payload-only slice.
  • T036 If comparator is added, add tests for only machine categories: added, removed, changed, unchanged, redacted_value_changed, redacted_presence_changed, redacted_count_changed. Implementation note: N/A - no comparator added.
  • T037 If comparator is added, test that customer-facing categories such as critical_risk, non_compliant, certified_change, restore_required, and security_failure never appear. Implementation note: N/A - no comparator added.

Checkpoint: Comparable semantics are deterministic; delta semantics are safe if added.

Phase 7 - Evidence Immutability and Empty/Missing/Unsafe Evidence

Purpose: Prove comparable promotion does not rewrite source evidence.

  • T038 Add apps/platform/tests/Feature/TenantConfiguration/Spec437ExchangeComparablePromotionFeatureTest.php.
  • T039 Test comparable derivation does not mutate raw_payload.
  • T040 Test comparable derivation does not mutate normalized_payload.
  • T041 Test comparable derivation does not mutate payload_hash.
  • T042 Test comparable derivation does not mutate operation_run_id or OperationRun provenance.
  • T043 Test comparable derivation does not mutate persisted coverage_level, latest_evidence_state, latest_claim_state, latest_payload_hash, TenantConfigurationResourceType.default_coverage_level, or prior evidence rows.
  • T044 Test empty collection has no comparable artifact because no Spec 436 evidence row exists.
  • T045 Test missing evidence has no comparable artifact.
  • T046 Test unsafe identity and blocked target have no comparable artifact.

Checkpoint: Comparable artifacts require safe content-backed evidence and evidence rows remain immutable.

Phase 8 - Redaction and No Raw Input Guards

Purpose: Prove protected values and forbidden input sources cannot leak.

  • T047 Add tests proving raw provider payload is not comparable input.
  • T048 Add tests proving raw stdout/stderr/transcript are impossible compare inputs.
  • T049 Add tests proving OperationRun context is not compare input.
  • T050 Add tests proving credential material, tokens, authorization headers, cookies, secrets, unexpected exact protected/sensitive values, malformed exact safe values, and invalid payload hashes do not appear in comparable payloads.
  • T051 Add tests proving inbound connector raw IP ranges, hosts, smart hosts, certificate names, comments, and routing metadata do not appear.
  • T052 Add tests proving remote domain protected values do not appear.
  • T053 Add tests proving transport rule sensitive values do not appear.
  • T054 Test GenericPayloadNormalizer and ExchangeTeamsComparablePayloadNormalizer are not used for Spec 436 Exchange PowerShell comparable derivation.

Checkpoint: Comparable payloads do not leak protected config or forbidden input data.

Phase 9 - No Product Promotion / No Trigger Surface

Purpose: Prove Spec 437 remains comparable-only.

  • T055 Add or update feature/static tests proving no renderable state, render model, persisted comparable coverage-level promotion, or read-model output is added.
  • T056 Add or update feature/static tests proving no certification, restore, customer-ready, customer-claimable, customer-safe summary, report, Review Pack, or PDF output is added.
  • T057 Add or update feature/static tests proving no route, Filament page/resource/widget, Livewire component, Blade view, navigation, asset/global search change, or CoverageV2ReadinessReadModel rendered output is added.
  • T058 Add or update feature/static tests proving no job, schedule, listener, console command, provider registration change, or runtime trigger is added.
  • T059 Add or update feature/static tests proving no migration, tenant_id, Exchange-specific compare table, legacy shim, fallback reader, or Exchange mini-platform is added.
  • T060 Record browser proof as N/A - no rendered UI surface changed.

Checkpoint: No rendered or background trigger surface changed.

Phase 10 - Regression Tests

Purpose: Prove adjacent Coverage v2 and Exchange readiness behavior remains intact.

  • T061 Run focused Spec 437 unit/feature tests.
  • T062 Run Spec 436 regression.
  • T063 Run Spec 435 regression.
  • T064 Run Spec 434 regression.
  • T065 Run Spec 433 regression.
  • T066 Run Spec 432/431/430 regression.
  • T067 Run Spec 421/425 Entra comparable/certified guard regression if available.
  • T068 Run Spec 415/417/419/420/426/427 Coverage v2/evidence/identity/source-contract regression.
  • T069 Run ProviderCapabilityRegistryTest or equivalent.

Checkpoint: Existing readiness/capture/identity/evidence behavior remains intact.

Phase 11 - Validation and Close-Out

Purpose: Complete final checks and implementation report.

  • T070 Run cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent.
  • T071 Run cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec437 --compact.
  • T072 Run cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec436|Spec435|Spec434|Spec433|Spec432|Spec431|Spec430' --compact.
  • T073 Run cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec421|Spec425|Spec415|Spec417|Spec419|Spec420|Spec426|Spec427|ProviderCapabilityRegistry' --compact.
  • T074 Run git diff --check.
  • T075 Run git status --short.
  • T076 Complete specs/437-exchange-comparable-promotion-slice-1/implementation-report.md with candidate gate result, branch/HEAD, dirty state before/after, files changed, Spec 436 prerequisite proof, target comparable matrix, safety matrix, no persisted coverage-level promotion proof, tests run, browser N/A, deployment impact, and deferred work.

Checkpoint: Validation passes or exact failures are documented.

Dependencies & Execution Order

  • Phase 1 blocks all implementation.
  • Phase 2 blocks target-specific comparable payload work.
  • Phases 3-5 may proceed in parallel after Phase 2 if separate files/helpers are used.
  • Phase 6 depends on Phases 3-5.
  • Phases 7-9 depend on builder behavior.
  • Phase 10 depends on implementation and focused tests.
  • Phase 11 is final.

Hard Stops

Stop and amend or split if implementation requires any of:

  • renderable output
  • raw payload/stdout/stderr/transcript/OperationRun context as compare input
  • protected config exact-value exposure
  • evidence payload/provenance mutation
  • persisted coverage_level = comparable promotion or resource/resource-type coverage state mutation
  • certification/restore/customer claims
  • UI/routes/jobs/schedules/listeners/commands/provider registration
  • migration or Exchange-specific compare table
  • tenant_id ownership truth
  • new OperationRun type
  • additional Exchange or Teams target types