Skip to main content
mz is the Phase 0 front end: lex → parse → lower → IR. It is a single Rust binary with no dependencies at all, which is a deliberate house convention rather than an oversight — a compiler whose check loop must stay sub-second on a modest laptop should not start life with a dependency tree to build first, and the small things it needs (JSON emission, SHA-256) are fully specified and therefore hand-rollable with verifiable correctness.

Getting it

There is no release, no published crate, and no installer. The crate is version = "0.0.0" with publish = false.

The four commands

With no command given, the first positional argument is treated as a file and check is assumed.
Documented elsewhere, not implemented here. RFC-0001 §4.3 describes mz fix applying every exact fix in one shot, and RFC-0003 §5 lists mz refs, mz path, mz patch and mz diff under “designed here, next in implementation order”. The binary dispatches exactly the commands in the table above.

Exit status is a contract

So the loop can branch on status without parsing output:

mz check --agent: the protocol

This is the surface an agent should use. RFC-0001 §4 states it as a versioned contract, and four properties define it.
1

Whole-program, all at once, deterministic order

Statement-per-line plus end-anchored blocks let the parser resynchronise at every line. The recovery target is at most one diagnostic per true author error — never a cascade, and never “fix one to see the next”. That is the direct answer to FM-5: a compiler that stops at the first parse error turns one mistake into five agent turns.
2

NDJSON, one diagnostic per line

Each line is a complete JSON object carrying code, severity, file, span as [start_line, start_col, end_line, end_col], say, and an optional fix.
3

say is written for a reader with zero file context

It quotes the offending source inline, so the agent needn’t re-read the file to understand the error. The stated target is ≤ 200 characters — density is the budget.
4

Fixes are data

Every diagnostic carries a machine-applicable fix when one is unambiguous, tagged exact, guess or none. The intent is that mz fix applies all exact fixes in one shot, deleting a whole class of mechanical error from the loop.
The shape RFC-0001 specifies:
The emitter in compiler/src/diagnostic.rs writes the same fields with severity added and confidence nested inside the fix object:
Every run ends with a summary line, so a consumer always has a terminator:
The human-readable mode ends with the same information as prose: mz: 3 errors (2 exact-fixable), 480ms.

Diagnostic codes

Codes are grouped by phase, and the ranges are stable: Two are worth quoting because they show what the messages are trying to be. MZ0402, when something that cannot start a view line does:
It names the whole set of valid continuations rather than only what was wrong — the Elm-derived expected-vs-found discipline RFC-0002 §3 names as the most valuable borrow in compiler-error UX, on the grounds that a small model cannot infer from an indirect hint. And MZ0501, which is a warning rather than an error, and is how RFC-0001 §1.6’s rule (“a component without a contract block compiles with a warning”) is actually enforced:
The end-echo diagnostics (MZ0206–MZ0208) are the payoff for the name echo: they can say which block on which line an end actually closes, and hand back the exact text to write instead.

mz outline: the representation for dependencies

When editing component A that uses B, an agent needs B’s interface, not B’s body. Reading the file gets both, plus comments and unrelated functions — RFC-0003’s barrier RB-2. The outline carries: the first doc line, the component name, declared capabilities, every prop with its type and default, every enum with its variant names only, the names of fn declarations, and a marker for whether a contract exists. It drops variant column data, view bodies and function bodies — which is where the bulk of a component’s bytes are. It is emitted as valid Mzizi, deliberately: a reader who can read the language can already read this, so there is no second format to learn and no second parser to keep in step. Measured over the nine primitives plus the corpus example, the worst case is 38% of source (spinner.mz); the test in compiler/tests/ir_measured.rs fails above 75%.

Compile speed is a protocol property

RFC-0001 §4.6 makes this explicit: “A slow compiler fails Phase 0 no matter how good its errors are.” The stated budget is sub-second incremental for a single-component change, and the benchmark is specified to record it per iteration. What has been measured so far is much narrower: parse and lower of all ten .mz files in the repository takes ~4.3 ms against a 400 ms test budget. That is a floor on a tiny corpus, not the incremental-compile figure the charter asks for. See Status.