Credibility pass: the fast-edit shavings swept from the ops-and-rev-13 batch

Server: turnFacts joins actingSeat's full priority order (a hanging
ward or slow-death window now reads as the lobby's attention, stubs
included), summarize and stubOf share one baseSummary, the stranded
doc comment returns to summarize, the protocol contract names
feedbackList, Sentry init moves below the imports it cannot precede,
randomBytes joins its group, the feedback path hoists once with the
operator-fields note. Engine: the safe's sight check trusts castSight
alone, the locked-safe predicate becomes lockedSafeAt, the doomed-grab
test drives both seats and must reach endTurn. Web: the twin safe
handlers merge, paPoints joins the reset ritual with a derived burnable
range, five decorative empty handlers and a dead class go, the hand
earns real list semantics, fitHandCards cites Card.svelte's tokens,
two wrap-sites reindent, feedbackReports moves home as a named type,
and the chronicle's stay-mounted reason is stated. feedback-reply.sh
adopts its siblings' set/usage conventions and speaks Node. Two test
screenshots leave the repo root.

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-09-01 11:04:01 -04:00
co-authored by Claude Fable 5
parent d37bc62c28
commit afa0e17483
11 changed files with 178 additions and 146 deletions
+17 -6
View File
@@ -1034,15 +1034,26 @@ describe("interception, escape, and hazard sense", () => {
state.squareContents[cellKey(chest.position!)] = { kind: "safe", damage: 0, createdBy: "foe" };
bot.position = { ...chest.position! };
bot.hand = [{ cardId: "number-3", instanceId: "N3" }];
for (let i = 0; i < 8; i++) {
const cmd = automatonCommand(viewFor(state, "bot"), "hunter", "archmage");
if (!cmd) break;
expect(cmd.type).not.toBe("pickUpTreasure");
const r = applyCommand(state, "bot", cmd);
// Drive whichever seat the maze wants (a punched foe answers its own
// counteraction window). The invariants: the bot never proposes the
// doomed grab, and its turn actually ends instead of idling forever.
let ended = false;
for (let i = 0; i < 24 && !ended; i++) {
const seat = actingSeat(state);
const view = viewFor(state, seat);
const chosen = automatonCommand(view, "hunter", "archmage");
let cmd = chosen ?? automatonFallback(view, "archmage");
if (seat === "bot") expect(cmd.type).not.toBe("pickUpTreasure");
let r = applyCommand(state, seat, cmd);
if (!r.ok && chosen) {
cmd = automatonFallback(view, "archmage");
r = applyCommand(state, seat, cmd);
}
expect(r.ok).toBe(true);
state = r.state;
if (cmd.type === "endTurn") break;
ended = seat === "bot" && cmd.type === "endTurn";
}
expect(ended).toBe(true);
});
it("a pressed carrier of any temperament turns to mist", () => {