Files
PaperClipAI/packages
Nicky LeachandPaperclip 3d0d178ff7 Reconcile qualified ACPX predecessors through ordinary recovery (#19153)
## Thinking Path

> - Paperclip runs agent work through a controller and a Runner.
> - A completed provider session can outlive an abrupt Runner exit.
> - The next owner must reconcile the retained source before it attaches
a new run.
> - The ordinary recovery foundation in #19132 first supports Codex App
Server.
> - Qualified ACPX providers need their own saved and live consistency
checks.
> - This pull request adds those checks and a separate provider
attestation.
> - The benefit is session continuity through existing recovery and
attachment.

## Linked Issues or Issue Description

Builds on #19132, which has merged. This PR targets `master` and
contains only the ACPX changes.

**What existing behavior does this improve?**

Recovery of a completed ACPX session after the Runner and provider stop.

**Current behavior**

Ordinary ACPX recovery and attachment preserve a qualified session. A
completed predecessor also needs trusted admission by its new owner
before restoration. Codex checks cannot attest ACPX state.

**Proposed behavior**

Reuse ordinary exact-source recovery. Compare live restored state with
saved dormant state when no uncertain effect explains new work. Require
the selected driver's separate ACPX prelaunch attestation. Settle
retained events before authenticated target attachment.

## What Changed

- Preserve baseline prepared cleanup and ordinary continuation. New
predecessor admission excludes prepared provider state; snapshots and
cleanup do not restart it.
- Observe existing recovery command facts. Keep ordinary active same-run
behavior and existing profile, workspace, model, permission, session and
catalog checks.
- Verify the restored qualified session's identity, turn, goal and
outstanding requests when saved state was dormant. Failed verification
reaps the owned process group.
- Validate scoped goal updates arriving during the final status snapshot
after the authoritative goal reply. Active or unknown updates fail
admission; earlier and benign queued events remain available to ordinary
polling.
- Recognize the existing inactive `limited`, `usage_limited` and
`budget_limited` goal statuses, so an unexpected active goal after
restore cannot bypass live verification. Treat malformed nested
working-state metadata as unproven while keeping missing-field
compatibility.
- Keep existing ordinary recovery of qualified session-open and
suspended ACPX sessions. The new integrity check does not expand
prepared restoration.
- Advertise `acpxRecoveryIntegrityVersion: 1`, separate from Codex
integrity. No native source mode or CLI remains.
- Require `acpxSourceRecoveryVersion: 1` from the selected trusted
execution driver for a stopped predecessor. Codex capability alone
cannot grant it.
- Reuse dynamic authenticated owner admission, retained source
accounting, and existing ordinary ACPX attachment.

## Verification

Current head `b294d8ae88d0` is one commit on `master` at `e80d745060fd`,
the merge of #19132. The ten-file diff is byte-for-byte identical to the
reviewed ACPX diff against its former base. The guide shows where
`paperclip-runnerd --build-metadata` emits
`acpxRecoveryIntegrityVersion: 1` and how host admission uses a separate
capability. [ACPX recovery
guide](https://github.com/paperclipai/paperclip/blob/b294d8ae88d019ef02a942e240bc5c14287239e0/packages/paperclip-runner/runner/DURABLE_TRANSPORT.md#recovering-acpx-between-turns)

The rebased head passed all 14 ACPX process cases, three native snapshot
checks, Runner typecheck and the binary metadata check locally. GitHub
CI, Docker and Windows passed on their first attempts. Standard Greptile
review 12 scored the rebased commit 5/5 with zero unresolved threads.
[CI
run](https://github.com/paperclipai/paperclip/actions/runs/42063188178)
· [Standard
review](https://github.com/paperclipai/paperclip/pull/19153#issuecomment-6646809075)

The preceding code commit `08df48de20d613efcd861c278a7f9929c21d6670`
includes the reviewed parent `c09ebb4a2a6c140521698cf9fd681de67cfb9745`.
Paid review 9 scores this exact head 5/5 with no unresolved findings
(summary updated 2026-11-05 09:13:11 UTC after the 09:07:15 UTC
request). Standard review 8 also scored this head 5/5. [PR workflow
41995103666](https://github.com/paperclipai/paperclip/actions/runs/41995103666),
[Runner Windows
41995103419](https://github.com/paperclipai/paperclip/actions/runs/41995103419),
and [Docker Runner
41995103366](https://github.com/paperclipai/paperclip/actions/runs/41995103366)
passed on this exact head.

The initial main attempt lost self-hosted runners: the Runner package
log records a shutdown signal, and the other affected jobs report lost
communication or cancellation. Only unsuccessful jobs were retried;
their successful retry and aggregate gate are green. No source,
assertion or timeout change was made for this interruption.

- Combined `runnerd-acpx-source-reconciliation.test.ts` and
`runnerd-source-reconciliation.test.ts`: 25 real native/fake-provider
process cases passed. ACPX contributes 14 cases, including the
final-snapshot goal race, process-group cleanup, same-PID adoption,
exact provider identities, retained accounting, limited/paused goals and
ordinary active same-run recovery.
- The maintained fake sidecar emits a real `runtime.goal` frame between
the dormant goal reply and final snapshot response. Before the fix,
recovery succeeded. Afterward it refuses admission, reaps the owned
sidecar/provider group, and records only the original provider turn.
- Three native wire tests passed. They cover active updates with
low/equal/missing revisions, foreign run/session identity, and unchanged
ordered delivery of earlier history plus benign new events. The queue is
inspected without consuming frames.
- Both parent Codex final-read tests passed in the combined checkout:
active-goal refusal/reap and safe paused-goal delivery.
- The real native backend completes A, settles its journals, kills
Runner and provider, recovers the same ACPX session, adopts the
replacement Runner after controller restart, attaches B and completes a
second turn, then uses ordinary warm attachment for C and completes a
third successful turn. Record, backend and agent session identities
remain exact; ordinary ACPX attachment may restart its sidecar.
- Provider compatibility checks also passed while preparing this stack:
30 permission ordering/forwarding cases, 19 factory cases, the native
inactive-goal classification unit, and six native warm/suspend
integration cases.
- Combined offline Runner/fake-provider build, Runner `tsc --noEmit`,
`cargo fmt --all -- --check`, parent-relative `git diff --check`, and
added-line secret/personal-data scan passed.
- Only focused local checks ran. Full suites and platform checks run in
CI.


## Risks

- Fake providers prove protocol behavior, not vendor restore inertness
or all vendor background work. Real provider qualification remains
required.
- The trusted process owner must reject unsafe completed predecessors
before launch. Ordinary same-run active-goal recovery remains supported.
- Probes use the existing bounded sidecar budget. A timeout can
terminate the sidecar through existing transport cleanup. Null goal
projections remain supported.
- Ordinary ACPX attachment can restart the sidecar. Record, backend and
agent session identities remain exact; the Runner PID remains the same.
- This draft adds no deployment, release pin change or parking hook.

## Model Used

OpenAI GPT-6.1 Sol (`gpt-6.1-sol`), high reasoning, through Codex with
local code and command tools.

## Checklist

- [x] I have included a thinking path and specified the model
- [x] I have checked ROADMAP.md and confirmed this does not duplicate
planned work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have not included internal or instance-local references
- [x] My branch name describes the change
- [x] Focused local tests pass
- [x] Tests and documentation cover the changes
- [x] Risks are documented
- [x] All Paperclip CI gates are green at the revised head
- [x] Greptile is 5/5 with no unresolved comments at the revised head
- [x] I will address review findings before requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-05 08:37:08 -08:00
..