When AI Should and Should Not Generate Comments
The over-commenting problem: AI tools tend to over-comment. The AI generates: '// Get the user by ID' above getUserById(). This comment: adds zero information — the function name already says exactly what it does. AI rule: 'Do not comment WHAT the code does — the code should be self-explanatory. Comment only WHY the code does something unexpected, or WHAT business context is not obvious from the code.' This single rule: eliminates 80% of unnecessary AI-generated comments while preserving the 20% that are genuinely useful.
When comments are required: AI rule: 'Comments required for: 1) Non-obvious business logic (why a discount is calculated this way, not just that it is calculated). 2) Workarounds and hacks (why the code deviates from the normal pattern — link to the issue/ticket). 3) Performance-critical decisions (why this algorithm was chosen over the simpler alternative). 4) Regulatory or compliance context (why this validation exists — reference the compliance requirement). 5) TODO items with ticket references (TODO(PROJ-123): migrate to the new API when available).' The AI: generates comments where they add value, not where they restate the code.
When comments are prohibited: AI rule: 'Never generate comments that: restate the code (// increment counter above counter++), explain standard library usage (// parse JSON above JSON.parse()), document obvious types (// user object above const user: User), or apologize for code quality (// this could be better). If the code needs a comment to explain WHAT it does: the code should be refactored, not commented.' The prohibition: prevents the AI from generating the low-value comments that clutter codebases. AI rule: 'The best comment rules are mostly prohibitions. Tell the AI what NOT to comment — then the remaining comments are the ones that actually help.'
Documentation-Level Comments
File-level comments: AI rule: 'File header comments required only for: 1) Files with non-obvious purpose (why does this utility exist?). 2) Files with important constraints (this module must remain synchronous for SSR compatibility). 3) Entry points (this is the main API router — all routes registered here). No file headers on standard files (components, services, types) where the file name and content are self-explanatory. When present: one paragraph maximum, no license headers (handled by tooling).' The AI: adds file-level context where it helps and skips it where it is noise.
Architecture Decision Records (ADRs) in comments: AI rule: 'For significant architectural decisions within code: use an ADR-style comment. Format: // ADR: [decision]. Context: [why this decision was made]. Alternatives considered: [what else was evaluated]. Decision: [what was chosen and why]. Example: // ADR: We use polling instead of WebSocket for notifications. Context: WebSocket connections dropped behind our corporate proxy. Alternatives: SSE (proxy issues), long polling (latency). Decision: short polling at 5s interval — reliable behind all proxies.' The AI: documents architectural decisions at the point where they are implemented. The developer reading the code: understands why the unusual approach was chosen.
Section separator comments: AI rule: 'Use section separators for files longer than 100 lines. Format: // --- Section Name ---. Standard sections: // --- Types ---, // --- Constants ---, // --- Helpers ---, // --- Main Logic ---, // --- Exports ---. The separators: create visual structure in long files. No separators in files under 100 lines (the file is already scannable).' The AI: adds structure to long files without cluttering short files. AI rule: 'Documentation-level comments serve future developers — including yourself in 6 months. The ADR explains why. The section separator helps navigate. The file header provides context. These comments: survive refactoring because they document decisions, not implementation.'
Regular comment: '// Use polling to fetch notifications every 5 seconds.' Code gets refactored. The polling interval changes to 10 seconds. The comment: now wrong (says 5s, code does 10s). ADR comment: '// ADR: Polling over WebSocket for notifications. Context: WebSocket dropped behind corporate proxy. Decision: short polling — reliable across all network configs.' Code gets refactored (interval changes). The ADR: still correct (the decision and its rationale have not changed). ADR comments: outlast implementation changes because they document the WHY, not the WHAT.
AI-Specific Comment Pitfalls
Pitfall 1: the AI generates a comment for every line. AI prompt: 'Add comments to this function.' AI output: every line gets a comment. The function: 10 lines of code, 10 lines of comments. The readability: worse, not better. Prevention rule: 'Comments should be rare — most code does not need comments. If you are about to add a comment: first check if the code can be made self-explanatory through better naming or structure. Only add a comment if the code cannot communicate the WHY.'
Pitfall 2: the AI generates stale comments during refactoring. The AI refactors a function but does not update the comments above it. The comment: describes the old behavior. The code: implements the new behavior. The reader: confused. Prevention rule: 'When modifying code: always review and update adjacent comments. If a comment describes behavior that the code no longer implements: remove or update the comment. Stale comments are worse than no comments — they actively mislead.'
Pitfall 3: the AI generates comments in a different language or style. The project uses English comments with American spelling. The AI: occasionally generates British spelling (colour instead of color) or translates from another language. Prevention rule: 'All comments in American English. Use present tense (validates the input, not validated the input). Use active voice (the function returns, not the result is returned by). No abbreviations in comments (use configuration, not config).' The AI: generates linguistically consistent comments. AI rule: 'AI comment pitfalls share a root cause: the AI defaults to verbose, obvious commenting because its training data rewards helpfulness. In code: less commenting is more helpful. The rules: override the AI's verbosity instinct with your project's signal-over-noise preference.'
Comment from 6 months ago: '// Returns the user's primary email address.' Current code: returns an array of all email addresses. A developer reads the comment, assumes they get a string, writes code that calls .toLowerCase() on the return value. Runtime error: .toLowerCase is not a function (because it is an array). The stale comment: caused a bug. No comment at all: the developer would have read the return type and written correct code. AI rule: 'When modifying code: always review adjacent comments. Stale comments mislead. Remove or update them.' The cost of a stale comment: measured in debugging hours.
Code Comment Rules Quick Reference
Quick reference for AI coding comment rules.
- Core rule: comment WHY, never WHAT — the code explains what, comments explain why
- Required: business logic context, workarounds with ticket links, performance decisions, compliance references
- Prohibited: restating code, explaining standard library, documenting obvious types, apology comments
- Format: // with single space, line above code for multi-word, no block comments for single lines
- JSDoc: exported functions and types only, @param @returns @throws format, no JSDoc on internals
- TODOs: always with ticket reference (TODO(PROJ-123)), no orphaned TODOs without tickets
- File headers: only for non-obvious purpose or important constraints, one paragraph maximum
- ADRs: decision + context + alternatives + rationale — at the code location where the decision applies
Comment Format and Style Standards
Inline comment format: AI rule: 'Inline comments: // single space after //. Same line as code only for short clarifications (less than 40 characters). Otherwise: comment on the line above the code it explains. Never use block comments (/* */) for single-line comments. Multi-line explanations: use multiple // lines, not /* */.' The AI: generates consistently formatted comments. The codebase: has a unified comment style.
JSDoc format for public APIs: AI rule: 'All exported functions and types have JSDoc comments. Format: @param name — description (one line per parameter). @returns description. @throws ErrorType — when condition. @example optional usage example for complex APIs. No JSDoc on private functions, utility helpers, or obvious getters/setters. The JSDoc: documents the contract, not the implementation.' The AI: generates documentation for public APIs and skips internal code. The documentation: serves developers who use the API, not those who read the implementation.
TODO and FIXME conventions: AI rule: 'TODO format: // TODO(PROJ-123): description of what needs to be done. FIXME format: // FIXME(PROJ-456): description of the known issue. HACK format: // HACK(PROJ-789): description and link to issue. All TODOs must have a ticket reference (no orphaned TODOs). No TODO without a ticket — create the ticket first, then add the TODO.' The AI: generates traceable TODO items that connect to the issue tracker. The team: can search for all TODOs and find the associated tickets. AI rule: 'Comment format rules ensure consistency and traceability. Every TODO connects to a ticket. Every JSDoc follows the same structure. Every inline comment uses the same style. The consistency: makes comments a reliable information source, not a random collection of notes.'
AI default: generate JSDoc for every function, including internal helpers called from one place. Result: 50 functions, 50 JSDoc blocks, 200 lines of documentation. Most of it: documents internal implementation that only the author reads. AI rule: 'JSDoc on exported functions and types only.' Result: 12 exported functions, 12 JSDoc blocks, 48 lines of useful API documentation. The 38 internal functions: self-documenting through naming. The documentation: 75% smaller, 100% more useful. JSDoc on exports: documents the contract. JSDoc on internals: documents implementation that changes frequently.