TenantAtlas/specs/166-finding-governance-health/research.md
ahmido 55aef627aa feat: harden finding governance health surfaces (#197)
## Summary
- harden findings and finding-exception Filament surfaces so workflow state, governance validity, overdue urgency, and next action are operator-first
- add tenant stats widgets, segmented tabs, richer governance warnings, and baseline/dashboard attention propagation for overdue and lapsed governance states
- add Spec 166 artifacts plus regression coverage for findings, badges, baseline summaries, tenantless operation viewer behavior, and critical table standards

## Verification
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact`

## Filament Notes
- Livewire v4.0+ compliance: yes, implementation stays on Filament v5 / Livewire v4 APIs only
- Provider registration: unchanged, Laravel 12 panel/provider registration remains in `bootstrap/providers.php`
- Global search: unchanged in this slice; `FindingExceptionResource` stays not globally searchable, no new globally searchable resource was introduced
- Destructive actions: existing revoke/reject/approve/renew/workflow mutations remain capability-gated and confirmation-gated where already defined
- Asset strategy: no new assets added; existing deploy process remains unchanged, including `php artisan filament:assets` when registered assets are used
- Testing plan delivered: findings list/detail, exception register, dashboard attention, baseline summary, badge semantics, and tenantless operation viewer coverage

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #197
2026-03-28 10:11:12 +00:00

5.8 KiB

Research: Finding Governance Health & Resolution Semantics Surface Hardening

Decision 1: Reuse existing governance truth instead of introducing a new semantic layer

Decision: Drive surface hardening from existing Finding.status, FindingException.current_validity_state, FindingRiskGovernanceResolver, and centralized badge domains rather than introducing a new persisted governance-health field or a presenter framework.

Rationale: The codebase already distinguishes valid, expiring, expired, revoked, rejected, and missing-support governance states, and it already exposes warning messages through FindingRiskGovernanceResolver. The operator problem is primarily under-communication on major surfaces, not missing underlying truth. Reusing the current truth sources satisfies the constitution's proportionality and no-new-layer constraints.

Alternatives considered:

  • Add a new stored governance_health field on findings: rejected because it would duplicate exception truth and require sync logic.
  • Introduce a new presenter or explanation framework: rejected because this slice needs clearer surfaces, not another interpretation layer.

Decision 2: Keep workflow lifecycle and governance validity as separate visible dimensions

Decision: Findings surfaces should show workflow lifecycle and governance validity as distinct operator-visible dimensions instead of collapsing them into a single synthetic super-status.

Rationale: A finding can be risk_accepted while governance is healthy, expiring, expired, revoked, or unsupported. A finding can also be resolved without proving permanent remediation. Separating lifecycle from governance validity prevents false calm and matches the constitution rule that distinct status dimensions should stay distinct when they matter.

Alternatives considered:

  • Replace current states with one combined surface enum such as accepted-risk-warning: rejected because it would blur workflow truth and governance truth together.
  • Leave lifecycle badges unchanged and hide governance only in detail: rejected because the list and summary surfaces are where prioritization happens.

Decision 3: Harden finding detail by reordering existing infolist truth into a leading status zone

Decision: Implement the detail-page change as a leading status and governance zone built from existing infolist data, leaving raw identifiers, run links, diffs, and evidence in secondary sections.

Rationale: The current finding detail already contains most of the required truth, including status, severity, due date, owner, assignee, and risk-governance entries. The main change needed is information hierarchy. Reordering existing truth is narrower and safer than introducing a new detail-specific read model.

Alternatives considered:

  • Build a separate read model or DTO for the view page: rejected because the current infolist already has the required fields.
  • Leave the current section order and add more warnings lower on the page: rejected because it does not solve the 5 to 10 second operator-read requirement.

Decision 4: Propagate governance attention to summary surfaces through existing DB-backed widget queries

Decision: Extend current tenant summary surfaces such as NeedsAttention and baseline-compare summary outputs with DB-backed aggregates for overdue findings, lapsed governance, and expiring governance instead of adding background jobs or a new tenant-governance dashboard.

Rationale: The dashboard widget and baseline-compare landing already compute DB-backed summaries without external calls. Adding a small set of operator-critical aggregates keeps these surfaces honest while preserving their glance-first character and avoiding a new subsystem.

Alternatives considered:

  • Add scheduled reminder jobs or alerting in this slice: rejected because the spec explicitly leaves proactive automation to a follow-up spec.
  • Create a dedicated governance-health dashboard: rejected because the current scope is surface hardening, not a new reporting domain.

Decision 5: Communicate resolved and closed cautiously, with optional secondary observation context

Decision: Treat resolved and closed as historical workflow states in primary UI language, and only show no longer observed or similar context as secondary explanatory information when it can be derived from current truth.

Rationale: The spec's central risk is that operators may read resolved as technical proof. The safest narrow fix is copy and layout: make workflow meaning explicit and reserve any observation-based explanation for clearly secondary context.

Alternatives considered:

  • Reinterpret resolved as no longer observed everywhere: rejected because it rewrites current workflow truth.
  • Add a new persistence field to separate resolution origin immediately: rejected because the spec explicitly defers that to a follow-up if needed.

Decision 6: Anchor testing in existing Livewire, Filament, Findings, and Badge suites

Decision: Extend the current Pest suites for findings list, finding detail, exception register, exception queue, dashboard widgets, baseline-compare summary, evidence integration, and badge semantics rather than creating a new presentation-only test framework.

Rationale: The repository already has strong coverage anchors for findings workflow, governance projection, exception lifecycle, needs-attention widgets, and baseline-compare explanation surfaces. Cross-surface consistency can be enforced most efficiently by extending those suites with operator-truth assertions.

Alternatives considered:

  • Add screenshot-heavy UI snapshot coverage as the main protection: rejected because the business truth is semantic distinction, not pixel fidelity.
  • Test a new intermediate presenter layer: rejected because the plan intentionally avoids creating one.