Skip to main content

Documenting a feature or System

Audience: developers & AI agents documenting a capability · Scope: how to structure docs for a feature, a System (multi-doc), or an integration layer · Last reviewed: 2026-07-20

Part of the documentation standards; builds on writing.md (the base every doc follows).

TL;DR — A feature doc explains a cohesive capability that spans many files — its purpose, its moving parts, and how they connect — so a reader can build a mental model and jump to any piece. On top of the base standard it adds a feature-specific spine: what & why → map the parts → admin settings → flow → integrations → data model → deployment → testing → gotchas. A feature big enough to need several docs becomes a System — one folder, a hub, and spoke docs.

Living standard — amend it.


Where a doc belongs — the top-level kinds

Most docs describe a capability you built — classify those by how much they span (it decides the doc form). A few top-level areas are fixed scaffolding: they already exist and you write into them rather than adding new ones. Everything at the top level of docs/ — folder or single file — is one of these kinds.

Capability tiers — pick one for a new capability:

TierWhat it isExampleDoc form
Featureone focused capability someone usestracking (analytics)one focused doc under docs/features/
Systema group of features sharing one data model, vocabulary, and purposeQuote Follow-Upa folder: a hub (README.md) + spoke docs
Integration layershared infrastructure that many systems build onPipedrive, Google Sheetsits own top-level doc or folder, referenced by systems

Fixed areas — the scaffolding around the capabilities; you write into these and rarely add new ones:

AreaWhat it isWhere
Foundation / platformthe substrate the whole site runs on — not something you added, the ground it stands ondocs/configbox/ (ConfigBox / Kenedo)
Cross-cuttinga practice or toolchain that applies across every capabilitydocs/testing/, plus the single-file scheduled-jobs.md and monitoring.md
Metadocs about the docs — these standardsdocs/standards/
Planningnot reference material — a register of work, prefixed _ so Docusaurus ignores itdocs/_known-issues.md, admin-guide/_backlog.md

A cross-cutting area only needs a folder once it has spokes. A single focused doc at the top level (scheduled-jobs.md, monitoring.md) is fine and preferable to a folder with one file in it — the same rule that applies to features.

The operator-facing Admin Guide (admin-guide/) is a separate audience area, not a kind of reference doc — see admin-guide.md.

It's a System, not a Feature, when ≥ 2 hold: it's made of multiple stand-alone features; they share a data model and vocabulary (the quote, the agent, the magic-link token, the imported stages); it spans multiple entry points / runtimes (a page and cron and a webhook and an API); no single doc can explain it without sprawling or duplicating.

System vs Integration layer: a System owns business capability; an Integration layer is shared plumbing. Test — if an unrelated system would also use it, it's a layer, not part of this system. So Pipedrive and Google Sheets are dependencies the Quote Follow-Up System links to, not spokes of it. (Our pipedrive/README.md already calls itself a "foundational layer" — same idea.)

How to document a System

One folder per System — which is also exactly what a Docusaurus sidebar category is, so this choice serves both the repo and the docs site:

docs/quote-follow-up/
_category_.json ← Docusaurus: the sidebar category's label + order
README.md ← the hub, and the category's index page: what the System is + the map
landing-page.md ← spoke (the page: states, save, data model)
authentication.md ← spoke (the no-login magic link + the machine Link API)
pipeline-stages.md ← spoke (imported Pipedrive pipelines & stages)
nudge-cadence.md ← spoke
stage-sync.md ← spoke
link-api-n8n.md ← spoke
  • README.md is the hub and the category index. GitHub shows it when you open the folder; Docusaurus auto-uses a folder's README.md/index.md as the category's index page; an AI/raw reader treats it as the entry point. One file, three readers.
  • _category_.json sets the sidebar label and order without ugly numeric filename prefixes (see the snippet below). With a README.md present you don't need a link — Docusaurus links the category to it.
  • Spokes are normal feature docs (the spine below); order them with a sidebar_position front-matter field, not a filename prefix (prefixes leak into the URL slug).
  • Integration layers stay top-level (docs/pipedrive/README.md) and are linked from the hub — never nested inside a System folder, because other systems use them too.
  • Never document the same behaviour twice. One doc owns each fact; the hub and the other spokes link to it.
  • Small features live in docs/features/ — one focused doc each. Don't make a per-feature folder for a single doc; promote a feature to its own top-level System folder only when it grows into a System (the test above).

Worked example: the Quote Follow-Up System lives in quote-follow-up/ — the hub (README.md) maps its spokes landing-page.md, authentication.md, pipeline-stages.md, nudge-cadence.md, stage-sync.md, and link-api-n8n.md, with Pipedrive/Sheets linked as Integration layers.

The spine of a feature doc

Start with the base skeleton (title · Audience/Scope/Last reviewed blockquote · TL;DR), then these sections in this order. Include the ones that apply and omit the rest — don't ship empty headingsexcept Admin settings and the Deployment runbook, which are mandatory: if none apply, say so explicitly (e.g. "No admin settings." / "No manual steps — ships with the code.") rather than dropping the section, so an operator always knows where to look. This holds for a standalone feature doc and for every spoke of a System.

  1. What it is & why it exists. The problem, the user, and the 30-second mental model, in one or two paragraphs. Link the live URL / entry point. (No changelog — see the base standard.)
  2. How it fits together. The centrepiece of a feature doc: a small diagram of the flow plus a moving-parts table — one row per component (file → role). A parts list and a picture of how they connect, so a reader jumps straight to the right file.
  3. Admin settings. (Mandatory.) Every admin-facing setting the feature exposes, in a table: name · where it's set (admin group / screen) · default · effect of blank/off. Be complete — this is the technical reference, not a sample. A System spoke lists the settings it owns and links the System's admin manual for the full picture. (The plain-language operator how-to for these settings lives in the separate Admin Guide — parallel, not duplicate.)
  4. Control / data flow. The request lifecycle (a page) or the pipeline (a job): inbound and outbound, what fires what, idempotency, and any ordering that matters.
  5. Integrations & contracts. External systems (Pipedrive, Google Sheets), auth, and the wire contract (endpoints, status codes, payload shape) — the part another team or automation codes against.
  6. Data model. The tables/columns the feature owns (name the migration that adds each — as a reference, not a history), plus any denormalisation / carry-forward rules. (Below settings & integrations — read what it does and how it's configured before its storage.)
  7. Deployment runbook (manual steps). (Mandatory.) The ordered, numbered manual steps to deploy / roll this out end to end — run migrations, set the settings, run any imports / setup CLI, add the cron entries, register the webhook, then a smoke test — so an operator can follow it top to bottom. Include how to turn it on/off. A System spoke covers its own steps and links the System's deployment playbook for the cross-cutting order.
  8. Testing. What's covered, how to run it, and the capture/guard rules. Link the testing doc.
  9. Gotchas & caveats. Prerequisites and footguns — the "why did this bite me" section.
  10. Extension points / possible follow-ups. Where to plug in next; genuinely open items only (no ✅-done).
  11. Related docs. Cross-links to sibling features and the hub.

Copy-paste: feature-doc skeleton

# <Feature> — <plain-words what it is>

> **Audience:** … · **Scope:** … · **Last reviewed:** YYYY-MM-DD

**TL;DR**<the capability + the single most important rule, in 2–4 lines.>

## What it is & why it exists
## How it fits together ← diagram + moving-parts table (file → role)
## Admin settings ← MANDATORY: table of EVERY setting — name · where set · default · blank/off
## Control / data flow ← inbound + outbound
## Integrations & contracts
## Data model ← tables/columns (+ owning migration)
## Deployment runbook ← MANDATORY: ordered manual steps (migrate → settings → import → cron → smoke) + on/off
## Testing
## Gotchas & caveats
## Possible follow-ups
## Related docs

Copy-paste: System hub (docs/<system>/README.md)

# <System> — overview

> **Audience:** … · **Scope:** the <System> as a whole; a map to its spoke docs · **Last reviewed:** YYYY-MM-DD

**TL;DR** — what the System does, end to end, in a few lines; then the map below.

## The parts (map) ← a diagram of the spokes + a table: spoke → doc → one-line role
## End-to-end flow ← how one unit of work moves across the spokes
## Shared concepts ← the SINGLE source of truth for things that span spokes
(the magic-link token, the imported stages, the quote↔deal model)
## Dependencies ← the Integration layers it builds on (links to pipedrive/README.md, the Sheets layer)
## Cross-cutting ops ← links to the deploy playbook / admin manual / testing doc

Alongside it, docs/<system>/_category_.json (Docusaurus reads the README as the category index automatically):

{ "label": "<System>", "position": 6, "collapsed": true }

Feature-doc anti-patterns

  • Kitchen-sink file — one doc covering five sub-systems; nobody finds their piece. Split, add a hub.
  • A parts list with no map — a Files table is necessary but not sufficient; show how they connect.
  • Duplicated behaviour across the hub and a spoke (or two spokes). One owner; the rest link.
  • Config buried in prose — put settings in a table (name · default · effect), not scattered sentences.
  • Changelog masquerading as status — commit hashes, dated "Status", ✅-done lists. See the base standard.
  • An Integration layer nested inside a System folder — shared plumbing (Pipedrive, Sheets) lives top-level and is linked, not owned by one System.
  • A folder for a one-doc feature — folders are for Systems; a lone feature lives in docs/features/ as a single doc.

Checklist — a feature doc is done when…

  • The base checklist (writing.md) passes.
  • A newcomer can state what the feature does and why from the first screen.
  • "How it fits together" has both a diagram and a moving-parts table (file → role).
  • Admin settings and a Deployment runbook (manual steps) are both present (mandatory) — if none apply, the section says so explicitly rather than being dropped.
  • Admin settings is a complete table (every setting · where set · default · blank/off), not a sample.
  • The Deployment runbook is ordered / numbered and followable top to bottom (migrate → settings → import → cron → smoke), and says how to turn the feature on/off.
  • Data model, control/data flow, integrations, and testing are covered — or deliberately N/A.
  • It links the admin/deploy/testing docs instead of duplicating them; the hub (if any) links here and back.
  • Only genuinely-open follow-ups remain; nothing resolved.
  • If it's a System: a folder with a README.md hub + _category_.json; spokes ordered via sidebar_position; the shared concepts live once in the hub; Integration-layer dependencies are linked, not nested.