| name | code-comment-standards |
| description | Enforces code comment quality standards. Comments document current functionality in approachable format. No phase/task/step references. Focus on "what" not lengthy "why". Use TSDoc for public APIs. Link to docs for architecture details. |
📝 Code Comment Standards
Overview
Ensures code comments are clear, current, and maintainable. Comments should be human-readable and approachable for junior engineers while remaining terse. This skill enforces removal of stale temporal references, plan-related comments, and guides proper documentation practices.
Core Principle: Document what code does, not historical context or plan progress.
When to Use
ALWAYS activate this skill when:
- Writing new functions, classes, or modules
- Refactoring existing code with comments
- Reviewing pull requests with comment changes
- Creating public APIs or exported functions
- Adding TODOs or workaround comments
- About to commit code (pre-commit review)
The 10 Rules
Rule 1: Document Current Functionality ONLY
Comments explain what code currently does, not what it used to do or might do in the future.
function formatRelative(timestamp: string | Date): string {
function formatRelative(timestamp: string | Date): string {
Rule 2: Remove ALL Comments When Logic is Removed
When code is deleted, ALL related comments must be removed. No "removed" annotations.
Rule 3: NO Phase/Task/Step References
Plan progress numbers don't belong in code. Link to plan documents instead.
const contacts = useContacts();
invalidateCache(contactId);
const contacts = useContacts();
Rule 4: TODOs for Product Debt
TODOs track deferred work. Must include brief description and link to plan/issue.
When to Use TODOs:
- Feature planned but not yet built
- Known limitations or bugs
- Performance improvements identified but deferred
- Workarounds that should eventually be removed
When NOT to Use TODOs:
- High-priority issues (create GitHub issue instead)
- Breaking changes (handle immediately)
- Security vulnerabilities (fix now)
Rule 5: Focus on "What" - Move "Why" to Docs
Comments explain what code does. Lengthy architectural why goes in docs/ folder.
const MAX_CACHE_SIZE = 200;
const MAX_CACHE_SIZE = 200;
The Boundary:
- "What" stays in code: Function purpose, parameters, return values, operation flow
- "Why" goes to docs: Architecture decisions, trade-offs, historical context, benchmarks
Rule 6: Use TSDoc Format for Public APIs
TypeScript files use TSDoc (extends JSDoc) with @param, @returns, @see, @example, @deprecated.
async function loadContacts(contactIds: string[]): Promise<Contact[]> {
function formatRelative(timestamp: string | Date): string {
Single-line comments are fine for inline explanations:
const MAX_CACHE_SIZE = 200;
Rule 7: Inline Comments for Non-Obvious Logic
Add inline comments when logic isn't self-evident: workarounds, edge cases, performance choices.
Workarounds:
const reactiveMap = ref({ ...originalMap });
Edge Cases:
async function handlePostSwitchNavigation() {
Performance Notes:
const contacts = await cache.contacts.where('id').anyOf(contactIds).toArray();
Security Considerations:
function sanitizeSearchQuery(query: string): string {
Type Safety:
const contact = (await cache.contacts.get(id)) as Contact;
Rule 8: Architecture Comments - Brief + Link
Architecture comments provide overview, then link to detailed docs.
RECOMMENDED: Hybrid Approach
Design Pattern Comments:
const contacts = ref<Contact[]>([]);
broadcast.notify('contact', contactId, 'update');
Convention Deviation Comments:
const cache = new Map<string, Contact>();
Rule 9: External Links - Context + Summary
External links (Stack Overflow, GitHub, RFCs) are acceptable if they provide context. Include summary in case link breaks.
function parseTimezoneOffset(timeZone: string): number {
When External Links are Acceptable:
- Stack Overflow: Include summary of solution
- GitHub issues: YOUR project issues with brief context
- RFCs/Standards: W3C, TC39, ECMAScript specs
- Library docs: For limitations or workarounds
function parseDate(input: string): Date {
Rule 10: Pre-commit Hook Validation
A pre-commit hook validates comments against temporal/plan references before commits.
Detected Patterns:
- Phase/Task/Step numbers without doc links
- Date references without context ("as of Q4 2024")
- Vague temporal references ("recently added", "will be removed soon")
- "Temporary fix" without TODO + issue link
Hook Output Example:
❌ Pre-commit check failed: Stale comment patterns detected
src/composables/useExample.ts:45
Issue: Phase/Task reference without documentation link
Found: // Phase 7: Moved to controller pattern
Fix: Add @see docs/architecture/phase-7-migration.md
src/utils/helpers.ts:123
Issue: Temporal reference without context
Found: // Added in Q4 2024 for bug fix
Fix: Explain WHY or link to issue/bug report
File Organization Comments
Section Dividers
Use clear visual separation for large files:
export interface UserOption {
label: string;
value: string;
}
export function useUserSelection() {
File-Level Documentation
Every module starts with purpose explanation:
import { format, parseISO } from 'date-fns';
Examples from Codebase
✅ Excellent Examples
useTimestampFormat.ts - Perfect function documentation:
function formatRelative(timestamp: string | Date): string {
useContacts.ts - Perfect architecture overview:
useUserSelection.ts - Clear section dividers:
const router = useRouter();
const userStore = useUserStore();
❌ Violations to Fix
Phase/Task References:
const contacts = useContacts();
const contacts = useContacts();
Temporal References:
function syncContacts() {
function syncContacts() {
Removed Logic Comments:
Pre-commit Hook Integration
Add to .husky/pre-commit or similar:
node scripts/checkCommentQuality.js
if [ $? -ne 0 ]; then
echo "❌ Comment quality check failed"
exit 1
fi
Script Example:
const patterns = [
/Phase \d+/gi,
/Task \d+/gi,
/Step \d+\.?\d*/gi,
/as of \w+ \d{4}/gi,
/added in \w+ \d{4}/gi,
/recently added/gi,
];
const hasProperReference = line => {
return /@see docs\//.test(line) || /TODO:.*docs\//.test(line) || /TODO:.*https:\/\//.test(line);
};
Comment Anti-Patterns
❌ Commenting Out Code
❌ Obvious Comments
userId.value = newValue;
userId.value = newValue;
❌ Plan Progress Comments
const contacts = await loadContacts();
const active = contacts.filter(c => c.status === 'active');
const contacts = await loadContacts();
const active = contacts.filter(c => c.status === 'active');
❌ Lengthy Architecture Essays
Quick Reference
Comment Placement:
- File-level: Module purpose and overview
- Public APIs: Complete TSDoc with @param/@returns/@see
- Internal functions: Brief single-line or multi-line
- Inline: Only for non-obvious logic
Required Tags:
@param - All public function parameters
@returns - All public function return values
@see - Links to docs for architecture/design details
@deprecated - Mark deprecated code with migration path
Optional Tags:
@example - Show usage examples for complex APIs
@throws - Document exceptions/errors thrown
Comment Length:
- Single-line:
// Brief explanation
- Multi-line:
/** Purpose + details */
- Section dividers:
// ===== SECTION NAME =====
- Move to docs if: >5 lines, historical context, benchmarks, decisions
Remember: Comments document current state, not history. Plan progress belongs in docs/plans/, not code. Use pre-commit hooks to catch stale references before they enter the codebase.