From a1a0689ca8ada6e87d4d0899f95dd422393eecd7 Mon Sep 17 00:00:00 2001 From: Poytr1 Date: Sat, 15 Aug 2026 11:44:25 +0800 Subject: [PATCH 1/2] feat(evals): firmer, individually binding referee VOTE wording (webchat Werewolf) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Measured motivation: the 7-player real game completed a perfect six-speaker sequential discussion and then stalled at day-vote with one ballot cast — zero hop refusals, zero gated wakes, zero lost replies; the polite 'now says their vote out loud' invitation simply read as optional to players with no strong read. The announcement now binds each player personally (MUST cast exactly one vote, in your next message; no strong read does not excuse you; not voting forfeits), keeping the machine-parsed prefix and Living-players list byte-identical so the scripted players' parsing is untouched. Scripted games pass unmodified; the real effect shows in the 7p runs. Eval-side only — no product code. Co-Authored-By: Claude Fable 5 --- evals/games/webchat-werewolf.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/evals/games/webchat-werewolf.ts b/evals/games/webchat-werewolf.ts index 50fce362c..9b5a726b5 100644 --- a/evals/games/webchat-werewolf.ts +++ b/evals/games/webchat-werewolf.ts @@ -195,10 +195,19 @@ export class WebchatWerewolfReferee implements ScriptedBrain { if (this.day.order.every((alias) => this.day!.spoke.includes(alias))) { this.day.spoke = [...this.day.spoke] this.phase = 'day-vote' + // Firmer, individually binding wording (measured motivation: real + // players completed a perfect 6-speaker discussion and then mostly + // never cast a vote — the polite invitation read as optional). The + // machine-parsed prefix `VOTE . Discussion is closed.` and the + // `Living players:` list are load-bearing for the scripted players + // and must not change. replies.push( `VOTE ${this.round}. Discussion is closed. Living players: ${this.aliveAliases().join(', ')}. ` + - `Every living player now says their vote out loud in this conversation, exactly once — for example ` + - `"${this.aliveAliases()[0]}: I vote for player-2". Name exactly one living player.` + `Every living player MUST now cast exactly one vote by posting a message in this conversation in ` + + `the exact form "${this.aliveAliases()[0]}: I vote for player-2" (your own name, then your vote). ` + + `This applies to YOU personally, whatever you said during the discussion — having no strong read ` + + `does not excuse you: pick the most suspicious living player and vote now, in your next message. ` + + `Not voting forfeits your voice in the lynch. Name exactly one living player.` ) } continue From e86c7f9e2ef8c8f7b4292abd039e5752c547c695 Mon Sep 17 00:00:00 2001 From: Poytr1 Date: Sat, 15 Aug 2026 12:17:57 +0800 Subject: [PATCH 2/2] fix(evals): vote example names living players only (review) A literal-minded player copies the example's target; a hardcoded alias can be dead in a later round. The example speaker AND target now come from the living list. Co-Authored-By: Claude Fable 5 --- evals/games/webchat-werewolf.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/evals/games/webchat-werewolf.ts b/evals/games/webchat-werewolf.ts index 9b5a726b5..bb789489f 100644 --- a/evals/games/webchat-werewolf.ts +++ b/evals/games/webchat-werewolf.ts @@ -201,13 +201,17 @@ export class WebchatWerewolfReferee implements ScriptedBrain { // machine-parsed prefix `VOTE . Discussion is closed.` and the // `Living players:` list are load-bearing for the scripted players // and must not change. + // The example names LIVING players only (review): a literal-minded + // player copies the example's target, and a hardcoded alias can be + // dead in a later round. + const living = this.aliveAliases() replies.push( - `VOTE ${this.round}. Discussion is closed. Living players: ${this.aliveAliases().join(', ')}. ` + + `VOTE ${this.round}. Discussion is closed. Living players: ${living.join(', ')}. ` + `Every living player MUST now cast exactly one vote by posting a message in this conversation in ` + - `the exact form "${this.aliveAliases()[0]}: I vote for player-2" (your own name, then your vote). ` + - `This applies to YOU personally, whatever you said during the discussion — having no strong read ` + - `does not excuse you: pick the most suspicious living player and vote now, in your next message. ` + - `Not voting forfeits your voice in the lynch. Name exactly one living player.` + `the form "${living[0]}: I vote for ${living[1] ?? living[0]}" — your own name, then ONE living ` + + `player from the list above. This applies to YOU personally, whatever you said during the ` + + `discussion — having no strong read does not excuse you: pick the most suspicious living player ` + + `and vote now, in your next message. Not voting forfeits your voice in the lynch.` ) } continue