Repository navigation
Closed
Labels
acceptedfeature request acceptedfeature request acceptedenhancementRequested improvement or new capability.Requested improvement or new capability.via-triageFiled through npx t3 triageFiled through npx t3 triage
Description
Problem
A sidebar pin (pinnedAt) is an explicit keep-active signal, but the server currently auto-settles pinned threads anyway:
isAutoSettlementCandidateinapps/server/src/orchestration/ThreadSettlementPolicy.tsnever checkspinnedAt, so pinned threads are swept for both inactivity and merged/closed-PR settlement.decider.tsthread.auto-settlehas no pinned guard — it even emits a companionthread.unpinnedevent, 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.
Related:
- [Feature]: Durable per-thread "never settle" pin — the existing "active" override is cleared by activity, so no thread can be kept permanently active #5575 (durable never-settle override — closed, different primitive:
settledOverridevs sidebarpinnedAt) - fix(clients): move settled pinned threads into the settled section #7969 (moved auto-settled pinned threads into Settled — the behavior this reverses for auto-settle; manual settle still unpins and lands in Settled)
Proposal
isAutoSettlementCandidatereturns false whenpinnedAt != null(covers inactivity + PR paths, skips PR lookups).thread.auto-settledecider rejects whenpinnedAt != null(stale-sweep race: pin landed after the snapshot), whilethread.settle(manual) still succeeds and clears the pin.- Docs updated: pinning prevents automatic settlement.
Acceptance
- Inactive pinned thread never auto-settles
- Merged/closed-PR pinned thread never auto-settles
- Unpinning re-arms normal auto-settle rules
- Manual settle of a pinned thread still works and unpins
Metadata
Metadata
Assignees
Labels
acceptedfeature request acceptedfeature request acceptedenhancementRequested improvement or new capability.Requested improvement or new capability.via-triageFiled through npx t3 triageFiled through npx t3 triage
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