---
phase: 06.3
plan: "03"
subsystem: diagnostics
tags: [client, server, e2e, duplicate-login, eviction]
requires:
  - phase: "06.2"
    provides: "D-51 replace-prior-session force_reset path"
provides:
  - "D-51 deterministic Playwright duplicate-login fixture"
  - "Server d51_eviction pino step envelope"
  - "Client window.__rebno.lastClientError capture for force_reset/remove/leave handlers"
affects: [phase-06.3, D-51, RebnoRoom, GameScene, colyseus-client]
tech-stack:
  added: []
  patterns: ["Multi-context Playwright same-account repro", "Unconditional staging-visible window.__rebno diagnostic publish"]
key-files:
  created:
    - apps/client/test/e2e/cli-08-dup-login.e2e.test.ts
  modified:
    - apps/server/src/RebnoRoom.ts
    - apps/client/src/scenes/GameScene.ts
    - apps/client/src/net/colyseus-client.ts
key-decisions:
  - "Used module `log.info(...)` in RebnoRoom; no `this.logger` exists."
  - "Included colyseus-client.ts because players.onRemove and room.onLeave handlers are bound there."
patterns-established:
  - "D-51 diagnostics include both server event ordering and client handler exception capture."
requirements-completed:
  - REQ-SRV-03
  - REQ-CLI-08
duration: 31 min
completed: 2026-05-14
---

# Phase 06.3 Plan 03: D-51 Duplicate Login Spike Summary

**Duplicate login now has a deterministic two-profile Playwright repro plus server/client diagnostic envelopes for 06.3-13.**

## Accomplishments

- Added `d51_eviction` pino logs for `start`, `state_deleted`, `force_reset_sent`, `prior_left`, and `new_player_added`.
- Wrapped GameScene force-reset and leave callbacks with `window.__rebno.lastClientError` capture.
- Wrapped `players.onRemove` and `room.onLeave` in `colyseus-client.ts` with the same error surface.
- Added `cli-08-dup-login.e2e.test.ts`, using two independent browser contexts and the same account fixture.
- Fixed typecheck regressions found while verifying: RoomRenderer walkable-grid telemetry now reads `cells`, and the font-gate unit test narrows invocation order values before comparison.

## Task Commits

1. **Task 1: Server eviction envelope** - `ccfd7bf` (`spike(06.3-03)`; also includes D-40/D-59 typecheck cleanup in co-located files)
2. **Task 2/3/4: Client lastClientError and dup-login fixture** - `be46a9b` (`spike(06.3-03)`)

## Files Created/Modified

- `apps/server/src/RebnoRoom.ts` - Added D-51 eviction step logs and type-safe D-40 layout telemetry narrowing.
- `apps/client/src/scenes/GameScene.ts` - Added `recordClientError(...)` and wrapped force-reset/onLeave callbacks.
- `apps/client/src/net/colyseus-client.ts` - Added `publishLastClientError(...)` and wrapped `players.onRemove` / `room.onLeave`.
- `apps/client/test/e2e/cli-08-dup-login.e2e.test.ts` - Added multi-context same-account D-51 repro.
- `apps/client/src/__test__/boot-font-gate.test.ts` - Narrowed mock invocation-order values for strict typecheck.
- `apps/client/src/render/RoomRenderer.ts` - Replaced invalid `WalkableGrid.flat()` telemetry with `WalkableGrid.cells` reads.

## Decisions Made

- Kept `force_reset` wire handling unchanged; this plan only adds diagnostics and defensive error capture.
- Kept the duplicate-login test unskipped so it is listed and runnable as the expected RED repro before 06.3-13.
- Did not modify `fixtures.ts`; existing `accountA`, `inviteSuffix`, `loginAs`, and `waitForGameReady` cover the repro.

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] RebnoRoom logger shape differed from the plan**
- **Issue:** The plan referenced `this.logger.info(...)`, but RebnoRoom uses imported module `log`.
- **Fix:** Added all D-51 log envelopes through `log.info(...)`.

**2. [Rule 3 - Blocking] Leave/onRemove handlers live in colyseus-client.ts**
- **Issue:** The plan file list omitted `apps/client/src/net/colyseus-client.ts`, but that file owns `players.onRemove` and `room.onLeave`.
- **Fix:** Added wrappers there and included the file in the commit.

**3. [Rule 2 - Blocking] Typecheck exposed earlier 06.3 regressions**
- **Issue:** Client typecheck failed on the D-59 font-gate test and D-40 walkable-grid telemetry; server typecheck failed on D-40 layout union access.
- **Fix:** Narrowed values/types without changing runtime behavior.

## Verification

- `pnpm --filter @rebno/server test --run` - PASS, 11 test files passed, 61 tests passed.
- `pnpm --filter @rebno/client test --run` - PASS, 26 test files passed, 190 tests passed, 4 todo.
- `pnpm --filter @rebno/client typecheck` - PASS.
- `pnpm --filter @rebno/server typecheck` - PASS.
- `pnpm --filter @rebno/client exec playwright test --list | Select-String "dup-login"` - PASS, listed the new D-51 test.

## Next Phase Readiness

Ready for `06.3-13`. The fix plan can use `d51_eviction` timestamps, `window.__rebno.lastClientError`, and the `cli-08-dup-login` repro to distinguish server ordering, wrong-recipient force reset, and client handler exceptions.

---
*Phase: 06.3*
*Completed: 2026-05-14*
