Public: anyone can read this; the crew can change it.
forked from trevato/cs
A stale or duplicated bundle is a red suite, not a dead deploy: the committed static/ is proved to be what the sources build #282
Check · Review · Land · Live done — Landed and live in production.
`scripts/build.ts` gains `differences(built, dir)`: every way a directory is not what these sources build, as sentences that end in the command which fixes it — a file this tree builds that is not there, a file whose bytes are not the built bytes, a second file under a name that belongs to one ("*…holds 1 stale file for "app" beside app.92a7f64176.js: app.0123456789.js — whoever picks between them…
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
scripts/build.tsgainsdifferences(built, dir): every way a directory is not what these sources build, as sentences that end in the command which fixes it — a file this tree builds that is not there, a file whose bytes are not the built bytes, a second file under a name that belongs to one ("…holds 1 stale file for "app" beside app.92a7f64176.js: app.0123456789.js — whoever picks between them picks at random, so runbun run scripts/build.ts <dir>and compare again"). The determinism test inscripts/build.test.tsnow makes its second build in a child process, the way a deploy makes one, and assertsdifferenceshas nothing to say and that the directory holds exactly one file per game and per asset and nothing else; a new test asksgit ls-filesfor anything named by its own hash or filed understatic/and fails with thegit rm --cachedthat undoes it. It writes nothing into the repository — both builds go tomkdtempdirectories removed infinally.On whether the stronger fix is worth it: it already landed. #241 went further than the manifest this issue sketched — no generated file is in git at all, the server builds into
FORGE_APP_DATA/staticbefore it binds — so the checkbox about proving a committedstatic/matches the sources is moot, and what survived is the one this pull lands: two builds of one tree agree, now across processes rather than within one, plus a guard that stops the artifact coming back. I did not add a manifest or a fixedstatic/app.jspath; with nothing committed there is nothing for two branches to collide over, and a per-deploy build makes a stale preview impossible. Nothing about the caching contract moved: same content-addressed names, sameimmutableyear, same ceilings insrc/games.ts,/examplestill reads the files it describes.Determinism is proved, not assumed: two runs of
bun run scripts/build.tsinto separate directories are byte-identical (diff -rclean), so the wholecodeis compared and not just its hash. Cost, honestly:scripts/build.test.tsgoes from ~281 ms to ~384 ms — about +0.1 s, at the line the issue drew, and it is the child process's Bun start-up (a full build there measured 108 ms). Full suite: 1239 pass, 0 fail, ~30 s,bun run test(typecheck +bun test), which is whatforge.jsonruns. Both new tests were shown to fail on a broken tree — a stagedstatic/app.0123456789.jsfails the git guard by name, and thedifferencesunit test covers the loud duplicate, the quiet stale single file, the missing file and a file edited in place.🤖 Generated with Claude Code
Closes #220