Credibility pass: the accretion sanded smooth

Blind reviews over d2b40ec..HEAD (engine / web / server+deploy). Orphaned
doc comments rejoined their functions; the swap-meet tradables collapsed
from four pasted deriveds to one (killing the "the's treasure" label);
FEAR's aura and banner now share the engine's own dreadDistance; the
long-press peek got one home; rulebook.ts stopped wearing JSON quotes;
process-named tests and war-story comments now state the constraints they
pin; the protocol doc caught up to its handlers; verify-ledgers.sh can
actually count failures; the runbook learned about the determinism gate
and the nightly backups. No behavior changes — 255 tests and all 48
production ledgers replay identically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-21 10:58:08 -04:00
co-authored by Claude Fable 5
parent 3445d12206
commit 6adcbe23b5
17 changed files with 209 additions and 204 deletions
+31 -31
View File
@@ -118,36 +118,36 @@ describe("automaton vs automaton", () => {
});
});
function underAttackShared(attackId: string, defenderHand: { instanceId: string; cardId: string }[], rig?: (s: GameState, defender: string) => void) {
let { state } = createGame({ playerIds: ["human", "bot"], seed: 42, sets: ["basic", "expansion1"], deckRev: 13 });
// burn round 1
for (let i = 0; i < 2; i++) {
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
if (!r.ok) throw new Error(`setup: ${r.error}`);
state = r.state;
}
while (actingSeat(state) !== "human") {
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
if (!r.ok) throw new Error(`setup: ${r.error}`);
state = r.state;
}
const human = state.players.find((p) => p.id === "human")!;
const bot = state.players.find((p) => p.id === "bot")!;
bot.position = { ...human.position };
defenderHand.forEach((c, i) => { bot.hand[i] = c; });
human.hand[0] = { instanceId: `${attackId}#A`, cardId: attackId };
rig?.(state, "bot");
const r = applyCommand(state, "human", {
type: "cast", instanceId: `${attackId}#A`, target: { kind: "player", playerId: "bot" },
...(attackId === "drop-object" ? { params: { cardId: "dagger" } } : {}),
});
function underAttack(attackId: string, defenderHand: { instanceId: string; cardId: string }[], rig?: (s: GameState, defender: string) => void) {
let { state } = createGame({ playerIds: ["human", "bot"], seed: 42, sets: ["basic", "expansion1"], deckRev: 13 });
// burn round 1
for (let i = 0; i < 2; i++) {
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
if (!r.ok) throw new Error(`setup: ${r.error}`);
return r.state;
state = r.state;
}
while (actingSeat(state) !== "human") {
const r = applyCommand(state, actingSeat(state), { type: "endTurn", draw: 0 });
if (!r.ok) throw new Error(`setup: ${r.error}`);
state = r.state;
}
const human = state.players.find((p) => p.id === "human")!;
const bot = state.players.find((p) => p.id === "bot")!;
bot.position = { ...human.position };
defenderHand.forEach((c, i) => { bot.hand[i] = c; });
human.hand[0] = { instanceId: `${attackId}#A`, cardId: attackId };
rig?.(state, "bot");
const r = applyCommand(state, "human", {
type: "cast", instanceId: `${attackId}#A`, target: { kind: "player", playerId: "bot" },
...(attackId === "drop-object" ? { params: { cardId: "dagger" } } : {}),
});
if (!r.ok) throw new Error(`setup: ${r.error}`);
return r.state;
}
describe("the clockwork does not waste counters on pointless targets", () => {
it("passes on drop-object rather than absorbing nothing", () => {
const state = underAttackShared("drop-object", [
const state = underAttack("drop-object", [
{ instanceId: "absorb#T", cardId: "absorb" },
{ instanceId: "blunt#T", cardId: "blunt" },
{ instanceId: "dagger#T", cardId: "dagger" },
@@ -157,7 +157,7 @@ describe("the clockwork does not waste counters on pointless targets", () => {
});
it("shields a drop-object aimed at its carried treasure", () => {
const state = underAttackShared("drop-object", [
const state = underAttack("drop-object", [
{ instanceId: "full-shield#T", cardId: "full-shield" },
{ instanceId: "dagger#T", cardId: "dagger" },
], (s, defender) => {
@@ -171,8 +171,8 @@ describe("the clockwork does not waste counters on pointless targets", () => {
});
describe("the clockwork guards gold only within sight", () => {
// Game X2XN: the bot blind-cast SAFE at a treasure it could not see, the
// engine refused it, and the fallback burned the whole turn.
// A refused cast forfeits the bot's whole turn (the fallback is endTurn),
// so SAFE must only ever be offered where the engine's sight rule allows it.
function goldOnTheFloor() {
let { state } = createGame({ playerIds: ["bot", "foe"], seed: 7, sets: ["basic", "expansion1"], deckRev: 36 });
while (actingSeat(state) !== "bot") {
@@ -260,7 +260,7 @@ describe("a clogged hand gets shed, not hoarded", () => {
describe("the clockwork honors absorb's fine print", () => {
it("answers NO SPELL with blunt, never absorb — durations soak no points", () => {
const state = underAttackShared("no-spell", [
const state = underAttack("no-spell", [
{ instanceId: "absorb#T", cardId: "absorb" },
{ instanceId: "blunt#T", cardId: "blunt" },
]);
@@ -428,7 +428,7 @@ describe("the widened spellbook", () => {
});
});
describe("round two of the owner's tactics", () => {
describe("finishing tactics: exile and adrenaline", () => {
it("exiles a thief carrying its gold to the far end of nowhere", () => {
let { state } = createGame({ playerIds: ["bot", "other"], seed: 42, sets: ["basic", "expansion1"], deckRev: 24 });
// burn round 1 and reach the bot's turn
@@ -536,7 +536,7 @@ describe("a pact once signed is honored", () => {
// The pact already stands; a fireball waits in hand as temptation.
state.sustained.push({
id: "fx-test", cardId: "buddy", casterId: "bot", targetId: "other",
turnsLeft: 1000, edge: undefined,
remainingTurns: 1000, data: {},
} as never);
bot.hand = [{ instanceId: "fireball#T", cardId: "fireball" }];
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");