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 #220

shipped production is serving it opened this has it
opened this

#219 is the second time a generated file has broken this repository, and the first time it took production with it. The build deletes stale bundles when it runs; a merge does not run the build. Two branches that each rebuild the shooter produce two differently-named files, git keeps both, each branch's check was green, and the merge is a tree that cannot boot. The quieter half of the same failure is worse: a merge that keeps only one of them leaves a single, valid-looking, stale bundle, and nothing in the suite would say a word.

The repository has the pieces to make this impossible to miss: the build is a function (write in scripts/build.ts) that takes a directory, and it is fast — a full build of all three games into a temporary directory measured 71 ms here, including Bun's start-up.

Done looks like

  • [ ] A test builds every game into a temporary directory and asserts that what is committed under static/ is exactly what the sources produce: the same set of names, one per game, and the same content. A tree with two shooter bundles fails it, and so does a tree with one that is out of date.
  • [ ] The failure message is the command: "run bun run scripts/build.ts and commit what it writes", with what was found and what was expected — the same voice bundleOf already uses.
  • [ ] It writes nothing into the repository: the temporary directory is cleaned up, static/ is read-only to this test, and the pull says what the test adds to bun test in milliseconds.
  • [ ] The test is reachable from the check forge.json runs, so it fails a pull rather than a deploy.
  • [ ] The pull weighs, in a short paragraph, whether the stronger fix is worth it — one path per game on disk (static/app.js) with the content hash carried in the URL and a manifest the server reads at boot, so two branches that both rebuild conflict in git instead of merging into rubble. Either ship it or say why the test is enough; do not leave the question unasked.
  • [ ] Whatever lands, the caching contract is unchanged: a bundle URL stays content-addressed, immutable and a year long, /example's measured sizes (#207) still read the files they describe, and the ceilings in src/games.ts still hold.

Files I expect to change

scripts/build.ts and a test beside it (scripts/build.test.ts), possibly src/games.ts, src/server.ts and src/pages/example.ts if the stronger fix is taken, and src/engine/GUIDE.md or README.md wherever the naming of a bundle is described.

Risks

  • A rebuild must be deterministic or this test is a flake. Prove it in the pull: build twice, same hashes. If Bun's output is not byte-stable across runs, compare what the bundle is rather than its bytes, and say so.
  • It waits for #219 only because the tree has to be green before a test about the tree means anything.
  • Keep the cost honest: if the check grows by more than a tenth of a second, say so; 71 ms is the measurement to beat.

Suggested: Torque — a guard with a number attached, and the alternative design to weigh.

commented

It happened again, one day later. main at 8a4655f carries static/app.07fd7f4c9f.js and static/app.d0901a691f.js — #232 and #235, neither rebased on the other — the server throws before it listens, and neither file is the tree (a rebuild writes app.ae4ebe5234.js, 95,029 / 37,531). #237 is the four-minute repair; this issue is the reason there should not be a third. Two occurrences in two days is the measurement this issue was missing: it is not a tidy-up, it is the check that stops a merge taking production down. The quiet variant — a merge that keeps one file and it is the stale one — still passes the suite today without a word.

commented

Two things since this was written. First, the measurement: three outages in three days — main now carries three shooter bundles at once. Second, #241, which I have put in front of this one: it proposes removing the artifact from git entirely and building into FORGE_APP_DATA at boot, which makes this class of failure impossible rather than visible. If #241 lands, what is left here is the one checkbox that survives — two builds of one tree agree — and whoever comes back to this should close it if that is covered. If #241 is judged too big, say so here and take this instead; what must not happen is a fourth outage with both still open.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs