Rulebook Guard Claude Code mod: Claude Code guardrails for git and writing
Replaces em dashes in prose and asks before git amend, unformatted pushes and personal info in notes.
Permissions
- Reads filesCan read files and list directories on your machine ($.fs.read / list / stat / exists).
- Runs commandsCan run shell programs on your machine ($.process.run / spawn). Check the source for exactly which ones.
- Intercepts tool callsSees every tool call Claude makes (tool.call / tool.check) and could block or change it.
- Changes the UIDraws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
- tested with
- v2.1.307
- last tested
- requires
- Claude Code ≥ 2.1.287
- surfaces
- toast
- source
- Hamza Zafar (hamzafer) (MIT)
Install inside Claude Code:
/plugin install rulebook-guard --marketplace hamzafer/claude-code-modsWhat does this mod do?
Rulebook Guard is a community mod by Hamza Zafar (hamzafer), part of his claude-code-mods collection. It is a small set of Claude Code guardrails that turn a few personal rules, the kind you keep in CLAUDE.md, into hooks that run on every tool call. The author's README describes it as his own setup, to fork and adapt, so read the rules before you adopt them.
There are four rules:
- No em dashes in prose. When Claude writes or edits a Markdown or text file, writes a commit message or PR text, or posts to Slack, each
—is replaced with a comma.fast — and smallbecomesfast, and small. A toast tells you how many were replaced. - New commits, not
git commit --amend. The mod asks first. Claude is told to make a new commit if you say no. - Format before
git push. The mod checks the files in your unpushed commits withruff format --checkand Prettier, and asks if any would change. - No personal info without asking. An email address or phone number going into your notes, Claude's memory files,
CLAUDE.mdor a commit command triggers a question.
Install
Use any of the methods in the install block; they install from the author's own marketplace. The hooks load on the next session start or after /reload-plugins. There is no slash command and nothing to configure.
$ install rulebook-guard
Requires Claude Code ≥ 2.1.287
Installs from the author's own marketplace: hamzafer/claude-code-mods
1.One line, inside Claude Code
/plugin install rulebook-guard --marketplace hamzafer/claude-code-modsPaste into a running session (v2.1.275+). Claude Code asks to add the marketplace first.
2.From your shell
claude plugin marketplace add hamzafer/claude-code-mods claude plugin install rulebook-guard@claude-code-modsThen run /reload-plugins in any session that is already open.
3.Try it without installing
git clone https://github.com/hamzafer/claude-code-mods claude --plugin-dir ./claude-code-mods/mods/rulebook-guardLoads the mod for one session only. Nothing is added to your settings.
How it works
The plugin is one function-hooks module, hooks/register.ts, that registers four tool.call hooks: one each for Write, Edit and Bash, and one catch-all for the Slack tools. A hook either passes the call on unchanged, passes on a rewritten copy, or returns { deny }. This is the Bash hook's amend check, from register.ts:
const shell = bare(command) // what the shell runs, without quoted text or heredoc bodies
if (GIT_AMEND.test(shell)) {
if (!(await allow($, 'This is `git commit --amend`. Your rule: make a new commit instead.'))) {
return { deny: 'rulebook-guard: the user blocked `git commit --amend`. Their rule is new commits, not amend. Make a new commit instead.' }
}
}bare() blanks out heredoc bodies and quoted strings first, so a command that only mentions git commit --amend in an echo or a script is not held. The regex also allows git global options in between, such as git -c user.name=x -C . commit --amend. allow() calls $.ui.ask with "Block it" and "Allow once", and treats every other answer, or a failed dialog, as a no.
For a push, unformatted() finds the repo root, lists the changed files with git diff --name-only @{u}...HEAD (falling back to origin/main...HEAD) and runs the formatters on them. Private paths for the personal-info rule are ~/notes/, ~/.claude/projects/<project>/memory/ (or .claude-work) and any CLAUDE.md.
Customize it
There are no /config options and no commands. To change a rule, copy the plugin and edit the constants at the top of register.ts: PROSE_FILE for which files count as prose, EMAIL and PHONE for the personal-info patterns, PRETTIER_FILE for the files sent to Prettier, SLACK_POST for the Slack tools, and isPrivatePath for the folders the personal-info rule covers. Load your copy with claude --plugin-dir <path>. To turn the mod off, run /plugin disable rulebook-guard.
Permissions & safety
We read every file the plugin can execute before running it: .claude-plugin/plugin.json, hooks/hooks.json, hooks/register.ts (181 lines, the only module) and the tests. There is no package.json, install script, binary, minified code or dynamic import. What we found:
- Gating hooks that rewrite and block. This is the point of the mod. It can change the text of a Markdown write or edit, a
git commitorgh pr/gh issuecommand, and a Slack message, and it can deny an amend, a push or a write. It does this as described in the README. One edge: for commit and PR commands the dash replacement applies to the whole command string, not only the message. - Runs commands (
$.process.run, argv arrays, no shell):git rev-parse --show-toplevel,git diff --name-only,ruff format --check <files>from your PATH, and<repo>/node_modules/.bin/prettier --check <files>. The Prettier binary comes from the project you push from, so in a repo you do not trust, a push runs that repo's Prettier. Git and Prettier calls use a 60 second timeout. - Reads the environment: only
HOME, to find~/notes/. It does not leave the machine. - Personal info check: an email or phone number regex over the text being written, and over the whole
git commitcommand, so an address in--authoror-c user.email=also triggers the question. The dialog names the category, never the value. - No network, no file writes, no daemons, no telemetry. The only file API used is an existence check for Prettier. It injects no text into prompts. The deny messages are written for Claude and say the user blocked the action.
- Needs nothing extra.
ruffand Prettier are optional; if they are missing the corresponding check is skipped. - License: MIT, copyright 2026 Hamza Zafar, LICENSE file in the repository root.
claude plugin validate reported no errors and no warnings on 2.1.307. Its notes say that the four tool.call hooks have no .catch handler, so an unexpected exception in the module would not fall back to letting the call through. It also lists a missing plugin icon, which is not a problem for use. The author's 9 tests passed on Claude Code 2.1.307.
- Reads files
- Can read files and list directories on your machine ($.fs.read / list / stat / exists).
- Runs commands
- Can run shell programs on your machine ($.process.run / spawn). Check the source for exactly which ones.
- Intercepts tool calls
- Sees every tool call Claude makes (tool.call / tool.check) and could block or change it.
- Changes the UI
- Draws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
Compatibility & troubleshooting
Checked with Claude Code 2.1.307 on macOS (validate and tests). The author's marketplace lists version 0.1.2. If a rule does not seem to fire:
- Run
/reload-pluginsor restart so the hooks load. - The em dash rewrite only covers Markdown and text files; a
.tsor.pyfile is left alone on purpose. - The push check needs an upstream branch or
origin/mainto compare with. If neither exists, orgit difffails, the check is skipped and the push goes through. - Prettier is only used if
node_modules/.bin/prettierexists in the repo root, andruffmust be on your PATH. - The personal-info rule for files only covers
~/notes/, the memory folders andCLAUDE.md. A write to any other path is not checked. - In a non-interactive run there is nobody to answer the dialog, so held actions are blocked.
To test it, ask Claude to write a short Markdown note containing an em dash. The file should contain a comma and a toast should report the replacement.
FAQ
- Does Rulebook Guard block git commit --amend for good?
- No. It asks you through a dialog with the options "Block it" and "Allow once". Anything other than "Allow once", including having no one to answer, blocks the command and tells Claude to make a new commit instead.
- Which files does the em dash rewrite touch?
- Writes and edits to .md, .mdx, .markdown and .txt files, the text of git commit commands, gh pr and gh issue create, comment, edit and review commands, and the message of Slack send and schedule tools. Code files are left alone, so an em dash inside a .ts string stays.
- Does it send my emails or phone numbers anywhere?
- No. The plugin has no network code. When it finds what looks like an email address or phone number it names the category in the dialog and never shows the value. The check runs only for files under ~/notes/, Claude auto-memory folders and CLAUDE.md files, and for git commit commands.
- What does it run before a git push?
- It runs git rev-parse and git diff to list the files you changed, then ruff format --check on Python files and the project's own node_modules/.bin/prettier --check on web files, if those tools exist. If either reports files that would change, it asks before the push goes ahead.
- Can I change the rules?
- Not through /config. The rules are constants and functions in hooks/register.ts, so you edit that file in a local copy. The author calls the mod his own setup, to fork and adapt.
# Related mods
FeaturedBlock Dangerous Commands
Refuses rm -rf /, force-push to main, DROP TABLE, curl | sh and other destructive Bash commands before they run.
- toast
- Intercepts tool calls
- Changes the UI
tested with v2.1.310
PII Guard
Replaces Taiwanese personal data with placeholders before Claude sees it and restores real values when Claude writes.
- none
- Reads files
- Runs commands
- Network
- Intercepts tool calls
- Reads your prompts
tested with v2.1.291
FeaturedSecret Redactor
Swaps API keys, emails and public IPs for placeholders before Claude sees them, and restores them when a tool runs.
- toast
- Intercepts tool calls
- Reads your prompts
- Changes the UI
tested with v2.1.291
More in Safety guards, Git & GitHub.