You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c945cce
Browse filesBrowse the repository at this point in the historyBrowse files
why: Two rules in this file gave opposite answers on the same
comment. The slop rubric said to keep the text and ask when
unsure; the estate now prefers deletion in the borderline case.
what:
- Add "Comments earn their maintenance cost": the loss, elite,
and upkeep gates, the one-to-two-line ceiling, and the keep
and delete lists
- Exempt doctests, usage examples, and param, return, and
raises lines on public API from the loss gate, and from
nothing else
- Point "Preservation & Context" at the new rule and drop its
keep-when-unsure default, keeping the invariant carve-out
Copy file name to clipboardExpand all lines: AGENTS.md
+89-2Lines changed: 89 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -501,6 +501,92 @@ colors.error("failed") # Red (errors)
501
501
502
502
**Bold may not render distinctly.** Some terminal/font combinations don't differentiate bold from normal weight. Don't rely on bold alone for visual distinction - pair it with color differences.
503
503
504
+
## Comments earn their maintenance cost
505
+
506
+
A comment ships only if it passes all three gates. Fail any: delete or rewrite.
507
+
Borderline: delete — borderline means the information is reconstructible, which
508
+
is what makes deletion cheap.
509
+
510
+
**Loss.** Three years from now, would losing this cost a maintainer real time
511
+
rediscovering intent, an invariant, a constraint, or a failure mode the code and
512
+
tests do not already make obvious?
513
+
514
+
**Elite.** Would SQLite, Redis, the Go standard library, or CPython write this
515
+
comment, at this length? Those projects state the constraint and stop. They do
516
+
not argue with an imagined objector.
517
+
518
+
**Upkeep.** Will it stay true without maintenance? A comment that hand-syncs a
519
+
value the code owns — a count, an offset, a line reference, a duplicated
520
+
constant — is false the first time that value moves.
521
+
522
+
### Ceiling
523
+
524
+
One or two lines. A comment reaching four is either carrying several facts, in
525
+
which case split it, or arguing, in which case cut it to the fact.
526
+
527
+
Rationale, alternatives weighed, and the story of how the code got here belong
528
+
in the commit message: timestamped, attached to the exact diff, and free to
529
+
maintain.
530
+
531
+
A comment often holds both a constraint and the deliberation that found it. Keep
532
+
the constraint, cut the deliberation. "Runs at most once per second" survives;
533
+
"this is the right trade for now" does not.
534
+
535
+
### Keep
536
+
537
+
- Why over how: upstream quirks, protocol and compatibility constraints,
538
+
performance tradeoffs still part of the contract.
539
+
- Invariants, preconditions, ordering, lifetime, and concurrency requirements
540
+
that types and tests cannot express.
541
+
- Code that looks wrong but is not, so a later cleanup does not reintroduce the
542
+
bug.
543
+
- A high-level sketch of an algorithm whose local operations do not reveal the
544
+
whole.
545
+
546
+
### Delete
547
+
548
+
- Narration of the next lines; code translated into English.
549
+
- Restated names, types, defaults, or control flow.
550
+
- Values duplicated from the code and hand-synced.
551
+
- Justification, hedging, or apology for a choice.
552
+
- Speculation about future requirements.
553
+
- History version control already holds, including commented-out code.
554
+
- Ticket and issue numbers. They say nothing to a reader without tracker access,
555
+
and they rot when the tracker moves. Unfinished work goes in the tracker, not
0 commit comments