13 KiB
Tasks: Findings Workflow Enforcement and Audit Backstop
Input: Design documents from /specs/151-findings-workflow-backstop/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/, quickstart.md
Tests: Tests are REQUIRED for this feature because it changes runtime behavior, authorization-sensitive mutation paths, and audit guarantees.
Operations: This feature does not introduce new long-running or queued work. Existing runbooks remain out of scope unless they mutate findings lifecycle truth, in which case they must use AuditLog coverage instead of new OperationRun behavior.
RBAC: Findings mutations remain tenant/admin plane behavior. Non-members or users outside workspace or tenant scope must resolve as 404; in-scope users lacking capability must resolve as 403. No raw capability strings or role-string checks may be introduced.
UI Naming: Existing operator-facing wording remains Triage, Start progress, Assign, Resolve, Close, Risk accept, and Reopen across UI and audit surfaces.
Filament UI Action Surfaces: Existing Findings list and view surfaces remain the primary UI contract. Tasks below preserve grouped workflow actions, confirmation requirements, audit logging, and inspection affordances.
Badges: No new badge domain is introduced. Existing finding status badges remain centralized and must not be remapped locally.
Phase 1: Setup (Shared Infrastructure)
Purpose: Prepare shared fixtures and helper coverage used by all stories.
- T001 Update lifecycle-ready finding factory states in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/database/factories/FindingFactory.php
- T002 [P] Add shared findings workflow test helpers in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Pest.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/Concerns/InteractsWithFindingsWorkflow.php
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Establish the shared workflow and audit foundation before any user-story slice is implemented.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T003 Normalize findings workflow audit action registration in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Audit/AuditActionId.php
- T004 Establish the service-owned findings workflow gateway for status, owner-assignment, and reason-bearing lifecycle mutations in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Findings/FindingWorkflowService.php
- T005 [P] Add workflow bypass regression guard coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingWorkflowGuardTest.php
- T006 [P] Tighten findings audit sanitization and summary handling in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Audit/AuditContextSanitizer.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Intune/AuditLogger.php
Checkpoint: Shared workflow and audit primitives are ready. User stories can now be implemented independently.
Phase 3: User Story 1 - Prevent Invalid Workflow Bypasses (Priority: P1) 🎯 MVP
Goal: Ensure every covered findings lifecycle mutation goes through one enforced transition path and fails closed on invalid or bypassed writes.
Independent Test: Attempt valid and invalid transitions through service, list action, bulk action, and direct mutation-style paths; only valid transitions should persist.
Tests for User Story 1
- T007 [P] [US1] Add transition validation tests for status changes, owner reassignment, and required-reason mutations in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingWorkflowServiceTest.php
- T008 [P] [US1] Add Livewire findings action enforcement tests that preserve the existing action surface contract in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php
Implementation for User Story 1
- T009 [US1] Remove or neutralize direct lifecycle mutators in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Models/Finding.php
- T010 [US1] Rewire single-record workflow actions to the canonical gateway in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/FindingResource.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/FindingResource/Pages/ViewFinding.php
- T011 [US1] Rewire bulk workflow actions to the canonical gateway in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/FindingResource.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/FindingResource/Pages/ListFindings.php
- T012 [US1] Tighten tenant-scope and capability enforcement for covered mutations in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Policies/FindingPolicy.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Findings/FindingWorkflowService.php
Checkpoint: User Story 1 is complete when invalid transitions and direct bypass attempts no longer mutate findings and existing Findings UI actions still function for authorized users.
Phase 4: User Story 2 - Trust the Audit History for Findings Lifecycle Changes (Priority: P1)
Goal: Guarantee that every covered findings lifecycle mutation produces one durable, readable, tenant-safe audit event.
Independent Test: Execute representative lifecycle changes and confirm exactly one audit row is created per mutation with the correct actor, scope, before-state, after-state, and reason metadata.
Tests for User Story 2
- T013 [P] [US2] Add findings audit backstop tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingAuditBackstopTest.php
- T014 [P] [US2] Add finding audit visibility, scope, and deleted-or-inaccessible record readability tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Audit/FindingAuditVisibilityTest.php
Implementation for User Story 2
- T015 [US2] Ensure each covered gateway mutation, including owner reassignment and reason-bearing updates, writes one canonical audit event in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Findings/FindingWorkflowService.php
- T016 [US2] Register findings workflow audit summaries and labels in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Audit/AuditActionId.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Navigation/RelatedNavigationResolver.php
- T017 [US2] Enforce findings audit metadata minimization in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Audit/AuditContextSanitizer.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Models/AuditLog.php
- T018 [US2] Add duplicate-audit prevention and backstop behavior in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Audit/AuditRecorder.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Intune/AuditLogger.php
Checkpoint: User Story 2 is complete when covered lifecycle mutations always emit one readable audit event and audit review remains tenant-safe.
Phase 5: User Story 3 - Keep Recurrence and Reopen Semantics Consistent Across All Mutation Paths (Priority: P2)
Goal: Bring system-driven reopen and auto-resolve flows under the same lifecycle truth and audit rules as interactive workflow actions.
Independent Test: Run recurrence and auto-resolve scenarios through baseline, permission posture, and Entra-admin flows and confirm they use the same workflow rules and audit outputs as UI actions.
Tests for User Story 3
- T019 [P] [US3] Add automation workflow regression tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingAutomationWorkflowTest.php
- T020 [P] [US3] Add concurrency edge-case tests for human and automation mutations in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Findings/FindingWorkflowConcurrencyTest.php
Implementation for User Story 3
- T021 [US3] Route baseline auto-close through the canonical gateway in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Baselines/BaselineAutoCloseService.php
- T022 [US3] Route permission posture lifecycle updates through the canonical gateway in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php
- T023 [US3] Route Entra admin roles lifecycle updates through the canonical gateway in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php
- T024 [US3] Unify recurrence reopen handling in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Jobs/CompareBaselineToTenantJob.php and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Findings/FindingWorkflowService.php
Checkpoint: User Story 3 is complete when automation paths no longer mutate findings lifecycle truth through private side channels.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Finalize documentation alignment and end-to-end verification across all stories.
- T025 [P] Update verification notes and final command set, including the Filament action-surface guard, in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/151-findings-workflow-backstop/quickstart.md and /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/151-findings-workflow-backstop/contracts/findings-workflow.openapi.yaml
- T026 Record final rollout notes and confirm that no unapproved implementation exemptions were introduced in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/151-findings-workflow-backstop/plan.md after running focused Pint and Pest validation
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies; can start immediately.
- Foundational (Phase 2): Depends on Setup completion; blocks all user stories.
- User Story 1 (Phase 3): Depends on Foundational completion; provides the MVP enforcement slice.
- User Story 2 (Phase 4): Depends on Foundational completion and should follow US1 because it hardens the same gateway with audit guarantees.
- User Story 3 (Phase 5): Depends on Foundational completion and benefits from US1 gateway consolidation before routing automation paths.
- Polish (Phase 6): Depends on all desired user stories being complete.
User Story Dependencies
- US1: Can start immediately after Foundational; no dependency on other stories.
- US2: Can begin after Foundational, but is lowest-risk after US1 establishes the canonical gateway.
- US3: Can begin after Foundational, but depends conceptually on the gateway introduced in US1 and the audit guarantees reinforced in US2.
Within Each User Story
- Tests should be written first and verified to fail before implementation.
- Gateway or policy changes should land before UI or automation rewiring.
- Story-specific verification should pass before moving to the next story.
Parallel Opportunities
- T001 and T002 can run in parallel.
- T005 and T006 can run in parallel once T003 and T004 are underway.
- Within each story, the test tasks marked
[P]can run in parallel. - US3 service rewiring tasks T021, T022, and T023 can run in parallel once the canonical gateway behavior is stable.
Parallel Example: User Story 1
# Write the two US1 test files in parallel
Task: T007 [US1] tests/Feature/Findings/FindingWorkflowServiceTest.php
Task: T008 [US1] tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php
# After the tests are in place, rewire the two UI surfaces in parallel
Task: T010 [US1] app/Filament/Resources/FindingResource.php + app/Filament/Resources/FindingResource/Pages/ViewFinding.php
Task: T011 [US1] app/Filament/Resources/FindingResource.php + app/Filament/Resources/FindingResource/Pages/ListFindings.php
Parallel Example: User Story 2
# Add audit backstop and visibility tests in parallel
Task: T013 [US2] tests/Feature/Findings/FindingAuditBackstopTest.php
Task: T014 [US2] tests/Feature/Audit/FindingAuditVisibilityTest.php
# Then split audit taxonomy and sanitizer work
Task: T016 [US2] app/Support/Audit/AuditActionId.php + app/Support/Navigation/RelatedNavigationResolver.php
Task: T017 [US2] app/Support/Audit/AuditContextSanitizer.php + app/Models/AuditLog.php
Parallel Example: User Story 3
# Route automation services independently once the gateway contract is stable
Task: T021 [US3] app/Services/Baselines/BaselineAutoCloseService.php
Task: T022 [US3] app/Services/PermissionPosture/PermissionPostureFindingGenerator.php
Task: T023 [US3] app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php
Implementation Strategy
MVP First
Implement User Story 1 first to establish a single enforced workflow mutation path and remove the most dangerous bypasses. This delivers immediate risk reduction even before audit and automation cleanup are complete.
Incremental Delivery
- Complete Setup and Foundational phases.
- Deliver US1 as the first mergeable slice.
- Add US2 to guarantee durable historical evidence for the same gateway.
- Extend the gateway to automation paths in US3.
- Finish with cross-cutting validation and documentation updates.
Suggested MVP Scope
- MVP: Phase 1 + Phase 2 + Phase 3 (User Story 1)
- Production-ready hardening slice: MVP + Phase 4 (User Story 2)
- Full feature scope: MVP + US2 + US3 + Polish