Skip to content

Serialize run.json writes and seed turnsUsed/mcpServers on resume - #343

Merged
TheGreatAxios merged 2 commits into
release/tui-bugfixesfrom
cl-5567-run-json-integrity
Aug 7, 2026
Merged

Serialize run.json writes and seed turnsUsed/mcpServers on resume#343
TheGreatAxios merged 2 commits into
release/tui-bugfixesfrom
cl-5567-run-json-integrity

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Chains saveState writes per sessionId so a straggler progress snapshot can no longer race a terminal finalize write and resurrect status: "running" on a finished session
  • Resolves a resumed session's turnsUsed and mcpServers once at the resume boundary (resolveResumeSeed), so createRunSink, connectedMcpServers, and the immediate post-resume saveState all read a trusted seed instead of resetting to zero/empty or each repeating its own default

Verification

  • bun run typecheck passes
  • bun run build passes
  • bun test: 4319 pass, 0 fail
  • New tests: src/session/state.test.ts (straggler-vs-terminal race, cross-session isolation), src/session/run-sink.test.ts (seeded turn count), src/tui/resume-seed.test.ts (resolveResumeSeed with non-empty mcpServers and non-zero turnsUsed fixtures, plus the pre-mcpServers-field record case)
  • Known gap, accepted deliberately: resolveResumeSeed and createRunSink's seeding are unit-tested, but the three call sites inside runTUI that consume resumeSeed (the createRunSink call, the connectedMcpServers initializer, the post-resume saveState) are not exercised by any test — runTUI has no test harness anywhere in the repo (it mounts a real TUI host/reactor), and tests/e2e fixture-repo runs are listed as planned, not yet built, in AGENTS.md. Building that harness for this fix is disproportionate: each call site is a single-line read of an already-tested value, so a regression there is a one-line diff that's easy to catch in review. Revisit if runTUI gets a real integration harness for other reasons.

Closes CL-5567
Closes CL-5566

@linear-code

linear-code Bot commented Aug 7, 2026

Copy link
Copy Markdown

CL-5567

CL-5566

@TheGreatAxios
TheGreatAxios changed the base branch from main to release/tui-bugfixes August 7, 2026 04:20
Concurrent saveState calls for one session had no ordering guarantee on
their underlying rename()s, so a late progress snapshot could land after
the terminal finalize write and flip a finished session back to
status: "running" with no finishedAt. Chain writes per sessionId so they
always apply in call order.

Documents why runner.ts's finalized flag still earns its place now that
saveState serializes writes per session: the write chain only orders
writes that are already issued, it has no way to know a stale
post-finalize snapshot shouldn't be issued at all.
Resuming a session unconditionally reset the run sink's turn counter
to zero and connectedMcpServers to empty, both in memory and by
immediately persisting those zeroed values to run.json before the
reactor even started. resolveResumeSeed folds a picked session's
run.json into a single concrete seed once, at the resume boundary, so
createRunSink, connectedMcpServers, and the immediate post-resume
saveState all read a trusted value instead of each repeating its own
`?? 0` / `?? []` default.
@TheGreatAxios
TheGreatAxios force-pushed the cl-5567-run-json-integrity branch from 67ce98c to ffe25ac Compare August 7, 2026 04:43
@TheGreatAxios
TheGreatAxios merged commit 7753fd5 into release/tui-bugfixes Aug 7, 2026
2 checks passed
@TheGreatAxios
TheGreatAxios deleted the cl-5567-run-json-integrity branch August 7, 2026 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant