M12 — Tooling for AI agents (plan and report)
Status: complete 2026-10-26 (results below). The owner asked for "MCP or any better feature AI agents can depend on" and chose all three layers below. Each is specified in tooling.md before it is built, and tested as M10's tools were.
Why
Agents write and fix code in a loop: write, compile, read the errors, change, compile again. Nova's compiler already knows most of what an agent needs. But it says so only as text for people, its spec lives in a repository an agent may not have, and nothing tells a model which mistakes Nova programs most often contain. The layers below make that knowledge available in the forms agents use, in order of how widely each one helps:
- Machine-readable diagnostics with fixes work in any agent harness, MCP or not, and in CI.
- An MCP server (
novac mcp) gives an agent's host Nova's checker, formatter, interpreter, C generator, spec and library documentation as tools and resources, with no repository checkout. llms.txtand an agent guide put the language in a model's context, and list the mistakes models make.
A1 — JSON diagnostics and fixes (tooling.md §5)
--diagnostics-format=json(the namediagnostics.mdplanned) oncheck,build,runandfmt --check: one JSON document on standard output (the program's own output, forrun, goes to standard output only when there are no errors). Each diagnostic has its code, severity, file, a 1-based start and end line and column, the message, its notes with their spans, thedocs/diagnostics.mdrow's text, and its fixes.- Fixes are edits the compiler is sure of: a text range and its replacement, with a title. A fix is offered only when applying it removes that diagnostic and introduces no other at that place, which the tests check for every fix kind on every corpus case that offers it. The first set:
mutbefore an argument for aborrow mutparameter (N0249),lettovarfor a variable that is assigned or mutably borrowed (N0211, N0248),astotruncate<T>(…)for a lossy cast (N0208), and a missing;(N0100 where the parser knows the token). novac fix FILESapplies every fix, re-checks, and repeats until none applies (at most 8 rounds), then prints what remains.--dry-runprints the edits instead.novac explain N0249prints a code's row ofdiagnostics.mdand the spec sections it cites (planned indiagnostics.mdsince M1).- The language server sends the same fixes as code actions (
textDocument/codeAction).
A2 — novac mcp (tooling.md §6)
- The Model Context Protocol over standard input and output: JSON-RPC 2.0, one message per line. Written in the compiler with no new dependencies, as
novac lspis. - Tools. Every tool takes source text (one file or several, by name) or paths, and returns structured content with a schema as well as text:
nova_check: A1's diagnostics, with fixes;nova_fix: the source with every fix applied, and what remains;nova_format: the formatted source, or the error that prevents it;nova_run: run in the interpreter, sandboxed: no files, sockets, processes or environment; a step budget and an output cap; standard input as text; the exit status, output and any panic with its location;nova_emit_c: the generated C, optionally with--explain-allocations,--explain-bounds-checksor--explain-overflow-checksoutput, for either profile;nova_explain: a diagnostic code's row and the spec sections it cites;nova_spec_searchandnova_spec_section: search the specification, and read one section;nova_api: thelib/coreand built-in API for a name;nova_symbol: the type and definition at a position, from the language server's index.
- Resources. The specification (
docs/type-system.md,grammar.md,diagnostics.md,unsafe.md, and the rest of the normative set),docs/api/core.md, and the guide, embedded innovacat build time so the server needs no checkout and always matches the compiler it runs. - Prompts.
write-nova(the agent guide, A3) andport-c-to-nova(the method of C6 and C9).
A3 — llms.txt and the agent guide
site/public/llms.txt(the llms.txt convention): what Nova is and links to the guide and spec pages as Markdown, andllms-full.txt, the guide and the normative spec in one file, generated at site build time.site/guide/for-agents.md: how to set upnovac mcp, the edit-check loop with--diagnostics-format=jsonandnovac fix, and common mistakes, each a wrong program and its correction, compiled bySiteTestslike every guide example, so the page cannot drift from the compiler.
A4 — agent instructions in new packages (tooling.md §7; added 2026-10-26)
The owner asked for novac new to write an agent instructions file, as Vite+'s vp create does. novac new writes AGENTS.md with a Nova section between <!--NOVA START--> and <!--NOVA END--> (from templates/AGENTS.md, embedded in novac); --agent claude|gemini|copilot|cursor adds that agent's file (an import of AGENTS.md where the agent supports one, a copy otherwise) and its MCP configuration for novac mcp; --no-agent writes none. novac agents refreshes the section in an existing package and never changes text outside the markers or an existing MCP configuration. Tests: AgentFilesTests (choice of agents, every file's content, MCP configurations parse, refresh keeps the authors' text, appends without markers, idempotent, every command the section names exists) and CliTests (new with and without agents, usage errors, agents from a subdirectory).
Acceptance
- Each layer: spec, positive and negative tests; the repository's own tests run against it.
- A1: every fix kind applied to every corpus case that offers it removes the diagnostic and adds none; the JSON schema is checked against a snapshot.
- A2: an MCP client test drives
novac mcpthrough initialisation and every tool, including sandbox refusals and the step budget, and checks responses against the protocol's schema for the version negotiated. - A3:
llms.txtlinks resolve on the built site; the agent guide's examples passSiteTests.
Results (run 2026-10-26)
- A1. Fixes are attached where the checker and parser report (
Diagnostic.Fixes):mutbefore an argument (withlet→varin the same fix when the place is aletlocal), a straymutremoved,let→varfor an assigned or mutably borrowed local,truncate<T>(…)for a lossy integeras, and a missing;after a declaration, assignment,returnor call. Each is offered only where the tests show it resolves the diagnostic; two rules were narrowed by them:mutis not offered for a place behind a shared reference (it would be N0248), and;is not offered after a non-call expression statement ({ -1 }would become N0225) or after an earlier error.--diagnostics-format=json,novac fix [--dry-run],novac explain, and quick fixes in the language server. The specification and guide are embedded innovac(Documentation/EmbeddedDocs.cs). Tests:FixTests(every corpus case that offers a fix, 34 fixes of all six kinds; targeted cases; cases where no fix may be offered; the JSON shape; a catalogue row for every code),CliTests(the commands, in process), andLspTests(code actions). - A2.
novac mcp(Tooling/McpServer.cs): versions2025-06-18,2025-03-26and2024-11-05; nine tools, 75 resources, two prompts. The interpreter gained a sandbox (InterpreterOptions.Sandboxed,StepLimit,MemoryLimit): files, sockets and processes are refused, the step budget and memory budget end the run with a fault, and the heap reports out of memory at the memory budget. Tests:McpTests(negotiation, every tool, the sandbox's refusals and limits, resources, prompts, protocol errors). - A3.
site/guide/for-agents.md(set-up, the loop, ten common mistakes, each compiled bySiteTests);llms.txt,llms-full.txtand each page's Markdown, generated bysite/scripts/prepare.mjs; all 39 links ofllms.txtresolve in the built site.
| Criterion | Result |
|---|---|
| A1: every fix kind resolves its diagnostic on every corpus case that offers it | met (FixTests, 34 fixes) |
| A1: the JSON schema | met (FixTests.Json_document_has_the_documented_shape, CliTests) |
| A2: an MCP client test through initialisation and every tool, with the sandbox and the step budget | met (McpTests, 15 tests) |
A3: llms.txt links resolve; the agent guide's examples pass SiteTests | met |
Not done: nova_check and the other tools take files, not a package directory (nova.toml); an agent checks a package's files by listing them. The sandbox bounds what a program can reach and how long it runs; it runs in the server's process, so it is not a boundary against a compiler or interpreter bug (risks.md).