fix(agents): don't fail CLI turn when the native harness owns compaction#87785
fix(agents): don't fail CLI turn when the native harness owns compaction#87785solomonneas wants to merge 1 commit into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed May 29, 2026, 8:04 AM ET / 12:04 UTC. Summary PR surface: Source +14, Tests +77. Total +91 across 2 files. Reproducibility: yes. current main's Codex app-server returns Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one coherent CLI native-owned compaction behavior, preferably this narrow branch if maintainers want the minimal fix, or close it after the broader overlapping recovery PR lands. Do we have a high-confidence way to reproduce the issue? Yes: current main's Codex app-server returns Is this the best way to solve the issue? Yes: adding a nonfatal native-owned no-op branch at the CLI lifecycle matches the sibling Codex preflight behavior and keeps genuine failures unchanged. The main maintainer choice is whether to land this narrow path or the broader overlapping recovery PR. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 351d056ca64f. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +14, Tests +77. Total +91 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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
|
|
Added real behavior proof from a live self-hosted gateway (the prior review predated it): the Evidence after fix section now shows redacted before/after gateway console output for the same over-budget Codex session — the native owned no-op is hit ( @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
runCliTurnCompactionLifecycle threw on the Codex app-server's successful no-op (ok:true, compacted:false) when it owns automatic compaction, failing the agent run and jamming the session lane (endless 'typing' on large Codex threads). Treat the owned no-op as benign: skip the throw and the context-engine fallback so the turn proceeds and the harness self-compacts. Matches the existing 'Codex owns compaction' contract in the auto-reply preflight path.
4c07fc7 to
28f22f0
Compare
|
Previous ClawSweeper run errored before completing ("Review failed before ClawSweeper could summarize" / AGENTS.md not fully read) after the rebase onto latest @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Closing as superseded by current main. Current main already avoids the original hard failure for the Codex-owned native compaction no-op by recognizing that result and falling back to context-engine compaction. That keeps the no-throw fix while preserving a known host-side compaction/rotation path before the turn proceeds. This PR now conflicts with that landed policy because its generic successful-no-op branch would skip both the throw and the context-engine fallback, while the merged main path intentionally falls back for the exact Codex-owned reason. If there is still a reproducible failure on current main after 81505ad, please open a fresh/rebased PR with that repro and a narrow regression test against the current CLI compaction behavior. Thanks for the detailed proof and for chasing the lane-jam failure. |
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in #87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Add `ownsNativeCompaction` capability to CliBackendPlugin so backends that manage their own transcript compaction (e.g. Claude Code) can declare it once and OpenClaw defers instead of fighting or failing. Today only Codex declares compaction ownership (via the embedded runner path + agentHarnessId). Claude-cli never reaches that path because it runs as a CLI subprocess with no harness id set, so the safeguard summarizer fires and hard-fails the turn. This PR: - Adds `ownsNativeCompaction?: boolean` to the backend plugin type - Propagates it through all 4 backend resolution paths - In `runCliTurnCompactionLifecycle`, when a backend declares ownership but has no harness endpoint, returns a no-op instead of falling through to the safeguard - Sets the flag on claude-cli (first adopter) Codex's existing native-harness path is unchanged: when `isNativeHarnessCompactionSession` matches, the harness compaction endpoint is still called as before. Generalizes the partial fix in openclaw#87785 (codex-scoped) to a capability any backend can opt into.
Summary
Budget/auto-triggered compaction on a Codex-backed session calls the Codex app-server, which owns automatic compaction and returns a successful no-op (
{ ok: true, compacted: false, reason: "codex app-server owns automatic compaction" }, the behavior added in #86772). The host lifecyclerunCliTurnCompactionLifecycleinsrc/agents/command/cli-compaction.tstreated any non-compacted native outcome withoutfallbackToContextEngineas a hard failure and threwCLI native harness compaction failed …. That fails the agent run (UNAVAILABLE) and the session lane never releases — on a large thread the bot shows a "typing" indicator indefinitely and never replies.This honors a contract the codebase already establishes elsewhere: the auto-reply preflight path skips compaction for Codex runtimes outright (
src/auto-reply/reply/agent-runner-memory.ts: "Its harness owns automatic compaction; OpenClaw preflight compaction is only for non-Codex embedded runtimes").runCliTurnCompactionLifecyclewas the one host path that did not honor it and threw instead.Fix
Surface an
ownedByNativeHarnessflag on the native outcome when the harness reports a successful no-op (result.ok === true), and add a caller branch before the throw that skips both the error and the context-engine fallback, letting the turn proceed so the harness compacts itself. Minimal and additive; no refactor. Genuine failures (ok:false, thrown, orundefinedresult) and the unsupported / recoverable-binding cases are unchanged.Note on shape: I extended the existing
NativeHarnessCliCompactionOutcome(which already uses parallel optional fields) rather than refactoring it into a discriminated union, to keep the fix small. Happy to take the union refactor in a follow-up if maintainers prefer.Sibling surfaces (not one-sided)
The other native-harness compaction entry points already tolerate the
ok:trueno-op, so this is the only path that needed fixing:src/agents/embedded-agent-runner/compact.queued.ts—shouldFallbackAfterHarnessCompactiononly fires onok:false; theok:trueno-op is returned directly.src/auto-reply/reply/agent-runner-memory.ts— Codex runtimes skip preflight compaction entirely; otherwise onlyisDeferredPreflightCompactionReasonthrows, which the owned-skip reason is not.Real behavior proof
Behavior addressed: A successful native-harness compaction no-op (
ok:true, compacted:false, "codex app-server owns automatic compaction") must let the turn proceed instead of throwing and jamming the session lane.Real environment tested: A self-hosted OpenClaw
2026.5.28gateway on Linux (Node 22.22.2) where this failure occurred in production, with the equivalent fix applied to the running build and the gateway restarted.Exact steps or command run after this patch: Drove one real agent turn through the live gateway against the same over-budget Codex session that had been failing (no channel delivery):
openclaw agent --session-id <redacted> --message "Reply with exactly: COMPACTION_FIX_OK" --jsonEvidence after fix: Console output / redacted runtime logs copied from the live gateway (same session), captured via
openclaw agent --session-id <redacted> --message "Reply with exactly: COMPACTION_FIX_OK" --json, before vs. after the fix.Before (pre-fix) — the throw and resulting lane jam:
After (post-fix) — same compaction outcome, now skipped instead of thrown; turn completes:
Agent result JSON:
stopReason: "stop",executionTrace.winnerProvider: "openai-codex",winnerModel: "gpt-5.5",attempts[0].result: "success",fallbackUsed: false.Observed result after fix: Copied live output — the previously-jammed over-budget Codex session completed a turn and the agent returned
COMPACTION_FIX_OK(gateway console output above). ZeroCLI native harness compaction failedoccurrences in gateway logs since the fix was deployed.What was not tested: Not re-driven through the Discord channel UI specifically — the turn was driven via the gateway
agentcommand without--deliver; behavior is proven at the live gateway turn boundary.Supplemental validation
cli-compaction.test.ts:node scripts/run-vitest.mjs src/agents/command/cli-compaction.test.ts→ 24 passed. Reverting only the source change makes the new test fail withCLI native harness compaction failed for codex/gpt-5.5: codex app-server owns automatic compaction(the exact production error).oxfmt --checkclean ·oxlintclean ·tsgo:test(core + extensions) exit 0.codex review --base origin/mainrun locally: no actionable correctness issues.Complements #87158 (Codex plugin side); coordinates with #87738 (same file, missing-thread
ok:falsecase). Related: #85160, #86772, #66263.