aontu

Agent and editor reference

Rendered from docs/reference-agents.md in the engine repository, where a correction belongs, and where the test suite executes every example on this page.

An editor and an agent read a model through the same doors, and there are more of them than the command line. This page is normative for that surface taken as a whole: which doors there are, what each answers, what none of them does, what posture each takes towards @"..." includes, and which implementation carries it.

Each door’s own specification is elsewhere and is linked from the table below. Nothing here repeats a tool list, an option or an exit table: the API reference specifies every verb, the language server specifies the protocol and the library behind it, and the errors reference specifies the exit codes and the codes a report carries.

Contents


The doors

doorreached byanswersspecified in
the verbsaontu <verb>, with --format json where a report is wantedone report a verbcommand-line interface
the embedded APIa library call, in either implementationthe same reports, as values rather than textTypeScript API, Go API
the language serveraontu lsp, or the aontu-lsp binary, over stdiodiagnostics, hover and completion as an editor asks for themthe language server
the tool serveraontu mcp, or the aontu-mcp binary, over stdioa tool for each report it serves, which is a subset of the verbs, under the same JSON contractthe MCP server
the teaching packaontu help <topic>the language, from inside the binary, with no network and no checkoutaontu help
the code indexaontu explain <code>, or --listwhat one refusal means, or every registered code with its classerrors reference
the starting documentsaontu init [dir]a model, an instance of it, and the checks to runaontu init
the prose entrypointaontu agentsmd --write <file>the stanza naming a document’s pin, root keys, shape and commandsaontu agentsmd
the structured-output bridgeaontu jsonschemaa JSON Schema for the document, and the list of what it could not sayaontu jsonschema
the published grammarsthe files in grammar/the emission surface, for a constrained decoder or a highlightergrammar reference
the editor pluginseditors/ for Visual Studio Code, Emacs and Vimthe language server, wired to an editoreditor configuration

A door is a way in, not a tier: the tool server answers with the report the verb prints, and the verb prints what the library returned. One question has one answer whichever door it arrives by, which is the property that makes a transcript in a document and a tool call in an agent the same evidence.

The machine answer

--format json is a per-verb option rather than a global one: fmt, template and agentsmd do not take it, and refuse it by name.

Where a verb does answer JSON it answers one object, and every one of them opens with the same block:

keycarries
aontuverb and version: which verb answered, and the version that answered it

aontu trace --format json is the one exception: it answers its record alone, under trace.

How an answer says whether it holds is one of three shapes. The shape belongs to the verb rather than to the run, so a document that does not hold changes the values and never the keys:

shapethe answer carriesthe verbs
ok and the answer beside itok, with out or recordthe bare entry point, model get, model why
a verdict wordverdict, with the verb’s own fieldsvet, subsume, breaking, relations, reaches, trim, jsonschema, view, render --check, allow
the payload aloneneither: the object is the answerhash, help, explain

A refusal is an answer, and the findings say what was refused. The key they arrive under is the verb’s too:

findings underthe verbs
findingsthe bare entry point, model get, model why, vet, subsume, breaking, relations, allow
errorsreaches
nothing: the verb reports nonetrim, jsonschema, view, render --check, hash, help, explain

A verb that reports no findings says what it could not do in a field of its own instead: view’s loss, jsonschema’s lossy and render --check’s drift.

A caller branches on ok or on verdict rather than parsing prose, and the exit code carries the same answer: the errors reference is normative for it. Each verb’s own section names the fields beside these.

The tool server keeps the same rule at the protocol level: a tool whose document does not hold answers with its own report and isError: false, because the report is the answer. isError is reserved for a call that could not be made at all, such as an unknown tool, a malformed argument, or a file argument the server does not serve.

What none of them does

These hold across every door, and each is the property an integrator needs before wiring one into something that runs unattended:

  • The language server never writes a file. It answers, and the editor owns the buffer.
  • The tool server never writes a file. set answers the new overlay text, and the caller owns the write.
  • init never overwrites. If any member of the trio already stands in the directory it refuses before writing any of them, so a refused run leaves nothing half written.
  • agentsmd --write changes only what lies between its two markers. Everything outside them is left exactly as it was, which is what makes it safe to re-run and safe to point at a file someone else writes prose in.
  • A --check run writes nothing. It compares and exits.
  • Evaluation never reaches the network. A module resolves from local stores only; the package verbs are the only ones that fetch, and they say so by name.

Includes, by door

@"..." reads a file while a document is evaluated, so every door that evaluates a document a caller supplied has a posture towards it. The postures are the trust contract; this is which door takes which by default.

doordefaulthow it is set
the verbssystem: an include reads what the process can read--trust none, --trust root[:dir], or --include-root <dir>, on every verb that reads a document; help, explain and init read none and refuse them, and lsp takes no arguments at all
the embedded APIwhatever the caller passes, and system where it passes nothingthe trust option of the call
the language serverconfined below the workspace folder the client named, and system where the client named noneinitializationOptions.aontu.trust.include: system, none, a root, or an in-memory map
the tool servernone: every include is denied--root <dir>, which confines includes below the resolved root and serves the path arguments of every tool

A server that evaluates source from a caller is exactly the place an unconfined include is a mistake, which is why the tool server denies them until a root says otherwise, and why a path argument is refused until then too.

The teaching topics

aontu help lists what the binary carries, and aontu help <topic> prints one. Each is staged into both implementations at build time from its source, and both suites hold the staged copy to that source byte for byte, so the answer travels with the binary rather than with a checkout.

topicwhat it carries
tasksthe job-to-verb index: which verb answers the question you have
languagethe grammar card: everything the language spells, on one page
examplesthe ladder, from plain JSON upward, one addition at a time
codeswhat a refusal means, and what to do about it
grammarthe published ABNF, for a parser or a constrained decoder

aontu help with no topic lists them, aontu --help documents the verbs and their flags, and --format json answers either as an object.

Which implementation has it

doorTypeScriptGo
the verbsyesyes, less the tool server
the embedded APIyesyes
the language serveryesyes
the tool serveryesno: aontu mcp says so and exits 2
the teaching packyesyes, from a committed copy of the staged pack
the code indexyesyes
the starting documentsyesyes
the prose entrypointyesyes
the structured-output bridgeyesyes
the published grammarsshared: the files are the distribution’s, not a port’sshared
the editor pluginseither binary serves themeither binary serves them

The tool server is the one door with no Go half. Its role there is the embedded API, which carries the same calls.