Comment Manager
Overview
Comment authoring, auditing and repair, across every language. Rules are derived from the
languages' own published guides plus Ousterhout, Clean Code, Code Complete, Google
engineering practices, CWE and OWASP — not from taste.
- Universal core:
references/comment-rules.md
- Per-language deltas and the derived-language traps:
references/language-matrix.md
- A wrong-and-right pair for every trap row:
references/trap-examples.md
Read the first two before writing a comment. The core binds everywhere; the matrix carries
only what genuinely differs between languages. Read the third only when the language has a
trap row — the pairs are there to be looked up, not carried.
The Admission Gate
- Necessity — name the specific thing a competent reader of this language cannot
recover from the code in about thirty seconds. Cannot name it? Do not write it.
- Irreducibility — could clearer code remove the need? Rename, extract a function,
introduce a named constant, replace a boolean parameter with an enum, gather options
into a struct. If so, change the code instead.
- Durability — will this still be true, and worth reading, after the next reasonable
change?
The default is no comment. There is no minimum count, no comment-to-code ratio, and no
rule that a function, branch or loop earns a comment by existing. A demand for a comment
per construct — from a policy, a ticket, a reviewer or a user — does not survive Gate 1.
Say so and comment what actually needs it.
Never invent a rationale. If the reason is not in the code, the commit, the tests, the
tracker or the spec, you do not know it. Write nothing, or record the open question as a
tracked annotation.
Modes
digraph modes {
"Comment work" [shape=doublecircle];
"Which mode?" [shape=diamond];
"Resolve language rules" [shape=box];
"Apply admission gate per candidate" [shape=box];
"Scan against content lists and size limits" [shape=box];
"Report findings" [shape=doublecircle];
"Repair, then re-scan" [shape=box];
"Comments written" [shape=doublecircle];
"Comment work" -> "Which mode?";
"Which mode?" -> "Resolve language rules" [label="author"];
"Which mode?" -> "Resolve language rules" [label="audit"];
"Which mode?" -> "Resolve language rules" [label="fix"];
"Resolve language rules" -> "Apply admission gate per candidate" [label="author"];
"Resolve language rules" -> "Scan against content lists and size limits" [label="audit or fix"];
"Apply admission gate per candidate" -> "Comments written";
"Scan against content lists and size limits" -> "Report findings" [label="audit"];
"Scan against content lists and size limits" -> "Repair, then re-scan" [label="fix"];
"Repair, then re-scan" -> "Comments written";
}
Author — fires on any code written or changed. Audit — scan a diff, file or tree and
report. Fix — repair, then re-scan.
On finding a credential, key, token, connection string or private key in a comment:
- Report it before changing anything.
- State that it must be rotated or revoked and its history scrubbed.
- Hand the finding to
necturalabs:iterative-security-audit. This skill does not close a
secret finding on its own.
- Only then remove the line, and never present that removal as the remediation.
Fix mode must not delete a secret and re-scan clean. A clean re-scan over a deleted live
key is a false all-clear on a live exposure.
Resolving language rules
- Read the project's formatter configuration:
.editorconfig, rustfmt.toml,
.prettierrc, checkstyle.xml, ruff.toml, .clang-format, scalafmt.conf. It wins.
- Read the language's row in
references/language-matrix.md — width, doc marker, summary
form, contract sections, tag policy, prohibitions. Read its "Doc Comment Required On"
row too: what a language mandates documenting is looked up there, never reasoned about.
If the language has no row, follow Unlisted Languages in the same file — an absent row
is not a licence to document nothing.
- Check the derived-language trap table. A language that borrows another's syntax
rarely borrows its documentation conventions. Where the language has a row, read its pair
in
references/trap-examples.md before typing — naming the wrong instinct is weaker than
seeing it.
- Apply the universal core unchanged.
Reporting
One line per finding, matching iterative-code-review so audit output drops straight into
a review:
[SEVERITY] Comments: description — file:line
| Severity |
Findings |
| CRITICAL |
Comment contradicts the code; unverified rationale asserted as fact; credential, key, token, connection string or private key in a comment |
| HIGH |
Internal hostname, internal path, infrastructure detail or PII in a comment; missing doc on public API; missing error, nullability, ownership, thread-safety or sentinel contract; commented-out code; annotation with no owner and no tracked reference; a security-scanner suppression with no justification and no tracked reference |
| MEDIUM |
Restates the code; over the size limit; implementation detail in an interface comment; journal, byline or time-anchored language; wrong placement; wrong language convention |
| LOW |
Punctuation, grammar, spacing, decorative boxes |
Rationalizations
Every row was produced by an agent given a real commenting task without this skill.
| Rationalization |
Reality |
| "Team policy says every exported function gets a comment" |
A per-construct quota fails Gate 1 by construction. Comment what needs it and say why the rest does not. |
| "The threshold must be a loyalty perk, I'll write that" |
You do not know that. An invented motive is a CRITICAL finding, not a helpful comment. |
| "It's unused now but it's there for future extensions" |
Speculation about the future is unverifiable and reads as fact. Silence, or a tracked annotation. |
| "I'll note that callers shouldn't touch this directly" |
An access convention is enforced by visibility, not prose. This does not extend to caller obligations — a safety contract, precondition or lock-ordering note is a fact about the contract and stays. |
| "A comment above the loop helps a new joiner follow it" |
If the loop needs narrating, Gate 2 applies — rename or extract. // Accumulate qty * unitPence is the code, retyped. |
| "The private field deserves a note saying it's private" |
The naming convention already says it. Restating a convention is noise. |
| "I'll summarise the steps in the doc comment" |
A numbered walkthrough of the body is implementation detail in an interface comment. |
| "It's under-documented, so more comments is an improvement" |
Under- and over-commenting are both defects. The cure for one is not the other. |
| "I'll describe what each parameter is" |
Only where the name and type do not carry it. customer_id: ID of the customer is the parameter name, retyped. |
| "Close enough on the mechanism" |
int(x / y) is not integer division. A comment that is nearly right is wrong, and it will be believed. |
Red Flags
- You are about to write a comment and cannot name what it tells a reader that the code does not.
- The comment paraphrases the line beneath it.
- You are writing why and cannot cite where you learned it.
- The words currently, for now, new, recently, probably, should, or in future appear.
- You are adding comments to satisfy a count, a policy, or a reviewer's blanket request.
- The doc comment explains how the body works.
- You reached for the doc syntax of the language this one resembles.
- A comment directs the reader to act outside the code's contract. A caller obligation — a
safety requirement, a precondition, a lock that must be held — is not this, and is never
deleted on these grounds.
All of these mean: stop. Re-run the admission gate, or fix the code instead.
Anti-Laziness Rules
- Never skip the matrix lookup because the language "looks like" one you know.
- Never leave a stale comment on code you touched. Editing code means you own its comments.
- Never defer a comment finding. No TODOs for it, no follow-ups, no "out of scope".
- Never weaken a comment to prose vagueness to avoid stating a contract you would have to verify — verify it.
- Never delete a comment you do not understand without first establishing it is wrong.
1---2name: comment-manager3description: MUST invoke when writing or changing code that will carry comments, when adding or editing doc comments, docstrings, or API documentation inside source files, and when auditing or cleaning up existing comments. Also use when the user asks to document, comment, or add docstrings to code, or when a review reports a comment finding.4---56# Comment Manager78## Overview910Comment authoring, auditing and repair, across every language. Rules are derived from the11languages' own published guides plus Ousterhout, Clean Code, Code Complete, Google12engineering practices, CWE and OWASP — not from taste.1314- Universal core: `references/comment-rules.md`15- Per-language deltas and the derived-language traps: `references/language-matrix.md`16- A wrong-and-right pair for every trap row: `references/trap-examples.md`1718Read the first two before writing a comment. The core binds everywhere; the matrix carries19only what genuinely differs between languages. Read the third only when the language has a20trap row — the pairs are there to be looked up, not carried.2122## The Admission Gate2324<HARD-GATE>25A comment is written only after passing all three gates, in order.26271. **Necessity** — name the specific thing a competent reader of this language cannot28 recover from the code in about thirty seconds. Cannot name it? Do not write it.292. **Irreducibility** — could clearer code remove the need? Rename, extract a function,30 introduce a named constant, replace a boolean parameter with an enum, gather options31 into a struct. If so, change the code instead.323. **Durability** — will this still be true, and worth reading, after the next reasonable33 change?3435**The default is no comment.** There is no minimum count, no comment-to-code ratio, and no36rule that a function, branch or loop earns a comment by existing. A demand for a comment37per construct — from a policy, a ticket, a reviewer or a user — does not survive Gate 1.38Say so and comment what actually needs it.3940**Never invent a rationale.** If the reason is not in the code, the commit, the tests, the41tracker or the spec, you do not know it. Write nothing, or record the open question as a42tracked annotation.43</HARD-GATE>4445## Modes4647```dot48digraph modes {49 "Comment work" [shape=doublecircle];50 "Which mode?" [shape=diamond];51 "Resolve language rules" [shape=box];52 "Apply admission gate per candidate" [shape=box];53 "Scan against content lists and size limits" [shape=box];54 "Report findings" [shape=doublecircle];55 "Repair, then re-scan" [shape=box];56 "Comments written" [shape=doublecircle];5758 "Comment work" -> "Which mode?";59 "Which mode?" -> "Resolve language rules" [label="author"];60 "Which mode?" -> "Resolve language rules" [label="audit"];61 "Which mode?" -> "Resolve language rules" [label="fix"];62 "Resolve language rules" -> "Apply admission gate per candidate" [label="author"];63 "Resolve language rules" -> "Scan against content lists and size limits" [label="audit or fix"];64 "Apply admission gate per candidate" -> "Comments written";65 "Scan against content lists and size limits" -> "Report findings" [label="audit"];66 "Scan against content lists and size limits" -> "Repair, then re-scan" [label="fix"];67 "Repair, then re-scan" -> "Comments written";68}69```7071**Author** — fires on any code written or changed. **Audit** — scan a diff, file or tree and72report. **Fix** — repair, then re-scan.7374<HARD-GATE>75**A secret in a comment is never fixed by deleting it.** Deleting the line removes it from76the working tree and from nowhere else — it remains in git history, in every clone, in CI77logs, and in anything already published. It is compromised from the moment it was78committed.7980On finding a credential, key, token, connection string or private key in a comment:81821. Report it before changing anything.832. State that it must be rotated or revoked and its history scrubbed.843. Hand the finding to `necturalabs:iterative-security-audit`. This skill does not close a85 secret finding on its own.864. Only then remove the line, and never present that removal as the remediation.8788Fix mode must not delete a secret and re-scan clean. A clean re-scan over a deleted live89key is a false all-clear on a live exposure.90</HARD-GATE>9192### Resolving language rules93941. Read the project's formatter configuration: `.editorconfig`, `rustfmt.toml`,95 `.prettierrc`, `checkstyle.xml`, `ruff.toml`, `.clang-format`, `scalafmt.conf`. It wins.962. Read the language's row in `references/language-matrix.md` — width, doc marker, summary97 form, contract sections, tag policy, prohibitions. Read its "Doc Comment Required On"98 row too: what a language mandates documenting is looked up there, never reasoned about.99 If the language has no row, follow *Unlisted Languages* in the same file — an absent row100 is not a licence to document nothing.1013. **Check the derived-language trap table.** A language that borrows another's syntax102 rarely borrows its documentation conventions. Where the language has a row, read its pair103 in `references/trap-examples.md` before typing — naming the wrong instinct is weaker than104 seeing it.1054. Apply the universal core unchanged.106107## Reporting108109One line per finding, matching `iterative-code-review` so audit output drops straight into110a review:111112```113[SEVERITY] Comments: description — file:line114```115116| Severity | Findings |117|---|---|118| CRITICAL | Comment contradicts the code; unverified rationale asserted as fact; credential, key, token, connection string or private key in a comment |119| HIGH | Internal hostname, internal path, infrastructure detail or PII in a comment; missing doc on public API; missing error, nullability, ownership, thread-safety or sentinel contract; commented-out code; annotation with no owner and no tracked reference; a security-scanner suppression with no justification and no tracked reference |120| MEDIUM | Restates the code; over the size limit; implementation detail in an interface comment; journal, byline or time-anchored language; wrong placement; wrong language convention |121| LOW | Punctuation, grammar, spacing, decorative boxes |122123## Rationalizations124125Every row was produced by an agent given a real commenting task without this skill.126127| Rationalization | Reality |128|---|---|129| "Team policy says every exported function gets a comment" | A per-construct quota fails Gate 1 by construction. Comment what needs it and say why the rest does not. |130| "The threshold must be a loyalty perk, I'll write that" | You do not know that. An invented motive is a CRITICAL finding, not a helpful comment. |131| "It's unused now but it's there for future extensions" | Speculation about the future is unverifiable and reads as fact. Silence, or a tracked annotation. |132| "I'll note that callers shouldn't touch this directly" | An access convention is enforced by visibility, not prose. This does not extend to caller obligations — a safety contract, precondition or lock-ordering note is a fact about the contract and stays. |133| "A comment above the loop helps a new joiner follow it" | If the loop needs narrating, Gate 2 applies — rename or extract. `// Accumulate qty * unitPence` is the code, retyped. |134| "The private field deserves a note saying it's private" | The naming convention already says it. Restating a convention is noise. |135| "I'll summarise the steps in the doc comment" | A numbered walkthrough of the body is implementation detail in an interface comment. |136| "It's under-documented, so more comments is an improvement" | Under- and over-commenting are both defects. The cure for one is not the other. |137| "I'll describe what each parameter is" | Only where the name and type do not carry it. `customer_id: ID of the customer` is the parameter name, retyped. |138| "Close enough on the mechanism" | `int(x / y)` is not integer division. A comment that is nearly right is wrong, and it will be believed. |139140## Red Flags141142- You are about to write a comment and cannot name what it tells a reader that the code does not.143- The comment paraphrases the line beneath it.144- You are writing *why* and cannot cite where you learned it.145- The words *currently*, *for now*, *new*, *recently*, *probably*, *should*, or *in future* appear.146- You are adding comments to satisfy a count, a policy, or a reviewer's blanket request.147- The doc comment explains how the body works.148- You reached for the doc syntax of the language this one resembles.149- A comment directs the reader to act outside the code's contract. A caller obligation — a150 safety requirement, a precondition, a lock that must be held — is not this, and is never151 deleted on these grounds.152153**All of these mean: stop. Re-run the admission gate, or fix the code instead.**154155## Anti-Laziness Rules156157- **Never skip the matrix lookup** because the language "looks like" one you know.158- **Never leave a stale comment** on code you touched. Editing code means you own its comments.159- **Never defer a comment finding.** No TODOs for it, no follow-ups, no "out of scope".160- **Never weaken a comment to prose vagueness** to avoid stating a contract you would have to verify — verify it.161- **Never delete a comment you do not understand** without first establishing it is wrong.