mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 11:20:42 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner reports provider failures to the execution and recovery services. > - Those services read the terminal event's structured `error` field. > - The ACPX transport-failure path wrote its code and message only at the top level. > - The session facade therefore replaced that cause with `error: null` and the generic message "Provider turn failed". > - This pull request uses the existing structured error contract while retaining the old fields. > - Recovery can retain the actual redacted cause without reopening the failed provider or assuming a retry is safe. ## Linked Issues or Issue Description **What happened?** A native ACPX run can lose its failure details between runnerd and the session facade. The transport-failure producer emits a failed turn with top-level `code` and `message`. The facade reads `error`. The server receives a generic provider failure and cannot use the original cause to explain or classify recovery. **Expected behavior** Retain the transport code and redacted cause in the structured terminal error. Keep failed sessions closed, provider termination unproven, and automatic replay disabled. **Steps to reproduce** 1. Open a native ACPX session and start a turn. 2. Send malformed activity from the sidecar after it acknowledges the turn. 3. Poll the native provider events. 4. Observe that `turn.failed.error` is absent even though the producer has a transport code and cause. Refs: #16366, #17543. Those changes cover legacy process-session diagnostics and session-ensure errors. This change repairs the native ACPX polling terminal contract. ## What Changed - Add the existing transport code and redacted message to the terminal event's structured `error` field. - Mark that error as non-recoverable. Keep the previous top-level fields for existing readers. - Add a real sidecar fault fixture and a native-provider regression. It checks one failed terminal, retained error details, a closed session, and no provider reopening. - Document the failure contract and verification scope in execution semantics and the recovery map. ## Verification - Red: the new fault test failed because the structured transport error code was null on the original code. - Green: all 26 native-provider integration tests pass with the fix. - Three session-facade terminal tests and three native-runtime provider-failure classification tests pass. - `pnpm -r typecheck` and `pnpm build` pass. - Hosted test partitions, native Runner checks, typecheck, build, browser shards and canary passed. Two final aggregate jobs received no runner for several minutes. The first CI attempt was cancelled after saving its status, and only those two cancelled jobs were resubmitted. Both aggregate jobs passed on attempt 2. The current head has 55 successful checks, four expected skips and successful Snyk status. - `git diff --check`, `node scripts/check-module-boundaries.mjs`, and `node scripts/check-maps.mjs` pass. - The full local Vitest suite is not run for this patch. The local filesystem fell below 500 MiB free during verification. The preceding full-suite attempt crashed embedded PostgreSQL; focused checks and CI are used without claiming that attempt passed. - Live incident: verified the exact predecessor sandbox was destroyed and workspace recovery completed. An audited user retry through the normal task-retry service started one new native run. That attempt preserved the original question but failed before provider startup with a missing workspace-sync descriptor binding. The startup race is fixed separately in #17838. A later audited retry completed successfully, saved its useful answer and restored its workspace. The agent API handoff failed; an audited operator repair through the normal issue service completed the required user assignment in Review without repeating the comment or provider work. This verifies recovery admission on the existing deployment; the new Runner change is not deployed yet. - Evidence limit: the historical terminal had `error: null` and its raw sidecar frame was not retained. Fault injection proves this producer defect and the same loss of diagnostics. It does not establish which transport fault caused the historical turn to end. ## Risks - Recovery now receives a specific transport failure code. The error remains non-recoverable and `providerTerminalObserved` remains false. Stop proof, effect reconciliation, workspace preservation, retry limits, and normal execution authority still govern any successor. - This change preserves diagnostics. It does not make a malformed or lost provider connection healthy. - No schema migration, credentials, provider selection, or model settings change. ## Model Used OpenAI Codex, GPT-6 family, with reasoning, source inspection, tool use, and code execution. The runtime does not expose the exact model ID or context window size. ## 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>