# Quickstart: Findings Workflow Enforcement and Audit Backstop ## Goal Verify that findings lifecycle mutations now follow one canonical workflow path and always produce durable audit history for covered changes. ## Prerequisites 1. Start Sail if it is not already running. 2. Use a workspace and tenant with at least one authorized findings operator. 3. Ensure test factories can create findings in multiple statuses. ## Focused Verification Flow ### 1. Run the focused post-implementation findings workflow suites ```bash vendor/bin/sail artisan test --compact \ tests/Feature/Findings/FindingWorkflowGuardTest.php \ tests/Feature/Findings/FindingWorkflowServiceTest.php \ tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php \ tests/Feature/Findings/FindingWorkflowRowActionsTest.php \ tests/Feature/Findings/FindingWorkflowViewActionsTest.php \ tests/Feature/Findings/FindingAuditBackstopTest.php \ tests/Feature/Audit/FindingAuditVisibilityTest.php \ tests/Feature/Findings/FindingRbacTest.php ``` Expected outcome: - workflow mutations succeed only for allowed transitions - list and view action surfaces still execute the canonical workflow gateway - owner reassignment and reason-bearing workflow mutations follow the same gateway and validation rules - audit entries are written exactly once per covered mutation - non-members get `404` - in-scope users without capability get `403` ### 2. Run the automation and recurrence suites ```bash vendor/bin/sail artisan test --compact \ tests/Feature/Findings/DriftStaleAutoResolveTest.php \ tests/Feature/PermissionPosture/PermissionPostureFindingGeneratorTest.php \ tests/Feature/EntraAdminRoles/EntraAdminRolesFindingGeneratorTest.php \ tests/Feature/Findings/FindingRecurrenceTest.php \ tests/Feature/Findings/FindingAutomationWorkflowTest.php \ tests/Feature/Findings/FindingWorkflowConcurrencyTest.php ``` Expected outcome: - system-origin resolve and reopen mutations emit canonical audit rows - recurrence and stale-auto-resolve paths use the same lifecycle truth as human actions - older automated observations do not override newer human terminal decisions ### 3. Run the existing findings compatibility suites ```bash vendor/bin/sail artisan test --compact \ tests/Feature/Findings/FindingAuditLogTest.php \ tests/Feature/Findings/FindingBulkActionsTest.php ``` Expected outcome: - legacy findings flows still pass on top of the canonical gateway and audit backstop ### 4. Run the Filament action-surface contract guard ```bash vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php ``` Expected outcome: - the Findings resource still satisfies the required Filament action surface slots after workflow rewiring - grouped actions, inspection affordances, and mutation visibility rules remain intact ### 5. Verify tenant-context UI actions 1. Open the Findings page for an entitled tenant. 2. Execute `Triage`, `Start progress`, `Assign`, `Resolve`, `Close`, `Risk accept`, and `Reopen` on representative findings, including an owner reassignment case and a reason-required transition. 3. Confirm that disabled actions remain visible for members without capability and execute as `403` if forced server-side. Expected outcome: - existing Findings action surfaces remain unchanged from the operator perspective - destructive-like workflow actions still require confirmation - `Close` and `Risk accept` are only visible for open findings; `Reopen` is only visible for terminal findings - invalid transitions fail safely and do not mutate the record - no workflow mutation bypasses the existing Findings action surface contract ### 6. Verify audit review 1. Open the canonical Audit Log surface. 2. Filter to finding-related audit rows. 3. Confirm that workflow history shows actor, tenant scope, before state, after state, owner or assignee changes, and transition reason where applicable. 4. Confirm that an authorized audit viewer can still understand the historical event when the live finding is deleted, merged away, or no longer directly accessible. Expected outcome: - finding audit rows remain readable even if the live finding is no longer directly visible - unauthorized audit viewers do not see finding-related tenant details outside their entitlement scope - internal bookkeeping metadata such as `_actor_type` and `_dedupe_key` do not render in the inspection view ## Implementation Sequence 1. Consolidate lifecycle mutations behind the canonical findings workflow gateway. 2. Neutralize direct `Finding` lifecycle mutators and other bypass paths in covered services. 3. Cover owner reassignment and reason-bearing lifecycle updates with the same gateway and audit contract. 4. Adopt the same gateway for auto-resolve and recurrence flows. 5. Normalize audit action registration and metadata expectations. 6. Add regression guards and focused test coverage, including the Filament action-surface guard. ## Rollout Notes - Prefer additive code-path hardening over schema changes. - Keep legacy `acknowledged` rows readable during rollout. - Human and system-origin lifecycle mutations now converge on the same workflow gateway and audit contract. - Workspace mismatch remains deny-as-not-found on the policy path and deny-safe on the Filament action path. - Run the focused findings and audit suites before broader tenant workflow or baseline suites.