Files
PaperClipAI/maps/agent-access-map
DottaandPaperclip d84061b923 fix(runner): recover journaled completion proposals (#16962)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Native runs preserve provider sessions across controller restarts.
> - A completion event can reach durable storage before the next session
checkpoint.
> - Recovery advanced the event cursor but lost the saved completion
proposal.
> - The completed turn then appeared to need another provider turn to
report its result.
> - This change restores the exact active turn's proposal before
advancing the cursor.
> - Recovery can finalize completed work without repeating its external
actions.

## Linked Issues or Issue Description

**What happened?**

After a controller restart, a native run could fail with
`native_finalization_missing` even though `run.result.proposed` was
already durable. The recovered driver skipped that event when its cursor
advanced, so the result was absent from its state. Automatic disposition
retries could then encounter outstanding tool receipts and exhaust
recovery.

**Expected behavior**

Restore the saved result for the exact active turn. Wait for provider
termination, then use normal finalization. Do not start another provider
turn to repeat completed work.

**Steps to reproduce**

1. Start a native Codex task and save its active-turn checkpoint.
2. Persist its completion proposal, then lose the controller before
another checkpoint.
3. Recover the same run after the provider completes. Before this
change, finalization reports a missing result.

**Paperclip version or commit**

Reproduced on `92b238137b`. The repair is based on `7c247243e5`.

**Deployment mode**

Native Runner with Codex. The incident used a remote sandbox; the
regression covers controller event recovery.

Related: #12845 and #15297. The older #12241 addresses provider process
continuity; this change repairs the controller's saved event projection.

## What Changed

- Restore valid completion proposals for the checkpoint's exact active
turn during event replay.
- Reject conflicting, invalid, or incorrectly bound proposals. Ignore
proposals from another turn and prevent adoption after a newer turn
starts.
- Keep provider termination and normal finalization as separate
requirements.
- Add eight behavioral cases using the real Codex driver and a simulated
transport, and document the recovery contract and verification scope.

## Verification

- Red: the new restart regression failed with
`native_finalization_missing` before the production change.
- Green: 254 tests passed across the native runtime, backend adapter,
and Codex recovery suites. The new cases check no repeated provider
work, no early finalization, duplicate proposals, conflicts, invalid
proposals, and stale turn/session bindings.
- `node scripts/check-maps.mjs` and `git diff --check` passed.
- `pnpm -r typecheck` and `pnpm build` passed locally. All CI gates
passed on `2ac025a15c`; Greptile rated that commit 5/5 with no
outstanding findings. The full local `pnpm test:run` was started after
completing the embedded PostgreSQL installation, then stopped while
still running once the complete CI test matrix passed; it is not
reported as a completed local run.
- Real local acceptance passed on `2ac025a15c` with the production Rust
Runner transport, Codex CLI `0.160.0`, and `gpt-6.1-sol` on macOS arm64.
Persisted the completion proposal while retaining the older active-turn
checkpoint; let the provider finish without persisting its later
controller events; stopped the exact owned runner/provider; recovered
the same provider session and turn. Observed one accepted result, one
durable `turn.start` command, and one line in the receipt file. Hosted
sandbox restart and recovery of the original stopped task have not been
performed.
- Initial setup failures are retained: dependency drift caused
diff-viewer type errors, and skipped PostgreSQL postinstall links
prevented database startup. Dependency alignment and the package
postinstall repaired those local prerequisites. Probe setup iterations
failed on a direct-provider response schema, invalid probe input fields,
and an original provider that still held its writer lock. Acceptance
uses the production transport, validated input, and exact-owner
shutdown. No production code changes were made for those probe setup
failures.

## Risks

- A stale proposal could finalize the wrong work. Recovery requires the
checkpoint's active turn and matching run, session, and source. It
rejects conflicting results and waits for provider termination.
- The change uses the existing paginated recovery scan. It adds no
database query per event or new retry allowance.
- No schema migration or change to task authorization is included.

## Model Used

OpenAI GPT-6, running as Codex with reasoning, tool use, and code
execution. The exact served model snapshot and context-window size are
not exposed in this session. The live acceptance probe uses
`gpt-6.1-sol`.

## 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-10-20 09:09:22 -05:00
..

Paperclip agent access map

This map accompanies the feature map. It records APIs, agent entry points, permission boundaries and verification for the same capability IDs. The shared contract defines the format and maintenance rules.

Browse access contracts

The same-named feature recipes define navigation and capability IDs. Run node scripts/storybook-catalog.mjs for the generated maps/generated/agent-access-map.md index, or browse the published feature guide. Add or update the affected companion; there is no central registration or count.

Existing baseline source references describe the original inspection, not current verification. Record new executed evidence in the PR, issue, or CI artifact with its revision and scope. Do not refresh unrelated headers as bookkeeping.

Using an entry

Read its Policy and Gaps before selecting an agent path. Native fallback, legacy REST/CLI, stdio MCP and a personal assistant connection can have different authority and availability. Use a real admitted production binding; a scenario declaration is not an installed tool. A restricted entry records current enforcement and leaves any unresolved delegation decision visible.

For API catalog disagreements, follow the route/service authorization and record discovery drift. For not-applicable, retain the concrete exception and local path. Split shared business operations from client-only presentation.

Use maintain-verification-skill to reconcile changed source and both maps. Use verify-paperclip and existing API/runner/MCP fixtures to collect the permitted-agent and denial evidence; report blocked/not-run coverage honestly. Run node scripts/check-maps.mjs after editing. The structural check does not certify permissions, API catalog coverage, tool admission or live behavior.

Native REST transport

The call_api parity change reconciles affected baselines against 58e16dbddfc9c8d0cf60867f9d9847f0feda055b and the changes in this PR. Ordinary REST operations use the same route authorization as legacy agent REST. Dedicated tools remain optional for those operations; protocol endpoints still need their existing clients. Board-only routes remain restricted for agent identity.

Native search_api / call_api requires operator rollout admission, a running authorized native run, current task assignment and execution-run binding, company and budget authority, task privacy, and a permitted work mode. Ask and Plan retain mutation restrictions, and runs retain their admitted JWT scope during restart recovery even when task mode changes. A waiting agent does not gain independent native control just because a REST route exists.

Credential-bearing replies, including company exports and their legacy alias, stay inline under a 10 MiB limit and use encrypted mutation receipts. Other saved API snapshots are limited to the issuing actor and responsible user, plus authorized administrators. Artifact uploads enforce the same access checks as downloads; private snapshots are excluded from company exports and public company logos. Explicit deliverables use the existing sharing path. Native event history, checkpoints and completion records omit API bodies while preserving receipt metadata and replay digests. Restored webhook secrets use the same encrypted receipt and inline response policy as newly created webhook secrets. Task image access requires the company boundary and the task permission; skill-test and low-trust agents do not need company-wide browsing authority. Completion replay applies the same idempotent projection to stored and expected payloads; the run-log guide describes its fields.

Sources: API client, catalog, native authority, credential storage classification, snapshot access, and history redaction. The affected entries remain baseline and source-only; this reconciliation does not certify every operation. Targeted real-route proof lives in the API integration suite, including owned routines, skill tests, scoped secrets, proposals and private export replay.