Files
agent-skills/claude-md/code-comments.md
T
naps62 08195c1cd4 feat(hooks): track writing contracts + linters in repo
comms-lint.py and comment-lint.py lived only in ~/.claude, which is not
a git repo. Contract prose lived in ~/.claude/CLAUDE.md. Neither survived
a machine rebuild.

Prose moves to claude-md/ fragments, imported via @name.md. Linters move
to hooks/. link.sh and home.nix distribute both. settings.json wiring
stays manual — it holds machine-local MCP/statusline config this repo
must not own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VaGR6ERGCfzWTtuv2rebGe
2026-07-27 14:34:29 +00:00

2.5 KiB

Code comments

Governs VOLUME and PURPOSE. Caveman governs wording. Enforced by ~/.claude/hooks/comment-lint.py.

Assume the reader is an agent with the whole repo, not a human with one file open. It can read call sites, docs/, the tests and git log faster than it can read your prose. So a comment is not for teaching. It exists for ONE job: to stop a confident wrong edit.

Write a comment only when an agent with repo access and thirty seconds of grep would still get it wrong. Four cases qualify:

  1. Landmine. The code looks redundant, wrong, or reorderable and is not, AND no test catches breaking it. Say what breaks. This is the highest-value comment in the codebase. // MUST read lastGoodPrice before fetchPrice - same eth_call state; no test catches this.
  2. Fact not in the repo. Deployed bytecode, a chain quirk, a library's undocumented behaviour. One line and a path into docs/.
  3. Unit, encoding or epoch the type cannot carry - 18-dp, wei, ms, which instant a timestamp is anchored to.
  4. Cross-file invariant a caller can break, stated as MUST / MUST NOT.
  5. A rejected alternative that was actually tried, one line: what was tried, why it lost. An agent reading only the code sees an obvious improvement and re-does the failed work. Keep this ONLY where the losing attempt is not recoverable elsewhere — if docs/ or an ADR records it, cite that instead. Subjective domains (game feel, UI, copy) usually have no such record, so the comment is the only copy: // Outward was tried: brightest when it fights the silhouette.

Delete everything else. Mechanism the code already shows; what another module does; why this design over another; measurement narratives; consequence chains; anything a test asserts; anything git log records. The agent derives all of it on demand, and prose that duplicates code is prose that will contradict it after the next refactor.

Budget: 1-3 lines. Past 3 lines you are teaching, not warning - the only exception is a landmine that genuinely needs the mechanism spelled out to be actionable. Whole-file headers get 3 lines: what this is, and the one trap. Not a table of contents.

Prefer moving substance INTO docs/ and leaving a path. An agent will follow the path; it costs one read and the doc does not rot against the code.

No emphasis. No bold, no italics, no superlatives. ALL-CAPS only for MUST / NEVER on a real invariant, or to name the trap.

Deleting a comment is cheap and reversible - it is in git. When unsure, delete.