v0.7.9.8 — the test command did not typecheck, and the plan had gone stale
Housekeeping before v0.8.0: the answer to "anything else that should be looked at first". One real hole, one stale document, and my own leavings. #102 — `npm test` passed green on a type error. `pretest` ran `scripts/build-web.ts`, which invokes `tsc --ignoreConfig` against three web entry points, so it saw only what those three transitively import and under a WEAKER configuration than tsconfig.json — no `noUncheckedIndexedAccess`, no `exactOptionalPropertyTypes`, `--types ''`. It never saw `src/server/` or a single file under `test/`. Demonstrated rather than argued: a planted `const DELIBERATE_TYPE_ERROR: number = 'not a number';` in src/server/session.ts gives `npm run typecheck` a TS2322 and `npm test` a clean `# fail 0`. `pretest` is `tsc --noEmit && node scripts/build-web.ts` now, and the same error exits 1 with the tests never running. This mattered THIS week rather than generally: v0.8.0 is steps 2-7 of the common board — display stream, credentials, persistence, Chromium supervisor — which is almost entirely src/server/, exactly the half the test command could not see. #103 — the plan had drifted from the code it is the source for. docs/plans/jitsi-common-board.md was written 2026-08-27, still said "No implementation has been performed", and is what steps 2-7 get built from. Step 1 shipped across four releases since, so every "current code finding" under it described a fault that is now fixed — a document reading as present tense and nine days stale sends the next reader to fix things twice. Measured: its PublicFrame sketch lists four properties never built (protocolVersion, config, scoring, deckCounts) and omits 28 that exist, and the shape is the real difference — the implementation is FLAT where the plan grouped things into objects, so a renderer written from the sketch would not compile. The plan now says so at the top and at step 1, names src/sim/view.ts and the redaction allow-list as the authority, keeps the original sketch for its reasoning, and calls out `protocolVersion` as unbuilt rather than dropping it quietly — step 2 is the reconnecting display stream and is the first thing that would want one. One step-1 item is STRUCK OFF rather than built: "add the Red Flag holder to the public player projection". The premise does not hold here. `decks.redFlags` is written once, in setup.ts, from `optionalRules.emergencyToolbox`, and never again — `redFlag.play` emits `phaseEnded` and does not spend it — so every player holds one or none does, decided before the deal. A per-player `redFlagHeld` would be one already-public option copied N times, while telling every reader of the common board that it varies by player and might change mid-game. Worse than the absence. Pinned by test so it is not re-raised from the plan. Four dead imports removed, all mine: `HAND_LIMIT` left unused in apply.ts, view.ts and web/game.ts when 0.7.9.6 consolidated the three copies of the §6.2 test, and `actingPlayer` in web/game.ts, dead since 0.7.9.5 made `currentActor` delegate. Finding them re-measured #46: `tsc --noUnusedLocals` now reports 40, up from 29 on 2026-08-30. That entry's "without the flag this list simply regrows" is a measurement rather than a forecast now. The other 36 and the flag stay open. 946 tests pass, up from 943. No behaviour changes: three new tests pin an invariant, and the rest is a build command, dead imports and a document. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y5boPxP6JHRYMm8adXaF5R
This commit is contained in:
co-authored by
Claude Opus 5
parent
88a42ae9e2
commit
312e0301e0
@@ -388,3 +388,50 @@ describe('a dispatch device says whether it is still available today (#101)', ()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* THE RED FLAG HOLDER IS NOT A PER-PLAYER FACT, so it does not belong on the public player view.
|
||||
*
|
||||
* `docs/plans/jitsi-common-board.md` step 1 asks for one: "Add the Red Flag holder to the public
|
||||
* player projection. It is public game state but is currently absent from `Frame`", and its
|
||||
* `PublicPlayerView` carries `redFlagHeld: boolean`. Every other step-1 item shipped across v0.7.9.2
|
||||
* to v0.7.9.5; this one is STRUCK OFF instead, because the premise does not hold in this codebase.
|
||||
*
|
||||
* `decks.redFlags` is written in exactly one place — `setup.ts`, from
|
||||
* `config.optionalRules.emergencyToolbox` — and never again. There is no `.set` anywhere else, and
|
||||
* `redFlag.play` (the intent gated on holding one) emits a `phaseEnded` event and does not spend it.
|
||||
* So every player holds one or none of them does, decided before the first card is dealt.
|
||||
*
|
||||
* A `redFlagHeld` on each player would therefore be `optionalRules.emergencyToolbox` copied N times
|
||||
* — already on the public projection — while implying to every reader of the common board that it
|
||||
* varies by player and might change during a game. That is worse than the absence.
|
||||
*
|
||||
* This test exists so the plan item is not re-raised from the plan text: if the rule ever DOES
|
||||
* become per-player, this fails and the projection is the right place to look.
|
||||
*/
|
||||
describe('the Red Flag holding is the Emergency Toolbox option, not a per-player fact', () => {
|
||||
const dealt = (emergencyToolbox: boolean): GameState =>
|
||||
createGame({
|
||||
id: 'g',
|
||||
seed: 99,
|
||||
config: { ...config, optionalRules: { ...config.optionalRules, emergencyToolbox } },
|
||||
playerNames: ['Ann', 'Bob', 'Cy'],
|
||||
});
|
||||
|
||||
for (const toolbox of [true, false]) {
|
||||
it(`gives every player the same answer with the toolbox ${toolbox ? 'on' : 'off'}`, () => {
|
||||
const s = dealt(toolbox);
|
||||
const held = s.players.map((p) => s.decks.redFlags.get(p.index) === true);
|
||||
assert.deepEqual(held, [toolbox, toolbox, toolbox], 'the Red Flag has become a per-player fact');
|
||||
});
|
||||
}
|
||||
|
||||
it('is already public, through the option it comes from', () => {
|
||||
const pub = publicSnapshot(dealt(true));
|
||||
assert.equal(
|
||||
pub.optionalRules.emergencyToolbox,
|
||||
true,
|
||||
'a spectator cannot tell whether the hand limit is three or four',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user