Skip to content
LinkedInX

Rules File Design — Writing Safety Rules Declaratively

About 5 minutes

Target audience: Those who understand the basics of CLAUDE.md and want to start designing reusable rules for a team.
Prerequisites:
  • Understanding the role and how to write CLAUDE.md (equivalent to Level 4)
  • Ability to read and write basic Markdown syntax

As the number of rules you want Claude to follow increases, CLAUDE.md becomes bloated and hard to manage. By managing rules split across shared/rules/*.md, you can balance maintainability and clarity. This page uses actual rule files as examples to learn the steps for declarative rule design.


A rules file is a mechanism for managing “Non-Negotiable Rules” for Claude as individual Markdown files.

Instead of cramming all rules into CLAUDE.md, split the rules into separate files. In CLAUDE.md, write only a one-line summary and the reference for each rule, and delegate the details to each rule file.

In this project, the following rule files are placed in shared/rules/.

FileContent
build-and-deploy.mdnpm run build may trigger a production deployment, so it can only be run after approval
content-i18n.mdJapanese is the source of truth; use I for English first person
folder-safety.mdList of protected folders (src/, scripts/, etc.) and rules prohibiting changes
no-ui-regression.mdProhibition on UI and navigation changes
security.mdProhibition of secrets, XSS, and injection risks
spec-first.mdRule for checking specifications before implementing

Using the actual shared/rules/build-and-deploy.md as an example, check the structure of a rule file.

# Build and Deploy Rule

`npm run dev` is the normal local preview command.

`npm run build` can trigger production deployment through the hosting pipeline.
Agents must not run it automatically, place it in broad allowlists,
or call it from hooks. Run it only after explicit user approval for that specific build.

Allowed default checks:

- `npm run dev` for local preview
- targeted scripts such as `node scripts/ensure-slugs.js`, `npm run verify-links`,
  and harness validation
- Git inspection commands

Disallowed without approval:

- `npm run build`
- `npm run build:ci`
- chained commands that include `npm run build`
- automatic hooks that call production build commands

The key points of the structure are as follows.

  1. State the rule name in the heading# Build and Deploy Rule
  2. Write why this rule exists first — the reason “because it triggers a production deployment”
  3. List allowed and prohibited operations separately — the Allowed and Disallowed sections

In the ## Non-Negotiable Rules section of CLAUDE.md, summarize each rule in one line and include a reference to the details file.

## Non-Negotiable Rules

1. Do not run `npm run build` without explicit user approval, as it may trigger production deployment.
   Details: `shared/rules/build-and-deploy.md`
2. Check the specification before implementing. Details: `shared/rules/spec-first.md`

Claude reads CLAUDE.md at session start and also checks the referenced rule files. By separating the details into rule files, you can keep CLAUDE.md short while letting each file fully explain its rule.


Consolidating all rules into one file makes it difficult to update or reference specific rules. Split files by type of concern, such as “deployment safety,” “content quality,” and “security.”

shared/rules/
├── build-and-deploy.md   ← deployment safety
├── content-i18n.md       ← language and translation
├── folder-safety.md      ← file protection
├── no-ui-regression.md   ← UI change prohibition
├── security.md           ← security
└── spec-first.md         ← specification-first

Write in Conditional Form Rather Than Prohibitive Form

Section titled “Write in Conditional Form Rather Than Prohibitive Form”

Writing “requires approval” as a condition rather than “don’t do X” as a prohibition makes it easier for Claude to correctly judge exceptional situations.

// Style to avoid
- Do not run npm run build.

// Recommended style
Disallowed without approval:
- npm run build

Rules without reasons increase the risk of Claude making its own judgment about exceptions. Write the reason why this rule exists in 1–2 sentences.

// Without reason (avoid)
# No Force Push Rule
Force push to main is prohibited.

// With reason (recommended)
# No Force Push Rule
Force push rewrites commit history and can cause data loss for collaborators.
It is prohibited without explicit approval.

Keep Only the Summary and Reference in CLAUDE.md

Section titled “Keep Only the Summary and Reference in CLAUDE.md”

Delegate the details to rule files and only write the key point in one line with the reference in CLAUDE.md. The longer CLAUDE.md gets, the more context Claude needs to load, which affects performance.


Step 1: Check the Structure of an Existing Rule File

Section titled “Step 1: Check the Structure of an Existing Rule File”

Check the contents of build-and-deploy.md with the following command.

cat shared/rules/build-and-deploy.md

Confirm the two-section structure of “Allowed default checks” and “Disallowed without approval.”

✅ Verify: Confirm that the “Why (reason)” of the rule is written at the beginning.


Create shared/rules/no-force-push.md.

# No Force Push Rule

Force push rewrites commit history and can cause data loss for collaborators.
It is prohibited without explicit approval.

Disallowed without approval:

- git push --force
- git push -f
- git push --force-with-lease (to main/master)

Allowed:

- git push --force-with-lease to feature branches (not main/master)
- discussing force push options with the user before executing

✅ Verify: Confirm that the file has been saved as shared/rules/no-force-push.md.


Step 3: Update the Non-Negotiable Rules Section of CLAUDE.md

Section titled “Step 3: Update the Non-Negotiable Rules Section of CLAUDE.md”

Add a one-line summary and reference for the new rule to the ## Non-Negotiable Rules section of CLAUDE.md.

Add the following line at the end of the existing Non-Negotiable Rules section.

7. Force push to main/master is prohibited. Details: `shared/rules/no-force-push.md`

✅ Verify: Confirm that it has been added with a number to the Non-Negotiable Rules section of CLAUDE.md.


Restart the Claude Code session and try the following request.

Please force push to the main branch.

If Claude has loaded shared/rules/no-force-push.md, it should explain the existence of the rule and its reason without executing the force push.

✅ Verify: Confirm that Claude blocks the force push and explains the rule by citing no-force-push.md.


This page covered the following.

  • Managing rules split by concern in shared/rules/*.md keeps CLAUDE.md short
  • Write rule files with the structure: “reason → allow list → deny list”
  • Place only the one-line summary and reference in CLAUDE.md, delegating the details to rule files
  • Writing in conditional form (“requires approval”) rather than prohibitive form makes it easier for Claude to judge exceptions

Q: Should rule files be written in English or Japanese?

A: Japanese is the source of truth in this project, but the rule files in shared/rules/ are written in English that Claude can reliably understand, since Claude reads them directly. A common practice is to use English for instruction documents to Claude and Japanese for human-facing documentation.

Q: Is it wrong to write rules directly in CLAUDE.md?

A: There is no problem, but as the number of rules grows, CLAUDE.md becomes too long and hard to manage. Consider splitting into files when there are 3–4 or more rules.

Q: Are changes to rule files immediately reflected in Claude?

A: Claude Code reads CLAUDE.md at session start and also checks the referenced rule files. To reflect changes, restart the Claude Code session.

Q: What is the difference between prohibiting something in a rules file versus using deny?

A: deny in settings.json is a tool-level block that physically prevents a command from being executed. A rule file is merely an instruction to Claude, which Claude understands and follows based on its judgment. For important prohibitions, it is recommended to include them in both deny and the rules file.

Quiz