v1.0.154 — claude-code Bash routing hotfix (CRITICAL)
Diagnosed live via /diagnose Phase 1-6: CC v2.1.x Bash tool ignores updatedInput.command substitution under permissionDecision: "allow" — the original command runs unchanged. Only permissionDecision: "deny" is honored for Bash blocking.
Impact
Every Claude Code user has been silently losing the curl/wget/inline-HTTP routing intervention. Users ran curl https://example.com, got the raw HTML, never saw the routing nudge to ctx_fetch_and_index / ctx_execute. Context-window protection — the core promise of context-mode — silently no-op'd in production for the dominant adapter. High-impact regression that surfaces on the first new-user test session.
Fix
Tool-aware claude-code formatter:
- Bash redirect (
updatedInput.command): emitpermissionDecision: "deny"with the routing guidance aspermissionDecisionReason. CC blocks the curl/wget call and shows the user the actionable redirect text verbatim. - Agent prompt injection (
updatedInput.prompt): keep the modify shape — CC honors allow+updatedInput for the Agent tool, so subagent routing-block injection continues to work unchanged. - Other adapters (gemini-cli, vscode-copilot, cursor, kimi): untouched — their hosts handle updatedInput differently and the previous shape stays correct.
Fallback deny message (rare path when echo wrapper unparseable) follows ADR-0003 CASE A voice: opens with "Redirected to ctx_execute / ctx_fetch_and_index", names alternatives via imperative call (Call ctx_execute(language, code) ...), affirms "full network access", ends with canonical transient-DNS retry hint. No "blocked", no bare-NOT negation, no org-rationale preface.
Validation
- 509/509 hooks tests green
- typecheck clean
- 4 files / +159 / -23
- Regression guards:
formatters.test.ts+integration.test.tslock the new deny shape and the ADR-0003 voice on the fallback path
Upgrade
/context-mode:ctx-upgrade
# then restart your Claude Code sessionAfter restart, curl / wget / python -c "requests.get(...)" from inside Claude Code will be blocked with a clear Redirected to ctx_execute / ctx_fetch_and_index ... message instead of silently running the original command.
Diagnostic trail
/diagnosePhase 1: differential loop (node vs bun) — byte-identical output, ruled out bun/node stdio incompatibility./diagnosePhase 4: forced-deny probe injected into pretooluse.mjs — proved CC honorspermissionDecision: "deny"but ignorespermissionDecision: "allow" + updatedInput.commandfor the Bash tool.- Confirmed against
refs/platforms/claude-code/src/utils/hooks.ts:552-620(parser source) and CC changelog 2.1.85 entry.