docs: stream-json tested live — it does not deliver observability, and v1 was harmful
deploy / test (push) Successful in 4m52s
deploy / build (push) Successful in 59s

Deployed the amd64 build to gw-04 and drove a real mission. The agent used
Bash and the standard tools; no tool.call events appeared, and the gateway's
unmatched-frame histogram still showed only session_start.

The reason is structural: TurnEvent::ToolCall is emitted from
tool_execution.rs, only for tools ZeroClaw itself runs. Claude Code runs its
tools in its own subprocess, so the event never fires. A provider that knows
about the calls changes nothing by itself.

The first version was also harmful — it returned the observed calls as
tool_calls, so the loop tried to execute Claude Code's tool names and fed
"Unknown tool: Bash" back to the model. Fixed in the fork; both runtimes
rolled back to the known-good image in the meantime.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-08-20 09:47:05 -07:00
co-authored by Claude Opus 5
parent ac4fa0b8f7
commit 536adddd0f
+37 -5
View File
@@ -51,12 +51,44 @@ workaround (`ssh gw-04 'cat /tmp/ci-logs/STEP; tail -40 /tmp/ci-logs/rust-step.l
but **a token with the `actions` scope** would have made the whole detour but **a token with the `actions` scope** would have made the whole detour
unnecessary. unnecessary.
### Watch the first real mission ### stream-json: tested live, and it does NOT deliver observability
Nothing has yet confirmed end to end that the PreToolUse gate behaves in a real Built for amd64 on gw-04, deployed, and driven with a real mission. Result:
guest, or that `tool.call` rows appear. The `stream-json` runtime image is
**still not deployed** — it is a separate image (`clawmates-runtime:streamjson`, - **The agent used tools** — it ran `echo hello-from-tools` via Bash and
built locally) and this pipeline does not ship it. exercised Read/Edit/Write/Glob/Grep, confirming again that mission agents
are not tool-free.
- **No `tool.call` events appeared.** The gateway's unmatched-frame histogram
showed only `session_start`, exactly as before.
Why: `TurnEvent::ToolCall` — the thing the gateway turns into a `tool_call`
frame — is emitted from `tool_execution.rs`, i.e. **only for tools ZeroClaw
itself executes**. Claude Code runs its tools inside its own subprocess, so
ZeroClaw never emits the event and ClawMates never sees it. The provider
knowing about the calls changes nothing on its own.
**Worse, the first version was actively harmful.** It put the recovered calls
into `ChatResponse.tool_calls`, which means "execute these" — so the agent loop
tried to run `Bash`, got `Unknown tool: Bash` (`tool_execution.rs:175`), and fed
that back to the model as a tool result: an extra LLM round-trip per call,
telling the agent its own work failed. The mission still completed with correct
output, which is precisely why it would have gone unnoticed.
Fixed in fork commit `295d6d3b8`: the calls are logged, never returned. **Both
runtimes were rolled back to the known-good image** (`:v084` on gw-04,
`:toolchain` locally) rather than leaving the harmful build in production. A
corrected image (`clawmates-runtime:streamjson2`) was building on gw-04 at
session end — `ssh gw-04 'tail -3 /tmp/rtbuild/build2.log'`.
**The real fix for mission-tier tool observability** is to plumb an event
channel into the provider so it can emit `TurnEvent::ToolCall` for calls it
merely observed. That is a change to ZeroClaw's provider trait and is its own
piece of work. Until then the microVM tier's `PostToolUse` tap remains the only
working tool telemetry.
### Still unverified
The PreToolUse gate has never run in a real guest.
``` ```
ssh gw-04 'cat /root/toolgate/denied.jsonl' # inside a mission VM ssh gw-04 'cat /root/toolgate/denied.jsonl' # inside a mission VM