Back to skills

Why Comments

Code

Why Comments

Flag comments that say what the code already says. Keep every comment that explains why. The user chooses which flagged comments to remove.

Definition

A comment is redundant if deleting it loses no information.

Test: remove the comment mentally. Could a reader still understand the code from the code alone? If yes, the comment is redundant.

A comment is valuable if it carries information the code cannot convey, such as a reason, a constraint, a history, or a warning.

When unsure, keep it.

Invocation

CommandBehavior
/why-commentsFind the 10 lowest-value comments.
/why-comments <number>Find that many lowest-value comments.
/why-comments allFind every low-value comment.

Workflow checklist

Copy this checklist and track your progress:

Comment Prune Progress:

  • 1. Resolve the limit (default 10)
  • 2. Search source files for comment candidates
  • 3. Rank from most to least redundant
  • 4. Get each candidate's age with git blame
  • 5. Present the table and ask for approval
  • 6. Remove only approved comments
  • 7. Run lint and typecheck

1. Search

  1. Resolve the limit from the invocation. Default is 10.
  2. Search source files. Skip generated output, vendored dependencies, lockfiles, and documentation.
  3. Rank candidates from most redundant to least.
  4. Get each candidate's age with git blame (see Comment age).

If a subagent is available, delegate the read-only search: request at most the limit, each with exact path, line, comment text, and one to three adjacent code lines. If a subagent is unavailable, run grep yourself. Do not simulate delegation or invent search results.

2. Present findings

Use exactly these columns:

CommentAgeWhy
// increment the counter8 months agoRemove. Restates count++ verbatim.
/** Returns the user id. */3 weeks agoRemove. Describes the function word by word.
// debounce avoids hammering the API on each keypress1 year agoKeep. Explains intent, not mechanics.
  • Comment: include the exact comment text in backticks.
  • Age: use the relative git blame age.
  • Why: start with *Remove.* or *Keep.*, then give one short reason.

Then ask:

Remove all recommended?

  • Yes, remove all recommended
  • No, I want to review each comment

3. Remove and verify

  1. Remove only the approved comments. If the user chose review mode, ask Remove or Keep for each, naming it by its exact text, not its location.
  2. Run the project's lint and typecheck. Fix anything the changes broke.

Never remove

Keep any comment that carries a why the code cannot convey:

  • backports, compatibility, or version-specific behavior;
  • infrastructure, deployment, or architecture;
  • workarounds, gotchas, or non-obvious reasons;
  • documentation, specifications, RFCs, or ADRs;
  • bugs, issues, tickets, or contextual TODOs/FIXMEs;
  • intent, trade-offs, or constraints;
  • public API documentation comments, even when they seem obvious.

Edge cases

  • Public API doc comments: keep them. They are contract documentation for consumers, even when they describe the obvious.
  • Commented-out code: that is dead code, not a comment. Output a STOP block and tell the user to invoke /prune. Do not delete it here. Do not continue ranking comments until the user has routed or dismissed that finding.
  • License headers: keep. Removing them changes legal posture.
  • Generated files: skip them entirely. Do not rank or report comments in generated output.
  • A comment that is half-wrong: flag it as a Keep-with-fix row instead of removing it. Deleting a wrong comment loses the warning it half-carries.

Comment age

For each candidate, run:

git blame -L <line>,<line> --date=relative -- <file>

Use the relative date. Mark uncommitted lines uncommitted.

See examples/findings-table.md for a worked table.

View on GitHub