Skill: Code Documentation and Comments
Defines what to comment, what not to comment, and how to keep comments from
rotting. Operationalizes engineering-principles.md §4.1 (naming reveals
intent) and §11.2 (comments on key functions).
Core principle: code says how; comments say why. A comment that
restates the code is noise that will drift out of sync. A missing "why" on
a non-obvious decision is a future bug.
Comment vs. rename — decide first
Before writing a comment, ask whether a better name removes the need:
// ❌ Comment compensating for a bad name
const d = 86400000; // milliseconds in a day
// ✅ The name carries the meaning — no comment needed
const MILLIS_PER_DAY = 86_400_000;
// ❌ Comment explaining what the code already says
// increment the counter by one
counter += 1;
// ✅ Comment explaining WHY (non-obvious business reason)
// Retry budget is 1 higher than the SLA allows — the gateway eats the first
// attempt during cold start (see incident 2026-03 in lessons-learned.md).
maxRetries += 1;
Rule: if a clearer name, a named constant, or an extracted function removes
the comment, prefer that. Comment only what the code cannot express.
What MUST be documented
- Public functions in services, controllers, utilities, and business-rule
modules — a doc comment stating purpose, parameters, return, thrown
errors, and side effects (if any). This is the API surface others rely on.
- Non-obvious "why" — workarounds, deliberate deviations from the obvious
approach, ordering that matters, performance/security trade-offs. Link to
the ADR or
lessons-learned.md entry when one exists.
- Units, ranges, and invariants that the type system doesn't capture
(e.g., "amount in cents", "0–1 inclusive", "must be called after
init()").
- TODO/FIXME with an owner and a tracking reference
(
// TODO(#123): …) — a bare TODO is invisible.
What must NOT be documented
- Restatements of the code (
// loop over users).
- Commented-out code — delete it; git remembers.
- Changelog/author noise in the body (
// modified by X on date) — that is
git's job.
- Comments that duplicate an enforced type or validation.
Avoiding comment rot
- A comment lives next to what it explains; if the code moves, the
comment moves with it.
- When you change behavior, update or delete the surrounding comment in the
same commit — a stale comment is worse than none.
- During code review, treat an out-of-date comment as a blocking finding
(see
proc-code-review).
Module / file-level documentation
Each non-trivial module/package gets a short header or README explaining its
responsibility and its place in the architecture (which layer, what it owns).
Keep it to a few lines — deep design rationale belongs in docs/architecture.md
or an ADR, not in source headers.
Common mistakes
| Mistake |
Cause |
Solution |
| Comment repeats the code |
Commenting by habit |
Comment the why, or delete |
| Comment compensates a bad name |
Naming skipped |
Rename / extract instead |
| Stale comment after a change |
Updated code, not the comment |
Same-commit rule; review catches it |
| Commented-out blocks pile up |
"Might need it later" |
Delete — git has history |
Bare TODO never resolved |
No owner/tracking |
TODO(#issue): … |
Resources
- doc-comment-formats.md — per-language doc-comment
syntax and examples (JSDoc/TSDoc, Javadoc, Python docstrings, Go doc
comments, JavaDoc-style for C#).
1---2name: proc-code-documentation3description: Use when writing or reviewing comments, docstrings, and inline documentation in code. When to comment vs. when to rename, the "why not what" rule, documenting public/business-rule functions, and avoiding comment rot. Per-language doc-comment formats as resources.4---56# Skill: Code Documentation and Comments78Defines what to comment, what *not* to comment, and how to keep comments from9rotting. Operationalizes `engineering-principles.md` §4.1 (naming reveals10intent) and §11.2 (comments on key functions).1112> **Core principle:** code says *how*; comments say *why*. A comment that13> restates the code is noise that will drift out of sync. A missing "why" on14> a non-obvious decision is a future bug.1516## Comment vs. rename — decide first1718Before writing a comment, ask whether a better name removes the need:1920```js21// ❌ Comment compensating for a bad name22const d = 86400000; // milliseconds in a day2324// ✅ The name carries the meaning — no comment needed25const MILLIS_PER_DAY = 86_400_000;26```2728```js29// ❌ Comment explaining what the code already says30// increment the counter by one31counter += 1;3233// ✅ Comment explaining WHY (non-obvious business reason)34// Retry budget is 1 higher than the SLA allows — the gateway eats the first35// attempt during cold start (see incident 2026-03 in lessons-learned.md).36maxRetries += 1;37```3839Rule: if a clearer name, a named constant, or an extracted function removes40the comment, prefer that. Comment only what the code **cannot** express.4142## What MUST be documented4344- **Public functions in services, controllers, utilities, and business-rule45 modules** — a doc comment stating purpose, parameters, return, thrown46 errors, and side effects (if any). This is the API surface others rely on.47- **Non-obvious "why"** — workarounds, deliberate deviations from the obvious48 approach, ordering that matters, performance/security trade-offs. Link to49 the ADR or `lessons-learned.md` entry when one exists.50- **Units, ranges, and invariants** that the type system doesn't capture51 (e.g., "amount in cents", "0–1 inclusive", "must be called after `init()`").52- **TODO/FIXME** with an owner and a tracking reference53 (`// TODO(#123): …`) — a bare TODO is invisible.5455## What must NOT be documented5657- Restatements of the code (`// loop over users`).58- Commented-out code — delete it; git remembers.59- Changelog/author noise in the body (`// modified by X on date`) — that is60 git's job.61- Comments that duplicate an enforced type or validation.6263## Avoiding comment rot6465- A comment lives **next to** what it explains; if the code moves, the66 comment moves with it.67- When you change behavior, update or delete the surrounding comment in the68 **same commit** — a stale comment is worse than none.69- During code review, treat an out-of-date comment as a blocking finding70 (see `proc-code-review`).7172## Module / file-level documentation7374Each non-trivial module/package gets a short header or README explaining its75responsibility and its place in the architecture (which layer, what it owns).76Keep it to a few lines — deep design rationale belongs in `docs/architecture.md`77or an ADR, not in source headers.7879## Common mistakes8081| Mistake | Cause | Solution |82|---------|-------|----------|83| Comment repeats the code | Commenting by habit | Comment the *why*, or delete |84| Comment compensates a bad name | Naming skipped | Rename / extract instead |85| Stale comment after a change | Updated code, not the comment | Same-commit rule; review catches it |86| Commented-out blocks pile up | "Might need it later" | Delete — git has history |87| Bare `TODO` never resolved | No owner/tracking | `TODO(#issue): …` |8889## Resources9091- [doc-comment-formats.md](doc-comment-formats.md) — per-language doc-comment92 syntax and examples (JSDoc/TSDoc, Javadoc, Python docstrings, Go doc93 comments, JavaDoc-style for C#).