TenantAtlas/specs/434-exchange-evidence-capture-adapter-content-only-guard/checklists/requirements.md
ahmido a23131cdbc feat: add Exchange evidence capture adapter guard (#501)
Summary: add Spec 434 Exchange PowerShell evidence capture adapter and prerequisite/identity/content-only guards; cap Exchange evidence at content_backed while preserving Graph capture. Validation: php artisan test --filter=Spec434 --compact; ./vendor/bin/pint --dirty --test; git diff --cached --check. Product Surface: N/A - no rendered UI surface changed; no deployment impact.
Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #501
2026-07-08 10:46:05 +00:00

213 lines
9.7 KiB
Markdown

# 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.
```