Aontu documentation
Rendered from
docs/index.md
in the engine repository — where a correction belongs, and where the
test suite executes every example on this page.
Aontu is a JSON structure unifier: a small language (a purpose-specific dialect inspired by CUE) and an engine that merges partial structures into one consistent result, or reports exactly where they conflict. The same source can describe data, the schema that constrains it, and the defaults that fill it in — all in one notation, all combined by a single operation: unification.
This repository ships two implementations kept in parity:
- TypeScript in
ts/— the canonical implementation, published to npm asaontu. - Go in
go/— a port (github.com/aontu-lang/aontu/go) that mirrors the core semantics.
Both are checked against one language-agnostic test suite in
test/spec/.
How this documentation is organised
The documentation is split by what you are trying to do when you open it. Reach for the part that matches your need:
| If you want to… | Read |
|---|---|
| Learn Aontu from zero by building something, step by step | Tutorial |
| Accomplish a specific task you already have in mind | How-to guides |
| Look up exact syntax, semantics, options, or API surface | Language reference · API reference |
| Understand how and why the engine works the way it does | Explanation |
Tooling:
- The
aontucommand — one binary and eleven verbs, in both implementations.vetvalidates data documents against a schema (and ships wrapped for CI as a GitHub Action);subsumeandbreakinggate schema evolution;getandwhyask an evaluated document what it says and what contributed to it;setchanges one in an overlay, by appending or in place;trimreports redundant entries;relationsruns the declared identity checks andreachesanswers whether one entity reaches another at any remove;jsonschemaexports the model as JSON Schema and names what the export cannot carry;hashpins what a document means;modmaintains a dependency closure;agentsmdwrites the prose stanza for a definition. With no file,aontustarts a REPL. - Language Server (LSP) — the
aontu-lspdiagnostics server (TypeScript and Go), how to wire it into an editor, and the reusable LSP library API. - The MCP server —
aontu-mcp, a Model Context Protocol server over stdio (TypeScript; the Go port offers the same calls as library API) answering with the identical reports the CLI prints.
For agents:
- The Aontu skill — an agent-facing teaching pack:
the grammar card, a
worked example ladder whose documents the test
suite executes, and the error-code index.
The
aontu agentsmdverb generates the matching AGENTS.md stanza. - The published grammar —
grammar/aontu.gbnfandgrammar/aontu.lark, the emission surface for constrained decoding, held by a test to accept every canonical form the shared suite produces.
Contract:
- The trust contract — hermeticity, termination, determinism, and sandboxing: what a host may rely on when evaluating an Aontu document, exactly where each guarantee is conditional today, and the budget/cycle error taxonomy.
Two further documents support the project itself:
- Test coverage — how coverage is measured for both implementations, the current numbers, and where the gaps are.
- Shared test specification — the format of the
cross-language
test/spec/*.tsvsuite.
Design notes (deeper analyses of specific behaviours and known defects)
live in docs/design/:
- Colon-chain nested
@"file"import — a since-resolved Go-port parity defect (fixed upstream in@tabnas/multisource/go) where a colon-chain imported value was dropped. - The number model — how a numeric literal is classified and how kind travels through operators and canon: the pre-tower record, its rounding edges since reversed by the tower’s exactness rule.
- The number tower — implemented:
boru’s four-leaf number structure mirrored (
integer,float,biginteger,bigdecimalunder a pure-supertypenumber), the0dexact literals, thelossy_integer_literalexactness error, and where a unification lattice forces deviations from boru.
The design behind the verb surface lives in
capability-review/: the survey that
asked what Aontu lacked in order to serve as a systems-definition
ground truth for agents, with eight companion design documents (G1–G8)
covering the constraint algebra, the validation verb, subsumption and
schema evolution, identity and relations, the trust contract,
distribution, the machine-facing access surface, and generation. Those
documents argue and specify; what each verb actually does is in the
API reference, and what has
been built phase by phase is recorded in the
progress register.
The project site — aontu.dev, not yet live — is
planned in site/: what it serves, and where each
page’s content comes from (this documentation set is rendered there,
not rewritten). The steps that stand it up outside a session are in
docs/site/manual-tasks.md.
Why the split?
The four kinds of document answer four different questions and are kept separate on purpose. A tutorial holds your hand and is allowed to omit detail; a how-to assumes you know the basics and just need the recipe; a reference is exhaustive and dry so you can trust it as the source of truth; an explanation is discursive and is the only place that argues about trade-offs. Mixing them — a reference that teaches, a tutorial that digresses into design rationale — serves none of those needs well, so each lives in its own file.
The rule applies to the toolkit as much as to the language, which is why a verb can appear in all four without any of them repeating another: met once, in passing, while the tutorial builds something; given as a recipe for one goal in the how-to guides; specified exhaustively — every flag, every exit code — in the API reference; and argued for, never merely listed, in the explanation.
A 30-second taste
# A schema, a default, and data — unified into one result.
port: *8080 | integer
host: string
host: "localhost"
Unifying the three lines above yields:
{ "host": "localhost", "port": 8080 }
The port is constrained to be an integer, defaults to 8080, and —
because nothing overrode the default — 8080 is what comes out. host
is constrained to a string and pinned to "localhost". Conflicting
facts (e.g. a second port: "high", or a port: 1.5) would instead
produce a precise unification error rather than a silent wrong answer:
the preferred branch keeps the kind it names, which is
argued in the explanation.
Try it without writing any code — both implementations ship an aontu
command that evaluates a file or starts a REPL:
echo 'port: *8080 | integer' | node ts/bin/aontu.js # or: go run ./cmd/aontu
Start with the Tutorial.