agentsclimarketplace

Code comments

Skill volodymyrkoval/tdd-claude/skills/code-comments

Personal Claude Code setup for TDD

Install
npx -y skills add volodymyrkoval/tdd-claude --skill code-comments

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Decides when and how to write code comments — JSDoc/docstrings on exported symbols, module/file-level headers, and inline comments. Apply when writing or modifying functions/classes/modules; when about to add a comment; when touching code with redundant restatements, commented-out code, or stale TODOs nearby (opportunistic cleanup, change-radius only). Language-agnostic principles with concrete syntax for JS/TS, Python, and Go — extends to Rust, Java, C#, Ruby. Reviewer applies it to flag comment-quality violations during code review. Does NOT cover README/feature-doc/CLAUDE.md updates (use docs-writer), commit messages, or changelog entries.

SKILL.md

10.9 KB, as published. Nobody here has run it

Code Comments — When and How

Principle

Comments earn their place by carrying context the code cannot. Types, names, and structure carry the what. Comments carry the why, the invariants, and the domain semantics no signature can encode. Comments that restate the next line are noise — they cost tokens, drift over time, and dilute the signal of the comments that matter.

First move when tempted to comment: can a better name or an extracted function carry the meaning instead? If yes, do that. Comments are the fallback when structure has done all it can.


1. JSDoc / docstrings on exported symbols

Covers functions, classes, types, enums, and exported constants — anything callers import or instantiate.

Add when: the symbol is exported, public on a class, or imported by name elsewhere. Skip when: the symbol is internal (not exported) and its name + types fully describe it, or the signature is trivially self-evident (isEmpty(x): boolean). Never skip a class even when its name is descriptive. The class name says what kind of thing; the docblock says what it's for and how it's used — a 1–2 sentence purpose statement saves callers from reading methods to understand intent.

For functions, include in priority order

  1. Purpose. One sentence on what it is for, not what it mechanically does. "Resolves the effective billing tier from subscription, overrides, and feature flags" beats "Returns the billing tier."
  2. Invariants / preconditions. What the caller must guarantee. "Assumes userId has been validated against the session."
  3. Domain semantics types can't capture. Units, ranges, nullability rules. "amount is in minor units (cents)."
  4. Non-obvious side effects or failure modes. "Logs to Sentry on retry exhaustion; does not throw."
  5. Cross-cutting constraints. Latency budgets, ordering guarantees, callers that matter.

For classes, include in priority order

  1. Purpose. What this class represents or coordinates. "Caches resolved feature-flag values for the lifetime of a single HTTP request."
  2. Invariants the instance maintains. What is always true once the instance exists. "Once start() is called, the connection is reused until close() — never reconnect manually."
  3. Lifecycle and ownership. Who creates instances, who owns them, when they're disposed. "Constructed by the DI container at request scope; do not instantiate manually."
  4. Threading / concurrency. "Not thread-safe; use one instance per worker."
  5. Extension points. If designed to be subclassed or extended, name how. Skip when the class is final/sealed.

Methods on an exported class: document public methods whose contract isn't already covered by the class doc. RequestFlagCache.resolve(key) doesn't need a docblock if the class doc already explains caching semantics; document it when the method has invariants or failure modes the class doc doesn't capture.

Never: redundantly document types the signature already shows. @param {string} userId - The user ID is pure noise.


2. Module / file-level header

Add when:

  • The file is a non-obvious architectural boundary (e.g. transport ↔ domain seam).
  • It encodes a contract that lives nowhere else (event shapes, protocol assumptions).
  • Its purpose isn't obvious from the filename alone.

Skip on: utility leaves whose name tells the story, test files, generated code.

Keep to a short paragraph covering:

  • What this module is (one sentence).
  • Where it sits — what depends on it, what it depends on — only if non-obvious.
  • Any file-wide invariants. "All exports are pure; no I/O."

3. Inline comments

Add only when one of these holds:

  • The code does something that would surprise a careful reader, and the surprise has a reason. // Re-sort here because RabbitMQ doesn't guarantee order on requeue
  • The shape of the code is load-bearing in a way someone might "simplify" away. // Do not collapse into Promise.all — the rate limiter needs serial execution
  • A magic literal carries domain meaning. // 86400 = one day in seconds
  • A workaround exists for an external bug or vendor limit; link the issue when possible. // Workaround for nodejs/node#1234 — drop on Node 22+
  • The block maps to a named domain rule. // VAT exemption applies only to B2B intra-EU; see invoice policy §3.2

Never add inline comments to:

  • Restate the line below.
  • Justify a variable name — fix the name instead.
  • Explain standard language features.
  • Leave TODOs without an owner and a date.

4. Style

  • Present tense, declarative. "Computes the rebate," not "Will compute the rebate."
  • Name the constraint, not the feeling. "Avoids a 30s timeout in the upstream gateway" beats "for performance reasons."
  • Reference external issues/RFCs by stable identifier when the comment depends on them.
  • A good docblock lets a caller skip reading the body. Aim for that.

5. Anti-patterns — never produce

  • Commented-out code "for later."
  • Box/banner ASCII decoration.
  • "Updated by X on Y" headers — version control already knows.
  • Apologetic comments (// This is ugly but…) — either fix the code, or name the constraint that forces the shape.
  • Redundant type echoes in JSDoc/docstrings (@param {string} userId - The user ID).
  • TODOs without an owner and a date.

6. Opportunistic cleanup of existing comments

When editing a function, also fix obviously bad comments that fall inside the change radius — same function, or the block of lines you're already touching. Leave the rest of the file alone unless the user asked for a sweep.

Clean up when nearby:

  • Redundant restatements (// increment counter above counter++)
  • Commented-out code with no TODO/FIXME rationale
  • TODOs without an owner or date
  • Header comments contradicted by the new behavior (a JSDoc claiming the function returns null after you changed it to throw)

Do not clean up:

  • Comments outside the function/block you're editing
  • Comments in unrelated files in the same diff
  • Comments you don't understand — flag in the review/PR description instead of deleting

This mirrors the Boy Scout Rule from design-rubric §3 — clean what you're already in, never expand the diff to chase comment debt.


7. Language syntax

The principles above are language-agnostic. The syntax differs.

TypeScript / JavaScript — JSDoc

Function:

/**
 * Resolves the effective billing tier from subscription, overrides, and feature flags.
 *
 * Assumes `userId` has been validated against the session.
 * Logs to Sentry on retry exhaustion; does not throw.
 *
 * @returns Tier identifier; `null` only when the user is mid-migration.
 */
export function resolveBillingTier(userId: UserId): Tier | null { ... }

Class:

/**
 * Caches resolved feature-flag values for the lifetime of a single HTTP request.
 *
 * Once `resolve()` returns a value for a key, the same value is returned for that
 * key for the rest of the request — flag flips mid-request are not observed.
 * Not safe to share across requests.
 *
 * Constructed by the DI container at request scope; do not instantiate manually.
 */
export class RequestFlagCache { ... }
  • In TypeScript, skip @param/@returns types — the signature carries them. Use @param/@returns prose only when adding semantics the type can't.
  • In plain JS, type tags (@param {string}) are useful documentation; keep the prose anyway.
  • Place JSDoc directly above the symbol, no blank line between.

Python — docstrings

Function:

def resolve_billing_tier(user_id: UserId) -> Tier | None:
    """Resolve the effective billing tier from subscription, overrides, and feature flags.

    Assumes ``user_id`` has been validated against the session.
    Logs to Sentry on retry exhaustion; does not raise.

    Returns:
        Tier identifier, or None only when the user is mid-migration.
    """

Class:

class RequestFlagCache:
    """Cache resolved feature-flag values for the lifetime of one HTTP request.

    Once :meth:`resolve` returns a value for a key, the same value is returned
    for that key for the rest of the request — flag flips mid-request are not
    observed. Not safe to share across requests.

    Constructed by the DI container at request scope; do not instantiate
    manually.
    """
  • Pick one style per project (Google, NumPy, or reST) and stay consistent.
  • Don't list Args: if every entry would just echo the type and name. Include only the params that need semantics.
  • A module docstring at the top of the file (before any imports) replaces the file-header comment.
  • Class docstring sits directly under the class line, indented. __init__ rarely needs its own docstring — the class docstring covers construction semantics.

Go — godoc

Function:

// ResolveBillingTier returns the effective billing tier from subscription,
// overrides, and feature flags.
//
// It assumes userID has been validated against the session, logs to Sentry on
// retry exhaustion, and does not return an error in that case.
//
// The returned tier is empty only when the user is mid-migration.
func ResolveBillingTier(userID UserID) Tier { ... }

Struct (Go's class-equivalent):

// RequestFlagCache caches resolved feature-flag values for the lifetime of
// a single HTTP request.
//
// Once Resolve returns a value for a key, the same value is returned for
// that key for the rest of the request — flag flips mid-request are not
// observed. RequestFlagCache is not safe for concurrent use by multiple
// goroutines outside the request that owns it.
type RequestFlagCache struct { ... }
  • Sentence starts with the symbol name — godoc convention applies to functions, structs, interfaces, types, and consts.
  • Package-level doc: a // Package foo … comment on the file containing package foo (or a dedicated doc.go).
  • No @-tag styles — Go has no JSDoc/docstring section convention.

Other languages

Apply the same priorities (Purpose → Invariants → Semantics → Side effects → Constraints) using the language's idiomatic doc form: Rust /// and //!, Java/C# Javadoc and XML doc, Ruby YARD, Swift markup. Skip type echoes when the signature carries the type.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.