# 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: ```bash 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