Implemented the accepted risk resolution guidance, including the AcceptedRiskResolutionAdapter, guidance cards, and updated related Filament views. Added unit, feature, and browser tests. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #425
298 lines
16 KiB
Markdown
298 lines
16 KiB
Markdown
# Implementation Plan: Spec 354 - Finding Exceptions / Accepted Risk Resolution Guidance v1
|
|
|
|
- Branch: `354-finding-exceptions-accepted-risk-resolution-guidance-v1`
|
|
- Date: 2026-06-05
|
|
- Spec: `specs/354-finding-exceptions-accepted-risk-resolution-guidance-v1/spec.md`
|
|
- Input: Spec 354 + repo inspection of Finding Exceptions queue/detail surfaces, accepted-risk governance resolver, Governance Inbox accepted-risk routing, and downstream review-output continuity.
|
|
|
|
## Summary
|
|
|
|
Add one derived accepted-risk guidance layer to the existing Finding Exceptions queue and detail owner surfaces so operators can see one dominant accepted-risk case, one dominant next-step affordance, and conservative owner-surface wording without reconstructing meaning from badges, dates, and grouped actions.
|
|
|
|
The implementation stays narrow:
|
|
|
|
- reuse existing `FindingException`, `FindingExceptionDecision`, `Finding`, `FindingRiskGovernanceResolver`, `ResolutionCase`, and current lifecycle actions
|
|
- keep queue/detail as the owning accepted-risk surfaces
|
|
- preserve current action confirmation, authorization, audit, and notification behavior
|
|
- reuse downstream customer-safe wording only where already repo-backed
|
|
- avoid new persistence, new provider seams, and new workflow frameworks
|
|
|
|
## Technical Context
|
|
|
|
- Language/Version: PHP 8.4.15, Laravel 12.52.x
|
|
- UI stack: Filament 5.2.x, Livewire 4.x
|
|
- Database: PostgreSQL, no schema change planned
|
|
- Testing: Pest unit + feature/Livewire + one strategic browser smoke
|
|
- Validation lanes: fast-feedback + confidence + browser
|
|
- Local runtime posture: Sail-first
|
|
- Deployment/runtime impact: no expected env, migration, queue-family, scheduler, storage, or panel/provider change
|
|
- Global search: unchanged; `FindingExceptionResource` remains not globally searchable
|
|
|
|
## Current Repo Truth That Constrains The Slice
|
|
|
|
- `FindingExceptionsQueue` already owns:
|
|
- workspace-wide accepted-risk access
|
|
- explicit `environment_id` filter behavior
|
|
- selected-record inspect state
|
|
- approve / reject actions with confirmation
|
|
- related finding and queue/deep-link actions
|
|
- `ViewFindingException` already owns:
|
|
- accepted-risk detail presentation
|
|
- renew / revoke actions with confirmation
|
|
- decision-register return-link continuity
|
|
- `FindingExceptionResource` already disables global search.
|
|
- `FindingRiskGovernanceResolver` already derives:
|
|
- accepted-risk workflow family
|
|
- governance warning text
|
|
- primary narrative
|
|
- next-action copy
|
|
- validity / attention signals
|
|
- the current repo-real fresh-decision-required warning path
|
|
- `GovernanceInboxSectionBuilder` already exposes accepted-risk lane text, due context, and the primary action label `Review accepted risk`.
|
|
- Customer-safe accepted-risk summaries already exist in review-output paths through `EnvironmentReviewComposer`, Customer Review Workspace, and review-pack summaries, but this slice should treat them as wording reference rather than a runtime mutation target.
|
|
- The queue audit (`ui-012`) already marks risk decision language, expiry visibility, and customer-safe wording as top issues.
|
|
- There is no need for a second accepted-risk model, a new accepted-risk page family, or a new review-output engine.
|
|
|
|
## Domain / Model Implications
|
|
|
|
- No schema or migration change is planned.
|
|
- No new persisted accepted-risk readiness entity, review-impact entity, or action-history model is allowed in this slice.
|
|
- The narrowest acceptable implementation shape is one derived accepted-risk guidance adapter or selector over:
|
|
- current `FindingException`
|
|
- current `FindingExceptionDecision`
|
|
- current linked `Finding`
|
|
- current `FindingRiskGovernanceResolver`
|
|
- current queue/detail action availability
|
|
- Existing ownership boundaries remain unchanged:
|
|
- exception lifecycle truth stays `FindingException` / `FindingExceptionDecision` owned
|
|
- source finding truth stays `Finding` owned
|
|
- customer-safe review truth stays review/output owned and unchanged by this slice
|
|
- any new guidance state stays request-local and derived
|
|
|
|
## UI / Filament / Livewire Implications
|
|
|
|
- Filament v5 continues to run on Livewire v4.x; no version or API drift is permitted.
|
|
- No panel/provider registration change is allowed; `apps/platform/bootstrap/providers.php` remains untouched.
|
|
- `FindingExceptionResource` stays not globally searchable.
|
|
- Existing destructive or high-impact accepted-risk actions must keep their current confirmation, authorization, notification, and audit posture.
|
|
- No new asset registration is planned, so there is no expected `filament:assets` deployment change for this spec.
|
|
|
|
## RBAC / Policy Implications
|
|
|
|
- Workspace membership and entitled environment access remain the only scope authorities.
|
|
- Current capabilities continue to decide queue visibility, detail visibility, and lifecycle-action executability.
|
|
- Guidance selection itself must remain safe for unauthorized users by operating only on already-authorized page state.
|
|
- Queue and detail must keep deny-as-not-found semantics for out-of-scope workspace/environment access.
|
|
|
|
## Audit / Logging / Evidence Implications
|
|
|
|
- Existing approve / reject / renew / revoke handling and current audit emission remain authoritative.
|
|
- No new audit stream, notification family, or evidence artifact is planned.
|
|
- The implementation must keep accepted-risk render paths read-only and side-effect free.
|
|
- Existing related-context disclosure, decision history, and evidence references remain secondary and only appear when already repo-backed on the current owner surfaces.
|
|
|
|
## Data / Migration Implications
|
|
|
|
- No database migration, backfill, or persisted projection is planned.
|
|
- All derived guidance output must be request-local and DB-backed from already stored truth.
|
|
- Compatibility shims are not justified because no data shape replacement is proposed in this prep slice.
|
|
|
|
## Rollout Considerations
|
|
|
|
- No feature flag is expected because the slice is a bounded presentation improvement over existing repo truth.
|
|
- Staging validation should still prove four operator states explicitly:
|
|
- expiring accepted risk
|
|
- expired, revoked, or fresh-decision-required support
|
|
- incomplete governance support (owner/rationale/review due missing on an existing exception record)
|
|
- calm valid state
|
|
- Production risk is limited to guidance hierarchy, wrong-link regressions, and owner-surface wording drift, so focused tests and one bounded browser smoke remain the main rollout controls.
|
|
|
|
## UI / Surface Guardrail Plan
|
|
|
|
- **Guardrail scope**:
|
|
- `FindingExceptionsQueue`
|
|
- selected-record queue summary and action hierarchy
|
|
- `ViewFindingException`
|
|
- downstream accepted-risk wording continuity only where already repo-backed
|
|
- **Affected surfaces**:
|
|
- `apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php`
|
|
- `apps/platform/resources/views/filament/pages/monitoring/finding-exceptions-queue.blade.php`
|
|
- `apps/platform/app/Filament/Resources/FindingExceptionResource.php`
|
|
- `apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php`
|
|
- `apps/platform/resources/views/filament/pages/monitoring/partials/finding-exception-queue-sidebar.blade.php`
|
|
- `apps/platform/app/Services/Findings/FindingRiskGovernanceResolver.php`
|
|
- `apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php`
|
|
- **Native vs custom**:
|
|
- preserve native Filament queue/detail ownership
|
|
- avoid new custom page families
|
|
- allow one bounded derived guidance adapter or selector if necessary
|
|
- **Shared-family relevance**:
|
|
- status messaging
|
|
- next-action guidance
|
|
- accepted-risk wording
|
|
- evidence / decision-history disclosure
|
|
- Governance Inbox to owner-surface continuity
|
|
- **Required tests / smoke**:
|
|
- focused unit tests for accepted-risk guidance selection
|
|
- feature/Livewire tests for queue/detail rendering and scope-safe action/link hierarchy
|
|
- one bounded browser smoke for the strategic queue/detail surfaces
|
|
- **UI/Productization coverage**:
|
|
- update `ui-012-finding-exceptions-queue.md`
|
|
- create or update `ui-036-exception-detail.md`
|
|
- update `route-inventory.md` coverage for `UI-036`
|
|
- update `unresolved-pages.md` to remove or reclassify `UI-036` once durable coverage exists
|
|
- update `design-coverage-matrix.md` only if classification or surface counts change
|
|
|
|
## Shared Pattern And System Fit
|
|
|
|
- **Preferred reuse path**:
|
|
- current `FindingRiskGovernanceResolver` truth
|
|
- current `ResolutionCase` / `ResolutionAction` contract
|
|
- current `GovernanceActionCatalog`
|
|
- current queue/detail links and navigation helpers
|
|
- current review-output accepted-risk wording as conservative wording reference only
|
|
- **Likely implementation shape**:
|
|
- one bounded `FindingExceptionResolutionAdapter` or page-local selector under the current `ResolutionGuidance` path
|
|
- queue/detail-specific mapping stays local to the accepted-risk owner surfaces
|
|
- existing paired lifecycle actions remain source-owned even when one dominant next-step affordance is promoted in the guidance summary
|
|
- **Avoid**:
|
|
- new accepted-risk workflow engine
|
|
- new persisted readiness or action state
|
|
- new global review-impact framework
|
|
- new provider/platform abstraction
|
|
|
|
## OperationRun UX Impact
|
|
|
|
Spec 354 does not create a new `OperationRun` type and does not require new `OperationRun` links on the accepted-risk owner surfaces.
|
|
|
|
Implementation responsibility is limited to preserving the current no-new-OperationRun-link posture unless an already-present owner-surface related-context path exists.
|
|
|
|
## Likely Runtime Files
|
|
|
|
| Area | Repo-real files |
|
|
|---|---|
|
|
| Queue runtime | `apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php`, `apps/platform/resources/views/filament/pages/monitoring/finding-exceptions-queue.blade.php` |
|
|
| Queue focused-review partial | `apps/platform/resources/views/filament/pages/monitoring/partials/finding-exception-queue-sidebar.blade.php` |
|
|
| Detail runtime | `apps/platform/app/Filament/Resources/FindingExceptionResource.php`, `apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php` |
|
|
| Accepted-risk truth | `apps/platform/app/Services/Findings/FindingRiskGovernanceResolver.php`, `apps/platform/app/Services/Findings/FindingExceptionService.php` |
|
|
| Shared guidance contract | `apps/platform/app/Support/ResolutionGuidance/ResolutionCase.php`, `apps/platform/app/Support/ResolutionGuidance/ResolutionAction.php` |
|
|
| Adjacent routing / continuity | `apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php`, current related-navigation helpers |
|
|
| Downstream wording reference only | `apps/platform/app/Services/EnvironmentReviews/EnvironmentReviewComposer.php`, `apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php`, current review-pack summary builders |
|
|
| UI audit docs | `docs/ui-ux-enterprise-audit/page-reports/ui-012-finding-exceptions-queue.md`, `docs/ui-ux-enterprise-audit/page-reports/ui-036-exception-detail.md`, `docs/ui-ux-enterprise-audit/route-inventory.md`, `docs/ui-ux-enterprise-audit/unresolved-pages.md` |
|
|
|
|
## Likely Test Files
|
|
|
|
| Layer | Planned file |
|
|
|---|---|
|
|
| Unit | `apps/platform/tests/Unit/ResolutionGuidance/Spec354AcceptedRiskResolutionAdapterTest.php` |
|
|
| Feature/Livewire | `apps/platform/tests/Feature/Monitoring/Spec354FindingExceptionsQueueGuidanceTest.php` |
|
|
| Feature/Livewire | `apps/platform/tests/Feature/Findings/Spec354FindingExceptionDetailGuidanceTest.php` |
|
|
| Browser | `apps/platform/tests/Browser/Spec354AcceptedRiskGuidanceSmokeTest.php` |
|
|
|
|
## Implementation Approach
|
|
|
|
### Phase 0 - Repo Truth Gate
|
|
|
|
1. Re-read `spec.md`, `plan.md`, `tasks.md`, `repo-truth-map.md`, `contracts/accepted-risk-guidance-signal-map.md`, and `checklists/requirements.md`.
|
|
2. Re-verify the current runtime truth in the queue/detail/resolver/governance files listed below.
|
|
3. Keep draft mismatches explicit:
|
|
- no new accepted-risk model
|
|
- no global-search change
|
|
- no standalone customer-facing accepted-risk surface
|
|
4. Confirm no migration, package, env var, queue-family, storage, panel/provider, or global-search change is required.
|
|
|
|
### Phase 1 - Tests First
|
|
|
|
1. Add unit coverage for deterministic guidance selection:
|
|
- valid accepted risk
|
|
- expiring accepted risk
|
|
- expired support
|
|
- revoked or rejected support
|
|
- fresh decision required
|
|
- pending or renewal-requested support
|
|
- missing governance support on an existing exception record
|
|
- incomplete owner/rationale/review support
|
|
- conservative owner-surface wording reuse without downstream artifact mutation
|
|
2. Add feature/Livewire coverage for the queue:
|
|
- one dominant case
|
|
- one dominant next-step affordance
|
|
- existing related context only when repo-backed
|
|
- no fake remediation buttons
|
|
- scope-safe links and explicit `environment_id` behavior
|
|
- out-of-scope access stays 404 and member-but-missing-capability behavior stays aligned with current queue semantics
|
|
3. Add feature/Livewire coverage for detail:
|
|
- one dominant case
|
|
- current infolist hierarchy remains detail-owned
|
|
- current high-impact actions remain state- and capability-bound
|
|
- owner/rationale/review support is visible before deeper diagnostics
|
|
- out-of-scope detail access stays 404 and action denial remains capability-bound
|
|
4. Add one browser smoke:
|
|
- queue expiring state
|
|
- queue or detail expired/revoked state
|
|
- detail incomplete-governance state
|
|
- calm valid state
|
|
|
|
### Phase 2 - Derived Guidance Contract
|
|
|
|
1. Choose the narrowest implementation shape:
|
|
- prefer one bounded accepted-risk adapter or selector
|
|
- avoid expanding review-output or provider adapters into a generic risk-workflow engine
|
|
2. Build one derived accepted-risk payload with:
|
|
- key
|
|
- title
|
|
- status
|
|
- severity
|
|
- reason
|
|
- impact
|
|
- primary action or dominant next-step mapping
|
|
- secondary actions
|
|
- technical details
|
|
3. Keep priority ordering explicit and narrow.
|
|
4. Preserve the current fresh-decision-required signal from `requiresFreshDecisionForFinding()` and do not expand it into a broader stale-governance framework.
|
|
|
|
### Phase 3 - Queue Integration
|
|
|
|
1. Add a top guidance presentation to `FindingExceptionsQueue` without removing current queue/table/selected-record truth.
|
|
2. Reuse existing repo-backed actions and links:
|
|
- inspect accepted risk
|
|
- approve exception
|
|
- reject exception
|
|
- open finding
|
|
- existing related context only when already available on the current surface
|
|
3. Keep destructive/high-impact actions unchanged:
|
|
- confirmation
|
|
- authorization
|
|
- audit
|
|
- notifications
|
|
4. Do not widen authorization because guidance is more visible.
|
|
|
|
### Phase 4 - Detail Integration
|
|
|
|
1. Add an explicit guidance summary to the detail surface through `FindingExceptionResource::infolist()` and `ViewFindingException`.
|
|
2. Reuse current owner/rationale/expiry/review data before inventing any new accepted-risk state.
|
|
3. Keep renew and revoke source-owned.
|
|
4. Keep decision history, evidence references, and related context secondary.
|
|
|
|
### Phase 5 - Downstream Continuity
|
|
|
|
1. Reuse current Governance Inbox accepted-risk deep-link and update it only if label or target continuity is inconsistent after queue/detail guidance becomes decision-first.
|
|
2. Reuse existing conservative accepted-risk wording as owner-surface reference only; do not mutate downstream review-output artifacts in this slice.
|
|
3. Avoid turning downstream review-output surfaces into second accepted-risk owner surfaces.
|
|
|
|
### Phase 6 - Copy, Audit, And Artifacts
|
|
|
|
1. Update only the copy required in `apps/platform/lang/en/localization.php`.
|
|
2. Update matching copy in `apps/platform/lang/de/localization.php`.
|
|
3. Update `docs/ui-ux-enterprise-audit/page-reports/ui-012-finding-exceptions-queue.md`.
|
|
4. Create or update `docs/ui-ux-enterprise-audit/page-reports/ui-036-exception-detail.md`.
|
|
5. Update `docs/ui-ux-enterprise-audit/route-inventory.md` and `docs/ui-ux-enterprise-audit/unresolved-pages.md` for `UI-036`.
|
|
6. Save screenshots under the Spec 354 artifact path, or record the host-visible artifact blocker honestly.
|
|
|
|
### Phase 7 - Validation
|
|
|
|
1. Run focused unit, feature, and browser coverage for this slice.
|
|
2. Re-run current queue/detail related acceptance and guard tests in the narrowest honest family.
|
|
3. Confirm final render paths remain DB-local and do not call `GraphClientInterface` or provider HTTP during page render.
|
|
4. Run `pint` and `git diff --check`.
|
|
5. Report broader-suite or unrelated browser-harness issues honestly if they remain outside this slice.
|