Skip to content

fix(sessions): recover startup only for newly created sessions - #858

Merged
steipete merged 4 commits into
openclaw:mainfrom
superbiche:fix/shared-first-turn-fresh-session
Oct 7, 2026
Merged

steipete merged 4 commits into
openclaw:mainfrom
superbiche:fix/shared-first-turn-fresh-session

Conversation

@superbiche

@superbiche superbiche commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

What Problem This Solves

A newly created persistent runtime session can fail its first prompt or control with SESSION_RESUME_REQUIRED when the adapter returns an ACP internal load/resume error for that empty session.

User Impact

A session confirmed to originate from session/new can recover from that specific -32603 load error with a fresh backend and restored preferences. Explicit native resumes, legacy records without creation provenance, imported sessions, and prior conversation activity keep requiring the original backend under same-session-only policy. The existing allow-fresh policy is unchanged. Thanks @superbiche.

Why This Change Was Made

Empty local history does not prove that a backend is new: an explicit native resume can return no replay while remote context still exists. CLI and runtime creation therefore persist a small session_origin value, parsing preserves known values, and state cloning retains it through model/mode acknowledgements. Recovery also excludes earlier prompts (including cancelled turns), agent output, and legacy Resume markers. Prompt callers distinguish their newly recorded current message from prior history. Missing-session and unsupported-load refusals and settings restoration remain intact.

Evidence

Baseline tests reproduced the first-turn failure. Maintainer tests also reproduced replacement attempts for legacy Resume markers and for an explicit native resume after actual creation, disk save, reload, and later load failure. The final candidate refuses those replacements; older records with unknown origin retain their prior strict behavior.

All 214 focused compiled reconnect, runtime-manager, persistence, identity, offline-control, and shared-runtime tests pass. Independent Codex review through P2 is clean after the provenance and state-cloning repairs. Final pnpm run check && pnpm run check:docs passed on isolated Linux with Node 24.19.0: 3,042 main-suite tests passed (15 skipped), all 210 coverage tests passed, and every coverage threshold was met. The synchronized agent and skill guides also passed their targeted formatter and Markdown checks.

The contributor's earlier real-adapter proof with the official Codex ACP adapter demonstrated the original recovery path and restoration of saved model/effort, plus native-ID preservation after cancellation. Current-head synthetic tests additionally validate creation provenance and the stricter history guards; no new hosted-provider run is claimed for those bookkeeping changes.

@superbiche
superbiche requested a review from a team as a code owner October 4, 2026 23:41
@clawsweeper

clawsweeper Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Oct 4, 2026
@clawsweeper

clawsweeper Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed October 7, 2026, 1:21 AM ET / 05:21 UTC (Revision 3).

ClawSweeper review

What this changes

The PR records how sessions were created and permits first-prompt or control recovery after an internal ACP load error only for confirmed new sessions without earlier conversation activity.

Merge readiness

✅ Ready for maintainer review

This PR remains necessary: current main still rejects the reported startup failure. The narrowed recovery preserves existing-session continuity, and no blocking correctness or security defect was found.

Priority: P2
Reviewed head: f4b6dbc2aea10f9553d952bab3746a1b33c9046c

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, well-supported repair with conservative continuity guards and no remaining actionable finding.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (terminal): Earlier-head terminal evidence exercises the real shared-runtime first turn through the official Codex ACP adapter and observes successful recovery with restored model/effort; current-head guards narrow that same path. Saved-state compatibility is supported by optional-field parsing, strict legacy behavior, round-trip coverage, and explicit-resume reload tests.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): Earlier-head terminal evidence exercises the real shared-runtime first turn through the official Codex ACP adapter and observes successful recovery with restored model/effort; current-head guards narrow that same path. Saved-state compatibility is supported by optional-field parsing, strict legacy behavior, round-trip coverage, and explicit-resume reload tests.
Evidence reviewed 8 items Pinned introduction reviewed: Reviewed all introduced production, documentation, and test hunks between the pinned main and PR head. The checkout matches the original head, and the supplied verified test merge has those exact main and head parents.
Current main still needs the fix: Current main unconditionally throws SESSION_RESUME_REQUIRED for a same-session-only load failure. Inspection of v0.19.4 showed the same strict recovery path. Canonical searches found no verified merged replacement implementing this startup exception.
Recovery eligibility and caller ordering: Fresh recovery requires session_origin=new, no import provenance, no agent messages or Resume marker, and no prior user prompt. Both prompt callers record their current message before connecting; control callers omit promptRecorded. Unsupported and missing-session errors remain excluded under same-session-only policy.
Findings None None.
Security None None.

How this fits together

acpx manages persistent agent sessions for CLI callers and embedded runtimes. Its reconnect layer loads the saved backend session, restores preferences, and either continues execution or reports a resume failure.

flowchart TD
  A[Prompt or control] --> B[Saved session record]
  B --> C[Load original backend]
  C --> D[Internal load failure]
  D --> E[Check creation and history]
  E --> F[Create backend and restore preferences]
  E --> G[Report resume required]
Loading

Before merge

None.

Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production and test growth production +82/-9 lines; tests +581/-0 lines Production growth implements creation provenance and bounded recovery eligibility, with most added lines devoted to regression coverage.

Technical review

Best possible solution:

Retain the provenance-gated startup exception while preserving original backend identity for every session with existing or uncertain context.

Do we have a high-confidence way to reproduce the issue?

Yes: current-main source deterministically rejects an internal load error under same-session-only policy, and the captured real-adapter transcript demonstrates the first-turn symptom on stock acpx. No current-main execution was performed during this review.

Is this the best way to solve the issue?

Yes: the exception reuses existing session creation and preference replay while adding conservative provenance and history checks, rather than weakening continuity for existing sessions.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 9f40f24d4e64.

Labels

Label changes:

No label changes.

Label justifications:

  • P2: This repairs a specific first-turn persistent-session failure without evidence of a broader urgent outage.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Earlier-head terminal evidence exercises the real shared-runtime first turn through the official Codex ACP adapter and observes successful recovery with restored model/effort; current-head guards narrow that same path. Saved-state compatibility is supported by optional-field parsing, strict legacy behavior, round-trip coverage, and explicit-resume reload tests.
  • proof: sufficient: Contributor real behavior proof is sufficient. Earlier-head terminal evidence exercises the real shared-runtime first turn through the official Codex ACP adapter and observes successful recovery with restored model/effort; current-head guards narrow that same path. Saved-state compatibility is supported by optional-field parsing, strict legacy behavior, round-trip coverage, and explicit-resume reload tests.

Evidence

What I checked:

  • Pinned introduction reviewed: Reviewed all introduced production, documentation, and test hunks between the pinned main and PR head. The checkout matches the original head, and the supplied verified test merge has those exact main and head parents. (f4b6dbc2aea1)
  • Current main still needs the fix: Current main unconditionally throws SESSION_RESUME_REQUIRED for a same-session-only load failure. Inspection of v0.19.4 showed the same strict recovery path. Canonical searches found no verified merged replacement implementing this startup exception. (src/runtime/engine/reconnect.ts:878, 9f40f24d4e64)
  • Recovery eligibility and caller ordering: Fresh recovery requires session_origin=new, no import provenance, no agent messages or Resume marker, and no prior user prompt. Both prompt callers record their current message before connecting; control callers omit promptRecorded. Unsupported and missing-session errors remain excluded under same-session-only policy. (src/runtime/engine/reconnect.ts:924, f4b6dbc2aea1)
  • Real adapter evidence retained: The captured contributor comment at fix(sessions): recover startup only for newly created sessions #858 (comment) compares stock acpx 0.19.1 with branch aa1509c using the official Codex ACP adapter. The shared-runtime first turn changes from SESSION_RESUME_REQUIRED to completed, with a replacement native ID and saved model/effort observed in the backend rollout. A cancelled-turn follow-up preserves its native ID. This is earlier-head terminal proof; current-head tests supplement the subsequently tightened provenance guards. (aa1509c932a8)
  • Stored-state compatibility: The optional provenance field preserves the existing session schema. Parsing accepts only new/resume and leaves older or unknown origins ineligible for recovery; serialization retains the acpx state and cloning preserves provenance through settings acknowledgements. Added tests cover round trips, legacy origins, explicit native resume after disk reload, imports, prior prompts, and cancelled turns. (src/session/persistence/parse.ts:441, f4b6dbc2aea1)
  • Validation and review continuity: The captured body reports 214 focused tests and successful full code/docs checks on Node 24.19.0. These were not rerun during this read-only review. The previous completed review retained no findings or published rank-up moves; its real-adapter evidence remains relevant to the recovery path narrowed by this head. (f4b6dbc2aea1)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • saariuslystoned: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (2 earlier review cycles)
  • reviewed 2026-10-04T23:45:24.542Z sha aa1509c :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-05T00:01:10.407Z sha aa1509c :: needs maintainer review before merge. :: none

@superbiche

Copy link
Copy Markdown
Contributor Author

Live proof for the first-turn recovery, with the official @agentclientprotocol/codex-acp 1.1.14 and the same script run against stock acpx 0.19.1 and against this branch (aa1509c, built locally).

The scenario is the same in both runs:

  1. acpx --agent <codex-acp> sessions new --name <name>
  2. set model gpt-6-luna and set reasoning_effort low
  3. createSharedAcpRuntime().ensureSession + startTurn("Reply with exactly the word PONG.")

Native session IDs are read from the session record before and after the turn. Home paths are trimmed, and the saved config catalog is shortened to the selected values.

acpx 0.19.1: the first turn fails, and the native session is kept but unusable.

23:48:30Z A.new 01a10951-a9ee-7172-b803-966752577514
23:48:41Z A.set-model model set: gpt-6-luna
23:48:52Z A.set-effort config set: reasoning_effort=low (5 options)
23:49:02Z A.before {"acpSessionId":"01a10952-013f-7811-ba84-e46ffecf91d0","messages":0}
23:49:03Z A.result {"status":"failed","error":{"message":"Persistent ACP session 01a10952-013f-7811-ba84-e46ffecf91d0 could not be resumed: Internal error","code":"RUNTIME","detailCode":"SESSION_RESUME_REQUIRED","retryable":true}}
23:49:03Z A.after {"acpSessionId":"01a10952-013f-7811-ba84-e46ffecf91d0","replaced":false,"messages":1}

This branch: the first turn completes on a replacement session.

23:49:14Z A.new cca2fc25-15a4-428a-8a2e-89c529651927
23:49:25Z A.set-model model set: gpt-6-luna
23:49:37Z A.set-effort config set: reasoning_effort=low (5 options)
23:49:46Z A.before {"acpSessionId":"01a10952-afe5-75d2-b5ca-8438a9238a73","messages":0}
23:49:51Z A.result {"status":"completed","stopReason":"end_turn"}
23:49:51Z A.after {"acpSessionId":"01a10952-dbc2-7013-b2dd-32cf8f2d6900","replaced":true,"messages":2}

The saved preferences reach the replacement session. Codex's own rollout for thread 01a10952-dbc2-7013-b2dd-32cf8f2d6900 records turn_context model gpt-6-luna, effort low.

The same check with a codex-acp build that returns a per-turn configuration receipt (_meta.codex.turnConfiguration) reports requested and threadSettings of gpt-6-luna / low with no model reroutes.

Cancelled first prompt, then restart and an offline control (AcpxRuntime, this branch, run with the receipt-capable codex-acp build):

23:39:24Z B.first {"status":"cancelled","stopReason":"cancelled"}
23:39:25Z B.before {"acpSessionId":"01a10949-54b9-7393-9140-95afb46df395","messages":["User"]}
23:39:26Z B.control accepted
23:39:26Z B.after {"acpSessionId":"01a10949-54b9-7393-9140-95afb46df395","preserved":true}

Codex kept a rollout for the cancelled turn, so it resumed and the native ID did not change. The refusal path, where a session with a recorded prompt fails to load with -32603, cannot be triggered with live Codex after a cancelled turn. test/runtime-offline-controls.test.ts and test/shared-runtime.test.ts cover it with the mock adapter.


@superbiche · contributor · drafted with Claude Opus 5.5, reviewed before posting; the voice and decisions are mine.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. labels Oct 5, 2026
@steipete
steipete force-pushed the fix/shared-first-turn-fresh-session branch from aa1509c to f4b6dbc Compare October 7, 2026 05:16
@steipete steipete self-assigned this Oct 7, 2026
@steipete steipete changed the title fix: first turn of a new persistent session fails with SESSION_RESUME_REQUIRED when the agent cannot resume it fix(sessions): recover startup only for newly created sessions Oct 7, 2026
@steipete
steipete merged commit b3cd843 into openclaw:main Oct 7, 2026
13 of 14 checks passed
@steipete

steipete commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Landed in b3cd843. Thanks @superbiche; Michel Tomas's co-author credit is preserved.

The baseline first-turn failure was reproduced. Additional regressions reproduced unsafe replacement attempts for Resume-only history and for an explicitly resumed backend after actual creation, disk save, and reload with no replay. The final same-session-only recovery requires persisted session/new provenance; explicit resumes, unknown legacy origins, imports, prior prompts, agent output, and Resume markers keep the original backend. State updates preserve that provenance, and the existing allow-fresh policy is unchanged.

Proof: 214 focused compiled tests; full Linux check with 3,042 passes (15 skips); 210 coverage passes; documentation plus agent/skill-guide checks; and clean independent review through P2. Exact-head CI passed on f4b6dbc: https://github.com/openclaw/acpx/actions/runs/37575516301.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants