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 dropsuq_players_model_cohort seed.tsuses a singleINSERT … 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.tsupserts targetpersonainstead 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:
Wait treats
status: erroras terminal —waitnow returnsok: falsewith 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".Error event carries details — engine errors now carry
model,side,httpStatus, andrequestIdon thestatus: errorevent. 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).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.