## Summary - add a first-class finding exception domain with request, approval, rejection, renewal, and revocation lifecycle support - add tenant-scoped exception register, finding governance surfaces, and a canonical workspace approval queue in Filament - add audit, badge, evidence, and review-pack integrations plus focused Pest coverage for workflow, authorization, and governance validity ## Validation - vendor/bin/sail bin pint --dirty --format agent - CI=1 vendor/bin/sail artisan test --compact - manual integrated-browser smoke test for the request-exception happy path, tenant register visibility, and canonical queue visibility ## Notes - Filament implementation remains on v5 with Livewire v4-compatible surfaces - canonical queue lives in the admin panel; provider registration stays in bootstrap/providers.php - finding exceptions stay out of global search in this rollout Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #184
87 lines
4.7 KiB
Markdown
87 lines
4.7 KiB
Markdown
# Quickstart: Finding Risk Acceptance Lifecycle
|
|
|
|
## Goal
|
|
|
|
Verify that the product can govern accepted-risk findings with explicit request, approval, expiry, renewal, revocation, and audit semantics.
|
|
|
|
## Prerequisites
|
|
|
|
1. Start Sail and ensure the application database is available.
|
|
2. Have at least one workspace, one tenant in that workspace, and at least one finding visible in tenant context.
|
|
3. Use two distinct tenant members for validation:
|
|
- requester with `finding_exception.manage`
|
|
- approver with `finding_exception.approve`
|
|
4. Use a seeded local Sail dataset with one workspace, one tenant, one eligible open finding, and one active exception near expiry for reminder validation.
|
|
|
|
## Happy Path
|
|
|
|
1. Open the tenant finding detail for an open finding.
|
|
2. Trigger `Request exception`.
|
|
3. Enter justification, accountable owner, and review or expiry timing.
|
|
4. Optionally link one or more supporting evidence references.
|
|
5. Confirm that the new exception appears as `pending` in the tenant exception register and the canonical approval queue.
|
|
6. Sign in as the approver.
|
|
7. Open the pending request from the canonical queue and choose `Approve exception`.
|
|
8. Confirm that:
|
|
- the exception becomes `active`
|
|
- the finding is shown as governed accepted risk
|
|
- audit history shows request and approval decisions
|
|
|
|
## Rejection Path
|
|
|
|
1. Create a second request for another finding.
|
|
2. Reject the request with a reason.
|
|
3. Confirm that:
|
|
- the exception becomes `rejected`
|
|
- the finding is not treated as valid accepted risk
|
|
- audit history includes the rejection decision
|
|
|
|
## Renewal Path
|
|
|
|
1. Use an active exception with a near-term expiry.
|
|
2. Trigger `Renew exception`.
|
|
3. Enter updated justification and evidence references.
|
|
4. Approve the renewal as an approver.
|
|
5. Confirm that:
|
|
- the validity window extends
|
|
- prior decision history remains visible
|
|
- the exception still has one current valid governing record
|
|
|
|
## Revocation and Expiry Path
|
|
|
|
1. Revoke one active exception with a reason.
|
|
2. Confirm that it becomes `revoked` and no longer counts as valid accepted risk.
|
|
3. Create or adjust another exception so its expiry is in the past.
|
|
4. Confirm that tenant and canonical views show it as `expired` and that the linked finding surfaces a governance warning if it still shows `risk_accepted`.
|
|
|
|
## Reminder Visibility Path
|
|
|
|
1. Use an active exception that is close to expiry according to the configured due-state thresholds.
|
|
2. Open the tenant finding detail, tenant exception register, canonical queue, and exception detail.
|
|
3. Confirm that requester, accountable owner, tenant managers, and entitled workspace approvers see the expected passive in-product reminder cues in the surfaces they can access.
|
|
4. Confirm that no scheduled job, email, background notification, or `OperationRun` is required for this visibility in v1.
|
|
|
|
## Concurrency and History Path
|
|
|
|
1. Submit a pending exception request for a finding.
|
|
2. Attempt to submit a second request or second renewal workflow for that same finding before the first reaches a terminal state.
|
|
3. Confirm that the system blocks the parallel pending workflow and preserves the original in-flight request.
|
|
4. Resolve, close, reopen, or change the severity of a finding with historical exception decisions.
|
|
5. Confirm that exception history remains readable and the UI shows whether the current finding state is still governed, no longer valid, or requires a fresh decision.
|
|
|
|
## Authorization Checks
|
|
|
|
1. Verify a tenant member with `finding_exception.view` but without manage or approve capabilities can inspect exception detail but cannot request, approve, renew, reject, or revoke.
|
|
2. Verify a non-member or wrong-tenant user receives deny-as-not-found behavior for tenant and canonical exception routes.
|
|
3. Verify the requester cannot approve their own pending request in v1, receives the defined self-approval rejection response, and does not change the exception state.
|
|
|
|
## Suggested Focused Test Runs
|
|
|
|
1. Run focused Pest feature tests for findings workflow, exception authorization, canonical queue filtering, and audit history.
|
|
2. Run any badge and action-surface guard tests impacted by new exception-state surfaces.
|
|
3. Run the minimal Livewire or Filament tests for tenant detail and canonical queue actions.
|
|
|
|
## Timed Acceptance Checks
|
|
|
|
1. Time SC-001 by starting on tenant finding detail and stopping when a complete exception request is visible in the canonical queue on the first successful run against the seeded baseline.
|
|
2. Time SC-003 by starting on exception detail and stopping when the reviewer can point to requester, approver, justification, and validity-window evidence without leaving the product on the first successful run against the seeded baseline. |