/** Leadership-facing retrospective scorecard with per-field provenance tags * and JSON export. */ import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; import type { Scorecard, ScorecardField } from '../../types/agentic'; import { OutcomeChip, PanelTitle } from './common'; const TAG_COLORS: Record = { OBSERVED: { bg: '#1b5e20', fg: '#a5d6a7' }, PREDICTED: { bg: '#0d47a1', fg: '#90caf9' }, HYPOTHETICAL: { bg: '#4a148c', fg: '#ce93d8' }, REQUIRED_EVIDENCE: { bg: '#4e342e', fg: '#ffcc80' }, }; const FIELDS: { key: keyof Scorecard; label: string }[] = [ { key: 'failure_summary', label: 'Failure' }, { key: 'frequency', label: 'Frequency' }, { key: 'exposure', label: 'Exposure' }, { key: 'severity', label: 'Severity' }, { key: 'confidence', label: 'Confidence' }, { key: 'novelty', label: 'Novelty' }, { key: 'concentration', label: 'Concentration' }, { key: 'downstream_impact', label: 'Downstream impact' }, { key: 'mitigations', label: 'Mitigations' }, { key: 'residual_risk', label: 'Residual risk' }, ]; function renderValue(v: unknown): string { if (v === null || v === undefined) return '—'; if (typeof v === 'object') return JSON.stringify(v); return String(v); } export default function ScorecardView({ card }: { card: Scorecard }) { const exportJson = () => { const blob = new Blob([JSON.stringify(card, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${card.scorecard_id}.json`; a.click(); URL.revokeObjectURL(url); }; return ( } /> {FIELDS.map(({ key, label }) => { const f = card[key] as ScorecardField; const tag = TAG_COLORS[f.tag]; return ( {label} {renderValue(f.value)} evidence: {f.evidence_ref || '—'} ); })} {card.notes.join(' · ')} · recommended option: {card.recommended_option ?? '—'} · policy{' '} {card.policy_version} · generated {card.generated_at} ); }