mzizi-dev/mzizi and a Rust toolchain; the
compiler has no dependencies.
main dispatches: check, fix,
contract, outline, hash, ir, build, run and harness. Commands that are designed but
not built (mz refs, mz path, mz patch, mz diff, mz test, mz fmt) are not used here.
1. Write and check a component
A component is one.mz file with one component, its props, a view and a contract. Start
from a real one, never from an RFC’s example: the repository’s primitives/ are CI-gated.
primitives/separator.mz with its portal attribute and comments left out; it passed
mz check and mz contract as written.) Then run the loop:
primitives/separator.mz, mz contract printed mz: 0 errors (0 exact-fixable), 3 contract clauses, 0 failed. A contract that fails is a defect to fix in the component, not in the
contract. A contract may constrain only what the component renders, never a declared copy of it.
mz contract checks a component against itself. No component lowers to Rust or renders
yet. Components that ship today are in the registry, installed with mzizi add or
cargo add mzizi-roots; see Mzizi Roots. The registry is the source for
every component, in every format, and a component an app needs that is missing goes upstream
first (Playbook).2. Write a service and run its contract
Aservice declares HTTP routes and handlers (when, header, respond) and a contract of
example and ensure clauses (RFC-0011).
Read examples/registry.mz in full, then write yours in its shape:
mz check and mz contract on 29 October 2026 (4 contract clauses,
0 failed, tested over 25 generated requests). Its first draft said ensure status in 200 404,
and mz contract rejected it: MZ0611, delete "/v1/health" gives status 405, and then
get "//mz-unknown" gives status 308. That is the contract doing its job. The generated
requests include methods and paths you did not list, so an ensure must cover the statuses
the service really returns for them. The full example, run the same day:
ensure clauses are checked over generated requests. That is a test, not a proof.
3. Build a service and run it in a container
mz build lowers a service to a local Rust and axum package. A service binds loopback unless
told otherwise (127.0.0.1), so it is private by default; a container sets HOST=0.0.0.0.
Cargo.toml, fixtures/ and src/main.rs. The generated main.rs, read on
29 October 2026, does what the language changelog says: it reads PORT, then HOST, and exits 1 with
HOST must be an IP address if HOST is not one. The generated Cargo.toml pins its
dependencies exactly (axum, tokio =1.53.3) and carries a [profile.release] with lto,
codegen-units = 1, panic = "abort", strip and overflow-checks.
A container recipe, built from those facts and from tracker row P11:
v0.12.0: its tokio pin was moved for RUSTSEC-2026-0386.
4. Write a program and mz run
A program holds fns, one of them fn main. Programs are checked, lowered to a
dependency-free Rust package, built with Cargo and run.
hello, fib, numbers, control,
errors, collections, records, text), run with mz run, printed exactly its
.expected file. The .expected files are CI’s oracle; add one for any example you add.
A program is where the idioms other languages bring get caught with fixes. Writing x = 2 ** 3
inside fn main gave two diagnostics on this run:
mz fix applied the one exact fix (inserting let) and left the guess for the author,
exiting 1 with one error remaining. An agent reads the say text, rewrites the line, and
re-checks. The program-level paths in the output were shortened here.
A program has expressions, bindings, functions, control flow, numbers, results, text, lists,
maps, sets and records with methods, in a narrow form. It has no modules, standard library or
concurrency, and no generics. The programs page is the reference.
5. Add a diagnostic, with its fix and harness entry
A change to what the language can do is not complete without its harness entry and its tracker row (owner, 7 October 2026). The rules are inCONTRIBUTING.md, “The language harness”, and
RFC-0012 §1.2:
- Name the failure mode the diagnostic removes (an idiom another language brings, a cascade of errors that hides the cause). If it cannot be named, it does not belong.
- Emit the code in
compiler/src, with asaytext that tells the reader what to write, and afixwhoseconfidenceisexactonly when the fix is certain. A fix that needs an operand it does not have is notexact(RFC-0006 §8.2 was corrected on exactly this). - Register it in
compiler/src/harness.rs: oneCodeinCODESwith atriggersource that emits it, and the feature’s entry inFEATURESwith tested examples (including their output, for a program). - Test it:
compiler/tests/harness.rsenforces that every construct and code is registered, and the example’s trigger must fire the code. - Check what an agent will read:
mz harness entry MZ0923prints the entry. ForMZ0923it showed"fixes": ["exact","guess"], the programs that raise it, and its trigger source. - Update
LANGUAGE-TRACKER.mdif a row’s status changes, and add aCHANGELOG.mdentry under## [Unreleased], in the same pull request. - Regenerate the docs table. The
MZ09xxtable on The compiler ismz harness definitionat the commit it names; do not hand-edit it.
CONTRIBUTING.md lists from compiler/: cargo fmt -- --check,
cargo clippy --all-targets -- -D warnings, cargo test, then mz check and mz contract
over every primitive and example.
6. Add an RFC
Anything that changes the surface syntax, the type system, the IR node model, the agent protocol or the public/private test boundary needs an RFC indesign/.
- Take the next free number. Numbers are never reused, and RFC-0005 is reserved. Check open
issues and open pull requests as well as
design/. - File:
design/RFC-NNNN-kebab-case-topic.md, with the H1# RFC-NNNN — <what it settles>. - Header block, three bold fields and a rule: Status (state implementation precisely; there is no “accepted”), Author, Scope (what it settles and what it defers).
- Design against named failure modes and cite them in the headings.
- Use real examples (a component with a reference, or a primitive). Measure any number with a test, and label a prediction as one.
- Record corrections in place: an amendment note on the earlier RFC, and a struck-through, answered open question.
- End with open questions, addressed to the next RFC by number.
- Open the pull request with the implementation in the same branch where you can, and the tracker, harness and changelog updates that go with it.
7. Run a benchmark episode
The runner ismzbench, in the language repository. An episode gives an author (a model or an
agent) one task’s input and asks it to write one file in one arm’s language, with up to five
iterations against that arm’s checker. Pilots 3 and 4 used the agent-driven mode (Mode 2):
benchmarks/runner/README.md; no episode was run for this
page. Rules that come from the pilots’ run records:
- Finish an episode only after its author has reported. Pilot 3 finished one early and had to revert the premature line, and says so.
- Register a
PLAN.mdbefore the first episode (mzbench plan) and do not change it afterwards. Then publish the raw episodes, the run record and every departure. - Say what the run is not. A pilot on public tasks declares no pass or fail. Only a run that applies RFC-0009 §6 on held-out tasks with the ~7B model can test the kill criterion.
- Do not name a model in a docs page. Say “a frontier model” and link the write-up, which names it.
8. File a good issue
The organisation’s issue forms (bug report, feature request) live inmzizi-dev/.github. A good Mzizi issue:
- Names the repository that owns the problem, and the file or command. A language bug goes in
mzizi-dev/mzizi; a component inmzizi-dev/mzizi-registry; a docs error inmzizi-dev/mzizi-docs. - Gives a reproduction that runs: the exact
.mzfile, the command, the output it printed, and what you expected. Say which commit ofmzyou built. - Separates tested from designed: say whether you saw a thing happen, or read it in an RFC.
- For substantial work, holds the goal, the owner’s decisions verbatim, the plan, acceptance
criteria and owner-only steps, so another session or person can pick it up. Every pull
request then references it with
Refs #n. - Never contains a secret, a credential’s status, or exploitable detail on a public repository.
Security reports go to
security@nyuchi.com, not an issue.
The Playbook
Why the project works this way: vision, mission, goals, the kill criterion and the practices.
The compiler
Every
mz command, and the generated diagnostic table.