feat: one writing contract for Claude Code and Codex

Replaces public-comms.md and code-comments.md (749 words, ~25 rules,
almost all prohibitions, no examples) with a single writing.md that
leads with worked examples.

The rule is selection, not compression: keep output short by cutting
whole ideas that don't change what the reader does next, then write what
survives as plain sentences. Not by dropping articles or writing
fragments, which Anthropic's Fable 5 guide calls out as the wrong lever.
Prompt style leaks into output style, so the file is written in the
voice it asks for.

Drops the BLUF ask-line rule entirely: everyone on a PR already knows
who reviews and who merges, and read literally it produced openers like
"Ask: reviewers please merge".

Links the contract to ~/.agents/AGENTS.md, which Codex had nothing in at
all, and to the nix module for the NixOS machine.
This commit is contained in:
naps62
2026-08-01 13:06:38 +00:00
parent 17677c18df
commit a1f95a1161
9 changed files with 197 additions and 101 deletions
-40
View File
@@ -1,40 +0,0 @@
## 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.