Capture harness, fixture verification, CI, and the public README

The site does no live inference. Rollouts are captured once against spark-1 and
replayed at their recorded wall-clock — a public demo with no auth cannot hold
an API key, and a recorded run can be scrubbed, permalinked, blind-compared and
verified in ways a live one cannot. What stops it being a video is that the
browser re-derives every number from the recorded moves.

verify_fixtures.py is the Python half of that: it replays every committed
fixture through the engine and reproduces its own rewards. All 16 land at
delta 0.0. A fixture that cannot be regenerated is a claim with no receipt.

First real measurement, thinking off, 8 seeds: solved 0/8. The model repeats
guesses it has already played, invents words (trape, slith, postt, boomy),
and contradicts its own feedback — consistency 0.09 to 0.17. That is the
published failure taxonomy showing up in our own data on the first run, and it
is why `consistency` is a reward component rather than a footnote.

A capture failure is recorded as a turn with a null reply, never dropped. A
capture that silently discarded failed turns would be reporting a better model
than the one that ran.

CI gates both halves and four things that fail silently in production: the word
lists must rebuild byte-identically, the prerendered routes must carry their own
baked og tags (crawlers do not run JS, so without them every shared link
previews as the homepage), no blob: URL may reach the bundle (the site's CSP has
no worker-src, so it falls back to default-src 'self' and a blob worker is
blocked with no error), and the conformance digest must match across languages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019mt6sHQHEnEYrJZvoMCJSB
This commit is contained in:
karti-ai
2026-08-28 15:47:31 -07:00
parent 69607fbfe9
commit 408ce4a525
43 changed files with 5279 additions and 136 deletions
+58 -18
View File
@@ -294,7 +294,7 @@ function codeSpans(src) {
* @param {'{' | '['} open
* @returns {string | null}
*/
export function literalAfter(src, anchor, open = '{') {
export function literalsAfter(src, anchor, open = '{') {
const flags = anchor.flags.includes('g') ? anchor.flags : `${anchor.flags}g`;
const re = new RegExp(anchor.source, flags);
const spans = codeSpans(src);
@@ -302,18 +302,29 @@ export function literalAfter(src, anchor, open = '{') {
const hit = spans.find((s) => offset >= s.start && offset < s.end);
return hit ? hit.code : true;
};
const found = [];
let match;
while ((match = re.exec(src)) !== null) {
// The anchor may legally match inside a comment or a string a docblock
// The anchor may legally match inside a comment or a string \u2014 a docblock
// that quotes `const meta = {`. Only a match in real code counts.
if (!isCode(match.index)) continue;
const from = src.indexOf(open, match.index + Math.max(match[0].length - 1, 0));
if (from === -1) continue;
const between = src.slice(match.index + match[0].length, from);
if (/[;=}]/.test(between)) continue;
return src.slice(from, scanBalanced(src, from));
const end = scanBalanced(src, from);
found.push({ text: src.slice(from, end), start: from, end });
// Skip past this literal so a nested anchor of the same name is not
// reported as a second, overlapping hit.
re.lastIndex = end;
}
return null;
return found;
}
/** First literal following `anchor`, or null. See {@link literalsAfter}. */
export function literalAfter(src, anchor, open = '{') {
const [first] = literalsAfter(src, anchor, open);
return first ? first.text : null;
}
/** Marker key on the stand-in an unresolvable identifier evaluates to. */
@@ -501,7 +512,10 @@ const VERTICAL_ANCHORS = [
const asVertical = (id, v) => ({
id,
title: v?.title ?? v?.label ?? v?.name ?? null,
description: v?.description ?? v?.blurb ?? v?.tagline ?? v?.summary ?? null,
// `anxiety` is this repo's field for the one line a vertical page leads
// with, and it is the only prose in a VerticalEntry short enough to be a
// meta description.
description: v?.description ?? v?.blurb ?? v?.tagline ?? v?.summary ?? v?.anxiety ?? null,
});
/**
@@ -559,8 +573,14 @@ export function loadManifest() {
}
/** @type {Map<string, {runs: any[], extras: Record<string, any>}>} */
const byDemo = new Map();
const container =
raw && typeof raw === 'object' && !Array.isArray(raw) && raw.demos && typeof raw.demos === 'object' ? raw.demos : raw;
// Unwrap the two envelopes the shell's own reader accepts. `{runs: [...]}`
// has to be unwrapped BEFORE the record branch below, or "runs" is read as a
// demo slug and every real demo reports zero runs.
let container = raw;
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
if (raw.demos && typeof raw.demos === 'object') container = raw.demos;
else if (Array.isArray(raw.runs)) container = raw.runs;
}
if (Array.isArray(container)) {
// A flat array of runs, each carrying its own `demo`/`slug`.
@@ -706,12 +726,32 @@ export function discoverRoutePatterns() {
return [...patterns];
}
const DEMO_PARAMS = /^(slug|demo|demoSlug)$/;
const VERTICAL_PARAMS = /^(vertical|verticalId|sector|category)$/;
/**
* Which set fills a pattern's one parameter.
*
* Decided by the STATIC segment in front of it, not by the parameter's name.
* This router calls both of them `:slug` — `demos/:slug` and `verticals/:slug`
* — so a name-based reader confidently prerenders `/verticals/wordle`, twelve
* 404s, and no vertical pages at all.
*/
function fillFor(pattern) {
const head = pattern.replace(/^\/+/, '').split('/')[0]?.toLowerCase() ?? '';
if (/^(demos?|d)$/.test(head)) return 'demo';
if (/^(verticals?|v|sectors?)$/.test(head)) return 'vertical';
const param = pattern.match(/:([A-Za-z0-9_]+)/)?.[1] ?? '';
if (/^(vertical|verticalId|sector|category)$/.test(param)) return 'vertical';
if (/^(slug|demo|demoSlug|id)$/.test(param)) return 'demo';
return null;
}
/**
* Expands the router's patterns against the real data into concrete paths.
*
* Child paths are taken as written. This router nests everything exactly one
* level under `/`, so a child's `path` is already the full path; a second level
* of nesting would need the parent prefix joined on, and this would silently
* emit the wrong routes rather than fail. If you nest deeper, fix this.
*
* @param {{metas: Map<string, any>, verticals: {id: string}[]}} data
* @returns {{routes: {path: string, kind: string, slug?: string, id?: string}[], errors: string[]}}
*/
@@ -749,18 +789,18 @@ export function expandRoutes(data) {
errors.push(`route pattern "${pattern}" has more than one parameter; prerender cannot expand it.`);
continue;
}
const param = params[0];
const fill = (value, record) => add(pattern.replace(/:[A-Za-z0-9_]+\??/, value), record);
if (VERTICAL_PARAMS.test(param)) {
if (!verticalIds.length) errors.push(`route "${pattern}" needs verticals, but none were readable from src/content/verticals.ts.`);
for (const id of verticalIds) fill(id, { kind: 'vertical', id });
} else if (DEMO_PARAMS.test(param) || param === 'id') {
const fill = fillFor(pattern);
const substitute = (value) => pattern.replace(/:[A-Za-z0-9_]+\??/, value);
if (fill === 'vertical') {
if (!verticalIds.length) errors.push(`route "${pattern}" needs verticals, but none were readable from ${rel(VERTICALS_FILE)}.`);
for (const id of verticalIds) add(substitute(id), { kind: 'vertical', id });
} else if (fill === 'demo') {
if (!demoSlugList.length) errors.push(`route "${pattern}" needs demos, but no demo meta was readable under src/demos/.`);
for (const slug of demoSlugList) fill(slug, { kind: 'demo', slug });
for (const slug of demoSlugList) add(substitute(slug), { kind: 'demo', slug });
} else {
errors.push(
`route pattern "${pattern}" uses parameter ":${param}", which prerender cannot fill. ` +
'Name it :slug (a demo) or :vertical (a vertical), or teach scripts/_lib.mjs about it.',
`route pattern "${pattern}" has a parameter prerender cannot fill. Put it under /demos/ or ` +
'/verticals/, or teach fillFor() in scripts/_lib.mjs about it.',
);
}
}