Skip to content

fix(subagent): recover terminal transcript before lost context#94420

Draft
yu-xin-c wants to merge 1 commit into
openclaw:mainfrom
yu-xin-c:openmeta/90299-subagent-terminal-boundary
Draft

fix(subagent): recover terminal transcript before lost context#94420
yu-xin-c wants to merge 1 commit into
openclaw:mainfrom
yu-xin-c:openmeta/90299-subagent-terminal-boundary

Conversation

@yu-xin-c

@yu-xin-c yu-xin-c commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #90299.

Summary

This keeps the lost-context sweeper from reporting a failed subagent when the current run already wrote a successful terminal assistant turn to its private transcript.

The new path is deliberately narrower than display-output recovery: it reads only entry.execution.transcriptFile, ignores copied stale history before the registry run start, and accepts only an explicit successful terminal stopReason (stop/end_turn). error, aborted, and toolUse turns still fall through to the existing recovery/error paths.

Real behavior proof

Behavior addressed:
When the subagent registry sweeper loses the in-memory run context, it now checks the current run's private transcript before emitting subagent run lost active execution context. A successful recovery requires a current-run assistant terminal turn, not merely visible/displayed output.

Real environment tested:
Local OpenClaw worktree on macOS after pnpm install --frozen-lockfile. The live proof below ran OpenClaw source through tsx, wrote an actual private JSONL transcript on disk, and invoked the real transcript-reader-backed resolveCompletionFromCurrentRunTranscript helper outside Vitest/CI.

Exact steps or command run after this patch:

  • Ran a local pnpm exec tsx -e '...' script that created a private child transcript containing one stale copied assistant result before startedAt and one current assistant turn with stopReason: "stop", then called resolveCompletionFromCurrentRunTranscript against that file.
  • Ran node scripts/run-vitest.mjs src/agents/subagent-session-reconciliation.test.ts src/agents/subagent-registry.test.ts.
  • Ran node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental false.
  • Ran pnpm exec oxfmt --check --threads=1 src/agents/subagent-session-reconciliation.ts src/agents/subagent-registry.ts src/agents/subagent-session-reconciliation.test.ts src/agents/subagent-registry.test.ts.
  • Ran node scripts/run-oxlint.mjs src/agents/subagent-session-reconciliation.ts src/agents/subagent-registry.ts src/agents/subagent-session-reconciliation.test.ts src/agents/subagent-registry.test.ts.

Evidence after fix:
Copied terminal output from the local OpenClaw live proof command:

[openclaw live proof] command=resolveCompletionFromCurrentRunTranscript
[openclaw live proof] transcriptFile=$TMPDIR/openclaw-real-proof-EfMJfc/child-run.jsonl
[openclaw live proof] recoveredStatus=ok
[openclaw live proof] recoveredReason=subagent-complete
[openclaw live proof] recoveredResult=current private terminal result
[openclaw live proof] staleCopiedOutputIgnored=true
[openclaw live proof] endedAtMatchedTerminalTurn=true

Observed result after fix:
The real transcript reader recovered status=ok from the current private terminal turn, ignored the stale copied pre-run output, and used the terminal turn timestamp instead of the fallback lost-context time. The focused registry regression also completes the stale active run as ok and preserves private transcript result instead of emitting the lost-context error.

What was not tested:
No live Agent Teams UI/gateway conversation was run manually. The live proof covers the private transcript recovery boundary directly, and the focused registry test covers the sweeper path with the session store still reporting status: running.

Validation

  • node scripts/run-vitest.mjs src/agents/subagent-session-reconciliation.test.ts src/agents/subagent-registry.test.ts -> 2 files passed, 71 tests passed.
  • node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental false -> exited 0.
  • pnpm exec oxfmt --check --threads=1 ... -> all matched files use the correct format.
  • node scripts/run-oxlint.mjs ... -> exited 0.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 18, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 7, 2026, 7:01 AM ET / 11:01 UTC.

Summary
The branch adds a current-run private transcript recovery path so stale active subagent runs can complete successfully before the lost-context fallback when the latest assistant turn has a successful terminal stop reason.

PR surface: Source +152, Tests +222. Total +374 across 4 files.

Reproducibility: yes. source-reproducible: current main can reach the stale active-run lost-context fallback after session-store reconciliation returns null, while the announcement path can still attach child output to a failed outcome. I did not run a live Agent Teams race in this read-only review.

Review metrics: 1 noteworthy metric.

  • Lifecycle recovery predicate: 1 recovery branch added. The diff changes whether stale active subagent runs settle as failed or successful before parent delivery.

Stored data model
Persistent data-model change detected: serialized state: src/agents/subagent-registry.test.ts, serialized state: src/agents/subagent-session-reconciliation.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #90299
Summary: This PR is a candidate fix for the canonical Agent Teams lost-context/output mismatch; earlier broad-output attempts are closed and adjacent delivery PRs do not replace this exact predicate.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Refresh the draft branch against current main and run exact-head focused validation before merge.
  • Maintainers should decide whether the transcript-reader proof is sufficient or require live Gateway race proof.

Risk before merge

  • [P1] A false-positive terminal predicate would convert an actually incomplete or stale child run from lost-context failure to success, affecting parent/child session state.
  • [P1] The PR is still a draft and should be refreshed and validated against current main before any merge decision.
  • [P1] The supplied proof exercises the transcript-reader boundary over on-disk JSONL, but it does not prove a full live Gateway race that loses execution context mid-run.

Maintainer options:

  1. Proceed After Exact-Head Refresh (recommended)
    Accept the bounded lifecycle risk once the draft is refreshed against current main and the focused agent/session validation is clean.
  2. Ask For Live Race Proof
    Require a live Agent Teams or Gateway transcript proving the lost-context race recovery if transcript-reader proof is not enough for this state transition.
  3. Pause Behind Adjacent Delivery Work
    Leave the PR unmerged if maintainers want broader subagent delivery/accounting changes to settle before this narrower recovery branch.

Next step before merge

  • [P2] The remaining action is maintainer review of the draft branch, exact-head validation, and acceptance of the recovery predicate; no narrow automated repair is identified.

Maintainer decision needed

  • Question: Should this draft PR land with the current private transcript terminal-turn predicate as the recovery boundary for the linked Agent Teams lost-context/output mismatch?
  • Rationale: The code path intentionally changes stale subagent lifecycle outcomes from failed to successful based on private transcript state, and that session/message-delivery semantic choice needs maintainer acceptance even though the patch is narrowly implemented.
  • Likely owner: vincentkoc — The history and prior review context make vincentkoc the best available owner for the recovery-boundary choice among the likely routing candidates.
  • Options:
    • Accept Private Transcript Boundary (recommended): Proceed after a refresh and exact-head validation, accepting that stop/end_turn in the current private transcript is sufficient lifecycle proof.
    • Require Live Gateway Race Proof: Ask for an Agent Teams or Gateway proof that recreates the lost-context race before accepting the lifecycle recovery behavior.
    • Pause For Broader Delivery Work: Keep this draft paused if maintainers want to resolve adjacent subagent delivery/accounting PRs before choosing this recovery predicate.

Security
Cleared: The diff changes agent lifecycle source and tests only; no dependency, workflow, secret-handling, permissions, or package-execution concern was found.

Review details

Best possible solution:

Land or adapt the current-run private transcript recovery after maintainers accept the successful-terminal-turn predicate and exact-head validation passes on current main.

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

Yes, source-reproducible: current main can reach the stale active-run lost-context fallback after session-store reconciliation returns null, while the announcement path can still attach child output to a failed outcome. I did not run a live Agent Teams race in this read-only review.

Is this the best way to solve the issue?

Yes, provisionally: the private current-run transcript predicate is narrower than broad display-output recovery and matches the safer terminal-success direction. Final acceptance still needs maintainer review because it changes lifecycle state and parent delivery semantics.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 695fa4e112f1.

Label changes

Label justifications:

  • P2: The PR addresses a normal-priority Agent Teams lifecycle/result mismatch with limited blast radius and no crash-loop or security signal.
  • merge-risk: 🚨 session-state: The new predicate can convert an unresolved child run from lost-context error to successful completion based on private transcript state.
  • merge-risk: 🚨 message-delivery: The recovered outcome controls whether the parent receives child transcript text as a successful completion or a failed lost-context event.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes after-fix terminal output from a local run that wrote an on-disk private transcript and invoked the real transcript reader outside Vitest, plus focused validation commands.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from a local run that wrote an on-disk private transcript and invoked the real transcript reader outside Vitest, plus focused validation commands.
Evidence reviewed

PR surface:

Source +152, Tests +222. Total +374 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 152 0 +152
Tests 2 222 0 +222
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 374 0 +374

What I checked:

  • Current main fallback remains reachable: Current main still completes stale active subagent runs with the lost active execution context error after session-store reconciliation and aborted-run handling do not settle the row. (src/agents/subagent-registry.ts:1097, 695fa4e112f1)
  • Running session rows still fall through: Current main's resolveCompletionFromSessionEntry returns null for running or otherwise unsettled session entries, leaving the stale active-run sweeper fallback reachable. (src/agents/subagent-session-reconciliation.ts:160, 695fa4e112f1)
  • Failed announcements can still carry child output: The announce path can read subagent output for failed terminal outcomes, matching the reported shape where a parent sees child output alongside a lost-context failure status. (src/agents/subagent-announce.ts:403, 695fa4e112f1)
  • PR head adds private transcript predicate: The PR reads entry.execution.transcriptFile, filters to current-run assistant turns, and accepts only stop/end_turn as successful terminal stop reasons. (src/agents/subagent-session-reconciliation.ts:148, bf41c90ad744)
  • PR head wires recovery before fallback: The new sweeper branch runs after persisted session completion and aborted-run checks, stores capped result text when present, then completes with the recovered successful outcome before the old lost-context error branch. (src/agents/subagent-registry.ts:964, bf41c90ad744)
  • Transcript reader contract checked: OpenClaw's transcript reader seam resolves explicit transcript files and returns display message objects from transcript records, preserving the message fields the PR inspects. (src/gateway/session-transcript-readers.ts:140, 695fa4e112f1)

Likely related people:

  • vincentkoc: Recent subagent registry performance work touched this area, and prior review context identifies this contributor as connected to the current private-transcript boundary discussion. (role: recent area contributor and likely follow-up owner; confidence: high; commits: c4a0ca0b7a41; files: src/agents/subagent-registry.ts, src/agents/subagent-session-reconciliation.ts)
  • SebTardif: Commit 4980c32 changed the failed subagent lifecycle completion recovery path and preserved the sweeper fallback family implicated by the report. (role: adjacent behavior contributor; confidence: high; commits: 4980c32846c3; files: src/agents/subagent-registry.ts)
  • jalehman: Commit 8ded756 added the transcript reader seam that this PR uses for private transcript recovery. (role: adjacent transcript seam contributor; confidence: medium; commits: 8ded75628437; files: src/gateway/session-transcript-readers.ts, src/gateway/session-utils.fs.ts)
  • MonkeyLeeT: Commit 8a60f39 updated subagent timeout and session-store reconciliation behavior adjacent to this terminal outcome path. (role: adjacent terminal-contract contributor; confidence: medium; commits: 8a60f39221db; files: src/agents/subagent-registry.ts, src/agents/subagent-session-reconciliation.ts)
  • steipete: Shortlog history shows substantial prior work across the central subagent registry and reconciliation files, making this a useful routing candidate when ownership is shared. (role: area contributor; confidence: medium; files: src/agents/subagent-registry.ts, src/agents/subagent-session-reconciliation.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.
Review history (2 earlier review cycles)
  • reviewed 2026-06-22T03:14:19.539Z sha bf41c90 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-01T18:40:58.118Z sha bf41c90 :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added 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 rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 19, 2026
@barnacle-openclaw

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@barnacle-openclaw barnacle-openclaw Bot added the stale Marked as stale due to inactivity label Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M stale Marked as stale due to inactivity 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.

[Bug]: Agent Teams subagent completion can report "lost active execution context" while still delivering child output

1 participant