fix(codex): keep message-tool replies final-only#100156
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 5:38 AM ET / 09:38 UTC. Summary PR surface: Source 0, Tests +10. Total +10 across 5 files. Reproducibility: yes. I did not rerun the full production Telegram failure locally, but current main’s ambiguous instruction plus the terminal message-tool classifier match the reported trace in #100153. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. 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 the focused instruction, assertion, and snapshot update if maintainers accept prompt-level enforcement here, while leaving long-chain reinforcement or recovery work to #100367. Do we have a high-confidence way to reproduce the issue? Yes. I did not rerun the full production Telegram failure locally, but current main’s ambiguous instruction plus the terminal message-tool classifier match the reported trace in #100153. Is this the best way to solve the issue? Yes. Because upstream Codex emits dynamic tool completions during the turn and OpenClaw intentionally treats delivered current-source message-tool sends as terminal, steering Codex to use the current-source message send only as the final visible reply is the narrowest maintainable fix for this bug. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 22dfb150488d. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source 0, Tests +10. Total +10 across 5 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
Review history (7 earlier review cycles)
|
20e9c95 to
07715f3
Compare
07715f3 to
ddd7202
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Superseding my previous proof artifact for now. The first uploaded video is not good enough as review proof: most of the clip stays on one static tool-output frame, and the final visible section can be read as ambiguous ordering. I am rerunning a cleaner Telegram proof with the chat pinned to the bottom so the tool-output-then-final-reply ordering is visible in one continuous capture. |
|
Focused English Telegram proof for @clawsweeper: What the video shows:
This replaces my earlier proof artifact, which was too long/static and ambiguous for review. @clawsweeper re-review |
|
Added inspectable proof to the PR body so review does not need
The contact sheet shows the English Telegram prompt, the Bash @clawsweeper re-review |
|
Reviewed at head The change is instruction-only — it rewrites the I checked the two things that decide whether this is the right lever:
Two things before it lands:
Minor, non-blocking: the instruction roughly quadruples in length (~+150 rough tokens per applicable run, scoped to |
ddd7202 to
787d668
Compare
|
Thanks @AmirF194, this was helpful. I rebased the branch onto current Local checks I ran after the rebase: GitHub now reports the PR as mergeable again; CI is running on the updated head |
|
Additional production evidence supports this mitigation. During an OpenClaw 2026.6.10 control window, we recorded no turn.dynamic_tool_terminal_release events caused by message; after moving to 2026.7.1-beta.2, we recorded more than 100. Affected turns follow message(send) -> tool result(ok) -> turn.dynamic_tool_terminal_release -> session ended, including acknowledgment/status messages before work completes. This independently matches #100153. The final-only instruction is useful defense in depth, though the long-term distinction should be explicit delivery intent rather than inferred terminality. This branch appears to need only a rebase/snapshot refresh. I can prepare that focused refresh or an adversarial GPT-5.6 continuation test if the author or a maintainer wants help, without widening this PR's scope. |
|
Closing: maintainers chose the structural completion contract over the prompt-only approach. #105365 (merged as 4dc6e18) adds an explicit |
Fixes #100153
What Problem This Solves
Fixes an issue where Codex-backed source-channel turns using
message_tool_onlydelivery could stop after sending a progress/status line throughmessage(action=send). In the observed Telegram turn, the assistant sent a visible "I'll check..." style status message, OpenClaw treated that deliveredmessagecall as terminal, and no GitHub/web/tool lookup happened afterward.Why This Change Was Made
This keeps the existing terminal-delivery behavior for real
message_tool_onlyreplies, but makes the Codex developer instruction explicit about the ordering contract: complete required tool work first, then usemessage(action=send)for the current source conversation only as the final user-visible source-channel output. It also distinguishes explicit non-source/out-of-bandmessage(action=send)calls, which remain ordinary tool work, from sends that target the current source conversation.No delivery receipt, route matching, channel integration, config, or tool execution behavior changes.
User Impact
Users in Telegram/Discord-style source-channel sessions should see fewer turns where the agent says it will check something and then silently stops. Codex is steered to do the work first and send one final visible reply to the current source conversation at the end of the turn, while still allowing explicit out-of-band sends to other conversations during the work.
Evidence
Before-fix real incident, redacted:
Environment: Windows OpenClaw gateway, Telegram source conversation, Codex app-server runtime,
message_tool_onlysource replies.The user asked the agent to inspect PR titles/labels.
The assistant called
message(action=send)with a progress/status message equivalent to "I'll check the PR titles/labels first."The message tool returned
{"ok":true,"messageId":"<redacted>"}.The app-server log immediately recorded:
The persisted session contained the user message, the assistant progress text, the
messagetool call/result, and then noweb_search,web_fetch,bash, GitHub, or other tool calls afterward.Focused after-fix verification:
Result:
Whitespace check:
Result: exit 0.
Prompt snapshot formatting check:
Result:
Autoreview:
Result:
Live Telegram proof (after-fix):
What the proof shows:
node -v, then send exactly one final visible reply with the Node version.v22.22.0.Node version: v22.22.0.Runtime note: the proof was recorded on the current Windows OpenClaw
2026.7.1-beta.2install with this PR's Codex developer-instruction change applied to the installed runtime file. I did not run the older PR branch binary directly against the current user config because OpenClaw correctly refuses older automatic gateway migrations.What was not tested:
pnpm prompt:snapshots:checkon Windows is blocked locally by a NodeexecFile/oxfmt.cmdspawn EINVAL; the prompt snapshot check runs on Linux CI for this PR.