We ship 12 agent config kits, one per stack, and every one of them
passes the same validator before release. One of the validator rules is
a line budget. This post is the actual count, where the lines go, and
why the budget exists at all.
The raw numbers
Across all 12 kits (Astro, .NET, Go, Laravel, Next.js, Node/Express,
Django, FastAPI, Rails, React, Rust, Svelte):
AGENTS.md: 112-113 lines per kit
CLAUDE.md: 40 lines per kit
copilot-instructions.md: 18 lines per kit
.cursor/rules: 4 files per kit (3-5 allowed)
Total instruction surface per stack: about 170 lines of always-on text
plus 4 scoped rule files that load only when their globs match. The
Next.js kit is representative:
## Project context (6 lines)
## Commands (12 lines)
## Code style (8 lines)
## Testing expectations (8 lines)
## Commit conventions (8 lines)
## Safety rules (10 lines)
## Stack-specific rules (6 lines)
## Definition of done (8 lines)
Why 300 is the number
The budget is not aesthetic. Past a few hundred lines of always-on
instructions, compliance gets selective: models follow short constraint
lists reliably and long ones partially. The failure mode is not "the
agent ignores everything", it is worse: it follows rule 4 and rule 17
and silently drops rule 31. You cannot tell which rules are live by
reading the config.
We validated this the boring way: same task, same model, configs of
different sizes, then checked which constraints survived. Short configs
held. Long ones leaked. The leaks were not random: middle-of-file rules
and anything phrased as a preference (rather than a command) went
first.
The validator enforces the result:
CLAUDE_LINE_BUDGET = 300
if len(claude_lines) > CLAUDE_LINE_BUDGET:
errors.append(f"CLAUDE.md exceeds {CLAUDE_LINE_BUDGET}-line budget")
Where the lines go, and what earns them
Ranked by observed value per line:
Commands: highest. Exact, working commands are the single most
used block. Agents act on them literally. Twelve lines here prevent
the most failures of any block in the file.
Safety rules: highest cost of omission. Secret handling,
destructive-command gates, dependency pinning. Rarely exercised, but
when needed they are the only thing standing between the agent and a
pushed secret. Ten lines, non-negotiable.
Definition of done: underrated. Eight lines that tell the agent
when to stop. Without it, agents either stop early or refactor
unrelated code. With it, "verify-and-stop" becomes checkable.
Code style prose: lowest. Style the linter can check should not
spend agent-attention lines. Our kits keep this block at 8 lines and
push the rest into scoped rules or the linter config itself.
The pressure test for any new line
Every proposed line goes through three questions:
1. Does the linter/types/CI already catch this? → it doesn't belong here
2. Would following it change what the agent does this session? → if not, cut it
3. Is it phrased as a command with a concrete trigger? → preferences leak first
If a line survives all three, it usually fits. If the file does not
fit, something existing has to die for it. That constraint is the
point: a budget forces ranking, and ranking is where the value comes
from.
The scoped-rule escape valve
The 300 budget covers always-on files. Stack detail that only matters
for some files (migration conventions, generated-code handling, test
factories) lives in .cursor/rules/*.mdc files with glob activation.
They cost nothing until the relevant files are open. Our kits keep
always-on minimal and push depth into scope.
That is the whole design: 112 lines of always-on baseline, 4 scoped
rules for depth, 300-line hard ceiling, validator-enforced.
Related reading
- Your CLAUDE.md is probably too long: the compliance cliff, explained.
- How we validate 12 agent config kits: the rest of the validator rules.
- Writing Cursor rules that actually fire: activation modes explained: how glob scoping works.
All 12 kits ship with these budgets validator-tested: AgentConfig Studio. The Next.js kit is free (MIT) if you want to count the lines yourself.
Top comments (0)