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.aontu:1:54
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.
28 verbs for checking, changing, and sharing a model
Validate data, query a path, explain a value, and check whether a schema change breaks compatibility. Fetch, lock, and publish the packages a model depends on. 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?
model- read one document: a path's value, why it holds, an overlay that changes it
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
sync- resolve the dependencies, lock them, and verify every pin
add- take on a dependency the project does not have
get- add a dependency, or raise its minimum version
remove- drop a dependency, and the vendor tree it held
why- why is this package in the closure?
publish- publish this package, a dry run until you say otherwise
pkg- the remaining package operations, one step at a time
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
template- read a generator written in the target's own syntax
trace- what wrote this line of generated output?
render- write the files a generator answers, or hold them to it
allow- may this role change 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 model 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.73.0 go install github.com/aontu-lang/aontu/go/cmd/aontu@latest MIT licensed. Source, issues and the design record are on GitHub.