PA.f194-A: `PlayTurnStore::open`'s catch-all arm retired a row onto its
declared `schema_id` alone, with no decode attempted. An Idunn rollback
across a schema-id move can hand a build a row stamped with a schema id it
has never seen whose bytes still decode cleanly under the current
`PlayTurnStoreState` shape (nothing about the struct changed, only the id).
That arm now attempts the decode first, exactly like the current- and
legacy-schema arms beside it: retires only on a genuine decode failure, and
leaves a readable row untouched with `open` failing loudly instead. The
sidecar's own `reason` field no longer claims "could not be read" when
nothing tried. `retire_unreadable_row`'s own doc comment now states this as
an explicit precondition on its caller. New test
`a_readable_row_declaring_an_unrecognized_future_schema_is_not_retired`
proves the readable case is not retired; the existing
`a_row_declaring_an_unrecognized_future_schema_is_retired_not_refused_forever`
still proves the genuinely undecodable case is. Mutation: reverting the
catch-all arm to retire on the schema id alone (no decode attempt) fails the
new test; reverted after confirming.
PA.f194-D: with the running hint correctly suppressed while a round is
genuinely in flight (PA.f193-D/PA.f194's own `run_in_progress` gate), the
play card rendered zero rows for the whole span between a player submitting
a turn and its own narration/question/refusal landing — a player who
submits sees nothing and has no sign anything is happening. A "resolving"
row now renders whenever `run_in_progress` is true, regardless of `state`,
staying inside invariant 8 (the player's own turn processing, no world
truth). The surviving hint's own text no longer claims "still being
resolved" — false in the only case it renders (`Running`, nothing actively
working on it) — and now says the turn did not finish. New tests
`the_card_shows_a_resolving_row_while_a_round_is_in_flight` and
`the_running_hints_own_text_does_not_claim_the_turn_is_still_in_flight`.
Mutation: removing the resolving-row block, and separately reverting the
hint text, each fails its own new test; reverted after confirming both.
PA.f194-E: `PlayTurnStore::retired_sidecar` (the field cached once at
`open`) has had no production consumer since PA.f193-E moved `/health`'s own
readiness reporting onto `PlayTable::retired_row_sidecar`, which scans the
store's directory fresh on every read instead of trusting a per-process
flag. Deleted the field, its accessor, and the tuple plumbing that carried it
through `open`'s match arms; `retire_unreadable_row`'s own doc comment no
longer credits it with `runtime_readiness` visibility. The two tests that
exercised it now assert on the sidecar file's own presence on disk directly,
which is what they were actually proving.
crates/ghostlight-dungeon --bin ghostlight-dungeon: 182 passed, 0 failed,
4 ignored (186 with --include-ignored and the Eve bridge built).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>