choir documentation
Getting started lives in the top-level README. Everything else is here, indexed by what you are trying to do.
Every page here is also compiled into the API documentation: each one is
pulled into the crate that implements it with #![doc = include_str!], so
cargo doc renders this prose beside the types it describes. That is not a
convenience — it is what keeps these pages honest. The release gate runs
cargo doc with -D warnings, so a Rust example in any of these files that
stops compiling fails the build.
Build both halves together with choir docs, which renders the book and
puts rustdoc inside it at /api/. From a checkout without the CLI
installed: cargo run -p choir-cli -- docs --open.
The comment above is a marker, not stray markup: choir docs replaces it
with a link to the node when the publishing workflow supplies that address
(D76).
Start here
| You want | Read |
|---|---|
| To know what this is and whether you want it | Why choir exists |
| How the pieces fit | Architecture |
| To run a node | Running a node |
| To use a node | The CLI and HTTP API |
| To get a change reviewed and landed | The contribution workflow |
| Something is broken | Troubleshooting |
Operating a node
| Page | Covers |
|---|---|
| Running a node | Starting the daemon, every policy file, the supervised macOS install |
| Authorization | ACLs (D29), repository ownership (D42), landing basis (D43), key rotation (D44), credential self-service (D36) |
| Rate limits, quotas and fairness | Request log and rate limits (D33), per-user quotas (D37), the sequencer’s in-flight window |
| Webhooks | Outbound ref-landed deliveries (D32) |
| Observability and repair | The decision journal, choir repair, what each derived record is for |
| Transports and the browser surface | Git over HTTPS and SSH (D31), the read-only page (D28), repository browsing (D30) |
Two runbooks sit beside these, for the two operations that are procedures rather than configuration:
- Private single-node beta runbook — the network hold, the TLS proxy, backups, staging promotion, go-live receipts.
- Restoring a node from a backup — the ordering rule, and the secrets a backup deliberately never holds.
- Canonical-node flip runbook — supervised install and turning on the protected-ref gates.
Using a node
| Page | Covers |
|---|---|
| The CLI and HTTP API | Every command and endpoint, generated from one table |
| The contribution workflow | Workspace to landed ref, and the review rules that bite in practice |
| Agent templates | Drop-in harness snippets for Claude Code, Codex and Cursor |
AGENTS.md | The same surface written for an agent that has never seen choir |
Reference
| Page | Covers |
|---|---|
| Troubleshooting | Symptoms, causes, fixes |
ERRORS.md | Every rejection code and its repair hint — generated from the node’s own table |
SYNC.md | Catching up on a log, and replaying a page’s hash chain and signatures so what the node served is checkable |
DECISIONS.md | What each D<n> in the code means, and which are one-way doors |
| Bridge permissions | The minimum GitHub App grants, and what must not be granted |
Which of these is generated
Editing a generated file by hand is wasted work: the release gate compares
it against its source and fails when they differ. Regenerate with
cargo run -p choir-cli --example gen-surface.
| Generated | Source |
|---|---|
| The surface block in using/cli.md | crates/choir-cli/src/surface.rs |
theme/choir-tokens.css, the book’s palette | crates/choir-node/src/ui.css |
| The cheat-sheet block in the README | crates/choir-cli/src/surface.rs |
AGENTS.md, /llms.txt, /api/schema | crates/choir-cli/src/surface.rs |
ERRORS.md | crates/choir-node/src/reject.rs |
The command lists in templates/ | crates/choir-cli/src/surface.rs |
Everything else on this page is written by hand and is fair game to edit.