TenantAtlas/specs/231-finding-outcome-taxonomy/tasks.md
ahmido 421261a517
Some checks failed
Main Confidence / confidence (push) Failing after 48s
feat: implement finding outcome taxonomy (#267)
## Summary
- implement the finding outcome taxonomy end-to-end with canonical resolve, close, reopen, and verification semantics
- align finding UI, filters, audit metadata, review summaries, and export/read-model consumers to the shared outcome semantics
- add focused Pest coverage and complete the spec artifacts for feature 231

## Details
- manual resolve is limited to the canonical `remediated` outcome
- close and reopen flows now use bounded canonical reasons
- trusted system clear and reopen distinguish verified-clear from verification-failed and recurrence paths
- duplicate lifecycle backfill now closes findings canonically as `duplicate`
- accepted-risk recording now uses the canonical `accepted_risk` reason
- finding detail and list surfaces now expose terminal outcome and verification summaries
- review, snapshot, and review-pack consumers now propagate the same outcome buckets

## Filament / Platform Contract
- Livewire v4.0+ compatibility remains intact
- provider registration is unchanged and remains in `bootstrap/providers.php`
- no new globally searchable resource was introduced; `FindingResource` still has a View page and `TenantReviewResource` remains globally searchable false
- lifecycle mutations still run through confirmed Filament actions with capability enforcement
- no new asset family was added; the existing `filament:assets` deploy step is unchanged

## Verification
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingWorkflowServiceTest.php tests/Feature/Findings/FindingRecurrenceTest.php tests/Feature/Findings/FindingsListFiltersTest.php tests/Feature/Filament/FindingResolvedReferencePresentationTest.php tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings tests/Feature/Filament/FindingResolvedReferencePresentationTest.php tests/Feature/Models/FindingResolvedTest.php tests/Unit/Findings/FindingWorkflowServiceTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantReview/TenantReviewExplanationSurfaceTest.php tests/Feature/TenantReview/TenantReviewRegisterTest.php tests/Feature/ReviewPack/TenantReviewDerivedReviewPackTest.php`
- browser smoke: `/admin/findings/my-work` -> finding detail resolve flow -> queue regression check passed

## Notes
- this commit also includes the existing `.github/agents/copilot-instructions.md` workspace change that was already present in the worktree when all changes were committed

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #267
2026-04-23 07:29:05 +00:00

17 KiB

Tasks: Finding Outcome Taxonomy & Verification Semantics

Input: Design documents from /specs/231-finding-outcome-taxonomy/ Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/finding-outcome-taxonomy.logical.openapi.yaml, quickstart.md, checklists/requirements.md

Tests: Required. This feature changes runtime behavior in the tenant findings workflow, terminal-outcome presentation, and findings-derived review/report buckets, so Pest coverage must be added or updated in apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php, apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php, apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php, apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php, apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php, and apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php. Operations: No new OperationRun is introduced. Existing operation_run_id provenance remains in scope only for trusted system clear and system reopen audit context; no new monitoring surface, queued notification surface, or run lifecycle contract may be introduced. RBAC: This feature stays on the tenant /admin/t/{tenant}/findings plane plus existing tenant-scoped review consumers. The implementation must preserve non-member or cross-tenant 404, in-scope missing-capability 403, current server-side authorization in FindingWorkflowService, and existing tenant-safe review visibility semantics. UI / Surface Guardrails: The existing tenant findings list, finding detail surface, and findings-derived review readers remain the only changed surfaces. This is a standard-native-filament slice with review-mandatory treatment; no new queue, no second detail shell, and no page-local outcome language may be introduced. Filament UI Action Surfaces: FindingResource remains the only mutated Filament action surface, and ReviewRegister plus TenantReviewResource remain read-only consumers of the shared outcome semantics. No new page family, no second inspect model, no new global search entry point, and no empty action groups may be introduced. Badges: Existing BadgeCatalog and BadgeRenderer semantics remain authoritative. Any terminal-outcome emphasis must extend shared finding presentation rules instead of adding page-local badge or color mappings.

Organization: Tasks are grouped by user story so each slice remains independently testable once the shared outcome seam exists. Recommended delivery order is US1 -> US2 -> US3 because manual canonical reasons must stabilize before trusted system-clear semantics and downstream reporting buckets can converge.

Test Governance Checklist

  • Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
  • Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
  • Planned validation commands cover the change without pulling in unrelated lane cost.
  • The declared surface test profile or standard-native-filament relief is explicit.
  • Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.

Phase 1: Setup (Focused Findings Outcome Test Surfaces)

Purpose: Prepare the narrow regression surfaces that will prove manual terminal reasons, trusted verification, and findings-derived report buckets.

  • T001 [P] Extend the canonical workflow transition test scaffold in apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php
  • T002 [P] Extend the trusted recurrence and verification-failure scaffold in apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php
  • T003 [P] Extend the terminal-outcome filter scaffold in apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php
  • T004 [P] Extend the findings detail presentation scaffold in apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php
  • T005 [P] Create the findings-derived summary bucket scaffold in apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php
  • T006 [P] Extend the accepted-risk projection scaffold in apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php

Checkpoint: Focused findings workflow, presentation, and reporting test surfaces are ready for implementation work.


Phase 2: Foundational (Blocking Canonical Outcome Seam)

Purpose: Establish the canonical outcome seam and pre-production reason-key normalization before any user story implementation begins.

CRITICAL: No user story work should begin until this phase is complete.

  • T007 Implement canonical resolve, close, and reopen reason-key families in apps/platform/app/Models/Finding.php
  • T008 Create the shared derived terminal-outcome mapper in apps/platform/app/Support/Findings/FindingOutcomeSemantics.php
  • T009 Update canonical historical-context interpretation in apps/platform/app/Services/Findings/FindingRiskGovernanceResolver.php
  • T010 Normalize canonical finding outcome fixture states in apps/platform/database/factories/FindingFactory.php
  • T011 Replace pre-production legacy reason keys in apps/platform/app/Jobs/BackfillFindingLifecycleJob.php
  • T012 Replace workspace-run legacy reason keys in apps/platform/app/Jobs/BackfillFindingLifecycleTenantIntoWorkspaceRunJob.php
  • T013 Add baseline canonical-outcome and audit-metadata contract assertions in apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php

Checkpoint: The canonical outcome seam exists, historical context is aligned to canonical keys, and all supporting fixtures and backfill paths use one pre-production key family.


Phase 3: User Story 1 - End A Finding With The Correct Terminal Meaning (Priority: P1) 🎯

Goal: Give operators bounded resolve and close reasons so manual terminal outcomes are explicit instead of prose-driven.

Independent Test: Resolve and close open findings through the existing actions, then verify the workflow response, detail narrative, and terminal-outcome filters show Resolved pending verification or the correct administrative closure outcome without depending on free-form text.

Tests for User Story 1

  • T014 [P] [US1] Add canonical manual resolve, close, risk-accept, and reopen validation plus audit-entry assertions in apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php
  • T015 [P] [US1] Add manual terminal-outcome detail assertions in apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php
  • T016 [P] [US1] Add manual terminal-outcome filter assertions in apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php

Implementation for User Story 1

  • T017 [US1] Enforce canonical manual resolve, close, risk-accept, and reopen reason keys plus structured audit outcome copy in apps/platform/app/Services/Findings/FindingWorkflowService.php
  • T018 [US1] Align close-action labels, modal copy, and field contract in apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php
  • T019 [US1] Replace single-record resolve and close inputs with canonical selections in apps/platform/app/Filament/Resources/FindingResource.php
  • T020 [US1] Replace bulk resolve and close inputs plus completion copy with canonical selections in apps/platform/app/Filament/Resources/FindingResource.php
  • T021 [US1] Surface manual terminal-outcome summaries on the finding detail surface in apps/platform/app/Filament/Resources/FindingResource.php

Checkpoint: User Story 1 is independently functional and operators can end findings with bounded manual terminal meanings.


Phase 4: User Story 2 - See Whether A Terminal Finding Was Actually Verified Clear (Priority: P1)

Goal: Distinguish operator-declared resolution from later trusted verified-clear outcomes and structured recurrence reopen paths.

Independent Test: Resolve a finding manually, then apply trusted system clear and trusted recurrence paths and verify the result becomes Verified cleared or reopens with a structured reason without adding a new primary status.

Tests for User Story 2

  • T022 [P] [US2] Add verified-clear transition and audit assertions for direct and post-manual system clears in apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php
  • T023 [P] [US2] Add recurrence and verification-failure reopen plus audit assertions in apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php
  • T024 [P] [US2] Add verified-cleared detail presentation assertions in apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php

Implementation for User Story 2

  • T025 [US2] Widen trusted system clear and reopen handling for verified-clear semantics and audit context in apps/platform/app/Services/Findings/FindingWorkflowService.php
  • T026 [US2] Normalize baseline auto-close system-clear reason keys in apps/platform/app/Services/Baselines/BaselineAutoCloseService.php
  • T027 [US2] Normalize Entra admin-role system clear and reopen reason keys in apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php
  • T028 [US2] Normalize permission-posture system clear and reopen reason keys in apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php
  • T029 [US2] Align recurrence-driven system reopen keys in apps/platform/app/Jobs/CompareBaselineToTenantJob.php
  • T030 [US2] Surface verified-cleared summaries and historical context on the finding resource in apps/platform/app/Filament/Resources/FindingResource.php

Checkpoint: User Story 2 is independently functional and terminal findings can now distinguish manual resolution from trusted verified clearance.


Phase 5: User Story 3 - Filter And Summarize Terminal Outcomes Consistently (Priority: P2)

Goal: Apply one canonical taxonomy across queue filters, review readers, and findings-derived reporting buckets.

Independent Test: Seed mixed terminal outcomes and verify the queue filters, default open backlog, review views, executive-pack export cues, and findings-derived summaries keep Resolved pending verification, Verified cleared, administrative closures, and Risk accepted in distinct buckets.

Tests for User Story 3

  • T031 [P] [US3] Add queue filter coverage for all canonical manual and verified terminal buckets plus default open-backlog regression assertions in apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php
  • T032 [P] [US3] Add findings-derived review, reporting, and export-summary bucket coverage in apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php
  • T033 [P] [US3] Add accepted-risk governance-bucket separation coverage in apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php

Implementation for User Story 3

  • T034 [US3] Implement terminal-outcome filters and default-visible queue summaries while preserving existing open-backlog defaults in apps/platform/app/Filament/Resources/FindingResource.php
  • T035 [US3] Reuse shared outcome semantics in review register findings summaries in apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php
  • T036 [US3] Reuse shared outcome semantics in tenant review outcome presentation and executive-pack export cues in apps/platform/app/Filament/Resources/TenantReviewResource.php

Checkpoint: User Story 3 is independently functional and downstream readers no longer invent their own terminal-outcome taxonomy.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Finish copy review, formatting, and the narrow proving workflow for the full feature.

  • T037 Review operator-facing outcome labels and modal helper copy in apps/platform/app/Filament/Resources/FindingResource.php
  • T038 Run formatting for the touched findings outcome files referenced in specs/231-finding-outcome-taxonomy/quickstart.md with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
  • T039 Run cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingWorkflowServiceTest.php tests/Feature/Findings/FindingRecurrenceTest.php and cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingsListFiltersTest.php tests/Feature/Filament/FindingResolvedReferencePresentationTest.php tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php for apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php, apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php, apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php, apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php, apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php, and apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): Starts immediately and prepares the focused test surfaces.
  • Foundational (Phase 2): Depends on Setup and blocks all user story work until the canonical outcome seam and pre-production key normalization are in place.
  • User Story 1 (Phase 3): Depends on Foundational completion and is the first shippable behavior slice.
  • User Story 2 (Phase 4): Depends on User Story 1 because trusted verification semantics build on the manual canonical reason contract.
  • User Story 3 (Phase 5): Depends on User Story 1 and User Story 2 because queue filters and review/report buckets must consume the settled shared taxonomy.
  • Polish (Phase 6): Depends on all desired user stories being complete.

User Story Dependencies

  • US1: No dependencies beyond Foundational.
  • US2: Requires the canonical manual reason contract from US1.
  • US3: Requires the settled manual and trusted verification semantics from US1 and US2.

Within Each User Story

  • Write the story tests first and confirm they fail before implementation is considered complete.
  • Keep apps/platform/app/Support/Findings/FindingOutcomeSemantics.php authoritative for derived terminal meaning instead of duplicating page-local mappings.
  • Finish story-level verification before moving to the next priority slice.

Parallel Opportunities

  • T001 through T006 can run in parallel during Setup.
  • T014, T015, and T016 can run in parallel for User Story 1.
  • T022, T023, and T024 can run in parallel for User Story 2.
  • T031, T032, and T033 can run in parallel for User Story 3.

Parallel Example: User Story 1

# User Story 1 tests in parallel
T014 apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php
T015 apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php
T016 apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php

Parallel Example: User Story 2

# User Story 2 tests in parallel
T022 apps/platform/tests/Feature/Findings/FindingWorkflowServiceTest.php
T023 apps/platform/tests/Feature/Findings/FindingRecurrenceTest.php
T024 apps/platform/tests/Feature/Filament/FindingResolvedReferencePresentationTest.php

Parallel Example: User Story 3

# User Story 3 tests in parallel
T031 apps/platform/tests/Feature/Findings/FindingsListFiltersTest.php
T032 apps/platform/tests/Feature/Findings/FindingOutcomeSummaryReportingTest.php
T033 apps/platform/tests/Feature/Findings/FindingRiskGovernanceProjectionTest.php

Implementation Strategy

MVP First

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3: User Story 1.
  4. Complete Phase 4: User Story 2.
  5. Validate the feature against the focused US1 and US2 tests before widening to downstream review/report consumers.

Incremental Delivery

  1. Ship US1 to replace free-form terminal reasons with bounded manual outcomes.
  2. Add US2 to close the roadmap gap between operator-declared resolution and trusted verified clearance.
  3. Add US3 to converge queue filters and findings-derived review/report buckets on the same taxonomy.
  4. Finish with copy review, formatting, and the focused validation pack.

Parallel Team Strategy

  1. One contributor can prepare the shared helper and canonical key normalization while another extends the focused test scaffolds.
  2. After Foundational work lands, manual findings actions and trusted system-clear producer paths can progress in parallel across different files.
  3. Review-register and tenant-review consumers can be updated in parallel once the settled outcome seam and queue filters are complete.

Notes

  • [P] tasks target different files and can be worked independently once upstream blockers are cleared.
  • [US1], [US2], and [US3] map directly to the feature specification user stories.
  • The suggested MVP scope is Phase 1 through Phase 4 because the feature promise is incomplete without the verified-clear slice.
  • All implementation tasks above follow the required checklist format with task ID, optional parallel marker, story label where applicable, and exact file paths.