TenantAtlas/specs/231-finding-outcome-taxonomy/quickstart.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

4.8 KiB

Quickstart: Finding Outcome Taxonomy & Verification Semantics

Goal

Implement one bounded findings outcome taxonomy on top of the existing findings lifecycle so that:

  • operator-resolved findings surface as Resolved pending verification
  • trusted system-cleared findings surface as Verified cleared
  • non-remediation closures stay separate
  • risk_accepted remains governed by exception validity instead of collapsing into remediation semantics

Prerequisites

  • Work on branch 231-finding-outcome-taxonomy
  • Use the existing tenant findings resource and current review consumers; do not add a new panel or queue
  • Run all PHP, Artisan, and Pint commands through Sail

Narrow implementation order

1. Tighten the finding-domain truth

  • Add canonical reason-key families to apps/platform/app/Models/Finding.php or an equivalent findings-local seam
  • Add apps/platform/app/Support/Findings/FindingOutcomeSemantics.php to derive:
    • terminal outcome key
    • verification state
    • report bucket
    • operator-facing label
  • Keep apps/platform/app/Services/Findings/FindingRiskGovernanceResolver.php aligned to the same bounded outcome semantics so risk_accepted stays separate from verified-clear meaning
  • Keep reopen reasons in audit metadata; do not add a reopened_reason column

2. Harden the workflow service

  • Update apps/platform/app/Services/Findings/FindingWorkflowService.php
  • Replace free-form validatedReason() usage with canonical key validation
  • Keep manual resolve as remediated and system-clear reasons as trusted verified-clear keys
  • Widen the system-clear path narrowly enough to confirm already resolved findings without adding a new primary status
  • Preserve or extend audit metadata for resolved_reason, closed_reason, reopened_reason, system_origin, and timestamps

3. Align automation paths

  • Update these existing producers to use the canonical system-clear and reopen keys:
    • apps/platform/app/Services/Baselines/BaselineAutoCloseService.php
    • apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php
    • apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php
    • apps/platform/app/Jobs/CompareBaselineToTenantJob.php
  • Replace legacy or ad hoc reason strings in apps/platform/app/Jobs/BackfillFindingLifecycleJob.php and apps/platform/app/Jobs/BackfillFindingLifecycleTenantIntoWorkspaceRunJob.php in the same slice instead of introducing alias maps

4. Update operator surfaces

  • Align apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php copy and reason-policy metadata with the canonical findings vocabulary
  • Update apps/platform/app/Filament/Resources/FindingResource.php
  • Replace free-form resolve and close textareas with canonical selections plus optional note fields if needed
  • Keep destructive-like actions confirmed with ->requiresConfirmation()
  • Update list filters, detail summaries, and terminal-outcome labels to use the shared semantics helper
  • Preserve the existing open backlog defaults from Spec 111

5. Update review and reporting consumers

  • Update apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php
  • Update apps/platform/app/Filament/Resources/TenantReviewResource.php
  • Reuse the shared semantics helper anywhere findings-derived summaries or projection buckets are rendered
  • Do not create a second reporting taxonomy or reporting-only persistence layer

6. Prove the change with focused tests

  • Extend existing findings service and UI tests first
  • Add one focused reporting summary test only if no existing suite naturally owns that proof
  • Keep coverage in feature suites; browser coverage is not needed for this slice

Validation commands

Run after implementation:

cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingWorkflowServiceTest.php tests/Feature/Findings/FindingRecurrenceTest.php
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
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent

Review checklist

  • No new primary findings status was introduced
  • resolved_reason and closed_reason are bounded canonical keys, not free-form reporting truth
  • reopened_reason remains reviewable through audit metadata without adding new persistence
  • risk_accepted still depends on exception validity and is not counted as verified clear
  • FindingResource, ReviewRegister, and TenantReviewResource use one shared outcome semantics seam
  • No compatibility aliases were kept for replaced reason keys unless a spec change explicitly required them