cvpfus Codex commited on
Commit ·
d1b4ad4
1
Parent(s): eee651b
Render judge runbook in session panel
Browse filesCo-authored-by: Codex <codex@openai.com>
- FIELD_NOTES.md +1 -1
- README.md +2 -2
- SUBMISSION.md +1 -1
- scripts/verify.py +4 -0
- static/app.css +49 -2
- static/app.js +33 -0
- static/index.html +6 -1
FIELD_NOTES.md
CHANGED
|
@@ -28,7 +28,7 @@ The app exposes the same budget through `/api/model-budget`, including numeric `
|
|
| 28 |
|
| 29 |
Runtime setup is also data-backed. `/api/runtime-setup` lists the app command, llama.cpp launch command, model-specific runtime paths, environment values, and fallbacks. The session panel renders a compact version so the demo can distinguish real model wiring from deterministic safety nets.
|
| 30 |
|
| 31 |
-
The judge runbook lives at `/api/demo-script`. It keeps the live presentation repeatable by pairing visible actions with API checks for health, model budget, runtime setup, runtime status, image descriptions, reader narration, and speech.
|
| 32 |
|
| 33 |
Submission readiness lives at `/api/submission-readiness`. It aggregates the demo-critical checks into one payload: model budget, award evidence, custom frontend assets, runtime setup, accessibility audit, image receipts, and executable demo API checks.
|
| 34 |
|
|
|
|
| 28 |
|
| 29 |
Runtime setup is also data-backed. `/api/runtime-setup` lists the app command, llama.cpp launch command, model-specific runtime paths, environment values, and fallbacks. The session panel renders a compact version so the demo can distinguish real model wiring from deterministic safety nets.
|
| 30 |
|
| 31 |
+
The judge runbook lives at `/api/demo-script` and is rendered in the session panel. It keeps the live presentation repeatable by pairing visible actions with API checks for health, model budget, runtime setup, runtime status, image descriptions, reader narration, and speech.
|
| 32 |
|
| 33 |
Submission readiness lives at `/api/submission-readiness`. It aggregates the demo-critical checks into one payload: model budget, award evidence, custom frontend assets, runtime setup, accessibility audit, image receipts, and executable demo API checks.
|
| 34 |
|
README.md
CHANGED
|
@@ -75,7 +75,7 @@ The verifier checks syntax, static assets, Space metadata consistency, determini
|
|
| 75 |
|
| 76 |
`/api/runtime-setup` exposes the commands, environment values, and fallback paths used for the model stack so the demo can be reproduced from the same data the UI displays.
|
| 77 |
|
| 78 |
-
`/api/demo-script` exposes a compact judge runbook with the visible actions and API checks that prove the submission claims.
|
| 79 |
|
| 80 |
`/api/accessibility-audit` exposes structured evidence for semantic reading order, keyboard navigation, reader cursor state, shortcut safety, live narration, image alt text, transcript review, user-controlled playback, and fallback resilience.
|
| 81 |
|
|
@@ -120,7 +120,7 @@ Navigation commands interrupt current speech before starting the next request, m
|
|
| 120 |
|
| 121 |
Reader-brain, image-description, speech, and image-generation responses include `elapsed_ms`. The session panel and transcript show recent latency so the Field Notes can discuss responsiveness with concrete numbers.
|
| 122 |
|
| 123 |
-
The session panel
|
| 124 |
|
| 125 |
A submission-readiness panel reads `/api/submission-readiness`, giving judges one compact rollup of the claims the live app can prove.
|
| 126 |
|
|
|
|
| 75 |
|
| 76 |
`/api/runtime-setup` exposes the commands, environment values, and fallback paths used for the model stack so the demo can be reproduced from the same data the UI displays.
|
| 77 |
|
| 78 |
+
`/api/demo-script` exposes a compact judge runbook with the visible actions and API checks that prove the submission claims. The session panel renders those actions as the Judge Runbook.
|
| 79 |
|
| 80 |
`/api/accessibility-audit` exposes structured evidence for semantic reading order, keyboard navigation, reader cursor state, shortcut safety, live narration, image alt text, transcript review, user-controlled playback, and fallback resilience.
|
| 81 |
|
|
|
|
| 120 |
|
| 121 |
Reader-brain, image-description, speech, and image-generation responses include `elapsed_ms`. The session panel and transcript show recent latency so the Field Notes can discuss responsiveness with concrete numbers.
|
| 122 |
|
| 123 |
+
The session panel renders the judge runbook from `/api/demo-script`, plus manifest-backed evidence for Tiny Titan, Llama Champion, Off-Brand, and Field Notes. A model-budget panel reads `/api/model-budget` so judges can see each role's parameter count in the live app.
|
| 124 |
|
| 125 |
A submission-readiness panel reads `/api/submission-readiness`, giving judges one compact rollup of the claims the live app can prove.
|
| 126 |
|
SUBMISSION.md
CHANGED
|
@@ -31,7 +31,7 @@ The prototype is designed for a live hackathon demo: every model-facing path has
|
|
| 31 |
1. Open the article and show that the app is a custom article interface, not a stock chatbot page.
|
| 32 |
2. Turn on screen-reader mode and press `Space` or `Next` to narrate the first semantic node.
|
| 33 |
3. Use `Heading`, `Image`, and `Summary` to navigate by article meaning instead of by raw page order.
|
| 34 |
-
4. Show the session panel: transcript, runtime readiness, latency,
|
| 35 |
5. Mention that `/api/demo-script` exposes the same judge runbook as structured data.
|
| 36 |
|
| 37 |
## Evidence endpoints
|
|
|
|
| 31 |
1. Open the article and show that the app is a custom article interface, not a stock chatbot page.
|
| 32 |
2. Turn on screen-reader mode and press `Space` or `Next` to narrate the first semantic node.
|
| 33 |
3. Use `Heading`, `Image`, and `Summary` to navigate by article meaning instead of by raw page order.
|
| 34 |
+
4. Show the session panel: transcript, runtime readiness, latency, judge runbook, award evidence, model budget, and runtime plan.
|
| 35 |
5. Mention that `/api/demo-script` exposes the same judge runbook as structured data.
|
| 36 |
|
| 37 |
## Evidence endpoints
|
scripts/verify.py
CHANGED
|
@@ -38,8 +38,10 @@ def verify_static_assets() -> None:
|
|
| 38 |
assert_true('data-reader-type="image"' in index_html, "Article should mark image reader nodes")
|
| 39 |
assert_true('aria-live="polite"' in index_html, "Article should expose an aria-live narration region")
|
| 40 |
assert_true("transcriptLog" in index_html, "Article should expose a visible transcript log")
|
|
|
|
| 41 |
assert_true("imageReceiptList" in index_html, "Article should expose generated image receipts")
|
| 42 |
assert_true("submissionReadinessList" in index_html, "Article should expose submission readiness checks")
|
|
|
|
| 43 |
assert_true("function haltPlayback" in app_js, "Reader controls should expose a shared playback halt helper")
|
| 44 |
assert_true(
|
| 45 |
"haltPlayback({ clearAutoAdvance: false });" in app_js,
|
|
@@ -200,6 +202,8 @@ def verify_routes() -> None:
|
|
| 200 |
assert_true("speedValue" in home.text, "Home route should include speed value output")
|
| 201 |
assert_true("autoAdvanceControl" in home.text, "Home route should include auto-advance control")
|
| 202 |
assert_true("transcriptLog" in home.text, "Home route should include transcript log")
|
|
|
|
|
|
|
| 203 |
assert_true("awardEvidenceList" in home.text, "Home route should include award evidence list")
|
| 204 |
assert_true("submissionReadinessStatus" in home.text, "Home route should include submission readiness status")
|
| 205 |
assert_true("submissionReadinessList" in home.text, "Home route should include submission readiness list")
|
|
|
|
| 38 |
assert_true('data-reader-type="image"' in index_html, "Article should mark image reader nodes")
|
| 39 |
assert_true('aria-live="polite"' in index_html, "Article should expose an aria-live narration region")
|
| 40 |
assert_true("transcriptLog" in index_html, "Article should expose a visible transcript log")
|
| 41 |
+
assert_true("demoScriptList" in index_html, "Article should expose the judge demo runbook")
|
| 42 |
assert_true("imageReceiptList" in index_html, "Article should expose generated image receipts")
|
| 43 |
assert_true("submissionReadinessList" in index_html, "Article should expose submission readiness checks")
|
| 44 |
+
assert_true("loadDemoScript" in app_js, "Frontend should render the structured demo script")
|
| 45 |
assert_true("function haltPlayback" in app_js, "Reader controls should expose a shared playback halt helper")
|
| 46 |
assert_true(
|
| 47 |
"haltPlayback({ clearAutoAdvance: false });" in app_js,
|
|
|
|
| 202 |
assert_true("speedValue" in home.text, "Home route should include speed value output")
|
| 203 |
assert_true("autoAdvanceControl" in home.text, "Home route should include auto-advance control")
|
| 204 |
assert_true("transcriptLog" in home.text, "Home route should include transcript log")
|
| 205 |
+
assert_true("demoScriptStatus" in home.text, "Home route should include demo script status")
|
| 206 |
+
assert_true("demoScriptList" in home.text, "Home route should include demo script list")
|
| 207 |
assert_true("awardEvidenceList" in home.text, "Home route should include award evidence list")
|
| 208 |
assert_true("submissionReadinessStatus" in home.text, "Home route should include submission readiness status")
|
| 209 |
assert_true("submissionReadinessList" in home.text, "Home route should include submission readiness list")
|
static/app.css
CHANGED
|
@@ -286,10 +286,18 @@ dd {
|
|
| 286 |
margin-top: 22px;
|
| 287 |
}
|
| 288 |
|
| 289 |
-
.award-header
|
|
|
|
| 290 |
margin-top: 22px;
|
| 291 |
}
|
| 292 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
.submission-header {
|
| 294 |
display: flex;
|
| 295 |
align-items: center;
|
|
@@ -318,7 +326,8 @@ dd {
|
|
| 318 |
.budget-header span,
|
| 319 |
.runtime-header span,
|
| 320 |
.image-receipt-header span,
|
| 321 |
-
.submission-header span
|
|
|
|
| 322 |
color: var(--accent-strong);
|
| 323 |
font-size: 0.76rem;
|
| 324 |
font-weight: 850;
|
|
@@ -374,6 +383,13 @@ dd {
|
|
| 374 |
list-style: none;
|
| 375 |
}
|
| 376 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 377 |
.award-list li {
|
| 378 |
border: 1px solid var(--line);
|
| 379 |
border-radius: 8px;
|
|
@@ -381,6 +397,37 @@ dd {
|
|
| 381 |
background: var(--surface);
|
| 382 |
}
|
| 383 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
.budget-list {
|
| 385 |
display: grid;
|
| 386 |
gap: 8px;
|
|
|
|
| 286 |
margin-top: 22px;
|
| 287 |
}
|
| 288 |
|
| 289 |
+
.award-header,
|
| 290 |
+
.demo-script-header {
|
| 291 |
margin-top: 22px;
|
| 292 |
}
|
| 293 |
|
| 294 |
+
.demo-script-header {
|
| 295 |
+
display: flex;
|
| 296 |
+
align-items: center;
|
| 297 |
+
justify-content: space-between;
|
| 298 |
+
gap: 10px;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
.submission-header {
|
| 302 |
display: flex;
|
| 303 |
align-items: center;
|
|
|
|
| 326 |
.budget-header span,
|
| 327 |
.runtime-header span,
|
| 328 |
.image-receipt-header span,
|
| 329 |
+
.submission-header span,
|
| 330 |
+
.demo-script-header span {
|
| 331 |
color: var(--accent-strong);
|
| 332 |
font-size: 0.76rem;
|
| 333 |
font-weight: 850;
|
|
|
|
| 383 |
list-style: none;
|
| 384 |
}
|
| 385 |
|
| 386 |
+
.demo-script-list {
|
| 387 |
+
display: grid;
|
| 388 |
+
gap: 10px;
|
| 389 |
+
margin: 12px 0 0;
|
| 390 |
+
padding-left: 20px;
|
| 391 |
+
}
|
| 392 |
+
|
| 393 |
.award-list li {
|
| 394 |
border: 1px solid var(--line);
|
| 395 |
border-radius: 8px;
|
|
|
|
| 397 |
background: var(--surface);
|
| 398 |
}
|
| 399 |
|
| 400 |
+
.demo-script-list li {
|
| 401 |
+
border: 1px solid var(--line);
|
| 402 |
+
border-radius: 8px;
|
| 403 |
+
padding: 10px 12px;
|
| 404 |
+
background: var(--surface);
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
.demo-script-title {
|
| 408 |
+
display: flex;
|
| 409 |
+
align-items: center;
|
| 410 |
+
justify-content: space-between;
|
| 411 |
+
gap: 8px;
|
| 412 |
+
font-size: 0.82rem;
|
| 413 |
+
font-weight: 850;
|
| 414 |
+
text-transform: uppercase;
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
.demo-script-title span:last-child {
|
| 418 |
+
border-radius: 999px;
|
| 419 |
+
background: rgba(31, 111, 104, 0.12);
|
| 420 |
+
color: var(--accent-strong);
|
| 421 |
+
padding: 2px 8px;
|
| 422 |
+
font-size: 0.7rem;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
.demo-script-list p {
|
| 426 |
+
margin: 6px 0 0;
|
| 427 |
+
color: var(--muted);
|
| 428 |
+
font-size: 0.82rem;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
.budget-list {
|
| 432 |
display: grid;
|
| 433 |
gap: 8px;
|
static/app.js
CHANGED
|
@@ -17,6 +17,8 @@ const autoAdvanceControl = document.querySelector("#autoAdvanceControl");
|
|
| 17 |
const transcriptLog = document.querySelector("#transcriptLog");
|
| 18 |
const copyTranscriptButton = document.querySelector("#copyTranscriptButton");
|
| 19 |
const clearTranscriptButton = document.querySelector("#clearTranscriptButton");
|
|
|
|
|
|
|
| 20 |
const awardEvidenceList = document.querySelector("#awardEvidenceList");
|
| 21 |
const submissionReadinessStatus = document.querySelector("#submissionReadinessStatus");
|
| 22 |
const submissionReadinessList = document.querySelector("#submissionReadinessList");
|
|
@@ -226,6 +228,36 @@ async function loadAwardEvidence() {
|
|
| 226 |
}
|
| 227 |
}
|
| 228 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
async function loadSubmissionReadiness() {
|
| 230 |
try {
|
| 231 |
const payload = await postJson("/api/submission-readiness");
|
|
@@ -683,6 +715,7 @@ controls.play.addEventListener("click", () => {
|
|
| 683 |
});
|
| 684 |
|
| 685 |
loadManifest();
|
|
|
|
| 686 |
loadAwardEvidence();
|
| 687 |
loadSubmissionReadiness();
|
| 688 |
loadModelBudget();
|
|
|
|
| 17 |
const transcriptLog = document.querySelector("#transcriptLog");
|
| 18 |
const copyTranscriptButton = document.querySelector("#copyTranscriptButton");
|
| 19 |
const clearTranscriptButton = document.querySelector("#clearTranscriptButton");
|
| 20 |
+
const demoScriptStatus = document.querySelector("#demoScriptStatus");
|
| 21 |
+
const demoScriptList = document.querySelector("#demoScriptList");
|
| 22 |
const awardEvidenceList = document.querySelector("#awardEvidenceList");
|
| 23 |
const submissionReadinessStatus = document.querySelector("#submissionReadinessStatus");
|
| 24 |
const submissionReadinessList = document.querySelector("#submissionReadinessList");
|
|
|
|
| 228 |
}
|
| 229 |
}
|
| 230 |
|
| 231 |
+
async function loadDemoScript() {
|
| 232 |
+
try {
|
| 233 |
+
const payload = await postJson("/api/demo-script");
|
| 234 |
+
demoScriptStatus.textContent = `${payload.estimated_minutes} min`;
|
| 235 |
+
demoScriptList.innerHTML = payload.actions
|
| 236 |
+
.map((item) => `
|
| 237 |
+
<li>
|
| 238 |
+
<div class="demo-script-title">
|
| 239 |
+
<span>${escapeHtml(item.label)}</span>
|
| 240 |
+
<span>${escapeHtml(`Step ${item.step}`)}</span>
|
| 241 |
+
</div>
|
| 242 |
+
<p>${escapeHtml(item.action)}</p>
|
| 243 |
+
<p>${escapeHtml(item.evidence)}</p>
|
| 244 |
+
</li>
|
| 245 |
+
`)
|
| 246 |
+
.join("");
|
| 247 |
+
} catch {
|
| 248 |
+
demoScriptStatus.textContent = "Unavailable";
|
| 249 |
+
demoScriptList.innerHTML = `
|
| 250 |
+
<li>
|
| 251 |
+
<div class="demo-script-title">
|
| 252 |
+
<span>Judge runbook</span>
|
| 253 |
+
<span>offline</span>
|
| 254 |
+
</div>
|
| 255 |
+
<p>The structured demo script is unavailable.</p>
|
| 256 |
+
</li>
|
| 257 |
+
`;
|
| 258 |
+
}
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
async function loadSubmissionReadiness() {
|
| 262 |
try {
|
| 263 |
const payload = await postJson("/api/submission-readiness");
|
|
|
|
| 715 |
});
|
| 716 |
|
| 717 |
loadManifest();
|
| 718 |
+
loadDemoScript();
|
| 719 |
loadAwardEvidence();
|
| 720 |
loadSubmissionReadiness();
|
| 721 |
loadModelBudget();
|
static/index.html
CHANGED
|
@@ -122,8 +122,13 @@
|
|
| 122 |
<button id="clearTranscriptButton" type="button">Clear</button>
|
| 123 |
</div>
|
| 124 |
<ol id="transcriptLog" class="transcript-log" aria-label="Narration transcript"></ol>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
<div class="award-header">
|
| 126 |
-
<h3>
|
| 127 |
</div>
|
| 128 |
<ul id="awardEvidenceList" class="award-list" aria-label="Hackathon bonus evidence"></ul>
|
| 129 |
<div class="submission-header">
|
|
|
|
| 122 |
<button id="clearTranscriptButton" type="button">Clear</button>
|
| 123 |
</div>
|
| 124 |
<ol id="transcriptLog" class="transcript-log" aria-label="Narration transcript"></ol>
|
| 125 |
+
<div class="demo-script-header">
|
| 126 |
+
<h3>Judge Runbook</h3>
|
| 127 |
+
<span id="demoScriptStatus">Loading</span>
|
| 128 |
+
</div>
|
| 129 |
+
<ol id="demoScriptList" class="demo-script-list" aria-label="Judge demo runbook"></ol>
|
| 130 |
<div class="award-header">
|
| 131 |
+
<h3>Award Evidence</h3>
|
| 132 |
</div>
|
| 133 |
<ul id="awardEvidenceList" class="award-list" aria-label="Hackathon bonus evidence"></ul>
|
| 134 |
<div class="submission-header">
|