/* global window, React */ // ============================================================ // Agent Policy — how the agent decides, and where TP draws the line. // Sections (top to bottom): // 1. Header + KPI strip (4 KPIs) // 2. Governance score card + autonomy heat map (novel) // 3. Rules library — filter by family, list of cards w/ autonomy band toggle // 4. Audit log — compact table of recent agent decisions // ============================================================ const { useState: usePolState, useMemo: usePolMemo } = React; const BANDS = [ { id: 'auto', label: 'Auto', short: 'AUTO', desc: 'Agent acts. No human in loop.' }, { id: 'notify', label: 'Notify', short: 'NOTIFY', desc: 'Agent acts. Pings TP after.' }, { id: 'approval', label: 'Approval', short: 'APPR', desc: 'Agent stages. TP confirms before action.' }, { id: 'human', label: 'Human-only', short: 'HUMAN', desc: 'TP decides. Agent never acts.' }, ]; const BAND_BY_ID = Object.fromEntries(BANDS.map(b => [b.id, b])); function PolicyKpi({ label, value, sub, kind }) { return (
{label}
{value}
{sub &&
{sub}
}
); } // ---------- Governance score card (novel) ---------- function GovernanceScore({ governance }) { const r = 56; // radius const c = 2 * Math.PI * r; const pct = governance.score / 100; const dash = c * pct; const tier = governance.score >= 80 ? 'green' : governance.score >= 60 ? 'amber' : 'red'; const tierLabel = tier === 'green' ? 'Healthy' : tier === 'amber' ? 'Watch' : 'Risk'; return (
GOVERNANCE SCORE
How well does policy balance autonomy & control?
{governance.score}
{tierLabel}
{governance.bands.map(b => { const tier = b.value >= 80 ? 'green' : b.value >= 60 ? 'amber' : 'red'; return (
{b.label} {b.value}
{b.sub}
); })}
); } // ---------- Autonomy heat map (novel) ---------- function AutonomyHeatmap({ families, rules, onCellClick, selectedCell }) { // grid[family.id][band.id] = { count, savings, triggers } const grid = {}; families.forEach(f => { grid[f.id] = {}; BANDS.forEach(b => { grid[f.id][b.id] = { count: 0, savings: 0, triggers: 0 }; }); }); rules.forEach(r => { if (!grid[r.family] || !grid[r.family][r.autonomy]) return; const cell = grid[r.family][r.autonomy]; cell.count += 1; cell.savings += r.dollarsSaved || 0; cell.triggers += r.triggers7d || 0; }); // Find the max cell value for color scaling const maxTriggers = Math.max(1, ...families.flatMap(f => BANDS.map(b => grid[f.id][b.id].triggers))); return (
AUTONOMY HEATMAP
Where the agent acts · where it asks
Cell shows rules · 7d triggers. Click to filter.
{BANDS.map(b => (
{b.label}
{b.short}
))} {families.map(f => (
{f.icon}
{f.label}
{f.sub}
{BANDS.map(b => { const cell = grid[f.id][b.id]; const intensity = cell.triggers / maxTriggers; const empty = cell.count === 0; const isSelected = selectedCell && selectedCell.family === f.id && selectedCell.band === b.id; return ( ); })}
))}
); } // ---------- Rule card with autonomy band selector ---------- function BandSelector({ value, onChange }) { return (
{BANDS.map(b => ( ))}
); } function RuleCard({ rule, family, onToggle, onAutonomy, onView }) { const band = BAND_BY_ID[rule.autonomy]; return (
{family.icon} {family.label} · {rule.id.toUpperCase()} {!rule.active && PAUSED}
onAutonomy(rule.id, b)} />
{rule.name}
WHEN {rule.when}
THEN {rule.then}
Triggered 7d {rule.triggers7d}× $ saved ${rule.dollarsSaved.toLocaleString()} Avg latency {rule.avgLatencyMs === 0 ? '—' : rule.avgLatencyMs < 1000 ? `${rule.avgLatencyMs}ms` : `${(rule.avgLatencyMs / 1000).toFixed(1)}s`} Override rate 20 ? 'rule__stat-val--red' : ''}`}> {rule.overrideRate}% onToggle(rule.id)} title={rule.active ? 'Pause rule' : 'Activate rule'}>
); } // ---------- Audit log table ---------- function AuditLog({ audit, rules, onShowToast }) { const ruleById = Object.fromEntries(rules.map(r => [r.id, r])); const [filter, setFilter] = usePolState('all'); const filters = [ { id: 'all', label: 'All' }, { id: 'auto', label: 'Agent acted' }, { id: 'tp-decided', label: 'TP decided' }, { id: 'tp-override', label: 'TP overrode' }, { id: 'waiting', label: 'Awaiting TP' }, ]; const filtered = audit.filter(a => { if (filter === 'all') return true; if (filter === 'auto') return /^auto/.test(a.outcome); if (filter === 'tp-decided') return a.outcome === 'TP decided'; if (filter === 'tp-override') return a.outcome === 'TP overrode' || a.outcome === 'TP approved'; if (filter === 'waiting') return /awaiting|notified/.test(a.outcome); return true; }); const outcomeKind = (o) => { if (o.startsWith('auto')) return 'green'; if (o === 'TP overrode') return 'red'; if (o === 'TP approved') return 'blue'; if (o === 'TP decided') return 'amber'; if (o.includes('awaiting')) return 'amber'; if (o === 'notified') return 'blue'; return 'grey'; }; return (
Agent decision audit · last {audit.length}
Every decision the agent made, with outcome and override.
{filters.map(f => ( ))}
Time Trip Rule Outcome Action taken Latency Override by
{filtered.map(a => { const rule = ruleById[a.ruleId]; const kind = outcomeKind(a.outcome); return (
{a.ts} {a.tripId} {rule ? rule.name : a.ruleId} {a.ruleId.toUpperCase()} {a.outcome} {a.action} {a.latencyMs === 0 ? '—' : a.latencyMs < 1000 ? `${a.latencyMs}ms` : `${(a.latencyMs / 1000).toFixed(1)}s`} {a.overrideBy ? ( <> {a.overrideBy.split(' ').map(p => p[0]).join('')} {a.overrideBy} ) : }
); })} {filtered.length === 0 && (
No entries match this filter.
)}
); } // ---------- New Rule modal ---------- function NewRuleModal({ families, onCancel, onCreate }) { const [family, setFamily] = usePolState(families[0].id); const [name, setName] = usePolState(''); const [whenText, setWhen] = usePolState(''); const [thenText, setThen] = usePolState(''); const [autonomy, setAuto] = usePolState('notify'); const [active, setActive] = usePolState(true); const canCreate = name.trim().length > 2 && whenText.trim().length > 4 && thenText.trim().length > 4; return (
e.stopPropagation()}>
New policy rule
Add a rule to the library
Rules are evaluated by the agent on every wave. New rules start in draft until reviewed by Carrier Manager.
{families.map(f => ( ))}
setName(e.target.value)} />