Public: anyone can read this; the crew can change it.

forked from trevato/cs

What the trainer writes into the repository is under test: the card the page boasts, and the flags that write it #206

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`src/client/weights.ts` is generated and was rendered straight into the first paint of `/` with nothing checking it; this pull puts all three pieces under test and leaves the page's HTML byte-identical.

shipped production is serving it deploy ae07c2d

opened this

src/client/weights.ts is generated and was rendered straight into the first paint of / with nothing checking it; this pull puts all three pieces under test and leaves the page's HTML byte-identical.

src/client/weights.test.ts gains the card: a faults(card) helper that returns one complaint per bad field, and a test per rule that both reads today's values and corrupts each field it governs — every field present and of its type, rates whole and 0–100 (999 fails), counts whole and positive, trainedAt an ISO date that exists and has happened, envSteps a whole number of decisions, and minutes/stepsPerSecond agreeing with envSteps to a tenth (an honest retrain at twice the speed or half the length stays green; a tenfold minutes does not). The packed weights are checked against OBS_SIZE, HEADS, one scale per tensor and a base64 string that decodes to exactly paramCount(shape) bytes.

src/pages/game.test.ts is new. The policy paragraph is now policyHtml(card) and gamePage takes an optional card — the test renders the page with a card nobody trained and asserts every number in the prose moved with it and not one of today's is left behind, which a number typed into the template by hand could not do; the prose with the digits masked is identical either way. Rendering with the real card produces exactly the bytes it did before this pull.

scripts/train.ts grew a boundary: parseOptions(argv) returns an Options and refuses a NaN, a negative, a zero count, a missing value, a bare word or an unknown flag with a sentence and exit 2, instead of reading process.argv from inside the run and training twelve minutes on NaN. --out names the one path the run writes (default src/client/weights.ts). scripts/train.test.ts checks that as data in and data out, plus weightsModule: the header, deterministic formatting, that the transpiled text imports and exports what weights.ts exports, and — the one that matters — that handed today's CARD and PACKED it reproduces the committed file character for character.

Nothing here trains: the two new files and the card tests add about 0.17 s, the seeded duels stay in src/rl/learned.test.ts, and bun run test (typecheck + 911 tests) is green in ~15 s, the same as on main. The README's bots section now says what the card is — one run's measurement, written by the trainer, never re-run on a push — and what each test does hold. I left bots.test.ts's older six-line card check where it is; it is weaker but not wrong, and deleting it was not this issue's.

🤖 Generated with Claude Code

Closes #111

commented

main is merged into this branch and the one conflict, src/pages/game.ts, is resolved keeping both sides whole. main had added the pending-result line under the leaderboard (NOTHING_POSTED / SAVED_LINE) and exported STYLE so src/server.ts can hash it into this page's style-src; this branch had turned the policy paragraph into policyHtml(card) and given gamePage a card option so a test can render a card nobody trained. The merged file has one import line carrying NOTHING_POSTED and type Card together, SAVED_LINE where main put it, and the widened gamePage signature with card = CARD — nothing from either change was dropped, and no third behaviour was invented in the merge. The README merged on its own; main's audio paragraph and this branch's section on the card being a measurement sit in different places.

What to look at: bun run test — typecheck plus 947 tests across 90 files — passes on the merge commit, and a booted server answers / with 200, the hashed style-src 'self' 'sha256-…' (no unsafe-inline), the saved line's first-paint sentence, and the card's numbers in the prose, which is the pair of features that conflicted proving they work at the same time. On the preview, the page under the leaderboard should say rounds are saved as they are played, and the bots paragraph should still read 8,192,000 ticks.

🤖 Generated with Claude Code

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs