fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR#4309
Merged
Conversation
…losed PR Sending a message in a settled thread un-settles it server-side (the decider prepends thread.unsettled on turn.start), but the merged/closed-PR auto-settle signal in effectiveSettled is client-derived and never clears, so the row snapped back into the settled tail the moment the new turn completed. Gate the change-request signal on thread idleness: a merged/closed PR only settles a thread quiet for at least an hour. Fresh activity keeps the follow-up conversation in the active list; once the burst goes stale the merge signal settles it again, matching the decider's activity-clears- overrides model. Web and mobile both partition through the shared effectiveSettled, so this covers both clients. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Contributor
ApprovabilityVerdict: Approved This is a targeted bug fix for thread settling logic on merged/closed PRs. The change adds an idle guard to prevent threads from immediately re-settling after follow-up activity. The author owns this code, the scope is limited, and comprehensive tests are included. You can customize Macroscope's approvability policy. Learn more. |
…le; note clock-skew exposure Codex review follow-ups: assert the strict one-hour boundary (activity exactly an hour old stays warm), assert the same shell re-settles once the follow-up burst goes idle, and document that cross-device clock skew shifts the idle window by its size — the same accepted exposure as the inactivity auto-settle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
macroscopeapp
Bot
dismissed
their stale review
July 22, 2026 21:14
Dismissing prior approval to re-evaluate ca5b817
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/client-runtime/src/state/threadSettled.ts`:
- Around line 107-114: Update the lifecycle documentation comment above the
settled-resolution logic to clarify that pending work and unadjudicated queued
turns are evaluated before explicit settled or unsettled overrides. Replace the
claim that overrides “win in both directions” with wording that accurately
reflects these blockers taking precedence, while preserving the existing
override behavior after blockers clear.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b1ae8f2c-80fb-4fb9-aeec-55962715db89
📒 Files selected for processing (2)
packages/client-runtime/src/state/threadSettled.test.tspackages/client-runtime/src/state/threadSettled.ts
… override CodeRabbit review: the effectiveSettled doc claimed the override "wins in both directions", but pending approvals/user-input, live sessions, and unadjudicated queued turns are evaluated first and hold a thread active regardless of any override. Say so explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
macroscopeapp
Bot
dismissed
their stale review
July 23, 2026 20:06
Dismissing prior approval to re-evaluate 3cea3f9
maria-rcks
approved these changes
Jul 23, 2026
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…losed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6)
cursor Bot
pushed a commit
to aaditagrawal/t3code
that referenced
this pull request
Jul 25, 2026
…4309–pingdotgg#4488) (#187) * fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR (pingdotgg#4309) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 193e3c6) * Fix composer context strip alignment and glass shell (pingdotgg#4404) (cherry picked from commit 6ef7aa8) * Polish iOS git progress overlay with glass effects (pingdotgg#4387) (cherry picked from commit ce467da) * Improve composer glass fallbacks (pingdotgg#4406) Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit 67a7b1a) * feat(web): collapse large git diffs by default to make chat more readable (pingdotgg#4409) (cherry picked from commit 51672b6) * Stop new threads inheriting checkout/branch from viewed thread (pingdotgg#4411) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 2f41c07) * fix: tone down branch-mismatch banner (pingdotgg#4416) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit fc3f78f) * fix: Claude Code skills discoverable for the composer $ picker (pingdotgg#4414) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 6b9a598) * fix(web): keep settled threads reachable when opened directly (pingdotgg#4413) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit bb38c33) * feat(sidebar-v2): thread snoozing (pingdotgg#4311) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: maria <maria@kuuro.net> (cherry picked from commit 202e560) * Upgrade Clerk packages and Expo integration (pingdotgg#4440) (cherry picked from commit 5d17354) Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com> * Increase light-mode contrast for user message bubbles (pingdotgg#4441) (cherry picked from commit 15e875a) * Restore model picker layout and retain iterative test state (pingdotgg#4450) Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit f7cc776) * Color settled PR labels on hover (pingdotgg#4451) Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit a7ee309) * [codex] Fix glass hover compositing artifacts (pingdotgg#4446) Co-authored-by: codex <codex@users.noreply.github.com> (cherry picked from commit ece0508) * Add Claude Opus 5 model (pingdotgg#4472) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Theo Browne <me@t3.gg> (cherry picked from commit 41a430a) * feat(web): add collapse-all toggle to diff panel (pingdotgg#4475) (cherry picked from commit 38cfc25) * feat(web): show fast mode as a bolt instead of a "Normal" label (pingdotgg#4488) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> (cherry picked from commit 5719e8a) * fix(sync): preserve Droid medium-access with Auto runtime mode Keep fork-only medium-access in RuntimeMode alongside upstream Auto. Update presentation maps and drop obsolete provider kind from slug helper. Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com> * fix(sync): restore fork release and runtime-mode adaptations Keep WSL node-pty on bullseye glibc, pin releases to the fork, and stop hard-requiring upstream relay/npm publish. Scope Auto vs Medium access by provider, normalize carried modes on new threads, and fix Claude/Droid type regressions from the restack. Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com> * fix(sync): refresh lockfile after Clerk upgrade restack Align patchedDependencies hashes (react-native-screens) and importer entries with the current workspace patches so frozen CI installs succeed. Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com> --------- Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: codex <codex@users.noreply.github.com> Co-authored-by: maria <maria@kuuro.net> Co-authored-by: aaditagrawal <aaditagrawal@users.noreply.github.com> Co-authored-by: tomlit <tomlit@gmail.com> Co-authored-by: jan <hi@4bs3nt.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Sending a message in a settled thread should un-settle it. Two of the three settle signals already behaved:
thread.unsettledwhenthread.turn.starthits an overridden thread (decider.ts).threadLastActivityAt.But the merged/closed-PR auto-settle signal in
effectiveSettledis client-derived and never clears. Send a message in a merged-PR thread and the row un-settles only while the queued-turn grace / live-session blockers hold — the moment the turn completes,changeRequestState === "merged"classifies it right back into the settled tail. This also defeats the server's un-settle on explicitly settled threads whose PR is merged: the override clears on send, then the merge signal re-settles the row anyway.Fix
Gate the change-request signal on idleness: a merged/closed PR settles a thread only after it has been quiet for
CHANGE_REQUEST_SETTLE_IDLE_MS(1 hour). Fresh activity — the sent message, its turn starting and completing — keeps the follow-up conversation in the active list; once the burst goes stale, the merge signal settles it again. This mirrors the decider's own "activity clears overrides so the thread can auto-settle again after this burst of work goes stale" model.Web (
SidebarV2.tsx) and mobile (threadListV2.ts) both partition through the sharedeffectiveSettled, so one change covers both clients. No contract or server changes: the VCS status contract carries no merge timestamp, so idle-based gating is the clean option.The explicit Settle action on a warm merged-PR thread still works — a user settle sets
settledOverride, which is checked before the merge signal.Testing
mergedandclosedPR states; an idle one still settles.threadListV2tests pass, lint and typecheck clean.🤖 Generated with Claude Code
Note
Low Risk
Client-only list-partitioning logic in shared
effectiveSettled; behavior is narrower (fewer surprise re-settles) with targeted tests and no server/contract changes.Overview
Fixes merged/closed PR threads snapping back to settled right after a follow-up message’s turn finishes.
effectiveSettledused to treat merged/closed change requests as an always-on settle signal, so activity blockers only briefly kept the row active.Merged/closed PRs now auto-settle only when
threadLastActivityAtis missing or older thanCHANGE_REQUEST_SETTLE_IDLE_MS(1 hour) relative tonow. Recent follow-ups stay in the active list; after the burst goes idle, the merge signal settles the thread again. Explicitsettled/activeoverrides and existing activity blockers are unchanged.Tests cover warm vs idle boundaries for
mergedandclosed, and re-settling once the idle window passes.Reviewed by Cursor Bugbot for commit 3cea3f9. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Keep warm threads active despite merged/closed PR until idle for one hour
effectiveSettledwould auto-settle a thread as soon as its change request reachedmergedorclosedstate, even if the thread had recent activity.CHANGE_REQUEST_SETTLE_IDLE_MSconstant (1 hour) in threadSettled.ts; a thread now only auto-settles iflastActivityAtis older thannow - 1h(or absent).Macroscope summarized 3cea3f9.
Summary by CodeRabbit