Files
PaperClipAI/doc
DottaandClaude Opus 5.5 e0e6462a73 fix(heartbeat): keep an agent's explicit resume comment that a stale continuation dropped (#20856)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents coordinate on tasks through comments. A comment posted with
`resume: true` is an explicit request for more work; on a finished task
it reopens the task, for a person or for another agent.
> - A comment that arrives while the assignee's run is still settling
queues its own run. If the settling run then closes the task, that
queued run is cancelled before dispatch as a stale continuation
(`continuation_task_ownership_changed`).
> - For a person's comment, the outbox saves the unread message first
and the release drain reopens the task (chaos s9401/t72). For another
agent's explicit `resume: true` comment, nothing was saved. The request
was dropped and the task stayed `done`.
> - This pull request saves that agent comment too, with its explicit
resume intent. The existing release-drain rule for an agent's explicit
resume reopens the task and delivers the comment once.
> - The benefit is that a parent agent's "do this next turn" request is
not lost to a timing race. An agent comment without `resume: true` stays
communicative, as before.

## Linked Issues or Issue Description

**What happened?**
On a hosted staging instance, a parent agent posted a comment with
`resume: true` on its child's task: "a changed requirement for your NEXT
turn". The child's provider turn had finished 90 s earlier, but its run
was still settling (workspace copy-back). The comment queued a new run.
40 s later the settling run applied its `done` decision. The queued run
was then cancelled with `continuation_task_ownership_changed`. The task
stayed `done` and no run ever read the comment. The cancelled run itself
is not shown as a failure (the task is terminal, so task chat hides it,
and Sentry skips expected cancellations), so nothing told anyone the
request was lost.

**Steps to reproduce**
1. Run an agent on a task. While its run is still settling, post a
comment from another agent with `resume: true`.
2. Let the run close the task (`done`).
3. The comment's queued run is cancelled as a stale continuation. The
task is not reopened and the comment is never delivered.

**Expected behavior**
The task reopens for the explicit resume request, and the comment is
delivered exactly once, as for a person's comment.

## What Changed

- `deferUndeliveredCommentsOfStaleRun` finds, per owed comment, the
comment's own `issue.comment_added` activity record: written by its
author (another agent, not the assignee) with `resumeIntent: true`.
Merged runs, whose wake is rewritten as comments join, therefore keep
each comment's own intent.
- `saveUndeliveredUserComments` also admits those comments
(`explicitResumeCommentIds`). When only such comments remain, the
deferred receipt records the agent as requester and carries
`resumeIntent`/`followUpRequested` in its payload and wake context. The
release drain's existing rule for an agent's explicit resume on a `done`
task then reopens and delivers it. Person-comment behaviour is
unchanged.
- `doc/run-log-events.md` describes the rule.

## Verification

- RED on `origin/master` (`1d67e309e0`): `pnpm --filter
@paperclipai/server exec vitest run
src/__tests__/heartbeat-held-comment-wake.test.ts -t "explicit resume
comment"` fails: `expected [] to have a length of 1 but got +0` (the
comment is never delivered after the stale cancellation).
- GREEN: the whole file passes (29/29), including two-requester
merged-run tests in both orders, the new negative test (`does not reopen
a finished task for another agent's comment without resume intent`) and
the existing person-comment and exactly-once tests.
- Related suites `ownership-reconciliation-report`,
`execution-continuation`, `chat-wake-conversation-batch` plus this file:
118/118 tests pass locally. One `afterAll` cleanup hook in
`ownership-reconciliation-report` timed out under local machine load; CI
runs the suite fresh.
- `pnpm --filter @paperclipai/server exec tsc --noEmit` passes.
- Not done: no restart-chaos cell. The harness posts follow-ups as the
board user, which s9401/t72 already covers; an agent-authored `resume:
true` comment needs a two-agent workload the harness does not have.

## Risks

- Low risk. Only a comment whose own wake was an agent's explicit
`resume: true` qualifies, only on a task an agent run closed, and only
when no run read the comment. The assignee's own comments never qualify.
- The ownership reconciler's durable backstop
(`checkStaleDroppedComments`) still covers person comments only. If the
fast path fails, an agent's resume comment is not recovered later.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, via Claude Code with
tool use (shell, file edits, read-only staging API reads).

## 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 not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [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
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 10:57:47 -06:00
..
…
…
…
…