Skip to content
commission

Writing commission's documentation

You will be able to add or change a documentation page and have it be consistent with every other page: in the right section, opening the right way, with examples that are tested and terminology that is defined exactly once.

These are the authoring conventions for everything under docs/. They are short because there are only a few of them and all of them are enforceable.

Generated versus written

This is the rule that matters most. Some pages are produced by a script from the source of truth in src/. They are overwritten on the next run, so hand-editing one looks like it worked, is silently reverted, and in the meantime makes the documentation disagree with the binary.

Every generated page opens with a comment naming its generator:

<!-- generated by scripts/generate-docs.ts — do not edit -->

If you see that line, close the file and edit the source instead.

The generated pages

pagegenerated bysource of truthregenerate with
docs/reference/cli.mdscripts/generate-docs.tsthe commander program exported from src/cli/index.tsbun run generate:docs
docs/reference/apply.mdscripts/generate-docs.tsapplySchemaJson() in src/core/apply.tsbun run generate:docs
docs/reference/mcp.mdscripts/generate-docs.tsthe tools registered in src/mcp/server.ts, read over the MCP protocolbun run generate:docs
docs/reference/config.mdscripts/generate-config-reference.tsthe config schema in src/configbun run generate:config
schema/commission-config.schema.jsonscripts/generate-config-reference.tsthe config schema in src/configbun run generate:config

Everything else under docs/ is prose, written by hand, owned by a person or an agent holding a Commission task.

How the rule is enforced

tests/docs.test.ts and tests/config.test.ts regenerate every artifact in memory and compare it to what is on disk. Any difference fails the suite and names the command that fixes it. Both generators also take --check, which does the same thing at the terminal and exits 2 — a refusal, in commission’s own vocabulary — so CI can run it directly:

bun run scripts/generate-docs.ts --check
bun run scripts/generate-config-reference.ts --check

The consequence worth internalising: you cannot change the CLI, the apply schema, or the MCP tool list without the documentation change landing in the same commit. That is the entire point. Reference pages that drift are the most expensive kind of documentation, because they are trusted and wrong.

Adding a new generated page

Extend scripts/generate-docs.ts rather than writing a new script. It already owns the --check flag, the artifacts() export the drift test imports, and the shared table-and-escaping helpers. A new page is a text() function plus one entry in build(); the drift test picks it up with no change.

If a page’s source cannot be read right now — for example, an export that another in-flight task is still adding — push a { path, reason } onto blocked instead of throwing. A missing page with a stated reason is recoverable; a crashed generator takes the whole suite down with it.

Every page opens with what the reader will be able to do

The first paragraph, before any subheading, is one sentence in the second person naming the capability the reader walks away with.

You will be able to bring an existing backlog into commission, or run commission alongside a tracker that is still the system of record — binding only the work that genuinely has to reflect outward, and keeping every outbound write supervised.

Not “this page covers interop.” Not a summary of the contents. What the reader will be able to do. If you cannot write that sentence, the page does not have a purpose yet, and no amount of good prose underneath will give it one.

This applies to index pages too, including the section indexes.

Every command example is copy-pasteable and tested

  • Copy-pasteable. No $ prompts, no ... elisions, no placeholder that is not obviously a placeholder. A reader should be able to select the block and paste it.
  • In order. A page’s blocks run top to bottom from a clean checkout. If a block depends on a previous one, they are part of the same sequence, not scattered.
  • Real output. Where output is shown, it is output that was actually produced, copied verbatim. Invented output is a lie with a short half-life.
  • Tested. Every command sequence in a guide or a getting-started page is executed by a test. Documentation that lies is worse than none, and the only way to know it has stopped lying is to run it.

How “tested” is enforced. tests/docs.test.ts extracts every ```sh block from every registered page, runs the commands in page order against a scratch database with commission on PATH, and asserts the exit code — 0 unless the page is deliberately showing a refusal, in which case the expected 2 is declared in the page’s entry. A silent success fails as loudly as a silent failure.

Three consequences for how you write a page:

  • Use ```sh only for commands that run. Captured transcripts and illustrative output go in a bare ``` block, which nothing executes.
  • A command that cannot run hermetically is skipped with a stated reason — a live Jira token, a long-running server, a network clone — and is then validated against the live commander tree instead, so an invented flag still fails. Same shape as the generator’s blocked list: recoverable, visible, never silent.
  • A closing “whole sequence” block must be a subset of the page. It is checked against what the page actually ran, so the recap cannot drift from the body.

A new page carrying a ```sh block must be registered in PAGES, or the suite fails — which is the point.

Annotate with # comments inside the block rather than prose between blocks, so the block survives being copied:

commission next --claim             # picks + claims a task, prints the context bundle
commission note myapp-3 -m "..."    # breadcrumbs for the next session
commission done myapp-3             # refused until criteria + gate evidence exist

One definition, in one place

docs/positioning.md is canonical. Its §6 vocabulary table is the only definition of commission’s terms, and its §1 sentences marked canonical are copied verbatim rather than paraphrased.

Documentation links to it and never redefines a term. If a page needs a word to mean something §6 does not say, the page is wrong, or the word is — and the fix is to change positioning.md first, which is owned by relay-54.

The same applies to claims about what commission does. Anything described in the present tense must be in the shipped list of positioning.md §8. Planned capability is written as planned, with its task id, or is not written at all. Check with commission show <id> before you put a claim on a page.

Where a page goes

if the page…it belongs in
gets a new reader to their first working loopstart/
walks a specific job end to endguides/
exhaustively lists what something accepts or returnsreference/
explains why the design is what it isconcepts/
tells a contributor how to work on commissioncontributing/

Pages that want to be in two sections are usually two pages. The commonest mistake is a guide that slowly turns into a reference table; the fix is to link to the generated table instead.

Structure and formatting

  • One # heading per page, matching the page’s subject. Titles come from the H1 — there is no frontmatter, because these files are read both on GitHub and rendered by the site, and frontmatter renders badly in one of them.
  • Sentence case in headings. ## Importing an existing backlog, not ## Importing An Existing Backlog.
  • Relative links with the .md extension../reference/cli.md, not /reference/cli. That is what works when the file is read on GitHub; the site rewrites them at build time. Link to a section with a GitHub-style anchor: ../positioning.md#6-vocabulary.
  • Every section index links its children, and every page links back to its section. Nothing is reachable only by search.
  • Wrap prose at about 90 columns. Diffs are read in terminals.
  • American or British spelling — pick the one already used on the page and stop thinking about it.

Tone

Declarative, specific, willing to state limits. Commission’s refusals are written that way and the documentation should match its error messages.

State the trade-off rather than hiding it. “Commission is not a semantic memory system” belongs in the docs for the same reason it belongs in the positioning: a reader who finds the limit themselves, after adopting, stops trusting the parts that were true.

Avoid entirely: AI-powered project management, autonomous software engineer, 10x productivity, AI teammate, and the rest of positioning.md §9.

Before you open a pull request

bun run generate:docs        # if you touched the CLI, apply schema, or MCP tools
bun run generate:config      # if you touched the config schema
bun test                     # the drift tests live here

Then attach the evidence the task’s gate asks for. Documentation tasks in this repository carry the documented gate: test, commit, and docs.

This page is docs/contributing/documentation.md in the Commission repository, rendered in place — the site keeps no copy of it. The repository is private, so there is no edit link to follow.