17 KiB
Implementation Plan: Spec 437 - Exchange Comparable Promotion Slice 1
Branch: feat/437-exchange-comparable-promotion-slice-1 | Date: 2026-07-09 | Spec: spec.md
Input: Feature specification from specs/437-exchange-comparable-promotion-slice-1/spec.md
Summary
Derive deterministic machine-comparable payloads for exactly transportRule, remoteDomain, and inboundConnector from immutable Spec 436 Exchange PowerShell content-backed evidence. The builder must consume only normalized_payload as material input, require a valid SHA-256 payload_hash plus content-backed/captured provenance gates, preserve existing evidence rows, keep persisted coverage state unchanged, represent protected values through redacted presence/count/safe-state semantics, emit stable identity as a scoped app-keyed HMAC anchor, enforce value policies for exact safe fields, keep compare-shape/source contract metadata hash-relevant, and add no renderable output, certification, restore, UI, customer output, jobs, schedules, listeners, migrations, tenant_id, new OperationRun type, or Exchange-specific compare table.
Technical Context
Language/Version: PHP 8.4 / Laravel 12
Primary Dependencies: Laravel, Pest 4, existing TenantConfiguration Coverage v2 services
Storage: Existing PostgreSQL-backed Coverage v2 tables are read only for this slice; no migration, comparable artifact persistence, or persisted coverage-level promotion planned
Testing: Pest unit and feature tests
Validation Lanes: fast-feedback and confidence; browser N/A
Target Platform: Laravel Sail locally, Dokploy/container deployment for staging/production
Project Type: Laravel monolith under apps/platform
Performance Goals: deterministic in-memory comparable derivation with no remote/provider calls
Constraints: normalized-payload-only material input, valid SHA-256 payload hash and content-backed/captured provenance required, evidence immutability, no persisted coverage_level = comparable, protected config redaction, exact safe field value policies, scoped HMAC identity anchors, no rendered surface
Scale/Scope: exactly three Exchange PowerShell resource types
UI / Surface Guardrail Plan
- Guardrail scope: no operator-facing surface change.
- Affected routes/pages/actions/states/navigation/panel/provider surfaces: N/A.
- No-impact class, if applicable: backend-only.
- Native vs custom classification summary: N/A.
- Shared-family relevance: backend Coverage v2 evidence/compare semantics only.
- State layers in scope: none.
- Audience modes in scope: N/A.
- Decision/diagnostic/raw hierarchy plan: N/A at UI layer; raw/provider/protected values must not enter comparable output.
- Raw/support gating plan: raw evidence remains internal storage only; comparable output contains no raw/protected exact values and does not update persisted coverage/readiness state.
- One-primary-action / duplicate-truth control: N/A.
- Handling modes by drift class or surface: hard stop if any rendered surface, route, action, report, download, or customer output appears.
- Repository-signal treatment: review-mandatory for any accidental UI/read-model/customer/report/trigger file change.
- Special surface test profiles: N/A.
- Required tests or manual smoke:
N/A - no rendered UI surface changed. - Exception path and spread control: none.
- Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
- UI/Productization coverage decision: No UI surface impact.
- Coverage artifacts to update: none.
- No-impact rationale: comparable-only backend service and tests.
- Navigation / Filament provider-panel handling: no changes.
- Screenshot or page-report need: no.
Product Surface Contract Plan
- Product Surface Contract reference:
docs/product/standards/product-surface-contract.mdchecked for no-rendered-surface path. - No-legacy posture: canonical bounded addition; no aliases, fallback readers, hidden routes, duplicate UI, old labels, or legacy fixtures.
- Page archetype and surface budget plan: N/A.
- Technical Annex and deep-link demotion plan: N/A at runtime; OperationRun/evidence/raw IDs/source keys/payloads are not rendered.
- Canonical status vocabulary plan: N/A - no product status vocabulary.
- Product Surface exceptions: none.
- Browser verification plan:
N/A - no rendered UI surface changed. - Human Product Sanity plan: N/A.
- Visible complexity outcome target: neutral.
- Implementation report target:
specs/437-exchange-comparable-promotion-slice-1/implementation-report.md.
Filament / Livewire / Deployment Posture
- Livewire v4 compliance: unchanged; no Livewire/Filament code changes.
- Panel provider registration location: unchanged; no panel provider registration change. Laravel panel providers remain under
apps/platform/bootstrap/providers.php. - Global search posture: unchanged; no Filament Resource changed.
- Destructive/high-impact action posture: none.
- Asset strategy: no assets; no new
filament:assetsrequirement. - Testing plan: focused unit and feature tests only; browser N/A.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, routes, jobs, listeners, or commands.
Shared Pattern & System Fit
- Cross-cutting feature marker: yes, backend Coverage v2 comparable semantics.
- Systems touched: existing TenantConfiguration evidence/comparable service layer.
- Shared abstractions reused: Spec 436 normalized evidence payloads; existing evidence models; existing hash/provenance metadata; app-keyed HMAC identity anchoring.
- New abstraction introduced? why?: bounded
ExchangePowerShellComparablePayloadBuilderbecause existing generic/ExchangeTeams compare paths do not enforce Spec 436 normalized-payload-only material input, required content-backed provenance, target-specific protected-value safety, exact safe field value policies, scoped identity HMAC anchoring, and no persisted coverage-level promotion for this slice. - Why the existing abstraction was sufficient or insufficient: Evidence storage is sufficient. Existing generic/ExchangeTeams comparable normalizers are insufficient and forbidden for this input path.
- Bounded deviation / spread control: provider-specific builder stays local to Exchange PowerShell evidence for three types; no platform-core status/persistence/UI/customer seam change.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no.
- Central contract reused: N/A.
- Delegated UX behaviors: N/A.
- Surface-owned behavior kept local: none.
- Queued DB-notification policy: N/A.
- Terminal notification path: N/A.
- Exception path: none.
OperationRun implementation posture:
- Do not add or modify
OperationRunTypeorOperationCatalog. - Do not use Exchange PowerShell invocation runs as comparable owners.
- Do not use OperationRun context as input.
- Do not store comparable payloads, deltas, raw output, transcripts, protected config, or customer text in OperationRun context/messages/notifications.
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes.
- Provider-owned seams: Exchange PowerShell comparable payload builder and target-specific safe field mapping.
- Platform-core seams: Coverage v2 evidence remains source truth; ownership remains workspace + managed environment + provider connection.
- Neutral platform terms / contracts preserved: evidence, comparable payload, normalized payload, resource type, workload, provider connection, managed environment, operation run provenance.
- Retained provider-specific semantics and why:
transportRule,remoteDomain,inboundConnector, Exchange PowerShell source metadata, and protected Exchange config semantics are required for this bounded slice. - Bounded extraction or follow-up path: Spec 438 internal render model is separate.
Constitution Check
| Principle / Gate | Result | Notes |
|---|---|---|
| Inventory-first / evidence truth | PASS | Comparable derives only when immutable evidence is content-backed/captured and does not promote persisted evidence coverage level. |
| Read/write separation | PASS | No provider writes, restore, apply, destructive action, or UI action. |
| Graph contract path | PASS | No Graph or Exchange call in Spec 437. |
| Deterministic capabilities | PASS | Comparable derivation is deterministic and testable. |
| Workspace isolation | PASS | No new ownership truth; evidence scope remains existing workspace/managed-environment/provider connection. |
| RBAC-UX | PASS | No routes/actions/resources/global search. |
| OperationRun truth | PASS | No new OperationRun type; context not input. |
| Evidence anchor contract | PASS | No fallback-to-latest or OperationRun-as-proof. |
| Data minimization | PASS | Raw/protected values excluded from comparable payloads; unexpected exact protected/sensitive values block output. |
| Product Surface | PASS | N/A - no rendered UI surface changed. |
| Customer output | PASS | No customer output, reports, Review Packs, PDFs, or customer claims. |
| Provider boundary | PASS | Provider-specific builder is bounded and local. |
| Test governance | PASS | Unit/Feature only; Browser N/A. |
| Proportionality | PASS | One bounded helper; no persistence/status/UI framework. |
| TCM/Coverage v2 cutover guard | PASS | No legacy adapters, fallback readers, dual writes, tenant_id, or customer claims. |
Test Governance Check
- Test purpose / classification by changed surface: Unit for builder/comparator determinism and redaction; Feature for evidence immutability and no-promotion/no-surface guards.
- Affected validation lanes: fast-feedback, confidence.
- Why this lane mix is the narrowest sufficient proof: Spec 437 changes backend comparable behavior only; no browser/render/provider execution lane is needed.
- Narrowest proving command(s):
cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec437 --compact- targeted regressions listed in Phase 6.
- Fixture / helper / factory / seed / context cost risks: reuse existing TenantConfiguration evidence factories/helpers; avoid global defaults.
- Expensive defaults or shared helper growth introduced?: no.
- Heavy-family additions, promotions, or visibility changes: none.
- Surface-class relief / special coverage rule: N/A.
- Closing validation and reviewer handoff: reviewer must verify valid payload hash and content-backed/captured provenance gates, scoped HMAC identity anchors, exact safe field value policies, no raw payload/context input, no evidence mutation, no UI/customer/trigger/persistence expansion, and exact target scope.
- Budget / baseline / trend follow-up: none.
- Review-stop questions: lane fit, redaction, evidence immutability, no-product-surface, no-mini-platform.
- Escalation path: none unless implementation requires renderable, persistence, UI, or migration; then amend/split.
- Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage.
- Why no dedicated follow-up spec is needed: comparable-only builder is the dedicated bounded slice; renderable is already deferred to Spec 438.
Project Structure
Documentation
specs/437-exchange-comparable-promotion-slice-1/
|-- checklists/
| `-- requirements.md
|-- implementation-report.md
|-- plan.md
|-- spec.md
`-- tasks.md
Source Code
Likely runtime paths if implementation proceeds:
apps/platform/app/Services/TenantConfiguration/
|-- ExchangePowerShellComparablePayloadBuilder.php
`-- ExchangePowerShellCoverageComparator.php # only if needed
apps/platform/tests/Unit/Support/TenantConfiguration/
`-- Spec437ExchangeComparablePayloadBuilderTest.php
apps/platform/tests/Feature/TenantConfiguration/
`-- Spec437ExchangeComparablePromotionFeatureTest.php
Structure Decision: Use existing TenantConfiguration service/test locations. Do not create new base folders, migrations, routes, UI surfaces, jobs, listeners, schedules, commands, or customer-output paths.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| New bounded builder helper | Required to enforce normalized-payload-only input and protected Exchange target semantics. | Reusing generic/ExchangeTeams normalizer would violate Spec 437 input and redaction gates. |
Proportionality Review
- Current operator problem: Future compare/render/certification work cannot safely proceed until Exchange evidence can be compared without leaking protected configuration or overclaiming readiness.
- Existing structure is insufficient because: Existing generic/ExchangeTeams comparable path predates Spec 436 normalized evidence and includes broader renderable behavior that Spec 437 explicitly defers.
- Narrowest correct implementation: One local builder for three concrete Exchange PowerShell target types; comparator only if needed; no persisted comparable artifact or coverage-level promotion.
- Ownership cost created: Focused tests and future review burden around redaction/determinism.
- Alternative intentionally rejected: Raw payload compare, normalized provider payload compare outside Spec 436 evidence, and ExchangeTeamsComparablePayloadNormalizer reuse.
- Release truth: Current-release prerequisite for the Exchange roadmap.
Phase 0 - Preflight
- Capture branch and HEAD.
- Capture
git status --short. - Confirm Spec 436 PASS/merge-ready or merged at current base.
- Confirm target types content-backed.
- Confirm comparable-only scope.
- Confirm renderable deferred.
- Confirm no UI/jobs/schedules/listeners/migration scope.
- Confirm no hard-gate stop condition.
Deliverable: Preflight documented in implementation-report.md.
Phase 1 - Comparable Builder
- Add Exchange PowerShell comparable payload builder.
- Use
normalized_payloadonly. - Require a valid SHA-256
payload_hash,evidence_state = content_backed,coverage_level = content_backed, andcapture_outcome = captured. - Forbid raw payload/stdout/stderr/transcript input.
- Forbid OperationRun context input.
- Add deterministic output shape.
Deliverable: Comparable builder exists and is covered by unit tests.
Phase 2 - Target Comparable Payloads
- Add
transportRulecomparable payload. - Add
remoteDomaincomparable payload. - Add
inboundConnectorcomparable payload. - Encode protected config using redacted presence/count/safe-state semantics.
- Block unexpected exact protected/sensitive values rather than sanitizing them through.
- Validate exact safe fields by target-specific value policy before output.
- Emit stable identity through scoped HMAC anchors instead of exact values or unsalted hashes.
- Keep compare-shape and normalizer contract metadata hash-relevant; exclude run/evidence provenance from comparable hash.
- Exclude volatile fields.
Deliverable: Three target comparable payloads.
Phase 3 - Determinism / Delta Semantics
- Prove deterministic comparable payload.
- Prove material changes produce changed comparable payload or machine deltas.
- Prove volatile changes ignored.
- Prove provider ordering deterministic.
- Add comparator only if repo architecture requires it.
Deliverable: Comparable semantics are deterministic.
Phase 4 - Safety / Immutability
- Prove evidence rows are not mutated.
- Prove persisted coverage/resource/resource-type state is not promoted to comparable.
- Prove no raw payload leaks.
- Prove OperationRun context is not compare input.
- Prove no renderable/customer/cert/restore state.
Deliverable: Comparable promotion without overclaim.
Phase 5 - Product Surface Guard
- Prove no UI/routes/jobs/schedules/listeners.
- Prove no report/review-pack/PDF/customer output.
- Prove browser N/A.
Deliverable: No product surface changed.
Phase 6 - Regression / Report
- Run focused tests.
- Run regressions.
- Run Pint.
- Run
git diff --check. - Complete implementation report.
Deliverable: Spec 437 implementation report.
Rollout Considerations
- No migration or deployment flag.
- No queue/scheduler/storage/asset change.
- No
filament:assetsrequirement introduced by this spec. - Comparable derivation remains internal backend behavior until a later spec explicitly adds render/read-model/customer surfaces.
Risk Controls
- Hard stop on raw payload/context input.
- Hard stop on protected exact value leakage.
- Hard stop on missing content-backed/captured provenance.
- Hard stop on invalid payload hash or malformed exact safe field values.
- Hard stop on evidence mutation.
- Hard stop on UI/read-model/customer/report/trigger/migration expansion.
- Hard stop on new OperationRun type or tenant_id ownership truth.
- Use static/no-surface tests in addition to behavior tests.