Files
PaperClipAI/server/src/services
51a65af9b8 fix(recovery): continue preserved preparation after process loss (#19464)
## Thinking Path

> - Paperclip manages AI agents and their execution state.
> - A server restart can stop workspace preparation before provider
execution.
> - Workspace recovery must preserve files before the task can continue.
> - Recovery handled interrupted preparations but skipped failed
process-loss records with the same no-provider certificate.
> - A withheld first retry could also hide the remaining retry budget.
> - This change resumes certified preparations through normal admission
after file recovery.

## Linked Issues or Issue Description

**What happened?**
A process-loss attempt remained failed after workspace recovery
completed. Its first retry had been cancelled before dispatch by the
workspace hold. The task had no running attempt or automatic
continuation.

**Expected behavior**
Continue once after the server proves that provider work did not start,
file preservation completed, and the exact leases stopped. Retain the
existing failure budget and all task admission gates.

**Steps to reproduce**
1. Stop a Runner preparation before native runtime selection. Record the
restart recovery bootstrap certificate.
2. Retain the workspace and withhold the first automatic retry before
dispatch.
3. Complete file preservation and restart the recovery worker.
4. Observe that the old code schedules no successor. The regression test
reproduces this with PostgreSQL and real filesystem operations.

**Paperclip version or commit**
Reproduced against master at `2f35eb1080`. Related prior work: #19422
continues saved user input after verified copy-back. This change handles
automatic continuation of certified process-loss preparation.

## What Changed

- Accept failed process-loss preparation only with the durable
no-provider bootstrap certificate and existing execution, lease and file
checks.
- Discover and settle the recovered source through the existing
preparation recovery path.
- Continue from a verified withheld retry without rewriting its history
or resetting its failure count. Adopt it only as the sole retry child;
multiple-child history reuses the newest existing child
deterministically.
- Exercise automatic dispatch, preserved-file readback, one provider
turn, accepted result and task completion in the local native-session
fixture.
- Keep a durable continuation receipt after file-hold settlement until a
successor is recorded. Known gates wait for existing eligibility events.
Unresolved delivery keeps its shared recovery deadline.
- Document the recovery and retry-budget rules.

## Verification

- Red: both new PostgreSQL/filesystem regressions failed with zero
scheduled successors where one was required.
- Green: 54 focused recovery, automatic-dispatch, interruption,
multiple-child history and admission safety cases pass on `13c27c2c2f`.
The full PostgreSQL admission adapter suite passes all 83 tests; server
source declaration typecheck also passes. Local environment: Darwin
arm64, Node 26.4.0, PostgreSQL 18.1, Vitest 5.0.3.
- Additional red/green: interruption after committed settlement,
pause/resume, failed enqueue after cursor advancement, and absence of an
earlier retry all failed before their repairs. Restart before enqueue,
restart after the successor claim, and pause/resume now preserve one
continuation. A rolled-back eligibility change cannot start execution.
Deferred and delivered records have no retry deadline.
- Local acceptance uses the real heartbeat dispatcher, isolated files
and PostgreSQL, with a simulated native provider. It reads the preserved
file, writes continued work, accepts the structured result and completes
the task once.
- Negative cases retain no-certificate, provider-evidence, live-owner,
Stop, missing-stop-receipt, wrong-snapshot, human-block, pause,
reassignment, approval and exhaustion fences.
- CI fixture regression: 4 error-propagation/concurrent-resolution cases
pass after adding the new obligation read to their transaction stubs;
existing assertions remain unchanged.
- Existing idle-drain and notification contract regressions: 4 tests
pass after restricting recovery wakes to actual durable obligations.
Late approvals block scheduled, queued and final dispatch.
- Additional existing retry-scheduling suite: 62 cases pass locally. The
pre-provider quota case exceeds its existing 5-second terminal wait on
this loaded Darwin host, including when tested alone and with the
preceding retry implementation. It remains a local timing limitation;
the assertion and timeout were not changed. All Linux CI server shards
pass on the combined head, including this unchanged suite.
- Existing run-control, legacy-recovery and shared execution-control
lifecycle suites: 128 tests pass with the review repair. Required CI
supplies final-revision broad coverage.
- Real-Codex acceptance was not run: automatic approval review rejected
authenticated provider execution because it could incur cost/external
effects and required explicit approval. No provider call ran; the
controlled-provider acceptance covers the causal restart and durable
scheduling behavior.
- Hosted acceptance and recovery of existing tasks require rollout. They
have not been claimed from the local provider fixture.
- Final-head review: Greptile 5/5 on `13c27c2c2f`, no outstanding
findings. Another contributor added the multiple-child history safety
repair in `13c27c2c2f` while CI was running. The delta was inspected and
the 54 focused recovery cases rerun successfully. Required CI passes on
that exact combined head:
https://github.com/paperclipai/paperclip/actions/runs/42241794918. All
55 successful checks include aggregate `ci / verify`, typecheck, build,
canary, all server and E2E shards, and Runner package/Rust/static
checks. The separate Paperclip Review service check remains queued
waiting for its assigned agent; no validated assessment has been
returned.

## Risks

A malformed preparation certificate or a false no-execution receipt
could permit duplicate work. The existing checks still reject provider
execution records, native coordinators, live controllers, unsettled
leases and unverified files. The pending continuation must survive a
restart without polling known admission blockers. A withheld retry
retains its original row and consumes its remaining failure budget.
Normal admission checks current ownership, approvals, pause and budgets.

## Model Used

OpenAI GPT-6 family via Codex. The exact model ID and context window are
unavailable in session metadata. Used reasoning, code editing and tool
execution.

## 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 task 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>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-11-06 09:36:46 -06:00
..
…
…
…
…
…