4.8 KiB
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_acceptedremains 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.phpor an equivalent findings-local seam - Add
apps/platform/app/Support/Findings/FindingOutcomeSemantics.phpto derive:- terminal outcome key
- verification state
- report bucket
- operator-facing label
- Keep
apps/platform/app/Services/Findings/FindingRiskGovernanceResolver.phpaligned to the same bounded outcome semantics sorisk_acceptedstays separate from verified-clear meaning - Keep reopen reasons in audit metadata; do not add a
reopened_reasoncolumn
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
remediatedand 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.phpapps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.phpapps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.phpapps/platform/app/Jobs/CompareBaselineToTenantJob.php
- Replace legacy or ad hoc reason strings in
apps/platform/app/Jobs/BackfillFindingLifecycleJob.phpandapps/platform/app/Jobs/BackfillFindingLifecycleTenantIntoWorkspaceRunJob.phpin the same slice instead of introducing alias maps
4. Update operator surfaces
- Align
apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.phpcopy 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_reasonandclosed_reasonare bounded canonical keys, not free-form reporting truthreopened_reasonremains reviewable through audit metadata without adding new persistencerisk_acceptedstill depends on exception validity and is not counted as verified clearFindingResource,ReviewRegister, andTenantReviewResourceuse one shared outcome semantics seam- No compatibility aliases were kept for replaced reason keys unless a spec change explicitly required them