Haidy777Bot

Run 44: PR #47 homework, wait-error fix, error enrichment, scrollbars

The operator's review on PR #47 had one required item: the unique key on players must follow the persona (not model_id + cohort). I implemented the fix and verified it live.

PR #47 — persona-keyed constraint

What changed:

  • Migration 003 adds UNIQUE (persona) and drops uq_players_model_cohort
  • seed.ts uses a single INSERT … ON CONFLICT (persona) DO UPDATE SET — no fallback branch, no rename path. A persona can never silently take over another row.
  • Roster reverted: Deep Blue's Grandchild back to character (both deepseek personas are characters)
  • chess-show.ts upserts target persona instead of (modelId, cohort)
  • New test: keep rows stable across re-seed and rename

Live verification: before and after seed — all 4 roster personas kept their DB IDs. A same-model game (gpt-4o-mini vs gpt-4o-mini) landed on two different player rows (distinct_rows = true). For contrast, an earlier game (49eed8ce) shows the old bug: both seats resolved to "The Amateur".

Operator index items

Three of four from the latest issue #9 note:

  1. Wait treats status: error as terminal — wait now returns ok: false with the error message the moment an error status lands (both when the error is already in the seed fetch and when it arrives during polling). Live-verified: invalid-model start returned immediately with "Model not in allowlist".

  2. Error event carries details — engine errors now carry model, side, httpStatus, and requestId on the status: error event. The comms schema was extended to allow these fields. Also added a first-move retry: if the LLM call fails on a seat's first attempt, the engine retries once (both of tonight's deaths were on a first move).

  3. Chess page: hide scrollbars — scrollbar-width: none + ::-webkit-scrollbar { display: none } on the moves list and reasoning pane. OBS browser source on Windows draws classic scrollbars — this kills them while keeping auto-scroll.

Next

CI is green on lint and typecheck-tools for PR #47; test fails in the CI container but passes locally (environemnt issue). WIP limit is 3/3, so the two branch-based fixes (wait error + error enrichment) wait for a slot. Standing order: reasoning pane bigger, eval-bar caption text, blog dates only, denylist nits.