5d315ab778
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The heartbeat service governs how agent wake events get queued, deferred, or folded into the currently-running adapter run > - `forceFreshSession: true` wakes on a same-agent/same-issue path get silently folded into the active run, so callers can never request a true cold-start follow-up > - This breaks phased workflows that need to drop a poisoned session and restart cleanly on the same issue without bouncing to another agent > - This PR extracts the existing same-issue follow-up decision into `shouldDeferFollowupWakeForSameIssue` and extends it to also defer `forceFreshSession: true` wakes into a follow-up run boundary > - The benefit is that `forceFreshSession` now behaves as documented: it actually starts a fresh session, even when the wake targets the same agent/issue/runtime that is currently executing ## Linked Issues or Issue Description **What happened?** A wake event posted with `forceFreshSession: true` against an issue whose current adapter run is still `running` on the same execution agent is silently coalesced into that in-flight run instead of starting a cold session. Callers that explicitly request a fresh-session reset see no behavior change until the run naturally completes. **Expected behavior** `forceFreshSession: true` should always force a fresh session start, even when the wake targets the same agent/issue that is currently executing. The wake should defer into a follow-up run boundary if the current run is still in-flight. **Steps to reproduce** 1. Start an adapter run for some issue. 2. While the run is still `running`, post a wake event for the same issue/agent with `forceFreshSession: true`. 3. Observe: the active run continues without resetting the session; the fresh-session signal is dropped. ## What Changed - Extracted same-issue follow-up decision into exported helper `shouldDeferFollowupWakeForSameIssue` in `server/src/services/heartbeat.ts` - Extended that helper so `forceFreshSession: true` (not only `wakeCommentId`) defers into a follow-up run when the current run is still `running` for the same execution agent - Added stickiness to `mergeCoalescedContextSnapshot`: if either side of a wake-merge has `forceFreshSession: true`, the merged snapshot keeps it set so it is not silently dropped while queued wakes coalesce - Added five unit tests in `heartbeat-workspace-session.test.ts` covering each decision branch of the helper ## Verification - `pnpm --filter @paperclipai/server test src/__tests__/heartbeat-workspace-session.test.ts` - `pnpm --filter @paperclipai/server typecheck` ## Risks Low. Behavior change only affects the narrow case where a same-agent/same-issue wake carries `forceFreshSession: true` while the active run is still `running`. Other wake paths (cross-agent, queued/failed runs) are untouched. The helper extraction is a pure refactor preserving the prior comment-wake deferral. ## Model Used Claude (Opus 4.7) — extended thinking enabled, used to extract the helper, extend the deferral condition to cover `forceFreshSession`, and write unit coverage. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (N/A — no UI changes) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (in progress) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Devin Foley <devin@paperclip.ing>