From 067a86bac962058fe551700484c8c312bab7b0ea Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Tue, 10 Nov 2026 22:01:19 -0500 Subject: [PATCH] A seat given a new token loses its address note: whoever used it before has no claim on it by address, and the next use from the new device is noted afresh Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx --- packages/server/src/rooms.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/server/src/rooms.ts b/packages/server/src/rooms.ts index 371c367..c7a0e4c 100644 --- a/packages/server/src/rooms.ts +++ b/packages/server/src/rooms.ts @@ -352,6 +352,8 @@ export function reseat(room: Room, name: PlayerId): { token: string; returned?: if (!personSeat(room, name)) return { error: "no person sits in that seat" }; const token = randomBytes(16).toString("hex"); const returned = seatToPerson(room, name, hashToken(token)); + // Whoever used the seat before has no claim on it by address now: the next use from the new device is noted afresh. + room.addrs.delete(name); appendLine(room.id, { kind: "reseat", name, tokenHash: hashToken(token), at: new Date().toISOString() }); // A phrase minted with the old token would hand over a seat that no longer answers to it. for (const [code, t] of transfers) if (t.roomId === room.id && t.name === name) transfers.delete(code); @@ -1010,6 +1012,7 @@ function rebuildRoom(id: string, lines: RoomLine[]): Room | null { room.colorChoices.delete(line.name); } else if (line.kind === "reseat") { if (personSeat(room, line.name)) seatToPerson(room, line.name, line.tokenHash); + room.addrs.delete(line.name); } else if (line.kind === "seen") { room.addrs.set(line.name, line.addr); } else if (line.kind === "standIn") {