Skip to content
Pathrule

docs

Rules as guardrails

How a Pathrule rule with an approved block pattern can stop a non-compliant change before it lands, while every other rule rides along as context.

On this page

A rule in Pathrule is not a note the assistant reads later. It is a guardrail that arrives before the assistant acts. Most documentation tells you what went wrong after it shipped. A guardrail can stop the change before it lands.

This page explains the difference between context that informs a turn and a rule that can block one. For the mechanics of how hooks deliver context, read How hooks work first. This page is about what a strict rule does once that context is in place.

Pull asks. Push arrives.

The old model is pull. The assistant has to remember to ask for your conventions, call a tool, and read the result before it edits anything. If it forgets, it edits blind, and you find the problem in review.

The hook model is push. On Claude Code and Codex, context arrives without the assistant asking for it when you submit a prompt and right before the assistant uses a tool. By the time the assistant is about to write a file, the rules attached to that path are already in front of it. Cursor, GitHub Copilot and Windsurf get no Pathrule hooks: they ask the local MCP server for rules, so there rules inform but do not block.

Two levels: advisory and blocking

Not every rule should interrupt the assistant. Pathrule treats rules at two levels.

  • Advisory rules ride along as context. They appear next to the file the assistant is about to touch, with their priority, so the assistant can factor them in. They do not stop anything. Most rules are advisory, at any priority.
  • Strict rules can block. A rule becomes strict when it carries a block pattern a person has approved: a forbidden form in the content, such as an import, an identifier, a class name or a CSS declaration, a forbidden location for a file, or both. When the assistant is about to edit or write a file in a way that matches, the hook stops the tool call before the file is written and returns the reason. The assistant reads it and tries again, this time inside the constraint.

Priority and blocking are independent. Priority (high, medium, low) decides how prominently a rule surfaces and which rules make the cut when space is short. It does not decide blocking: every strict rule for the path is checked, whatever its priority.

How a rule becomes strict

An assistant cannot arm a block pattern on its own.

  1. The rule is written in plain words first, by you or by an assistant you asked.
  2. An assistant can propose a block pattern for it through the MCP write and update tools for rules. The preferred form names the forbidden text exactly as the rule spells it, with real examples that must be caught and near misses that must not. Pathrule builds the pattern from that and tests it against both sets; if either fails, the proposal is refused with the reason rather than weakened.
  3. The proposal is stored with the rule and is not enforced.
  4. Only after a person approves it does the hook start blocking, and the remedy written for it becomes the "do this instead" the assistant sees.

A rule can also carry a required check: a verification command that must have passed before the turn ends, such as a test suite for a package. Like a block pattern, it is proposed and is not enforced until a person approves it. Once approved, on Claude Code and Codex the hook holds the turn open with the exact command to run until it has passed.

What the assistant sees

A blocked edit comes back with the rule name, a short preview of the rule, the approved remedy and a pointer to the full rule. For a rule named "No direct database client in UI components", it reads like this:

Pathrule blocked: "No direct database client in UI components"

UI components never import the database client. Data goes through the data layer hooks.

Do this instead: call the data layer hook for this resource.

Your edit matches this rule's forbidden pattern. Read the full rule via pathrule_read_rule(<id>) and retry without the violation.

Claude Code and Codex receive this as a denial of the tool call, in each client's own hook format. Cursor, GitHub Copilot and Windsurf have no Pathrule hooks, so nothing is blocked there. Blocking applies to file edits and writes; a shell command still receives the rule as context.

The split is deliberate. Blocking a low-stakes edit wastes the assistant's turn and yours. Blocking is reserved for the rules where a violation is a real regression and someone has signed off on exactly what counts as one.

Before and after

Consider a rule that says secrets never go into committed files, with an approved block pattern for the key format your provider uses.

Without the guardrailWith the guardrail
The assistant's intentAdd an API key to a config file to make a feature workSame
What happensThe edit landsThe hook blocks the matching tool call before the file is written
When you find outLater, in review (or not at all)In the same turn. The assistant sees the rule text and switches to an environment variable
Result on diskA committed secretThe matching edit was not written

The same pattern applies to any rule a team has paid for in production: a data-access policy that must filter by user, a migration convention, a file that is generated and must not be hand-edited. The rule stops being a comment someone hopes the assistant read and becomes a check that runs before the edit lands. A block pattern catches the forms it was approved for, so it complements review rather than replacing it.

Filenames pull the right memory

You do not always have to wait for a tool call. On Claude Code and Codex, when your prompt names a file that an attached memory is about, the prompt hook can surface that memory's body before the assistant opens anything. Naming the file you are working on is often enough to put the right context in front of the assistant on the first turn. When more than one memory matches the same filename, the hook shows the candidates instead of guessing.

Fail open by design

A guardrail that breaks your workflow when it breaks is worse than no guardrail. Pathrule fails open. If the hook cannot evaluate a rule, errors, or times out, it does not block your work. The change proceeds. Enforcement is a safety net, not a gate you can get stuck behind.

You stay in control. If you ever want hooks off entirely, one file turns them off.

Verify it yourself

You do not have to take the behavior on faith.

To see which hooks your AI client has registered, read its settings file. For Claude Code, Pathrule registers its hooks in the project:

cat .claude/settings.json

Codex uses .codex/hooks.json, in a repository that has Codex files.

To turn every Pathrule hook off instantly (the kill switch), create one file:

touch ~/.pathrule/kill-hooks

The next tool call passes straight through with no Pathrule involvement. Remove the file to turn hooks back on:

rm ~/.pathrule/kill-hooks

To confirm a rule is actually attached to a path, run pathrule rule list in the folder, or open the assistant's Pathrule context surface in your editor. The rule shows up with its priority before the assistant acts on that path, and a strict rule shows its block the first time an edit matches it.

  • How hooks work for the delivery mechanics and the empty-state behavior.
  • Writing rules for how to author a rule worth enforcing.
  • MCP overview for the deep path the assistant uses when the hook is not enough.