arqix Architecture (arc42)
This page assembles the arc42 architecture document from one unit per chapter (REQ-01-01-11-01).
Until arqix assemble build exists, the directives below document the intended assembly; afterwards they drive it.
Introduction and Goals¶
arqix is a deterministic documentation-as-code toolchain: it creates, formats, lints, assembles, traces, and publishes modular Markdown documentation whose structure and relationships are machine-readable. Documentation is treated as a dataset with a contract, not as prose with goodwill.
The system exists because "related" links between artefacts are not enough (see the blog post why arqix had to exist): requirements, stories, code, and tests need verifiable, tool-enforced traceability that survives automation.
Top Quality Goals¶
| Priority | Quality goal | Anchored by |
|---|---|---|
| 1 | Determinism — identical inputs and configuration produce byte-identical outputs | REQ-00-00-00-01 |
| 2 | Machine-readability — diagnostics, catalogs, logs, and reports are documented data contracts | REQ-00-00-00-03, REQ-00-00-00-02 |
| 3 | Safety and containment — no writes outside declared scope, no overwrites without approval, no content execution | REQ-00-00-00-07/08/13/14 |
| 4 | Traceability — every artefact participates in a verifiable US → REQ → code/test graph | REQ-01-01-08-, REQ-03-01-05- |
| 5 | Bilingual quality — translation completeness and drift are lintable | REQ-00-00-00-10 |
Stakeholders¶
The four current personas under ../personas/ (six earlier ones retired in the 2026 merge) condense into four C4 roles: the Documentation Maintainer (PER-01, standards and governance), the Builder (PER-09, corpus alongside code, pipelines, and architecture), the Assessor (PER-10, evaluates and consumes the corpus), and the Coding Agent (PER-08, deterministic story-by-story automation; includes CI).
Coverage per persona is tracked in the requirements review table.
Architecture Constraints¶
| Constraint | Consequence | Source |
|---|---|---|
| Rust, single binary | All behaviour ships in one deterministic CLI; the Python checker scripts are reference implementations to be ported | repository layout, scripts/ |
| MIT OR Apache-2.0 | Licensing of all shipped code and templates; contributions are dual-licensed the same way | LICENSE-APACHE, LICENSE-MIT |
| Docs-as-code | All artefacts are Markdown + YAML frontmatter in git; no database, no service | docs/en/index.md |
| Agent-neutral process | Normative process rules live in AGENTS.md only; agent-specific files are thin adapters | ADR-0001 |
| Filesystem containment | The CLI never accesses files outside the repository root and configured allowed roots | REQ-00-00-00-13 |
| No content execution | Document content never triggers process execution; external tools run only when explicitly configured | REQ-00-00-00-14 |
| Versioned contracts | SemVer for the product plus separately versioned config_version and schema_version |
REQ-01-01-15-02 |
| GitHub Pages rendering | Embedded diagrams must be Mermaid; the C4 model source is Structurizr DSL | ADR-0002, REQ-01-01-11-04 |
Context and Scope¶
arqix operates on a documentation corpus inside a git repository. Humans and coding agents drive it through the CLI; CI runs the same commands as a gate; MCP clients consume the corpus through the built-in server. Rendering is delegated to external tools that arqix orchestrates but never trusts with control flow.
External interfaces: the filesystem (bounded by REQ-00-00-00-13), the render toolchain contract (errors forwarded transparently, REQ-04-01-03-07), the exit-code contract towards CI (REQ-04-01-08-01), and MCP over stdio (REQ-05-01-12-*).
Solution Strategy¶
- One deterministic CLI. Every capability is a subcommand of a single Rust binary; every command resolves against the effective configuration (REQ-00-00-00-06) and honours the shared exit-code and diagnostics contracts (REQ-00-00-00-02/03). Determinism (REQ-00-00-00-01) is an architectural property, not a per-feature promise: no wall-clock, no randomness, stable ordering everywhere.
- Documents are data.
Frontmatter plus a small ontology (
docs/ontology/) make structure and relationships machine-readable; IDs and slugs derive deterministically from configured policy (REQ-00-00-00-04). The corpus in this repository is arqix's first real corpus. - Contracts first, implementation second. The 165 requirements, the requirements style guide, and the Python checker scripts (requirements, frontmatter, trace markers, and the trace oracle) define testable contracts before Rust code exists; the scripts are the reference specification for the Rust port and stay as oracles until the cross-check retires them (chapter 8).
- Traceability as a graph. Trace markers in code and tests, frontmatter links, and the derived-from/has-requirement symmetry form one graph that scan, matrix, coverage, and evidence-bundle commands project into views (REQ-03-01-*).
- One parser, two layers. Documents are parsed exactly once by a shared Document Parser: a lossless concrete-syntax layer that the formatter needs for meaning-preserving rewrites (REQ-01-01-03-03), and a semantic document model (frontmatter, sections and anchors, directives, trace markers) that store, linter, assembler, and trace engine consume (REQ-02-01-09-, REQ-05-01-10-). One grammar, one implementation — parser drift across components would silently break determinism.
- Delegated rendering. Pandoc and site toolchains stay external processes behind an orchestrator; arqix owns inputs, artefact placement, and error transparency, never the renderer (REQ-04-01-03-*).
Building Block View¶
The binary decomposes into fifteen components: the CLI entrypoint as composition root, the document parser as shared reading layer, the verification orchestrator sequencing the quality gate, and twelve feature components cut along the requirement clusters:
| Component | Responsibility | Requirement cluster |
|---|---|---|
| CLI Entrypoint & Dispatch | Argument parsing, subcommand routing, composition root (config → component → diagnostics/exit code) | REQ-00-00-00-02/03/06 |
| Document Parser | Single deterministic parse of YAML frontmatter into the semantic model (id, iri, title, classes, triples, language); retains raw frontmatter lines and body for the rewriter | REQ-05-01-10-*, REQ-01-01-03-03 |
| Verification Orchestrator | Sequences the configured verify sub-steps (format, lint, trace scan, coverage) via the stable command interface; fail-fast/aggregate modes, per-step JSON results; never implements a check itself (ADR-0003) | REQ-04-01-05-* |
| Config Resolver | Effective configuration from defaults + overrides, validation | REQ-01-01-16-*, REQ-00-00-00-06 |
| Document Store & Catalog | Discovery over the roots, JSON catalog reading declared IDs, backing doc list/read/search | REQ-05-01-08-, REQ-05-01-10-, REQ-02-01-06-01 |
| Template Engine | Kind-based creation, placeholder substitution | REQ-00-00-00-05, REQ-01-01-05-* |
| Formatter & Finaliser | Canonical rewrites over the parser CST: fmt (key order, directives) and finalise (mechanical metadata updates, injected clock); the only mutator of existing source documents (ADR-0004) |
REQ-01-01-03-, REQ-01-01-06-, REQ-00-00-00-08 |
| Linter | Includes, references, ID policy, lifecycle, done claim, translation source | REQ-01-01-04-, REQ-01-01-18-, REQ-03-01-09-*, REQ-00-00-00-10 |
| Assembler | Chapter/include directives, glob expansion, cycle detection, JSONL log | REQ-02-01-09-, REQ-02-01-11-, REQ-04-01-01-* |
| Trace Engine | Marker scan, trace graph, matrices, coverage, marker freshness against git history | REQ-03-01-05-, REQ-03-01-02-, REQ-01-01-08-, REQ-03-01-11- |
| Report & Export | Audit exports, evidence bundles, stable schemas | REQ-04-01-12-, REQ-03-01-04- |
| Publish & Render Orchestrator | Pandoc/site orchestration per language | REQ-04-01-03-, REQ-04-01-07- |
| Policy Checker | Changed files vs declared change scope | REQ-01-01-07-*, REQ-00-00-00-07 |
| MCP Server | search/read/list over stdio, transport-separated | REQ-05-01-12-* |
| Diagnostics & Exit Codes | Machine-readable diagnostics, 0/1/2 contract | REQ-00-00-00-02/03, REQ-04-01-08-, REQ-04-01-10- |
Shared spine: the CLI Entrypoint invokes every feature component and is the only place that turns results into exit codes; every component reports through Diagnostics & Exit Codes, reads configuration through the Config Resolver, and reads documents through the Document Parser; the Verification Orchestrator sequences the quality-gate sub-steps through the same command interface the entrypoint uses (ADR-0003). These five are the components that make the cross-cutting contracts (chapter 8) enforceable in one place; beyond the shared reading path through the Document Store & Catalog (Template Engine, Linter, Assembler, and MCP Server all discover the corpus through it — the Trace Engine walks the filesystem itself, mirroring the Python oracle), lateral coupling between feature components is limited to the export and publish paths: the Publisher's edges (→ Assembler for staging, → Store and Trace Engine for the specification catalogue), the Reporter's edges (→ Trace Engine for evidence, → Store and Assembler for the knowledge bundle), the MCP Server's trace tool (→ Trace Engine), and the Assembler's reuse of the Linter's include-directive grammar — the orchestrators' edges are command-API orchestration, not implementation coupling. A complementary write-path invariant holds across the cut: existing source documents are mutated only by the Formatter & Finaliser; the Template Engine creates new files, and Assembler and Publisher write generated artefacts (ADR-0004).
Command ownership¶
Each command has exactly one owning component — the component whose tests own the command's behaviour. The spine (Entrypoint → Config Resolver → … → Diagnostics & Exit Codes) is implicit in every flow; write flows additionally pass the containment, overwrite, and dry-run guards.
| Command | Owning component | Flow between entrypoint and diagnostics | Requirement anchor |
|---|---|---|---|
config validate, config show |
Config Resolver | resolver only | REQ-01-01-16-* |
doc init |
Template Engine | writes the package scaffold; IDs/slugs via Document Store | REQ-01-01-01-* |
doc new <kind>, unit new |
Template Engine | → Store (ID/slug/target path) → guarded write | REQ-00-00-00-05, REQ-01-01-13-* |
doc list |
Document Store & Catalog | → Parser (bulk) → JSON catalog | REQ-05-01-08-* |
doc read |
Document Store & Catalog | → Parser (sections/anchors) | REQ-05-01-10-* |
doc search |
Document Store & Catalog | → Parser; index question open (chapter 11) | REQ-02-01-06-01 |
fmt |
Formatter & Finaliser | → Parser CST → canonical rewrite | REQ-01-01-03-* |
finalise |
Formatter & Finaliser | → Parser CST → targeted value edit; injected clock | REQ-01-01-06-* |
lint run (incl. translation-source check) |
Linter | → Parser/Store → findings | REQ-01-01-04-, REQ-01-01-18-, REQ-00-00-00-10 |
assemble build |
Assembler | → Parser (directives) → Store (targets) → pages/ + JSONL log |
REQ-02-01-11-, REQ-04-01-01- |
trace scan, trace check |
Trace Engine | → Parser (markers, links) + code/test files → graph | REQ-03-01-05-, REQ-03-01-06- |
trace coverage, trace matrix |
Trace Engine | graph projections; serialisation via Report & Export | REQ-01-01-08-, REQ-03-01-02- |
trace ratchet |
Trace Engine | baseline (--baseline / configured / committed snapshot) → fail on verified-coverage regression |
REQ-04-01-15-, REQ-04-01-16- |
trace freshness |
Trace Engine | active markers → git last-change of marker vs target requirement → possibly-stale findings (ADR-0015) | REQ-03-01-11-* |
report bundle (evidence bundles) |
Report & Export | → Trace Engine (graph) → stable schemas | REQ-03-01-04-, REQ-04-01-12- |
report knowledge (OKF export) |
Report & Export | → Store (scope, lifecycle) → Assembler (expansion) → concept documents | REQ-05-01-15-* |
publish site --lang, render pdf |
Publish & Render Orchestrator | → Assembler → external toolchain (errors forwarded) | REQ-04-01-03-, REQ-04-01-07- |
policy check |
Policy Checker | changed-file list (external) → policy from config | REQ-01-01-07-* |
verify |
Verification Orchestrator | → fmt/lint/scan/coverage/ratchet/freshness via the command interface (ADR-0003) | REQ-04-01-05-* |
mcp serve |
MCP Server | transport adapter over Store operations | REQ-05-01-12-* |
This table is the seed for the component test contracts: every row becomes the owning component's command-level test suite, and every flow becomes an integration-test skeleton.
The command taxonomy behind this table — noun–verb scheme, every analysis exists exactly once (coverage is trace coverage), report reserved for export products, verify as the deliberate top-level exception — is fixed in ADR-0005; this table is the normative command map.
Runtime View¶
Every scenario walks the shared spine — entrypoint → config resolution → feature component → diagnostics → exit code — so only the component-specific middle is described per scenario. Scenarios are documented once their commands ship; the publish scenario follows with its story.
arqix verify — the one-command loop¶
The Verification Orchestrator sequences the configured sub-steps as child invocations of the same binary — it never implements a check itself (ADR-0003, REQ-04-01-05-*).
- Resolve the effective configuration (REQ-00-00-00-06).
- Run
fmt --check,lint run,trace scan, andtrace coveragethrough the stable command interface;--fail-faststops at the first failing step, the default aggregates all of them. - Collect each step's exit code into the per-step report (the
verifywire schema in the ICD). - Exit with the worst channel observed:
0clean,1findings,2when any sub-step ended outside the findings channel.
arqix assemble build — deterministic assembly¶
- Discover the corpus through the Document Store (skip-dirs applied, directory symlinks never followed).
- Map every source document to its output under
pages/; a second source claiming an already-owned output is a structural error (ASM-003). - Expand
<!-- arqix:include … -->depth-first, with the DFS stack as cycle detector (ASM-001) and repository containment enforced on every target (ASM-004, REQ-00-00-00-13). - Write the pages plus one JSONL record per assembly step — doc, chapter_id, out, include, sha256, bytes, at_line (REQ-04-01-01-04/-05).
arqix doc new — template instantiation¶
- Validate the kind as a lowercase slug so it can never escape the configured root as a path component (REQ-00-00-00-13).
- Scan the existing document IDs and derive the next counter deterministically (REQ-00-00-00-04, REQ-01-01-13-01).
- Instantiate the kind's template into the configured location, never overwriting (TPL-001, REQ-00-00-00-08); dates stay
TODOforfinalise(ADR-0004: no ambient clock). - Report id, kind, and path as the creation result (REQ-01-01-13-02).
Planned¶
arqix publish site --lang— per-language root resolution and toolchain orchestration with error forwarding (REQ-04-01-07-*); documented with its story.
Deployment View¶
TODO — to be filled when distribution is set up.
Intended shape: a single statically-built binary installed via cargo install (later: release artefacts per platform); no runtime dependencies except the optional external render toolchain; CI consumes the same binary as developers (REQ-00-00-00-02 keeps behaviour identical across environments).
Crosscutting Concepts¶
Each concept below is a system-wide contract with its own cross-cutting requirement; components implement them via the shared spine (chapter 5).
- Determinism — byte-identical outputs for identical inputs and configuration; stable ordering, no ambient state (REQ-00-00-00-01).
- Corpus traversal — the markdown corpus walk reproduces Python
sorted(dir.rglob('*.md'))byte for byte: each directory level is sorted, directory symlinks are never followed, and*.tpl.mdtemplates are excluded. It is one shared internal helper (src/util.rscollect_markdown, consumed by the store and the publisher); the trace engine and the checkers keep their own walks, and consolidating them is planned refactor work.walkdiris deliberately not adopted (ADR-0014 dependency posture): it would still need the same manual sort, skip-directory, and extension filtering wrapped around it to match the oracle, so it removes almost no code while adding a supply-chain dependency and a silent ordering- or symlink-drift risk. - Diagnostics contract — every diagnostic is available as documented JSON with severity, stable code, message, and source location (REQ-00-00-00-03, REQ-04-01-10-*); coverage gaps use the same shape, and trace outputs are layered with per-layer stability promises (ADR-0006).
- Exit codes —
0success,1findings or gate failure,2usage error; stable across releases (REQ-00-00-00-02, REQ-04-01-08-01). - Effective configuration — one resolution path from
arqix.tomlthrough defaults and overrides;config showrenders exactly what commands act on (REQ-00-00-00-06). - ID and slug policy — deterministic derivation from configured policy, global duplicate detection, stable anchors (REQ-00-00-00-04).
- i18n model — source documents with linked translations; missing, unresolved, and outdated translations are lint findings and CI gates (REQ-00-00-00-10).
- Guardrails — declared change scope via policy files, no overwrites without approval, filesystem containment, no content execution (REQ-00-00-00-07/08/13/14).
- Performance budgets — sub-second search/read and a ten-second verification loop on a 1000-document corpus as calibratable budgets (REQ-00-00-00-11/12).
- Line splitting and frontmatter parsing — four deliberately separate splitter contracts, not one shared splitter (REQ-00-00-00-01, ADR-0004).
The parser's semantic split (
parser::py_splitlines) mirrors Pythonstr.splitlinesover its full boundary set (form feed, NEL, the Unicode line and paragraph separators), so everybody_offset, trace, and lint line number is indexed in that one line space. The rewriter's frontmatter split (rewriter::split_frontmatter) is byte-lossless instead: it breaks only on\nand preserves the exact fence bytes and terminator, sofmtleaves an already-conforming document byte-identical (ADR-0004). The checkers read through their own reference-faithful reader (checkers::shared::read_universal, one shared copy since refactor slice R5), pinned by the mirrored selftest cases now that the Python reference implementations are retired. The assembler'sfrontmatter_line_countstays a fourth local counter overstr::lines(): folding it into the parser'sbody_offsetwould mix two line-index spaces and force a re-parse of the fragment. Consolidating these contracts is deliberately unplanned work: they differ in meaning, not by accident, and a shared splitter would have to serve all four meanings at once. - Checker contract ownership — the Rust engine owns every corpus check: the frontmatter and requirements checkers (
lint frontmatter/lint requirements), the trace engine, the marker gate, and the report units. The executable specification is the test suite: each contract's reference fixtures are mirrored case by case in its test module (selftest_cases_match_the_oracleand its siblings), so a regression against a pinned behaviour failscargo test. The dogfoodedarqix verifyis the authoritative corpus gate: format, lint including the frontmatter/requirements checkers, trace-scan, coverage/ratchet/freshness per the configured[policies.verify], the marker gate, and the strategy-aware report-freshness check. The provenance of each port (the retired Python reference implementations and their conformance suites) is recorded in chapter 11 and the refactor-program plan package.
Architecture Decisions¶
Decisions are kept as ADRs under ../adr/, maintained per the path model with a canonical governance language (REQ-01-01-11-02).
| ADR | Decision | Status |
|---|---|---|
| ADR-0001 | AGENTS.md is the canonical agent instruction document; CLAUDE.md is a thin adapter; extension points carry no normative rules | accepted |
| ADR-0002 | Structurizr DSL is the C4 model source; embedded views are derived Mermaid | accepted |
| ADR-0003 | The verify loop is its own orchestrator component: sequencer over the stable command interface, never a checker | accepted |
| ADR-0004 | finalise lives in the Formatter & Finaliser — the only mutator of existing source documents, mechanical only, with an injected clock | accepted |
| ADR-0005 | Noun–verb command scheme; every analysis exists exactly once (coverage is trace coverage); report reserved for export products; verify as top-level exception |
accepted |
| ADR-0006 | Trace output is layered — canonical core graph, diagnostics projection, audit products — each with its own stability promise; schema_version in every JSON output |
accepted |
| ADR-0007 | One node identity rule: declared document ID, else repository-relative path; file as attribute everywhere; edges reference node ids |
accepted |
| ADR-0008 | Human-facing reports are assemblies of question units — one unit answers one named question; raw model dumps are machine artefacts, never reports | accepted |
| ADR-0009 | Documentation production policy: new documents are units discriminated by section-kind; code→doc links via the documented-by marker; one generator surface (report units); rustdoc as a gated layer; schema_version per interface |
accepted |
| ADR-0010 | Lifecycle vocabularies: declared states carry intent, computed states carry findings; per-nature vocabularies (stories draft→specified→in-implementation→done, requirements active/retired, prose draft→final via finalise), terminal retired; ADR decision-status stays orthogonal |
accepted |
| ADR-0011 | Configuration boundary: a value becomes configuration on double bookkeeping or legitimate per-repository variance, stays convention as tool identity, stability contract, or check substance; one source feeds engine and reference tools, defaults preserve the present | accepted |
| ADR-0012 | ID policy model: declared triples are the source of truth for relations, the ID is an opaque label; per-family patterns govern shape, uniqueness, and generation, named groups activate optional consistency checks; defaults reproduce the current shapes | accepted |
| ADR-0013 | Stitching model: include directives declare heading levels (absolute or relative), the assembler re-levels whole fragments; heading ownership is corpus policy; site splits cut the assembled outline, never fragment boundaries; PDF is always single-page; arqix:chapter retired |
accepted |
| ADR-0014 | MCP transport: mcp serve implements the required protocol subset directly over stdio (blocking JSON-RPC loop, serde_json), no SDK dependency; scripted-session tests own spec conformance; revisit trigger is a requirement beyond the subset (HTTP/SSE, resources, prompts) |
accepted |
| ADR-0015 | Marker freshness by git arithmetic: a marker is possibly-stale when its target requirement was committed after the marker's own file; exposed as trace freshness, informational in verify |
accepted |
| ADR-0016 | Architecture views are generated from workspace.dsl via a containerised renderer (Kroki) into committed SVGs with a regenerate-and-diff freshness gate; the in-process C4-Mermaid checker is withdrawn |
accepted |
| ADR-0017 | Process profiles and the layered ontology: rules stay code, their activation and binding become configuration, vocabulary becomes layered corpus data (reserved core, module vocabularies, project ontology) validated by an ONT meta-rule family; guarded lifecycle stays core, domain status is declared vocabulary | accepted |
| ADR-0018 | Evidence anchors and derived triples: a claim is a body marker above the supported block plus a derived-triples edge that fmt generates from it; position-bound attributes stay on the marker, the edge joins the validated graph; confidence is a declared vocabulary; only claim markers are lifted |
accepted |
Decision records predating the ADR directory live in the planning packages under docs/en/plans/ (ID scheme, canonical-owner model, atomicity, subject conventions).
Quality Requirements¶
TODO — quality tree and concrete scenarios to be elaborated.
Seed: the quality goals of chapter 1 refine into the cross-cutting requirements REQ-00-00-00-01..14; the two measurable performance budgets are REQ-00-00-00-11 (search/read ≤ 1 s @ 1000 documents) and REQ-00-00-00-12 (verify ≤ 10 s @ 1000 documents), both marked calibratable.
Risks and Technical Debt¶
Maintained as implementation proceeds. The Rust core landed in Phase 4 (parser, store, linter, rewriter, trace engine, verify, templates, assembler); the items below track what that left open.
Known at specification time:
- Python/Rust checker drift: closed (chapter 8 — the oracle policy ran its course: oracle until conformance, then retirement).
Every family passed conformance — trace (
cli_tracegreen with the Rust binary, value-equal output on the real corpus), the marker gate, the report units, and the frontmatter/requirements checkers (JSON value-equal) — and the owner retired all five Python scripts directly on 2026-07-15 (task #78), closing the grace period. The drift risk is gone with the second implementation; what guards the contracts now is the Rust test suite, which mirrors the retired oracles' selftest fixtures (selftest_cases_match_the_oracleand siblings), so a regression against the pinned behaviours fails the gate. - Performance budgets have their first real measurements: at ~480 corpus documents (roughly half the 1000-document reference corpus),
arqix verifycompletes in ~5.5s warm against the ten-second budget (REQ-00-00-00-12; the git-history marker-freshness sub-step dominates at ~2.7s) anddoc searchin ~0.15s against the one-second budget (REQ-00-00-00-11). Revisit when the corpus approaches 1000 documents or a budget is exceeded; the freshness sub-step is the first optimization candidate. - The C4 views are rendered from
workspace.dslvia the digest-pinned Kroki image (ADR-0016) and committed undermodel/generated/. Remaining debt: the freshness gate (just render-views-check, the architecture-diagrams workflow) is manual-dispatch only and not yet part of the blocking CI gate; promoting it once the Kroki invocation is confirmed on a runner is open. doc searchis a linear full-text scan in v1 (src/store.rs); no index yet. The one-second budget (REQ-00-00-00-11) may later force an index, which brings state and invalidation questions. Decide with a dedicated search story, after measuring the linear scan on the real corpus.- The assembly log path is a fixed v1 default (
pages/assembly.jsonl); REQ-04-01-01-03 asks for it to be configurable, which lands with the render/publish configuration story in Phase 5. A missing include target is currently left verbatim by the assembler (the linter's LNT-001 is the tool that flags it); folding that signal intoassemble buildis a later refinement. - A future documentation consistency check (drift between the C4 model, the Mermaid views, and the prose) is recorded as an extension path of the verification pipeline (REQ-01-01-11-05); no story schedules it yet.
Glossary¶
First project-specific terms; the full glossary will be scaffolded via arqix doc new glossary with stable IDs (REQ-01-01-12-*) once the tool exists.
For domain vocabulary, the ontology labels under docs/ontology/ remain the controlled vocabulary.
| Term | Definition |
|---|---|
| red skeleton | The complete set of #[ignore]d command-contract tests under tests/cli_*.rs, one group per row of the command-ownership table (chapter 5), created before any implementation. It is simultaneously the implementation backlog (what is still ignored), the progress gauge (requirements referenced by verifies markers), and the done criterion (everything un-ignored and green). The name blends Kent Beck's red–green–refactor cycle with Alistair Cockburn's walking skeleton; the near-collision with the comedian Red Skelton is accidental but mnemonic. |
| red phase | The first step of implementing a story test-first (AGENTS.md, "Test-driven implementation"): un-ignore the story's skeleton tests, refine their bodies and fixtures, run them, and prove they fail. The red output goes into the pull request as evidence that the tests preceded the code and can actually fail. Only then is the behaviour implemented until green. |