Stamp the build into the output, not into a tracked file

The stamping scheme was wrong in a way worth recording. tools/stamp.js rewrote
src/build-info.js before every serve and build, so after each commit the
committed stamp named the *previous* commit — as it does right now, reading
76072ed+ while HEAD is 5c1784d — and the next serve rewrote it and dirtied the
tree again. A generated value does not belong in a tracked file if anything
routinely regenerates it.

src/build-info.js is now permanent and reads `commit: 'dev'`. tools/build.js
substitutes the real commit into the bundled output only, and fails loudly if
the substitution finds nothing to replace. So dist/theladder.html names the
commit that produced it, running from source honestly reads "0.3.0 · dev", and
the working tree never churns. tools/stamp.js is gone and `npm run serve` is a
plain static server again.

Also here, for picking this up later: a "Where things stand" section in the
README with the five open questions in the order they are likely to matter —
whether money stops mattering late, the negotiation gate that four early options
sit behind, the feedback widget nobody uses, how thin Dispatch is next to the
mailroom, and third-tier versus second-pack.

121 tests. docs/DECISIONS.md §25 corrected to describe what the code now does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VMSFHyVPitUoosW5wyEADj
This commit is contained in:
JesseMarkowitz
2026-09-10 06:12:58 -04:00
co-authored by Claude Opus 5
parent 5c1784d990
commit 4957c24e31
6 changed files with 76 additions and 64 deletions
+25 -2
View File
@@ -53,8 +53,8 @@ npm run serve # then open http://localhost:8080
The game plays from the keyboard: Enter takes the focused option, Enter again
moves to the next day, and Tab / Shift+Tab pick a different option. The top of
every screen names the game, the pack, your current title, and the version and
commit you are running.
every screen names the game, the pack, your current title, and the build —
`0.3.0 · dev` when running from source, and the commit it came from when built.
A server is needed during development because browsers refuse ES module imports
over `file://`. If port 8080 is taken, run `python3 -m http.server <port>`
@@ -88,6 +88,29 @@ real person did, including anything they typed into the feedback box.
There are no runtime dependencies and no build step for development. Node is
used only to run the tests, the single-file build, and the log analyser.
## Where things stand
The MVP is complete and has survived three playtests. Two tiers, 31 events, a
retrospective, saves, and a feedback log that has already found one real bug.
Open questions, in the order they are likely to matter:
- **Does money stop mattering late?** A careful player ends around $8,300 over
200 turns. Tuning has been corrected twice from playtest logs and should be
judged from a session, not from simulated play — that is how the last trap got
in.
- **`skills.negotiation >= 15` gates four different early options.** The logs
show players bouncing off it repeatedly in the first thirty turns. It is
probably set too high for how slowly the skill grows.
- **Nobody uses the feedback widget.** Zero ratings across three sessions. The
locked-gate data in the log has been more useful than anything typed; the
widget may need to be more present, or may not need to exist.
- **Dispatch is eleven events against the mailroom's nineteen.** It passes the
variety guard, but it has had far less play than the mailroom.
- **The third tier, or the second content pack.** Promotion working entirely as
data is decent evidence the engine/content split holds; a second *setting*
would be the proof.
## Layout
```