---
name: "code_documentation"
description: "Write code documentation developers actually read: pick the right doc type (docstring, comment, ADR, README), document WHY over WHAT, and lead with working examples. Triggers when writing or reviewing docstrings, inline comments, READMEs, ADRs, or API docs for a codebase."
---

# Code Documentation

## Purpose

Code tells a reader what the software does right now. Documentation tells them
why it does it that way, how to use it, and which decisions shaped it. This
skill turns an agent that "adds comments" into one that writes docs a developer
will open, trust, and keep.

## Workflow

### 1. Pick the right doc type before writing anything

Choosing wrong is the most common docs failure. Use scope and question:

- **Inline comment** — scope: a line or block. Answers: why is this line
  non-obvious? (a weird workaround, a magic constant, a constraint that is not
  in the code). If the code says WHAT clearly, do not comment the WHAT.
- **Docstring** — scope: a function, class, or module. Answers: what does it
  do, how do I call it, what does it return, what can go wrong.
- **README** — scope: the project. Answers: what is this, how do I install
  and run it in the first five minutes, what do I do when it breaks.
- **ADR (Architecture Decision Record)** — scope: one significant decision.
  Answers: which option we chose, which we rejected and why, what downside we
  knowingly accepted.

Rule of thumb: stable, broad-impact knowledge (API contracts, architecture)
goes in versioned docs next to the code. Code-coupled details (side effects,
hacks) stay in comments. One ADR covers one decision, never a bundle.

### 2. Examples over prose, and the examples must run

Developers skim prose and read examples. Every docstring on a public function,
every README usage section, every API reference gets a runnable example.

- Use realistic data, never foo/bar/baz.
- Keep the example minimal but complete: copy, paste, run.
- Verify the example actually executes. A broken example destroys trust in the
  whole document faster than missing docs ever would.

Python docstring example (Google style, doctest-ready):

```python
def retry(fetch, max_attempts=3, delay=0.5):
    """Call `fetch` until it succeeds, with delays between attempts.

    Args:
        fetch: Zero-argument callable that performs the request.
        max_attempts: How many total tries before giving up.
        delay: Seconds to wait between attempts.

    Returns:
        Whatever `fetch` returns on success.

    Raises:
        The last exception from `fetch` if every attempt fails.

    Example:
        >>> import functools, requests
        >>> fetch = functools.partial(requests.get, "https://api.example.com/data")
        >>> response = retry(fetch, max_attempts=5, delay=0.5)
    """
```

### 3. Comments explain WHY, docstrings explain WHAT

Good comment: "Retry window must stay under 30s because the payment provider
times out at 31s (see ADR-0017)." That knowledge is not in the code anywhere.

Bad comment: `i = i + 1  # increment i by 1`. It restates the code and adds
nothing. If a block needs a paragraph of prose to make sense, extract it into
a well-named function first.

Format for deferred work: `// TODO(username): description - issue#123`.
A TODO without an owner and an issue is litter.

### 4. ADRs capture the decision while the context is fresh

Write the ADR the same day the decision is made. Retrofitting ADRs is slower
and less accurate, same as any docs.

Structure (Michael Nygard's format, see `references/adr-template.md`):

- **Title** — one line: "ADR-0017: Immediate confirmation before billing events"
- **Status** — proposed, accepted, rejected, deprecated, or superseded, near
  the top. Never delete a superseded ADR; mark it superseded and link the
  replacement so the reasoning history survives.
- **Context** — the forces that shaped the choice: constraints, requirements,
  deadlines.
- **Decision** — what we are doing, stated as a commitment ("We will keep
  the synchronous confirmation call").
- **Consequences** — what gets easier, what gets harder, what is now
  impossible. Name the accepted downside explicitly.
- **Rejected options** — each alternative with the reason it lost. This is
  what stops the next person from "fixing" an intentional tradeoff.

Keep it short enough that a person and an agent can read the whole record
before changing the code it describes. An ADR index at the top of the docs
folder (number, title, status) makes retrieval cheap.

### 5. README: five minutes to running or it failed

A README that does not get someone running in five minutes is a design review
waiting to happen.

- Line one: one sentence saying what the project is and who it is for.
- Quick start: install, configure, run. Under 60 seconds of reading.
- Prerequisites listed before installation, not buried in troubleshooting.
- Troubleshooting: common errors, what causes them, how to fix them.
- Badges (CI, version, license) at the top when they exist.

API docs follow the same discipline: endpoint, method, auth at a glance;
realistic request/response examples; error codes with causes and resolution
steps; rate limits and pagination stated up front.

## Output Contract

When asked to document code, deliver in this order:

1. Docstrings on every public function, class, and module (WHAT + runnable
   example). Private helpers get docstrings only when their behavior is
   non-obvious.
2. Inline comments only on the WHY of non-obvious logic (no restatement).
3. An ADR when the change involves an architectural choice, a tradeoff, or a
   constraint future readers will ask about.
4. README/API updates when behavior a user touches has changed.
5. A self-check report: which doc type each change got, and the output of
   `bin/check_docstrings.py` on the touched files showing no public API lacks
   a docstring. Date anything that can go stale.

## Operating Rules

1. Every factual claim in the docs must be verifiable: behavior from the
   code or tests, decisions from the people who made them. Never invent
   error codes, defaults, or performance numbers. Unverifiable goes in as
   clearly-marked opinion or gets cut.
2. Write the docs when you write the code, in the same change. Retrofits rot.
3. Keep docs in the same repository as the code, in version control. Docs in
   an external wiki nobody owns go stale within weeks.
4. One source of truth per fact. Link instead of duplicating. When two copies
   exist, they will diverge, and nobody will know which is right.
5. Consistent voice: second person ("you") for guides, first person plural
   ("we") for ADRs.
6. Testable artifacts only: run `bin/check_docstrings.py <files>` before
   claiming coverage is complete. Doctest-marked examples should pass under
   `python3 -m doctest` where practical.
