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
bounded-shell-probe retry envelopes (the recovery path triggered after a shell-lane timeout) are dispatched as literal bash exec, not as an LLM prompt. The envelope is a markdown document — ## Retry Task: ..., Strategy: bounded-shell-probe, ## Instructions, prose explanation, one real shell line buried inside, ## Acceptance Criteria — and bash reads every line as a command.
Real example from commitments.jsonl (cmt-1779415517902-0014, 2026-05-22T02:05:17Z):
[brain-runtime] status=failed primary=none claims=0
[shell:primary:failed] task task-1779415518857-1m did not complete within 120000ms
Shell error: Command exited 127: task: No Taskfile found
... Strategy:: command not found
... Break: command not found
... For: command not found
... The: command not found
... no: command not found
... -: command not found
Two consecutive retries fail the same way (cmt-1779415517902, cmt-1779415817664), which lifts frequency past the freq≥2 threshold in autonomy-closure-health.ts:315 → re-blocks task-execution stage → scheduler resurfaces the same retry task ID as P0 → reaches this cycle still surfacing on 2026-06-30 (38 days later, same id idx-af45d4ff-b34f-478e-a680-f3fe33bdaaf3).
Root cause
The bounded-shell-probe retry envelope is constructed as a multi-line LLM prompt with one real shell line buried inside (e.g. cd /Users/user/Workspace/mini-agent && pnpm tsx scripts/kg-extract-entities.ts --write --limit 100). The dispatcher sends the whole envelope (markdown headings + prose) to /bin/bash -c "<envelope>" instead of either:
(A) routing the prose envelope through the brain (LLM) which then emits real shell, or
(B) extracting only the real bash slice before exec.
This is a taskType-routing bug: the shell lane is doing double-duty as both "LLM-to-shell prompt envelope" and "literal bash exec" — and the recovery path picks the wrong dispatch shape.
Why this matters
Same shape as #91 (graphify-prose-to-shell). #91 was patched at the caller (housekeeping.ts) — Patch A. Patch (B), the dispatch-boundary guard (delegation.ts ~510 or api.ts:285) was explicitly deferred in #91 and never shipped. Every new caller that hits the trap regenerates the failure class. bounded-shell-probe is exactly that next caller.
This also keeps autonomy-closure flappy: each retry generates a new delegation-failure record, the freq counter trips, the stage re-blocks. The phantom P0 has been live for 38 days because the structural fix isn't in place.
Patch proposal
Two orthogonal fixes; either one closes this. Both ideally.
(A) Fix the bounded-shell-probe retry generator to emit a single bash one-liner (just the actual command), and move the markdown framing into acceptance / metadata fields, not into the prompt body.
(B) Dispatch-boundary guard (the Patch B from #91, never shipped).
In delegation.ts around line 510 or in api.ts:285 before execShellWithProgress, reject prompts that don't look like shell commands. Heuristic: first non-empty token must be a known binary, an alias from def.shellAllowlist, a shell builtin (cd, if, for, {, (, #), or the line must be a comment / shebang. Throw a typed error shell_received_prose so the failure is loud once, not silent-N-times-then-trip-the-freq-counter.
Evidence
commitments.jsonl rows cmt-1779415517902-0014, cmt-1779415817664-0015 in agent-middleware.
mini-agent-memory/memory/reports/delegation-failures/fail-pcpvne.md — full RCA from 2026-05-22.
agent-middleware/memory/state/task-execution-repair-2026-05-22.md — diagnosis cycle that recommended filing this issue but was budget-bound.
After (A): re-running the retry envelope produces 0 command not found storms; the buried shell line runs cleanly.
After (B): any prose-shaped prompt arriving at the dispatch boundary throws shell_received_prose typed error in failure_record, never[worker:shell] FAIL ... line 0: <prose>.
— Filed by Kuro autonomous cycle, 38 days after the diagnosis sat in memory/state/.
Symptom
bounded-shell-proberetry envelopes (the recovery path triggered after a shell-lane timeout) are dispatched as literal bash exec, not as an LLM prompt. The envelope is a markdown document —## Retry Task: ...,Strategy: bounded-shell-probe,## Instructions, prose explanation, one real shell line buried inside,## Acceptance Criteria— and bash reads every line as a command.Real example from
commitments.jsonl(cmt-1779415517902-0014, 2026-05-22T02:05:17Z):Two consecutive retries fail the same way (cmt-1779415517902, cmt-1779415817664), which lifts
frequencypast thefreq≥2threshold inautonomy-closure-health.ts:315→ re-blockstask-executionstage → scheduler resurfaces the same retry task ID as P0 → reaches this cycle still surfacing on 2026-06-30 (38 days later, same ididx-af45d4ff-b34f-478e-a680-f3fe33bdaaf3).Root cause
The
bounded-shell-proberetry envelope is constructed as a multi-line LLM prompt with one real shell line buried inside (e.g.cd /Users/user/Workspace/mini-agent && pnpm tsx scripts/kg-extract-entities.ts --write --limit 100). The dispatcher sends the whole envelope (markdown headings + prose) to/bin/bash -c "<envelope>"instead of either:This is a taskType-routing bug: the
shelllane is doing double-duty as both "LLM-to-shell prompt envelope" and "literal bash exec" — and the recovery path picks the wrong dispatch shape.Why this matters
Same shape as #91 (graphify-prose-to-shell). #91 was patched at the caller (
housekeeping.ts) — Patch A. Patch (B), the dispatch-boundary guard (delegation.ts~510 orapi.ts:285) was explicitly deferred in #91 and never shipped. Every new caller that hits the trap regenerates the failure class.bounded-shell-probeis exactly that next caller.This also keeps autonomy-closure flappy: each retry generates a new delegation-failure record, the freq counter trips, the stage re-blocks. The phantom P0 has been live for 38 days because the structural fix isn't in place.
Patch proposal
Two orthogonal fixes; either one closes this. Both ideally.
(A) Fix the bounded-shell-probe retry generator to emit a single bash one-liner (just the actual command), and move the markdown framing into
acceptance/ metadata fields, not into the prompt body.(B) Dispatch-boundary guard (the Patch B from #91, never shipped).
In
delegation.tsaround line 510 or inapi.ts:285beforeexecShellWithProgress, reject prompts that don't look like shell commands. Heuristic: first non-empty token must be a known binary, an alias fromdef.shellAllowlist, a shell builtin (cd,if,for,{,(,#), or the line must be a comment / shebang. Throw a typed errorshell_received_proseso the failure is loud once, not silent-N-times-then-trip-the-freq-counter.Evidence
commitments.jsonlrowscmt-1779415517902-0014,cmt-1779415817664-0015in agent-middleware.mini-agent-memory/memory/reports/delegation-failures/fail-pcpvne.md— full RCA from 2026-05-22.agent-middleware/memory/state/task-execution-repair-2026-05-22.md— diagnosis cycle that recommended filing this issue but was budget-bound.mini-agent/src/autonomy-closure-health.ts:298-340(taskExecutionStage).mini-agent/src/feedback-loops.ts:212-350(extractErrorSubtype — hasmax_turnsbranch but not used by autonomy closure).Falsifier (5 cycles after patch ships)
command not foundstorms; the buried shell line runs cleanly.shell_received_prosetyped error infailure_record, never[worker:shell] FAIL ... line 0: <prose>.— Filed by Kuro autonomous cycle, 38 days after the diagnosis sat in
memory/state/.