Context
Recurring agent-tooling friction, surfaced empirically this session (2026-06-27): I invoked rg -r five times in one session, each time silently corrupting grep output. rg -r is --replace (it rewrites every match in the displayed output to the replacement token) — NOT recursion. ripgrep recurses by default. So rg -rn "escalateDiagnosis" displayed lines as service.n(...) where the code actually says service.escalateDiagnosis(...), once nearly driving a wrong assertion about deleted-method call sites.
The decisive datapoint: the 5th occurrence was immediately after I wrote a dedicated file-based memory guard against it — proving a memory loads at next-session start and cannot break entrenched muscle-memory within the current session. The memory layer is necessary but not sufficient; the fix has to fire at action-selection time.
The Problem
A Model-Experience friction→gold case: a recurring, measured agent-tooling mistake the documentation/memory layer demonstrably cannot prevent in-session. It costs a re-run each time and risks wrong conclusions from corrupted output.
#13674 (CLOSED — "Stop-hook deference-register lint") already established the conceptual home: in that ticket's own thread the over-action / pre-act layer is named explicitly — "the pre-act predicate belongs at action-selection time (a self-applied check, or a pre-tool-use hook)." The stop-hook gates the turn-tail's under-action half; a pre-tool-use hook gates the per-action half. This ticket is a concrete, high-frequency instance of that named-but-unbuilt pre-tool-use layer.
The Architectural Reality
- Substrate: agent harness config — a Claude-Code PreToolUse hook on the
Bash tool, living under .claude/ (a committed, swarm-shared repo artifact), not Neo runtime code.
- The hook inspects the
Bash command string; if it contains a standalone rg invocation with a bare -r / --replace flag and no adjacent replacement argument signalling genuine --replace intent, it warns (or requires confirmation).
- Swarm-shared: any maintainer hitting the same flag-shape inherits the guard.
The Fix
- Add a
PreToolUse matcher for Bash in the repo's Claude-Code hook config (.claude/) that detects the rg ... -r / --replace shape and emits a warning: "rg -r is --replace, not recursion — rg recurses by default; did you mean a plain recursive search?"
- Keep it narrow: only flag
rg (not cp -r / rm -r / etc.), and don't false-positive when a genuine replacement argument is present.
Acceptance Criteria
Out of Scope
- A general agent-tool-use lint framework — this is the specific, high-frequency
rg -r guard. A broader framework, if wanted, is a separate ticket continuing the #13674 lineage.
Secondary Observation (not this ticket's scope)
The L3_No_Hold_State stop-hook and the post-review-pickup §5 session-sunset clause are in tension when measured substrate-degradation (like this footgun's recurrence) accumulates after a milestone ships: §5 sanctions sunset on "measured substrate-error increase," while L3 rejects any non-operator-confirmed terminal. Worth a future reconciliation in the #13674 stop-hook MX lineage — flagged here because this session is the empirical anchor.
Related
#13674 (CLOSED — stop-hook deference-lint; names the pre-tool-use / pre-act layer this instantiates)
Live latest-open sweep (2026-06-27): checked latest 20 open issues + all-state search for ripgrep / rg-replace / tool-use-guard / footgun; no equivalent found (closest is #13674, closed, which names this layer rather than building it).
Origin Session ID: 090a68e6-1a28-4b20-a5fd-842ebac3e729
Retrieval Hint: "rg -r replace footgun pre-tool-use hook MX guard"
Context
Recurring agent-tooling friction, surfaced empirically this session (2026-06-27): I invoked
rg -rfive times in one session, each time silently corrupting grep output.rg -ris--replace(it rewrites every match in the displayed output to the replacement token) — NOT recursion. ripgrep recurses by default. Sorg -rn "escalateDiagnosis"displayed lines asservice.n(...)where the code actually saysservice.escalateDiagnosis(...), once nearly driving a wrong assertion about deleted-method call sites.The decisive datapoint: the 5th occurrence was immediately after I wrote a dedicated file-based memory guard against it — proving a memory loads at next-session start and cannot break entrenched muscle-memory within the current session. The memory layer is necessary but not sufficient; the fix has to fire at action-selection time.
The Problem
A Model-Experience friction→gold case: a recurring, measured agent-tooling mistake the documentation/memory layer demonstrably cannot prevent in-session. It costs a re-run each time and risks wrong conclusions from corrupted output.
#13674(CLOSED — "Stop-hook deference-register lint") already established the conceptual home: in that ticket's own thread the over-action / pre-act layer is named explicitly — "the pre-act predicate belongs at action-selection time (a self-applied check, or a pre-tool-use hook)." The stop-hook gates the turn-tail's under-action half; a pre-tool-use hook gates the per-action half. This ticket is a concrete, high-frequency instance of that named-but-unbuilt pre-tool-use layer.The Architectural Reality
Bashtool, living under.claude/(a committed, swarm-shared repo artifact), not Neo runtime code.Bashcommand string; if it contains a standalonerginvocation with a bare-r/--replaceflag and no adjacent replacement argument signalling genuine--replaceintent, it warns (or requires confirmation).The Fix
PreToolUsematcher forBashin the repo's Claude-Code hook config (.claude/) that detects therg ... -r/--replaceshape and emits a warning: "rg -ris--replace, not recursion — rg recurses by default; did you mean a plain recursive search?"rg(notcp -r/rm -r/ etc.), and don't false-positive when a genuine replacement argument is present.Acceptance Criteria
rg -r/rg --replaceinvocations with a clear "did you mean recursive?" message.rg --replace '<pattern>' '<replacement>', nor on other tools'-rflags..claude/so the whole swarm inherits it.rg -rn "foo"test invocation.Out of Scope
rg -rguard. A broader framework, if wanted, is a separate ticket continuing the#13674lineage.Secondary Observation (not this ticket's scope)
The
L3_No_Hold_Statestop-hook and thepost-review-pickup §5session-sunset clause are in tension when measured substrate-degradation (like this footgun's recurrence) accumulates after a milestone ships: §5 sanctions sunset on "measured substrate-error increase," while L3 rejects any non-operator-confirmed terminal. Worth a future reconciliation in the#13674stop-hook MX lineage — flagged here because this session is the empirical anchor.Related
#13674(CLOSED — stop-hook deference-lint; names the pre-tool-use / pre-act layer this instantiates)Live latest-open sweep (2026-06-27): checked latest 20 open issues + all-state search for ripgrep / rg-replace / tool-use-guard / footgun; no equivalent found (closest is
#13674, closed, which names this layer rather than building it).Origin Session ID: 090a68e6-1a28-4b20-a5fd-842ebac3e729
Retrieval Hint: "rg -r replace footgun pre-tool-use hook MX guard"