LexCrisis / server /ui.html
RadheRadheontop's picture
Sync the Space with the repository, four months on
93b58ab
Raw History Blame Contribute Delete
60.3 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LexCrisis</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--bg: #101112;
--bg-elevated: #17191b;
--bg-panel: rgba(28, 30, 33, 0.94);
--bg-card: rgba(38, 40, 44, 0.9);
--bg-card-strong: rgba(48, 51, 56, 0.95);
--border: rgba(255, 255, 255, 0.08);
--border-strong: rgba(255, 255, 255, 0.16);
--text: #f5f3ef;
--text-soft: #cfc8bb;
--text-muted: #9f9a91;
--blue: #78aefc;
--blue-deep: #3f6fa8;
--cyan: #6bd5c8;
--green: #95d47f;
--amber: #e4c36f;
--red: #ee746a;
--shadow: 0 20px 50px rgba(0, 0, 0, 0.32);
--radius-xl: 24px;
--radius-lg: 18px;
--radius-md: 14px;
--radius-sm: 10px;
--font-sans: "Manrope", "Segoe UI", sans-serif;
--font-mono: "IBM Plex Mono", "Cascadia Code", monospace;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
min-height: 100%;
background:
radial-gradient(circle at top left, rgba(120, 174, 252, 0.10), transparent 26%),
radial-gradient(circle at bottom right, rgba(107, 213, 200, 0.08), transparent 22%),
linear-gradient(180deg, #121315 0%, #0d0f11 100%);
color: var(--text);
font-family: var(--font-sans);
}
body {
padding: 28px;
}
.shell {
max-width: 1560px;
margin: 0 auto;
display: grid;
gap: 20px;
}
.hero {
display: grid;
grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.8fr);
gap: 20px;
}
.panel {
background: linear-gradient(180deg, rgba(31, 33, 37, 0.98), rgba(21, 23, 25, 0.98));
border: 1px solid var(--border);
border-radius: var(--radius-xl);
box-shadow: var(--shadow);
overflow: hidden;
min-width: 0;
}
.panel-inner {
padding: 22px;
}
.eyebrow {
margin-bottom: 14px;
color: var(--cyan);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.18em;
font-weight: 800;
}
h1 {
margin: 0 0 14px;
font-size: clamp(42px, 6vw, 66px);
line-height: 0.92;
letter-spacing: -0.05em;
}
.hero-copy {
max-width: 64ch;
color: var(--text-soft);
font-size: 18px;
line-height: 1.7;
}
.hero-copy strong {
color: var(--text);
font-weight: 700;
}
.mini-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.mini-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
min-width: 0;
}
.mini-card label {
display: block;
color: var(--text-muted);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.14em;
margin-bottom: 10px;
}
.mini-card div {
font-size: 32px;
font-weight: 800;
line-height: 1;
}
.hero-strip {
margin-top: 14px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.hero-pill {
flex: 1 1 160px;
min-width: 0;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.02));
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 14px 15px;
}
.hero-pill label {
display: block;
margin-bottom: 8px;
color: var(--text-muted);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.16em;
font-weight: 800;
}
.hero-pill div {
color: var(--text);
font-size: 16px;
font-weight: 700;
line-height: 1.45;
letter-spacing: -0.01em;
}
.layout {
display: grid;
grid-template-columns: 330px minmax(0, 1fr) 390px;
gap: 20px;
align-items: start;
}
.section-title {
margin: 0 0 16px;
color: var(--text-muted);
font-size: 12px;
letter-spacing: 0.18em;
text-transform: uppercase;
font-weight: 800;
}
.tasks {
display: grid;
gap: 12px;
}
.task-card {
background: linear-gradient(180deg, rgba(44, 47, 52, 0.76), rgba(34, 36, 40, 0.72));
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
cursor: pointer;
transition: transform 0.18s ease, border-color 0.18s ease, background 0.18s ease;
min-width: 0;
}
.task-card:hover,
.task-card.active {
border-color: rgba(120, 174, 252, 0.9);
background: linear-gradient(180deg, rgba(57, 62, 69, 0.82), rgba(39, 42, 47, 0.78));
transform: translateY(-1px);
}
.task-top {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: flex-start;
margin-bottom: 10px;
}
.task-name {
font-size: 20px;
font-weight: 800;
line-height: 1.2;
letter-spacing: -0.03em;
}
.badge {
flex-shrink: 0;
border-radius: 999px;
padding: 6px 10px;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid var(--border-strong);
}
.easy { color: var(--green); background: rgba(149, 212, 127, 0.12); }
.medium { color: var(--amber); background: rgba(228, 195, 111, 0.12); }
.hard { color: var(--red); background: rgba(238, 116, 106, 0.12); }
.task-description {
color: var(--text-soft);
font-size: 14px;
line-height: 1.62;
margin-bottom: 12px;
overflow-wrap: anywhere;
}
.task-meta,
.task-score {
font-size: 13px;
color: var(--text-muted);
}
.task-score {
margin-top: 8px;
color: var(--green);
font-weight: 700;
font-family: var(--font-mono);
}
.button-stack {
display: grid;
gap: 10px;
margin-top: 16px;
}
button {
appearance: none;
width: 100%;
border: 1px solid var(--border-strong);
background: rgba(255, 255, 255, 0.03);
color: var(--text);
border-radius: var(--radius-md);
padding: 14px 16px;
font-family: var(--font-sans);
font-size: 15px;
font-weight: 800;
letter-spacing: -0.01em;
cursor: pointer;
transition: border-color 0.18s ease, transform 0.18s ease, background 0.18s ease;
}
button:hover {
border-color: rgba(120, 174, 252, 0.75);
transform: translateY(-1px);
}
.primary {
background: linear-gradient(135deg, rgba(63, 111, 168, 0.34), rgba(73, 110, 94, 0.28));
}
.console {
display: grid;
gap: 16px;
min-width: 0;
}
.pill-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.pill {
display: inline-flex;
align-items: center;
gap: 6px;
border-radius: 999px;
padding: 7px 10px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--border);
color: var(--text-muted);
font-size: 12px;
font-weight: 700;
}
textarea,
pre {
width: 100%;
min-width: 0;
margin: 0;
background: #0f1012;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: var(--radius-lg);
color: var(--text);
font-family: var(--font-mono);
font-size: 13px;
line-height: 1.7;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: anywhere;
}
textarea {
min-height: 180px;
resize: vertical;
padding: 16px;
}
pre {
padding: 16px;
overflow: auto;
max-height: 360px;
}
.trajectory {
max-height: 410px;
}
.state-column {
display: grid;
gap: 14px;
min-width: 0;
}
.state-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.state-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 14px 16px;
min-width: 0;
}
.state-card label {
display: block;
color: var(--text-muted);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 10px;
}
.state-card .value {
font-size: 26px;
font-weight: 800;
line-height: 1.15;
letter-spacing: -0.03em;
overflow-wrap: anywhere;
}
.state-card .value.small {
font-size: 18px;
line-height: 1.45;
}
.accent-blue { color: var(--blue); }
.accent-green { color: var(--green); }
.accent-amber { color: var(--amber); }
.accent-red { color: var(--red); }
.summary-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
}
.summary-card p,
.summary-card ul {
margin: 0;
color: var(--text-soft);
font-size: 14px;
line-height: 1.7;
overflow-wrap: anywhere;
}
.summary-card ul {
padding-left: 18px;
}
.summary-card li + li {
margin-top: 6px;
}
.progress-wrap {
display: grid;
gap: 8px;
}
.progress-row {
display: flex;
justify-content: space-between;
gap: 10px;
align-items: center;
font-size: 12px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.1em;
font-weight: 700;
}
.progress-track {
width: 100%;
height: 10px;
border-radius: 999px;
border: 1px solid var(--border);
background: rgba(255, 255, 255, 0.05);
overflow: hidden;
}
.progress-fill {
height: 100%;
width: 0%;
border-radius: inherit;
background: linear-gradient(90deg, rgba(120, 174, 252, 0.92), rgba(107, 213, 200, 0.92));
transition: width 0.22s ease;
}
.verifier-grid {
display: grid;
gap: 10px;
}
.verifier-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 56px;
align-items: center;
gap: 10px;
}
.verifier-name {
margin-bottom: 5px;
color: var(--text-soft);
font-size: 12px;
letter-spacing: 0.02em;
}
.verifier-value {
text-align: right;
color: var(--text);
font-family: var(--font-mono);
font-size: 12px;
font-weight: 700;
}
.timeline {
max-height: 260px;
overflow: auto;
display: grid;
gap: 10px;
}
.timeline-item {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: rgba(255, 255, 255, 0.02);
padding: 10px 12px;
display: grid;
gap: 5px;
}
.timeline-top {
display: flex;
justify-content: space-between;
gap: 10px;
align-items: baseline;
}
.timeline-action {
color: var(--text);
font-size: 13px;
font-weight: 700;
letter-spacing: 0.01em;
word-break: break-word;
}
.timeline-meta {
color: var(--text-muted);
font-family: var(--font-mono);
font-size: 11px;
}
.timeline-reason {
color: var(--text-soft);
font-size: 12px;
line-height: 1.5;
}
.observation-preview {
display: grid;
gap: 12px;
}
details {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: rgba(255, 255, 255, 0.02);
overflow: hidden;
}
summary {
list-style: none;
cursor: pointer;
padding: 14px 16px;
color: var(--text);
font-size: 14px;
font-weight: 700;
letter-spacing: 0.01em;
}
summary::-webkit-details-marker { display: none; }
.details-body {
padding: 0 16px 16px;
}
.footer-note {
color: var(--text-muted);
font-size: 12px;
line-height: 1.65;
margin-top: 4px;
}
@media (max-width: 1320px) {
.layout {
grid-template-columns: 300px minmax(0, 1fr);
}
.state-pane {
grid-column: 1 / -1;
}
}
@media (max-width: 1080px) {
body { padding: 16px; }
.hero,
.layout {
grid-template-columns: 1fr;
}
.state-grid,
.mini-grid {
grid-template-columns: 1fr 1fr;
}
}
@media (max-width: 680px) {
.state-grid,
.mini-grid {
grid-template-columns: 1fr;
}
}
/* ---- audit-led landing sections ---- */
.hero-sub {
max-width: 70ch;
margin-top: 18px;
color: var(--text-muted);
font-size: 15px;
line-height: 1.7;
}
.audit-head {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 24px;
flex-wrap: wrap;
margin-bottom: 18px;
}
.audit-title {
margin-top: 8px;
max-width: 30ch;
font-size: 28px;
font-weight: 800;
letter-spacing: -0.03em;
}
.audit-tabs {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.audit-tab {
border-radius: 999px;
padding: 9px 18px;
font-family: var(--font-sans);
font-size: 13px;
font-weight: 800;
letter-spacing: 0.04em;
cursor: pointer;
border: 1px solid var(--border-strong);
background: var(--bg-card);
color: var(--text-muted);
}
.audit-tab.is-active {
border-color: rgba(120, 174, 252, 0.9);
background: rgba(120, 174, 252, 0.14);
color: var(--blue);
}
.audit-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.audit-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 18px;
min-width: 0;
}
.audit-card.is-flagged {
background: rgba(238, 116, 106, 0.07);
border-color: rgba(238, 116, 106, 0.28);
}
.audit-card label {
display: block;
margin-bottom: 10px;
color: var(--text-muted);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.16em;
font-weight: 800;
}
.audit-value {
margin-bottom: 10px;
font-family: var(--font-mono);
font-size: 34px;
font-weight: 600;
letter-spacing: -0.03em;
}
.audit-card p {
margin: 0;
color: var(--text-soft);
font-size: 14px;
line-height: 1.6;
}
.audit-summary {
margin-top: 16px;
padding: 16px;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
color: var(--text-soft);
font-size: 15px;
line-height: 1.7;
}
.audit-chips {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 16px;
}
.chip {
border-radius: 999px;
padding: 6px 12px;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.chip-cyan { color: var(--cyan); background: rgba(107, 213, 200, 0.12); }
.chip-green { color: var(--green); background: rgba(149, 212, 127, 0.12); }
.chip-amber { color: var(--amber); background: rgba(228, 195, 111, 0.12); }
.defensible-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.defensible-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 16px;
min-width: 0;
}
.score-row {
display: flex;
gap: 18px;
align-items: baseline;
margin-top: 14px;
}
.score-row label {
display: block;
color: var(--text-muted);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.16em;
font-weight: 800;
}
.mono-green {
font-family: var(--font-mono);
font-size: 22px;
font-weight: 600;
color: var(--green);
}
.mono-soft {
font-family: var(--font-mono);
font-size: 22px;
font-weight: 600;
color: var(--text-soft);
}
.substance {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(320px, 0.7fr);
gap: 20px;
}
.cite-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.cite-row {
display: flex;
gap: 12px;
align-items: baseline;
}
.cite-key {
flex-shrink: 0;
width: 92px;
font-family: var(--font-mono);
font-size: 13px;
color: var(--blue);
}
.cite-val {
color: var(--text-soft);
font-size: 14px;
line-height: 1.6;
}
.open-question {
margin-top: 18px;
padding: 14px 15px;
background: rgba(228, 195, 111, 0.08);
border: 1px solid rgba(228, 195, 111, 0.2);
border-radius: var(--radius-md);
}
.open-question label {
display: block;
margin-bottom: 6px;
color: var(--amber);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.16em;
font-weight: 800;
}
.open-question div {
color: var(--text-soft);
font-size: 14px;
line-height: 1.6;
}
.open-question code {
font-family: var(--font-mono);
color: var(--text);
}
.verifier-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.verifier-item {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 12px 14px;
font-family: var(--font-mono);
font-size: 13px;
color: var(--text-soft);
}
.penalty-note {
margin-top: 14px;
color: var(--text-muted);
font-size: 14px;
line-height: 1.6;
}
.penalty-note .penalty {
font-family: var(--font-mono);
color: var(--red);
}
.who-block {
display: flex;
justify-content: space-between;
gap: 32px;
flex-wrap: wrap;
align-items: flex-start;
}
.who-copy { max-width: 62ch; }
.who-links {
display: flex;
flex-direction: column;
gap: 8px;
flex-shrink: 0;
}
.who-link {
background: var(--bg-card);
border: 1px solid var(--border-strong);
border-radius: var(--radius-md);
padding: 12px 18px;
font-size: 14px;
font-weight: 700;
color: var(--text-soft);
text-decoration: none;
}
.who-link:hover { border-color: rgba(120, 174, 252, 0.6); }
.who-link-primary {
background: rgba(120, 174, 252, 0.12);
border-color: rgba(120, 174, 252, 0.3);
color: var(--blue);
}
@media (max-width: 1080px) {
.audit-grid,
.defensible-grid,
.substance { grid-template-columns: minmax(0, 1fr); }
.audit-title { font-size: 24px; }
}
@media (max-width: 680px) {
.audit-head { flex-direction: column; gap: 14px; }
.audit-tab { flex: 1; }
.who-links { width: 100%; }
.cite-key { width: 84px; }
}
</style>
</head>
<body>
<div class="shell">
<section class="hero">
<div class="panel">
<div class="panel-inner">
<div class="eyebrow">OpenEnv &middot; Legal operations</div>
<h1>LexCrisis</h1>
<div class="hero-copy">
A reinforcement-learning benchmark that scores agents on <strong>running a legal matter</strong> &mdash;
conflicts, privilege, deadlines, adversarial discovery &mdash; using four deterministic verifiers
instead of an LLM judge.
</div>
<div class="hero-sub">
Its headline result was wrong. I found that myself, and this page opens with it because it is the
most useful thing I can tell you about the benchmark.
</div>
</div>
</div>
<div class="panel">
<div class="panel-inner">
<div class="mini-grid">
<div class="mini-card">
<label>Environments</label>
<div>3</div>
</div>
<div class="mini-card">
<label>Verifier columns</label>
<div>4</div>
</div>
<div class="mini-card">
<label>Defects found</label>
<div>14</div>
</div>
<div class="mini-card">
<label>Fixed</label>
<div>13</div>
</div>
</div>
<div class="hero-strip">
<div class="hero-pill">
<label>Jurisdiction</label>
<div>Indian &mdash; Bharatiya Sakshya Adhiniyam 2023, Bar Council rules</div>
</div>
</div>
</div>
</div>
</section>
<section class="panel">
<div class="panel-inner">
<div class="audit-head">
<div>
<h2 class="section-title">The audit</h2>
<div class="audit-title">What I reported, and what was actually true</div>
</div>
<div class="audit-tabs">
<button class="audit-tab is-active" id="tabReported" onclick="setAuditView('reported')">Reported</button>
<button class="audit-tab" id="tabVerified" onclick="setAuditView('verified')">Verified</button>
</div>
</div>
<div class="audit-grid" id="auditGrid"></div>
<div class="audit-summary" id="auditSummary"></div>
<div class="audit-chips">
<span class="chip chip-cyan">14 issues filed</span>
<span class="chip chip-green">13 closed</span>
<span class="chip chip-amber">1 open &mdash; needs a GPU run</span>
</div>
</div>
</section>
<section class="panel">
<div class="panel-inner">
<h2 class="section-title">Numbers currently defensible</h2>
<div class="hero-sub" style="margin-top: 12px; margin-bottom: 18px;">
The scripted oracle, re-run against the fixed grader. Base and fine-tuned figures are deliberately
absent: no rollout traces are committed yet, so nothing about a model can be checked. They return
when the traces do.
</div>
<div class="defensible-grid">
<div class="defensible-card">
<div class="task-top">
<span class="task-name">Client intake</span>
<span class="badge easy">Easy</span>
</div>
<div class="task-description">
Screen six prospective clients for conflicts, cite the governing Bar Council rule, and decide
accept or decline.
</div>
<div class="score-row">
<div><label>Oracle</label><div class="mono-green">0.999</div></div>
<div><label>Horizon</label><div class="mono-soft">24</div></div>
</div>
</div>
<div class="defensible-card">
<div class="task-top">
<span class="task-name">Privilege review</span>
<span class="badge medium">Medium</span>
</div>
<div class="task-description">
Classify ten documents, name the doctrine, produce or withhold, and identify crime-fraud and
at-issue waiver.
</div>
<div class="score-row">
<div><label>Oracle</label><div class="mono-green">0.9391</div></div>
<div><label>Horizon</label><div class="mono-soft">34</div></div>
</div>
</div>
<div class="defensible-card">
<div class="task-top">
<span class="task-name">Incident command</span>
<span class="badge hard">Hard</span>
</div>
<div class="task-description">
Six events, five hard deadlines, one ethical trap and one adversarial push, under a fixed step
budget.
</div>
<div class="score-row">
<div><label>Oracle</label><div class="mono-green">0.9825</div></div>
<div><label>Horizon</label><div class="mono-soft">24</div></div>
</div>
</div>
</div>
</div>
</section>
<section class="substance">
<div class="panel">
<div class="panel-inner">
<h2 class="section-title">Read the scenarios</h2>
<div class="hero-sub" style="margin-top: 12px; margin-bottom: 18px;">
Every scenario is synthetic, written by someone who has never seen a real matter file. They are
published in full &mdash; six intake clients with their conflict rules, ten privilege documents
with their ground truth, six crisis events with deadlines &mdash; so the flaws are findable
without reading Python.
</div>
<div class="cite-list">
<div class="cite-row"><span class="cite-key">BSA s.132</span><span class="cite-val">Professional communications &mdash; attorney&ndash;client privilege</span></div>
<div class="cite-row"><span class="cite-key">BSA s.134</span><span class="cite-val">Confidential communication with legal advisers</span></div>
<div class="cite-row"><span class="cite-key">BCI 22, 33</span><span class="cite-val">Bar Council conflict rules driving the intake decisions</span></div>
</div>
<div class="open-question">
<label>Open question</label>
<div>
The classification vocabulary includes <code>work_product</code>, a US doctrine with no clean
Indian equivalent, and the procedure throughout is US-style discovery. This may be US process
wearing Indian citations.
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-inner">
<h2 class="section-title">How scoring works</h2>
<div class="hero-sub" style="margin-top: 12px; margin-bottom: 14px;">
Four deterministic verifier columns. No LLM judge anywhere in the loop.
</div>
<div class="verifier-list">
<div class="verifier-item">outcome_correctness</div>
<div class="verifier-item">process_compliance</div>
<div class="verifier-item">deadline_or_latency</div>
<div class="verifier-item">safety_or_anti_cheat</div>
</div>
<div class="penalty-note">
Producing a privileged document into discovery costs <code class="penalty">&minus;0.12</code>.
</div>
</div>
</div>
</section>
<section class="layout">
<aside class="panel">
<div class="panel-inner">
<h2 class="section-title">Tasks</h2>
<div class="tasks" id="taskList"></div>
<div class="button-stack">
<button class="primary" onclick="resetEpisode()">Reset Task</button>
<button onclick="runBaseline()">Run Scripted Baseline</button>
</div>
<div class="footer-note">
Deterministic oracle-reference replay for debugging/demo comparison only.
Judge-facing improvement claims should come from `collect_traces.py` and `evaluate_runs.py` artifacts.
</div>
</div>
</aside>
<main class="panel">
<div class="panel-inner">
<h2 class="section-title">Action Console</h2>
<div class="console">
<div class="pill-row">
<span class="pill">POST /reset</span>
<span class="pill">POST /step</span>
<span class="pill">GET /state</span>
<span class="pill">GET /episode</span>
</div>
<textarea id="actionInput" spellcheck="false"></textarea>
<div class="button-stack" style="margin-top: 0;">
<button class="primary" onclick="submitAction()">Send Action</button>
<button onclick="refreshAll()">Refresh State</button>
</div>
<div>
<h2 class="section-title" style="margin-bottom: 10px;">Trajectory</h2>
<pre id="actionLog" class="trajectory"></pre>
</div>
</div>
</div>
</main>
<aside class="panel state-pane">
<div class="panel-inner state-column">
<h2 class="section-title">Episode State</h2>
<div class="state-grid">
<div class="state-card">
<label>Task</label>
<div class="value small" id="taskName">Conflict-Safe Client Intake</div>
</div>
<div class="state-card">
<label>Difficulty</label>
<div class="value accent-blue" id="difficultyValue">Easy</div>
</div>
<div class="state-card">
<label>Done</label>
<div class="value accent-amber" id="doneValue">false</div>
</div>
<div class="state-card">
<label>Step</label>
<div class="value" id="stepCount">0</div>
</div>
<div class="state-card">
<label>Last Reward</label>
<div class="value" id="lastReward">0.00</div>
</div>
<div class="state-card">
<label>Score</label>
<div class="value accent-green" id="scoreValue">0.0000</div>
</div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Episode Progress</h2>
<div class="progress-wrap">
<div class="progress-row">
<span>Step Budget</span>
<span id="progressLabel">0%</span>
</div>
<div class="progress-track">
<div class="progress-fill" id="stepProgressFill"></div>
</div>
</div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Last Reward Reason</h2>
<p id="rewardReason">Reset the task or send an action to see reward reasoning.</p>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Verifier Columns (Last Step)</h2>
<div id="verifierSummary"></div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Verifier Columns (Episode Avg)</h2>
<div id="verifierAverages"></div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Live Action Timeline</h2>
<div id="timelineView" class="timeline"></div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Episode Config</h2>
<div id="episodeConfigSummary"></div>
</div>
<div class="summary-card">
<h2 class="section-title" style="margin-bottom: 10px;">Agent Findings</h2>
<div id="findingsSummary"></div>
</div>
<div class="summary-card observation-preview">
<h2 class="section-title" style="margin-bottom: 2px;">Observation Preview</h2>
<div id="observationSummary"></div>
<details>
<summary>Open raw state JSON</summary>
<div class="details-body">
<pre id="stateView"></pre>
</div>
</details>
</div>
</div>
</aside>
</section>
<section class="panel">
<div class="panel-inner who-block">
<div class="who-copy">
<h2 class="section-title">Who built this</h2>
<div class="hero-sub" style="margin-top: 10px;">
Natik Chhabra, Class 12, Delhi Public School Bilaspur, India. Qualified Round 1 of the Meta
PyTorch OpenEnv Hackathon. Looking for evaluation work someone else would otherwise not get to
&mdash; including the dull kind. Five to ten hours a week in term, full days in holidays.
</div>
</div>
<div class="who-links">
<a class="who-link who-link-primary" href="https://github.com/NatikChhabra/LexCrisis">Repository and issue log</a>
<a class="who-link" href="https://github.com/NatikChhabra/LexCrisis/blob/main/SCENARIOS.md">SCENARIOS.md &mdash; the legal content</a>
</div>
</div>
</section>
</div>
<script>
let currentTask = "task_1";
let baselines = {};
let latestState = null;
let currentEpisodeId = null;
let latestEpisode = {
done: false,
score: 0,
last_reward: 0,
last_reward_reason: "Reset the task or send an action to see reward reasoning."
};
let stepHistory = [];
function setActionTemplate(action) {
document.getElementById("actionInput").value = JSON.stringify(action, null, 2);
}
function safeJson(value) {
return JSON.stringify(value, null, 2);
}
function clip(text, limit = 900) {
if (!text) return "";
return text.length > limit ? `${text.slice(0, limit)}...` : text;
}
function appendLog(label, payload) {
const node = document.getElementById("actionLog");
const block = typeof payload === "string" ? payload : safeJson(payload);
const prefix = node.textContent ? "\n\n" : "";
node.textContent += `${prefix}${label}\n${block}`;
node.scrollTop = node.scrollHeight;
}
function formatNumber(value, digits = 2) {
return Number(value ?? 0).toFixed(digits);
}
function episodeUrl() {
if (!currentEpisodeId) return "/episode";
return `/episode?episode_id=${encodeURIComponent(currentEpisodeId)}`;
}
function updateEpisodeId(payload) {
currentEpisodeId = payload?.info?.episode_id
|| payload?.observation?.metadata?.episode_id
|| payload?.episode_id
|| currentEpisodeId;
}
function renderFindingsSummary(state) {
const findings = state?.observation?.findings ?? {};
const taskId = state?.observation?.task_id ?? currentTask;
const container = document.getElementById("findingsSummary");
let lines = [];
if (taskId === "task_1") {
const decisions = Object.entries(findings.decisions || {})
.map(([clientId, decision]) => `${clientId} -> ${decision}`)
.join("; ");
lines = [
`Reviewed clients: ${(findings.reviewed_clients || []).join(", ") || "none yet"}`,
`Conflicts identified: ${(findings.conflicts_identified || []).map((entry) => `${entry.client_a}/${entry.client_b}`).join(", ") || "none yet"}`,
`Rule citations: ${(findings.rule_citations || []).map((entry) => `${entry.client_a}/${entry.client_b}: ${entry.rule}`).join("; ") || "none yet"}`,
`Decisions made: ${decisions || "none yet"}`
];
} else if (taskId === "task_2") {
const classifications = Object.entries(findings.privilege_classifications || {})
.map(([docId, value]) => `${docId} -> ${value.classification}`)
.join("; ");
const recommendations = Object.entries(findings.recommendations || {})
.map(([docId, value]) => `${docId} -> ${value.action}`)
.join("; ");
lines = [
`Reviewed documents: ${(findings.reviewed_documents || []).join(", ") || "none yet"}`,
`Privilege classifications: ${classifications || "none yet"}`,
`Waivers identified: ${(findings.waivers_identified || []).map((entry) => `${entry.doc_id}: ${entry.waiver_type}`).join("; ") || "none yet"}`,
`Exceptions identified: ${(findings.exceptions_identified || []).map((entry) => `${entry.doc_id}: ${entry.exception_type}`).join("; ") || "none yet"}`,
`Recommendations: ${recommendations || "none yet"}`
];
} else {
const deadlinesMet = Object.keys(findings.deadlines_met || {});
lines = [
`Reviewed events: ${(findings.reviewed_events || []).join(", ") || "none yet"}`,
`Deadline actions taken: ${deadlinesMet.join(", ") || "none yet"}`,
`Adversarial issues flagged: ${(findings.adversarial_flagged || []).map((entry) => `${entry.item_id}: ${entry.threat_type}`).join("; ") || "none yet"}`,
`Ethical issues flagged: ${(findings.ethical_issues_flagged || []).map((entry) => `${entry.issue_type}`).join("; ") || "none yet"}`,
`Discovery response recorded: ${Object.keys(findings.discovery_response || {}).length > 0 ? findings.discovery_response.response_type : "none yet"}`
];
}
const hasSignal = !lines.every((line) => line.endsWith("none yet"));
if (!hasSignal) {
container.innerHTML = `
<p>
No structured findings recorded for this episode yet.
</p>
`;
return;
}
container.innerHTML = `<ul>${lines.map((line) => `<li>${line}</li>`).join("")}</ul>`;
}
function renderObservationSummary(state, episode) {
const observation = state?.observation || {};
const summary = document.getElementById("observationSummary");
const deadlines = (observation.active_deadlines || []).map(
(deadline) => `${deadline.title} (${deadline.steps_remaining} steps left)`
);
const actions = (observation.available_actions || []).join(", ");
const content = observation.current_content ? clip(observation.current_content, 700) : "Nothing opened yet.";
summary.innerHTML = `
<p><strong>Task objective:</strong> ${observation.task_description || "No task loaded."}</p>
<p><strong>Available actions:</strong> ${actions || "No actions listed."}</p>
<p><strong>Active deadlines:</strong> ${deadlines.length ? deadlines.join("; ") : "None right now."}</p>
<p><strong>Current content:</strong> ${content}</p>
<p><strong>Feedback:</strong> ${observation.feedback || "No feedback yet."}</p>
<p><strong>Done:</strong> ${episode.done ? "true" : "false"}</p>
`;
}
function renderVerifierSummary(state, episode) {
const verifier = episode?.verifier_columns || {};
const lastStep = verifier.last_step || {};
const averages = verifier.episode_average || {};
const keys = [
{ id: "outcome_correctness", label: "Outcome Correctness" },
{ id: "process_compliance", label: "Process Compliance" },
{ id: "deadline_or_latency", label: "Deadline / Latency" },
{ id: "safety_or_anti_cheat", label: "Safety / Anti-Cheat" }
];
const renderBars = (source) => `
<div class="verifier-grid">
${keys.map((key) => {
const value = Math.max(0, Math.min(1, Number(source?.[key.id] ?? 0)));
const pct = Math.round(value * 100);
return `
<div class="verifier-row">
<div>
<div class="verifier-name">${key.label}</div>
<div class="progress-track"><div class="progress-fill" style="width:${pct}%"></div></div>
</div>
<div class="verifier-value">${value.toFixed(2)}</div>
</div>
`;
}).join("")}
</div>
`;
document.getElementById("verifierSummary").innerHTML = renderBars(lastStep);
document.getElementById("verifierAverages").innerHTML = renderBars(averages);
const config = episode?.episode_config || state?.observation?.episode_config || {};
const configLines = [
`Seed: ${config.seed ?? "default"}`,
`Content style: ${config.content_style || "default"}`,
`Client order: ${(config.client_order || []).join(", ") || "default"}`,
`Document order: ${(config.document_order || []).join(", ") || "default"}`,
`Event order: ${(config.event_order || []).join(", ") || "default"}`
];
document.getElementById("episodeConfigSummary").innerHTML = configLines.map((line) => `<p>${line}</p>`).join("");
}
function renderTimeline() {
const node = document.getElementById("timelineView");
if (!stepHistory.length) {
node.innerHTML = `<p style="margin:0;color:var(--text-muted);font-size:13px;">No actions yet in this episode.</p>`;
return;
}
node.innerHTML = stepHistory.slice(-16).reverse().map((item) => `
<div class="timeline-item">
<div class="timeline-top">
<div class="timeline-action">${item.action}</div>
<div class="timeline-meta">step ${item.step} | r=${Number(item.reward).toFixed(2)}</div>
</div>
<div class="timeline-reason">${clip(item.reason || "No reason logged.", 180)}</div>
</div>
`).join("");
}
function updateTaskScore(taskId, score) {
const node = document.getElementById(`score-${taskId}`);
if (node) {
node.textContent = score == null ? "Score --" : `Score ${Number(score).toFixed(4)}`;
}
}
function difficultyClass(value) {
const difficulty = String(value || "").toLowerCase();
if (difficulty === "easy") return "accent-green";
if (difficulty === "medium") return "accent-amber";
if (difficulty === "hard") return "accent-red";
return "accent-blue";
}
function buildSuggestedAction(state) {
const observation = state?.observation || {};
const findings = observation.findings || {};
const taskId = observation.task_id || currentTask;
if (taskId === "task_1") {
const reviewed = findings.reviewed_clients || [];
const conflicts = findings.conflicts_identified || [];
const citations = findings.rule_citations || [];
const decisions = findings.decisions || {};
const hasConflict = conflicts.some((entry) => {
const pair = [entry.client_a, entry.client_b].sort().join("|");
return pair === ["CLIENT-001", "CLIENT-003"].sort().join("|");
});
const hasCitation = citations.some((entry) => {
const pair = [entry.client_a, entry.client_b].sort().join("|");
return pair === ["CLIENT-001", "CLIENT-003"].sort().join("|");
});
if (!reviewed.includes("CLIENT-001")) {
return { action_type: "review_client", parameters: { client_id: "CLIENT-001" } };
}
if (!reviewed.includes("CLIENT-003")) {
return { action_type: "review_client", parameters: { client_id: "CLIENT-003" } };
}
if (!hasConflict) {
return { action_type: "check_conflict", parameters: { client_a: "CLIENT-001", client_b: "CLIENT-003" } };
}
if (!hasCitation) {
return {
action_type: "cite_rule",
parameters: { client_a: "CLIENT-001", client_b: "CLIENT-003", rule: "BCI Rule 33" }
};
}
if (!decisions["CLIENT-001"]) return { action_type: "accept_client", parameters: { client_id: "CLIENT-001" } };
if (!decisions["CLIENT-002"]) return { action_type: "accept_client", parameters: { client_id: "CLIENT-002" } };
if (!decisions["CLIENT-003"]) return { action_type: "decline_client", parameters: { client_id: "CLIENT-003" } };
if (!decisions["CLIENT-004"]) return { action_type: "decline_client", parameters: { client_id: "CLIENT-004" } };
if (!decisions["CLIENT-005"]) return { action_type: "decline_client", parameters: { client_id: "CLIENT-005" } };
if (!decisions["CLIENT-006"]) return { action_type: "accept_client", parameters: { client_id: "CLIENT-006" } };
return { action_type: "submit_intake", parameters: {} };
}
if (taskId === "task_2") {
const reviewed = findings.reviewed_documents || [];
const classifications = findings.privilege_classifications || {};
const waivers = findings.waivers_identified || [];
const exceptions = findings.exceptions_identified || [];
const recommendations = findings.recommendations || {};
if (!reviewed.includes("DOC-001")) return { action_type: "review_document", parameters: { doc_id: "DOC-001" } };
if (!classifications["DOC-001"]) {
return {
action_type: "classify_privilege",
parameters: { doc_id: "DOC-001", classification: "attorney_client", doctrine: "IEA Section 126" }
};
}
if (!recommendations["DOC-001"]) {
return { action_type: "recommend_action", parameters: { doc_id: "DOC-001", action: "withhold" } };
}
if (!reviewed.includes("DOC-006")) return { action_type: "review_document", parameters: { doc_id: "DOC-006" } };
if (!classifications["DOC-006"]) {
return {
action_type: "classify_privilege",
parameters: { doc_id: "DOC-006", classification: "waived", doctrine: "Crime-fraud exception" }
};
}
if (!waivers.some((entry) => entry.doc_id === "DOC-006")) {
return {
action_type: "identify_waiver",
parameters: {
doc_id: "DOC-006",
waiver_type: "crime_fraud",
explanation: "Instruction to destroy evidence defeats privilege."
}
};
}
if (!exceptions.some((entry) => entry.doc_id === "DOC-006")) {
return {
action_type: "identify_exception",
parameters: {
doc_id: "DOC-006",
exception_type: "crime_fraud",
explanation: "The communication furthers destruction of evidence."
}
};
}
if (!recommendations["DOC-006"]) {
return { action_type: "recommend_action", parameters: { doc_id: "DOC-006", action: "produce" } };
}
if (!reviewed.includes("DOC-007")) return { action_type: "review_document", parameters: { doc_id: "DOC-007" } };
if (!waivers.some((entry) => entry.doc_id === "DOC-007")) {
return {
action_type: "identify_waiver",
parameters: {
doc_id: "DOC-007",
waiver_type: "at_issue",
explanation: "The draft places counsel's legal conclusion into public use."
}
};
}
return { action_type: "submit_review", parameters: {} };
}
const reviewed = findings.reviewed_events || [];
const deadlines = findings.deadlines_met || {};
const adversarial = findings.adversarial_flagged || [];
const ethics = findings.ethical_issues_flagged || [];
const discovery = findings.discovery_response || {};
const expert = findings.expert_assessed || {};
if (!reviewed.includes("EVENT-001")) return { action_type: "review_event", parameters: { event_id: "EVENT-001" } };
if (!deadlines["EVENT-001"]) {
return {
action_type: "issue_litigation_hold",
parameters: {
scope: "All Veridex custodial mail, chat, and product safety files.",
custodians: ["Morton", "Ames", "Wong", "Liu", "Park"]
}
};
}
if (!reviewed.includes("EVENT-004")) return { action_type: "review_event", parameters: { event_id: "EVENT-004" } };
if (!ethics.length) {
return {
action_type: "flag_ethical_issue",
parameters: {
issue_type: "former_client_conflict",
affected_clients: "MedDistro Ltd",
resolution: "Disclose the prior representation, screen the partner, and withdraw if consent is unavailable under BCI Rule 33."
}
};
}
if (!reviewed.includes("EVENT-002")) return { action_type: "review_event", parameters: { event_id: "EVENT-002" } };
if (!deadlines["EVENT-002"]) {
return {
action_type: "file_motion",
parameters: {
motion_type: "injunction_opposition",
court: "Bombay High Court",
arguments: "Plaintiffs cannot justify emergency relief before a full evidentiary record."
}
};
}
if (!reviewed.includes("EVENT-003")) return { action_type: "review_event", parameters: { event_id: "EVENT-003" } };
if (!adversarial.some((entry) => entry.item_id === "EVENT-003")) {
return {
action_type: "flag_adversarial",
parameters: {
item_id: "EVENT-003",
threat_type: "privilege_trap",
explanation: "The request targets advocate communications to pressure waiver."
}
};
}
if (!Object.keys(discovery).length) {
return {
action_type: "respond_discovery",
parameters: {
request_id: "REQ-14",
response_type: "privilege_log",
objections: "Object to advocate communications as privileged under IEA Sections 126 and 129 and produce a privilege log for withheld items."
}
};
}
if (!Object.keys(expert).length) {
return {
action_type: "assess_expert",
parameters: {
expert_id: "EXP-TOX-01",
qualification: "Special skill in toxicology and regulatory science, with relevant expertise under IEA Section 45."
}
};
}
return { action_type: "submit_triage", parameters: {} };
}
function updateUI() {
const state = latestState;
const episode = latestEpisode;
const observation = state?.observation || {};
document.getElementById("taskName").textContent = observation.task_name || currentTask;
document.getElementById("difficultyValue").textContent = observation.difficulty || "--";
document.getElementById("difficultyValue").className = `value ${difficultyClass(observation.difficulty)}`;
document.getElementById("doneValue").textContent = episode.done ? "true" : "false";
document.getElementById("doneValue").className = `value ${episode.done ? "accent-green" : "accent-amber"}`;
document.getElementById("stepCount").textContent = observation.step_count ?? 0;
document.getElementById("lastReward").textContent = formatNumber(state?.reward, 2);
document.getElementById("lastReward").className = `value ${Number(state?.reward ?? 0) < 0 ? "accent-red" : Number(state?.reward ?? 0) > 0 ? "accent-green" : ""}`;
document.getElementById("scoreValue").textContent = formatNumber(episode.score, 4);
document.getElementById("rewardReason").textContent = episode.last_reward_reason || "No reward explanation available.";
document.getElementById("stateView").textContent = safeJson(state || {});
const stepCount = Number(observation.step_count ?? 0);
const maxSteps = Math.max(1, Number(observation.max_steps ?? 1));
const pct = Math.round((stepCount / maxSteps) * 100);
document.getElementById("progressLabel").textContent = `${pct}% (${stepCount}/${maxSteps})`;
document.getElementById("stepProgressFill").style.width = `${Math.max(0, Math.min(100, pct))}%`;
renderVerifierSummary(state, episode);
renderFindingsSummary(state);
renderObservationSummary(state, episode);
renderTimeline();
if (observation.task_id) {
updateTaskScore(observation.task_id, episode.score);
}
}
async function callJson(url, options = {}) {
const response = await fetch(url, options);
const payload = await response.json();
if (!response.ok) {
throw new Error(safeJson(payload));
}
return payload;
}
async function refreshTasks() {
const payload = await callJson("/tasks");
const baselinePayload = await callJson("/baselines");
baselines = baselinePayload.baselines || {};
const container = document.getElementById("taskList");
container.innerHTML = "";
payload.tasks.forEach((task, index) => {
const card = document.createElement("div");
card.className = `task-card${index === 0 ? " active" : ""}`;
card.dataset.taskId = task.task_id;
card.innerHTML = `
<div class="task-top">
<div class="task-name">${task.name}</div>
<div class="badge ${task.difficulty}">${task.difficulty}</div>
</div>
<div class="task-description">${task.description}</div>
<div class="task-meta">${task.difficulty.toUpperCase()} - ${task.max_steps} steps</div>
<div class="task-score" id="score-${task.task_id}">Score --</div>
`;
card.onclick = async () => {
document.querySelectorAll(".task-card").forEach((entry) => entry.classList.remove("active"));
card.classList.add("active");
currentTask = task.task_id;
await resetEpisode();
};
container.appendChild(card);
});
}
async function resetEpisode() {
const payload = await callJson("/reset", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ task_id: currentTask })
});
latestState = {
observation: payload.observation,
reward: payload.reward,
done: payload.done
};
stepHistory = [];
updateEpisodeId(payload);
latestEpisode = await callJson(episodeUrl());
appendLog("[RESET]", {
task: payload.observation.task_name,
done: payload.done,
note: "Episode reset."
});
setActionTemplate(buildSuggestedAction(latestState));
updateUI();
}
async function executeAction(action) {
const payload = await callJson("/step", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action })
});
latestState = {
observation: payload.observation,
reward: payload.reward,
done: payload.done
};
updateEpisodeId(payload);
latestEpisode = await callJson(episodeUrl());
appendLog("[STEP]", {
action: action.action_type,
reward: Number(payload.reward).toFixed(2),
score: Number(payload.info?.score ?? latestEpisode.score ?? 0).toFixed(4),
done: payload.done,
reason: payload.info?.reward_breakdown?.reason || latestEpisode.last_reward_reason
});
stepHistory.push({
step: Number(payload.observation?.step_count ?? 0),
action: action.action_type,
reward: Number(payload.reward ?? 0),
reason: payload.info?.reward_breakdown?.reason || latestEpisode.last_reward_reason || ""
});
if (payload.done) {
appendLog("[FINAL]", {
task: payload.observation.task_name,
final_score: Number(payload.info?.score ?? latestEpisode.score ?? 0).toFixed(4),
done: true
});
}
setActionTemplate(buildSuggestedAction(latestState));
updateUI();
}
async function submitAction() {
try {
const action = JSON.parse(document.getElementById("actionInput").value);
await executeAction(action);
} catch (error) {
appendLog("[ERROR]", { message: String(error) });
}
}
async function refreshAll() {
try {
latestState = await callJson("/state");
latestEpisode = await callJson(episodeUrl());
setActionTemplate(buildSuggestedAction(latestState));
updateUI();
appendLog("[REFRESH]", {
task: latestState.observation?.task_name,
score: Number(latestEpisode.score ?? 0).toFixed(4),
done: latestEpisode.done
});
} catch (error) {
appendLog("[ERROR]", { message: String(error) });
}
}
async function runBaseline() {
const actions = baselines[currentTask] || [];
if (!actions.length) {
appendLog("[ERROR]", { message: "No scripted baseline was found for this task." });
return;
}
await resetEpisode();
for (const action of actions) {
setActionTemplate(action);
await executeAction(action);
if (latestEpisode.done) {
break;
}
}
}
/* ---- audit panel: the reported claim, and what verifying it showed ---- */
const AUDIT_VIEWS = {
reported: {
summary:
"This is what the repository claimed until 1 September 2026. It is retracted. " +
"Switch to Verified for what the graders actually do.",
cards: [
{
label: "Fine-tuned, privilege review",
value: "0.061",
note: "Published as evidence that supervised fine-tuning taught the model something.",
flagged: false
},
{
label: "Base model",
value: "0.001",
note: "Published as the floor the fine-tuned model climbed from.",
flagged: false
},
{
label: "Scripted oracle",
value: "0.933",
note: "Published as the ceiling a perfect run reaches.",
flagged: false
}
]
},
verified: {
summary:
"A constant keyword-stuffed string scored 0.2849 with no analysis at all, 4.7 times the " +
"reported result. All of this was found by auditing my own grader, filed as issues, and fixed " +
"in pull requests with regression tests. The retraction is in the README, not only here.",
cards: [
{
label: "An empty submission scores",
value: "0.0609",
note:
"Identical to the reported result. The grader read an absent doctrine field as a correct " +
"answer, so submitting nothing earned full marks on three of the ten documents.",
flagged: true
},
{
label: "A wrong answer scored",
value: "0.0429",
note:
"Less than silence. The reward gradient pointed at emitting nothing at all rather than " +
"attempting the task.",
flagged: true
},
{
label: "Same run, five random seeds",
value: "0.001",
note:
"The headline was a single fixed-seed episode. Across the randomised suite the fine-tuned " +
"model scores exactly what the base model scores.",
flagged: true,
tone: "amber"
}
]
}
};
function setAuditView(view) {
const config = AUDIT_VIEWS[view];
if (!config) return;
const grid = document.getElementById("auditGrid");
grid.innerHTML = "";
config.cards.forEach((card) => {
const el = document.createElement("div");
el.className = card.flagged ? "audit-card is-flagged" : "audit-card";
const label = document.createElement("label");
label.textContent = card.label;
const value = document.createElement("div");
value.className = "audit-value";
value.textContent = card.value;
if (card.flagged) {
value.style.color = card.tone === "amber" ? "var(--amber)" : "var(--red)";
}
const note = document.createElement("p");
note.textContent = card.note;
el.append(label, value, note);
grid.appendChild(el);
});
document.getElementById("auditSummary").textContent = config.summary;
document.getElementById("tabReported").classList.toggle("is-active", view === "reported");
document.getElementById("tabVerified").classList.toggle("is-active", view === "verified");
}
setAuditView("reported");
refreshTasks()
.then(() => resetEpisode())
.catch((error) => appendLog("[ERROR]", { message: String(error) }));
</script>
</body>
</html>