From c35bc08b8b5eca28dc88e7131a2e185c211fa198 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 8 Apr 2026 23:47:04 +0300 Subject: [PATCH] fix: remove single-quoted Python literal from claude stream processor The claude provider pipes stream-json output through `python3 -u -c '...'` to track tool usage and update the dashboard orchestrator. The Grep branch used `f"pattern: {tool_input.get('pattern', '')}"`, embedding four single quotes inside what is already a bash single-quoted string. Bash toggles its SQ state on every literal `'`, so the four quotes fall back to SQ-in state (even number of toggles), hiding the problem from bash syntax checks. But each pair also strips its contents out of the SQ, so `'pattern'` becomes a bare word and Python receives `tool_input.get(pattern, )` -- a valid-but-wrong expression that raises `NameError: name "pattern" is not defined` on every Grep call. The exception aborts the inner `for item in content` loop before `update_orchestrator_task` runs, so Grep invocations were silently missing from `.loki/state/agents.json` and the dashboard tool counter. Claude sessions continued, but every Grep also printed a spurious `[Parse error: name 'pattern' is not defined]` to stderr. Fix: use double quotes and string concatenation, which stays safe inside bash SQ. Add BUG-RUN-004 regression assertions in tests/test-bugfix-audit.sh to prevent reintroducing the pattern. --- autonomy/run.sh | 10 +++++++++- tests/test-bugfix-audit.sh | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/autonomy/run.sh b/autonomy/run.sh index f1314526..aa6fd8d6 100755 --- a/autonomy/run.sh +++ b/autonomy/run.sh @@ -9740,7 +9740,15 @@ def process_stream(): elif tool == "Bash": tool_desc = tool_input.get("description", tool_input.get("command", "")[:60]) elif tool == "Grep": - tool_desc = f"pattern: {tool_input.get('pattern', '')}" + # NOTE: This Python block runs as the argument of + # bash `python3 -u -c`, wrapped in a bash single- + # quoted string. Any single-quoted Python literal + # here would close bash SQ mid-code and Python + # would receive `tool_input.get(pattern, )`, a + # bare identifier instead of a string literal, + # crashing with NameError. Use double quotes and + # string concatenation to stay SQ-safe. + tool_desc = "pattern: " + tool_input.get("pattern", "") elif tool == "Glob": tool_desc = tool_input.get("pattern", "") diff --git a/tests/test-bugfix-audit.sh b/tests/test-bugfix-audit.sh index 78a382f8..4e09ef67 100755 --- a/tests/test-bugfix-audit.sh +++ b/tests/test-bugfix-audit.sh @@ -349,14 +349,47 @@ test_source "BUG-CMD-012: worktree merge uses env var for signal file" \ test_source "BUG-GH-011: gh status has space before version" \ 'installed \$\(gh --version' +# ------------------------------------------- +# BUG-RUN-004: Claude stream processor Grep branch used a single-quoted +# Python literal inside a bash single-quoted heredoc (python3 -u -c '...'), +# silently breaking bash SQ and making Python see a bare identifier instead +# of the "pattern" string, crashing with NameError on every Grep tool call. +# Fix: use double quotes and concatenation, no single-quoted literals in +# the Python block. +# ------------------------------------------- +RUN_SH="$SCRIPT_DIR/../autonomy/run.sh" + +((TOTAL++)) +if grep -qE 'tool_input\.get\("pattern", ""\)' "$RUN_SH"; then + log_pass "BUG-RUN-004: Grep branch reads pattern with double quotes" +else + log_fail "BUG-RUN-004: Grep branch reads pattern with double quotes" \ + "expected double-quoted .get(\"pattern\", \"\")" +fi + +((TOTAL++)) +if grep -qE "tool_input\.get\('pattern'" "$RUN_SH"; then + log_fail "BUG-RUN-004: no single-quoted 'pattern' literal in run.sh" \ + "single-quoted literal reintroduced -- breaks bash SQ in python3 -u -c" +else + log_pass "BUG-RUN-004: no single-quoted 'pattern' literal in run.sh" +fi + # ------------------------------------------- # Syntax validation # ------------------------------------------- ((TOTAL++)) if bash -n "$LOKI" 2>/dev/null; then - log_pass "bash -n syntax validation passes" + log_pass "bash -n syntax validation passes (loki)" +else + log_fail "bash -n syntax validation (loki)" "script has syntax errors" +fi + +((TOTAL++)) +if bash -n "$RUN_SH" 2>/dev/null; then + log_pass "bash -n syntax validation passes (run.sh)" else - log_fail "bash -n syntax validation" "script has syntax errors" + log_fail "bash -n syntax validation (run.sh)" "script has syntax errors" fi # -------------------------------------------