Writing rules
How to express a constraint the assistant must follow, with the right scope and priority so it lands without drowning the context window.
On this page
A rule is a constraint the assistant must follow inside a scope. Rules are the strongest piece of content in Pathrule: they arrive as requirements rather than as background, and a rule that carries an approved executable constraint can stop a matching change before it lands.
This page covers when to write a rule, how to choose scope and priority, what enforcement means, and the patterns to avoid.
When to write a rule
Reach for a rule when there is a thing the assistant must not do, or a thing it must always do, in a specific part of the codebase.
- "Never use the service role key in browser code."
- "All money values are stored as integers in cents. Never use floats."
- "Migrations must run before the matching code change. No exceptions."
- "JSX files in
apps/webuse Tailwind classes only. No CSS modules, no inline styles."
If the answer is "it depends on the situation, the assistant should think about it," that is a memory, not a rule. Rules are for non negotiable things.
Scope types
Every rule has a scope type that decides which paths or files it applies to.
folder. Applies to a directory subtree. Best for area specific rules: anything that lives underapps/api/auth, anything underservices/billing.file_type. Applies to files matching a glob like*.tsxor**/*.test.ts. Best for cross cutting concerns that are tied to a file kind, not a directory.project. Applies everywhere in the workspace. Use sparingly. A project rule rides every prompt.
The scope and the node path the rule is attached to together decide what the assistant sees. A folder rule attached at /apps/web covers anything under apps/web.
Priority levels
Priority decides how aggressively the rule shows up. Within a matching scope, higher priority rules are considered first.
high. For things that cause bugs, security regressions, or compliance issues if violated.medium. The default. Use for "almost always but not load bearing".low. Stylistic. Surfaces when there is room and the topic is on point. Use for taste and convention.
High priority is a budget. If half your rules are high priority, none of them are. Pick the ones that really cannot be violated.
Enforcement: advisory and strict
Enforcement is a separate setting from priority. Priority ranks how strongly a rule surfaces; enforcement decides what happens on a violation.
advisory. The rule is context. The assistant weighs it and decides how to apply it. Rules you write in the Local Console or VS Code, and rules an assistant writes, are advisory.strict. A rule becomes strict when it carries an executable constraint that a person has approved: the exact forbidden form, such as an import, an identifier or a location. The pre-tool hook can then block a file edit or write that matches it before the change lands, and returns the rule and its remedy as the reason. An assistant can attach a proposed constraint when it writes or updates a rule (pathrule_write_rule,pathrule_update_rule), but a proposal is stored as a proposal and blocks nothing until a person approves it; an assistant can never approve its own. See Rules as guardrails.
Rewriting a rule keeps enforcement honest. An approved constraint is tied to the sentence of the rule it was proved against. If you rewrite the rule and that sentence is gone, the constraint stops enforcing on its own, so a rule never keeps blocking for a reason it no longer states. Editing other parts of the rule, or adding a paragraph, leaves an untouched constraint armed.
Blocking depends on the client. Pathrule installs tool hooks for Claude Code, and for Codex when the repository has Codex files, and a block applies where that pre-tool hook honours the decision. Cursor, Windsurf and GitHub Copilot get no Pathrule hooks, and Remote MCP installs none, so there rules arrive as context only. Delivery alone does not enforce anything.
Structure
A rule has a name and a body. Keep the body imperative and short.
Name: No service role key in browser code
Body:
- Never import SUPABASE_SERVICE_ROLE_KEY in any file under apps/web.
- Use the anon key plus row level security.
- If you need server only access, do it from apps/api or a server action.
An assistant writes rules with pathrule_write_rule. In VS Code use New Rule…, and in a Local workspace you can also write one in the Local Console. The CLI reads rules but does not write them:
pathrule rule read "No service role key in browser code"
The shape that works best in practice is one constraint per rule with a small bulleted body. Long prose rules get skimmed by both humans and assistants.
Reusable, not duplicated
A rule lives at one path and covers everything beneath it, so one rule is enough for a whole subtree. If the same constraint applies to two distant folders, put it at their nearest common path, or use a file_type scope with a glob, rather than copy pasting the text into two rules. One rule means one edit when the constraint changes.
Pathrule helps here: a new rule whose name matches an existing rule in the workspace is refused by default, and the write tells you which rule already exists. You can override that deliberately (allow_duplicate through MCP) after checking the existing rule. To re-home a rule, move it to another path (Move… in VS Code, or pathrule_update_rule with move_to_path).
Versioning and concurrent edits
Rules carry a version token like memories. Two teammates editing the same rule at the same time will conflict cleanly rather than overwrite each other. In VS Code the conflict offers the same choices as for a memory: Reload, Copy My Version & Reload or Keep Mine (Overwrite).
How rules show up to the assistant
- Rules in a matching scope are ranked by priority and by how relevant they are to the task. The most relevant arrive as full bodies; the rest are named, so the assistant knows they exist and can read one in full with
pathrule_read_rule. - A strict rule always arrives in full where it applies, because a name alone cannot explain a block.
- Rules are also compiled into the instruction files your clients read (for example CLAUDE.md for Claude Code and AGENTS.md for Codex), so a client without a prompt hook still starts from them.
Whether a rule can block a change, rather than just inform the assistant, is set by its enforcement mode (advisory or strict), not by its priority.
Anti patterns
- High priority for everything. Pick the rules that really matter. The rest should be medium.
- Rules that read like memories. "We tend to prefer X" is a memory. "Never do Y" is a rule.
- Rules that overlap. Two high priority rules with conflicting language is worse than one clear rule.
- Project scope used by default. Most rules belong under a folder. Pull a rule up to
projectonly if it really applies everywhere.
Local and Cloud authoring
The CLI does not write knowledge in either edition: your agent writes through Pathrule's MCP tools. In a Local workspace you also create and edit entries in the Local Console or VS Code, and for a Cloud workspace the Pathrule Cloud console shows them. The CLI's knowledge commands list, read and search them in both.
What to read next
- Writing memories for facts and decisions that are not constraints.
- Writing skills for reusable procedures the assistant can invoke.
- How hooks work for how the runtime decides which rules to surface.