docs/content-model.md opens with "Engine specification". It is also where the rule lives that a leading underscore makes a file unaddressable — and the human who owns this site did not know that rule, because nothing in this repository is addressed to an author. Twelve documents named docs/ while being exclusively about building the parser is a signpost pointing at the wrong room. Naming the directory for its audience makes the gap visible instead of hiding it. docs/ is now reserved and deliberately absent: an empty docs/ is an honest statement that end-user documentation does not exist, where docs/ full of parser specs was a claim that it did. HARNESS.md stays at the root. Root holds the three entry points — README.md for a human, CLAUDE.md for an agent, HARNESS.md for whoever maintains the machine — and harness/README.md is the map of the directory, so moving the guide inside would have collided with it for nothing. Mechanical and wide: 100 path references across 24 files. Every verify.sh gate that names a doc by path, the directory lists the dangling-path and ADR-number gates scan, surface.sh's output target, the Makefile, CLAUDE.md's read order, the skill, four commands, and two Go package comments. A first pass with a shell loop silently edited only four files and the rest still said docs/; the fix was to write the file list out and check the remaining count was zero rather than trust the loop's exit status. No rule, threshold, gate or obligation moved — this is a rename, and the gates demonstrated it twice: they stayed green on the new paths, and the ADR-number gate caught ADR-0082 before the entry existed. Deferred, both on the human's call: the end-user documentation site itself, which wants its own decision about where it lives and whether its claims are gated; and moving examples/ under docs/, since demo-site is a live site root that verify.sh, the coverage test and make demo all point at, and moving it would couple a rename to a design nobody has made. 31 files, +146/-106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
39 lines
3.1 KiB
Bash
39 lines
3.1 KiB
Bash
# Growth budgets. `_MAX` fails verify.sh; `_WARN` prints and moves on.
|
|
# Raising a _MAX needs an ADR stating old and new values. Growth requires a signature.
|
|
#
|
|
# Only whole-system budgets fail. A hard per-file limit is the one gate whose cheapest fix makes the
|
|
# code worse — sharding a coherent file into a `_helpers.go` turns it green while creating the package
|
|
# CLAUDE.md rule 3.6 bans. Total mass cannot be gamed by moving code between files; file length can.
|
|
|
|
CORE_LOC_MAX=3000 # cmd/ + internal/{content,render,web} + repo root, non-test .go (ADR-0041, ADR-0065, ADR-0074)
|
|
EXT_LOC_MAX=3500 # internal/ext/ — composition, grows after the core freezes (ADR-0074)
|
|
FILE_LOC_WARN=500 # any single .go file — advisory
|
|
FUNC_LOC_WARN=60 # any single function — advisory
|
|
DEPS_MAX=9 # total modules in go.mod, direct plus indirect (ADR-0074)
|
|
CLAUDE_LOC_MAX=150 # CLAUDE.md only — the one file billed on every turn (ADR-0053)
|
|
|
|
# Two ceilings because "the core stops growing after Arc 2" (architecture.md invariant 9) is only an
|
|
# invariant if something measures it: post-freeze CORE holds and only EXT rises.
|
|
# Costed, not round, and re-costed once (ADR-0041): the first figure covered spine, bundles, queries,
|
|
# render, routing and templates (~1200-1800 → 2000) but never budgeted what cmd/ would hold. Adding `check`
|
|
# ~250, `new` ~100, `-dev` ~100, change detection ~100 and the page cache ~200 to a core already at 1870
|
|
# gives ~2620 → CORE 2800. A second raise is evidence something belongs in internal/ext/, not evidence the
|
|
# number is still too small.
|
|
# Feeds, sitemap, OpenGraph, shortcodes, image sizing, galleries, paging, indieweb ~900-1200 → EXT
|
|
# 2000, deliberately loose since that is where growth belongs. Reaching CORE asks what to delete;
|
|
# reaching EXT asks whether a template would have done it — only .go lines count here.
|
|
# Raised a second time, 2800 → 2850 (ADR-0065), for eight lines of theme contract. ADR-0041 said to read a
|
|
# second raise as evidence something belongs in `ext`: it is, and the candidates are `feed.go` and
|
|
# `discover.go`, which cannot move until a feature can own a route. That is the registry's trigger, not this
|
|
# feature's problem, and the honest fix was not to pretend the contract fits.
|
|
#
|
|
# Raised a third time, and this one is different: 2850 → 3000 core, 2000 → 3500 ext, 6 → 9 modules, all
|
|
# signed off in advance of a list of features rather than in response to one that arrived (ADR-0074). A
|
|
# ceiling raised on evidence is a measurement; a ceiling raised on intent is a budget, and this is the second
|
|
# kind. `ext` was the binding one — 1975 of 2000 with a syntax-highlighting feature still to write.
|
|
#
|
|
# CLAUDE_LOC_MAX is a different kind of budget: every other ceiling here bills once, when someone reads
|
|
# the code, while CLAUDE.md is re-sent on every turn of every session. 150 leaves ~20 lines of headroom
|
|
# over the current file. Reaching it means moving detail to the doc that owns the topic, never deleting
|
|
# a rule to fit — `harness/README.md`'s compression contract governs which of the two you are doing.
|