Skip to content

fix(server): capture checkpoints before refreshing PR status - #10347

Merged
t3dotgg merged 1 commit into
mainfrom
t3code/checkpoint-capture-before-status-refresh
Sep 6, 2026
Merged

fix(server): capture checkpoints before refreshing PR status#10347
t3dotgg merged 1 commit into
mainfrom
t3code/checkpoint-capture-before-status-refresh

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Sep 6, 2026

Copy link
Copy Markdown
Member

CheckpointReactor ran the git status refresh on the same worker as checkpoint capture, and before it. That refresh ends in a remote PR lookup under the vcs status write lock. A fast follow-up message could edit files before the capture committed, so the checkpoint recorded the wrong tree.

The refresh now runs on its own drainable worker (statusRefreshWorker). Turn completion enqueues the refresh and moves straight to capture, so capture never waits behind the network call and checkpoints for other threads do not queue behind it either. drain waits on both workers. One test pins the behavior: the PR refresh blocks on a Deferred that stays open until the checkpoint.diff.finalized receipt lands and the ref contains the edited file.

Extracted from #10297.

Written by Claude Fable 5.1 in Claude Code.

Note

Decouple local git status refresh from checkpoint capture in CheckpointReactor

  • Completion events in CheckpointReactor.ts now enqueue status refresh work on a separate drainable worker instead of awaiting it inline, so checkpoint processing can proceed while the refresh is pending
  • The reactor drain operation now waits for both the main worker and the new status-refresh worker
  • Non-interruption failures in the status-refresh worker are logged and swallowed; only interruption causes propagate
  • Adds test coverage in CheckpointReactor.test.ts for capturing a turn's checkpoint while pull-request status lookup is still pending
  • Behavioral Change: CheckpointReactor.make drain now blocks on queued status refreshes; callers relying on drain completing without pending refresh work will see different timing

Macroscope summarized 5d98a6c.

CheckpointReactor ran the git status refresh, which ends in a remote PR
lookup under the vcs status write lock, on the same worker as checkpoint
capture. A fast follow-up message could edit files before the capture
committed. Enqueue the refresh on its own drainable worker so capture
runs first.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 6, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 5d98a6c

Macroscope's review found this PR approvable — This is a focused server bug fix that isolates slow PR status refreshes from checkpoint capture while preserving worker draining and error handling. The added test directly covers checkpoint capture during a pending PR lookup, with no broader API, deployment, security, or configuration impact.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.6 KiB 13.6 KiB +12 B (+0.1%) 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.0 KiB −1 B (−0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.5 KiB 6.6 KiB +13 B (+0.2%) 7.8 KiB
Codex Live turn WebSocket decoded 57.1 KiB 57.1 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 10 10 0 (0.0%) 21
Claude Total thread wire 13.5 KiB 13.5 KiB +13 B (+0.1%) 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.0 KiB −8 B (−0.1%) 7.3 KiB
Claude Live turn WebSocket wire 6.5 KiB 6.5 KiB +21 B (+0.3%) 7.8 KiB
Claude Live turn WebSocket decoded 57.8 KiB 57.8 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 8 8 0 (0.0%) 21

Baseline: eb8ed80 · PR result: 5d98a6c · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@t3dotgg
t3dotgg merged commit e0adcc8 into main Sep 6, 2026
22 checks passed
@t3dotgg
t3dotgg deleted the t3code/checkpoint-capture-before-status-refresh branch September 6, 2026 09:56
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 6, 2026
## What's Changed
* feat(usage): pool subscription limits per provider across accounts and environments by @juliusmarminge in pingdotgg/t3code#10300
* chore(web): remove usage limits demo fixtures by @juliusmarminge in pingdotgg/t3code#10330
* fix(web): expose error disclosure state by @saphid in pingdotgg/t3code#10125
* fix(web): name the editor picker accurately by @saphid in pingdotgg/t3code#10124
* fix(web): make task row states readable by @saphid in pingdotgg/t3code#10128
* fix(web): explain hosted connection prerequisites by @saphid in pingdotgg/t3code#10129
* fix(web): name combobox chip removal targets by @saphid in pingdotgg/t3code#10127
* fix(marketing): present the Git workflow as an illustration by @saphid in pingdotgg/t3code#10130
* feat(mobile): pool usage limits across selected environments by @juliusmarminge in pingdotgg/t3code#10334
* fix(release): space automatic nightlies at least six hours apart by @t3dotgg in pingdotgg/t3code#10272
* refactor(web): share bulk thread deletion between sidebars by @t3dotgg in pingdotgg/t3code#10106
* refactor(client): share tool outcome rules by @t3dotgg in pingdotgg/t3code#10122
* refactor(server): share Claude result status and error mapping by @t3dotgg in pingdotgg/t3code#10296
* fix(server): settle inactive threads without a PR lookup by @t3dotgg in pingdotgg/t3code#10103
* fix(ssh): report remote stop failures without losing ownership by @t3dotgg in pingdotgg/t3code#10105
* perf(server): stop scanning old OpenCode parts by @t3dotgg in pingdotgg/t3code#10116
* perf(server): avoid full thread reads on turn start by @t3dotgg in pingdotgg/t3code#10108
* perf(web): skip checkpoint map rebuilds while streaming by @t3dotgg in pingdotgg/t3code#10118
* perf(server): skip plan bodies in thread summaries by @t3dotgg in pingdotgg/t3code#10341
* fix(server): skip disabled provider instances for text generation fallback by @t3dotgg in pingdotgg/t3code#10346
* fix(server): capture checkpoints before refreshing PR status by @t3dotgg in pingdotgg/t3code#10347
* fix(web): keep manual panel choices during a turn by @t3dotgg in pingdotgg/t3code#10113
* fix(threads): keep completed requests closed across clients by @t3dotgg in pingdotgg/t3code#10123
* perf(server): finish runtime messages without full thread reads by @t3dotgg in pingdotgg/t3code#10120
* refactor(server): let adapters declare context compaction by @t3dotgg in pingdotgg/t3code#10112
* fix(server): link thread PRs without an open client by @t3dotgg in pingdotgg/t3code#10101


**Full Changelog**: pingdotgg/t3code@v0.0.39-nightly.20260906.1293...v0.0.39-nightly.20260906.1303

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.39-nightly.20260906.1303
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant