TenantAtlas/specs/435-exchange-structured-output-target-normalizer-readiness/tasks.md
ahmido a09cc6ca8d Spec 435: Exchange structured output readiness (#502)
## Summary

- Add Spec 435 backend-only Exchange structured output envelope and target normalizer readiness helpers for transportRule, remoteDomain, and inboundConnector.
- Add deterministic hash input/readiness handling and no-promotion guard coverage.
- Add Spec 435 spec, plan, tasks, checklist, and implementation report artifacts.

## Validation

- git diff --cached --check
- cd apps/platform && php artisan test --filter=Spec435 --compact

## Product Surface / Deployment

- Livewire v4 compliance unchanged.
- Filament provider registration unchanged under apps/platform/bootstrap/providers.php.
- Global search unchanged; no resources added or modified.
- Destructive/high-impact actions: none.
- Asset strategy: none; no filament:assets requirement for this slice.
- Browser proof: N/A - no rendered UI surface changed.
- Deployment impact: no env vars, migrations, queues, scheduler, storage, assets, or Dokploy runtime behavior changes.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #502
2026-07-08 14:33:23 +00:00

16 KiB

Tasks: Exchange Structured Output and Target Normalizer Readiness

Input: Design documents from specs/435-exchange-structured-output-target-normalizer-readiness/ Prerequisites: spec.md, plan.md, checklists/requirements.md Implementation Mode: structured-output and normalizer readiness only. No evidence rows, no content-backed promotion, no compare/render, no certification, no restore, no UI, no customer claims, no jobs/schedules/listeners, no migrations, no tenant_id.

Test Governance Checklist

  • Lane assignment is named as Unit/Feature fast-feedback/confidence and is the narrowest sufficient proof for readiness behavior.
  • New or changed tests stay in focused Spec 435 families; no heavy-governance or browser family is added accidentally.
  • Fixtures stay local to Exchange structured-output and target normalizer readiness tests.
  • Planned validation commands cover readiness and regressions without broad unrelated lane cost.
  • Browser proof is explicitly N/A - no rendered UI surface changed.
  • Human Product Sanity and Product Surface implementation-report close-out are N/A - no rendered UI surface changed.
  • Any migration, UI, customer-output, evidence-persistence, or target-expansion need is escalated to spec amendment or follow-up spec.

Phase 1: Preflight

Purpose: Lock repo truth and prerequisites before runtime work.

  • T001 Capture current branch, HEAD, and git status --short in specs/435-exchange-structured-output-target-normalizer-readiness/implementation-report.md; before runtime/test implementation, confirm the branch is feat/435-exchange-structured-output-target-normalizer-readiness or record an explicit Spec Kit branch-name exception.
  • T002 Confirm Specs 430-434 are completed or implementation-closed read-only context and are not edited.
  • T003 Confirm Spec 434 implementation report is PASS/merge-ready and no stale checklist/report blocker remains open for this readiness slice.
  • T004 Confirm Spec 433 readiness proof remains sufficient for client-secret blocking, scoped/current Exchange.ManageAsApp, combined readiness, provider capability support, and runner gate consumption.
  • T005 Confirm Spec 432 production runner boundary, process executor abstraction, output guard, timeout/concurrency guards, and sanitized OperationRun context exist.
  • T006 Confirm target scope is exactly transportRule, remoteDomain, and inboundConnector.
  • T007 Confirm implementation starts with no evidence rows, no Microsoft calls, no real Exchange Online connection, no tenant PowerShell execution, no UI/routes/jobs/schedules/listeners, no migration, no tenant_id, no compare/render/certification/restore/customer output, and no target expansion.

Phase 2: Structured Output Envelope

Purpose: Prove runner output has a safe structured contract before normalizer readiness.

  • T008 Add ExchangePowerShellStructuredOutputEnvelope or repo-canonical equivalent under apps/platform/app/Services/TenantConfiguration/.
  • T009 Include resource type, command contract name/version, exchange_online_powershell_rest, runner mode, shape state, items, item count, empty collection marker, warnings classification, output guard state, normalizer readiness state, redaction readiness state, and identity readiness state.
  • T010 Exclude raw stdout, raw stderr, transcripts, serialized Exchange object text, credential material, provider secrets, tokens, authorization headers, and cookies from envelope state.
  • T011 Add unit tests proving structured collection and structured empty collection are accepted as envelope states.
  • T012 Add tests proving malformed output maps to a readiness blocker.
  • T013 Add tests proving scalar output maps to a readiness blocker.
  • T014 Add tests proving warning-prefixed output blocks or classifies safely without normalizer readiness.
  • T015 Add tests proving binary/non-UTF8 output blocks.
  • T016 Add tests proving oversized output blocks.
  • T017 Add tests proving non-zero exit blocks.
  • T018 Add tests proving timeout blocks.
  • T019 Add tests proving raw runner output is not evidence and is not copied into OperationRun context/logs/summaries.
  • T020 Add tests proving structured-output readiness uses fake process executor or fake runner output only.

Phase 3: Target Normalizer Readiness

Purpose: Define target-specific readiness without evidence persistence.

  • T021 Add or refine ExchangePowerShellEvidenceNormalizer or repo-canonical target readiness dispatcher.
  • T022 Add or refine ExchangeTransportRuleEvidenceNormalizer or repo-canonical equivalent.
  • T023 Add or refine ExchangeRemoteDomainEvidenceNormalizer or repo-canonical equivalent.
  • T024 Add or refine ExchangeInboundConnectorEvidenceNormalizer or repo-canonical equivalent.
  • T025 Each target readiness definition must include resource type, source surface, command contract name/version, payload shape version, normalizer version, identity candidate fields, material fields, volatile fields, sensitive fields, ordering rules, hash input rules, redaction policy, and readiness blockers.
  • T026 Add tests proving normalized payload previews are in-memory/test-only, are not persisted as evidence, and readiness dispatch does not invoke ExchangePowerShellEvidenceCaptureAdapter::capture(), CoverageResourceUpserter::upsert(), or CoverageEvidenceWriter::append().

Phase 4: transportRule Readiness

Purpose: Make transportRule ready for Spec 436 evidence promotion.

  • T027 Define transportRule stable identity candidate fields and tests.
  • T028 Define priority/order handling and tests.
  • T029 Define state/mode handling and tests.
  • T030 Normalize conditions/actions/exceptions deterministically and add tests.
  • T031 Exclude or demote volatile fields and add tests proving volatile-only changes do not affect hash preview.
  • T032 Classify sensitive patterns, words, and header values and prove they do not enter OperationRun context/logs/summaries.
  • T033 Define deterministic collection ordering and hash input rules.
  • T034 Add tests proving same material payload gives same hash preview and material change gives different hash preview.

Phase 5: remoteDomain Readiness

Purpose: Prove stable remoteDomain identity or block explicitly.

  • T035 Decide whether source Identity can be proven stable from current contracts/fixtures.
  • T036 If proven, add tests distinguishing default remote domain and custom remote domains.
  • T037 If proven, add tests blocking missing Identity.
  • T038 If proven, add tests blocking duplicate Identity.
  • T039 Add tests blocking display-name-only identity.
  • T040 Add tests blocking domain-only derived identity unless explicitly proven safe.
  • T041 Add tests blocking identity conflict and unsupported identity.
  • T042 N/A - remoteDomain source Identity readiness was proven for default/custom fixtures; blocker path remains covered by missing/display/domain-only/duplicate/conflict tests.
  • T043 Define settings normalization, volatile fields, sensitive fields, ordering rules, redaction policy, and hash input rules.
  • T044 Add tests proving remoteDomain readiness is either complete or explicitly blocked without evidence creation.

Phase 6: inboundConnector Readiness

Purpose: Prove inboundConnector identity and redaction safety or block explicitly.

  • T045 Decide whether stable connector identity can be proven from current contracts/fixtures.
  • T046 Add tests blocking missing connector identity.
  • T047 Add tests blocking duplicate connector identity.
  • T048 Add tests blocking identity conflict and unsupported identity.
  • T049 Classify IP addresses as protected config and add tests.
  • T050 Classify smart hosts as protected config and add tests.
  • T051 Classify certificate names as protected config and add tests.
  • T052 Classify comments as potentially sensitive and add tests.
  • T053 Classify routing metadata as protected config and add tests.
  • T054 Prove protected config, raw provider payloads, serialized objects, transcripts, mail/message/file content, credentials, secrets, tokens, authorization headers, and cookies do not enter OperationRun context/logs/summaries.
  • T055 N/A - inboundConnector protected-config redaction was proven for IPs, smart hosts, certificate names, comments, and routing metadata; blocker path remains fail-closed through explicit readiness blockers.
  • T056 Define deterministic material fields, volatile fields, ordering rules, and hash input rules.
  • T057 Add tests proving inboundConnector readiness is either complete or explicitly blocked without evidence creation.

Phase 7: Hash, Empty Collection, Failure, and No-Promotion Safety

Purpose: Prove cross-target safety invariants.

  • T058 Add ExchangePowerShellHashInputBuilder or repo-canonical equivalent.
  • T059 Add tests proving same normalized material payload produces the same hash preview.
  • T060 Add tests proving material changes change hash preview.
  • T061 Add tests proving volatile changes do not change hash preview.
  • T062 Add tests proving provider order changes do not change hash preview when order is not meaningful.
  • T063 Add tests proving target type and normalizer version are included according to repo pattern.
  • T064 Add tests proving hash input excludes raw stdout/stderr, OperationRun context, runtime timestamps, PowerShell session metadata, credential metadata, and permission metadata.
  • T065 Add tests proving empty collection is distinguishable from permission failure, source unavailable, malformed output, warning/scalar/binary output, non-zero exit, and timeout.
  • T066 Add tests proving empty collection creates no resource row and no evidence row.
  • T067 Add blocker mapping tests for malformed, scalar, warning-prefixed, binary, oversized, non-zero, timeout, identity conflict, unsupported identity, identity unproven/missing/duplicate, redaction unproven, normalizer unready, hash unready, and target not ready, using repo-canonical codes such as empty_collection, missing_stable_external_id, derived_identity_blocked, and duplicate_stable_identity where applicable.
  • T068 Add DB-backed tests proving no tenant_configuration_resource_evidence rows are created by Spec 435 readiness flows and no resource/evidence append path is called.
  • T069 Add tests proving no raw Exchange payload or normalized Exchange payload is persisted as evidence.
  • T070 Add tests proving no content_backed, comparable, renderable, certified, restore-ready, customer-ready, report, Review Pack, PDF, or customer claim state appears.

Phase 8: Product Surface, Trigger, Ownership, and Architecture Guards

Purpose: Prove readiness work does not alter product/runtime surfaces outside scope.

  • T071 Add static guard assertions proving no routes, Filament pages/resources/widgets, Livewire components, Blade views, navigation, assets, or global search changes are introduced.
  • T072 Add static guard assertions proving no jobs, schedules, listeners, console triggers, customer output, reports, Review Packs, PDFs, restore, certification, compare/render code, or browser surface are introduced.
  • T073 Add static guard assertions proving no migrations, Exchange-specific evidence table, raw payload table, customer output table, UI state table, or legacy snapshot table are introduced.
  • T074 Add static guard assertions proving no platform-core tenant_id ownership truth, legacy shim, fallback reader, dual write, or Exchange mini-platform is introduced.
  • T075 Record browser proof as N/A - no rendered UI surface changed.
  • T076 Record Livewire v4 compliance unchanged, provider registration unchanged under apps/platform/bootstrap/providers.php, global search unchanged, destructive/high-impact actions none, asset strategy none, and deployment impact none.

Phase 9: Regression and Validation

Purpose: Prove adjacent Exchange/Coverage behavior remains intact.

  • T077 Run focused Spec 435 tests: cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec435 --compact.
  • T078 Run Spec 434 regression: cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec434 --compact.
  • T079 Run Spec 433 regression: cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec433 --compact.
  • T080 Run Spec 432/431/430 regression: cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec432|Spec431|Spec430' --compact.
  • T081 Run Coverage v2/generic capture/identity regression: cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec415|Spec417|Spec419|Spec420|Spec426|Spec427' --compact.
  • T082 Run provider capability regression: cd apps/platform && ./vendor/bin/sail artisan test --filter='ProviderCapabilityRegistryTest|ProviderCapabilityEvaluationTest' --compact.
  • T083 If Sail is unavailable, document the failure and run the same focused filters with cd apps/platform && php artisan test ... --compact.
  • T084 Run cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent or repo-canonical Pint command.
  • T085 Run git diff --check.
  • T086 Run git status --short and confirm only intended active Spec 435 and runtime/test files changed.

Phase 10: Implementation Report

Purpose: Close out with reviewable proof.

  • T087 Complete specs/435-exchange-structured-output-target-normalizer-readiness/implementation-report.md.
  • T088 Record candidate gate result, branch, HEAD, dirty state before/after, and files changed.
  • T089 Record Spec 434, Spec 433, and Spec 432 prerequisite proof.
  • T090 Record structured output envelope proof.
  • T091 Record transportRule, remoteDomain, and inboundConnector readiness proof or explicit blockers.
  • T092 Record identity readiness, redaction readiness, hash input readiness, empty collection readiness, and failure readiness proof.
  • T093 Record no evidence, no content-backed promotion, no compare/render/certification, no restore/customer claim, no UI/route/job/schedule/listener, no migration, no tenant_id, and no mini-platform proof.
  • T094 Complete the required target matrix.
  • T095 Complete the required no-promotion matrix.
  • T096 Record tests run, deferred work, PASS/PASS WITH CONDITIONS/FAIL result, and any bounded follow-up blockers.

Dependencies

  • Phase 1 must complete before runtime changes.
  • Phase 2 must complete before target normalizer readiness.
  • Phases 4-6 can proceed in parallel by target after Phase 3.
  • Phase 7 depends on target normalizer readiness definitions.
  • Phase 8 can run alongside Phase 7 but must pass before close-out.
  • Phase 10 closes only after validation is documented.

Stop Conditions

Stop and amend or split if implementation needs:

  • evidence rows or normalized evidence persistence;
  • calls from readiness flow into ExchangePowerShellEvidenceCaptureAdapter::capture(), CoverageResourceUpserter::upsert(), CoverageEvidenceWriter::append(), or an equivalent resource/evidence append path;
  • content_backed, comparable, renderable, certified, restore-ready, customer-ready, or customer-claim promotion;
  • Microsoft calls, Exchange Online connection, or real tenant PowerShell execution;
  • UI, routes, navigation, Filament, Livewire, Blade, browser, asset, or global search changes;
  • job, schedule, listener, console trigger, or public start surface;
  • migration, Exchange-specific evidence table, tenant_id, legacy shim, fallback reader, dual write, or mini-platform;
  • outboundConnector, acceptedDomain, organizationConfig, mailboxPlan, sharingPolicy, Teams, Security and Compliance, mutation commands, restore commands, reports, Review Packs, or PDFs.