# Tasks: Spec 343 - Customer Review Attestation & Accepted Risk Lifecycle **Branch**: `343-customer-review-attestation-accepted-risk-lifecycle` | **Date**: 2026-06-01 | **Spec**: `specs/343-customer-review-attestation-accepted-risk-lifecycle/spec.md` ## Phase 0: Preflight / Guardrails - [ ] T001 Confirm working tree is clean and branch is `343-customer-review-attestation-accepted-risk-lifecycle`. - [x] T002 Confirm no completed spec package is modified (Specs 326, 329, 337, 342 are context only). - [x] T003 Re-read Spec 342 state contract and repo-truth map so Spec 343 does not regress customer-safe consumption semantics. ## Phase 1: Repo Truth Map + State Contract (no runtime changes yet) - [x] T010 Inspect current Customer Review Workspace implementation: - `apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php` - `apps/platform/resources/views/filament/pages/reviews/customer-review-workspace.blade.php` - [x] T011 Confirm accepted risk truth source and fields: - `apps/platform/app/Models/FindingException.php` - `apps/platform/app/Models/FindingExceptionDecision.php` - [x] T012 Confirm acknowledgement truth does not already exist as a review-scoped model/table (do not assume). - [x] T013 Update `specs/343-customer-review-attestation-accepted-risk-lifecycle/repo-truth-map.md` with confirmed classifications and evidence. - [x] T014 Update `specs/343-customer-review-attestation-accepted-risk-lifecycle/review-attestation-risk-state-contract.md` so every displayed state is repo-backed or explicitly “not available / deferred”. - [x] T015 Decide the narrowest correct acknowledgement basis capture (review id + pack id and/or evidence snapshot id) that supports “re-ack required” without guessing. ## Phase 2: Acknowledgement Persistence (conditional) - [x] T020 If repo truth confirms no review acknowledgement persistence exists, add a minimal persisted entity: - migration (PostgreSQL) for `environment_review_acknowledgements` (final name TBD) - model `EnvironmentReviewAcknowledgement` (final name TBD) - workspace + managed-environment scoping fields - captured basis fields (review pack id and/or evidence snapshot id where present) - indexes for `(workspace_id, managed_environment_id, environment_review_id)` and actor/time query paths - [x] T021 Decide append-only vs single-current record semantics; implement the narrowest correct version and capture the decision in spec artifacts. - [x] T022 Add/extend policies/gates so cross-workspace access is denied-as-not-found and acknowledgement writes require a dedicated capability. ## Phase 3: Service + Audit Wiring - [x] T030 Add an acknowledgement service/action class (domain-owned) that: - authorizes the actor (capability + scope) - records acknowledgement with basis capture - emits an audit event - [x] T031 Add audit action IDs for acknowledgement events and ensure payload is customer-safe. ## Phase 4: Customer Review Workspace UI Wiring - [x] T040 Implement derived “attestation state” computation for the page using only repo-backed truth (no new status families). - [x] T041 Update the Blade view to render: - acknowledgement card (status/reason/impact/primary next action) - evidence/review-pack basis fields for the acknowledgement section - accepted-risk lifecycle section remains visible and customer-safe - [x] T042 Add an “Acknowledge review” action: - uses `Action::make(...)->action(...)` - requires confirmation - collects optional comment - writes only through the service/action class - shows success/error notifications - [x] T043 Keep diagnostics collapsed by default and capability-gated (`support_diagnostics.view`). - [x] T044 Ensure no legal/compliance/certification wording is introduced and existing “not a legal attestation” disclosures remain consistent. ## Phase 5: Accepted Risk Lifecycle Tightening (Finding Exceptions) - [x] T050 Confirm the accepted-risk section uses `FindingException` truth consistently (status + validity states + owner/reason/dates). - [x] T051 Add or refine highlighting for: - expiring / expired / revoked / missing_support - missing owner, missing rationale, missing expiry/review date (only if repo truth supports these fields) - [x] T052 Ensure accepted-risk “no records” copy never implies “no risks exist” (truth: only “no accepted risks recorded”). ## Phase 6: Feature/Livewire Tests (Pest) - [x] T060 Add `apps/platform/tests/Feature/Filament/Spec343CustomerReviewAttestationAcceptedRiskTest.php` covering: - acknowledgement card visible and correct per state - acknowledgement required vs acknowledged (fixture-backed) - “re-ack required” only when basis drift detection is repo-backed - no legal/e-signature claim - evidence basis visibility - diagnostics collapsed by default - acknowledgement action authorization + audit emission + basis capture - cross-workspace isolation (not found) - [x] T061 Add test coverage for accepted-risk lifecycle visibility using existing `FindingException` fixtures/factories. ## Phase 7: Browser Smoke + Screenshots - [x] T070 Add `apps/platform/tests/Browser/Spec343CustomerReviewAttestationAcceptedRiskSmokeTest.php` covering browser-visible states: - acknowledgement required - acknowledged (if fixture-supported) - accepted risks present (active / due for review / expired where possible) - no accepted risks - diagnostics collapsed - dark mode (if practical) - [x] T071 Capture screenshots under `specs/343-customer-review-attestation-accepted-risk-lifecycle/artifacts/screenshots/`: - `01-acknowledgement-required.png` - `02-review-acknowledged.png` - `03-accepted-risks-present.png` - `04-accepted-risk-due-for-review.png` - `05-accepted-risk-expired.png` - `06-no-accepted-risks.png` - `07-diagnostics-collapsed.png` - `08-dark-mode.png` - [x] T072 If a screenshot state is unreachable, document why in the spec package instead of faking backend truth. ## Phase 8: UI Coverage Artifacts (post-diff decision) - [x] T080 Decide whether `docs/ui-ux-enterprise-audit/page-reports/ui-006-customer-review-workspace.md` requires an update due to new acknowledgement card/action. - [x] T081 Record the final decision in the PR close-out entry `Guardrail / Exception / Smoke Coverage` (do not leave it implicit). ## Phase 9: Validation - [x] T090 Run: - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/Spec343CustomerReviewAttestationAcceptedRiskTest.php --compact` - `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec343CustomerReviewAttestationAcceptedRiskSmokeTest.php --compact` - `cd apps/platform && ./vendor/bin/sail artisan test --filter='CustomerReview|EnvironmentReview|ReviewPack|Evidence|FindingException|Audit' --compact` - Note: the broad filter run currently surfaces unrelated failing tests (e.g. `WorkspaceLastOwnerGuardTest`, `TenantDashboardProductizationReadinessTest`) and triggered a PHP crash (`zend_mm_heap corrupted`, signal 6) in this environment; Spec 343 gates rely on the targeted spec tests above. - [x] T091 Run: - `cd apps/platform && php vendor/bin/pint --dirty` - `git diff --check` - [x] T092 Update `repo-truth-map.md` + state contract based on what was discovered/implemented. ## Explicit Non-Goals - [x] NT001 Do not build a generic GRC framework, risk scoring engine, or policy exception board. - [x] NT002 Do not introduce legal signature / compliance certification semantics. - [x] NT003 Do not introduce external customer portal architecture or external identity federation/invitations in this slice. - [x] NT004 Do not introduce Graph/provider calls during UI render. - [x] NT005 Do not expose raw provider JSON, internal IDs as primary labels, or diagnostics by default. - [x] NT006 Do not rewrite completed Specs 326, 329, 337, or 342. ## Required Final Report Content For Later Implementation When implementation completes, report: - What changed (acknowledgement truth + accepted-risk lifecycle visibility). - Attestation states supported and any deferred/unavailable states. - Accepted risk lifecycle states supported and what fields are repo-backed. - Evidence/review-pack basis and audit truth (no false claims). - RBAC/isolation behavior. - Files changed. - Tests run + results. - Browser smoke + screenshots path. - Migration/deployment impact statement (migrations yes/no; env vars; queues/scheduler; filament assets).