v0.7.9.2 — two things the table could hear that only one seat should
Both leaks were found while planning the common board (Gitea#20 step 1), and both are live multiplayer bugs with or without that display, so they are fixed now rather than with 0.8.0. `game.log` is one shared list and `linesSince(seat)` slices it with no per-seat filter, so every line reaches every player. It carried the SEED in the opening line of each multiplayer game — the whole future of the deal — and the NAME OF A CARD DRAWN BLIND from the face-down Home Office deck. Solitaire deliberately keeps both: a one-seat table has nobody to leak to, the seed is what a bug report quotes, and a player's own history naming their own draw is the record. A Department slot is face up and stays named. The drawer still learns their card through `justDrawn`, which already goes to that seat alone. Neither was found by a test. Every test in `redaction.test.ts` passes an empty log, so the whole of narration has sat outside the redaction net since the net was built. Both now have tests there; TODO #91 carries what is still owed and supersedes #78, which described a gap that had already been closed and never mentioned this one. `docs/rules/` had no current description of the game, and `content.ts` named `card-reference.md` as the file that carries what the cards say — a file whose own banner says not to use its numbers, describing the v0.4.5 deck where 3/4 is a Mail-Express with three coaches. Every file in that directory is a deliberate historical record, so none of them is rewritten. `as-built.md` is new and GENERATED from the same catalogues the engine instantiates from, with a test that re-runs the generator and fails when the checked-in file disagrees. A hand-written replacement would have drifted the same way, for the same reason. TODO.md: #32 closed — the playtest migration note did its job and the jump is made; the durable fact it carried is kept. #78 retired in favour of #91. The "play it at a table" section now records that 0.7.4-0.7.9 were test-run without change requests, and that more testing comes at the end of the 0.7.9 series. 897 tests pass, up from 891. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E3Qk7uresKCHksdZajXCLg
This commit is contained in:
co-authored by
Claude Opus 5
parent
7ade60e21f
commit
819996faa2
@@ -19,6 +19,71 @@ page as `v0.1.0 · <sha> · <date>`, so what is deployed can always be identifie
|
||||
|
||||
---
|
||||
|
||||
## 0.7.9.2 — 2026-09-07
|
||||
|
||||
Two multiplayer information leaks, and the documentation problem that let a wrong table sit in
|
||||
`docs/rules/` for several releases with the code pointing at it.
|
||||
|
||||
### The shared narration log was telling every seat things only one seat should know
|
||||
|
||||
Both found while planning the public common board (Gitea#20 step 1), and **both are live multiplayer
|
||||
bugs with or without that display** — which is why they are fixed here rather than waiting for
|
||||
0.8.0.
|
||||
|
||||
`game.log` is ONE list. `linesSince(seat)` (`server/session.ts:181`) slices it with no per-seat
|
||||
filter at all, so every line written there reaches every player. Two things were being written into
|
||||
it that should never have left the seat that caused them:
|
||||
|
||||
**The seed, in the opening line of every multiplayer game.** `competitive · 3 players · seed 4242`
|
||||
handed each player the entire future of the deal — every card order, every die roll.
|
||||
|
||||
**The name of a card drawn blind from the Home Office deck.** `Player Cy drew Red Flags from the
|
||||
Home Office deck`, to the whole table, from a face-down deck.
|
||||
|
||||
**Solitaire deliberately keeps both, and that is the rule rather than an exception.** A one-seat
|
||||
table has nobody to leak to; the seed in the log is what a bug report quotes — both of the issues
|
||||
fixed in 0.7.9.1 opened by naming it — and a solo player's own history naming their own draw is the
|
||||
record, not a leak. The rule is *do not tell the OTHER seats*, not *write less down*. A Department
|
||||
slot stays named for the same reason: those piles are face up, a discard goes onto one precisely so
|
||||
a rival can take it, so the card was public before it was drawn.
|
||||
|
||||
The drawing seat still learns what it got. `justDrawn` is the owner-only channel and `session.ts`
|
||||
already sends it to that seat alone, so hiding the name from the shared log costs the drawer nothing.
|
||||
The seed remains in `game.seed`, in every save and in the lobby record, so nothing administrative or
|
||||
replayable loses it.
|
||||
|
||||
**These were not found by a test. They were found by reading a plan.** Every test in
|
||||
`redaction.test.ts` passes `[]` for the narration log, so the whole of it has sat outside the
|
||||
redaction net since the net was built. Tests for both now live there, but two strings are not a net —
|
||||
TODO #91 carries what is still owed, and supersedes #78, which described a gap that had already been
|
||||
closed and never mentioned this one.
|
||||
|
||||
### `docs/rules/` had no current description of the game, and `content.ts` pointed at a superseded one
|
||||
|
||||
`content.ts` named `docs/rules/card-reference.md` as "the place that now carries what the cards say".
|
||||
That file opens with its own banner — **"⚠ SUPERSEDED… Do not use its numbers"** — and describes the
|
||||
v0.4.5 deck: twelve numbered trains, `3 / 4 | Mail-Express | 3 coaches, no caboose`, against a
|
||||
`content.ts` whose train 3 is the Express, two freight cars, `oneFreightPerLocation`. The code was
|
||||
sending readers to a table it had itself replaced.
|
||||
|
||||
Every file in `docs/rules/` turns out to be a historical record and says so: `rules-v0.1.md` is a
|
||||
faithful transcription of the prototype PDFs, `open-questions.md` is the gap tracker, `rules-v0.2.md`
|
||||
and `card-reference.md` both carry superseded banners. **So the fix is not to rewrite one of them** —
|
||||
the record is worth more intact than patched, and there was simply no current reference at all.
|
||||
|
||||
`docs/rules/as-built.md` is new and is **generated** — trains, Mainline cards, Offices, freight
|
||||
facilities, modifiers and track, emitted from the same exported catalogues the engine instantiates
|
||||
from, by `scripts/build-card-reference.ts` (`npm run build:cards`).
|
||||
`test/card-reference.test.ts` re-runs the generator and asserts the checked-in file matches, so
|
||||
changing a card face without regenerating turns the suite red.
|
||||
|
||||
**A hand-written replacement would have drifted exactly the same way**, and for the same reason:
|
||||
nothing fails when a table falls behind a constant. That is the whole lesson of the file it replaces.
|
||||
|
||||
897 tests pass, up from 891.
|
||||
|
||||
---
|
||||
|
||||
## 0.7.9.1 — 2026-09-07
|
||||
|
||||
Two playtest bugs from one session (seed 550943578). Both were reported as the game getting a rule
|
||||
|
||||
Reference in New Issue
Block a user