You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature]: Prevent pinned threads from auto-settling #11711
A sidebar pin (pinnedAt) is an explicit keep-active signal, but the server currently auto-settles pinned threads anyway:
isAutoSettlementCandidate in apps/server/src/orchestration/ThreadSettlementPolicy.ts never checks pinnedAt, so pinned threads are swept for both inactivity and merged/closed-PR settlement.
decider.tsthread.auto-settle has no pinned guard — it even emits a companion thread.unpinned event, silently dropping the user's pin.
Docs (docs/user/thread-sidebar.md) state: "Pinning does not prevent automatic settlement."
The existing ThreadSettlementPolicy.test.ts case is even named "blocks pins, ..." but only covers settledOverride: 'active' (the transient keep-active override), not the sidebar pin.
thread.auto-settle decider rejects when pinnedAt != null (stale-sweep race: pin landed after the snapshot), while thread.settle (manual) still succeeds and clears the pin.
Sidebar pin (pinnedAt) is an explicit keep-active signal, but the server still auto-settles pinned threads (inactivity and merged/closed PR) and thread.auto-settle emits a companion thread.unpinned, dropping the pin. Current docs say pinning does not prevent automatic settlement.
This is real and matches main. It is an enhancement (documented, intentional today), not a defect.
Code
isAutoSettlementCandidate in apps/server/src/orchestration/ThreadSettlementPolicy.ts never checks pinnedAt, so pinned threads are swept for both inactivity and PR settlement. The reactor filters on that helper before PR lookups.
decider.tsthread.auto-settle guards settledOverride only. The shared settle path always unpins.
The policy test named “blocks pins, …” only covers settledOverride: 'active' (transient keep-active), not sidebar pinnedAt.
Web/mobile already bucket settledOverride === "settled" before pin. If the server never auto-settles a pinned thread, it stays in Pinned with no client change. Manual settle still unpins and lands in Settled.
settledOverride: 'active' and sidebar pinnedAt are different primitives. Activity clears the former; the latter is durable until unpin or settle.
Review/merge #11712. Policy + decider + reactor tests and docs match the acceptance list. Unpinning re-arms auto-settle by clearing pinnedAt (no extra work). Pinning a settled thread already un-settles it, so treating pin as keep-active is consistent with pin-as-promotion.
Not a duplicate of #5575. No second implementation PR needed.
Activity
juliusmarminge commentedon Sep 14, 2026
Triage
Sidebar pin (
pinnedAt) is an explicit keep-active signal, but the server still auto-settles pinned threads (inactivity and merged/closed PR) andthread.auto-settleemits a companionthread.unpinned, dropping the pin. Current docs say pinning does not prevent automatic settlement.This is real and matches
main. It is an enhancement (documented, intentional today), not a defect.Code
isAutoSettlementCandidateinapps/server/src/orchestration/ThreadSettlementPolicy.tsnever checkspinnedAt, so pinned threads are swept for both inactivity and PR settlement. The reactor filters on that helper before PR lookups.decider.tsthread.auto-settleguardssettledOverrideonly. The shared settle path always unpins.settledOverride: 'active'(transient keep-active), not sidebarpinnedAt.settledOverride === "settled"before pin. If the server never auto-settles a pinned thread, it stays in Pinned with no client change. Manual settle still unpins and lands in Settled.settledOverride: 'active'and sidebarpinnedAtare different primitives. Activity clears the former; the latter is durable until unpin or settle.Related
Fixes #11711): feat(settings): pinned threads stay active unless auto-settle pinned threads is on #11712 — do not open another.Next step
Review/merge #11712. Policy + decider + reactor tests and docs match the acceptance list. Unpinning re-arms auto-settle by clearing
pinnedAt(no extra work). Pinning a settled thread already un-settles it, so treating pin as keep-active is consistent with pin-as-promotion.Not a duplicate of #5575. No second implementation PR needed.
feat(settings): add auto-settle pinned threads toggle
fix(server): prevent pinned threads from auto-settling
feat(settings): add auto-settle pinned threads toggle