/** * Attribution-matrix heatmap: one row per violation, one column per causal * layer. Cell color encodes tri-state evidence (SUPPORTED / RULED_OUT / * UNKNOWN); the primary layer carries a ring. Clicking a row selects the * violation for the consequence replay view. */ import Box from '@mui/material/Box'; import Chip from '@mui/material/Chip'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; import type { RotrAttributionMatrix } from '../../types/rotr'; const LAYERS = [ 'perception', 'prediction', 'planning', 'localization', 'map', 'control', 'policy_rule', 'data_label', ]; const STATUS_COLOR: Record = { SUPPORTED: '#c62828', RULED_OUT: '#1b5e20', UNKNOWN: '#616161', }; interface Props { matrix: RotrAttributionMatrix; selectedViolationId: string | null; onSelect: (violationId: string) => void; } export default function RotrAttributionHeatmap({ matrix, selectedViolationId, onSelect }: Props) { return ( {Object.entries(STATUS_COLOR).map(([status, color]) => ( ))} ring = primary layer (highest-confidence positive evidence) {LAYERS.map((l) => ( ))} {matrix.rows.map((row) => { const selected = row.violation_id === selectedViolationId; return ( onSelect(row.violation_id)} style={{ cursor: 'pointer' }} > {LAYERS.map((layer) => { const cell = row.layers[layer]; const status = cell?.status ?? 'UNKNOWN'; const isPrimary = row.primary_layer === layer; return ( {layer}: {status} {' '} (conf {cell ? cell.confidence.toFixed(2) : '—'})
{cell?.evidence ?? 'no evidence recorded'} } arrow >
); })}
violation {l}
{row.violation_id.replace(/^bank-[0-9a-f]+-/, '')} ); })}
{matrix.invariant}
); }