# Data Model: Baseline Compare Matrix: High-Density Operator Mode

## Overview

This follow-up introduces no new persisted entity. It reuses the existing Spec 190 matrix truth and adds derived presentation models for operator density, staged filtering, and non-blocking status cues.

## Existing Source Truths Reused Without Change

### Baseline compare truth from Spec 190

The following derived or canonical inputs remain authoritative and are not redefined by this spec:

- workspace-scoped baseline reference truth
- visible tenant summaries
- subject summaries
- subject-by-tenant matrix cells
- compare-start availability and existing drilldown destinations

This spec changes how those inputs are rendered and interacted with, not how they are computed.

## New Derived Presentation Models

### MatrixPresentationState

**Type**: request-scoped page presentation contract  
**Source**: route/query state + visible tenant count + existing run state

| Field | Type | Notes |
|------|------|-------|
| `requestedMode` | string | `auto`, `dense`, or `compact` from route/query state |
| `resolvedMode` | string | Final mode used for rendering: `dense` or `compact` |
| `visibleTenantCount` | integer | Existing visible-set count from the matrix bundle |
| `activeFilterCount` | integer | Count of currently applied filters |
| `hasStagedFilterChanges` | boolean | Whether filter draft state differs from applied state |
| `autoRefreshActive` | boolean | True when background polling is active because compare work is queued or running |
| `lastUpdatedAt` | datetime or null | Timestamp for the currently rendered matrix data |
| `canOverrideMode` | boolean | Whether the operator may locally switch away from `auto` |

### MatrixFilterDraft

**Type**: request-scoped staged filter model  
**Source**: page form state only

| Field | Type | Notes |
|------|------|-------|
| `selectedPolicyTypes` | array<string> | Draft policy-type filter selection |
| `selectedStates` | array<string> | Draft state-group selection |
| `selectedSeverities` | array<string> | Draft severity selection |
| `tenantSort` | string | Current tenant sort choice |
| `subjectSort` | string | Current subject sort choice |
| `focusedSubjectKey` | string or null | Optional current subject focus |

### DenseSubjectRowView

**Type**: request-scoped dense-mode row view  
**Source**: existing subject summary + existing matrix cells

| Field | Type | Notes |
|------|------|-------|
| `subjectKey` | string | Stable row key |
| `displayName` | string | Primary row label |
| `policyType` | string | Compact secondary label |
| `baselineExternalId` | string or null | Optional secondary context |
| `deviationBreadth` | integer | Existing subject summary metric |
| `missingBreadth` | integer | Existing subject summary metric |
| `ambiguousBreadth` | integer | Existing subject summary metric |
| `maxSeverity` | string or null | Existing subject summary severity |
| `trustLevel` | string | Existing subject summary trust |
| `cells` | array<DenseCellView> | One condensed cell per visible tenant |

### DenseCellView

**Type**: request-scoped dense-mode cell view  
**Source**: existing matrix cell + existing tenant summary freshness

| Field | Type | Notes |
|------|------|-------|
| `tenantId` | integer | Visible tenant identifier |
| `subjectKey` | string | Subject row key |
| `state` | string | Existing Spec 190 state |
| `freshnessState` | string | Freshness signal shown in compact form |
| `trustLevel` | string | Trust signal shown in compact form |
| `severity` | string or null | Optional attention signal |
| `attentionLevel` | string | Derived presentation label such as `aligned`, `refresh_recommended`, or `needs_attention` |
| `reasonSummary` | string or null | Short secondary explanation for compact reveal surfaces |
| `primaryDrilldownUrl` | string or null | Preferred next follow-up action |
| `secondaryDrilldownUrls` | array<string, string> | Additional compact follow-up links when available |

### CompactSubjectResultView

**Type**: request-scoped single-tenant row view  
**Source**: one visible tenant summary + existing matrix cell + existing subject summary

| Field | Type | Notes |
|------|------|-------|
| `tenantId` | integer | The single visible tenant in compact mode |
| `subjectKey` | string | Stable subject key |
| `displayName` | string | Primary subject label |
| `policyType` | string | Secondary grouping/context |
| `state` | string | Existing Spec 190 state |
| `freshnessState` | string | Compact freshness label |
| `trustLevel` | string | Compact trust label |
| `severity` | string or null | Optional attention indicator |
| `reasonSummary` | string or null | Short explanation line |
| `primaryDrilldownUrl` | string or null | Main follow-up action |
| `runUrl` | string or null | Secondary run-level follow-up |

### MatrixSupportSurfaceState

**Type**: request-scoped supporting-context contract  
**Source**: page state + existing legends + refresh metadata

| Field | Type | Notes |
|------|------|-------|
| `legendMode` | string | `grouped`, `collapsed`, or equivalent compact support behavior |
| `showActiveFilterSummary` | boolean | Whether applied filters are summarized inline |
| `showLastUpdated` | boolean | Whether the page displays last-updated metadata |
| `showAutoRefreshHint` | boolean | Whether passive auto-refresh copy is visible |
| `showBlockingRefreshState` | boolean | Reserved for deliberate user-triggered reloads only |

## Rendering and Resolution Rules

### Mode resolution rules

1. If `requestedMode = auto` and `visibleTenantCount > 1`, resolve to `dense`.
2. If `requestedMode = auto` and `visibleTenantCount = 1`, resolve to `compact`.
3. If a manual override is present, use it unless it would produce an invalid empty layout.
4. Manual override remains route-local and must never be persisted as product truth.

### Dense-mode rules

- The subject column remains sticky during horizontal scroll.
- The primary visible content per cell is state, trust, freshness, and attention.
- Long explanatory text and repeated action links do not render as the dominant cell body.

### Compact single-tenant rules

- The tenant header does not repeat as a pseudo-column structure.
- Each subject entry shows one primary status line and a reduced set of secondary metadata.
- Existing subject focus and drilldown continuity remain available.

### Filter workflow rules

- Heavy multi-select filters use staged state first and apply only when the operator confirms.
- Applied filter count and scope summary reflect the applied state, not merely the draft state.
- Reset may clear both draft and applied state in one explicit action.

### Status signal rules

- `blocking refresh` is reserved for deliberate user-triggered reload or recalculation moments.
- `auto-refresh active` indicates passive polling while compare work is still queued or running.
- `lastUpdatedAt` reflects the timestamp of the rendered matrix payload, not merely the latest compare run in the system.

### Safety rules

- No rendering path may widen tenant visibility beyond the existing visible set.
- No presentation-state change may change the underlying compare state, trust, or freshness semantics.
- No grouped legend or compact cell may invent new status vocabulary outside existing centralized badge semantics.

## Relationships

- One `MatrixPresentationState` governs one rendered matrix page.
- One `MatrixFilterDraft` belongs to one `MatrixPresentationState`.
- In dense mode, one `DenseSubjectRowView` maps to many `DenseCellView` entries.
- In compact mode, one visible tenant yields many `CompactSubjectResultView` entries.
- One `MatrixSupportSurfaceState` coordinates legends, refresh hints, and active-filter summaries for the same page render.