Richard asked what the 8,192-byte rule cap was, how close the rules were to it, and whether it was real. The cap is a single constant, MAX_BYTES = 8 * 1024 in backend/tests/test_claude_rules.py. Claude Code’s own docs set no size limit on a rule file. The limits that do exist are elsewhere: CLAUDE.md is skipped above 4 MiB, and MEMORY.md is truncated after 200 lines or 25 KB. Three of the sixteen rules were within 125 bytes of the cap, and pdr2.md had 24 bytes to spare. Yesterday a trap had to be squeezed down to a pointer to fit.
We raised the cap to 16 KB with a 12 KB target. At about 2.5 bytes per token, even a full rule costs very little against a 1M window. What the old cap was really protecting was shape: a rule should be a list of traps, with the stories in area_*.md. A file cap guards that badly. It bites at the end, on whichever bullet happens to be added last, and it says nothing about which bullet has grown. So the test now also caps each bullet at 600 bytes. Across all sixteen rules the median bullet is about 190 bytes. Two bullets were over 740, and both were procedures and incident stories, not traps. They failed the new test, which is its positive control. I trimmed them to the trap and checked that every fact I removed was already in its area file, or added it there.
Whether a bullet is a trap or a story is a judgement, so I didn’t try to write a test for it. Instead the routing table in docs/memory_architecture.md now says what is not allowed in a rule and where each kind of thing goes, and /harvest-session cites that table at the point where it writes a rule. One example of the drift was still in place: pdr2.md described Run #2’s arms and a planning card, which is issue state. At Richard’s go-ahead it now points at #523 and #610, and the S0 measurement it quoted moved to area_pdr2.md.