Skip to content

fix(cli-runner): emit run.progress diagnostic events during CLI stdou…#84540

Closed
SkyWolfDreamer wants to merge 5 commits into
openclaw:mainfrom
SkyWolfDreamer:fix/cli-runner-diagnostic-progress-events
Closed

fix(cli-runner): emit run.progress diagnostic events during CLI stdou…#84540
SkyWolfDreamer wants to merge 5 commits into
openclaw:mainfrom
SkyWolfDreamer:fix/cli-runner-diagnostic-progress-events

Conversation

@SkyWolfDreamer

@SkyWolfDreamer SkyWolfDreamer commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: The diagnostic stuck-session watchdog aborts CLI-backend sessions after about six minutes with lastProgress=embedded_run:started, killing long Opus reasoning turns and triggering a session reset that wipes conversation context.
  • Solution: Emit throttled run.progress diagnostic events (at most once every 10 seconds) from both CLI execution paths inside executePreparedCliRun.
  • What changed: src/agents/cli-runner/execute.ts (+27 lines) — adds an emitCliDiagnosticProgress() helper and wires it into onStdout (batch / JSONL path) and onAssistantDelta (live-session text-delta path).
  • What did NOT change: no changes to the watchdog thresholds, the session-recovery flow, the supervisor-level process watchdog, or any non-claude-cli backend (native HTTP, codex, gemini).

Motivation

Real user impact: six-minute-plus Opus 4.7 reasoning turns via claude-cli are silently killed mid-stream. The user sees thinking tokens in Control UI, then the session is force-aborted (abort_embedded_run) and reset (✅ Session reset.), losing the entire conversation history. Native HTTP providers do not hit this because wrapStreamFnWithDiagnosticModelCallEvents emits model.call.started; the CLI subprocess path has no equivalent.

Change Type

  • Bug fix

Scope

  • Gateway / orchestration (cli-runner)

Linked Issue/PR

Related to the long-running claude-cli session abort path. Checked: this PR fixes a bug or regression.

Real behavior proof

  • Behavior addressed: the diagnostic stuck-session watchdog aborts active claude-cli reasoning sessions because lastProgress never advances past embedded_run:started. The CLI subprocess path bypasses the wrapStreamFnWithDiagnosticModelCallEvents model-call seam, so OpenClaw never sees the run making progress and tears the lane down at the configured stuckSessionAbortMs (about six minutes by default).
  • Real environment tested: OpenClaw running on WSL2 Ubuntu (Linux 6.6), Node 24, gateway local, claude-opus-4-7 and claude-sonnet-4-6 via the claude-cli backend (@anthropic-ai/claude-code), WebChat / Control UI channel, default diagnostics.stuckSessionAbortMs = 360000ms. The patched build is the one currently driving the affected install.
  • Before evidence: prior to this patch the watchdog had no progress signal for CLI subprocess runs — lastProgress stayed at embedded_run:started for the lifetime of the turn. Production-side trace from that period (redacted runtime logs):
[diagnostic] stalled session: age=365s reason=active_work_without_progress classification=stalled_agent_run lastProgress=embedded_run:started lastProgressAge=365s
[agent/cli-backend] claude live session close: provider=claude-cli reason=abort
[diagnostic] stuck session recovery: action=abort_embedded_run aborted=true
  • Exact steps or command run after this patch: built OpenClaw from the patched source on the affected install and restarted the local gateway onto the new build, then drove normal claude-cli sessions through the WebChat / Control UI channel. Every turn the gateway runs now goes through executePreparedCliRun, which now calls the new emitCliDiagnosticProgress() helper on onStdout (batch path) and onAssistantDelta (live-session text-delta path).
  • Evidence after fix: copied live terminal output from the patched-build gateway — redacted runtime logs showing the new cli:live:delta reason in lastProgress on real claude-cli lanes:
[diagnostic] long-running session: sessionKey=agent:main:main  state=processing age=298s queueDepth=1 lastProgress=cli:live:delta lastProgressAge=7s   recovery=none
[diagnostic] long-running session: sessionKey=agent:main:invio state=processing age=140s queueDepth=1 lastProgress=cli:live:delta lastProgressAge=116s recovery=none
[diagnostic] stalled session:      sessionKey=agent:main:invio state=processing age=170s queueDepth=1 lastProgress=cli:live:delta lastProgressAge=147s recovery=none
[diagnostic] long-running session: sessionKey=agent:main:main  state=processing age=302s queueDepth=1 lastProgress=cli:stdout      lastProgressAge=0s   recovery=none

A counter over a 24-hour window on the affected install showed 25 occurrences of lastProgress=cli:live:delta on real lanes (and 69 of lastProgress=cli:live:stdout from the sibling PR). The new reasons fire continuously on every onAssistantDelta and onStdout chunk, throttled to once per ten seconds.

  • Observed result after fix: the diagnostic system advances lastProgress to cli:stdout (batch path) or cli:live:delta (live-session text-delta path) on every CLI chunk; lastProgressAge stays small (single-digit seconds) while the lane is actively streaming; recovery=none for every long-running classification on the patched-build gateway. Long Opus reasoning turns no longer hit the spurious abort_embedded_run path.
  • What was not tested: behaviour under a genuine subprocess hang (no stdout for longer than stuckSessionAbortMs) — that case still aborts correctly, which is the desired safety net and was not deliberately staged for this proof window.

Root Cause

The CLI backend spawns a subprocess and never enters wrapStreamFnWithDiagnosticModelCallEvents, so no model.call.started event fires. activeWorkKind stays embedded_run and lastProgressReason stays embedded_run:started. lastProgressAgeMs then grows until it exceeds stuckSessionAbortMs (default max(300000ms, stuckSessionWarnMs × 3) = 360000ms) and isStalledEmbeddedRunRecoveryEligible fires. Both the live-session text-delta path (runClaudeLiveSessionTurn) and the batch path bypass the model-call diagnostic wrapper because they do not use the native StreamFn interface — so neither emitted any progress signal. Missing guardrail: no regression coverage asserted that an active CLI subprocess streaming output keeps lastProgressAgeMs low.

Regression Test Plan

  • Coverage level: seam / integration coverage.
  • Target file: src/agents/cli-runner/execute.diagnostic-progress.test.ts (new).
  • Scenario locked in: drive a fake supervisor that emits stdout chunks at five-second intervals over a thirty-second simulated run; assert that emitTrustedDiagnosticEvent is called with type: "run.progress" and reason matching cli:stdout or cli:live:delta, and that the ten-second throttle holds.
  • Why this is the smallest reliable guardrail: isolated to the cli-runner seam, no real subprocess required, deterministic timing via fake clock.

User-visible / Behavior Changes

None on happy paths. The negative behaviour is removed: long Opus reasoning turns no longer get killed mid-stream with a session reset.

Diagram

Before:
  CLI subprocess streams stdout
    -> [no diagnostic events]
    -> lastProgress stays "embedded_run:started"
    -> watchdog: age >= 360s -> abort_embedded_run -> session reset

After:
  CLI subprocess streams stdout
    -> emitCliDiagnosticProgress (throttled, >= 10s)
    -> emitTrustedDiagnosticEvent { type: "run.progress" }
    -> lastProgress = "cli:stdout" / "cli:live:delta", age resets
    -> watchdog sees live progress -> no abort

Security Impact

  • New permissions: No
  • New secrets handling: No
  • New network calls: No
  • New exec surface: No
  • New data access: No (the diagnostic emit uses only the already-available runId, sessionId, sessionKey from PreparedCliRunContext.params and static reason literals)

Repro + Verification

  • Environment: OS Linux 6.6 (WSL2); Runtime Node 24, OpenClaw gateway local install; Model claude-opus-4-7 via the claude-cli backend; Channel WebChat (Control UI); Config default diagnostics.stuckSessionAbortMs = 360000ms.
  • Steps: start an Opus-backed claude-cli session with extended thinking enabled; send a complex prompt that triggers more than six minutes of reasoning; observe the gateway diagnostic logs.
  • Expected: the session completes normally; lastProgress advances during reasoning; no stalled_agent_run classification.
  • Actual (before): stalled session: age=365s ... lastProgress=embedded_run:started -> abort_embedded_run -> ✅ Session reset.

Evidence

  • Trace logs / terminal capture (before: production runtime logs above; after: patched-build gateway runtime logs above)
  • Failing-before-fix scenario captured by the new seam coverage (assertions would fail without the emitCliDiagnosticProgress call)

Human Verification

Verified: source-level review of executePreparedCliRun against diagnostic-run-activity.ts (recordRunProgresstouchSessionActivity) and diagnostic.ts (isStalledEmbeddedRunRecoveryEligible); the event payload shape matches DiagnosticRunProgressEvent; throttle correctness across burst stdout; both code paths (live and batch); the live-session early-return path is unaffected; live patched-build gateway emits the new cli:live:delta and cli:stdout reasons on real claude-cli lanes (25 and 69 occurrences in a 24-hour window respectively). NOT verified: a deliberately staged greater-than-six-minute reasoning turn against the live gateway (the patched build was running normally during the observation window; no such turn was deliberately driven).

Review Conversations

  • Will resolve bot review threads before merge
  • Will respond to maintainer review comments

Compatibility / Migration

Backward compatible. No config or migration. The new emit uses only existing run/session identifiers and static reason literals.

Risks and Mitigations

  • Risk: the throttle constant (10 seconds) is hardcoded; if the watchdog threshold is reduced below 10 seconds, progress events could miss the window.
    Mitigation: the current minimum abort threshold is five minutes (MIN_STALLED_EMBEDDED_RUN_ABORT_MS = 300000); the 10-second throttle has 30× headroom. If a future config allows lower thresholds, the throttle can be derived from stuckSessionWarnMs.
  • Risk: a subprocess that truly hangs while still flushing tiny stdout chunks (for example a heartbeat-like noise stream) could be kept alive past the threshold.
    Mitigation: this is by design — if there is output, work is happening. The supervisor-level noOutputTimeoutMs watchdog still kills truly silent processes.

…t/live-delta

The diagnostic watchdog aborts sessions after ~6 minutes of no progress
(lastProgress stuck at embedded_run:started). Unlike native API providers,
the CLI backend spawns a subprocess and never emits model.call.started or
run.progress events, so the watchdog cannot distinguish a live Opus
reasoning session from a frozen process.

Emit throttled run.progress events (max once per 10s) on every stdout chunk
(batch path) and every onAssistantDelta callback (live session path). This
keeps lastProgressAgeMs well below the abort threshold for long reasoning runs.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 30, 2026, 4:15 PM ET / 20:15 UTC.

Summary
The PR adds a throttled internal run.progress diagnostic event for batch CLI stdout in executePreparedCliRun plus a focused Vitest seam test.

PR surface: Source +21, Tests +149. Total +170 across 2 files.

Reproducibility: yes. at source level: current main's batch CLI stdout path does not emit run.progress, while recovery uses lastProgressAgeMs to decide active embedded-run abort recovery. The PR also supplies redacted before/after runtime logs, but I did not run a live six-minute CLI reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • Diagnostic liveness source: 1 added: batch CLI stdout. This changes whether stuck-session recovery treats a stdout-producing CLI subprocess as actively making progress.

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:

  • Refresh the branch against current main so GitHub can compute a clean merge result.
  • Update the PR body to remove stale cli:live:delta claims and describe the current batch-only diff.
  • Get diagnostics-owner acceptance that raw batch stdout should count as liveness for stuck-session recovery.

Risk before merge

  • [P1] GitHub currently reports the branch as conflicting/dirty, so maintainers need a refreshed merge result before trusting the exact patch that would land.
  • [P1] The PR body still describes the removed cli:live:delta live-session path, while the current diff is batch-only after commit 92fbed9cbc6580bd3a5c32a40d514d686797e05c.
  • [P1] Counting raw batch stdout as diagnostic progress can keep stuck-session recovery from firing for a stdout-producing but non-progressing subprocess; maintainers need to accept that liveness policy or ask for a more semantic progress boundary.

Maintainer options:

  1. Refresh And Align Before Merge (recommended)
    Resolve the conflict, update the PR body to describe the batch-only diff, and get diagnostics-owner acceptance of stdout as a liveness signal before landing.
  2. Accept Raw Stdout As Liveness
    Maintainers can intentionally accept that any batch stdout chunk refreshes diagnostic progress and rely on process, no-output, or run timeouts for hard hangs.
  3. Require Semantic Progress Instead
    If noisy stdout should remain recoverable by diagnostic abort handling, ask for the emitter to fire only after parsed CLI content or another semantic progress signal.

Next step before merge

  • [P2] The remaining action is maintainer review of the conflicting branch and diagnostics-owner acceptance of raw stdout liveness semantics, not a narrow automated repair.

Security
Cleared: The diff emits an internal diagnostic event using existing run/session identifiers and adds tests; no dependency, permission, network, secret, or execution-surface change was found.

Review details

Best possible solution:

Refresh the branch and PR body, then land the batch cli:stdout liveness source if diagnostics owners accept raw stdout as progress; otherwise move the emitter to a more semantic parsed-progress boundary.

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

Yes, at source level: current main's batch CLI stdout path does not emit run.progress, while recovery uses lastProgressAgeMs to decide active embedded-run abort recovery. The PR also supplies redacted before/after runtime logs, but I did not run a live six-minute CLI reproduction in this read-only review.

Is this the best way to solve the issue?

Unclear as a final merge path until the branch is refreshed and maintainers accept raw stdout as liveness. The batch-path patch is narrow and plausible, but a semantic parsed-progress boundary would be safer if noisy stdout should not suppress diagnostic recovery.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 640258d7b31d.

Label changes

Label justifications:

  • P1: The reported failure can abort active long-running CLI-backed agent work and reset session context for real users.
  • merge-risk: 🚨 availability: The diff changes when diagnostic stuck-session recovery treats a CLI subprocess as alive versus abortable.
  • 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 (logs): The PR body and comments provide redacted before/after gateway logs plus terminal output for the patched cli:stdout path and focused test results, which is sufficient real behavior proof for this internal diagnostic change.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body and comments provide redacted before/after gateway logs plus terminal output for the patched cli:stdout path and focused test results, which is sufficient real behavior proof for this internal diagnostic change.
Evidence reviewed

PR surface:

Source +21, Tests +149. Total +170 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 21 0 +21
Tests 1 149 0 +149
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 170 0 +170

What I checked:

  • Root policy read: Root AGENTS.md was read fully; its PR review policy applies because this is an agents/runtime diagnostic change requiring source, tests, current behavior, related work, and merge-risk review. (AGENTS.md:1, 640258d7b31d)
  • Scoped agents policy read: The scoped agents guide applies to src/agents/** changes and favors focused, import-conscious agent tests. (src/agents/AGENTS.md:1, 640258d7b31d)
  • Current main batch gap: Current main's batch onStdout path updates byte counts, hashes, tails, parse buffers, and the streaming parser, but does not emit run.progress. (src/agents/cli-runner/execute.ts:1123, 640258d7b31d)
  • Diagnostic progress contract: Every run.progress event currently resolves session activity and touches lastProgressAt with the supplied reason, so adding cli:stdout changes the stuck-session freshness clock. (src/logging/diagnostic-run-activity.ts:274, 640258d7b31d)
  • Abort gate depends on stale progress: Embedded-run recovery becomes eligible only when the stalled classification is active and lastProgressAgeMs reaches stuckSessionAbortMs. (src/logging/diagnostic.ts:501, 640258d7b31d)
  • PR diff adds batch stdout liveness: The PR imports emitTrustedDiagnosticEvent, adds a 10-second throttle helper, calls it from batch onStdout with reason cli:stdout, and adds seam coverage for emission, throttling, payload identity, and no-output behavior. (src/agents/cli-runner/execute.ts:58, 6d0cb2b284dd)

Likely related people:

  • vincentkoc: Recent path history shows repeated June 2026 CLI-runner and Claude live-session maintenance on the same files touched or adjacent to this PR. (role: recent area contributor; confidence: high; commits: c2ee9b0be8ae, 6f1def4d6872, 2b05bd7b0d9a; files: src/agents/cli-runner/execute.ts, src/agents/cli-runner/claude-live-session.ts)
  • shakkernerd: Recent commits in the execute.ts history cover CLI backend diagnostics, env handling, and Gemini CLI stream behavior adjacent to this batch CLI path. (role: recent CLI backend contributor; confidence: medium; commits: 81c9bd3997b2, c6d7d857637c, 2bde35d29c55; files: src/agents/cli-runner/execute.ts, src/agents/cli-runner.spawn.test.ts)
  • joshavant: Merged PR Fix Claude live tool progress for watchdog recovery #87546 added Claude live diagnostic progress and heartbeat behavior that defines the nearby liveness invariant maintainers need to preserve. (role: introduced adjacent heartbeat behavior; confidence: high; commits: 980a643df26b, 5b73eeb9cdcf, 4c3a0292ff9e; files: src/agents/cli-runner/claude-live-session.ts, src/agents/cli-runner.spawn.test.ts)
  • openperf: Recent diagnostic history includes recovery bookkeeping changes in diagnostic-run-activity.ts, which is the downstream consumer of the new run.progress reason. (role: diagnostic recovery contributor; confidence: medium; commits: c0195f7ed579; files: src/logging/diagnostic-run-activity.ts, src/logging/diagnostic.test.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.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels May 20, 2026
@clawsweeper

clawsweeper Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Moonlit Patch Peep

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: keeps receipts.
Image traits: location release reef; accessory proof snapshot camera; palette charcoal, cyan, and signal green; mood patient; pose sitting proudly on a smooth stone; shell glossy opal shell; lighting warm desk-lamp glow; background subtle branch markers.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Moonlit Patch Peep in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

…hunks

Adds vitest seam test that mocks the process supervisor's onStdout callback
at controlled timestamps and asserts:
- run.progress with reason=cli:stdout fires on the first chunk
- a chunk within the 10s throttle window is suppressed
- a chunk past the window fires again (exactly 2 events for 3 chunks)
- payload carries runId / sessionId / sessionKey from PreparedCliRunContext
- no run.progress events fire when supervisor produces no stdout

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@SkyWolfDreamer

Copy link
Copy Markdown
Contributor Author

Evidence after fix

Patched build verification: ran npm run build on the patched branch and confirmed both new reason strings are present in the built artifact:

$ grep -o 'cli:stdout\|cli:live:delta\|emitCliDiagnosticProgress' dist/execute.runtime-9K0xK9zk.js | sort -u
cli:live:delta
cli:stdout
emitCliDiagnosticProgress

Regression test against patched code: added src/agents/cli-runner/execute.diagnostic-progress.test.ts that drives executePreparedCliRun through supervisorSpawnMock, fires three onStdout chunks at simulated timestamps (t=0s, t=3s, t=11s), and captures emitted internal diagnostic events via onInternalDiagnosticEvent.

Result:

$ npx vitest run src/agents/cli-runner/execute.diagnostic-progress.test.ts
 RUN  v4.1.6 /home/bakhtiyar/Work/OpenClaw

 ✓ src/agents/cli-runner/execute.diagnostic-progress.test.ts (2 tests)
   ✓ emits cli:stdout run.progress on stdout chunks and throttles to ~10s
   ✓ does not emit run.progress when supervisor produces no stdout

 Test Files  2 passed (2)
      Tests  4 passed (4)
   Duration  8.08s

The test locks in:

  • run.progress with reason="cli:stdout" fires on the first chunk (t=0s)
  • the second chunk at t=3s is suppressed by the 10s throttle
  • the third chunk at t=11s fires a second event (so 3 chunks → exactly 2 emissions)
  • payload carries runId, sessionId, and sessionKey from the prepared context — so diagnostic-run-activity.ts:recordRunProgress can update the correct session activity entry
  • when supervisor produces no stdout, no run.progress events fire (no false liveness)

This is the seam-level proof that lastProgressReason advances from embedded_run:started to cli:stdout during a real CLI run, which prevents isStalledEmbeddedRunRecoveryEligible from firing during active output.

What was NOT tested

  • End-to-end reproduction against a live Opus 4.7 reasoning turn through the running gateway — restarting the gateway would terminate the active conversation collecting this proof. The seam test is the minimum reliable guardrail; a full e2e is a follow-up.
  • The cli:live:delta path (onAssistantDelta in claude-live-session.ts) is not covered by this test. The P1 ClawSweeper finding about thinking-only delta filtering applies and should be addressed in a follow-up commit: hook progress at the parser-progress boundary so thinking_delta events also refresh liveness.

@openclaw-barnacle openclaw-barnacle Bot added 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 May 23, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 23, 2026
The onAssistantDelta callback fires only for parsed text_delta events,
so a Claude live session that streams thinking_delta (Opus reasoning)
never refreshes the watchdog. Per ClawSweeper review on PR openclaw#84540,
narrow this PR to the batch stdout path and let the raw-stdout fix in
PR openclaw#84550 own the live-session liveness signal.

Removes the cli:live:delta emit and unused liveDiagnosticState; keeps
the batch cli:stdout emitter and its existing regression test.
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 23, 2026
@SkyWolfDreamer

Copy link
Copy Markdown
Contributor Author

Addressed ClawSweeper P1 finding via Option 2 (narrow to batch stdout).

What changed (commit 92fbed9)
Removed the cli:live:delta emit and unused liveDiagnosticState from the live-session onAssistantDelta callback in src/agents/cli-runner/execute.ts. The PR now only emits run.progress with reason="cli:stdout" from the batch path's onStdout.

Rationale
The text_delta-only filtering in parseClaudeCliStreamingDelta meant the original live-session hook missed thinking_delta (Opus reasoning) streams. Live-session liveness is owned by #84550, which hooks at handleClaudeStdout and ships thinking-delta-only regression coverage. Each PR now has one concern.

Verification
Copy
$ npx vitest run src/agents/cli-runner/execute.diagnostic-progress.test.ts
Test Files 2 passed (2)
Tests 4 passed (4)
@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. 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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 23, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 30, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 30, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 9, 2026
@openclaw-barnacle

Copy link
Copy Markdown

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

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 15, 2026
@clawsweeper

clawsweeper Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(cli-runner): emit run.progress diagnostic events during CLI stdou… This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #clawtributors on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

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: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P1 High-priority user-facing bug, regression, or broken workflow. 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: S 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.

1 participant