跳转至

prompt.md — Doxygen comment generation specification (English)

Purpose: a strict, machine-readable yet human-friendly prompt that instructs an AI to generate idiomatic, high-quality Doxygen comments for modern C++ code (C, C++20/23, templates, concepts, macros, embedded/OS code). Use this file as the contract that the generator must follow. Tone: concise technical (LLVM/Qt-like), third-person present tense, with small tasteful flourishes allowed to avoid robotic dryness — but never introduce ambiguity or invent behavior.


1 — Scope & high-level rules (MUST / MUST NOT)

  • MUST produce Doxygen comments in English.
  • MUST use third-person present tense (e.g., “Initializes the cache.”).
  • MUST NOT use first-person (“we”, “I”, “our”) except within @note when explicitly allowed for brief clarifications.
  • MUST support both block style (/** ... */) and line style (/// ...) comments.

  • MUST be consistent per file: choose either block or line style within that file and use it for all declarations in that file.

  • MUST include a file-level Doxygen header at the top of every source and header file.
  • MUST document public and protected APIs. Private functions may be documented but are optional.
  • MUST document every enum, struct, class, union, typedef, and non-static data member.
  • MUST document every public and protected function; constructors, destructors, and operators included.
  • MUST include the following tags for every function (if not applicable, write @return None or @throws None as described below): @brief, @param, @return, @note, @warning, @throws, @since, @ingroup.
  • MUST include parameter direction for every @param: @param[in], @param[out], or @param[in,out].
  • MUST list @param entries in the same order as the function signature.
  • MUST explain units and ranges for numeric parameters where applicable (e.g., “milliseconds”, “bytes”, “MHz”).
  • MUST document default values for parameters when the code provides defaults.
  • MUST include @return for non-void functions. MUST NOT include @return for void functions (explicitly forbidden).
  • MUST include @since (use provided release/version or since: N/A if unknown).
  • MUST include @ingroup when the symbol belongs to a module or logical group; otherwise set @ingroup none.
  • MUST document template parameters (@tparam) and concept constraints when generating comments for templates.
  • MUST include thread-safety statements only if present in the code or explicitly stated in repo metadata. Do not assume thread safety.
  • MUST be conservative with @throws — only list exceptions observable in the function body or documented upstream; if none, write @throws None.
  • MUST avoid inventing behavioral guarantees not reflected by the code. If uncertain, add a FIXME note (see Error Handling section).
  • MUST follow the style/length/formatting rules in Section 4.

2 — File-level header (required)

Every file must start with a file-level block like:

/**
 * @file    relative/path/to/file.h
 * @brief   One-sentence summary of the file's responsibility.
 *
 * Longer one-paragraph description (optional, max 2–3 short sentences).
 *
 * @author  <git:author-name or "N/A">
 * @date    <git:last-commit-date or "N/A">
 * @version <git:last-tag-or-commit or "N/A">
 * @since   <project version or "N/A">
 * @ingroup <module or "none">
 */
  • Fill @author, @date, @version from git metadata if available; otherwise set to "N/A".
  • Keep the file-level description concise (≤ 2–3 short sentences).

3 — Function & method comment template (MUST follow)

  • Use this canonical template. If a tag is not applicable, include it with None as the value (so the presence of the tag is guaranteed and the output is machine-validateable).

Block style example:

/**
 * @brief  Short description in third-person present tense.
 *
 * Detailed description (optional). If present, keep to a few short sentences.
 *
 * @param[in]   name    Description. Specify units and valid range when applicable.
 * @param[out]  out     Description. If pointer, explain ownership semantics.
 * @param[in,out] buf   Description. Mention buffer length and units if relevant.
 * @tparam T            Description of template parameter T (if applicable).
 * @return             Describe return value. If not applicable (void), omit @return.
 * @throws             List exceptions thrown, or `None`.
 * @note               Short clarifications, constraints, or references.
 * @warning            Short warnings (e.g., reentrancy, performance).
 * @since              Version or "N/A".
 * @ingroup            Module name or "none".
 */

Line-style equivalent:

/// @brief Short description.
/// @details Optional extended description in third-person present tense.
/// @param[in] name Description...
/// @return Description...
  • MUST include @tparam for templates.
  • MUST include @throws (or @throws None).
  • MUST include @note (or @note None) and @warning (or @warning None).
  • MUST not use @return for void functions.

4 — Formatting constraints (MUST)

  • Line width: every line inside the comment must be ≤ 100 characters.
  • Whitespace & alignment:

  • If using block style (/** ... */) the leading * must be vertically aligned (common column) for the entire block.

  • If using line style (///) each /// must start at the same column for that file.
  • Padding & blank lines:

  • Single blank line allowed between @brief paragraph and the tag block.

  • No more than one consecutive blank line inside a comment block.
  • Sentence style: start with a capital letter; end with a period.
  • Examples: Use @code / @endcode for short usage examples (max 6 lines).
  • Language mechanics: use simple present tense verbs (e.g., “Returns”, “Initializes”, “Parses”).
  • Maximum tag line length: the text following a tag should be wrapped so that the whole line remains ≤100 chars.
  • Consistency: within a file, keep tag ordering stable: @brief → extended desc (optional) → @param / @tparam (in signature order) → @return@throws@note@warning@since@ingroup.

5 — Special cases & advanced language features

Templates / Concepts

  • MUST annotate template parameters with @tparam and describe constraints.
  • For constrained templates, explicitly state concept requirements in @tparam (e.g., @tparam T Must satisfy std::integral).

Constexpr / inline / noexcept

  • Document behavior and compile-time guarantees. E.g., @note This function is constexpr and may be evaluated at compile time.

Operators / Conversions

  • Use @brief to state semantic meaning; include @note for subtlety (e.g., cost, aliasing).

Macros

  • Document the macro’s purpose, expected arguments, side effects, and recommended alternatives (if any).

Exceptions

  • Only document exceptions that can be thrown directly or via called functions that are not noexcept. If none, @throws None.

6 — Class & struct documentation (MUST)

Each class/struct must have:

  • @brief one-line design purpose.
  • @details short paragraph for lifetime, ownership, and common usage.
  • @note thread-safety note (only if known).
  • @code example that demonstrates typical usage (required, max 6 lines).
  • Document public/protected member functions and all non-static data members (brief for members, fuller for functions).

Class example:

/**
 * @brief  Lightweight ring buffer for bytes.
 *
 * Provides single-producer single-consumer semantics. Does not allocate after
 * construction.
 *
 * @note   Not thread-safe unless externally synchronized.
 *
 * @ingroup utils
 *
 * @code
 * RingBuffer rb(1024);
 * rb.push(...);
 * @endcode
 */
class RingBuffer { ... };

7 — Enums & constants (MUST)

  • Every enum and enum class must have:

  • @brief describing the enum's role.

  • Each enumerator must have a one-line trailing comment or an @enum block listing names and meanings.
  • Constants (constexpr, const) must have a @brief and unit (if numeric).

Example enumerator:

/**
 * @brief  Device power states.
 * @ingroup driver
 */
enum class PowerState {
    Off,    ///< Power is off.
    Sleep,  ///< Low-power sleep mode.
    On      ///< Fully powered.
};

8 — Member variable documentation (MUST)

  • MUST document every non-static data member.
  • Specify ownership (owner, observer, borrowed), lifetime, and whether it may be nullptr.
  • Keep member comments short (one sentence).

Example:

/// @brief Pointer to underlying device context. Ownership: observer; may be nullptr.
DeviceContext* ctx_;

9 — Tags that must always appear and how to handle “not applicable”

Because the downstream tooling expects a predictable set of tags, always include the following for functions and classes:

  • @brief (never None)
  • @param (for each parameter; if none, omit the block)
  • @return (for non-void); do not add for void
  • @throws — use @throws None if none.
  • @note — use @note None if none.
  • @warning — use @warning None if none.
  • @sinceN/A if unknown.
  • @ingroupnone if not part of a group.

10 — Error handling & ambiguous code (MUST)

If the generator cannot determine meaning from code:

  • Prefer conservative language (e.g., “May return -1 on error.” → only if code shows that).
  • Add a FIXME line in the @note with a short reason why the annotation is uncertain and what is needed (e.g., “FIXME: ownership unclear — confirm by inspecting caller or README”).
  • Do not invent behavior (e.g., do not claim that a function throws std::runtime_error unless visible).
  • If the code uses custom error codes rather than exceptions, document the error-code set and mapping where visible; otherwise @throws None and @note FIXME: error-code mapping unclear.

11 — Allowable creative flourishes

  • Short, tasteful explanatory text in @note is allowed to reduce dryness, but must be factual and concise.
  • No rhetorical or marketing language. Keep it professional.
  • Examples and short code snippets are encouraged for classes and public APIs.

12 — Validation rules (automatic checks — MUST run after generation)

The generator must pass the following checks. If any check fails, the generator must rewrite the comment until all pass.

  1. File header present: regex (?s)/\*\*.*@file\s+.+\*/ at file start.
  2. Per-file style consistency: all comment blocks use /** or all ///.
  3. Required tags presence: each function/class comment contains @brief and @since and @ingroup.
  4. Parameter order & presence: number and names of @param entries match function signature in order.

  5. Validate with a parser or a conservative regex-based check.

  6. @param directions present: every @param has [in], [out], or [in,out].
  7. Void functions must NOT contain @return: fail if @return appears in void function.
  8. Line length: no line inside comment > 100 chars.
  9. Star / prefix alignment: for block style, each interior line must start with * (space-star-space) after the opening /**.
  10. Enumerations & members documented: every enum/struct/non-static member must have an adjacent doc comment.
  11. Template params annotated: presence of @tparam for templates.
  12. @throws presence: must exist (with None if not applicable).
  13. No first-person: fail if comment contains \b(we|our|I|my)\b outside quoted text.
  14. Third-person present tense: spot-check verbs like “initializes”, “returns”, “parses”; if glaringly different (e.g., “will initialize”), flag and rewrite.
  15. FIXME handling: if FIXME is present, ensure it's in @note and explains the ambiguity.

Provide exact failure messages for each check so the generator can iterate.


13 — Good / Bad examples

Good (function)

/**
 * @brief  Parses a little-endian unsigned integer from `buf`.
 *
 * Parses exactly `len` bytes and returns the resulting value. If `len` is 0,
 * behavior is undefined.
 *
 * @param[in] buf   Pointer to input bytes. Must be non-null.
 * @param[in] len   Number of bytes to parse. Unit: bytes. Valid range: 1..8.
 * @return          Parsed 64-bit unsigned integer.
 * @throws          None
 * @note            This function does not perform bounds checking on the
 *                  caller-provided buffer.
 * @warning         Behavior is undefined for len==0.
 * @since           1.2.0
 * @ingroup         util
 */
uint64_t parse_le_uint(const uint8_t* buf, size_t len);

Bad (function)

/** Parses bytes into a number. This function will parse and return value. */
uint64_t parse_le_uint(const uint8_t* buf, size_t len);
  • Issues: first-person / future tense; no tags; no units; no param directions; too short; possibly misleading.

14 — Implementation notes for the generator (instructions for the AI implementing this prompt)

  • Parse the source file to extract declarations and signatures before generating comments. Prefer an AST when available; if not, use robust regexes with conservative fallbacks.
  • For each symbol:

  • Generate tags following the canonical ordering (Section 4).

  • Fill @throws, @note, @warning with None if inapplicable.
  • For templates, include @tparam and describe constraints.
  • For each parameter, inspect type to infer direction:

    • pointer to non-const ⇒ likely @param[out] or @param[in,out] depending on name and usage (if unknown, prefer in,out and add a FIXME).
    • const pointer/reference ⇒ @param[in].
    • return by non-const reference ⇒ usually @param[out] for the parameter and @return for function when appropriate — be conservative, and add FIXME if ambiguous.
    • Ownership language: if variable name contains owner/owns/unique_ptr/std::unique_ptr, document as owner. If raw pointer and no visible ownership, document as observer.
    • Thread-safety: include explicit statement only when code or repo docs indicate it. Otherwise include @note Not thread-safe unless externally synchronized. where appropriate.
    • When inferring error codes or exceptional behavior, prefer not to claim exceptions. If the code returns sentinel values (e.g., -1), document the sentinel only if visible in the implementation or header comment.
    • Do not consult external knowledge to invent behavior. Use only repository artifacts and inline code context.

15 — Git metadata & author fields

  • If the agent has access to git via an external tool, populate:

  • @author ← git --format="%an"

  • @date ← date of last commit touching the file (ISO 8601)
  • @version ← last tag or short commit hash
  • If no git info available, set fields to "N/A".

16 — Output quality & rewrite policy (strictness)

  • This prompt is strong-constraint: any deviation from mandatory checks must trigger an automatic rewrite.
  • The generator should attempt up to 3 automatic refinement passes per file to satisfy the validation rules before returning results to the user.
  • If, after 3 passes, the code still fails validation due to ambiguous code, include FIXME notes and a short summary explaining what could not be determined and why.

17 — Example workflow for the AI consumer (summary)

  1. Parse file → collect symbols and signatures.
  2. Generate file-level header.
  3. For each symbol generate comment block per the templates.
  4. Run validation checks (Section 12).
  5. If checks fail, rewrite (up to 3 passes). If still failing, add FIXME and explanation.
  6. Return the modified file with comments inserted, and a short machine-readable report of checks (JSON recommended).

Return an object with fields:

{
  "file": "path/to/file.h",
  "generated_comments": N,
  "errors": [
    {"symbol": "foo()", "check": "line_length", "message": "line > 100 chars"}
  ],
  "fixme_count": M
}

19 — Quick checklist for reviewers (human)

  • Is @brief clear and in present tense?
  • Do @param entries match signature order and include direction?
  • Is @return present only for non-void functions?
  • Are units / ranges specified where applicable?
  • Are enums, structs, and members documented?
  • Are lines ≤ 100 chars and stars aligned?
  • Are any FIXME notes present? If so, are they justified?