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
Check · Review · Land · Live done — Landed and live in production.
`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
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
src/client/weights.tsis 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.tsgains the card: afaults(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,trainedAtan ISO date that exists and has happened,envStepsa whole number of decisions, and minutes/stepsPerSecondagreeing withenvStepsto 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 againstOBS_SIZE,HEADS, one scale per tensor and a base64 string that decodes to exactlyparamCount(shape)bytes.src/pages/game.test.tsis new. The policy paragraph is nowpolicyHtml(card)andgamePagetakes an optionalcard— 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.tsgrew a boundary:parseOptions(argv)returns anOptionsand 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 readingprocess.argvfrom inside the run and training twelve minutes onNaN.--outnames the one path the run writes (defaultsrc/client/weights.ts).scripts/train.test.tschecks that as data in and data out, plusweightsModule: the header, deterministic formatting, that the transpiled text imports and exports whatweights.tsexports, and — the one that matters — that handed today'sCARDandPACKEDit 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, andbun run test(typecheck + 911 tests) is green in ~15 s, the same as onmain. 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 leftbots.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