Spec 438: Exchange internal render model slice 1 (#505)

Implements Feature Spec 438 and associated plan/tasks/update artifacts for Exchange internal render model slice 1.

Target branch: platform-dev

Follow-up integration path after merge: platform-dev -> dev.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #505
This commit is contained in:
ahmido 2026-07-10 13:30:14 +00:00
parent ff1a545c31
commit 71e3745aee
5 changed files with 1448 additions and 0 deletions

View File

@ -0,0 +1,127 @@
# Requirements Quality Checklist: Spec 438 - Exchange Internal Render Model Slice 1
**Purpose**: Validate that Spec 438's requirements are complete, unambiguous, internally consistent, measurable, repo-grounded, and implementation-ready. This checklist tests the requirements writing, not the implementation.
**Created**: 2026-07-10
**Feature**: [spec.md](../spec.md)
## Candidate And Prerequisite Quality
- [x] CHK001 Is the candidate source identified as directly user-provided rather than an invented queue item? [Traceability, Spec `Preparation Selection Summary`]
- [x] CHK002 Is the Spec 437 prerequisite stated with merged PASS/merge-ready evidence and current HEAD? [Completeness, Spec `Preparation Selection Summary`]
- [x] CHK003 Is the completed-spec guardrail explicit for Spec 422 and Specs 429-437? [Consistency, Spec `Preparation Selection Summary`]
- [x] CHK004 Is the stale `dev` versus current `platform-dev` base decision disclosed? [Assumption, Spec `Preparation Selection Summary`]
- [x] CHK005 Does the Candidate Check acknowledge zero current consumers and zero visible product outcome? [Clarity, Spec `Spec Candidate Check`]
- [ ] CHK006 Is a current-release operator workflow or real consumer demonstrated for this standalone layer? [BLOCKER: no; PROP-001, Spec `Spec Candidate Check`]
- [ ] CHK007 Can the topic be described as an independent current operator problem rather than a sub-operator implementation slice? [BLOCKER: no; Spec Approval Rubric Rule C, Spec `Spec Candidate Check`]
- [x] CHK008 Does the candidate gate use the exact `Defer` classification, an evidence-based 5/12 score, and FAIL instead of allowing technical boundedness to override the constitution/rubric blocker? [Consistency, Spec `Spec Candidate Check`]
## Scope And Proportionality Quality
- [x] CHK009 Is exactly one local builder proposed and every broader abstraction explicitly forbidden? [Scope, Spec `Proportionality Review`]
- [x] CHK010 Are the three supported resource types named exhaustively? [Completeness, Spec `Functional Requirements`]
- [x] CHK011 Does the spec keep the proposal provider-owned rather than platform-core? [Consistency, Spec `Provider Boundary / Platform Core Check`]
- [x] CHK012 Are persistence, enums/statuses, taxonomies, interfaces, registries, DTOs, consumers, and UI frameworks answered explicitly? [Completeness, Spec `Proportionality Review`]
- [x] CHK013 Is the correct narrower path—folding the mapping into the first real consumer spec—documented? [Proportionality, Spec `Spec Candidate Check`]
- [x] CHK014 Are hard stops objectively tied to scope-changing conditions? [Measurability, Spec `Final Candidate Gate`]
## Input Contract Quality
- [x] CHK015 Does the spec require the complete Spec 437 result envelope rather than the nested payload? [Clarity, Spec `Input Contract`]
- [x] CHK016 Are all required top-level envelope fields, types, and success values enumerated? [Completeness, Spec `Input Contract`]
- [x] CHK017 Are workload, nested type, shape version, compare-input marker, identity, redaction, provenance, and target sections enumerated at their exact paths? [Traceability, Spec `Input Contract`]
- [x] CHK018 Is the exact comparable shape version fixed? [Clarity, Spec `Input Contract`]
- [x] CHK019 Are Spec 437 comparable-hash recomputation and constant-time consistency comparison defined while explicitly stating that the unkeyed hash does not authenticate origin or provenance and requires trusted in-process composition? [Integrity, Spec `Input Contract`]
- [x] CHK020 Is identity anchor validation defined without permitting anchor output? [Security, Spec `Input Contract`]
- [x] CHK021 Are canonical remote-domain identity denylist rules and `domain_name_is_identity=false` explicit? [Security, Spec `Input Contract`]
- [x] CHK022 Must inbound routing duplicates agree with canonical material values? [Consistency, Spec `Input Contract`]
- [x] CHK023 Is invalid input exactly `null`, are recognized allowlisted fields distinguished from ignored unknown fields, and must every `protected_values`/`sensitive_values` entry pass exact marker-key-set validation without a new blocker/status taxonomy? [Clarity, Spec `Input Contract`]
- [x] CHK024 Are Evidence, Resource, ResourceType, OperationRun, raw/normalized input, streams, provider response, and old-renderer fallbacks prohibited? [Coverage, Spec `Forbidden Input And Fallbacks`]
## Output Contract Quality
- [x] CHK025 Is the exact top-level output order and model version fixed? [Measurability, Spec `Output Contract`]
- [x] CHK026 Are fixed boundary booleans distinguished from new persisted/status truth? [Clarity, Spec `Output Contract`]
- [x] CHK027 Is identity presentation limited to the exact generic label and boolean? [Security, Spec `Output Contract`]
- [x] CHK028 Are every target section's field names, labels, types, nullability, and order defined? [Completeness, Spec target mappings]
- [x] CHK029 Does the spec forbid hidden metadata bags, generic pass-through, recursive output traversal, and stringification? [Completeness, Spec `Functional Requirements`]
- [x] CHK030 Are identity anchors, hashes, source, and provenance validation-only and excluded from output? [Security, Spec `Common Mapping Semantics`]
## Count, Marker, And Determinism Quality
- [x] CHK031 Are configured-field, redacted-field, redacted-value, and presence semantics defined separately? [Clarity, Spec `Common Mapping Semantics`]
- [x] CHK032 Are unknown-key counting and duplicate protected/sensitive-section counting prohibited? [Edge Case, Spec `Common Mapping Semantics`]
- [x] CHK033 Is priority canonicalization defined with one output type? [Clarity, Spec `Common Mapping Semantics`]
- [x] CHK034 Are safe-enum input type, canonicalization function, accepted upstream spellings, exact token-to-output map, and rejection behavior specified? [Measurability, Spec `Common Mapping Semantics`]
- [x] CHK035 Is marker consistency fully defined across the exact key set, additional-key rejection, order independence, redacted, present, count, and state? [Completeness, Spec `Common Mapping Semantics`]
- [x] CHK036 Are key-order, unknown-key, volatile-metadata, safe-change, and protected-change expectations measurable while preserving valid envelope hashes? [Coverage, Spec `Success Criteria`]
## Target Mapping Quality
- [x] CHK037 Are `transportRule` source sections, allowlists, safe scalars, labels, field order, and forbidden values exact? [Completeness, Spec `transportRule Mapping`]
- [x] CHK038 Does the transport contract distinguish configured fields from protected value counts? [Clarity, Spec `transportRule Mapping`]
- [x] CHK039 Are `remoteDomain` classification, all eight settings, groups, labels, field order, marker-only settings, and exact-domain exclusion specified? [Completeness, Spec `remoteDomain Mapping`]
- [x] CHK040 Is `auto_reply_enabled` the only exact safe remote-domain setting? [Security, Spec `remoteDomain Mapping`]
- [x] CHK041 Are `inboundConnector` material truth, routing keys, labels, field order, safe counts, and duplicate validation specified? [Completeness, Spec `inboundConnector Mapping`]
- [x] CHK042 Does the connector contract exclude exact IP/domain/host/smart-host/certificate/comment/source/routing values? [Security, Spec `inboundConnector Mapping`]
- [x] CHK043 Do all target mappings fail closed on malformed allowlisted data? [Edge Case, Spec `Functional Requirements`]
## Truth, Surface, And Customer Boundary Quality
- [x] CHK044 Is data ownership N/A because the builder accepts no record/model and performs no lookup? [Consistency, Spec `Spec Scope Fields`]
- [x] CHK045 Are Evidence, Resource, ResourceType, and OperationRun immutability requirements explicit? [Completeness, Spec `Evidence, Resource, And Coverage Immutability`]
- [x] CHK046 Is in-memory model availability separated from persisted `CoverageLevel::Renderable`? [Clarity, Spec `Evidence, Resource, And Coverage Immutability`]
- [x] CHK047 Are ReadModel, old renderer, UI/routes, reports/Review Packs/PDF, CustomerOutputGate, certification, restore, and triggers out of scope? [Coverage, Spec `Functional Requirements`]
- [x] CHK048 Is Product Surface Impact consistently N/A with browser and Human Product Sanity rationale? [Consistency, Spec `Product Surface Impact`]
- [x] CHK049 Is OperationRun neither input, output, persistence, nor a new operation? [Consistency, Spec `OperationRun UX Impact`]
- [x] CHK050 Are migration, environment, queue, scheduler, listener, storage, asset, permission, and external-call impacts all none? [Completeness, Spec `Data And Migration Impact`]
## Test Governance And Acceptance Quality
- [x] CHK051 Does the test classification follow proving purpose: Unit, focused Feature, Heavy-Governance/diff, Browser N/A? [Consistency, Spec `Testing / Lane / Runtime Impact`]
- [x] CHK052 Are array fixtures the default and database fixtures opt-in? [Cost Control, Spec `Testing / Lane / Runtime Impact`]
- [x] CHK053 Are Feature tests limited to concrete database row/attribute immutability while source, cache, filesystem, Review-Pack, report, PDF, and other side-effect absence remains explicit Heavy-Governance review? [Test Governance, tasks.md]
- [x] CHK054 Does planned purity proof cover database, network, filesystem, logging, cache, session, events, and queues? [Coverage, tasks.md]
- [x] CHK055 Are leakage, material-change, protected-value stability, and database immutability measurable? [Acceptance Quality, Spec `Success Criteria`]
- [x] CHK056 Are regression filters, Pint, diff, changed-file, and status checks named? [Completeness, Spec `Testing / Lane / Runtime Impact`]
- [x] CHK057 Are implementation-report fields and target/boundary matrices explicitly documented for this deferred close-out, with runtime work recorded as not executed in `implementation-report.md`? [Completeness, Spec `Consumer-Owned Implementation Report Reference`]
- [x] CHK058 Are tasks explicitly reference-only and non-executable, requiring migration into a consumer-owning spec rather than reactivation through documentation or future evidence alone? [Safety, tasks.md]
- [ ] CHK059 Is there no product question blocking safe implementation? [BLOCKER: current operator workflow/consumer is unresolved; Spec `Open Questions`]
## Review Outcome
- [x] CHK060 Technical cross-artifact findings for approval class/score, gate-resolution wording, protected/sensitive marker validation, unknown-key semantics, hash-authentication limits, compositional protected-value wording, and Feature-vs-Heavy-Governance separation were corrected in preparation files only.
- [x] CHK061 Review outcome is `defer-or-merge-with-first-consumer`, not implementation approval.
- [x] CHK062 Any implementation-loop invocation is prohibited while the candidate/readiness gates remain FAIL.
- [x] CHK063 No application code, test, migration, UI, route, or runtime behavior was changed during preparation.
## Deferral Governance
- [x] Candidate result recorded as FAIL / Defer / 5/12.
- [x] Defer classification recorded in all active artifacts.
- [x] Implementation prohibition recorded in all active artifacts (`Implementation permitted: No`).
- [x] Missing runtime consumer and workflow owner documented.
- [x] Reactivation criteria documented.
- [x] No implementation confirmed.
- [x] Dirty state and diff-safety recorded in `implementation-report.md`.
- [x] Runtime scope and no-product-surface change confirmed.
## Implementation Proof
- Implemented runtime/tests: not executed.
- Runtime implementation: not executed.
- Runtime tests: not executed.
- Browser checks: not run (no rendered UI surface changed).
- Deployment impact: none.
- Merge readiness: not merge-ready as implementation.
## Preparation Result
**Technical contract quality**: PASS after preparation-artifact corrections.
**Requirements checklist**: FAIL because CHK006, CHK007, and CHK059 are blocking product/constitution questions.
**Candidate Selection Gate**: FAIL.
**Spec Readiness Gate**: FAIL for implementation.
**Governance outcome**: DEFERRED.
**Implementation outcome**: NOT EXECUTED.
**Merge outcome**: NOT APPLICABLE.
The smallest safe next action is to identify the first current internal operator consumer and fold this local transformation contract into that consumer-owning spec. No implementation behavior is proven by this checklist.

View File

@ -0,0 +1,84 @@
# Implementation Report: Spec 438 - Exchange Internal Render Model Slice 1
**Outcome**: DEFERRED — NOT IMPLEMENTED
## A. Final Gate Result
- **Outcome**: DEFERRED.
## B. Candidate Decision
- **Result**: FAIL
- **Class**: Defer
- **Score**: 5 of 12
## C. Implementation Permission
- **No** (implementation is not permitted while deferred).
## D. Reason
- No current operator workflow or direct runtime consumer exists for this slice.
- The planned internal render model would be speculative foundation without a reachable runtime owner.
## E. Runtime Work
- **None**.
## F. Files Changed
- `specs/438-exchange-internal-render-model-slice-1/spec.md`
- `specs/438-exchange-internal-render-model-slice-1/plan.md`
- `specs/438-exchange-internal-render-model-slice-1/tasks.md`
- `specs/438-exchange-internal-render-model-slice-1/checklists/requirements.md`
- `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`
No `apps/platform` runtime code, test, migration, route, UI, job, command, schedule, or listener files were changed.
## G. Tests
- Not run for this deferred close-out.
- Candidate decision to defer prohibits runtime/test implementation and execution in this spec.
## H. Browser
- N/A — no rendered UI surface changed.
## I. Deployment
- None.
## J. Merge Readiness
- **Not merge-ready as an implementation**.
- Eligible only for governance/documentation close-out according to repo convention.
## K. Reactivation
- Requires a consumer-owning workflow and renewed Candidate Selection and Spec Readiness before execution.
## Branch and dirty state
- **Branch**: `feat/438-exchange-internal-render-model-slice-1`
- **HEAD at review**: `ff1a545c`
- **git status --short (at review start and end)**: `?? specs/438-exchange-internal-render-model-slice-1/`
- **Candidate state at review**: deferred-only governance updates.
## Closure proof
- **Runtime merge readiness**: FAIL
- **Implementation merge readiness**: FAIL
- **Governance close-out readiness**: PASS, only if no runtime/specs outside this deferred package are changed.
### No-runtime implementation proof
No runtime implementation was added under `apps/platform/`:
- `ExchangePowerShellInternalRenderModelBuilder` does not exist.
- `Spec438ExchangeInternalRenderModelBuilderTest` does not exist.
- `Spec438ExchangeInternalRenderModelBuilderFeatureTest` does not exist.
- `git diff --check` output: PASS.
`git diff -- specs/438-exchange-internal-render-model-slice-1` was used to confirm only spec artifacts were updated.
**Spec 438 remains deferred and must not be implemented until a current consumer-owning workflow passes Candidate Selection and Spec Readiness.**

View File

@ -0,0 +1,362 @@
# Implementation Plan: Spec 438 - Exchange Internal Render Model Slice 1
**Branch**: `feat/438-exchange-internal-render-model-slice-1` | **Date**: 2026-07-10 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `specs/438-exchange-internal-render-model-slice-1/spec.md`
## Summary
Add one pure local `ExchangePowerShellInternalRenderModelBuilder` that accepts the complete successful result envelope produced by Spec 437 and returns a fixed internal-only model for exactly `transportRule`, `remoteDomain`, or `inboundConnector`. The builder returns `null` for invalid input, validates required envelope/provenance/identity/redaction/target shape, maps only explicit safe fields, derives protected value presence/count summaries, preserves deterministic order, and performs no lookup, write, integration, I/O, or fallback.
**Execution status**: BLOCKED / REFERENCE ONLY. This standalone zero-consumer plan fails PROP-001 and Spec Approval Rubric Rule C and MUST NOT be executed unchanged. A consumer-owning spec must absorb and adapt the relevant contract and tasks; new current-release evidence may justify that new or amended candidate, but documentation alone does not reactivate this plan.
**Implementation Plan Status**: Deferred
**Implementation Work**: Prohibited
**Deployment Impact**: None
No runtime phases will be executed in this spec. No tests will be added in this deferred closeout state. No product surface will change. No deployment action is required.
## Deferred implementation outline
This section keeps the historical technical breakdown as a migration reference only.
## Technical Context
**Language/Version**: PHP 8.4 / Laravel 12
**Primary Dependencies**: Existing `ExchangePowerShellComparablePayloadBuilder` contract/constants, Laravel container, Pest 4
**Storage**: N/A for runtime behavior; existing PostgreSQL-backed rows are used only by the focused immutability feature test
**Testing**: Pest Unit and Feature; explicit heavy-governance/diff review; Browser N/A
**Validation Lanes**: fast-feedback, confidence, targeted regression; no browser lane
**Target Platform**: Laravel Sail locally; existing Dokploy container runtime unchanged
**Project Type**: Laravel monolith under `apps/platform`
**Performance Goals**: deterministic in-memory array transformation with no remote or database work
**Constraints**: one runtime class, complete Spec 437 result envelope only, nullable fail-closed output, fixed target allowlists, no persistence/consumer/framework
**Scale/Scope**: exactly three target types and one model version
No `research.md` is required: the input contract, target projections, redaction marker shape, and repository precedent are resolved from current Spec 437 source/tests. No `data-model.md`, `contracts/`, or `quickstart.md` is required because the slice adds no entity, schema, API, route, command, or user workflow.
## Repository Truth And Prerequisite
- Base HEAD `ff1a545c` is `Spec 437: Exchange comparable promotion slice 1 (#504)`.
- `specs/437-exchange-comparable-promotion-slice-1/implementation-report.md` records PASS and merge-ready.
- The Spec 437 builder success envelope is top-level `comparable`, `blocker`, `resource_type`, `payload`, `comparable_hash`.
- Workload, nested resource type, comparable shape version, compare-input marker, identity, target projection, redaction, source, and provenance are nested inside `payload`.
- Comparable payload shape is `exchange-powershell-comparable-payload-v1`.
- Spec 437 has no runtime call site outside its tests; zero current consumers is a documented proportionality risk.
- Spec 422 and Specs 429-437 remain read-only history.
## Public API And Failure Contract
Planned method:
```php
public function build(array $comparableResult): ?array
```
- Valid complete success envelope -> fixed render model array.
- Any invalid, blocked, malformed, unsupported, mismatched, or unsafe envelope -> `null`.
- No blocker enum/result DTO/exception taxonomy is added.
- The API does not accept models or context objects and performs no lookup.
## Target Mapping Plan
### Common validation
Validate before mapping:
1. Top-level success marker, null blocker, supported resource type, associative payload, and SHA-256 comparable hash.
2. Nested workload, matching resource type, comparable shape version, and `normalized_payload_only` marker.
3. Identity field/HMAC/source-key shape and source-key consistency.
4. Redaction marker `protected_values_use_safe_markers=true`.
5. Content-backed/captured provenance markers and SHA-256 payload hash.
6. Target-required array sections, accepting empty sections but rejecting non-empty list-shaped sections.
7. Spec 437 comparable-hash consistency by canonicalizing the payload without provenance and comparing the recomputed hash in constant time; this unkeyed hash is not origin or provenance authentication.
8. Canonical remote-domain identity denylist plus `domain_name_is_identity=false`.
9. Inbound routing duplicates agree with canonical material values when present.
10. Recognized allowlisted scalar policies and redacted-marker consistency; recognized fields not explicitly safe as exact scalars are marker-only.
11. Every value in validation-only `protected_values` and `sensitive_values` is a canonical redacted marker with the exact marker key set; raw scalars, lists, nested non-marker maps, and additional marker keys fail closed.
Unknown non-allowlisted field names are ignored for output and counts, except that every value inside the wholly protected/sensitive validation sections must still pass canonical marker validation. Missing/malformed required structure or malformed recognized data returns `null`.
### Shared output
Emit in fixed order:
1. `resource_type`
2. `workload`
3. `model_version`
4. `internal_only`
5. `customer_output`
6. `certified`
7. `restore_ready`
8. `identity_label`
9. `sections`
Identity/HMAC/source key, hashes, source metadata, and provenance are validation-only and never emitted.
### `transportRule`
- Map `material.enabled`, `material.state`, `material.mode`, and canonical integer priority.
- Emit the exact section/field/label order defined in the spec, including explicit `null` optional scalars and fixed zero-valued counts.
- Summarize only the explicit condition/action/exception allowlists from the spec.
- Preserve allowlisted safe action scalars.
- Count configured fields separately from redacted values.
- Do not count duplicate `protected_values`/`sensitive_values` validation sections.
### `remoteDomain`
- Reject canonical identity fields `domainname`, `displayname`, and `name`, and require validation-only `remote_domain_class.domain_name_is_identity=false`.
- Derive `default`/`custom` from `remote_domain_class.is_default`.
- Emit only exact safe `settings.auto_reply_enabled`.
- Emit the exact section/field/label order defined in the spec; all other recognized settings are marker-only.
- Aggregate fixed delivery/message setting groups through marker presence/count semantics.
- Never emit exact domain or identity.
### `inboundConnector`
- Map material `enabled`, canonical connector type, and `require_tls`.
- Reject present routing duplicates that disagree with those canonical material values.
- Summarize only named routing keys through safe presence/count fields.
- Emit the exact section/field/label order defined in the spec; non-duplicate recognized routing fields are marker-only.
- Treat routing copies of material fields as validation duplicates, not second display truth.
- Never emit raw IP/domain/host/smart-host/certificate/comment/source/routing values.
## Count And Canonicalization Plan
- `configured_field_count`: recognized key with non-null safe scalar or present marker.
- `redacted_field_count`: recognized key represented by a valid marker.
- `redacted_value_count`: sum of valid marker counts.
- Unknown keys do not count.
- `protected_values`/`sensitive_values` validate safety but do not contribute display counts.
- Priority normalizes non-negative integer or digit string to integer.
- Safe enums require strings, canonicalize through trim + ASCII non-alphanumeric removal + lowercase, and use only the fixed token-to-output map in the spec (including `auditandnotify -> audit_and_notify` and `onpremises -> on_premises`).
- Marker `state` must agree with `present` and `count`.
- Fixed section/field insertion order is canonical; non-semantic lists are sorted before output.
- Protected exact-value stability uses compositional proof: Spec 437 regression owns exact-value-to-marker equivalence, and Spec 438 accepts only the resulting comparable-envelope semantics.
## 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**: backend-only.
- **Native vs custom classification**: N/A.
- **Shared-family relevance**: none.
- **State layers in scope**: none.
- **Audience modes**: N/A.
- **Decision/diagnostic/raw hierarchy**: no rendered hierarchy; raw/protected inputs are excluded.
- **Raw/support gating**: excluded from output.
- **One-primary-action / duplicate-truth control**: N/A.
- **Handling modes**: hard stop for any UI/ReadModel/report/download/customer surface.
- **Repository-signal treatment**: review-mandatory changed-file boundary.
- **Special surface test profiles**: N/A.
- **Required tests/manual smoke**: `N/A - no rendered UI surface changed`.
- **Exception path**: 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**: one pure service plus backend tests.
- **Navigation/provider-panel handling**: no change.
- **Screenshot/page-report need**: no.
## Product Surface Contract Plan
- **Reference**: `docs/product/standards/product-surface-contract.md` checked for the no-impact path.
- **No-legacy posture**: no compatibility path, fallback, hidden route, duplicate UI, or old renderer reuse.
- **Page archetype/surface budget**: N/A.
- **Technical Annex/deep-link demotion**: no surface; technical identifiers are omitted.
- **Canonical status vocabulary**: N/A.
- **Product Surface exceptions**: none.
- **Browser verification**: `N/A - no rendered UI surface changed`.
- **Human Product Sanity**: N/A.
- **Visible complexity target**: neutral.
- **Implementation report target**: this deferred standalone close-out uses `implementation-report.md`.
Stand-alone status-only closure must remain the only allowed report purpose for this package.
## Filament / Livewire / Deployment Posture
- **Livewire v4 compliance**: unchanged; no Livewire code.
- **Panel provider registration**: unchanged; providers remain in `apps/platform/bootstrap/providers.php`.
- **Global search**: unchanged; no Resource.
- **Destructive/high-impact actions**: none.
- **Asset strategy**: no assets and no `filament:assets` change.
- **Testing plan**: two focused Pest files, regressions, dependency/diff review; browser N/A.
- **Deployment impact**: no env, migration, queue, scheduler, storage, route, provider, permission, external call, or asset impact.
## Shared Pattern & System Fit
- **Cross-cutting marker**: no shared operator interaction family.
- **Systems touched**: Spec 437 result envelope and local Exchange service seam.
- **Shared abstractions reused**: existing comparable contract constants/shape only.
- **New abstraction**: exactly one local final builder, justified as protected-value leakage boundary.
- **Why existing abstraction is insufficient**: Spec 437 is machine-oriented; legacy renderer consumes another input shape and generically stringifies values.
- **Bounded deviation/spread control**: no interface, registry, DTO, generic base, shared presenter, consumer, or second runtime class.
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: no.
- **Central contract reused**: N/A.
- **Delegated behaviors**: N/A.
- **Surface-owned behavior**: none.
- **Queued DB notification**: N/A.
- **Terminal notification**: N/A.
- **Exception**: none.
No OperationRun type, catalog entry, row, context, transition, message, or link is created or changed.
## Provider Boundary & Portability Fit
- **Shared boundary touched?**: no.
- **Provider-owned seam**: Exchange PowerShell comparable-to-internal mapping.
- **Platform-core seams**: none.
- **Neutral terms preserved**: resource type, workload, model boundary flags.
- **Retained provider semantics**: three concrete Exchange target mappings only.
- **Follow-up**: the first consumer-owning spec must absorb and adapt this contract; unchanged Spec 438 remains non-executable and no generalization is pre-approved.
## Constitution Check
| Principle / Gate | Result | Plan evidence |
|---|---|---|
| PROP-001 / BLOAT-001 | FAIL | Zero current consumers and no current operator workflow; a future-risk-only layer is not justified by current release truth. |
| ABSTR-001 | PASS only on technical shape | The proposed class is narrow and security-sensitive, but that exception does not cure the standalone Rule C failure. |
| PERSIST-001 | PASS | Derived in memory only. |
| STATE-001 | PASS | No enum/status/reason/lifecycle state. |
| UI-SEM-001 / LAYER-001 | PASS with hard stop | No consumer or shared UI layer; builder does not become product truth. |
| PROV-001 | PASS | Mapping remains provider-owned. |
| TEST-TRUTH-001 / TEST-GOV-001 | PASS | Focused Unit/Feature proof; broad boundary checks remain explicit governance/diff review. |
| Workspace scope safety | PASS / N/A | No record input, query, route, ownership field, or lookup. |
| Evidence anchor contract | PASS | No Evidence input/fallback/mutation and no proof/currentness claim. |
| OperationRun truth | PASS | No OperationRun input/output/state. |
| Customer output gate | PASS | No gate dependency or customer/report output. |
| TCM/Coverage v2 cutover | PASS | No legacy adapter, dual truth, `tenant_id`, or persisted Renderable promotion. |
| Product Surface Contract | PASS / N/A | No rendered surface; browser and sanity N/A. |
| Read/write separation | PASS | Pure readless transformation with no write or external call. |
| Data minimization | PASS | Identity/provenance/hash/raw values excluded. |
The Constitution Check blocks this plan permanently in its standalone form. A consumer-owning spec must migrate the relevant contract/tasks and run its own Constitution Check; new evidence must be encoded in that candidate rather than used to execute this unchanged plan. Any additional class, persistence, status, unauthorized surface, or generic abstraction also fails the migrated design.
## Test Governance Check
- **Test classification**: Unit for pure behavior; Feature for DB immutability; Heavy-Governance/diff for scope/dependency proof; Browser N/A.
- **Affected lanes**: fast-feedback, confidence, targeted regression.
- **Narrowest commands**: Spec 438 filter first, adjacent sequence filters second.
- **Fixture/helper cost**: minimal array fixtures; DB context opt-in only in Feature.
- **Expensive defaults/shared helper growth**: none.
- **Heavy-family changes**: none; no new discovery framework.
- **Surface relief**: N/A backend-only.
- **Closing handoff**: re-run focused tests, regressions, Pint, diff/status, and inspect source dependencies/changed paths.
- **Budget/trend follow-up**: none expected.
- **Review-stop questions**: exact envelope? fixed allowlists? no double counts? no forbidden dependency? one class? no consumer?
- **Escalation path**: reject-or-split on breadth.
- **Workflow outcome**: blocked/defer. The focused lane design may be retained only inside a future consumer-owning spec.
## Project Structure
### Preparation artifacts
```text
specs/438-exchange-internal-render-model-slice-1/
├── spec.md
├── plan.md
├── tasks.md
└── checklists/
└── requirements.md
```
The standalone Spec 438 closeout record is a governance artifact only, not a runtime implementation log. This spec uses `implementation-report.md` to document Deferred status and closure proof only.
### Planned runtime/test files
```text
apps/platform/
├── app/Services/TenantConfiguration/
│ └── ExchangePowerShellInternalRenderModelBuilder.php
└── tests/
├── Unit/Support/TenantConfiguration/
│ └── Spec438ExchangeInternalRenderModelBuilderTest.php
└── Feature/TenantConfiguration/
└── Spec438ExchangeInternalRenderModelFeatureTest.php
```
No other runtime, test-family, documentation, route, UI, migration, job, listener, command, report, or customer-output path is planned.
## Implementation Phases
The phases below are reference work decomposition only. Do not execute them in this package. A future consumer-owning spec may adopt and adapt relevant steps only after its own Candidate Selection and Spec Readiness gates pass.
### Phase 0 - Preflight And Proportionality
- Capture branch/HEAD/dirty state and Spec 437 PASS proof.
- Reconfirm one mapping class, a named current operator workflow and real consumer in the owning spec, plus no persistence/customer-output/general-framework expansion.
- Stop if no real consumer exists, the comparable envelope changed incompatibly, or another mapping runtime class is required.
### Phase 1 - Tests First: Envelope Boundary
- Add failing Unit cases for supported/blocked/malformed envelopes and forbidden object/raw/normalized inputs.
- Fix exact nullable failure behavior and required envelope validation.
- Add dependency guard expectations before implementation.
### Phase 2 - One Local Builder
- Create the final builder with one public method and fixed common output.
- Add explicit target dispatch and no generic traversal/pass-through.
- Keep validation/mapping private within the same class.
### Phase 3 - Target Mappings
- Implement `transportRule`, `remoteDomain`, and `inboundConnector` mappings from explicit allowlists.
- Implement marker validation, count semantics, and enum/priority canonicalization.
- Keep fixed section/field order.
### Phase 4 - Leakage, Determinism, Material Change
- Run the leakage corpus.
- Prove key-order/unknown-key/volatile stability.
- Prove safe material changes and protected exact-value stability.
### Phase 5 - Immutability And Boundary Proof
- Add minimal DB fixtures and prove no rows/attributes mutate.
- Inspect builder dependencies and changed paths.
- Prove no Renderable, ReadModel, old renderer, UI, customer, trigger, migration, or operation integration.
### Phase 6 - Regression And Close-Out
- Run focused and adjacent regressions.
- Run Pint, diff, changed-file, and status checks.
- In the consumer-owning spec only, create and complete that spec's implementation report with the adapted matrices and Product Surface decision.
## Validation Commands
```bash
cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec438 --compact
cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec430|Spec431|Spec432|Spec433|Spec434|Spec435|Spec436|Spec437' --compact
cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec415|Spec417|Spec419|Spec420|Spec421|Spec422|Spec425|Spec426|Spec427|ProviderCapability|SourceContract|CoverageV2Readiness|CustomerOutputGate' --compact
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
git diff --check
git diff --name-only
git status --short
```
If Sail is unavailable or is killed during an authorized consumer-owning implementation, that spec's implementation report may record the exact environmental failure and a repo-approved fallback result, following Spec 437 precedent; it must not silently claim the Sail lane passed.
## Complexity Tracking
| Risk | Conditional bounded shape | Current decision |
|---|---|---|
| One local presentation builder with zero current consumers | One class, three concrete mappings, no shared/generic infrastructure | Deferred: migrate the contract into the first real consumer-owning spec; do not revive this plan unchanged |
| Focused Feature immutability proof for a pure builder | Minimal existing-row snapshots only | Conditional on candidate approval; Unit proof alone cannot demonstrate unchanged existing rows |
## Hard Stops
Stop and amend or split if implementation requires:
- executing this standalone reference plan, including after merely documenting a future consumer
- a second runtime class, interface, registry, DTO, presenter family, base class, trait, or generic framework
- Evidence/Resource/ResourceType/OperationRun/normalized/raw/provider input or fallback
- old `ExchangeTeamsRenderableSummaryBuilder` reuse
- generic recursion, unknown-key output, generic stringification, or provider dump
- persisted render model, cache-as-truth, coverage-level promotion, migration, enum, status family, or `tenant_id`
- ReadModel, Filament, Livewire, route, view, navigation, global search, asset, report, Review Pack, PDF, CustomerOutputGate, certification, restore, job, schedule, listener, command, or OperationCatalog integration
- additional Exchange or Teams target types
- broad Heavy-Governance discovery added to fast Unit/Feature lanes
- an unresolved Spec 437 envelope/version change

View File

@ -0,0 +1,664 @@
# Feature Specification: Spec 438 - Exchange Internal Render Model Slice 1
**Feature Branch**: `feat/438-exchange-internal-render-model-slice-1`
**Created**: 2026-07-10
**Status**: Deferred
**Type**: Coverage v2 / Microsoft 365 / Exchange / Internal Presentation Model / Backend-only
**Priority**: P1
**Risk**: High
**Mode**: Derived-only internal render model for successful Spec 437 comparable result envelopes; no persisted renderable promotion, no read-model integration, no UI, and no customer output
**Input**: Direct user-provided corrected Spec 438 candidate.
**Candidate Result**: FAIL
**Candidate Class**: Defer
**Candidate Score**: 5/12
**Implementation permitted**: No
**Implementation state**: Not implemented
## Deferral Decision
Spec 438 is deferred because no current operator workflow or direct runtime consumer requires an Exchange internal render model.
The proposed builder would be speculative foundation.
No runtime implementation is permitted while this spec remains deferred.
Candidate Score: 5/12
Candidate Result: FAIL
Candidate Class: Defer
Implementation permission: no
Current Runtime Consumer: none
Current Workflow Owner: none
Spec 436:
Content-backed Exchange evidence exists.
Spec 437:
Comparable Exchange payloads exist.
Current limitation:
Those comparable payloads have no proven runtime consumer outside tests.
Spec 438 is not:
- implemented
- completed
- passed
- merge-ready as a runtime change
- approved for implementation
## Reactivation Conditions
Spec 438 or its relevant safety rules may only be resumed if all of the following are satisfied:
1. A currently reachable Operator or Product workflow has a concrete reproducible Exchange problem.
2. A direct Runtime Consumer for Spec 437-comparable payloads is named.
3. The consumer uses the output in the same spec.
4. The Workflow Owner is explicitly assigned.
5. Only actually required Exchange target types are in scope.
6. RBAC, Workspace, Environment, and Provider scope are documented.
7. Redaction and Protected-Value rules are part of the Consumer spec.
8. UI integration includes browser proof and Product Surface proof.
9. Customer/Report/Review-pack/PDF proximity includes an Exchange-specific content-safety contract.
10. Candidate selection and Spec Readiness support an implementable class.
No new spec may be created only for the unused render model builder.
## Deferred Safety Requirements (deferred safety requirements)
The following rules remain valuable but are not implemented:
- Comparable payload as the only allowed source.
- No Evidence fallback.
- No raw_payload fallback.
- No normalized_payload fallback.
- No OperationRun context.
- No legacy ExchangeTeams renderer.
- Fixed type allowlists.
- No generic stringify/map output.
- No protected exact values.
- No HMAC-, source_key-, or hash display.
- No persisted CoverageLevel::Renderable promotion.
- No customer, certification, restore, or remediation claims.
## Preparation Selection Summary
- **Selected candidate**: Spec 438 - Exchange Internal Render Model Slice 1.
- **Source location**: Direct user-provided candidate in this session. The automatic candidate queue remains empty and is not used to invent adjacent scope.
- **Why selected**: Spec 437 is merged at current `platform-dev` base HEAD `ff1a545c`, records PASS and merge-ready, proves comparable result envelopes for exactly `transportRule`, `remoteDomain`, and `inboundConnector`, and explicitly defers Spec 438 as the next Exchange slice.
- **Close alternatives deferred**: Coverage-level `renderable` promotion, `CoverageV2ReadinessReadModel` integration, Filament/Livewire/UI, customer output, reports, Review Packs, PDFs, comparator/delta prose, certification, restore/apply, jobs, schedules, listeners, additional Exchange targets, Teams targets, and a shared presentation framework.
- **Roadmap relationship**: Continues the bounded Exchange sequence from Specs 429-437. It establishes only a safe local transformation boundary over the Spec 437 result contract.
- **Completed-spec guardrail result**: Specs 429-437 and Spec 422 are completed historical context. They are read-only and MUST NOT be rewritten. No existing Spec 438 branch, directory, or runtime class existed before preparation.
- **Smallest viable implementation slice**: One local builder with one public array-in/nullable-array-out method, three explicit target mappings, fixed output sections, and focused leakage/determinism/immutability proof.
- **Feature description fed into Spec Kit**: Derive a deterministic internal-only redaction-safe Exchange render model from successful Spec-437 comparable result envelopes for `transportRule`, `remoteDomain`, and `inboundConnector`, with no persistence, UI, ReadModel, customer output, OperationRun, migration, or generic renderer.
- **Branch-base note**: The repository guideline still names `dev`, but Spec 437 is merged on `platform-dev` and `origin/dev` does not contain that prerequisite. Preparation therefore starts from current merged `platform-dev` truth and records the deviation instead of branching from a stale base.
- **Candidate Selection Gate**: FAIL. The candidate is directly provided and technically bounded, but no current operator workflow or real consumer requires the standalone layer. PROP-001 and Spec Approval Rubric Rule C override the numeric score. The transformation must be folded into a new or amended consumer-owning candidate; new current-release evidence alone does not reactivate this standalone package.
## Spec Candidate Check
- **Problem**: The proposal anticipates that a future operator presentation will need a bounded transformation contract over Spec 437 comparable payloads.
- **Today's failure**: No current shipped operator workflow consumes the Spec 437 result and no current decision, delay, or product claim is shown to fail because this builder is absent. The stated legacy-renderer collision is a future risk, not a current workflow failure.
- **User-visible improvement**: None in this slice. A future combined consumer spec could provide the operator improvement while keeping this mapping local to the real workflow.
- **Smallest enterprise-capable version**: When a real internal operator consumer exists, one local Exchange-specific builder in that consumer-owning spec, supporting exactly three proven Spec 437 result shapes and returning a model only for a valid successful envelope.
- **Explicit non-goals**: No consumer integration, shared interface, registry, DTO family, presenter family, persisted state, coverage promotion, customer output, UI, comparator, delta prose, report, Review Pack, PDF, restore, certification, job, trigger, migration, enum, or status family.
- **Permanent complexity imported**: One provider-owned builder class plus two focused Pest test files. No source of truth, persistence, status axis, route, UI concept, or shared platform contract.
- **Why now**: The Spec 437 prerequisite is available, but availability alone does not establish current-release necessity. Preparation can preserve the proposed safety contract; implementation is deferred until a real consumer exists.
- **Why not local**: The correct narrower implementation is local mapping inside the first real operator-consumer spec. Creating that local layer as its own zero-consumer spec is still below the operator domain and fails Rule C.
- **Approval class**: Defer.
- **Red flags triggered**: #2 new builder, #4 future-facing foundation language, and #6 micro-spec sequence. Defense: the builder has three concrete target mappings, no generic extension point, no consumer integration, no persistence, and a hard stop against shared-layer growth. Zero current consumers remains an explicit review risk rather than being disguised as reuse.
- **Score**: Nutzen: 1 | Dringlichkeit: 0 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 0 | Wiederverwendung: 0 | **Gesamt: 5/12**. The bounded security value is locally useful, but current urgency, product proximity, and reuse are not repo-proven; the rubric therefore requires defer or merge.
- **Decision**: FAIL for standalone implementation. Preserve this package as a blocked technical draft, or merge its safety contract into a future spec that owns a current operator problem and real consumer. Any implementation-loop invocation before that gate changes is prohibited.
## Spec Scope Fields
- **Scope**: Provider-owned, in-memory Exchange comparable-to-internal-model transformation only.
- **Primary Routes**: N/A - no route, controller, API route, Filament page/resource/widget, Livewire component, view, report, PDF, download, or navigation change.
- **Data Ownership**: None. The public API accepts only an in-memory Spec 437 result envelope. It does not accept or resolve Workspace, ManagedEnvironment, ProviderConnection, Evidence, Resource, ResourceType, or OperationRun records and creates no ownership truth.
- **RBAC**: N/A - no invocation surface, action, route, record lookup, or mutation. A later consumer MUST define authorization and scope in its own spec.
- **Default filter behavior when environment context is active**: N/A - no canonical view.
- **Entitlement checks preventing cross-environment leakage**: N/A in this pure builder. It MUST NOT add a lookup, fallback-to-latest behavior, or provider-native `tenant_id` ownership path.
## No Legacy / No Backward Compatibility Constraint
- **Compatibility posture**: canonical bounded addition over the Spec 437 result envelope.
- **Legacy aliases, fallback readers, hidden routes, duplicate UI, old labels, or historical fixtures kept?**: no.
- **Why clean addition is safe now**: No persisted or external contract changes. The legacy `ExchangeTeamsRenderableSummaryBuilder` is neither changed nor reused, and no compatibility shim connects it to the new path.
## UI Surface Impact
- [x] No UI surface impact
- [ ] Existing page changed
- [ ] New page/route added
- [ ] Navigation changed
- [ ] Filament panel/provider surface changed
- [ ] New modal/drawer/wizard/action added
- [ ] New table/form/state added
- [ ] Customer-facing surface changed
- [ ] Dangerous action changed
- [ ] Status/evidence/review presentation changed
- [ ] Workspace/environment context presentation changed
No-impact rationale: Spec 438 adds only a local backend transformation service and tests. Any route, ReadModel, Filament, Livewire, Blade, navigation, global-search, asset, report, or download change invalidates this decision and requires a separate product-surface spec.
## UI/Productization Coverage
N/A - no reachable UI surface impact. No route inventory, design coverage, page report, screenshot, or browser artifact is required.
## Product Surface Impact
Reference: `docs/product/standards/product-surface-contract.md`.
- **Product Surface Contract applies?**: Only as a checked no-impact boundary.
- **Page archetype**: N/A.
- **Primary user question**: N/A.
- **Primary action**: N/A.
- **Surface budget result**: N/A.
- **Technical Annex / deep-link demotion**: No runtime surface exists. Identity HMAC, source key, hashes, provenance, OperationRun detail, raw payload, and technical logs are excluded from output rather than rendered.
- **Canonical status vocabulary**: N/A - no product-facing status or badge changes.
- **Visible complexity impact**: neutral.
- **Product Surface exceptions**: none.
## Browser Verification Plan
- **Browser proof required?**: no.
- **No-browser rationale**: `N/A - no rendered UI surface changed`.
- **Focused path when required**: N/A.
- **Primary interaction to execute**: N/A.
- **Console, Livewire, Filament, network, and 500-error checks**: N/A.
- **Full-suite failure triage**: N/A.
## Human Product Sanity Check
- **Required?**: no.
- **No-human-sanity rationale**: N/A - no product surface changed.
- **Reviewer questions**: N/A.
- **Planned result location**: If this reference contract is migrated, the consumer-owning spec's implementation report records its surface decision and visible-complexity outcome; standalone Spec 438 creates no report.
## Product Surface Merge Gate Checklist
- [x] No-legacy posture recorded.
- [x] Product Surface Impact is N/A with rationale.
- [x] Browser proof is `N/A - no rendered UI surface changed`.
- [x] Human Product Sanity is not applicable with rationale.
- [x] Product Surface exceptions are `none`.
- [x] Any consumer-owning implementation report that adopts this contract must record Livewire v4, provider registration, global search, destructive/high-impact actions, assets, tests/browser, deployment, visible complexity, and completed-spec rewrite posture.
## Cross-Cutting / Shared Pattern Reuse
- **Cross-cutting feature?**: no operator-facing shared interaction family is touched.
- **Interaction class(es)**: provider-owned internal presentation transformation only.
- **Systems touched**: Spec 437 result envelope and the new local builder.
- **Existing pattern(s) to extend**: Nullable builder result convention and explicit target mapping under `apps/platform/app/Services/TenantConfiguration/`.
- **Shared contract / presenter / renderer to reuse**: none. `ExchangeTeamsRenderableSummaryBuilder` is forbidden.
- **Why existing shared paths are insufficient**: The legacy renderer accepts provider-near normalized payload plus context, exposes display-oriented values, and includes generic stringification. It does not implement the Spec 437 envelope boundary.
- **Conditional technical fit**: One local provider-owned builder would be a proportionate security boundary for the three concrete targets inside a consumer-owning spec. ABSTR-001's security allowance does not waive PROP-001, LAYER-001, Spec Approval Rubric Rule B, or Rule C for this zero-consumer standalone package.
- **Consistency impact**: Fixed internal-only boundary metadata and protected-value semantics remain identical for all three mappings.
- **Review focus**: Reject dependencies on Evidence/Resource/OperationRun/ReadModel/customer-output classes or any generic pass-through.
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: no.
- **Shared OperationRun UX contract/layer reused**: N/A.
- **Delegated UX behaviors**: N/A.
- **Local surface-owned behavior**: none.
- **Queued DB-notification policy**: N/A.
- **Terminal notification path**: N/A.
- **Exception required?**: none.
OperationRun impact is `N/A - derived locally from a supplied comparable envelope without a new operation`. No OperationRun type, catalog entry, context input, context output, or row mutation is allowed.
## Provider Boundary / Platform Core Check
- **Shared provider/platform boundary touched?**: no shared seam is changed.
- **Boundary classification**: provider-owned.
- **Seams affected**: Exchange PowerShell comparable result to internal model only.
- **Neutral platform terms preserved**: resource type, workload, internal-only boundary flags.
- **Provider-specific semantics retained and why**: The three Exchange resource types and their fixed safe mappings are the concrete current cases.
- **Why this does not deepen provider coupling accidentally**: No platform-core interface, registry, taxonomy, persistence, status, or consumer is changed.
- **Follow-up path**: The first real consumer-owning spec must absorb and adapt this mapping contract and its relevant tasks. Unchanged standalone Spec 438 does not become executable merely because a later consumer is documented; no genericization is pre-approved.
## UI / Surface Guardrail Impact
N/A - no operator-facing surface change.
## Proportionality Review
- **New source of truth?**: no.
- **New persisted entity/table/artifact?**: no.
- **New abstraction?**: yes - exactly one local final builder class.
- **New enum/state/reason family?**: no.
- **New cross-domain UI framework/taxonomy?**: no.
- **Current operator problem**: None demonstrated. There is no current consumer or operator workflow for the proposed model.
- **Existing structure is insufficient because**: Not proven for the current release. Spec 437 is machine-comparable and currently has no runtime call site.
- **Narrowest correct implementation**: Defer the standalone slice; include one local mapping class only when the first real internal operator consumer establishes current need.
- **Ownership cost**: One security-sensitive mapping and focused tests must remain aligned with the Spec 437 envelope version.
- **Alternative selected**: Fold the mapping and its leakage boundary into the first consumer spec so security is proven at the same time as the current operator workflow; a generic presenter/registry remains rejected as overproduction.
- **Release truth**: The contract is a parked preparation artifact only; it is not approved current-release implementation truth.
- **Current consumer evidence**: `ExchangePowerShellComparablePayloadBuilder` has no application call site outside Spec 437 tests. The reachable Coverage v2 Inspect flow uses `CoverageV2ReadinessReadModel` and the legacy `ExchangeTeamsRenderableSummaryBuilder` over persisted `normalized_payload`; current Exchange PowerShell evidence remains capped at `ContentBacked`, so that legacy `Renderable` path is not a Spec 437/438 consumer.
- **Hard proportionality stop**: More than one mapping class, a new interface/DTO/registry/presenter family, or persistence invalidates this parked local-only draft. A runtime consumer also remains out of scope here; resolving the product blocker requires migrating the contract into a consumer-owning spec rather than reviving this task package unchanged.
## Testing / Lane / Runtime Impact
- **Test purpose / classification**: Unit for pure envelope validation/mapping/leakage/determinism; Feature for focused database immutability; Heavy-Governance/static review for dependency and changed-file boundary proof; Browser N/A.
- **Validation lanes**: fast-feedback, confidence, and existing targeted regression filters. No browser lane.
- **Why sufficient**: The builder is pure in-memory behavior; only the no-write assertion needs database fixtures. Broad repository discovery does not belong in Unit/Feature tests.
- **New or expanded test families**: one focused Unit file and one focused Feature file; no browser or broad discovery family.
- **Fixture/helper cost impact**: Reuse minimal Spec 437 envelope fixtures. Database setup is opt-in only in the immutability feature test.
- **Heavy-family visibility**: Source dependency checks and `git diff --name-only` are explicit close-out proof, not hidden in the fast lane.
- **Special surface test profile**: N/A.
- **Reviewer handoff**: Confirm exact input/output shape, null-on-invalid behavior, allowlists, leakage corpus, no source dependencies, minimal fixture cost, and changed-file scope.
- **Budget/baseline/trend impact**: none expected.
- **Escalation needed**: defer the standalone candidate; if folded into a consumer-owning spec, keep the focused test design and reject-or-split broad static discovery.
- **Active feature PR close-out entry**: Guardrail / Exception / Smoke Coverage.
- **Planned validation commands**:
- `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec438 --compact`
- `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec430|Spec431|Spec432|Spec433|Spec434|Spec435|Spec436|Spec437' --compact`
- `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec415|Spec417|Spec419|Spec420|Spec421|Spec422|Spec425|Spec426|Spec427|ProviderCapability|SourceContract|CoverageV2Readiness|CustomerOutputGate' --compact`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `git diff --check`
- `git diff --name-only`
- `git status --short`
## User Scenarios & Testing
### User Story 1 - Build a Safe Internal Model (Priority: P1)
As an internal TenantPilot consumer developer, I can supply a successful Spec 437 comparable result envelope and receive a deterministic internal-only model whose identity and protected values cannot be displayed exactly.
**Why this priority**: It establishes the only in-scope capability and the security boundary shared by all three target mappings.
**Independent Test**: A valid envelope for each supported target yields the fixed model contract, while invalid or blocked envelopes yield `null`.
**Acceptance Scenarios**:
1. **Given** a valid successful Spec 437 envelope, **When** the builder runs, **Then** it returns the fixed boundary metadata, protected identity label, and target-specific sections.
2. **Given** a blocked, malformed, wrong-workload, wrong-version, or mismatched envelope, **When** the builder runs, **Then** it returns `null` and creates no alternate model.
3. **Given** an Evidence, Resource, OperationRun, raw payload, or normalized payload object instead of the envelope, **When** the public API is invoked, **Then** the input is rejected by type/shape and no fallback occurs.
---
### User Story 2 - Preserve Safe Material Meaning (Priority: P1)
As an internal operator-experience designer, I need safe state, enum, count, and presence semantics to change predictably without exact protected values affecting the model.
**Why this priority**: A presentation model is useful only if it reflects safe material changes while remaining stable across protected-value substitutions.
**Independent Test**: Safe booleans/enums/counts/presence change only their expected output fields; protected exact-value or unknown-key changes with identical safe semantics leave the model byte-equivalent.
**Acceptance Scenarios**:
1. **Given** `enabled`, `require_tls`, a safe enum, or a safe marker count changes, **When** the model is rebuilt, **Then** only the corresponding allowlisted output changes.
2. **Given** an upstream protected exact value changes and Spec 437 produces a successful envelope with unchanged valid marker presence/count/state, **When** only that resulting envelope is supplied to this builder, **Then** the model is identical.
3. **Given** input keys are reordered or unknown keys are added, **When** the model is rebuilt, **Then** fixed field/section order and output bytes remain unchanged.
---
### User Story 3 - Preserve Existing Truth Boundaries (Priority: P1)
As a platform reviewer, I need proof that deriving the internal model does not create or mutate database, coverage, OperationRun, UI, customer-output, or trigger truth.
**Why this priority**: The model must remain a pure adapter and must not silently become `CoverageLevel::Renderable` or customer proof.
**Independent Test**: Focused database snapshots and dependency/diff review show no writes, no forbidden dependencies, and no product-surface or customer-output files changed.
**Acceptance Scenarios**:
1. **Given** existing Evidence, Resource, ResourceType, and OperationRun rows, **When** the builder runs on a separately supplied envelope, **Then** row counts and relevant attributes remain unchanged.
2. **Given** implementation files are reviewed, **When** dependencies and changed paths are inspected, **Then** no ReadModel, old renderer, CustomerOutputGate, report, UI, route, job, listener, console, migration, enum, or catalog integration exists.
### Edge Cases
- Top-level `resource_type` and nested `payload.resource_type` disagree.
- `comparable=true` is missing, false, or non-boolean; `blocker` is non-null.
- `payload` is absent, list-shaped, or uses another workload/shape/version/input marker.
- `comparable_hash`, identity HMAC, source key, or provenance payload hash is missing or malformed.
- Identity source key does not match `resource_type:field:value_hmac`.
- Required target sections are absent or list-shaped.
- An allowlisted safe boolean/enum/priority has the wrong type or value.
- A required redacted marker has inconsistent `redacted`, `present`, `count`, and `state` values.
- Unknown keys exist beside valid target data; they are ignored and never counted or emitted.
- Empty target sections remain valid when the Spec 437 shape permits them and produce zero counts.
## Input Contract
The public contract is:
```php
public function build(array $comparableResult): ?array
```
The input MUST be the complete successful result returned by `ExchangePowerShellComparablePayloadBuilder`, not the nested comparable payload alone.
Required top-level values:
- `comparable === true`
- `blocker === null`
- `resource_type` is exactly `transportRule`, `remoteDomain`, or `inboundConnector`
- `payload` is an associative array
- `comparable_hash` is a lowercase 64-character SHA-256 value
Required nested values:
- `payload.workload === exchange`
- `payload.resource_type` matches top-level `resource_type`
- `payload.comparable_payload_shape_version === exchange-powershell-comparable-payload-v1`
- `payload.compare_input === normalized_payload_only`
- `payload.identity.field` is a non-empty string
- `payload.identity.value_hmac` is a lowercase SHA-256 value
- `payload.identity.source_key` exactly matches `resource_type:field:value_hmac`
- `payload.redaction.protected_values_use_safe_markers === true`
- `payload.provenance.payload_hash` is a lowercase SHA-256 value
- `payload.provenance.evidence_state === content_backed`
- `payload.provenance.coverage_level === content_backed`
- `payload.provenance.capture_outcome === captured`
- all target-required projection sections exist as arrays; an empty section is valid, while any non-empty list-shaped section is malformed
Required target invariants:
- The canonicalized `remoteDomain` identity field (lowercase with non-alphanumeric characters removed) is not `domainname`, `displayname`, or `name`, and `remote_domain_class.domain_name_is_identity === false`; any missing, true, or malformed identity safety marker returns `null`.
- When present, `inboundConnector.routing.connector_type`, `routing.enabled`, and `routing.require_tls` MUST equal their canonical `material` counterparts; disagreement returns `null`.
- Recognized allowlisted `transportRule` condition/exception fields and recognized non-scalar-safe action fields MUST be valid redacted markers when present.
- Recognized allowlisted `remoteDomain` setting fields other than `auto_reply_enabled` MUST be valid redacted markers when present.
- Recognized allowlisted `inboundConnector` routing fields other than the three material duplicates MUST be valid redacted markers when present.
- Every present entry in `protected_values` and `sensitive_values`, including entries whose field name is not display-allowlisted, MUST be an exact canonical redacted marker. Raw scalars, lists, nested non-marker maps, or markers with additional keys return `null`.
Envelope integrity validation MUST recompute Spec 437's `comparable_hash`: remove `payload.provenance`, remove null-valued associative entries, recursively sort associative maps using the Spec 437 natural case-insensitive key ordering while preserving list order, JSON-encode with unescaped slashes and throwing errors, hash with SHA-256, and compare in constant time with the top-level hash. A changed key inside the hashed region is accepted only when the supplied hash is recomputed; provenance-only changes remain outside the hash by Spec 437 contract.
This hash check proves canonical payload consistency only. It is an unkeyed hash, deliberately excludes `provenance`, and does not authenticate origin or evidence state. The API is therefore a trusted in-process boundary: a future consumer MUST pass the direct Spec 437 service result and MUST NOT treat deserialized or user-supplied arrays as authenticated comparable provenance.
Invalid input returns `null`. No exception taxonomy, blocker family, or fallback output is introduced.
## Forbidden Input And Fallbacks
The builder MUST NOT accept or resolve `TenantConfigurationResourceEvidence`, `TenantConfigurationResource`, `TenantConfigurationResourceType`, `OperationRun`, raw provider payload, normalized payload, stdout, stderr, transcript, provider response, credential/permission evidence, ReadModel, report, Review Pack, PDF, or customer-output models.
There is no fallback from invalid comparable input to Evidence, normalized/raw data, OperationRun context, the old Exchange/Teams renderer, generic stringification, or display/name/domain identity.
## Output Contract
A successful build returns exactly this top-level order:
```text
resource_type
workload
model_version
internal_only
customer_output
certified
restore_ready
identity_label
sections
```
Fixed values:
- `workload = exchange`
- `model_version = exchange-internal-render-model-v1`
- `internal_only = true`
- `customer_output = false`
- `certified = false`
- `restore_ready = false`
- `identity_label = { label: "Protected stable identity", protected: true }`
No hidden metadata bag is allowed.
`identity_label` always emits `label` and then `protected`. Every section always emits every field listed below in the listed order. An absent optional safe scalar is emitted as `null`; count fields are non-negative integers and presence fields are booleans.
## Common Mapping Semantics
- Exact identity field, HMAC, source key, comparable hash, payload hash, source metadata, and provenance are validation inputs only and MUST NOT be emitted.
- Unknown non-allowlisted field names are ignored for output and counts and MUST NOT change the model. The only stricter exception is `protected_values`/`sensitive_values`: unknown field names there remain undisplayed and uncounted, but every associated value MUST still pass exact marker-key-set validation.
- Missing or malformed required sections and malformed allowlisted fields/markers return `null`.
- `configured_field_count` counts recognized allowlisted keys with a non-null safe scalar or a marker whose `present` is true.
- `redacted_field_count` counts recognized allowlisted fields represented by valid redacted markers.
- `redacted_value_count` is the sum of those markers' non-negative `count` values.
- Unknown keys and the duplicate validation-only `protected_values`/`sensitive_values` sections MUST NOT contribute to display counts.
- Priority accepts a non-negative integer or digit string and is emitted as an integer.
- A safe-enum input MUST be a non-empty string. Canonicalize it by trimming, removing every non-ASCII-alphanumeric character, and lowercasing; then use only this fixed token map: `enabled -> enabled`, `disabled -> disabled`, `enforce -> enforce`, `audit -> audit`, `auditandnotify -> audit_and_notify`, `wrap -> wrap`, `ignore -> ignore`, `reject -> reject`, `append -> append`, `prepend -> prepend`, `partner -> partner`, and `onpremises -> on_premises`. Any other token returns `null` for the whole model.
- A marker is valid only when it is an associative array whose key set is exactly `redacted`, `present`, `count`, and `state`; input key order is irrelevant. `redacted=true`, `present` is boolean, `count` is a non-negative integer, and `state` is consistent: `absent` for false/zero, `present` for true/one, `present_multiple` for true/count greater than one. Additional keys make the marker malformed.
- Collections are sorted only where order is non-semantic; fixed sections and fields retain the contract order defined below.
- Protected exact-value stability is compositional: the mandatory Spec 437 regression proves upstream exact-value variants collapse to the same valid safe-marker semantics, while the Spec 438 Unit case supplies only those valid comparable-envelope semantics and proves identical render output. No exact protected value is injected into or accepted by the Spec 438 API.
## transportRule Mapping
Required input sections: `material`, `conditions`, `actions`, `exceptions`, `protected_values`, and `sensitive_values`.
Fixed output section order:
1. `state`: `label`, `enabled`, `state`; label `State`, nullable boolean, and nullable enum (`enabled`/`disabled`).
2. `execution`: `label`, `mode`; label `Execution` and nullable enum (`enforce`/`audit`/`audit_and_notify`).
3. `priority`: `label`, `value`; label `Priority` and canonical non-negative integer or `null`.
4. `conditions_summary`: `label`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Conditions summary`.
5. `actions_summary`: `label`, `delete_message`, `disclaimer_fallback_action`, `disclaimer_location`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Actions summary`, nullable safe scalar fields, and fixed counts.
6. `exceptions_summary`: `label`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Exceptions summary`.
7. `redaction_summary`: `label`, `redacted_field_count`, `redacted_value_count`; label `Redaction summary`, with totals from the three display summary sections only.
For the three configured summaries, `protected_values_present` is true exactly when at least one recognized marker has `present=true`.
Allowlisted condition keys: `from`, `recipient_domain_is`, `sender_domain_is`, `sent_to`, `subject_contains_words`, `subject_or_body_contains_words`, `body_contains_words`.
Allowlisted action keys: `apply_html_disclaimer_text`, `apply_html_disclaimer_fallback_action`, `apply_html_disclaimer_location`, `delete_message`, `redirect_message_to`, `header_contains_words`, `set_header_value`.
Allowlisted exception keys: `except_if_from` and `except_if_recipient_domain_is`.
Rule names, display names, raw conditions/actions/exceptions, patterns, words, phrases, headers, email addresses, domains, senders, recipients, and routing values MUST NOT appear.
## remoteDomain Mapping
Required input sections: `remote_domain_class`, `settings`, `protected_values`, and `sensitive_values`.
Fixed output section order:
1. `classification`: `label`, `kind`; label `Classification`, with nullable `default`/`custom` derived only from `is_default`.
2. `delivery_settings`: `label`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Delivery settings`, over `auto_forward_enabled`, `target_delivery_domain`, `tnef_enabled`, and `trusted_mail_outbound_enabled`.
3. `message_settings`: `label`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Message settings`, over `allowed_oof_type`, `mail_tips_access_level`, and `mail_tips_access_scope`.
4. `feature_states`: `label`, `auto_reply_enabled`; label `Feature states` and nullable exact boolean.
5. `protected_settings_summary`: `label`, `configured_field_count`, `protected_values_present`, `redacted_field_count`, `redacted_value_count`; label `Protected settings summary`, aggregated across all eight allowlisted settings without double-counting `protected_values` or `sensitive_values`.
6. `redaction_summary`: `label`, `redacted_field_count`, `redacted_value_count`; label `Redaction summary`, with totals from the allowlisted settings only.
Exact domain, domain label, name, display name, exact identity, raw routing, and protected setting values MUST NOT appear. `domain_name_is_identity` is validation-only, MUST be exactly false, and MUST NOT be emitted.
## inboundConnector Mapping
Required input sections: `material`, `routing`, `protected_values`, and `sensitive_values`.
Fixed output section order:
1. `connector_state`: `label`, `enabled`; label `Connector state` and nullable boolean.
2. `connector_type`: `label`, `value`; label `Connector type` and nullable canonical `partner`/`on_premises`.
3. `tls_state`: `label`, `require_tls`; label `TLS state` and nullable boolean.
4. `routing_summary`: `label`, `sender_domains_present`, `sender_domain_count`, `sender_ip_addresses_present`, `sender_ip_address_count`, `associated_accepted_domains_present`, `associated_accepted_domain_count`, `smart_hosts_present`, `smart_host_count`, `routing_metadata_present`, `routing_metadata_field_count`; label `Routing summary`. `routing_metadata_present` is true when at least one recognized marker for `restrict_domains_to_ip_addresses`, `cloud_services_mail_enabled`, or `connector_source` has `present=true`; `routing_metadata_field_count` is the number of those three recognized markers with `present=true`.
5. `protected_values_summary`: `label`, `tls_certificate_name_present`, `tls_certificate_name_count`, `comment_present`, `redacted_field_count`, `redacted_value_count`; label `Protected values summary`. Redacted totals cover the named non-duplicate routing allowlist only.
6. `redaction_summary`: `label`, `redacted_field_count`, `redacted_value_count`; label `Redaction summary`, with totals from all named non-duplicate routing allowlist fields only.
`routing.connector_type`, `routing.enabled`, and `routing.require_tls` are validation duplicates and MUST NOT create duplicate display truth; when present, they MUST agree with the canonicalized `material` values, and the display values come only from `material`.
Connector name, display name, raw IPs/CIDRs, domains, hosts, smart hosts, certificate names, comments, connector source values, and other routing/TLS values MUST NOT appear.
## Functional Requirements
- **FR-438-001**: The system MUST add exactly one local final `ExchangePowerShellInternalRenderModelBuilder` or repo-canonical equivalent.
- **FR-438-002**: The public API MUST be `build(array $comparableResult): ?array` and MUST accept only the complete successful Spec 437 result envelope by shape.
- **FR-438-003**: Invalid, blocked, unsupported, mismatched, unsafe, or malformed input MUST return `null` with no fallback.
- **FR-438-004**: Supported resource types MUST be exactly `transportRule`, `remoteDomain`, and `inboundConnector`.
- **FR-438-005**: The builder MUST validate top-level success markers, nested workload/type/version/input markers, canonical comparable-hash integrity, identity anchor shape, redaction marker, provenance gates, target-required sections, remote-domain identity safety, and inbound duplicate-field consistency.
- **FR-438-006**: The builder MUST emit the fixed top-level output and fixed target section/field order defined above.
- **FR-438-007**: Every emitted field MUST be explicitly allowlisted; no recursive pass-through, unknown-key section, generic stringification, or JSON dump is allowed.
- **FR-438-008**: Unknown non-allowlisted keys MUST NOT affect counts, ordering, or output; values under unknown `protected_values`/`sensitive_values` field names MUST nevertheless pass canonical marker validation.
- **FR-438-009**: Malformed allowlisted scalar values or redacted markers MUST return `null`.
- **FR-438-010**: Exact identity, identity field/HMAC/source key, comparable/payload hashes, source metadata, provenance, and raw/provider values MUST NOT be emitted.
- **FR-438-011**: Protected values MUST be represented only through fixed presence/count/redacted-state semantics.
- **FR-438-012**: Count semantics MUST follow the definitions in Common Mapping Semantics and MUST avoid duplicate protected/sensitive-section counting.
- **FR-438-013**: Safe material changes MUST affect only the corresponding output fields.
- **FR-438-014**: Protected exact-value changes with unchanged valid safe semantics MUST NOT change the model.
- **FR-438-015**: The same logical envelope with different key order, unknown keys, or volatile metadata MUST produce byte-equivalent canonical output.
- **FR-438-016**: The builder MUST NOT depend on Evidence, Resource, ResourceType, OperationRun, ReadModel, old ExchangeTeams renderer, CustomerOutputGate, report, Review Pack, PDF, route, UI, job, listener, console, migration, registry, or catalog classes.
- **FR-438-017**: Builder invocation MUST create or mutate no database row, latest pointer, coverage level, capture outcome, source metadata, claim state, or OperationRun state.
- **FR-438-018**: The implementation MUST NOT persist `CoverageLevel::Renderable`, a render model/payload/cache, or any new truth.
- **FR-438-019**: The implementation MUST add no UI, route, navigation, global search, asset, report, customer output, certification, restore, trigger, migration, tenant ownership, enum, status family, interface, registry, DTO family, or generic presentation framework.
- **FR-438-020**: Existing `ExchangeTeamsRenderableSummaryBuilder`, `CoverageV2ReadinessReadModel`, `CoverageV2ResourceInstancesTable`, `CustomerOutputGate`, OperationRun types/catalog, and completed Specs 429-437 MUST remain unchanged.
## Non-Functional Requirements
- **NFR-438-001 - Determinism**: Equal logical safe input MUST yield byte-equivalent output with fixed section/field order.
- **NFR-438-002 - Data minimization**: Output MUST contain only fixed boundary metadata, protected identity label, and allowlisted safe section values.
- **NFR-438-003 - Fail closed**: Any malformed required contract element or allowlisted value MUST yield `null`.
- **NFR-438-004 - Purity**: The builder MUST perform no I/O, remote call, database lookup/write, event dispatch, queue work, logging of payload data, caching, or session mutation.
- **NFR-438-005 - Proportionality**: Runtime scope is one class. Tests MUST protect leakage, determinism, and immutability without creating a broad discovery framework.
- **NFR-438-006 - Provider containment**: Exchange semantics remain inside the provider-owned service seam and do not become platform-core vocabulary or persistence.
- **NFR-438-007 - Boundary language**: Section labels and values MUST avoid customer-ready, compliance, security verdict, risk, remediation, certification, and restore guidance. Fixed false top-level boundary keys are the only permitted certification/restore wording.
## Forbidden Output Corpus
Tests MUST prove output excludes supplied examples of:
- rule/display/connector names and exact stable identity
- identity HMAC, source key, comparable hash, payload hash, provenance
- patterns, words, phrases, header values, email addresses, senders, recipients, domains
- IP addresses, CIDRs, hosts, smart hosts, certificate/TLS names, comments, connector-source/routing values
- raw payload, normalized payload, stdout, stderr, transcript, provider response
- credentials, tokens, authorization headers, cookies, permission evidence
- customer-ready, compliant/non-compliant, secure/insecure, critical/risk, remediation/fix/recommended language
## Evidence, Resource, And Coverage Immutability
Spec 438 MUST NOT create or mutate Evidence, Resource, ResourceType, ProviderConnection, OperationRun, EnvironmentReviewSection, Review Pack, StoredReport, report, PDF, cache, or any latest pointer. Existing evidence remains `content_backed`. `render_model_available` is an in-memory success description only and MUST NOT be persisted as `CoverageLevel::Renderable` or any new field/state.
## Data And Migration Impact
- New entities/tables/columns/indexes: none.
- Migration: none.
- Tenant ownership changes: none.
- Environment variables: none.
- Queues/schedules/listeners/commands: none.
- Storage/cache/assets/provider permissions/external calls: none.
## Assumptions
- Spec 437's result envelope and shape version remain stable for implementation.
- A successful result includes the current provenance and redaction markers produced by `ExchangePowerShellComparablePayloadBuilder`.
- The builder is invoked only by tests in this slice; a runtime consumer is intentionally deferred and is not implied.
- Any future invocation is trusted in-process composition from the direct Spec 437 result. Canonical hash equality is not origin authentication and cannot replace caller ownership, RBAC, evidence-currentness, or consumer-boundary proof.
- Missing optional safe scalar values are represented as `null` in their fixed output fields; missing required contract structure returns `null` for the whole model.
## Risks
- **Premature layer risk**: No current consumer exists. Mitigation: one local class only, no shared contract, and no consumer integration.
- **Leakage risk**: Exact protected values could pass through via generic traversal. Mitigation: target field allowlists, marker validation, forbidden corpus tests, and no metadata bag.
- **Double-count risk**: Spec 437 repeats protected/sensitive markers in validation sections. Mitigation: display counts use only explicitly named primary target sections.
- **Overclaim risk**: Internal model availability could be read as persisted renderability or customer readiness. Mitigation: fixed false boundary flags and no ReadModel/claim/customer integration.
- **Legacy collision risk**: Old renderer can expose provider-near values. Mitigation: source dependency guard and no fallback.
- **Test bloat risk**: Broad file discovery could enter the fast lane. Mitigation: focused Unit/Feature tests plus explicit diff/dependency close-out.
## Open Questions
- **Blocking product question**: Which current-release internal operator workflow and real consumer requires this model? Until a consumer-owning spec answers this, the standalone candidate fails PROP-001 and Spec Approval Rubric Rule C.
The technical input envelope, null-on-invalid behavior, target allowlists, count semantics, canonical enum casing, output version, and no-product-surface boundary are otherwise fixed.
## Success Criteria
### Measurable Outcomes
- **SC-438-001**: All three supported Spec 437 success envelopes produce the exact fixed internal model contract.
- **SC-438-002**: Every blocked/malformed/unsupported input case returns `null` and produces no fallback output.
- **SC-438-003**: The complete leakage corpus has zero exact-value occurrences in encoded output.
- **SC-438-004**: Same logical safe input, reordered input keys, unknown keys, and volatile metadata produce byte-equivalent output.
- **SC-438-005**: Safe booleans/enums/counts/presence changes affect only expected fields; protected exact-value substitutions with unchanged safe semantics produce identical output.
- **SC-438-006**: Database immutability proof shows zero created rows and zero relevant attribute changes.
- **SC-438-007**: Changed-file and dependency proof shows one runtime class, two focused test files, active Spec 438 artifacts, and no forbidden runtime surface.
- **SC-438-008**: Focused tests, required regressions, Pint, and `git diff --check` pass or exact pre-existing/environmental limitations are documented.
## Acceptance Criteria
### Scope And Input
- Exactly one builder and three targets.
- Complete successful Spec 437 result envelope only.
- `null` for any invalid or unsafe envelope.
- No Evidence/raw/normalized/OperationRun/old-renderer fallback.
### Output And Safety
- Fixed deterministic top-level and target-specific section order.
- Fixed internal/customer/certification/restore boundary values.
- Generic protected identity label only.
- No exact protected values, hashes, provenance, or hidden metadata.
- Unknown fields ignored; malformed allowlisted values block.
- Count semantics and canonical enum/priority normalization proven.
### Truth And Surface Boundaries
- No persistence or `CoverageLevel::Renderable` promotion.
- No Evidence/Resource/ResourceType/OperationRun mutation.
- No ReadModel, UI, route, report, Review Pack, PDF, customer-output, certification, restore, job, listener, schedule, command, migration, enum, status, registry, interface, or DTO family.
- Browser and Human Product Sanity are N/A.
### Validation
- Unit, focused Feature, targeted regressions, and changed-file/dependency review complete.
- Pint and `git diff --check` pass.
- The consumer-owning spec's future implementation report records branch/HEAD/dirty state, files changed, prerequisite proof, adapted target/boundary matrices, tests, its browser rationale, Livewire/provider/global-search/action/asset posture, deployment impact, and deferred work; standalone Spec 438 creates no report.
## Consumer-Owned Implementation Report Reference
Standalone Spec 438 MUST NOT create an implementation report while its gates remain FAIL. If a consumer-owning spec absorbs this contract and passes its own gates, that spec's implementation report SHOULD adapt and include the following evidence:
- Candidate gate, branch, HEAD, dirty state before/after, and files changed.
- Spec 437 prerequisite/envelope proof and proportionality result.
- Public API, null-on-invalid, no-fallback, target mapping, count semantics, canonicalization, leakage, determinism, material-change, and protected-value stability proof.
- Evidence/Resource/ResourceType/OperationRun immutability and no persisted Renderable proof.
- No ReadModel/old renderer/customer/report/Review Pack/PDF/UI/route/trigger/migration/tenant-id proof.
- Test/lane results, browser N/A, Human Product Sanity N/A, Livewire v4, provider registration, global search, destructive/high-impact action, asset strategy, deployment impact, visible complexity, no completed-spec rewrite assertion, and deferred work.
Required target matrix:
| Type | Spec 437 comparable prerequisite | Internal model available | Persisted renderable | Protected exact values exposed | Blocker |
|---|---:|---:|---:|---:|---|
| `transportRule` | Yes | implementation proof | No | No | `null` on invalid input |
| `remoteDomain` | Yes | implementation proof | No | No | `null` on invalid input |
| `inboundConnector` | Yes | implementation proof | No | No | `null` on invalid input |
Required boundary matrix:
| Area | State |
|---|---|
| Internal model | Derived only |
| Evidence mutation | No |
| Resource mutation | No |
| Coverage-level promotion | No |
| ReadModel integration | No |
| UI | No |
| Customer output | No |
| Reports/Review Packs/PDF | No |
| Certification | No |
| Restore | No |
| OperationRun | No new operation or input |
| Migration | No |
## Follow-Up Spec Candidates
- First internal operator consumer of the model, with explicit Product Surface, RBAC, browser, and Human Product Sanity gates.
- Any customer/report/Review Pack/PDF consumption with a separate content-safety and CustomerOutputGate contract.
- Comparator/delta semantics if a real consumer requires them.
- Additional Exchange or Teams target mappings only after their comparable contracts are proven.
No follow-up is pre-approved by this spec.
## Final Candidate Gate
**Preparation candidate decision**: FAIL.
**Spec Readiness Gate**: FAIL for implementation because the candidate lacks a current operator workflow and real consumer. The technical contract may be reused only as reference material: resolving the blocker requires migrating and adapting it inside a consumer-owning spec, not documenting a consumer while executing this standalone task package.
If a future consumer-owning spec resolves the blocker, implementation PASS would additionally require the local-only proportionality boundary, complete-envelope input, fixed allowlists, leakage/determinism/immutability proof, no persistence, and no customer-output posture to remain intact.
For this unchanged standalone package, a runtime consumer remains a scope violation. The consumer-owning spec that resolves the product blocker must replace these gates/tasks with its own authorized integration scope. Independently, FAIL if implementation introduces a shared presentation layer, second mapping class, interface/registry/DTO family, generic traversal/stringification, exact protected-value leakage, Evidence/raw/normalized/OperationRun fallback, old renderer reuse, persistence or Renderable promotion, unauthorized ReadModel/UI/customer/report integration, migration, new operation type, or insufficient focused safety proof.

View File

@ -0,0 +1,211 @@
---
description: "Dependency-ordered implementation tasks for Spec 438"
---
# DEFERRED — DO NOT IMPLEMENT
Spec Readiness Gate: FAIL
Candidate Class: Defer
Implementation permitted: No
Stop before T001.
## Deferred Governance Close-Out (completed)
- [x] Candidate result documented (`FAIL` / `Defer` / `5/12`) and implementation prohibited.
- [x] Deferral reason documented (`no current operator workflow and no direct runtime consumer`).
- [x] Runtime consumer absence documented in `spec.md`.
- [x] Reactivation conditions documented in `spec.md`.
- [x] No implementation confirmed in `plan.md` and `tasks.md`.
- [x] Dirty-state and runtime-change scope recorded in `implementation-report.md`.
- [x] `git diff --check` documented in `implementation-report.md` (no runtime/test execution artifacts).
# Tasks: Spec 438 - Exchange Internal Render Model Slice 1
**Input**: Design documents from `specs/438-exchange-internal-render-model-slice-1/`
**Prerequisites**: `spec.md` and `plan.md`
**Tests**: None added or run while deferred.
**Browser**: `N/A - no rendered UI surface changed`.
**Execution status**: BLOCKED / REFERENCE ONLY. These tasks MUST NOT be executed in standalone Spec 438. A consumer-owning spec must migrate and adapt the relevant tasks, name the current operator workflow and real consumer, and pass its own Candidate Selection and Spec Readiness gates; merely documenting new evidence does not reactivate this task list.
## Test Governance Decision
- **Classification**: Unit, focused Feature, explicit Heavy-Governance/diff review; Browser N/A.
- **Lane outcome**: `blocked/defer`. If a future consumer-owning spec resolves the gate, keep the focused test shape and reject or split broad repository discovery.
- **Fixture posture**: Array fixtures are default; database/workspace/provider fixtures are opt-in only for the immutability story.
- **Runtime boundary**: Exactly one new runtime class and no consumer integration.
## Phase 1: Preflight And Candidate Gates
**Purpose**: Reconfirm prerequisites and stop conditions before runtime work.
**Blocking gate**: Stop before T001. Resolution requires moving the relevant contract/tasks into a consumer-owning spec; this unchanged package remains non-executable even if later evidence identifies a consumer.
All T001-T048 paths and report references below are non-executable migration examples. The consumer-owning spec must copy only relevant tasks, replace Spec 438 report paths with its own paths, and re-establish dependency order before execution.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T001 Create `specs/438-exchange-internal-render-model-slice-1/implementation-report.md` and record branch, HEAD, initial `git status --short`, `git diff --check`, and base-branch deviation.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T002 Record Spec 437 PASS/merge-ready and exact success-envelope proof from `specs/437-exchange-comparable-promotion-slice-1/implementation-report.md` and `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellComparablePayloadBuilder.php` in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T003 In the consumer-owning spec that adopts this reference material, re-run Candidate Selection and proportionality gates, name the current operator workflow and direct runtime consumer, migrate only relevant tasks from `specs/438-exchange-internal-render-model-slice-1/tasks.md`, and stop on more than one mapping class or any shared abstraction; do not continue execution in this standalone task file.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T004 Confirm the supported target set remains exactly `transportRule`, `remoteDomain`, and `inboundConnector` against `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellComparablePayloadBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T005 Confirm completed Specs 422 and 429-437 remain read-only and record the completed-spec rewrite assertion in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T006 Capture the pre-implementation changed-file allowlist in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`: one builder, two focused tests, and active Spec 438 artifacts only.
**Checkpoint**: Stop if Spec 437 is not at the current base, the envelope/version changed incompatibly, or any hard-stop scope is needed.
---
## Phase 2: Foundational Envelope Boundary
**Purpose**: Establish failing tests and the single-class API before target mapping.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T007 Create `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php` with minimal successful Spec 437 envelope fixtures and an exact public-contract/reflection assertion for `build(array $comparableResult): ?array`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T008 Add failing supported-target and common-boundary-output cases to `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T009 Add failing null-on-invalid cases for missing/false comparable marker, non-null blocker, unsupported type, wrong workload/version/input marker, type mismatch, malformed or stale comparable hash, identity/source-key mismatch, invalid provenance, canonical remote-domain identity denylist, unsafe `domain_name_is_identity`, inconsistent inbound routing/material duplicates, missing/list-shaped target sections, and raw-scalar/list/nested/additional-key values in `protected_values` or `sensitive_values` in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T010 Add failing no-model/no-fallback cases for Evidence, Resource, ResourceType, OperationRun, raw payload, normalized payload, stdout/stderr/transcript, provider response, and legacy renderer-shaped input in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T011 Create exactly one final `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php` with one public nullable build method, common envelope validation, fixed top-level output, and no constructor dependency.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T012 Implement null-on-invalid behavior, canonical Spec 437 comparable-hash recomputation/constant-time comparison, and no exception/blocker taxonomy or fallback in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php` until T008-T010 pass.
**Checkpoint**: The builder can accept only a complete valid Spec 437 result shape and cannot resolve any alternate input.
---
## Phase 3: User Story 1 - Build A Safe Internal Model (Priority: P1) 🎯 MVP
**Goal**: Produce the exact fixed model for all three supported target envelopes.
**Independent Test**: Each valid target fixture produces fixed boundary metadata, protected identity label, and exact target section order; malformed target data returns `null`.
### Tests For User Story 1
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T013 [US1] Add failing `transportRule` exact section/field/label order, explicit nullable scalar, safe scalar, configured/redacted count, and forbidden exact-value assertions in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T014 [US1] Add failing `remoteDomain` exact section/field/label order, classification, grouped settings count, exact-domain exclusion, marker-only settings, and unsafe identity assertions in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T015 [US1] Add failing `inboundConnector` exact section/field/label order, state/type/TLS, routing presence/count, matching and mismatched duplicate-material truth, marker-only routing, and protected routing exclusion assertions in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
### Implementation For User Story 1
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T016 [US1] Implement the explicit `transportRule` allowlist and fixed section mapping in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T017 [US1] Implement the explicit `remoteDomain` allowlist and fixed section mapping in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T018 [US1] Implement the explicit `inboundConnector` allowlist and fixed section mapping in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T019 [US1] Implement strict recognized-allowlist scalar validation plus exact marker-key-set validation for all displayed markers and every `protected_values`/`sensitive_values` entry, without generic recursion/pass-through, in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
**Checkpoint**: All three valid envelopes build; exact protected identity/config values never enter the model.
---
## Phase 4: User Story 2 - Preserve Safe Material Meaning (Priority: P1)
**Goal**: Make safe changes visible and protected/unknown/volatile changes stable.
**Independent Test**: Reordered or semantically equivalent input yields byte-equivalent output; only an expected safe field changes for each safe material change.
### Tests For User Story 2
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T020 [US2] Add failing canonical key-order, fixed section-order, repeated-build, and encoded byte-equivalence cases in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T021 [US2] Add failing unknown-key and volatile source/provenance metadata stability cases using a recomputed valid hash whenever the hashed payload region changes in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T022 [US2] Add failing priority integer/digit-string cases plus every fixed safe-enum token mapping, canonical-equivalent Spec 437 spellings such as `AuditAndNotify`, `audit-and-notify`, `OnPremises`, and unsupported/non-string enum rejection in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T023 [US2] Add failing configured-field, redacted-field, redacted-value, protected-presence, duplicate-section non-counting, exact marker-key-set, additional-marker-key, and malformed protected/sensitive-section cases in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T024 [US2] Add failing safe boolean/enum/count/presence material-change cases with expected-field-only diffs in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T025 [US2] Add the compositional protected-value stability case in `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`: use only valid Spec 437 comparable-envelope fixtures with identical marker semantics, prove identical render output, and link the upstream exact-value substitution proof to the mandatory Spec 437 regression rather than injecting exact values into the Spec 438 API.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T026 [US2] Add the full forbidden leakage and boundary-language corpus for all three targets to `apps/platform/tests/Unit/Support/TenantConfiguration/Spec438ExchangeInternalRenderModelBuilderTest.php`.
### Implementation For User Story 2
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T027 [US2] Implement fixed-order canonical output and non-semantic collection sorting in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T028 [US2] Implement exact count semantics and duplicate `protected_values`/`sensitive_values` exclusion in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T029 [US2] Implement priority canonicalization, the exact trim/remove-non-ASCII-alphanumeric/lowercase enum token map, and marker-state consistency checks in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T030 [US2] Remove any generic traversal/stringification/output discovered while making T020-T026 pass in `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInternalRenderModelBuilder.php`.
**Checkpoint**: Safe material semantics are deterministic and protected exact values cannot influence or leak into output.
---
## Phase 5: User Story 3 - Preserve Existing Truth Boundaries (Priority: P1)
**Goal**: Prove the builder remains pure, unintegrated, and non-persistent.
**Independent Test**: Existing database records remain byte-equivalent and source/dependency review finds no forbidden integration.
### Tests For User Story 3
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T031 [US3] Create `apps/platform/tests/Feature/TenantConfiguration/Spec438ExchangeInternalRenderModelFeatureTest.php` with minimal existing Evidence, Resource, ResourceType, and OperationRun fixtures plus a separately supplied valid comparable envelope.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T032 [US3] Add row-count and before/after attribute assertions proving no Evidence, Resource, ResourceType, latest pointer, coverage level, claim state, source metadata, or OperationRun mutation in `apps/platform/tests/Feature/TenantConfiguration/Spec438ExchangeInternalRenderModelFeatureTest.php`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T033 [US3] Add focused database assertions that no `CoverageLevel::Renderable` value, render row/artifact truth, `EnvironmentReviewSection`, `StoredReport`, or new `OperationRun` row is created and that all relevant persisted attributes remain unchanged in `apps/platform/tests/Feature/TenantConfiguration/Spec438ExchangeInternalRenderModelFeatureTest.php`.
### Boundary Review For User Story 3
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T034 [US3] Inspect the builder constructor/imports/calls as Heavy-Governance proof and record no Evidence/Resource/OperationRun/ReadModel/old-renderer/CustomerOutputGate/Review-Pack/report/PDF/UI/trigger/migration/catalog dependency plus no DB, HTTP/remote, filesystem/storage, Log, cache-as-truth, Session, Event, Queue, Bus, payload logging, generated report/PDF artifact, or other I/O/static-facade side effect in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T035 [US3] Review `git diff --name-only` against the allowlist and record no ReadModel, Filament, Livewire, route, view, navigation, asset, report, customer-output, job, listener, schedule, command, migration, enum, registry, catalog, or completed-spec changes in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T036 [US3] Record Product Surface `N/A - no rendered UI surface changed`, Human Product Sanity N/A, no customer output, and neutral visible complexity in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
**Checkpoint**: The internal model remains derived-only and has no runtime consumer or persistence side effect.
---
## Phase 6: Regression Validation
**Purpose**: Protect the corrected Exchange sequence and adjacent Coverage/customer boundaries.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T037 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec438 --compact` and record results in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T038 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec430|Spec431|Spec432|Spec433|Spec434|Spec435|Spec436|Spec437' --compact` and record results in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T039 Run the mandatory Spec 422 collision regression with `cd apps/platform && ./vendor/bin/sail artisan test --filter=Spec422 --compact` and record results in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T040 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter='Spec415|Spec417|Spec419|Spec420|Spec421|Spec425|Spec426|Spec427' --compact` and record results in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T041 Run `cd apps/platform && ./vendor/bin/sail artisan test --filter='ProviderCapability|SourceContract|CoverageV2Readiness|CustomerOutputGate' --compact` and record results in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T042 Classify any existing skips, Sail signal/resource failures, or fallback runs accurately without converting them into false passes in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
**Checkpoint**: Existing evidence, compare, legacy renderer, read-model, and customer-output behavior remains intact.
---
## Phase 7: Final Quality And Close-Out
**Purpose**: Complete formatting, diff, gate, and report evidence.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T043 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` and record the result in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T044 Run `git diff --check`, `git diff --name-only`, and `git status --short` and record final outputs in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T045 Re-evaluate the Constitution, Spec Candidate, Product Surface, test-governance, workspace, evidence, OperationRun, customer-output, and temporary Coverage v2 gates in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T046 Complete the required target and boundary matrices plus API, no-fallback, leakage, determinism, material-change, count, immutability, no-Renderable, no-consumer, tests, deployment, and deferred-work evidence in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T047 Record Livewire v4 compliance, `apps/platform/bootstrap/providers.php` provider posture, global search, destructive/high-impact actions, asset strategy, `filament:assets` need, deployment impact, and completed-spec rewrite assertion in `specs/438-exchange-internal-render-model-slice-1/implementation-report.md`.
- [ ] DEFERRED / NOT APPLICABLE WHILE DEFERRED — T048 Mark `specs/438-exchange-internal-render-model-slice-1/tasks.md` complete only after every applicable task has evidence; do not check preparation tasks based on intent alone.
## Dependencies & Execution Order
- Phase 1 blocks all runtime/test changes.
- Phase 2 establishes the API and blocks all target mapping.
- Phase 3 completes the independently testable MVP.
- Phase 4 depends on all three mappings.
- Phase 5 depends on builder behavior and may begin once Phase 3 is stable.
- Phase 6 follows focused implementation/tests.
- Phase 7 is final.
- Target tests share one file and are not marked parallel.
- The Feature test uses database context only when its immutability assertions require it.
## Implementation Strategy
1. Do not execute this task list. If a consumer-owning spec migrates relevant tasks, run its proportionality and prerequisite gates before any runtime/test work.
2. Write failing envelope tests before the builder.
3. Complete the three target mappings inside the same class.
4. Prove leakage/determinism before adding DB fixtures.
5. Run focused tests before regressions.
6. Keep consumer integration out of this reference package; the consumer-owning spec must define and authorize its own integration tasks.
## Hard Stops
Stop and amend or split if implementation requires:
- more than one runtime class or any interface/registry/DTO/presenter/base/trait framework
- attempting to unlock this unchanged task list through documentation or future-consumer evidence alone
- a runtime consumer or ReadModel/UI/customer/report integration
- model/Evidence/raw/normalized/OperationRun/provider fallback
- old ExchangeTeams renderer reuse
- generic recursive pass-through, JSON dump, or stringification
- persistence, Renderable promotion, migration, enum/status/reason family, `tenant_id`, new operation type, or catalog entry
- additional Exchange/Teams target types
- broad discovery tests disguised as Unit/Feature proof
## Notes
- Every task uses the required `- [ ] T### [P?] [US?] Description with file path` format.
- No application implementation occurs during preparation.
- Stand-alone Spec 438 close-out requires `implementation-report.md` to document deferred-status proof. Implementation tasks remain migration references for a future consumer-owning spec.