Skip to content

fix(server): settle threads server-side - #253

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-09-02-settle-threads
Sep 3, 2026
Merged

fix(server): settle threads server-side#253
rynfar merged 2 commits into
pylonfrom
upstream/2026-09-02-settle-threads

Conversation

@rynfar

@rynfar rynfar commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Adopts #8600. Thread settlement moves from the clients to the server: a new
ThreadSettlementReactor evaluates merge and inactivity rules, sidebarAutoSettle*
becomes a server setting rather than a per-client one, and a threadAutoSettlement
capability 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

  • planModeEnabled survives the settings move. The relocated
    sidebarAutoSettle* keys sit directly beside Pylon's planModeEnabled in both
    ClientSettingsSchema and ClientSettingsPatch, so taking upstream's side
    wholesale would have deleted it.
  • The sidebar keeps Pylon's isInFlight. #8600 folds approval and
    input into in-flight; Pylon deliberately treats those as attention states
    that stay prominent when the row is not active. Upstream's server-owned settle
    predicate is taken; Pylon's row prominence is kept.
  • GitManager keeps skipped. Pylon's first skip guard covers
    git worktree add -b feature origin/main, which upstream has no equivalent for.
    Upstream's new localBranchExists condition is added alongside.
  • ChatView keeps activeComposerDelegatedWork and the cross-account handoff
    block, with upstream's activeThreadSettled derivation added.
  • decider adopts upstream's typed OrchestrationThreadSettleBlockedError.
    Pylon's interaction.* kinds live in hasOpenBlockingRequest, which is
    untouched, so the extra coverage survives — and its test case is kept, upgraded
    to the new error type.
  • docs/user/thread-sidebar.md arrived saying "T3 Code"; it says Pylon.

What ws.ts looks like is not what it is

#8600 narrows parkingCommand back to archiveCommand, which reads like a lost
Pylon generalization. It is not — upstream's pre-image has parkingCommand too.
The commit moves settle cleanup into ProviderCommandReactor's thread.settled
handler, which dispatches the same onlyIfSettled: true session stop and also
covers settlements that have no client attached. Verified before adopting.
Pylon has no recordClientCommandAnalytics helper, so that context line is dropped.

A hunk that silently did not apply

#8600 rewrites isUnpublishedBranch to treat a preserved branch.<name>.remote
and .merge pair as evidence a branch was published. That hunk produced no
conflict 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-runtime typecheck 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.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actions github-actions Bot added size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.7 KiB 13.6 KiB −170 B (−1.2%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 6.9 KiB −1 B (−0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.8 KiB 6.6 KiB −169 B (−2.4%) 7.8 KiB
Codex Live turn WebSocket decoded 58.7 KiB 57.2 KiB −1.5 KiB (−2.5%) 66.4 KiB
Codex Live turn messages 11 10 −1 (−9.1%) 21
Claude Total thread wire 13.8 KiB 13.6 KiB −189 B (−1.3%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 6.9 KiB +5 B (+0.1%) 7.3 KiB
Claude Live turn WebSocket wire 6.8 KiB 6.6 KiB −194 B (−2.8%) 7.8 KiB
Claude Live turn WebSocket decoded 59.5 KiB 58.1 KiB −1.5 KiB (−2.5%) 66.4 KiB
Claude Live turn messages 11 10 −1 (−9.1%) 21

Baseline: 5ac5778 · PR result: 97df523 · 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: 109.5 KiB
  • Claude decoded thread snapshot: 110.2 KiB

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

t3dotgg and others added 2 commits September 3, 2026 10:01
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
rynfar force-pushed the upstream/2026-09-02-settle-threads branch from 97df523 to 417f9cf Compare September 3, 2026 16:03
@rynfar
rynfar merged commit b8e5774 into pylon Sep 3, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 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.

2 participants