@@ -513,6 +513,89 @@ When stuck in debugging loops:
5135133 . ** Document the issue** comprehensively for a fresh approach
5145144 . ** Format for portability** (using quadruple backticks)
515515
516+ ## Comments earn their maintenance cost
517+
518+ A comment ships only if it passes all three gates. Fail any: delete or rewrite.
519+ Borderline: delete — borderline means the information is reconstructible, which
520+ is what makes deletion cheap.
521+
522+ ** Loss.** Three years from now, would losing this cost a maintainer real time
523+ rediscovering intent, an invariant, a constraint, or a failure mode the code and
524+ tests do not already make obvious?
525+
526+ ** Elite.** Would SQLite, Redis, the Go standard library, or CPython write this
527+ comment, at this length? Those projects state the constraint and stop. They do
528+ not argue with an imagined objector.
529+
530+ ** Upkeep.** Will it stay true without maintenance? A comment that hand-syncs a
531+ value the code owns — a count, an offset, a line reference, a duplicated
532+ constant — is false the first time that value moves.
533+
534+ ### Ceiling
535+
536+ One or two lines. A comment reaching four is either carrying several facts, in
537+ which case split it, or arguing, in which case cut it to the fact.
538+
539+ Rationale, alternatives weighed, and the story of how the code got here belong
540+ in the commit message: timestamped, attached to the exact diff, and free to
541+ maintain.
542+
543+ A comment often holds both a constraint and the deliberation that found it. Keep
544+ the constraint, cut the deliberation. "Runs at most once per second" survives;
545+ "this is the right trade for now" does not.
546+
547+ ### Keep
548+
549+ - Why over how: upstream quirks, protocol and compatibility constraints,
550+ performance tradeoffs still part of the contract.
551+ - Invariants, preconditions, ordering, lifetime, and concurrency requirements
552+ that types and tests cannot express.
553+ - Code that looks wrong but is not, so a later cleanup does not reintroduce the
554+ bug.
555+ - A high-level sketch of an algorithm whose local operations do not reveal the
556+ whole.
557+
558+ ### Delete
559+
560+ - Narration of the next lines; code translated into English.
561+ - Restated names, types, defaults, or control flow.
562+ - Values duplicated from the code and hand-synced.
563+ - Justification, hedging, or apology for a choice.
564+ - Speculation about future requirements.
565+ - History version control already holds, including commented-out code.
566+ - Ticket and issue numbers. They say nothing to a reader without tracker access,
567+ and they rot when the tracker moves. Unfinished work goes in the tracker, not
568+ the source.
569+ - Transient observations — "currently", "for now", "the latest release" —
570+ that go stale with no nearby edit.
571+
572+ ### The upkeep gate in practice
573+
574+ It reaches values that track our own code. It does not reach frozen external
575+ facts.
576+
577+ Bad (Delete):
578+
579+ ``` python
580+ # There are 321 tests to complete for servers.
581+ ```
582+
583+ Good (Keep):
584+
585+ ``` python
586+ # CPython < 3.11 has no ExceptionGroup, so this branch stays.
587+ ```
588+
589+ ### Documentation exception
590+
591+ Doctests, minimal usage examples, and param, return, and raises lines on public
592+ API are exempt from the loss gate — they serve the caller, not the maintainer.
593+ They are exempt from nothing else. Ceiling: a good man page entry.
594+
595+ NumPy-style ` Parameters ` , ` Returns ` , and ` Attributes ` sections and executable
596+ doctests fall under this exception — autodoc ships every field whether or not
597+ you describe it, and a doctest that runs is also a test.
598+
516599## AI Slop Prevention
517600
518601Treat AI slop as ** review-hostile noise** , not as proof that text or
@@ -570,8 +653,9 @@ on unrelated code while still resolving.
570653
571654### Preservation & Context
572655
573- ** When unsure, leave the text in place and ask.** Subjective cleanup
574- must never be a reason to remove load-bearing rationale.
656+ Subjective cleanup must never remove load-bearing rationale. Adjudicate
657+ comments with the comment policy above; borderline cases are deleted, not
658+ kept.
575659
576660- ** Preserve the "Why":** You MUST NOT delete comments that document
577661 invariants, protocol constraints, platform quirks, security
0 commit comments