From 5c2bec043e0d0f96d0e738020f7b63bc162e3f54 Mon Sep 17 00:00:00 2001 From: Daniele Date: Mon, 24 Aug 2026 18:31:21 +0100 Subject: [PATCH] docs: reading a dev-doc is not conditional on the size of the change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The routing table said "before you touch one of these areas, open its file", and the closing line explained why a pointer is not a summary. Neither survives contact with a change that looks trivial: the diagnosis feels complete after a grep, the edit is one line, and the file never gets opened. That is how the narrow-page bug in the previous commit was nearly shipped as a one-line addition to the very enumeration that was the defect. State the missing half. "The fix is obvious" is what triggers the rule, not what excuses you from it, because a dev-doc is not a description of the code — it is the rules and traps the code cannot state about itself, and grepping the source finds what the code does, never what you must not do to it. Add the two consequences that make it cheap to comply: the same-change update rule means the file has to be opened regardless, so opening it first is free and is the only moment it can still change what gets built; and the file is read whole, since the paragraph that saves you is not the one matching the grep. Give the write-side standing rule its read half explicitly, where it was only ever phrased as an obligation to type into the file. --- CLAUDE.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index f26660e..88ad8fa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -18,7 +18,7 @@ Four places. **Only this file is loaded into your context automatically** — th Code that lives outside this repo but that a change here can break is listed under [Sibling repositories](#sibling-repositories). -**Before you touch one of these areas, open its file:** +**Before you touch one of these areas, open its file — every time, before the first edit:** | You are touching | Read | | ---- | ---- | @@ -37,6 +37,15 @@ Code that lives outside this repo but that a change here can break is listed und A pointer is not a summary. If the table sends you to a file, that file is where the decision was recorded and why the obvious alternative was rejected — inferring it from this one instead is how a trap already paid for gets stepped on twice. +**Reading it is not conditional on the size of the change, and "the fix is obvious" is what triggers the rule, not what excuses you from it.** A one-line CSS edit, a renamed field, a typo in a label — those are exactly the changes made without opening anything, because the diagnosis felt complete after a grep. It wasn't: a `dev-docs` file is not a description of the code, it is the **rules and traps the code cannot state about itself** — invariants whose violation compiles cleanly and fails silently, a helper that must be called synchronously and looks identical to the one that must not, an enumeration that is load-bearing, the alternative that was already tried and reverted. Grepping the source finds *what* the code does; it cannot find *what you must not do to it*. Reconstructing that from the code later means reconstructing it from the one version that cannot explain itself. + +Two practical consequences: + +- **You will have to open the file anyway.** The [standing rule](#dev-docs) says a change to a subsystem updates its dev-doc *in the same change*. Opening it first costs nothing extra and is the only moment when what it says can still change what you build; opening it last reduces it to a place to type into. +- **Read the whole file, not the section you think you need.** They are short by design. The part that saves you is rarely the part matching your grep — it is two paragraphs away, in the trap you did not know existed. + +The worked example is in [`dev-docs/frontend.md`](dev-docs/frontend.md): the Models → TTS page rendering 45px wide. The cause was not in the page but in a missing rule *about* the page, and the fix was not to add the missing name to a list but to delete the list — because a hand-maintained enumeration of element names fails silently, with no console error and no failed build. A grep found the symptom in three calls and would have shipped the one-line version of the fix. + ## Sibling repositories Three repositories are checked out **beside** this one, at the same level as its root. They are separate git repos — own history, own `CLAUDE.md`, own release cycle — and are not part of this Cargo workspace: @@ -216,6 +225,8 @@ To pick up `config.yml` / `providers.yaml` / database changes (read only at star `dev-docs/*.md` carries the **third standing rule**, for the same reason as the other two: **a change to a subsystem updates that subsystem's dev-doc in the same change.** These files are the recorded rationale — what was tried, what broke, why the obvious alternative was rejected — and a rationale reconstructed later is reconstructed from the code, which is the one version that cannot explain itself. New subsystem ⇒ new file plus a row in [`dev-docs/README.md`](dev-docs/README.md) *and* in the routing table at the top of this file; if it does not appear in both, nobody will open it. +That rule has a **read half, and it is the half that gets skipped**: you do not edit a subsystem you have not read the dev-doc for — see [How this documentation is organized](#how-this-documentation-is-organized). Writing into a file you opened only at the end is bookkeeping; the file earns its cost only when it is read before the first edit. + Keep the split honest in the other direction too: a rule a change *anywhere* could violate belongs in `CLAUDE.md`, not in a dev-doc nobody loaded. ### The changelog