Your agents write the code. aontu holds the definition.
aontu defines the entities in a software system, their types, and the relations between them. Use it to check changes proposed by a coding agent: a change is admitted or refused, with the source line named when a constraint fails.
Write down what the system is
Define which fields a service needs and what values they allow. Types, defaults, and data use the same notation, so you can write them in one document and check them together.
type() marks spec as schema and keeps it
out of the output. &: $.spec.service applies that
schema to every service, including entries you add later.
tier:*1 supplies a default: api gets 1,
auth specifies 3, and a tier of the wrong kind is refused.
spec: type({ service:{ owner:string tier:*1 } })
services: { &: $.spec.service }
services: api: owner: "platform"
services: auth: { owner:"identity" tier:3 } {
"services": {
"api": { "owner": "platform", "tier": 1 },
"auth": { "owner": "identity", "tier": 3 }
}
} Check relations between services
Add calls, a relation that must stay acyclic, then make
the two services call each other. The document fails to evaluate
because the calls form a cycle. The refusal names the edge,
$.services.api.calls.0, and points to the constraint:
spec: type({ service:{ owner:string tier:*1 calls?:rel() & acyclic() } })
services: { &: $.spec.service }
services: api: { owner:"platform" calls:[path($.services.auth)] }
services: auth: { owner:"identity" calls:[path($.services.api)] } [aontu/relation_cycle]: Cannot relate value at path $.services.api.calls.0
Cannot relate value: path($.services.auth)
--> system.aon:1:52
1 | spec: type({ service:{ owner:string tier:*1 calls?:rel() & acyclic() } })
^ value was: path($.services.auth)
The refusal includes the relation_cycle error code, a
class, and an exit status. A repair loop can use these to decide what
to fix. The error-code reference lists each
class and the action it calls for.
23 verbs for checking and changing a model
Validate data, query a path, explain a value, and check whether a schema change breaks compatibility. The TypeScript and Go command lines are checked against one shared test suite. See the reference for each command's output formats and exit codes.
vet- does this data satisfy the schema?
get- what does it say at a path?
why- why does that value hold, and who set it?
set- change one value in an overlay, or in place
subsume- is this schema a widening of that one?
breaking- which changes break an earlier version?
trim- which entries are redundant?
relations- run the declared identity checks
hash- pin what a document means, not how it is spelled
mod- maintain a dependency closure
agentsmd- write the AGENTS.md stanza for a definition
reaches- is there a path from one entity to another?
view- draw the model: tree, graph, matrix, layers, poset
jsonschema- export the model, and name what the export cannot carry
render- write the files the model says to write
template- read a generator written in the target's own syntax
allow- may this role read that path?
fmt- one agreed form for the source, so layout is never argued about
init- scaffold a model, some data, and the checks that hold them
explain- what does this error code mean?
help- the verbs, and the topics behind them
lsp- the language server, for an editor
mcp- the same reports, over stdio, for an agent
Every flag and exit code is in the
API and CLI reference. With no file,
aontu starts a REPL.
Made to be driven by a program
An agent can retrieve a path, ask which source lines contributed to a value, and propose an edit. The CLI provides these operations, and every page on this site is also available as markdown.
-
Query a path
aontu get $.services.authretrieves one slice;--keyslists what exists;whynames every contribution to a value and the line that wrote it. -
Act on a validation result
vetbranches its exit code (valid, invalid, incomplete, or the definition itself is unusable) so a repair loop knows which thing to fix, and a CI gate knows what to block. -
An MCP server
aontu mcpruns locally over stdio and answers with the identical reports the CLI prints. No hosting, no key, no network. -
A published grammar
GBNF and Lark files ship in the package for constrained decoding, held by a test to accept every canonical form the suite produces, so a model can only emit definitions that parse.
Evaluation limits
aontu has no user-defined functions, clock, or randomness. Evaluation runs within configured budgets. The trust contract states the conditions for termination, deterministic output, and access to files or host values.
Statements combine by unification. Compatible statements narrow the result; contradictory statements produce an error. Adding a statement later does not give it priority over an earlier one.
Install
npm install aontu@0.62.0 go install github.com/aontu-lang/aontu/go/cmd/aontu@latest MIT licensed. Source, issues and the design record are on GitHub.