Replace the comment rules in CLAUDE.md with the mutation test #100

Closed
opened 2026-08-23 09:37:22 +00:00 by a73x · 1 comment
a73x commented 2026-08-23 09:37:22 +00:00 (Migrated from git.a73x.sh)

[claude 2026-08-23] ~/.claude/CLAUDE.md currently says both "Comments show why, not how" and "Write assumptions down as comments". The second is what produced a 27% comment-to-code ratio. Trialled a replacement on eight packages (branch comment-audit, 546 lines removed, make ci + boot-gate green) and the rule that survived contact is mechanical rather than stylistic.

Proposed replacement for the ## Code block

- Don't assume behaviors — assert them in a test named for the claim
- Mutate the claim: if a test catches it, delete the comment and move the
  why into that test's failure message
- If only the compiler or the linter catches it, the comment stays — they
  are loud but cannot explain themselves
- What nothing catches: make it structural, or comment what a reader
  outside the code cannot run
- A kept comment should be able to say what fails when it is wrong

This drops "Write assumptions down as comments" and redirects it.

Why each clause is there

  • Named for the claim is the precondition that makes deletion safe. It works in this repo because test names already read as sentences (TestAwaitingHostCertDoesNotSpendRetryBudget). In a package where tests are named TestAdopt1 the rule would destroy information and replace it with nothing.
  • Move the why into the failure message — a comment in a test still does not fire. The message does. See TestLifecycleIsNeverReadByAControlLoop, which names the axes to branch on instead.
  • Compiler/linter clause was discovered by breaking it: RevokedCert.Serial widened to uint64 fails at a call site two files away with cannot use string as uint64 and no hint why. ST1020 does the same for an exported symbol's godoc summary — that one bit this very branch.
  • What nothing catches is contract semantics (what a wire field means to a consumer), external facts (what macOS will not let a Linux test observe), and peer contracts (what a v0.0.5 agent does on absence).

Evidence it is affordable

Reduction tracks coverage, inverted — guestAddr/resolveGuestCIDR near full coverage gave up nearly every comment; RunCLI/newPlatform at 0% gave up none. api/capacity.go and api/networks.go needed zero deletions: they were written this way already.

This is a change to the user's own working rules, so it is filed rather than applied.


Migrated from git-collab issue e145d242ea5c514d85f341686e78c1d386d8359d.

Original author: a73x dev@a73x.sh.

Close reason: [claude 2026-08-23] Applied — see comment above.

[claude 2026-08-23] `~/.claude/CLAUDE.md` currently says both "Comments show why, not how" and "Write assumptions down as comments". The second is what produced a 27% comment-to-code ratio. Trialled a replacement on eight packages (branch `comment-audit`, 546 lines removed, `make ci` + boot-gate green) and the rule that survived contact is mechanical rather than stylistic. ### Proposed replacement for the `## Code` block ``` - Don't assume behaviors — assert them in a test named for the claim - Mutate the claim: if a test catches it, delete the comment and move the why into that test's failure message - If only the compiler or the linter catches it, the comment stays — they are loud but cannot explain themselves - What nothing catches: make it structural, or comment what a reader outside the code cannot run - A kept comment should be able to say what fails when it is wrong ``` This drops "Write assumptions down as comments" and redirects it. ### Why each clause is there - **Named for the claim** is the precondition that makes deletion safe. It works in this repo because test names already read as sentences (`TestAwaitingHostCertDoesNotSpendRetryBudget`). In a package where tests are named `TestAdopt1` the rule would destroy information and replace it with nothing. - **Move the why into the failure message** — a comment in a test still does not fire. The message does. See `TestLifecycleIsNeverReadByAControlLoop`, which names the axes to branch on instead. - **Compiler/linter clause** was discovered by breaking it: `RevokedCert.Serial` widened to `uint64` fails at a call site two files away with `cannot use string as uint64` and no hint why. `ST1020` does the same for an exported symbol's godoc summary — that one bit this very branch. - **What nothing catches** is contract semantics (what a wire field means to a consumer), external facts (what macOS will not let a Linux test observe), and peer contracts (what a v0.0.5 agent does on absence). ### Evidence it is affordable Reduction tracks coverage, inverted — `guestAddr`/`resolveGuestCIDR` near full coverage gave up nearly every comment; `RunCLI`/`newPlatform` at 0% gave up none. `api/capacity.go` and `api/networks.go` needed **zero** deletions: they were written this way already. This is a change to the user's own working rules, so it is filed rather than applied. --- Migrated from git-collab issue `e145d242ea5c514d85f341686e78c1d386d8359d`. Original author: a73x <dev@a73x.sh>. Close reason: [claude 2026-08-23] Applied — see comment above.
a73x commented 2026-08-23 11:33:54 +00:00 (Migrated from git.a73x.sh)

[claude 2026-08-23] Applied to ~/.claude/CLAUDE.md (backup: CLAUDE.md.bak-20260823).

Landed as written, with two edits for the file's register:

  • Kept "Codify instructions in code, not prose", "Comments show why, not how", and "Group by domain" — the mutation test does not replace them.
  • "What nothing catches" now names the three categories the audit actually found rather than describing them abstractly: wire contracts, peer versions, the host OS.

"Write assumptions down as comments" is gone. Its replacement is the second clause: the assumption still gets written down, it just gets written down somewhere that fires.

[claude 2026-08-23] Applied to ~/.claude/CLAUDE.md (backup: CLAUDE.md.bak-20260823). Landed as written, with two edits for the file's register: - Kept "Codify instructions in code, not prose", "Comments show why, not how", and "Group by domain" — the mutation test does not replace them. - "What nothing catches" now names the three categories the audit actually found rather than describing them abstractly: wire contracts, peer versions, the host OS. "Write assumptions down as comments" is gone. Its replacement is the second clause: the assumption still gets written down, it just gets written down somewhere that fires.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
a73x/eitri#100
No description provided.