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

195 lines
13 KiB
Markdown

# Tasks: Spec 437 - Exchange Comparable Promotion Slice 1
**Input**: Design documents from `specs/437-exchange-comparable-promotion-slice-1/`
**Prerequisites**: [spec.md](./spec.md), [plan.md](./plan.md), [checklists/requirements.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
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- [x] New or changed tests stay in Unit/Feature families; any heavy-governance or browser addition is explicit.
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default.
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
- [x] Browser proof is explicitly `N/A - no rendered UI surface changed`.
- [x] Human Product Sanity is explicitly `N/A - no product surface changed`.
- [x] 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.
- [x] T001 Capture current branch, HEAD, and `git status --short` in `specs/437-exchange-comparable-promotion-slice-1/implementation-report.md`.
- [x] T002 Confirm Spec 436 PASS/merge-ready or merged state from `specs/436-exchange-content-backed-evidence-promotion-slice-1/implementation-report.md`.
- [x] T003 Confirm target scope is exactly `transportRule`, `remoteDomain`, and `inboundConnector`.
- [x] T004 Confirm comparable-only scope and renderable deferred.
- [x] T005 Confirm no UI/routes/jobs/schedules/listeners/commands/migrations/customer output are in scope.
- [x] T006 Confirm no `tenant_id` ownership truth, Exchange-specific compare table, or new OperationRun type is in scope.
- [x] 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.
- [x] T008 Add `apps/platform/tests/Unit/Support/TenantConfiguration/Spec437ExchangeComparablePayloadBuilderTest.php` with failing tests for normalized-payload-only input.
- [x] T009 Add `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellComparablePayloadBuilder.php`.
- [x] 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.
- [x] T011 Ensure unsupported resource types return no comparable payload or explicit blocker.
- [x] 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.
- [x] 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.
- [x] T014 Add tests for `transportRule` stable identity and deterministic comparable output.
- [x] T015 Implement `transportRule` mapping for enabled/state/mode safe fields.
- [x] T016 Include priority/order when semantically material.
- [x] T017 Represent conditions/actions/exceptions through redacted deterministic structures.
- [x] T018 Exclude raw rule text, raw patterns, sensitive raw header values, sensitive raw email addresses, raw provider payload, and raw stdout/stderr.
- [x] 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.
- [x] T020 Add tests for stable source identity and deterministic `remoteDomain` comparable output.
- [x] T021 Block domain-only and display-only identity from comparable payload creation, including case and separator variants such as `domain_name` and `DISPLAY_NAME`.
- [x] T022 Represent safe settings and default/custom classification only where safe.
- [x] T023 Represent protected domain/settings values through redacted presence/count/state semantics.
- [x] T024 Exclude raw domain values if protected, raw provider payload, and raw stdout/stderr.
- [x] 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.
- [x] T026 Add tests for stable connector identity and deterministic `inboundConnector` comparable output.
- [x] T027 Represent routing/TLS/protected config through safe presence/count/state categories.
- [x] T028 Exclude raw IPs, hosts, smart hosts, certificate names, comments, routing metadata, raw provider payload, and raw stdout/stderr.
- [x] T029 Add tests for protected config redaction, no exact-value exposure, and malformed exact safe field blockers.
- [x] 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.
- [x] T031 Add tests proving same normalized material produces the same comparable payload.
- [x] T032 Add tests proving material changes change comparable payload.
- [x] T033 Add tests proving volatile changes do not change comparable payload.
- [x] T034 Add tests proving provider ordering does not change comparable payload when order is not meaningful.
- [x] 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.
- [x] 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.
- [x] 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.
- [x] T038 Add `apps/platform/tests/Feature/TenantConfiguration/Spec437ExchangeComparablePromotionFeatureTest.php`.
- [x] T039 Test comparable derivation does not mutate `raw_payload`.
- [x] T040 Test comparable derivation does not mutate `normalized_payload`.
- [x] T041 Test comparable derivation does not mutate `payload_hash`.
- [x] T042 Test comparable derivation does not mutate `operation_run_id` or OperationRun provenance.
- [x] 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.
- [x] T044 Test empty collection has no comparable artifact because no Spec 436 evidence row exists.
- [x] T045 Test missing evidence has no comparable artifact.
- [x] 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.
- [x] T047 Add tests proving raw provider payload is not comparable input.
- [x] T048 Add tests proving raw stdout/stderr/transcript are impossible compare inputs.
- [x] T049 Add tests proving OperationRun context is not compare input.
- [x] 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.
- [x] T051 Add tests proving inbound connector raw IP ranges, hosts, smart hosts, certificate names, comments, and routing metadata do not appear.
- [x] T052 Add tests proving remote domain protected values do not appear.
- [x] T053 Add tests proving transport rule sensitive values do not appear.
- [x] 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.
- [x] T055 Add or update feature/static tests proving no renderable state, render model, persisted comparable coverage-level promotion, or read-model output is added.
- [x] 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.
- [x] 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.
- [x] T058 Add or update feature/static tests proving no job, schedule, listener, console command, provider registration change, or runtime trigger is added.
- [x] 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.
- [x] 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.
- [x] T061 Run focused Spec 437 unit/feature tests.
- [x] T062 Run Spec 436 regression.
- [x] T063 Run Spec 435 regression.
- [x] T064 Run Spec 434 regression.
- [x] T065 Run Spec 433 regression.
- [x] T066 Run Spec 432/431/430 regression.
- [x] T067 Run Spec 421/425 Entra comparable/certified guard regression if available.
- [x] T068 Run Spec 415/417/419/420/426/427 Coverage v2/evidence/identity/source-contract regression.
- [x] 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.
- [x] T070 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`.
- [x] T071 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec437 --compact`.
- [x] T072 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec436|Spec435|Spec434|Spec433|Spec432|Spec431|Spec430' --compact`.
- [x] T073 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec421|Spec425|Spec415|Spec417|Spec419|Spec420|Spec426|Spec427|ProviderCapabilityRegistry' --compact`.
- [x] T074 Run `git diff --check`.
- [x] T075 Run `git status --short`.
- [x] 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