---
name: documentation
description: "Use when creating or substantively editing ANY markdown doc — invoke BEFORE writing. Genre registry, templates and style authority for technical docs: LLDs, ADs, plans, changelogs, READMEs, runbooks. Owns the tense rule: truth docs state the present; history only in dated records. Also maps a codebase's workflows into mermaid sequence diagrams ('map workflows', 'trace flows', 'sequence diagram'). Baselining is the maintenance agent."
---

# Technical documentation skill

This skill writes one document at a time: the genre registry says what kind of document it is, a template gives its shape, the style guide its prose, and `doc-lint` checks the mechanical half. It does not baseline, audit or reconcile a repo's doc tree; that is the `maintenance` agent, which calls this skill once per document it scaffolds.

## Load order

1. This file.
2. Your genre's row in [`templates/Readme.md`](templates/Readme.md) § Registry, then the template that row names.
3. [`references/style-guide.md`](references/style-guide.md) § The model, § Labels, § Sentences and § Vocabulary before writing prose; the rest of it only for the section you are writing.
4. [`references/frontmatter.md`](references/frontmatter.md) when you write or change frontmatter keys beyond `type:` and `description:`.
5. Only for their own tasks: [`references/document-sets.md`](references/document-sets.md) (more than one sibling document, or a doctrine document), [`references/untemplated.md`](references/untemplated.md) (no registry row fits), [`references/instruction-style.md`](references/instruction-style.md) (instruction files), [`references/source-comments.md`](references/source-comments.md) (source-file comments), [`references/examples.md`](references/examples.md) (worked good and bad examples).

---

## Writing one document

1. **Find the genre.** Match the request against § Routing, then read that genre's registry row: nature, `type:`, location, required keys, required sections. No row fits ⇒ `references/untemplated.md`.
2. **Find the existing document.** If a document on the topic already exists, extend it; a second document on one topic is drift. A new doctrine or playbook document also waits for the user's approval (§ Doctrine and playbooks). If the file is a frozen record (a plan at `Complete` or `Abandoned`, a committed changelog entry, an executed runbook), never edit it: write a new dated record that links back.
3. **Earn it, and route a set.** A new truth document that states rules (doctrine, a system, an architecture decision) first lists the decisions only it would own, each checked against the documents that exist; under about six, its rules go to their homes and the document is not written. More than one sibling document, or any doctrine document, follows `references/document-sets.md` from here: a term table and a rule ledger before prose, rendered from the ledger, one cold read.
4. **Place and name it** at the registry's location. `docs/structure.md` is the placement authority for anything the registry leaves open.
5. **Write it from the template, then run its genre procedure.** A template's procedure section binds that genre only: doctrine's is the reason check (`templates/doctrine.md` § Reason check). Keep the template's section names exactly; omit optional sections with nothing real to say. Write the body from the outside in (style guide § Shape), every heading and bold label a noun phrase, every sentence after a label third person, one rule per sentence in the term engineers use (style guide § Sentences, § Vocabulary). In a truth document, every sentence is present tense (§ The three natures). Every line owns a decision: before stating a rule, search the neighbours for it, and cite the one found rather than restating it (style guide § Net-net).
6. **Write the frontmatter.** `type:` from the registry, `description:` in at most 300 characters saying what the document settles and where its boundary sits, then the genre's required keys (`references/frontmatter.md` for each key's rules).
7. **Run the lint** from the repo root on the repo-relative path: `node <skill>/scripts/doc-lint.mjs docs/features/sign-in.md` (or `--changed`). Fix every `[block]` finding; read every `[warn]` and fix it unless the judgment it flags is genuinely yours. A disable takes bare rule ids, `<!-- doc-lint-disable: id -->`, alone on its own line for the whole file with the reason in a second comment on the next line, or at the end of one line for that line only.
8. **Edit, don't append, on a substantive change to an existing truth document.** Keep its section shape, shed any history narration, progress marker or stale tripwire in the sections you touch, bump `last-reviewed:`, update `objects:` if what it designs changed, and remove any retired key on the way through.

---

## Genre procedures

Some genres carry steps beyond writing from the template. Each procedure lives in its template, binds that genre alone, and runs at step 5 of § Writing one document.

| Genre | Procedure | Why the genre needs it |
| --- | --- | --- |
| Doctrine | `templates/doctrine.md` § Reason check: every reason judged obvious or non-obvious by a context-free sub-agent; non-obvious reasons stay or are added, obvious ones are cut | Written once in a while and read for years, so each line pays for itself; the writer cannot judge obviousness, because it knows every reason |
| Doctrine, and any set of siblings | `references/document-sets.md`: usefulness test, term table, rule ledger, one cold read | A set written one document at a time restates itself |

A genre with no row here has no procedure beyond its template.

## Doctrine and playbooks

Two genres are standards rather than accounts of one repository: a doctrine document settles one concern every product handles, and a playbook settles one interface or workflow shape every product builds. Both are read by the next product as much as by this one, so four rules bind them beyond their templates:

- **General form:** each reads correctly copied verbatim into another product's repository. It names nothing only its own repository has: the product, its domain entities, its vendors and stack, its people, its own documents by path. An example uses an object every product has, and the repository's own values stay in its feature documents, which name the standard in their Scope.
- **Extend first:** before a new document is proposed, the existing set is read (`grep -m1 '^description:' docs/architecture/{doctrine,playbooks}/*.md`), and content whose subject one of them already covers lands there as a section, a principle or a row.
- **New only on a clear distinction:** a new document is written only for a concern or a shape none of the existing ones owns, with decisions of its own (the template's earn-it test).
- **Never without approval:** an agent never creates a doctrine or playbook document on its own initiative, a baseline and a harvest included. It names the proposed document, the existing documents it was checked against and the distinction between them, then waits for the user's yes in chat. An unattended session files the request as a stop. An edit to an existing document follows the normal loop.

## The three natures

Every document is exactly one of three things, and the registry names which for every genre. Decide before writing a word: every other rule follows from the split.

| | **Truth** | **Record** | **Queue** |
| --- | --- | --- | --- |
| States | How the system is, now | What happened | Work not done yet |
| Named by | Topic: `auth.md`, `AD-003-persistence.md` | Date: `YYYY-MM-DD-slug.md` | A fixed name: `backlog.md`, `journal.md` |
| On change | Body rewritten in place | Frozen at its terminal status | A row appended, or a resolved row deleted |
| Read to | Act correctly today | Trace provenance, diagnose, audit | Pick up the next piece of work |

The guarantees break on mixing: a reader holding a truth document must never need history to interpret it, a reader holding a record must trust it was never rewritten, and a reader holding a queue must trust that every row in it is still open.

- **Truth documents narrate no history.** When the system changes, the change-story goes to a changelog entry and the truth document simply becomes correct. Write as if the current design had always been the plan.
- **Records are never edited to match the present.** A completed plan stays wrong in hindsight; a scope change gets a new dated record that links back.
- **Queue rows are resolved by deletion.** A finished backlog item, a landed journal fact, a drained bookkeeping row is deleted, never marked done; the plan or changelog entry that did the work is the record.
- **One bridge: an Architecture Decision's Decision Changelog.** For a decision, the journey is part of the reasoning, so an AD ends with a dated, append-only tail while its body stays current. No other truth document carries dated history.

| ❌ Strip this from a truth document | ✅ Write this |
| --- | --- |
| "Build Sequence phases 0–4 are complete." | Nothing; progress lives in the plan or backlog |
| "There is no standalone `skills/components/` — treat any reference to it as stale." | Nothing; fix the references and state only the present design |
| "Folded in from the `NuStack-X` repo (2026-06-12)." | "Vendor-connector catalogue; one subpath per vendor." |
| "was X, now Y", "the old worker", "Phase 2 softened this", "v1 → v2" | The current fact, with no predecessor named |

- **Dates:** a truth document carries no dated line. The exceptions are closed: the frontmatter's tooling keys (`last-reviewed:`, `last-updated:`, `rev:`, `harness-version:`), an AD's Decision Changelog, and a dated path inside a link or code span, which cites a record rather than claiming a date.
- **Citing a record:** by what it is, never by when it was. "The dev reset runbook" linked to the file stays true; "the 2026-09-13 reset" goes stale at the second reset.
- **Verification stamps:** "Driven 2026-09-13 · PASS" in a checklist is a dated event. The section states what must be true and which suite test guards it; that someone drove it belongs to the changelog entry of the unit that drove it.

The full strip-list and the record-side rules: `references/style-guide.md` § The Two Natures — tense and history.

---

## Truth documents

- **Intent and promises; facts are the graph's.** An owning document (feature, package, system) says why the product is shaped this way and what it promises, and names the objects it designs in `objects:`. Every computable fact (a table's columns, which function writes which column, which route sits behind which guard, which file holds what) is the code's, and a hand-typed copy is wrong the day the code moves. `doc-lint` blocks the retired mechanism sections (`mechanism-section`) and an owning document with no `objects:`.
- **Read by people, pointed at by the footer.** Sharp bullets under noun-phrase headings, each a bold label, a colon, one or two plain sentences; code named only where a person types or sees it, or at a cross-cutting seam; every other pointer in the closing **For the agent** footer (style guide § Owning documents — the body and the footer).
- **The stability test.** A sentence that would change when a function is renamed, a file moves, or a route, column or error code changes is the code's, not the document's. The code is the authority on *what*; the document on *why* (style guide § Shape).
- **Unbuilt work has one home per kind, outside doctrine.** A doctrine document is a specification and records no product's build state. Elsewhere, decided, unbuilt design sits in the body, wrapped in an `UNBUILT` marker; a shortfall in what is built is one bullet under Gaps; the work that would close either is a backlog row, which the document never tracks (style guide § The stability test).
- **No empty stubs.** Omit a section with nothing real to say. Write "None" only where the absence is itself information, such as a plan's Cross-Module Contracts Affected.
- **No redirect documents.** Moving a document deletes the old file and repoints every inbound link; a "Moved to X" stub rots and creates false search hits.

### Indexes and descriptions

- **Every document describes itself** in its `description:`, so a folder is browsed with `grep -m1 '^description:' <folder>/*.md` and no index keeps a row per file.
- **A folder's `Readme.md` describes the folder:** what it holds, who reads it, how its files are named. No file list, no tree (`docs/structure.md` holds the one tree), no record IDs such as `AD-010`. Nothing appends to an index when a sibling file is added; the changelog guide, `docs/history/CHANGELOG.md`, is no exception.
- **The links an index may carry:** a sibling folder's `Readme.md`, the mandated scaffolds (`structure.md`, `operations/setup.md`, `history/CHANGELOG.md`, `history/backlog.md`, `history/journal.md`, `history/health-log.md`, `memory/main.md`), and the root `CLAUDE.md` and `AGENTS.md`. `doc-lint` blocks the rest under `docs/` as `index-lists-files`, a drawn tree as `index-file-tree`, a named file or record as `index-names-records`.
- **Routing documents point at truth.** A "read first" row names the topic's truth document, never a plan or changelog entry. An index of the records themselves (a History section naming `plans/` and `changelog/`) is sanctioned.

### Ownership edges

A document names the objects it designs in `objects:`, and a source file names the document that speaks for it in its path header. The harness's ownership scan reads one edge: the transitional `owns:` region glob on each feature, package, system and surface-owning UX document, the narrower glob winning. **Always write the header pointer as well** — the scan switches to it and to the object closure, and pointers already in place spare that switch a second pass over the code. Where a repository has no `docs/architecture/systems/knowledge-layer.md`, this skill and `references/frontmatter.md` are the whole authority on document–code edges. `docs/structure.md` is harness-owned: the installer writes it, and the `maintenance` agent stamps only its `harness-version`.

---

## Routing

| Request | Route |
| --- | --- |
| Baseline / reconcile docs | `maintenance` agent (baseline mode); it calls this skill per template |
| Document a feature (LLD) | [`templates/feature.md`](templates/feature.md) |
| Document a feature's data flow or state | The feature doc's Flows (behaviour) and Promises (guarantees); a persisted shape belongs in the API reference (style guide § State at persistence points); component and transient state are not documented |
| Document a workspace package | [`templates/package.md`](templates/package.md), the residual owner of `packages/{name}/**` |
| Document one concern the platform handles everywhere (authentication, storage, the API protocol) | [`templates/doctrine.md`](templates/doctrine.md): design and principles in general form, no mechanism, no project link, owns no code; written through [`references/document-sets.md`](references/document-sets.md) |
| Document one interface or workflow shape every product builds (the shell, a settings area, analytics pages, a record's lifecycle) | [`templates/playbook.md`](templates/playbook.md): the shape and its rules in general form, owns no code; created only with the user's approval (§ Doctrine and playbooks) |
| Write or rework several sibling documents at once (a doctrine folder, a family of features) | [`references/document-sets.md`](references/document-sets.md): usefulness test, term table, rule ledger, render, one cold read |
| Document one system spanning packages | [`templates/system.md`](templates/system.md): one machine end to end, never a giant feature doc |
| Record or revise an architecture decision | [`templates/architecture-decision.md`](templates/architecture-decision.md): one AD per subject, revised in place |
| Create or update a changelog entry | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record; frozen inside its commit; no row in `CHANGELOG.md`) |
| Create or update a plan | [`templates/plan.md`](templates/plan.md) (record) |
| Steering docs: system overview, domain model, glossary, non-goals, security, testing strategy | The registry row's template |
| Catalog the API surface / the environment variables | [`templates/api-reference.md`](templates/api-reference.md) / [`templates/environment-registry.md`](templates/environment-registry.md) |
| What a person sees and can do on a surface | [`templates/ux-behavior.md`](templates/ux-behavior.md): decides observable behavior before the code; not the checklist, which only verifies it |
| Behavioral checklist for one feature | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md): the verification gate's driving script |
| Acceptance criteria for one capability | [`templates/acceptance-criteria.md`](templates/acceptance-criteria.md): stable `AC-n` lines |
| Machine setup, first run, stack | [`templates/setup.md`](templates/setup.md), one per repo |
| Recurring procedure (develop, deploy, rotate, diagnose) | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
| Cold-start build order | [`templates/implementation-map.md`](templates/implementation-map.md), written by the executing session at build start |
| Capture a mid-execution fact / log doc-sync debt / log open work | [`templates/journal.md`](templates/journal.md) / [`templates/bookkeeping.md`](templates/bookkeeping.md) / [`templates/backlog.md`](templates/backlog.md) (queues) |
| One-shot migration | [`templates/migration-runbook.md`](templates/migration-runbook.md) (record) |
| Hand-over at the end of an unattended or multi-session build | [`templates/handover.md`](templates/handover.md) (record) |
| Protected files | [`templates/protected-files.md`](templates/protected-files.md) |
| Root README | [`templates/root-readme.md`](templates/root-readme.md): outward opening, then orientation and routing |
| Scaffold a standard doc (docs index, changelog guide, backlog, memory) | The registry's § Baseline scaffolds |
| Frontmatter keys (`objects:`, `verifies:`, the transitional `owns:`) | [`references/frontmatter.md`](references/frontmatter.md) |
| Source-file comments: what stays, what moves to a doc, proving a sweep | [`references/source-comments.md`](references/source-comments.md) |
| Instruction file (`CLAUDE.md`, a rule, an agent, skill prose) | [`references/instruction-style.md`](references/instruction-style.md): every-load prose stays lean; the present-tense rule applies too |
| Author or restructure a skill | The skill-authoring field guide in the etna repo (`nurixlabs/etna`), `docs/playbooks/skills/`. No etna checkout ⇒ ask the user for access, or proceed from first principles with `references/instruction-style.md` governing the prose |
| Map a codebase's workflows: call chains from user action to the database or an external system, as mermaid sequence diagrams | [`references/workflow-mapping.md`](references/workflow-mapping.md), with [`references/workflow-patterns.md`](references/workflow-patterns.md) |
| No template matches | [`references/untemplated.md`](references/untemplated.md) |

---

## Resources

| File | Use for |
| --- | --- |
| `templates/Readme.md` | The genre registry: every genre's nature, `type:`, location, required keys and sections; `doc-lint` reads it |
| `templates/` | One template per genre the registry names |
| `references/document-sets.md` | Writing several sibling documents as one design: the usefulness test, term table, rule ledger, render, and the review rubric the `doc-reviewer` agent reads |
| `references/style-guide.md` | The prose authority: the nine principles, what earns a line, depth per genre, the outside-in shape and stability test, labels and voice, owning documents, tense, diagrams, reference documents |
| `references/frontmatter.md` | Each frontmatter key's rules, the transitional `owns:`, the retired keys |
| `references/instruction-style.md` | The style for instruction files |
| `references/untemplated.md` | Writing a document no template covers, and co-authoring one with a person |
| `references/source-comments.md` | Source-file comments, and the scripts that check them |
| `references/examples.md` | Good and bad documentation, side by side |
| `references/workflow-mapping.md`, `references/workflow-patterns.md` | Tracing a codebase's workflows into mermaid sequence diagrams, and the patterns to look for |
| `scripts/doc-lint.mjs` | Mechanical checks over written docs: tense and history, dates, redirect stubs, frontmatter, the registry's keys and sections, index shape, owning-document body, and a doctrine folder read as a set (citations resolve; no shared objects, restated sentences, body links or `UNBUILT` markers) |
| `scripts/source-lint.mjs` | Mechanical checks over source comments; run `--changed` before finishing any change that writes source |
| `scripts/comment-strip.mjs` | Proof that a comment sweep changed no executable code |
