The state of CLAUDE.md, October 2026
We read 492 public CLAUDE.md files and counted the rules, the hooks and the settings behind them. The tables are below, and the data file is a download.
What we looked at
- One repo per GitHub organization. We found 702 organizations by GitHub code search for coding agent rules files.
- 667 rules files were fetched. 492 of them are CLAUDE.md (405 at the repo root, 87 under .claude/). The other 175 are AGENTS.md (150) and GEMINI.md (25).
- Date of the run: Oct 26 2026.
- Every column in the data file comes from public files at public URLs.
Everything below is about the 492 CLAUDE.md files unless it says otherwise.
How many rules a file has
We count rule like lines with a keyword analyzer. The median CLAUDE.md has 8. The smallest has 0 and the largest has 525. A quarter of the files have more than 26, and one in ten has more than 57.
| Rule like lines in the file | Files | Share of 492 |
|---|---|---|
| 0 | 86 | 17.5% |
| 1 to 4 | 107 | 21.7% |
| 5 to 9 | 82 | 16.7% |
| 10 to 19 | 67 | 13.6% |
| 20 to 49 | 93 | 18.9% |
| 50 or more | 57 | 11.6% |
What is enforced today
These are the shares of the 492 files whose repo also has the setting or hook shown.
| In the same repo | Files | Share of 492 |
|---|---|---|
| A .claude/settings.json | 185 | 37.6% |
| A .claude/settings.local.json | 15 | 3.0% |
| A hooks directory | 60 | 12.2% |
| At least one hook command | 100 | 20.3% |
| Hook events or a hooks directory | 108 | 22.0% |
| permissions.deny | 30 | 6.1% |
| permissions.allow | 85 | 17.3% |
| A model set | 4 | 0.8% |
| A settings file that is not valid JSON | 2 | 0.4% |
| A .claude workflow | 29 | 5.9% |
Across all 667 rules files, 105 (15.7%) have at least one hook command. The 22.0% row counts a hooks directory or any hook event; the 20.3% row counts only repos with a hook command.
What the free kit already matches
The free kit has a catalog of hooks and settings. We matched each rule like line against it. There are 10,997 rule like lines in total.
| Result | Lines | Share of 10,997 |
|---|---|---|
| Matched a deny hook | 21 | 0.2% |
| Matched a nudge hook | 68 | 0.6% |
| Matched a setting | 133 | 1.2% |
| No match (prose) | 10,775 | 98.0% |
116 files (23.6%) have at least one line that matched something in the kit.
What a model says about the rest
Most lines matched nothing, so we drew two random samples of 300 of the unmatched lines. A model (Sonnet) labeled each one DENY, CHECK, SETTING, JUDGMENT or NOT_A_RULE. DENY means a hook could block it. CHECK means a hook could check it. SETTING means a setting covers it.
| Label | Sample 1 | Sample 1 share | Sample 2 | Sample 2 share |
|---|---|---|---|---|
| DENY | 50 | 16.7% (plus or minus 4.2) | 50 | 16.7% (plus or minus 4.2) |
| CHECK | 39 | 13.0% (plus or minus 3.8) | 42 | 14.0% (plus or minus 3.9) |
| SETTING | 12 | 4.0% (plus or minus 2.2) | 8 | 2.7% (plus or minus 1.8) |
| JUDGMENT | 44 | 14.7% (plus or minus 4.0) | 51 | 17.0% (plus or minus 4.3) |
| NOT_A_RULE | 155 | 51.7% (plus or minus 5.7) | 149 | 49.7% (plus or minus 5.7) |
Ranges are 95% margins. Sample 1 drew from 10,775 unmatched lines. After sample 1 we tightened the line detector, so it rejects code, paths, headings and fragments. That left 7,131 unmatched lines, and sample 2 is a fresh draw from them.
The tightening was tuned on sample 1, so sample 1 could be overfit. Sample 2 is the check. NOT_A_RULE moved from 51.7% to 49.7%, which is inside the range. The share of real rules that a hook or a setting could enforce was 101 of 145 (69.7%, plus or minus 7.5) in sample 1 and 100 of 151 (66.2%, plus or minus 7.5) in sample 2. Pooled, that is 201 of 296, or 68%.
The claim we make is this: about two thirds of real rules could be enforced by a hook or a setting. Could is not does. This counts what is possible, not what is installed.
As a control, a second model (Opus) relabeled the first 40 lines of sample 1. It gave the same label on 32 of 40, or 80%.
What this does not show
- The sample leans toward repos that have settings. Hook shares are likely overstated for CLAUDE.md files in general.
- The analyzer matches keywords. It is not a parser, so it can miss rules and count lines that are not rules.
- One repo per organization. Large organizations count once, and the repo we got may not be their main one.
- The labels come from a model, and each share has a range. A different model could label differently.
- No person checked the labels line by line.
- A rule that could be enforced is not a rule that someone should enforce. Some of these are better left to judgment.
The data
Download data.csv One row per organization, 667 rows. Columns:
- login: the GitHub organization.
- repo: the repo we read.
- rules_file: the rules file name we found.
- bytes: size of that file.
- has_settings, has_settings_local: 1 if the repo has .claude/settings.json or settings.local.json.
- has_hooks_dir: 1 if the repo has a hooks directory.
- hook_events: the hook event names set in the settings.
- n_hook_commands: how many hook commands the settings define.
- has_permissions_deny, has_permissions_allow, has_model: 1 if the settings set that key.
- settings_invalid: 1 if the settings file did not parse as JSON.
- has_claude_workflow: 1 if the repo has a Claude workflow file.
- n_total: rule like lines the analyzer found.
- n_deny, n_nudge, n_setting: lines matched to a deny hook, a nudge hook or a setting in the free kit.
- n_prose: lines with no match.
Check your own repo: paste its address into the analyzer.
Related: the free analyzer, the sample report, the log and the steward-kit repo.
Method and authorship
Produced by the steward-kit Claude Code sessions. The labels come from a language model, the matches from the free analyzer. No person reviewed the file line by line.