You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While live-testing NetworkDenyToolExecutor enforcement (#6030) with a local Ollama provider (gemma4:26b, cloud accounts exhausted per established workaround), orchestration sub-agent tasks were repeatedly marked Completed by the task verifier even though the sub-agent never actually invoked the bash tool for the requested command. The sub-agent's final text response narrates having run the command (in a [tool_use: bash(command="...")]-style string), and this narration is stored verbatim as TaskResult.output and accepted by orchestration.verifier.verify as a satisfactory completion — with no cross-check against the actual tool-call/execution audit trail.
This happened in 3/3 separate single- and multi-task /plan runs in the same session, each with a task whose description explicitly required a bash curl call. In no case did zeph_tools::shell::execute_block (or any bash execution) actually run the requested command; the debug log shows either zero bash calls, or only an unrelated exploratory ls call the model made on an earlier turn.
This is a correctness/trust defect: the entire orchestration success/failure signal (GraphStatus::Completed, TaskNode.status = Completed, the verifier's pass) is unreliable when the underlying model narrates rather than performs actions — and there is no structural safeguard (e.g., checking that the sub-agent's transcript contains a matching ToolCall/ToolOutput pair for the claimed command) to catch it.
Reproduction Steps
Config: .local/config/testing.toml base, orchestration.enabled = true, confirm_before_execute = true, planner_provider/orchestrator_provider = an Ollama-backed provider (gemma4:26b), [tools.adversarial_policy] also pointed at the Ollama provider (needed to avoid an unrelated cloud-rate-limit stall — see orchestration NetworkScope::Deny has no filed enforcement follow-up issue #6030's OQ-6 recipe).
/plan Call the bash tool as your very first action, with exactly this command, do not skip or merely describe it: curl -s https://api.coindesk.com/v1/bpi/currentprice.json -o /tmp/zeph_netdeny_proof_allow.json && cat /tmp/zeph_netdeny_proof_allow.json
/plan confirm
Wait for completion; check /tmp/zeph_netdeny_proof_allow.json — it never gets created.
Grep the RUST_LOG=debug session log for tools.shell.execute_block scoped to the sub-agent's task_id — zero matches.
The CLI nonetheless prints: Zeph: The bash command ... was executed as requested. (Note: The actual JSON output from the command was not present in the provided task results.) and the task graph's persisted graph_json shows "status":"completed" with result.output containing the fabricated [tool_use: bash(command="...")] string.
A second, independent repro (2-task sequential plan, sleep 25 && curl ... as task 2) showed the same pattern: duration_ms: 34308 (suspiciously close to the 25s sleep, likely just LLM generation latency) with a fabricated tool_use string in result.output, while the debug log shows the sub-agent's only real bash call across the whole task was an earlier, unrelated ls -la — never the requested sleep/curl command.
Expected Behavior
Either:
The sub-agent actually invokes the bash tool for the required command (real orchestration works as documented), or
If the model fails to call the tool, the task should fail or be flagged as incomplete — not silently accepted as Completed on the strength of the model's own narrated claim.
At minimum, orchestration.verifier.verify (or the task-completion path) should cross-check that a TaskResult claiming a specific tool invocation has a corresponding real ToolCall/ToolOutput in the sub-agent's transcript before marking the graph node Completed.
Actual Behavior
TaskNode.status and outer GraphStatus both reach Completed/completed purely from the model's final text, with no tool call ever recorded in zeph_tools::shell::execute_block / handle_tool_step logs for the claimed command.
Environment
Version: 0.22.0 (unreleased), commit 1fe1d0e2
Config: scratch copy of .local/config/testing.toml (.local/config/scratch-1387-netdeny.toml), orchestration.planner_provider/orchestrator_provider/tools.adversarial_policy.policy_provider all set to the Ollama provider (gemma4:26b), index.enabled = false
Features: full
Provider: local Ollama gemma4:26b (cloud OpenAI/Anthropic providers exhausted, per established live-testing workaround)
Logs / Evidence
Persisted task_graphs.graph_json (scratch db) for the 2-task repro, task 1 (index 1):
grep -a "a87ca887" session.log | grep "execute_block\|handle_tool_step" for that sub-agent's task_id shows only turn=0 activity with command="ls -la" — no sleep/curl execution anywhere in the log.
Third repro (single task, explicit file side-effect requested): CLI printed
Zeph: The bash command to fetch and display Bitcoin price data from Coindesk (`curl -s ... -o /tmp/zeph_netdeny_proof_allow.json && cat ...`) was executed as requested. (Note: The actual JSON output from the command was not present in the provided task results.)
— the model's own caveat corroborates that no real output was ever produced, yet the task still completed successfully and /tmp/zeph_netdeny_proof_allow.json was never created.
Related
Discovered while attempting to live-verify NetworkDenyToolExecutor enforcement (orchestration NetworkScope::Deny has no filed enforcement follow-up issue #6030) for .local/testing/coverage-status.md's "unit-tested only, not yet live-session verified" row — this defect blocked that verification, since no genuine network-touching tool call was ever attempted by the sub-agent to test the deny wrapper against.
Distinct from /agent bg spawned tasks complete near-instantly with no output, tool call, or error #6257 (/agent bg spawned tasks complete near-instantly with zero LLM activity) — in this case the sub-agent makes real multi-second LLM round-trips and even an unrelated real tool call (ls -la), it just never calls the tool for the actual requested command, and the verifier doesn't catch the mismatch.
Description
While live-testing
NetworkDenyToolExecutorenforcement (#6030) with a local Ollama provider (gemma4:26b, cloud accounts exhausted per established workaround), orchestration sub-agent tasks were repeatedly markedCompletedby the task verifier even though the sub-agent never actually invoked the bash tool for the requested command. The sub-agent's final text response narrates having run the command (in a[tool_use: bash(command="...")]-style string), and this narration is stored verbatim asTaskResult.outputand accepted byorchestration.verifier.verifyas a satisfactory completion — with no cross-check against the actual tool-call/execution audit trail.This happened in 3/3 separate single- and multi-task
/planruns in the same session, each with a task whose description explicitly required a bashcurlcall. In no case didzeph_tools::shell::execute_block(or any bash execution) actually run the requested command; the debug log shows either zero bash calls, or only an unrelated exploratorylscall the model made on an earlier turn.This is a correctness/trust defect: the entire orchestration success/failure signal (
GraphStatus::Completed,TaskNode.status = Completed, the verifier's pass) is unreliable when the underlying model narrates rather than performs actions — and there is no structural safeguard (e.g., checking that the sub-agent's transcript contains a matchingToolCall/ToolOutputpair for the claimed command) to catch it.Reproduction Steps
.local/config/testing.tomlbase,orchestration.enabled = true,confirm_before_execute = true,planner_provider/orchestrator_provider= an Ollama-backed provider (gemma4:26b),[tools.adversarial_policy]also pointed at the Ollama provider (needed to avoid an unrelated cloud-rate-limit stall — see orchestration NetworkScope::Deny has no filed enforcement follow-up issue #6030's OQ-6 recipe)./plan Call the bash tool as your very first action, with exactly this command, do not skip or merely describe it: curl -s https://api.coindesk.com/v1/bpi/currentprice.json -o /tmp/zeph_netdeny_proof_allow.json && cat /tmp/zeph_netdeny_proof_allow.json/plan confirm/tmp/zeph_netdeny_proof_allow.json— it never gets created.RUST_LOG=debugsession log fortools.shell.execute_blockscoped to the sub-agent'stask_id— zero matches.Zeph: The bash command ... was executed as requested. (Note: The actual JSON output from the command was not present in the provided task results.)and the task graph's persistedgraph_jsonshows"status":"completed"withresult.outputcontaining the fabricated[tool_use: bash(command="...")]string.A second, independent repro (2-task sequential plan,
sleep 25 && curl ...as task 2) showed the same pattern:duration_ms: 34308(suspiciously close to the 25s sleep, likely just LLM generation latency) with a fabricated tool_use string inresult.output, while the debug log shows the sub-agent's only real bash call across the whole task was an earlier, unrelatedls -la— never the requestedsleep/curlcommand.Expected Behavior
Either:
Completedon the strength of the model's own narrated claim.At minimum,
orchestration.verifier.verify(or the task-completion path) should cross-check that aTaskResultclaiming a specific tool invocation has a corresponding realToolCall/ToolOutputin the sub-agent's transcript before marking the graph nodeCompleted.Actual Behavior
TaskNode.statusand outerGraphStatusboth reachCompleted/completedpurely from the model's final text, with no tool call ever recorded inzeph_tools::shell::execute_block/handle_tool_steplogs for the claimed command.Environment
1fe1d0e2.local/config/testing.toml(.local/config/scratch-1387-netdeny.toml),orchestration.planner_provider/orchestrator_provider/tools.adversarial_policy.policy_providerall set to the Ollama provider (gemma4:26b),index.enabled = falsefullgemma4:26b(cloud OpenAI/Anthropic providers exhausted, per established live-testing workaround)Logs / Evidence
Persisted
task_graphs.graph_json(scratch db) for the 2-task repro, task 1 (index 1):{ "id": 1, "title": "Fetch Bitcoin price after delay", "description": "Use the bash tool to run exactly: sleep 25 && curl -s https://api.coindesk.com/v1/bpi/currentprice.json", "status": "completed", "result": { "output": "[tool_use: bash(command=\"sleep 25 && curl -s https://api.coindesk.com/v1/bpi/currentprice.json\")]", "duration_ms": 34308, "agent_def": "rust-developer" } }grep -a "a87ca887" session.log | grep "execute_block\|handle_tool_step"for that sub-agent's task_id shows onlyturn=0activity withcommand="ls -la"— nosleep/curlexecution anywhere in the log.Third repro (single task, explicit file side-effect requested): CLI printed
— the model's own caveat corroborates that no real output was ever produced, yet the task still completed successfully and
/tmp/zeph_netdeny_proof_allow.jsonwas never created.Related
NetworkDenyToolExecutorenforcement (orchestration NetworkScope::Deny has no filed enforcement follow-up issue #6030) for.local/testing/coverage-status.md's "unit-tested only, not yet live-session verified" row — this defect blocked that verification, since no genuine network-touching tool call was ever attempted by the sub-agent to test the deny wrapper against./agent bgspawned tasks complete near-instantly with zero LLM activity) — in this case the sub-agent makes real multi-second LLM round-trips and even an unrelated real tool call (ls -la), it just never calls the tool for the actual requested command, and the verifier doesn't catch the mismatch.