Machine Interface Control Document
This page assembles the machine-facing interface contract of arqix — the surface a caller, CI gate, or agent programs against — from one unit per interface concern. arc42 explains how the tool is built; this ICD fixes what it exposes and consumes. It cites the deciding ADRs (0003–0006 for the command taxonomy, orchestration, rewriter, and trace/diagnostics contracts) rather than re-deciding them, and composes generated fragments (the Command Reference, the Diagnostics Registry) where those exist.
Sections one to four are the output side (command surface, exit codes, diagnostics, wire schemas); section five is the input side agents author (markers, directives, triples); section six fixes the not-yet-shipped contracts ahead of their code.
Command Surface¶
The interface a caller drives is the command tree.
It follows the noun–verb scheme decided in ADR-0005 (config, doc, unit, fmt, finalise, lint, assemble, trace, report, publish, render, policy, verify, mcp), with verify as the one top-level exception.
The normative command-ownership map is the arc42 chapter-5 table; this section is the machine-interface view of the same surface, defined by the clap tree in src/main.rs.
Every command accepts the global --format {text,json} flag (default text); --format json is the contract for machine consumers.
Only commands whose story has shipped return a stable result; the rest are stubs that exit 70 (see the exit-code contract).
The exhaustive, always-current per-command reference (every subcommand, flag, and argument) is a generated projection of the clap tree — report question Q-11, produced by the single generator surface decided in ADR-0009 — and is composed into the ICD here once that generator ships.
Until then, arqix <command> --help is the authoritative live surface.
Exit Codes¶
The stable exit-code contract (REQ-00-00-00-02, REQ-04-01-08-01) is the first thing a CI gate or agent reads:
| Code | Meaning | Example |
|---|---|---|
0 |
success | a command completed with no findings |
1 |
findings / quality-gate failure | lint run found an error; fmt --check saw an unformatted file; verify had a sub-step with findings |
2 |
usage or system error | an unknown flag; a source-write or scaffold I/O failure; a verify sub-step that itself ended outside the findings channel |
70 |
unimplemented stub | a Phase-5 command whose story has not shipped |
70 sits deliberately outside the stable 0/1/2 range so a stub can never be mistaken for a real result.
Within 2, arqix distinguishes two sub-cases by convention: a usage error (bad arguments, reported by clap) and a system I/O error (fmt/finalise cannot write a source file; doc new/doc init cannot create the target) — both are 2, never the exit-1 findings channel.
The governing code is the dispatcher in src/main.rs (EXIT_UNIMPLEMENTED) and the per-command handlers.
Diagnostics¶
Every command that reports findings emits one shared JSON shape (REQ-00-00-00-03, ADR-0006 layer 2), so a consumer parses one format across the whole tool.
The --format json payload is:
{
"schema_version": 1,
"diagnostics": [
{"severity": "error|warning", "code": "LNT-001", "message": "…",
"file": "docs/…md", "line": 12}
]
}
file and line are present only when a finding has a source location.
The code is a stable, greppable identifier owned by one component.
Stable codes carried today (the authored catalog; it becomes generated once the diagnostic call sites move to typed DTOs — ADR-0009): CFG-001, CFG-002 (config resolver); DOC-001 (document store); LNT-001, LNT-002, LNT-003, LNT-010 (linter); FMT-001 (formatter); FIN-001 (finaliser); TPL-001 (templates); ASM-001, ASM-002, ASM-003 (output collision), ASM-004 (include containment) (assembler); TRC-COV-001, TRC-COV-002, TRC-KIND-001 (trace coverage).
The shared struct lives in src/diag.rs.
The full owner/severity/stability registry is the planned Diagnostics & Exit-Code Registry fragment.
Wire Schemas¶
The machine-readable outputs a consumer parses under --format json.
Every object key is sorted (the JSON is emitted from a sorted map), so byte output is stable for a given input.
doc list—{"schema_version", "documents": [{"id", "title", "kind", "file", "lang"}]}.doc read—{"schema_version", "id", "title", "iri", "kind", "lang", "file", "body"}.doc search—{"schema_version", "query", "hits": [{"id", "file", "line"}]}.trace scan— the graph:{"schema_version", "nodes": [...], "edges": [...]}(ADR-0006 layer 1).trace coverage— coverage by requirement kind withTRC-*diagnostics.trace matrix— CSV, not JSON (ADR-0006 layer 3).verify—{"schema_version", "steps": [{"step", "exit_code", "ok", "informational", "skipped"}], "ok"};informationalmarks a step whose findings do not gate, andskippedmarks a step the profile declared but the context did not run (report-freshness under a non-gating snapshot strategy).assemble build— the assembly logpages/assembly.jsonl, one JSON object per line withdoc,chapter_id,out,include,sha256,bytes,at_line.
schema_version axis (ADR-0009): each interface owns its own version rather than one global number; every contract above currently sits at 1.
The assembly log is the one output that does not yet carry a schema_version field — a follow-up adds it.
When the diagnostic and result payloads move to typed serde DTOs, these shapes become a generated JSON-Schema fragment instead of this authored prose.
Input Grammars¶
The inputs an author — human or AI agent — writes for arqix to read.
These are the contracts agents most need, because agents are the primary authors of markers, directives, and triples.
The parsers live in src/trace.rs (markers), src/linter.rs (include directives, consumed by the assembler), and src/parser.rs (frontmatter triples); the fixture tests in their test modules are the executable specification of the marker and frontmatter grammars.
Trace markers¶
Markers attach a source or test line to a requirement or a document. They are line comments, matched only when the whole comment is the marker:
- In Rust (
.rs):// arqix:implements REQ-XX-YY-ZZ-NNon a code item;// arqix:verifies REQ-XX-YY-ZZ-NNor// arqix:no-requirementon a test function (exactly one of the two — both is an error, TRC-005). // arqix:plans REQ-XX-YY-ZZ-NN— the planned claim without framework skip syntax (US-03-01-10): counts as planned in coverage, never as verified; satisfies the test-marker duty likeverifies.- In Markdown (
.md): the same verbs inside an HTML comment,<!-- arqix:implements REQ-… -->. // arqix:documented-by <unit-iri>(decided in ADR-0009): attaches a code item to the unit that documents it, the inverse of a unit'sdocuments-artefacttriple. The trace engine learns to parse it in the follow-up slice; the grammar is fixed here so agents can author it now.
Assembly directives¶
Composition directives are whole-line HTML comments in a document body:
<!-- arqix:include <path> -->— splice the file at<path>(relative to the including file) in place, expanded depth-first byassemble build. An include cycle is a hard error (ASM-001).<!-- arqix:chapter <n> -->— a human-facing chapter marker that travels with the following include.
The path must be a single token; prose that merely mentions the directive is not matched.
Reference markers¶
A document body can also carry paragraph-level references — the doc-side analogue of a frontmatter references-artefact triple (ADR-0009):
<!-- arqix:references-artefact <arqix-iri> -->— a whole-line HTML comment with a singlearqix:IRI. It emits areferences-artefactedge from the enclosing document to the referenced document, located at the marker's own body line. Place the marker on the line(s) directly above the block it annotates, like a code comment above the code. The target must resolve to a known document (LNT-003). The grammar is designed to extend to any ontology property (<!-- arqix:<property> <iri> -->) as a later generalisation.
Frontmatter triples¶
A document declares ontology edges in its YAML frontmatter triples: list:
object may be inline (object: arqix:…) or a - list item; both are matched with the oracle's whitespace tolerance (any run of spaces after the dash or colon).
Only arqix:-prefixed objects become graph edges; the predicate must be a defined arqix:properties/… (ONT-001) and each object must resolve to a scanned document (ONT-003).
Forward Contracts¶
Two interfaces are named in the command surface but not yet implemented — their commands are stubs that exit 70.
Their wire contract is authored here ahead of the code, so the shape is fixed before it ships and consumers can build against it.
This is deliberate: an interface designed after its callers appear drifts (ADR-0006).
report bundle¶
Produces an evidence bundle for audit and compliance.
The intended contract: a directory (or archive) of the generated question units and trace matrices plus a top-level manifest.json listing each artefact with its path, sha256, and the snapshot commit — a deterministic, self-describing evidence set.
Fixed fields and layout are settled with the report family's story before the command leaves stub state.
mcp serve¶
Exposes search/read/list over the Model Context Protocol on stdio, so an agent host can consume arqix as an MCP server.
The intended contract: the tool set (at least search, read, list) with their parameter and result schemas mapping onto the same doc search/read/list wire shapes (see Wire Schemas), carrying the same schema_version discipline.
The method set is fixed with the MCP story before the command leaves stub state.
Until then, both commands honour the exit-code contract by returning 70, never a 0/1/2 result that a caller could mistake for real output.