Files
BT411/scratchpad
arcattackandClaude Opus 5 b7e4837738 seat identity swap (SAURON played as 'Draco'): the LEFT handler ate the pref of a re-seating player
THE CHAIN (reconstructed from the night's logs, then REPRODUCED offline in
scratchpad/test_seat_identity.py before fixing):

  1. At round end every pod relaunches and seat-requests again.  SAURON's
     request was walk-up-assigned the departed Draco's old seat, and his pref
     (callsign/mech) was correctly written -- the assign line even printed
     callsign='SAURON'.
  2. His request conn then closed BY DESIGN (the pod re-dials to HELLO) --
     and the beacon-death branch of _drop_game, added 2026-07-26 for the
     departed-player roster fix, treated any beacon death on an unclaimed
     seat as a LEAVE: it printed a false 'PLAYER n LEFT' and POPPED the pref
     written milliseconds earlier.
  3. The next egg release _reload_egg_file()'d the DISK egg -- where the GUI's
     Start Session had saved the ADOPTED roster names, including 'Draco' on
     that row -- and with no pref left to override it, Draco's callsign
     shipped on SAURON's seat.  His plasma (and that round's score
     attribution) wore the wrong name.  Per-seat HELLO-vs-close ordering
     roulette explains why only one seat swapped.

THE FIX: a LEFT-grace window (SEAT_LEFT_GRACE_SECONDS=15).  A beacon that
dies younger than the grace is the pod's designed post-assign re-dial: keep
the pref and the reservation, print nothing.  A real join-menu leaver has
held the seat far longer, so the departed-player roster fix keeps working
(pop + LEFT exactly as before); claimed seats were already exempt.

REGRESSION SUITE (new, offline, drives the real Relay class -- no ports):
  A. designed instant close: pref survives, seat stays protected  [was FAIL]
  B. real leave (aged beacon): pref popped + seat freed           [unchanged]
  C. claimed seat: pref survives an unrelated conn death          [unchanged]
  D. a different identity assigned onto a held seat overwrites
     the held pref (the operator's original suspicion, locked in) [unchanged]
All four console suites pass (rearm 25, net 17, roster 22, identity 7).

Python-only: no client update needed; the running console picks it up on its
next Start Session.  Awaiting live verification next games night.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 00:11:59 -05:00
..