[Feature]: Prevent pinned threads from auto-settling
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
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:
- #5575 (durable never-settle override — closed, different primitive:
settledOverridevs sidebarpinnedAt) - #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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/server/src/orchestration/ThreadSettlementPolicy.ts and ThreadSettlementPolicy.test.ts, then inspect the thread.auto-settle decider and docs/user/thread-sidebar.md. Verify the policy and decider both respect pinnedAt while manual thread.settle still unpins and succeeds. Add coverage for inactivity, merged or closed PRs, unpinning, and the stale-sweep race, and update the documentation wording.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, documentation
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100