Skip to content

fix(claude-code): narrow PostToolUse hook matcher from .* to Bash|Write|Edit|MultiEdit (sable-h0ah) - #183

Merged
Rome-1 merged 1 commit into
mainfrom
sable-h0ah-narrow-claude-posttool-matcher
Jun 27, 2026
Merged

fix(claude-code): narrow PostToolUse hook matcher from .* to Bash|Write|Edit|MultiEdit (sable-h0ah)#183
Rome-1 merged 1 commit into
mainfrom
sable-h0ah-narrow-claude-posttool-matcher

Conversation

@Rome-1

@Rome-1 Rome-1 commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Problem

rafter agent init --with-claude-code (and rafter agent enable claude-code.hooks) registered the rafter hook posttool secret-redaction hook with a catch-all .* matcher. That fires rafter hook posttool after every Claude Code tool call — including Read and MCP tools, which never produce secrets to redact — adding latency to every operation for every rafter-cli user. posttool was designed for shell output + file writes.

Fix

Narrow the Claude Code PostToolUse matcher from .* to Bash|Write|Edit|MultiEdit — the tools whose output is actually worth scanning (shell output + file writes). PreToolUse matchers (Bash, Write|Edit) are unchanged.

Changed in both install paths per language for parity:

  • Node: src/commands/agent/init.ts (init/legacy) + src/commands/agent/components.ts (component spec)
  • Python: rafter_cli/commands/agent.py (legacy) + rafter_cli/commands/agent_components.py (component spec)

Docs (SKILL.md, shared-docs/PLATFORM_PARITY_AUDIT.md, CHANGELOG.md) and test expectations updated. A PostToolUse-matcher assertion was added to the Python install test to mirror existing Node coverage.

Scope

Claude Code only. Codex (.* PostToolUse) and Gemini (.* AfterTool) have the same broad-matcher latency issue but need platform-correct tool names (Codex Bash|apply_patch, Gemini run_shell_command|write_file|replace|edit) — tracked separately in sable-4alt, not touched here.

Security review

This is rafter's own install path, so it went through rafter-code-review:

  • The change is a hardcoded literal-string swap — no user input, no new path/secret/shell handling. No injection/traversal/proto-pollution surface. The new matcher is a flat literal alternation (no ReDoS) and strictly more restrictive than .*.
  • Tradeoff (deliberate, documented): the redaction hook no longer fires on Read/MCP outputs — a reduction in defense-in-depth breadth. Acceptable because the actual security control (PreToolUse command interception) is untouched, and redaction still covers the highest-value channels (shell output + file writes). If MCP-output redaction is later wanted, it should return as a targeted matcher, never .*.
  • rafter secrets . is clean for this diff (the 106 repo hits are intentional test fixtures). Remote rafter run (SAST/SCA) was not run here — RAFTER_API_KEY is unset in this environment; please let CI / the merger run it.

Testing

  • Affected Node files (agent-compatibility, platform-integration): 132 passed.
  • Affected Python files (test_agent_init, test_agent_components, test_suppression): 112 passed.
  • TypeScript build (tsc): clean. Ruff: zero new errors from this diff.
  • Full suites are green except two pre-existing failures unrelated to this change (verified via git stash — they fail without this diff too), tracked in sable-6udz: a Node AuditLogger test (error-handling-gauntlet.test.ts) and a Python version-match test that invokes a stale global rafter binary.

Closes sable-h0ah.

🤖 Generated with Claude Code

…te|Edit|MultiEdit

rafter agent init --with-claude-code (and agent enable claude-code.hooks)
registered the `rafter hook posttool` redaction hook with a catch-all `.*`
matcher, so it fired after EVERY Claude Code tool call — including Read and
MCP tools, which never produce secrets to redact — adding latency to every
operation. Narrow the matcher to the tools whose output is worth scanning:
shell output (Bash) and file writes (Write/Edit/MultiEdit).

Changed in both install paths per language (init/legacy + component spec),
keeping Node and Python identical. PreToolUse matchers are unchanged.

Scope is Claude Code only. Codex (.* PostToolUse) and Gemini (.* AfterTool)
have the same broad-matcher latency issue and are tracked separately in
sable-4alt for platform-correct narrow matchers.

Docs (SKILL.md, PLATFORM_PARITY_AUDIT.md, CHANGELOG) and test expectations
updated; a PostToolUse-matcher assertion added to the Python install test
to mirror the Node coverage.

Closes sable-h0ah

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Rome-1
Rome-1 merged commit c32a34b into main Jun 27, 2026
@Rome-1 Rome-1 mentioned this pull request Jun 28, 2026
Rome-1 added a commit that referenced this pull request Jun 28, 2026
Patch release bundling the unreleased changes on main since 0.8.9:
- Claude Code PostToolUse matcher narrowed .* -> Bash|Write|Edit|MultiEdit (#183)
- Hooks tolerate harness-appended flags, e.g. --hook-json (#180)
- Dependency CVE re-lock (axios, hono, tar, js-yaml, +transitives) and
  remote-skill tarball extraction hardening (#184)

Bumps node/package.json + python/pyproject.toml to 0.8.10 (parity), the
rafter-security skill resource version (node + python), and finalizes the
CHANGELOG 0.8.10 section.

Refs sable-ehb1

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant