Check whether your agent instruction files reach the agent at all: Codex, Claude Code, Cursor, Copilot.
Project description
rulereach
English · Русский · 简体中文 · Español · Português
Your agent instruction files can be perfectly written and still never reach the agent.
A Cursor rule with globs as a YAML list never attaches. A @import in CLAUDE.md that
points one directory too high is skipped without a word. A file in .github/instructions/
without applyTo applies to nothing. A nested AGENTS.md quietly replaces the root one.
None of that shows up as an error anywhere: the agent just works without your rules.
rulereach reads the instruction files in a repository, applies each tool's documented
loading rules, and reports what will never be loaded.
$ rulereach check
.claude/rules/api.md
x RR204 [claude] paths pattern 'photos [2024/**' unreadable bracket expression, so it matches nothing
fix: rewrite the pattern; escape a literal bracket as \[ and keep brace groups small
docs: https://code.claude.com/docs/en/memory
.cursor/rules/style.mdc
x RR102 [cursor] globs is a YAML list; Cursor expects one comma-separated string, so the rule never auto-attaches
fix: write: globs: src/**/*.ts
docs: https://forum.cursor.com/t/glob-pattern-rules-are-never-respected-by-agent/160133
AGENTS.md
x RR201 [claude] the repository has AGENTS.md but no CLAUDE.md; Claude Code reads CLAUDE.md, not AGENTS.md, so it starts with no project instructions at all
fix: add a CLAUDE.md whose first line is @AGENTS.md
docs: https://code.claude.com/docs/en/memory
rulereach: 5 error(s), 4 warning(s), 1 note(s)
Install
pipx install rulereach # or: uv tool install rulereach
Nothing is sent anywhere: the tool reads files and exits. No API keys, no network calls.
Use
rulereach check # report unreachable instructions, exit 1 on errors
rulereach check --strict # exit 1 on warnings and notes too
rulereach check --tool cursor # one tool at a time
rulereach check --exclude "tests/fixtures/**" # skip deliberately broken fixtures
rulereach list # every instruction file and when it activates
rulereach explain src/app.ts # what each tool loads when working on that file
explain is the answer to "why is the agent ignoring my rule":
$ rulereach explain packages/web/index.ts
Working on packages/web/index.ts:
Codex CLI
1. AGENTS.md - nearest file in the chain
2. packages/web/AGENTS.md - nearest file in the chain
Claude Code
(nothing - this tool loads no project instructions here)
Cursor
1. AGENTS.md - AGENTS.md on the path to the file
GitHub Copilot
1. packages/web/AGENTS.md - nearest AGENTS.md in the directory tree
Add --json to any command for machine-readable output.
Checks
| ID | Tool | What it catches |
|---|---|---|
| RR101 | Cursor | file in .cursor/rules that is not .mdc, so it is ignored |
| RR102 | Cursor | globs written as a YAML list or quoted, so nothing matches |
| RR103 | Cursor | rule with no alwaysApply, globs or description: manual only |
| RR104 | Cursor | globs pattern that matches no file in the repository |
| RR201 | Claude Code | AGENTS.md but no CLAUDE.md: no project instructions load |
| RR202 | Claude Code | @import that does not resolve (imports are relative to their file) |
| RR203 | Claude Code | import chain deeper than the four-hop limit |
| RR204 | Claude Code | paths pattern that cannot match: bad bracket, brace budget |
| RR205 | Claude Code | paths pattern that matches no file in the repository |
| RR206 | Claude Code | claude.md and other miscasings, ignored on case-sensitive filesystems |
| RR207 | Claude Code | non-.md file in .claude/rules |
| RR301 | Codex | AGENTS.md chain over the 32 KiB default cap, so the tail is dropped |
| RR302 | Copilot | nested AGENTS.md shadowing the root file for a subtree |
| RR303 | Codex | committed AGENTS.override.md hiding the shared AGENTS.md |
| RR304 | Codex | empty instruction file, which is skipped |
| RR401 | Copilot | file in .github/instructions not named NAME.instructions.md |
| RR402 | Copilot | path-specific instructions with no applyTo, so they never apply |
| RR403 | Copilot | applyTo pattern that matches no file in the repository |
Severity is about consequence, not style. An error means the file cannot load, ever. A warning means it probably does not load, or loads less than you think. A note is behaviour worth knowing that is not a mistake, such as one stale pattern in a rule whose other patterns still match.
Every finding cites the vendor documentation that defines the behaviour. The exact sentences the checks are built on are collected in docs/semantics.md.
Configuration
Optional. Put the flags you would otherwise repeat into pyproject.toml:
[tool.rulereach]
exclude = ["tests/fixtures/**"]
strict = false
Projects without a pyproject.toml can use a .rulereach.toml with the same keys at the top
level. If both exist, .rulereach.toml wins, and command line flags win over both, so
--exclude replaces the configured list and --no-strict turns off a configured strict.
An unreadable file, an unknown key or a value of the wrong type is reported on stderr rather
than ignored.
In CI
- name: rulereach
run: uvx rulereach check
check exits 1 when there is at least one error, 0 otherwise. Use --strict to fail on
warnings as well.
What this is not
It does not sync your instruction files, and it does not grade your prose. Tools that
generate CLAUDE.md from AGENTS.md already exist, and so do linters for stale paths and
dead commands. rulereach answers the question they skip: will this file be loaded at all,
and when.
Related
- skillfrisk - scan agent skills and MCP servers for prompt injection and unsafe instructions.
- ciparity - find drift between pre-commit hooks and your CI pipeline.
License
MIT
☕ Support the author
This project is free and MIT-licensed. If it saved you time, you can send a coffee.
USDT, Tron network (TRC-20) only:
TS9ywGeSyKQxiCszdKCHLR8DRAsnYCosNN
Другие языки / Other languages
- Українська: проєкт безкоштовний. Якщо він заощадив вам час — можна підтримати автора, USDT у мережі Tron (TRC-20), адреса вище.
- Русский: проект бесплатный. Если он сэкономил вам время, можно поддержать автора, USDT в сети Tron (TRC-20), адрес выше.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rulereach-0.2.0.tar.gz.
File metadata
- Download URL: rulereach-0.2.0.tar.gz
- Upload date:
- Size: 141.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8203072c088c443acb7b577c140210bf74e08f367d5b01bb7ef11fa0a2c20d8a
|
|
| MD5 |
5196c15c8ff92b285e900a0fa8b785a5
|
|
| BLAKE2b-256 |
2d24797cb472cc42916345de5fb63cf54e67b9a80be2575ec91b03f582496992
|
Provenance
The following attestation bundles were made for rulereach-0.2.0.tar.gz:
Publisher:
release.yml on Topicspot/rulereach
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rulereach-0.2.0.tar.gz -
Subject digest:
8203072c088c443acb7b577c140210bf74e08f367d5b01bb7ef11fa0a2c20d8a - Sigstore transparency entry: 2312891378
- Sigstore integration time:
-
Permalink:
Topicspot/rulereach@88c54851bbd166f3c4577cf45cf14c1ce61273cd -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Topicspot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88c54851bbd166f3c4577cf45cf14c1ce61273cd -
Trigger Event:
push
-
Statement type:
File details
Details for the file rulereach-0.2.0-py3-none-any.whl.
File metadata
- Download URL: rulereach-0.2.0-py3-none-any.whl
- Upload date:
- Size: 23.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1785e2e698c3f378327eeec3b023768c2720d6ca1a60967d501947b18105c861
|
|
| MD5 |
48f130170c61c8da81b4ff77c1e65cdd
|
|
| BLAKE2b-256 |
4b789fb1c2604db6b639ed5763a2d9c9d9da86d4843bf00c88cbd1f6916934c9
|
Provenance
The following attestation bundles were made for rulereach-0.2.0-py3-none-any.whl:
Publisher:
release.yml on Topicspot/rulereach
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rulereach-0.2.0-py3-none-any.whl -
Subject digest:
1785e2e698c3f378327eeec3b023768c2720d6ca1a60967d501947b18105c861 - Sigstore transparency entry: 2312891383
- Sigstore integration time:
-
Permalink:
Topicspot/rulereach@88c54851bbd166f3c4577cf45cf14c1ce61273cd -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Topicspot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88c54851bbd166f3c4577cf45cf14c1ce61273cd -
Trigger Event:
push
-
Statement type: