Credibility pass: session residue swept from the rev-10 run

War-story comments become timeless constraints (carrier rule, boobytrap
tell, remove-curse prescription); the rev changelog reunites under
GameConfig.deckRev; three hand-copied cardless stack literals fold into
openCardlessStack; the visionstone one-edge loop is shared via
throughOneEdge with the edge-target hairpin exclusion stated; drain()
moves to test helpers and replaces four inline copies; the butt-head
sweep test loses its dead scaffolding and its expect(refused || true)
tautology and now asserts both branches; a process-named suite is
renamed for the behavior it pins; dead .bezel-spacer CSS and the fx
effect's fossilized cleanup story go. No behavior changes: 304 engine
tests pass, 36/36 ledgers replay, web typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
Eric Wagoner
2026-08-29 19:14:03 -04:00
co-authored by Claude Fable 5
parent f2af1e26f8
commit e93bcc15a2
11 changed files with 107 additions and 139 deletions
+3 -11
View File
@@ -3,7 +3,7 @@ import {
type CreatureState, applyCommand, activePlayer, boardView, creatureAt, type GameState, type PlayerId, createGame } from "../src/game";
import { cellKey, edgeKey, SIDES, stepTarget, type Cell, type Side } from "../src/board";
import type { CardInstance } from "../src/cards";
import { newExpansionGame as newGame, must, giveCard, toRound2, emptyNeighborCell, pushSustained } from "./helpers";
import { newExpansionGame as newGame, must, drain, giveCard, toRound2, emptyNeighborCell, pushSustained } from "./helpers";
/** Summon a creature next to its creator (round 2+, consumes the attack). */
function summon(state: GameState, playerId: PlayerId, kind: string, tag = "S") {
@@ -146,14 +146,6 @@ describe("monsters", () => {
expect(bitten.hand.length).toBe(6);
});
/** Rev 8: scorches open counteraction windows — wave them through. */
function drain(state: GameState): GameState {
while (state.stack) {
state = must(state, state.stack.waitingOn, { type: "pass" });
}
return state;
}
it("the fire imp scorches on sight and dies only to water", () => {
let { state } = newGame();
state = toRound2(state);
@@ -824,7 +816,7 @@ describe("the imp's fire is a spell (rev 8)", () => {
expect(state.stack?.kind).toBe("spell");
giveCard(state, "mark", "full-shield", "FS", 0);
state = must(state, "mark", { type: "counteract", instanceId: "full-shield#FS" });
while (state.stack) state = must(state, state.stack.waitingOn, { type: "pass" });
state = drain(state);
expect(state.players.find((p) => p.id === "mark")!.life).toBe(15);
});
@@ -845,7 +837,7 @@ describe("the imp's fire is a spell (rev 8)", () => {
state = r.state;
if (!state.stack) state = must(state, "imp-owner", { type: "endTurn", draw: 0 });
expect(state.stack?.kind).toBe("spell");
while (state.stack) state = must(state, state.stack.waitingOn, { type: "pass" });
state = drain(state);
const after = state.players.find((p) => p.id === "mark")!;
expect(after.life).toBe(2);
expect(after.alive).toBe(true);