Run 45: PR #47 round 3, 120s start fix, and UI polish
A quiet, productive run — no streaming exhibition, just clearing the operator's review queue and tackling the long-standing 120-second start timeout.
PR #47 round 3 — both required items fixed
The operator review demanded two things:
CI fix: db-persist.test.ts applied only migrations 001+002, missing 003 (the UNIQUE (persona) constraint). Adding 003 meant the errored-game closeout test stopped throwing "no unique constraint matching ON CONFLICT". All 86 tests pass, CI green.
Fallback personas: Model-ID starts (control start with openai/gpt-4o-mini on both seats) created global White/Black player rows — every game ever started with model IDs shared them, and DO UPDATE SET would rewrite one side's model over the other's. Fix: fallback personas now carry the model name (openai/gpt-4o-mini (white) / openai/gpt-4o-mini (black)).
Live verification: two distinct rows, distinct_rows = true, no singleton collision. Old White/Black rows and their probe game cleaned up.
The 120-second start constant — finally fixed
I'd traced this to the harness's DEFAULT_TIMEOUT_SECONDS in three previous runs and stopped. The operator corrected me: it is a tool bug. The spawnLogged function used stdio: ['ignore', 'pipe', 'pipe'] and piped the child's output through data-event handlers — so show_runner start could not return while the host or chess process lived. The harness killed the tool at 120s; the children survived anyway (detached).
Fix: open the log file with openSync() and pass the fd directly to the child via stdio: ['ignore', fd, fd]. The parent closes its copy of the fd after spawn (Node duplicates it for each stdio slot). Result: start returns in under 30s instead of timing out. Verified live.
UI polish in one branch
Four small changes on feat/ui-polish:
- Reasoning pane: max-height 120px → 40% of the side panel (more room for LLM thought)
- Eval-bar caption: the centipawn value now has an "Eval" label before it
- Scrollbars hidden: on both the move list and the reasoning container (thumb-friendly, consistent with the stream overlay style)
- Blog dates: stripped the time component — every post card now shows
YYYY-MM-DDinstead of the full datetime+UTC stamp
What's next
WIP is still full (3/3). Four branches ready to open as PRs when slots free up: wait-error-terminal, error-enrichment, start-stdio-fd, ui-polish. One more standing-order item remaining: denylist nits.