Files
PaperClipAI/doc
DottaandPaperclip b4a66027b7 fix(server): deliver chat completions after nested workspace saves (#18665)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent Chat returns completed worker tasks to the original
conversation.
> - Delivery must retain its wake receipt when execution gates refuse
admission.
> - A workspace save can contain a nested snapshot operation.
> - The old checks lost the receipt and treated that saved snapshot as
unfinished work.
> - This pull request preserves the receipt and recognizes a successful
owning save.
> - The benefit is that completed work can reach the chat through the
normal queue.

## Linked Issues or Issue Description

Refs #18652. Related: #17206 covers failed finalize recovery. This
repair handles a successful finalize with an enclosed snapshot and does
not change failed-save recovery policy.

**What happened?**

A delegated worker finished and saved its result. The original chat
received no update. The dependency gate compared operation start times.
A nested snapshot started after its enclosing finalize and therefore
left a permanent hold. The completion wake also lost its exact
idempotency receipt when the queue merged a refused wake into a generic
dependency wait. The outbox reported `Completion wake returned no run or
durable receipt`.

**Expected behavior**

A successful finalize covers a completed operation enclosed by that save
when company, workspace, issue, and run match. Completion wakes that
disable coalescing keep their own durable receipt even when admission
waits. Dependency, budget, Stop, and pause gates still apply.

**Steps to reproduce**

1. Hand a task from a chat to a worker and make the chat wait on that
task.
2. Finish a workspace finalize that starts before its nested snapshot
and ends after the successful snapshot.
3. Mark the worker Done and deliver its completion outbox entry.
4. On the parent revision, the dependency stays blocked and the
completion receipt is absent.

**Paperclip version or commit**

Reproduced against `53f480d1b3` with real disposable Postgres rows and
the normal queue/outbox services.

## What Changed

- Honor `allowRunCoalescing: false` when recording execution waits.
- Accept an enclosed successful operation only when the successful
finalize has the same company, workspace, issue, and run and covers its
whole recorded interval.
- Preserve the existing rule that a strictly later successful workspace
finalize clears earlier work.
- Add failure controls for foreign runs, unfinished snapshots, failed
saves, snapshots that finish too late, and later operations.
- Exercise the real outbox and queue together. Hold provider dispatch at
the existing drain boundary and verify server-recorded Done facts reach
the admitted turn.
- Document receipt identity and workspace-save coverage.

## Verification

- Before repair: the two causal regressions fail and five safety
controls pass. The missing exact receipt and empty wakeable-dependent
list match the observed failure.
- After repair: those seven cases pass without assertion changes.
- The full affected set passed 288 tests and failed one existing
scheduling test. Its unchanged Node24 baseline also failed. A
closed-phase probe showed the fake adapter finished successfully at
3.453 seconds, after the incidental 3-second poll. The test now joins
the existing execution promise and retains its status and dependency
assertions under the unchanged Vitest timeout. The synchronized full
dependency suite passes all 13 cases.
- `pnpm -r typecheck` and `pnpm build` pass on pinned Node24/pnpm9.
`pnpm test:run` is running. The combined real outbox/queue case passes.
Fresh Greptile is 5/5 on `d7cee24b7032c7fdf171bfd1246cd90d41db1cba`.
Exact-head normal CI and required `ci / verify` and `ci / e2e` pass.
- The original scheduling failures on Node26 and Node24, the
unchanged-source baseline failure, and the closed-phase probe are
retained in the validation record. No model, deadline, production
assertion, or paid attempt was retried to change the failure grade.
- Current-head CI attempt1 passed all product and workspace coverage but
failed the unchanged serialized retry-worker case at
`issue-scheduled-retry-routes.test.ts:606` (first batch not observed
before the poll deadline;410 other shard tests passed). The exact
unchanged case passes locally on Node24 with real Postgres. The one
failed-jobs-only retry passed on the same head; the original grade is
retained.
- The full local command completed all1828 chat integration tests. Its
general stage remains running and has retained failures in unchanged
`workspace-runtime.test.ts` (30-second local port-conflict fixture) and
`muse-control.test.ts` (current binding authentication fixture). These
are not counted as passing local full-suite evidence. Their current-head
hosted coverage passed.
- The separate advisory Paperclip Review app is paused and has no code
finding. Its in-progress state is preserved and is not counted as a
pass; it is not a required repository status check.
- The live Cloud completion journey remains failed and unqualified. It
must pass at the deployed fixed revision before daily-plan admission. No
QA oracle, model, budget, or run limit changes are included.

## Risks

- The workspace coverage query must not clear a save from another owner
or new work after finalization. The guard checks the full interval and
exact owner identity, with negative controls.
- Refused noncoalescible automatic wakes retain separate receipts.
Replaceable automatic signals still merge. No new polling or provider
retry path is added.
- No migration or API change. Deployment and live acceptance are
separate remaining gates.

## Model Used

- OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The
exact deployment variant and context-window size are not exposed in this
session.

## 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
- [x] All Paperclip CI gates are green
- [x] 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: Paperclip <noreply@paperclip.ing>
2026-11-02 15:06:26 -06:00
..
…
…
…
…