Skip to content

fix(server): settle no longer leaves monitors and dev servers running - #5774

Merged
t3dotgg merged 3 commits into
mainfrom
t3code/settle-stops-session
Aug 9, 2026
Merged

fix(server): settle no longer leaves monitors and dev servers running#5774
t3dotgg merged 3 commits into
mainfrom
t3code/settle-stops-session

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Aug 9, 2026

Copy link
Copy Markdown
Member

Settling a thread means "I'm done with this", but the provider session kept running its background work. An audit of real usage found settled threads with PR monitors that ran 4 more hours (then woke the thread at 3am via reason: activity) and dev servers that burned ports and RAM for 13+ hours.

Settle now mirrors archive: after the command lands, the server dispatches thread.session.stop if the thread has a live session. That takes down everything inside the provider process — monitors, background shells, subagent fleets.

Details worth knowing:

  • The decider already rejects settling a starting/running session, so this only ever stops idle sessions between turns.
  • A stopped session-set does not count as session activity, so the stop cannot un-settle the thread it follows.
  • Terminals stay open on settle (unlike archive): a settled thread is still reachable and can be un-settled, and terminals are user-opened panes, not thread background work.
  • The archive path is byte-compatible: same commandId format, same ordering.

Not covered here: processes an agent detach-spawns with nohup/setsid escape the provider process tree entirely. That needs process-group/cgroup ownership and is a separate change.

Tests: two new server.test.ts cases (settle with live session stops it without closing terminals; settle with no session dispatches nothing extra). Existing archive hook tests all pass.


Built by Claude Fable 5 running in Claude Code.


Note

Medium Risk
Changes thread lifecycle and when provider sessions stop, including a new race-sensitive decider path; behavior is guarded by onlyIfSettled and covered by new tests.

Overview
Settle now tears down idle provider sessions (monitors, dev servers, background work) by dispatching a follow-up thread.session.stop after thread.settle lands, using the same post-command hook as archive when the thread still has a non-stopped session. Terminals stay open on settle—only archive continues to close terminal panes.

Settle cleanup stops are conditional: thread.session.stop gains optional onlyIfSettled, and the decider rejects that stop if the thread was unsettled, the session is starting/running, or a queued turn start appeared before the stop is decided—so a quick re-engage after settle does not kill the new session. Archive-driven stops remain unconditional.

The WS layer shares one “parking” path for archive and settle, logs a warning when the pre-stop session snapshot read fails (instead of silently skipping), and adds integration tests for settle-with-session vs no-session.

Reviewed by Cursor Bugbot for commit 4a614a9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix thread.settle to stop sessions conditionally without closing terminals

  • Dispatching thread.settle via the WS RPC now triggers a follow-up thread.session.stop (with onlyIfSettled=true) when the thread has a non-stopped session, replacing the previous behavior that also closed terminals.
  • Adds an onlyIfSettled boolean field to the thread.session.stop command contract; when set, the stop is rejected with OrchestrationCommandInvariantError if the thread has been re-engaged (session starting/running, or a queued turn start exists).
  • Terminal closing on session stop remains only for thread.archive, not thread.settle.
  • Behavioral Change: thread.settle no longer closes dev server terminals or monitors as a side effect.

Macroscope summarized 4a614a9.

Settling a thread now stops its idle provider session the same way
archive does, so PR watch loops and background dev servers die when
you mark the thread done instead of running on for hours and waking
the thread back up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 96cc87ba-821f-48c3-a84e-076c49e55e85

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 9, 2026
Comment thread apps/server/src/ws.ts
Comment thread apps/server/src/ws.ts
@github-actions

github-actions Bot commented Aug 9, 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 11.3 KiB 11.3 KiB −25 B (−0.2%) 15.1 KiB
Codex Thread snapshot wire 5.5 KiB 5.5 KiB +1 B (+0.0%) 7.3 KiB
Codex Live turn WebSocket wire 5.9 KiB 5.9 KiB −26 B (−0.4%) 7.8 KiB
Codex Live turn WebSocket decoded 49.7 KiB 49.7 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 16 16 0 (0.0%) 21
Claude Total thread wire 11.3 KiB 11.3 KiB +10 B (+0.1%) 15.1 KiB
Claude Thread snapshot wire 5.5 KiB 5.5 KiB −2 B (−0.0%) 7.3 KiB
Claude Live turn WebSocket wire 5.8 KiB 5.8 KiB +12 B (+0.2%) 7.8 KiB
Claude Live turn WebSocket decoded 50.6 KiB 50.6 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 16 16 0 (0.0%) 21

Baseline: 886195e · PR result: 4a614a9 · 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: 94.6 KiB
  • Claude decoded thread snapshot: 95.4 KiB

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

Review follow-up: the pre-stop projection read stays best-effort, but a
failed read now leaves a warning instead of silently skipping the stop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/server/src/ws.ts
@macroscopeapp

macroscopeapp Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 4a614a9

This is a straightforward bug fix extending existing archive cleanup logic to also work for settle commands. The changes follow established patterns, include defensive race-condition handling, and are well-tested.

You can customize Macroscope's approvability policy. Learn more.

Review follow-up: the settle-originated session stop is now conditional
(onlyIfSettled) and decided in the decider against the serialized read
model, so a turn started between the settle and the stop survives.
Archive stops stay unconditional.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit 5bb8c03 into main Aug 9, 2026
17 checks passed
@t3dotgg
t3dotgg deleted the t3code/settle-stops-session branch August 9, 2026 02:44
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Aug 9, 2026
## What's Changed
* chore: vouch gfsaaser24 by @t3dotgg in pingdotgg/t3code#5761
* chore: vouch saphid by @t3dotgg in pingdotgg/t3code#5763
* fix(server): stop Codex threads with queued follow-ups by @t3dotgg in pingdotgg/t3code#5762
* fix(web): usage page loses the cost quality panel, gains a back button by @t3dotgg in pingdotgg/t3code#5756
* feat(server): agents can now open the images you paste into chat by @t3dotgg in pingdotgg/t3code#5757
* fix(web): pinned reorder no longer reshuffles while writes land by @t3dotgg in pingdotgg/t3code#5767
* feat(web): overhaul project settings into a real settings page by @t3dotgg in pingdotgg/t3code#5768
* fix(web): usage totals no longer jump while devices report in by @t3dotgg in pingdotgg/t3code#5772
* fix(server): settle no longer leaves monitors and dev servers running by @t3dotgg in pingdotgg/t3code#5774
* feat: pick worktree or current checkout per project by @t3dotgg in pingdotgg/t3code#5766
* fix(web): sidebar rows show the branch again, not a truncated plan step by @t3dotgg in pingdotgg/t3code#5776
* feat(server): vp run migrate-dev-db seeds worktree dev dbs with real data by @t3dotgg in pingdotgg/t3code#5773
* feat(web): keep unsent drafts one click away in the sidebar by @t3dotgg in pingdotgg/t3code#5777


**Full Changelog**: pingdotgg/t3code@v0.0.33-nightly.20260809.1039...v0.0.33-nightly.20260809.1040

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

Labels

size:M 30-99 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