# Research: Monitoring Page-State Contract

## Decision: Reuse existing query, session, and navigation helpers instead of creating a global page-state framework

### Rationale

The affected pages already express most of the required behavior through page-local Livewire properties, `CanonicalAdminTenantFilterState`, `CanonicalNavigationContext`, existing table-state persistence, and explicit request hydration methods. The product problem is missing contract clarity, not missing infrastructure. The narrowest correct move is to make those rules explicit and consistent without introducing a second runtime state engine.

### Alternatives considered

- Create a shared monitoring page-state framework or registry: rejected because it would import more runtime structure than the five primary surfaces plus the compare launch surface need.
- Keep all fixes page-local and undocumented: rejected because it would reduce isolated bugs but would not prevent future drift.

## Decision: Adopt one deterministic precedence rule for supported query, session, and local state

### Rationale

The existing surfaces already imply a common precedence model. Supported query or deeplink input is the only safe way to restore bookmarked or shared state, while session should continue to back only the filter, search, and sort state a page already owns. After mount, page-local active state should become authoritative so the page does not continue to behave as if query parameters are a second hidden state source.

The standardized rule is:

1. supported query or deeplink state hydrates first on mount
2. session provides baseline only for explicitly persisted table filters, search, or sort state
3. invalid or unauthorized requested state is dropped with a predictable fallback
4. page-local active state becomes authoritative after hydration

### Alternatives considered

- Session-first precedence: rejected because it makes shared links and dashboard drillthroughs unpredictable.
- Query-only restoration for every state slice: rejected because several pages intentionally persist table state in session.

## Decision: Make selected-record inspect the only inspect model on Audit Log and Finding Exceptions Queue

### Rationale

Both surfaces already carry selected-record properties and query-driven selected IDs. The safest way to remove ambiguity is to ensure that action-based inspect, inline detail, summary or decision state, and selected-record deeplink entry all resolve to the same selected-record contract. This makes refresh, back, and close-detail behavior testable and predictable.

### Alternatives considered

- Keep action-based inspect and query-selected inline detail as parallel models: rejected because it preserves the current ambiguity.
- Move inspect into modal-only flows: rejected because the current pages already use inline or workbench detail as the main operator model.

## Decision: Keep Baseline Compare Matrix as the only explicit draft or apply special case

### Rationale

Baseline Compare Matrix already maintains separate draft and applied state and exposes a real operator need for staged filter changes before recalculating visible results. The right move is to tighten and document that behavior, not to normalize it away. Draft state remains local-only until apply, while applied compare state and supported focus state remain the only shareable or restorable slices.

### Alternatives considered

- Force Compare Matrix into direct-active filtering like simpler monitoring pages: rejected because it would degrade operator control and page performance semantics.
- Create a generic draft/apply engine for all monitoring pages: rejected because only one real surface needs that behavior now.

## Decision: Treat Baseline Compare Landing as launch context, not as a competing owner of compare state

### Rationale

Baseline Compare Landing already passes profile, subject, and navigation context into the matrix route. The contract should make that role explicit: landing provides launch context that seeds the matrix, but the matrix owns the applied compare state and focus state after hydration. This avoids splitting authoritative state across two pages.

### Alternatives considered

- Persist compare landing context independently from the matrix: rejected because it would create a second state owner for the same operator flow.
- Ignore landing context and rebuild matrix state locally only: rejected because it would break deeplink and drillthrough continuity.

## Decision: Extend existing Pest and Livewire suites instead of relying on browser-only verification

### Rationale

The repository already has focused tests for Operations drillthrough, Audit Log inspect flow, Finding Exceptions Queue hierarchy, Evidence Overview page behavior, Baseline Compare Landing, Baseline Compare Matrix, and generic table persistence. These suites already touch the exact seams this spec needs. Adding one narrow cross-surface contract test plus a focused browser smoke suite gives strong coverage without turning the feature into a browser-heavy effort.

### Alternatives considered

- Browser-test every state permutation: rejected because it is expensive and duplicates what existing feature tests can assert more cheaply.
- Document the contract without automation: rejected because the risk here is behavioral drift, not just documentation quality.