# Requirements Checklist: Exchange Evidence Capture Adapter and Content-Only Guard **Feature**: `specs/434-exchange-evidence-capture-adapter-content-only-guard/` **Mode**: Backend adapter/guard implementation close-out. Preparation completed earlier; implementation evidence is documented in `tasks.md` and `implementation-report.md`. ## Implementation Evidence Note - Completed items below are marked only where supported by the implementation report, completed task evidence, focused Spec 434 feature coverage, regression results, or code review evidence. - Unsafe-identity writer non-invocation is proven by adapter code order plus zero resource/evidence database assertions; Spec 434 did not add a literal writer spy. ## Preparation Gate - [x] `spec.md` exists. - [x] `plan.md` exists. - [x] `tasks.md` exists. - [x] `checklists/requirements.md` exists. - [x] Candidate Selection Gate result is recorded. - [x] Spec Readiness Gate result is recorded. - [x] Completed-spec guardrail result for Specs 429-433 is recorded. - [x] Spec 433 PASS WITH CONDITIONS dependency is recorded. - [x] Product Surface impact is `N/A - no rendered product surface changed`. - [x] Browser proof is `N/A - no rendered UI surface changed`. - [x] Proportionality review is present for the adapter/guard abstraction. - [x] No application runtime file was edited during preparation. ## Prerequisites for Implementation - [x] Re-check current branch, HEAD, and dirty state before runtime changes. - [x] Confirm Specs 429-433 remain read-only context. - [x] Confirm Spec 433 has no merge-blocking readiness/redaction/no-promotion finding for this adapter slice. - [x] Confirm Spec 430 verified command contracts still cover `transportRule`, `remoteDomain`, and `inboundConnector`. - [x] Confirm Spec 432 runner boundary remains implemented and validated. - [x] Confirm Spec 433 combined credential/permission readiness remains implemented and validated. - [x] Confirm `exchange_powershell_invoke` provider capability evaluation remains implemented and validated. - [x] Confirm no new UI/routes/jobs/schedules/listeners/migrations/customer-output scope is required. ## Scope Requirements - [x] Adapter boundary only. - [x] Content-only guard only. - [x] Identity hard-stop before evidence append. - [x] Empty collection no-fake-evidence policy. - [x] No full target evidence promotion. - [x] No compare/render. - [x] No certification. - [x] No restore. - [x] No customer claim. - [x] No UI. - [x] No jobs/schedules/listeners/triggers. - [x] No migration unless spec is amended. - [x] No `tenant_id` ownership truth. ## OperationRun Requirements - [x] Uses `tenant_configuration.capture`. - [x] Does not add a new OperationRun type. - [x] Requires same workspace and managed environment scope. - [x] Requires matching provider connection scope. - [x] Uses existing summary keys only; no `OperationSummaryKeys` expansion was required. - [x] Summary counts are flat numeric values. - [x] OperationRun context contains no raw payload. - [x] OperationRun context contains no raw stdout/stderr. - [x] OperationRun context contains no credential material, token, provider response body, or serialized Exchange object. ## Adapter Boundary Requirements - [x] Exchange adapter exists or repo-canonical equivalent exists. - [x] Adapter is internal/trusted only. - [x] Adapter accepts only `transportRule`, `remoteDomain`, and `inboundConnector`. - [x] Adapter requires Spec 433 readiness. - [x] Adapter requires `exchange_powershell_invoke` provider capability status `Supported`. - [x] Adapter requires Spec 432 runner boundary. - [x] Adapter accepts only successful list-shaped `ExchangePowerShellInvocationResult` output with sanitized `structured_collection` or `empty_collection` context. - [x] Adapter requires Spec 430 verified command contracts. - [x] Adapter does not use `ProviderGateway` or the generic Graph list path. - [x] Adapter does not fake Graph endpoints or fake captured outcomes. - [x] Adapter-local outcome/failure codes are limited to the Spec 434 allowlist. - [x] Persisted evidence outcomes reuse existing `CaptureOutcome` values only. ## Identity Requirements - [x] Identity is evaluated before evidence append. - [x] Identity conflict blocks. - [x] Missing stable external ID blocks unless an existing repo-approved safe rule applies. - [x] Unsupported identity blocks. - [x] Duplicate identity blocks. - [x] Display-name-only stable identity is impossible by default. - [x] Unsafe identity blocks before the writer path by adapter code order plus zero resource/evidence assertions; no literal writer spy is used. - [x] Unsafe identity creates no resource or evidence row. ## Content-Only Guard Requirements - [x] Maximum Exchange adapter coverage level is `content_backed`. - [x] Comparable is not set. - [x] Renderable is not set. - [x] Certified is not set. - [x] Restore-ready is not set. - [x] Customer-claimable is not set. - [x] Existing Graph capture writer behavior remains unchanged. ## Empty Collection Requirements - [x] Empty collection produces a safe zero-item outcome. - [x] Empty collection uses `exchange_capture_empty_collection` or repo-canonical equivalent only as an internal sanitized outcome. - [x] Empty collection may update safe summary counts only. - [x] Empty collection creates no fake resource row. - [x] Empty collection creates no fake evidence row. - [x] Durable collection-level empty proof is deferred. ## Redaction Requirements - [x] Raw provider payload stays out of OperationRun context, messages, logs, notifications, and summaries. - [x] Raw stdout/stderr stays out of OperationRun context, messages, logs, notifications, and summaries. - [x] Serialized Exchange objects stay out of OperationRun context, messages, logs, notifications, and summaries. - [x] Credential material, tokens, authorization headers, cookies, and certificate material never appear in context/logs/tests. - [x] Sensitive Exchange configuration examples are not rendered or summarized as product/customer output. ## Product Surface / Trigger Requirements - [x] No routes. - [x] No Filament pages/resources/widgets. - [x] No Livewire components. - [x] No Blade/view changes. - [x] No navigation. - [x] No asset changes. - [x] No global search changes. - [x] No job trigger. - [x] No schedule trigger. - [x] No listener trigger. - [x] No customer output. - [x] No report, Review Pack, PDF, restore, compare/render, or certification surface. - [x] Browser result is `N/A - no rendered UI surface changed`. ## Architecture Requirements - [x] Uses existing Coverage v2 evidence architecture. - [x] Generic Graph capture remains intact. - [x] No Exchange-specific evidence table. - [x] No `tenant_id` ownership truth. - [x] No new `CaptureOutcome` enum value. - [x] No Exchange mini-platform. - [x] No legacy shim. - [x] No fallback reader. - [x] No dual write. - [x] No Coverage v1 bridge. ## Validation Requirements - [x] Focused Spec 434 unit-test intent is covered by the DB-backed Spec 434 feature test file per the tasks implementation note. - [x] Focused Spec 434 feature tests pass; implementation report records 25 tests / 154 assertions. - [x] Spec 433 regression passes. - [x] Spec 432/431/430 regression passes. - [x] Coverage v2/generic capture/identity/provider regressions pass. - [x] Provider capability regressions prove `exchange_powershell_invoke` must be `Supported` before adapter capture proceeds. - [x] Laravel 12, PHP 8.4, PostgreSQL, and Pest 4 compatibility notes are recorded. - [x] Pint passes. - [x] `git diff --check` passes for tracked changes; untracked file content is not claimed as covered until staged/tracked and is listed through `git status --short`. - [x] `git status --short` is documented. - [x] Implementation report records all required matrices and deferred work. ## Final Implementation Gate Choose one during implementation close-out: ```text PASS PASS WITH CONDITIONS FAIL ``` PASS requires: ```text Exchange capture adapter boundary exists. tenant_configuration.capture is reused. No new OperationRun type is added. exchange_powershell_invoke provider capability is required and Supported. Accepted runner output is an ExchangePowerShellInvocationResult with list-shaped structured or empty collection context. Identity hard-stop prevents unsafe evidence append. Content-only guard prevents promotion beyond content_backed. Empty collection policy prevents fake evidence. Generic Graph capture remains intact. OperationRun context is sanitized. Persisted outcomes use existing CaptureOutcome values and internal outcome/failure codes are allowlisted. No compare/render/certification/restore/customer state appears. No UI/routes/jobs/schedules/listeners are added. No tenant_id ownership truth is introduced. No Exchange-specific evidence table appears. Focused tests and regressions pass. ``` PASS WITH CONDITIONS is allowed only for bounded follow-ups that do not weaken adapter safety, identity hard-stop, content-only guard, empty-collection safety, redaction, no-promotion posture, no-product-surface posture, ownership, or no-mini-platform posture. FAIL if: ```text Exchange adapter bypasses readiness gates. Exchange adapter proceeds while exchange_powershell_invoke is not Supported. Exchange adapter accepts malformed or unverified runner output. Unsafe identity can append evidence. CoverageEvidenceWriter can over-promote through the Exchange path. Empty collection creates fake evidence. New CaptureOutcome values are added without spec amendment. Exchange routes through Graph gateway incorrectly. OperationRun stores raw payload or credential/provider secrets. Coverage promotes to comparable/renderable/certified. Restore/customer claims appear. UI/routes/jobs/schedules/listeners are added. tenant_id ownership truth is introduced. Exchange-specific evidence table appears. Tests do not prove adapter and guard safety. ```