fix(server): settle threads server-side - #253
Merged
Merged
Conversation
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 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.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
Three follow-ups the cherry-pick did not carry. #8600 rewrites isUnpublishedBranch to treat a preserved branch.<name>.remote and .merge pair as evidence the branch was published. That hunk applied to neither a conflict nor a type error — it simply did not land, leaving the old remote-refs-only check. Its own test caught it. With the rewrite in place, Pylon's pruned-branch skip is no longer the right answer: prune removes the tracking ref but leaves the config, so the branch is now distinguishable from one that was never published and the lookup should run rather than fall back to the last-known PR. Pylon's test asserted the saved API call; it now asserts the live one. ws.ts keeps upstream's narrowing from parkingCommand back to archiveCommand. That is not a lost Pylon feature — upstream had parkingCommand too, and #8600 moves settle cleanup into ProviderCommandReactor's thread.settled handler, which dispatches the same onlyIfSettled stop and also covers settlements with no client attached.
rynfar
force-pushed
the
upstream/2026-09-02-settle-threads
branch
from
September 3, 2026 16:03
97df523 to
417f9cf
Compare
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.
Adopts
#8600. Thread settlement moves from the clients to the server: a newThreadSettlementReactorevaluates merge and inactivity rules,sidebarAutoSettle*becomes a server setting rather than a per-client one, and a
threadAutoSettlementcapability flag keeps older clients from double-driving it under version skew.
This is the 55-file one I had parked for a maintainer call. That was the wrong
call — its size is merge cost, not a product decision, and Pylon has no competing
settle design.
Carve-outs
planModeEnabledsurvives the settings move. The relocatedsidebarAutoSettle*keys sit directly beside Pylon'splanModeEnabledin bothClientSettingsSchemaandClientSettingsPatch, so taking upstream's sidewholesale would have deleted it.
isInFlight.#8600foldsapprovalandinputinto in-flight; Pylon deliberately treats those as attention statesthat stay prominent when the row is not active. Upstream's server-owned settle
predicate is taken; Pylon's row prominence is kept.
GitManagerkeepsskipped. Pylon's first skip guard coversgit worktree add -b feature origin/main, which upstream has no equivalent for.Upstream's new
localBranchExistscondition is added alongside.ChatViewkeepsactiveComposerDelegatedWorkand the cross-account handoffblock, with upstream's
activeThreadSettledderivation added.decideradopts upstream's typedOrchestrationThreadSettleBlockedError.Pylon's
interaction.*kinds live inhasOpenBlockingRequest, which isuntouched, so the extra coverage survives — and its test case is kept, upgraded
to the new error type.
docs/user/thread-sidebar.mdarrived saying "T3 Code"; it says Pylon.What ws.ts looks like is not what it is
#8600narrowsparkingCommandback toarchiveCommand, which reads like a lostPylon generalization. It is not — upstream's pre-image has
parkingCommandtoo.The commit moves settle cleanup into
ProviderCommandReactor'sthread.settledhandler, which dispatches the same
onlyIfSettled: truesession stop and alsocovers settlements that have no client attached. Verified before adopting.
Pylon has no
recordClientCommandAnalyticshelper, so that context line is dropped.A hunk that silently did not apply
#8600rewritesisUnpublishedBranchto treat a preservedbranch.<name>.remoteand
.mergepair as evidence a branch was published. That hunk produced noconflict and no type error — it just was not there, leaving the old
remote-refs-only check. Its own new test caught it.
Applying it then made Pylon's pruned-branch test fail, correctly: Pylon skipped
the lookup because remote refs alone could not distinguish a pruned branch from an
unpublished one. They now can, so the lookup runs and the badge comes from live
state rather than a last-known fallback. That test now asserts the live call.
Verification
t3,@t3tools/web,@t3tools/mobile,@t3tools/contracts,@t3tools/client-runtimetypecheck clean. Lint clean. 3950 server, 3407 web,1174 mobile, 681 client-runtime, 396 contracts, 614 desktop tests passing.
Model: Claude Opus 5 in Claude Code.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.