# Code Comment

> MANDATORY for every task that creates, modifies, refactors, or outputs code in any language (C++, C#, Java, Python, JS/TS, HLSL/GLSL, shell, build scripts) — load BEFORE writing code, even when the user never mentions comments; documentation-grade comments are part of the code deliverable itself. Also load on any mention of comments, 注释, docstrings, API docs, file headers, or comment review/improvement.

- Skill: `minghou-lei/code-comment` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add minghou-lei/code-comment`
- Raw SKILL.md: https://api.skillmd.com/api/skills/minghou-lei/code-comment/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: Minghou-Lei (https://skillmd.com/u/minghou-lei)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/minghou-lei/code-comment

---


# Code Comment — Documentation-Grade Commenting Contract

## §0 · Mandate

- This skill governs EVERY task that creates or modifies code, in any language,
  whether or not the user mentioned comments. The comment coverage in §2 is part
  of the deliverable itself — same rank as the code compiling. It is never an
  "unrequested rider", never optional polish, never skipped to keep a diff small.
- A code change is NOT done until the §2 coverage floor is met for everything touched.
- These rules steer the agent only. Never copy agent / task / workflow / review
  language into code, comments, patches, or any generated artifact.

## §1 · Philosophy

- Comments are written for a maintainer reading this code cold, months later,
  without this conversation, without the diff, without the task context.
- **Burden of proof is reversed:** every new or modified function gets a comment
  by default. Silence is the exception that must be justified, and only the §2
  exempt list qualifies.
- **When in doubt, go up:** unsure between Tier A and Tier S → write Tier S.
  Unsure whether a body paragraph needs a comment → write it. A slightly
  redundant comment is acceptable; a missing one is a defect.
- **Detailed ≠ noisy.** Every comment must carry real information along at least
  one of these dimensions: intent/motivation, input constraints (unit, range,
  null/empty semantics, normalization), output semantics (sentinels, ownership),
  side effects, thread model, lifetime, call timing/order, performance traits,
  algorithm provenance, empirical-value rationale, known limits, paired APIs.
  A comment that merely restates the name is the floor — acceptable only for
  genuinely trivial code where nothing more exists to say.

## §2 · Coverage floor (hard requirements)

| Target | Requirement |
|---|---|
| New file | File header: responsibility, explicit non-responsibility/boundary, layer, threading/lifetime/encoding constraints |
| New or modified class / struct / interface / enum | Class-level doc: role, collaborators, lifecycle, thread model |
| Every new or modified function / method — **including private, static, file-local helpers** | At least Tier A (one line); Tier S whenever any §3 trigger fires |
| Public API / cross-module / cross-language entry | Tier S always, full usage contract |
| New member variables, constants, magic numbers, enum values | Meaning + unit + range + provenance |
| Function body | Layer-1 paragraph narration (≥ 2 logical steps) + Layer-2 line anchor at every §4-taxonomy hit |
| Lambda / callback crossing module, thread, or async boundaries | One line: responsibility + constraint |

Exempt from the floor (silence allowed):
- machine-generated regions and files (`DO NOT EDIT`, `Generated by`, bindings, protobuf output);
- a one-line lambda passed inline whose meaning is obvious at the call site;
- pure pass-through overrides MAY use a single line stating "纯转发，无额外行为" —
  that line itself is useful (tells the maintainer not to look further).

Modified counts in full: any function whose body you edit — even one line —
becomes "modified" and falls under the floor, including upgrading its existing
comments per §5.

### Scope & protected code

- Default scope: code you create or modify in this task, plus anything the user
  explicitly names. Do not sweep untouched files for comment work unless asked.
- Never comment-edit without the user naming the file and confirming intent:
  third-party / vendored / submodule code; generated output; external SDK or
  engine source; package caches and toolchains; lockfiles; minified bundles;
  copied external examples and test fixtures. If a request includes protected
  code, handle only project-owned code and name the untouched remainder in the
  final summary.

## §3 · Tier system

### Tier S — full structured doc comment

Trigger — any one of:
- a parameter whose unit / range / null / ownership semantics are not fully
  self-evident from name + type;
- a return value with sentinel / error / empty semantics;
- branches or loops carrying business or algorithmic logic;
- side effects: I/O, network, global/static state, GPU submit, cache
  invalidation, allocation handed to the caller;
- threading, re-entrancy, call-order, or lifetime constraints;
- an algorithm, math, coordinate/color-space transform, encoding, or parsing;
- fallback, compatibility, platform, or driver-specific paths;
- public API, cross-module, cross-language, asset-pipeline, shader/RHI, or
  external-tool contract.

In practice: everything except trivial getters / setters / one-line forwarders /
literal predicates is Tier S.

Content requirements (format per the language reference, §7):
- one-sentence responsibility (`@brief` / summary line);
- a 1–4 sentence body: why it exists, the approach chosen, design rationale
  when non-obvious;
- **every** parameter: meaning + unit + valid range + null/empty/zero semantics
  where applicable;
- return: meaning + sentinel values + ownership;
- error behavior: exceptions / error codes / silent fallback;
- `@note` / `<remarks>`: thread model, lifetime, performance characteristics,
  required call order;
- `@warning` when misuse has real consequences; `@see` for paired / inverse
  functions.
- Include a tag only when it says something true and useful — but actively look
  for material along every dimension above before declaring it empty. "I didn't
  think about threading" is not the same as "no threading constraint exists".

### Tier A — one-line responsibility comment

For trivial functions only (simple getter/setter, one-line forwarder, literal
predicate, mechanical path join).
- Whenever any context beyond the name exists — value provenance, empty/null
  meaning, unit, stability guarantees, valid call window — it MUST be in the line.
- If genuinely nothing exists beyond the name, a plain responsibility line is
  still required. In this contract, coverage outranks sparseness.

## §4 · Function-body comments — two layers

Body comments operate on two distinct layers. Both are mandatory; one never
substitutes for the other.

### Layer 1 — paragraph narration (the flow)

- A body with ≥ 2 logical steps is divided into logical paragraphs, each opened
  by a comment stating **what this step does, and why when the why is not
  obvious**. Reading only the paragraph comments must reveal the function's full
  flow, like section headings of an article.
- Short linear bodies (< ~8 lines, single step) need no paragraph comments —
  the function-level comment covers them.
- Paragraph comments narrate the **step**, never the values inside it. What a
  literal means and where it came from belongs to Layer 2, on its own line — do
  not fold value facts into the paragraph header.

### Layer 2 — line anchors (the points)

Reader calibration — **the review-pause rule**: the reader is a competent
maintainer who did not write this code, six months later. Any line that would
make that reader pause, mentally simulate execution, reach for a calculator, or
open a doc before feeling safe — gets a comment at that line. Your own
familiarity with the line is not evidence; you just wrote it.

Trigger taxonomy — scan for these token categories; **every hit needs a line
anchor** unless it is a trivial idiom (0/1 loop init, index 0, obvious
increment) or an already-commented named constant:
- numeric literals: empirical thresholds, magic numbers, sentinels, scale
  factors, epsilons;
- bit operations, masks, shifts, flag packing/unpacking;
- compound boolean conditions (≥ 2 clauses): the domain meaning of the whole predicate;
- early exits (return / continue / break / goto): why bail at exactly this point;
- casts with precision, signedness, or truncation implications;
- index/boundary arithmetic: the off-by-one reasoning behind `n-1`, `+1`,
  floor/ceil choices, `±0.5` rounding;
- unit / coordinate-space / color-space conversions, at the conversion line;
- concurrency primitives: lock scope, memory order, atomic choice;
- regex patterns, format strings, protocol/struct offsets;
- calls with side effects or order constraints ("must run before/after X because …");
- performance tricks (rsqrt, branchless forms, SIMD-friendly shapes): the
  trade-off and its evidence;
- intentionally empty branches and swallowed errors: why ignoring is correct;
- platform/driver workarounds: trigger condition, affected versions, removal
  condition — HACK / WORKAROUND / FIXME format per the language reference;
- fallback chains: the order tried and why that order.

Content formula for a value anchor: **meaning** (what the value represents in
domain terms — always) + **provenance** (spec, paper, ticket, profiling,
评审定值 — whenever known) + **change impact** (what breaks when it changes —
whenever dangerous). Provenance not derivable from code or evidence: write the
meaning and mark honestly ("经验值，出处未追溯") — never invent a source (§8).

Placement: explanation fits in one short clause → trailing comment on the same
line (the natural home of value anchors); longer, or covering a multi-line
construct → own line immediately above. No mandated column alignment.

Magic-number decision tree:
- value used ≥ 2 times, bound by a cross-file contract (C++/shader sync,
  serialized format), or meant as a tunable knob → extract a named constant
  with a full comment at the definition; use sites then need no anchor (a short
  pointer at most);
- single local use → annotate in place, trailing.

The noise line: a trailing comment restating syntax (`i++; // 递增 i`) is
forbidden; a trailing comment carrying value semantics, provenance, or change
impact is **required**. The difference is information gain, not position.

### Canonical example — the daily anchor (C++ shown; same shape in every language)

```cpp
// ❌ 裸函数：本契约下不存在的交付物
int32 GetActiveLOD() const;
float ComputeLodBias(float Distance);

// ✅ 档位 A：平凡函数也必须有一行，且字面职责之上能补的上下文必须补
/** 当前激活的 LOD 层级，范围 [0, MaxLOD]；Initialize() 前恒为 0 */
int32 GetActiveLOD() const;

// ✅ 判定树的命名常量分支：可调参数在定义处完整注释，使用处不再重复
/** 近景保护带半径（米）：此距离内植被永不降级；放宽前先在低端机复测帧耗 */
static constexpr float NearProtectRange = 30.0f;

// ✅ 档位 S（触发：算法 + 经验阈值）+ §4 双层函数体注释
/**
 * @brief  根据观察距离计算植被批次的 LOD 偏移，驱动渐进降级
 *
 * 采用平方反比衰减而非线性衰减：远景植被密度对视觉的影响是非线性的，
 * 平方曲线允许 50m 外多降一档（实测帧耗 -0.8ms，性能报告 #233）。
 *
 * @param  Distance  相机到批次包围盒中心的距离，单位米，必须 >= 0
 * @return LOD 偏移，范围 [0.0, 4.0]；0 表示最高精度，越大越粗糙
 * @note   纯函数，无副作用，任意线程可调
 * @see    ApplyLodBias() —— 消费本值并写入渲染状态的配套函数
 */
float ComputeLodBias(float Distance)
{
    // 近景保护带：玩家脚边的植被不参与降级，避免视野中心突变
    if (Distance < NearProtectRange)
    {
        return 0.0f;  // 0 = 最高精度档，调用方据此跳过偏移应用
    }

    // 平方反比映射：远景密度感知是非线性的，平方曲线允许远处比线性多降一档
    const float Normalized = FMath::Square(Distance / 120.0f);  // 120m = 密度感知饱和点（美术评审定值）
    return FMath::Clamp(Normalized * 4.0f, 0.0f, 4.0f);  // 上限 4.0 = LOD 档数，与 FoliageLODConfig 层数严格对应
}
```

Why this example passes §10: the paragraph comments alone narrate the flow
(Layer 1); every value is explained on the exact line where it appears
(Layer 2) — 30m documented once at its named constant, 120m and the 4.0 cap
anchored in place as single-use values; provenance is real or absent, never
invented.

## §5 · Existing comments: upgrade, don't delete

Within scope (§2), for every comment adjacent to code you touch:
- Outdated, or contradicts actual behavior → **fix it; treat as bug-severity.**
- Vacuous, name-translation, or copy-paste template comment → **rewrite in place**
  into an informative comment at the proper tier. Do not delete-only.
- Deleting a comment is allowed ONLY when the code it described is itself deleted.
- Good existing comments: extend, don't duplicate. Behavior changed → comment
  updated in the same edit, never left for later.
- Visibly wrong comments on code outside scope: do not edit; report the location
  in the final summary.

## §6 · Placement

- Function-level comments sit immediately above the declaration/definition —
  never as the first statement inside the body.
- Declaration/definition split (C/C++ headers etc.): caller-facing contract at
  the declaration; implementation details, fallback order, and local constraints
  at the definition. Never duplicate the same text in both.
- Group comments state their range explicitly ("以下 4 个 helper 共享…"); they
  must not read as belonging only to the next function. A shared boundary is
  stated once, at the most-misuse-prone location (file header, group comment, or
  public entry) — then per-function comments stay function-specific.
- One placement style per file; match the surrounding project style.

## §7 · Language, style, and encoding

- Comments in **Simplified Chinese by default**. English only when: contributing
  to an open-source repo, project rules demand it, or the file already has a
  consistent English comment style.
- Match the project's existing marker conventions (`/** */` vs `///`, docstring
  style). When the project has none, use the language reference defaults.
- Before writing Tier S comments in a language, read its reference once per session:
  - C / C++ → `references/cpp-doxygen.md`
  - C# → `references/csharp-xmldoc.md`
  - Java → `references/java-javadoc.md`
  - JavaScript / TypeScript → `references/js-jsdoc.md`
  - Python → `references/python-google.md`
  - HLSL / GLSL / USF → `references/shader-comment.md`
- Reference missing → follow project style and language norms; never claim to
  have read a missing file.
- Writing Chinese comments into non-UTF-8 files (GBK/CP936, UTF-8-BOM trees):
  the per-file encoding round-trip gate applies in full — verify encoding, BOM,
  and EOL survive the edit.

## §8 · Truthfulness limits

- Never fabricate: performance numbers, platform/driver behavior, protocol
  semantics, threshold provenance, external-tool contracts. State only what
  code, tests, project docs, or conversation evidence supports.
- A dimension matters but evidence is missing → write the verifiable part; mark
  genuinely uncertain claims as assumptions or omit that dimension. Ask the user
  one minimal question only when the missing fact would make comments wrong or
  misleading.
- A comment must never paper over a bad name, bad abstraction, or wrong
  behavior: fix the code when safe and in scope; otherwise write the truthful
  comment AND report the issue in the final summary.

## §9 · Artifact cleanliness

- Zero agent / AI / task / phase / plan / review / workflow traces in any code,
  comment, header, or artifact. No "本次修改…", "根据需求…", "Phase 2 拆分…",
  process notes, or rejected alternatives. Comments describe the code as it is,
  timelessly.
- File headers describe long-term responsibility and boundaries — never the task
  or conversation that created the file.
- `@author` / `@date` / hand-maintained version fields appear only when the
  project style explicitly requires them: VCS already owns authorship and
  history, and these fields rot silently. (`@since` on public APIs is the
  exception — it records the version an API became available, which callers
  genuinely need.)
- Review tasks: report comment-coverage gaps as findings; do not edit files
  unless asked. Explanation/comparison tasks: answer normally; any embedded code
  artifact still follows this contract.

## §10 · Final verification — count, don't vibe

Before reporting done:
1. **List every function/method created or modified. Count them. Count their
   comments at the correct tier. The numbers must match.**
2. Every Tier S comment covers params (unit/range/null), return (sentinels),
   errors, side effects, and threading/lifetime where applicable?
3. Every body with ≥ 2 logical steps has paragraph narration (§4 Layer 1)?
4. **Line-anchor scan (§4 Layer 2): re-scan your final diff for the trigger
   taxonomy — numeric literals, bit ops, compound booleans, early exits, casts,
   index/boundary arithmetic, unit/space conversions, concurrency primitives,
   regex/format strings/offsets, side-effect calls, empty branches. Every hit
   is (a) anchored at its line, (b) a named constant with a commented
   definition, or (c) a trivial idiom. Count hits and coverage.**
5. New files have headers; new classes, members, constants, enum values are documented?
6. All touched comments are accurate against the **final** code, not an earlier
   draft of the change?
7. Zero workflow traces; zero vacuous lines left un-upgraded (§5)?
8. Comment language and marker style consistent with file and project? Encoding
   round-trip verified for non-UTF-8 files?

Any check fails → fix before reporting. The final summary's 验证 line names the
comment coverage explicitly (files touched, functions commented N/N, line
anchors N/N).

