Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Roadmap

Status: Era 1 (M1–M3) is complete. This document answers one question — what comes next, and why in this order.

It stopped being a build diary on 2026-09-21. Roughly 900 lines of completed M1a–M1f increment narrative were removed: every accepted/rejected table, every status section, every derivation of a rule that had already landed. Nothing was lost that is not preserved better elsewhere — the semantics went to spec.md, the evidence to bootstrap.md and releases/4fb1554.md, the current status to capability-matrix.md, and the narrative to Git. Two rules that other files were citing this file for — where a loop target binds, and why native recursion is refused rather than counted — were normative, so they moved to spec.md where a reader would look for them.

Ambition beyond the next few milestones is NAZM_LANGUAGE_GOALS.md. The invariants that constrain any ordering are master-architecture.md.


Where the line is today

nazm runThe interpreter. The widest subset
nazm buildNative, through Core IR, MIR and LIR, by LLVM or Cranelift
compiler/*.nzA compiler for Nazm written in Nazm, reaching a C2 ≡ C3 fixpoint; all 21 parity probes as the reference builds them (N102), and narrower than the language — limitations.md

Ask nazm capabilities --json for construct-level truth; it is read from the compiler’s own tables. Ask capability-matrix.md for architectural truth, area by area.

What Era 1 delivered

MilestoneOutcomeEvidence
M1 — native vertical sliceInt/Bool/Str/Ints/Strs, all control flow, calls, one IR level, LLVM text → clangcapability-matrix.md areas 10–11; 127 two-oracle tests
M2 — facilities for a compilerText, sequences, I/O, modulesbootstrap.md §1
M3 — bootstrapC1 → C2 → C3, byte-identical in IR and executablebootstrap.md §3
Concurrency C-1…C-3Specified first, then interpreted, then compiled, then compiled by the Nazm compilercapability-matrix.md area 14
AI-native (a)Versioned schemas, a checked grammar, a generated guide, a canonical formatter, machine-applicable fixescapability-matrix.md areas 22–24
ReleaseOne experimental candidate, contained, manifest-verified twicereleases/4fb1554.md

What M2 bypassed rather than delivered

This matters more than what it delivered, because it is where the next decisions come from. M2’s first, third and fourth rows — value/copy/move semantics with cleanup, records and tagged unions with exhaustive matching, and generics — were never built. The compiler was written around them, with parallel Ints/Strs arrays addressed by index. That was the shortest sound path to a bootstrap and it worked; it also means the type system has never been asked the questions that make type systems hard, and that the memory model is still the one bootstrap.md §1 states: allocate, never free.


What comes next, and why in this order

The ordering rule is master-architecture.md §3: a layer earns its existence by owning a semantic responsibility no existing layer owns. Matching the aspirational IR diagram is not such a reason. By that test the next step is not the next box in the diagram — it is the one place where a responsibility is currently owned twice.

N1 — Source identity, and one resolution result · complete, 2026-09-21

Done, in four slices (0045ed9, 26a52bd, ea016c3):

N1ASpan is { file, start, end } with file-local offsets; SourceMap replaces the merged buffer; each file is parsed on its own text. The published diagnostic shape is unchanged
N1COne built-in inventory. nazm-lir’s 31-variant enum and its by_name/name tables are gone; Builtin is nazm_syntax::Intrinsic. Type and Intrinsic moved to nazm-syntax so the backend can see them without reaching the interpreter
N1Bnazm_core::check produces a nazm_syntax::Resolution; the backend reads it. Deleted from nazm-lir: resolve, bind, scoped, the scope stack, the name-keyed signature table, the declared-names set, native_ty, and the built-in-first rule at the call and spawn sites
N1DA cargo xtask check rule fails if nazm-lir declares a name-keyed table; eleven tests run resolution-sensitive programs both ways and require one answer

The acceptance test was met: one of the two resolvers no longer exists. crates/nazm-lir/src declares no symbol table keyed by a name and performs no name lookup.

No new crate. The shared vocabulary went into nazm-syntax, which both consumers already depend on; the resolver did not move, the duplicate was deleted. architecture.md §7.1 records why a nazm-hir holding a copy of the checker’s answer would have been the pass-through the ordering rule exists to prevent.

What N1 deliberately did not do: no HIR, no Core IR, no MIR — a resolution is not an IR — no ownership, effects, capabilities, generics, visibility, separate or incremental compilation, and no content-addressed identity. Every id it produces is session-local.

N2 — Compilation units, visibility and module interfaces · complete, 2026-09-22

Done, in two commits (ae77034 the semantics, 871f09e the implementation), after a separate correction (72019e2) that removed a lossy Serialize from Span.

N2Aspec.md settles it: one module is one file; top-level definitions are private and pub exports; use makes a module’s exported interface nameable, unqualified; imports are not transitive; every collision is a diagnostic naming both sides; cycles stay legal; the root module owns main. Grammar gains [ visibility ], one bit, one spelling
N2BModuleId and a ModuleGraph the driver builds while loading — a graph, not an ordered bag of files. nazm-sema is created, and earns it: nazm-syntax’s lexer, parser, formatter and AST referred to types, intrinsic and resolve exactly zero times
N2C/D/Edeclare_unit reads one module’s declarations and returns its UnitInterface; check_unit checks its bodies against its own definitions and its dependencies’ interfaces. check is a loop over the two and holds no resolution of its own
N2FDeleted: the checker’s program-wide name table, the evaluator’s HashMap<String, usize> and its private copy of the built-in-first rule, and the backend’s last two name lookups. 80 of the self-hosted compiler’s 215 functions became pub; 135 stayed private

The acceptance test was met. crates/nazm-core/tests/unit_checking.rs checks a module against an interface for a module whose source does not exist — no tree, no body, nothing to parse — and refuses the same module when that interface is empty. A dependency’s bodies are not a parameter of check_unit and are not reachable from one.

What N2 deliberately did not do: nothing is separately compiled. Lowering still takes the whole program and emits one LLVM module; there are no per-module artefacts, no cached interfaces and no linker symbols. Every id remains session-local. No packages, no re-export, no aliasing, no qualified paths, no HIR.

N3 — Durable identity and persisted interfaces · complete, 2026-09-22

Done, in one commit after a separate constitution commit (40b1c9a the semantics).

N3Aspec.md settles what makes this the same module and the same definition, before any representation. A source root — the root module’s directory, derived not declared. ModuleKey is the normalised path relative to it; DefKey is that plus a kind and a name. A body edit, a signature edit, a visibility change and a move all keep the key; a rename does not
N3BModuleKey/DefKey in nazm-sema, beside the session ids rather than replacing them. The loader computes them and withdraws one where the two compiler implementations could disagree
N3Cnazm-iface: nazm.interface/1, deterministic, validated on read. serde lives there and not in nazm-sema, so a session-local id cannot be serialised by accident
N3DInterfaceHash — BLAKE3 over the canonical bytes. Twelve invalidation rows measured rather than asserted
N3Enazm interface FILE, so the boundary is real: two processes, two directories, and a dependent checked with its dependency’s source deleted
N3FA sema purity gate, verified to fire both ways; five identity mutations, all caught

The symlink policy is the part that was settled rather than coded around. The reference loader keys by canonical path and the Nazm-written one by normalised text, so an aliased file is one module to the first and two to the second. Durable identity declines where they could disagree, and so does a path that escapes the source root. Both compile exactly as before; they simply get no key, and everything built on one refuses rather than guesses.

What N3 is not. No cache, no store, no query engine, no scheduler, no artefact reuse, and no claim that anything is faster. InterfaceHash answers must this module’s dependents be re-checked and excludes bodies by design — using it as a codegen cache key would hand back an object file compiled from a body that has since changed, which is why architecture.md §7.3 names an implementation fingerprint and a BuildKey it is not.

N4 — Sound incremental semantic reuse · complete, 2026-09-22

Done, in two commits (2565419 the keys and the store, 7b44b4f the root and the reuse).

N4AA declared source root, which had to come first: under a derived one a module’s key depends on which file the compilation began at, so two compilations of one project never share anything. nazm.root is an empty marker — enforced empty, because the first field it carried would make it a manifest — and --source-root DIR names one without writing a file. With neither, nothing changes
N4Bnazm-cache: SourceFingerprint over the exact source bytes with no normalisation at all, CheckerIdentity deriving the built-in table, the type set and both schemas with an explicit SEMANTIC_EPOCH for what cannot be derived, and CheckKey over both plus each direct import’s (ModuleKey, InterfaceHash). Every input tested by removing it
N4Cnazm.check/1 and a local store. Content-addressed, so entries are immutable and two compilers need no lock; published by rename; validated on read by recomputing the key from the inputs the entry records. Sixteen ways of damaging one, every one a miss
N4DOne hook in nazm-core, Reuse. check_unit is still the only thing that decides what a body means; the driver only says which bodies it needs decided. Only a clean check is written, so no entry is ever a cached refusal
N4E--no-cache, --cache-report (one nazm.check-report/1 object, off by default), NAZM_CACHE_DIR. The store’s location is not part of any identity
N4FA cache soundness gate, proved by breaking it three ways; six mutations; twenty-nine end-to-end tests, all of them running the binary

The acceptance test was met, three times. A private body change re-checks its own module and leaves its importer alone. An exported signature change re-checks the importer and finds the error it now has. In A → B → C, a change to C that forces B to re-check but leaves B’s interface unchanged stops at B — which is the difference between interface-driven invalidation and a reachability sweep, and the reason the design is worth the keys.

What N4 is not, and does not claim. Incremental native compilation. What is reused is the second stage of checking one module — its bodies. Every module is still read, parsed and declared from source on every run, which is exactly what makes a skipped module invisible. nazm run and nazm build reuse nothing, because both need the resolution that only checking a body produces, and lowering is still whole-program. There is no object, IR or LIR cache, no query database, no scheduler and no eviction policy.

N5 — Separate code generation and internal linking · complete, 2026-09-22

Done, in three commits (0bf58be a preflight correction, 41e0536 the symbol constitution, d303571 the split).

N5AA native symbol is a spelling of the definition’s DefKey, not a position in a whole-program numbering. The encoding escapes every byte outside [A-Za-z0-9] including _, so it is injective and collisions are impossible by construction — no digest, no truncation, no probability. pub chooses linkage and never spelling
N5BLowering splits into a global plan — signature admissibility and the recursion refusal, both of which span modules — and lower_module, which reads one module’s bodies and every function’s signature. No new IR
N5Cemit_unit per module. A call across a boundary is a declare and a linker reference; a unit contains no other module’s body and has no route to one
N5DRuntime and platform entry in artefacts of their own, defined once. Constants needed no qualification: private linkage makes them local labels, established by linking two objects that both define @.s0
N5Eclang -c per artefact, then a link. Deterministic input order, a working directory this build created and removes, and nothing else touched
N5FA native identity gate, proved by breaking it three ways; five mutations; sixteen end-to-end cases; clean-build cost measured against the previous commit

The acceptance tests were met. Three modules each define a private helper and all three compile; a diamond generates the shared module once; a legal import cycle links; a cross-module call cycle is still refused; an imported main is not the process entry; two checkouts and two entry points give one library identical symbols.

A preflight found a live defect and fixed it first. Every native runtime failure named the file nazm build was invoked on, so a division by zero in lib.nz printed main.nz with lib.nz’s line and column — a location that points somewhere real and wrong. The interpreter had been right all along and no assertion compared the two.

What N5 answered that N4 had assumed. A’s object names B in one declare and one call. Changing B’s body, adding a private definition, or adding an export A does not call leave A’s artefact byte-identical — so an object depends on its dependencies’ symbol identity and ABI signature, not their implementations. N4’s report said otherwise; it was reasoning ahead of an architecture that did not exist yet.

What N5 is not. A cache. Every module is regenerated on every build, and the clean build is roughly twice as slow for a small program — almost entirely clang process startup, which performance.md measures rather than hides.

After N5, in dependency order

Depends onWhy not before
A persistable unit interfacedurable identity ✓done — N3
A key independent of which file was nameda declared source root ✓done — N4
Semantic check reusethat, plus a key covering every checking input ✓done — N4
Separate code generationunits ✓ + a linking model ✓done — N5
Native artefact reuseseparate code generation ✓ + a key over the backend’s input ✓done — N6
Content-addressed compilationreuse ✓ + a normalised form of a definitionnothing normalises or hashes a definition — research-register.md R2
A language serverunits ✓ + durable identity ✓ + reuse ✓ + a lossless CSTit would re-implement the semantic engine otherwise
Ownership / the surface memory model—the largest open design question; research-register.md R1
Effectsa typed core IRand “is divergence an effect?” is unanswered — spec.md Open
Capabilities, information floweffectsarchitecture.md §5 keeps the three separate

N6 — Content-addressed native object reuse · complete, 2026-09-22

An emitted LLVM unit whose object was compiled before is not compiled again. architecture.md §7.6 owns the design; this is what shipped and in what order.

preflightA generated artefact names a module by its durable identity. Two strings used to carry the path the command line spelled — the source_filename and every runtime failure’s location — so one project built from two directories was two programs. Without this there is no reuse between checkouts and no honest failure message
N6AObjectKey over three things and nothing else: a digest of the exact bytes handed to the object compiler, that compiler’s identity, and the configuration it resolves. A store beside the semantic one under a shared .nazm/ root, one file per entry, validated six ways before it is believed
N6B–DOne clang -### per build reads what the driver says it will actually run, so the triple, the CPU features, the relocation model and the ABI are in the key without anyone enumerating them. The invocation is hermetic: an environment built from nothing plus ten named variables. Module, runtime and entry units all go through one key and one store. --no-cache, --build-report, nazm.build-report/1
N6EAn object cache gate, proved by breaking each of its rules; six mutations, three of which attack the key and three the validation; forty end-to-end and store-level cases
N6FMeasurement, and the authorities

What the key is, and what it is not. Not a second dependency graph — not the module’s source, not each dependency’s exported signatures, not an emitter epoch. Every one of those is an approximation of what clang -c reads, and every approximation leaves something out. The emitted IR is the input, so N5’s measured precision falls out rather than being encoded: a dependency’s body change and an export the caller never calls each leave the caller’s object alone, and a called signature change does not, because it is written into the caller’s own declare.

What a warm store cannot do. Bypass anything. A key is a digest of an artefact, so the artefact must exist before the key does, so the reading, parsing, checking, backend admissibility, lowering and emission have all already happened — including the whole-program recursion refusal, which a fully warm store never reaches.

Measured. On the five-module compiler: -O0 665.4 ms with --no-cache, 730.7 ms cold, 157.6 ms warm; -O2 1693.0 ms, 1755.4 ms, 157.6 ms. A one-module edit costs 198–218 ms whether it is a private body, a called export’s body or an export nobody calls — the three are indistinguishable, which is the whole point. A warm build runs two external processes where a cache-disabled one runs eight.

What N6 is not. Incremental native compilation. Lowering and emission run every time and so does the link; there is no executable cache, no LinkKey, no incremental linker, no persistent LIR, no LTO. Nothing is evicted, so the store grows until it is deleted.

N7 — Memory constitution and the first reclamation — complete, 2026-09-22

The cache ladder stopped here on purpose. architecture.md §7.7 owns the design and the evidence; spec.md’s memory constitution owns the law.

preflightA mutation verdict is measured the way the suite is authoritative — one job, one test thread. nproc reports 10 inside a container limited to one CPU, and the suite has wall-clock deadlines, so verdicts were a function of scheduling. The dangerous direction was never the one that was noticed: a spurious failure while measuring a mutant counts as CAUGHT and is invisible
N7AThe audit. Every type across both implementations, every allocation site, the leak measured, and compiler/*.nz counted
N7B–CFive models compared against real Nazm code; the constitution settled in spec.md before anything was implemented
N7DReference counting on the sequence header. Reclamation on the three exit edges of a generated function, and the same rule modelled in the interpreter rather than inherited from the host
N7ESixteen cases, each run twice and compared; six mutations
N7FMeasurement, and the authorities

What the audit changed. Two findings moved the design before a line was written. A Str has four provenances and does not say which — a literal’s constant, argv, a heap buffer, or the interior of any of them, because str_slice is specified not to allocate — so free is wrong for three of the four. And the specification’s Str value semantics are currently paid for with the leak. Str is therefore out of the slice, in the specification’s own words.

What did not change. Any program’s meaning. let b = a; still aliases a sequence, a push through one is still visible through the other, a parameter is still borrowed. A model that had to break that to be implementable would have been the wrong model.

Measured. 5,000 / 20,000 / 80,000 short-lived sequences: 4.38 / 12.28 / 43.52 MiB before, 1.78 / 1.88 / 1.86 MiB after. Flat in work where it was linear. A genuinely live sequence and a string-heavy loop are both unchanged.

After N7, in dependency order

Depends onWhy not before
Reclaiming Ints and Strsa memory constitution ✓done — N7
Reclaiming Stra representation that records provenancedone — N8. Four provenances, one of them an interior pointer, answered by a third field naming the owner
Reclaiming Chana rule for a value whose lifetime is a scope’s and whose holders are tasksdone — N8. The count is atomic, because it does cross; a waiter implies a live reference, which is what makes rc == 0 sufficient
Reclamation in the self-hosted backendthe above, and a migrationdone — N8. No source change was needed; the runtime is derived from the Rust emitter’s and a gate refuses drift
User-defined recordsa decision this milestone deliberately did not makeresearch-register.md R1, re-scoped: value semantics are a live question for a kind of value with no existing meaning to break
Ownership cyclesa recursive type existing at allimpossible today: no value can refer to another that can refer back

N8 — Complete current heap reclamation — complete, 2026-09-22

Every heap-backed type the language has is reclaimed, in the reference interpreter, in the Rust compiler’s output, and in the output of the compiler written in Nazm.

N8A–CThe Str backing model — { pointer, length, owner }, four origins classified rather than guessed at — string and channel reclamation, container element ownership, task-boundary ownership, and four runtime leaks that were nobody’s feature
N8Dcompiler/emit.nz migrated. Its runtime is derived from the Rust emitter’s rather than transcribed, with a gate; its decisions are held by a differential memory test
N8ENine mutations, and the scaling measurements
N8FThe authorities

The number that says what it was for: the accumulator shape from the 2026-09-21 incident, at 8,000 iterations, fell from 70.66 MiB to 2.23 MiB. 80,000 temporary strings against a constant live set: 4.17 MiB → 1.77 MiB. 2,000 short-lived channels: 2.38 MiB → 1.80 MiB. Sequences, a genuinely live sequence and a sieve are unchanged, which is the control. The cost is about 13–16 ns per string operation and nothing measurable elsewhere.

compiler/*.nz needed no source change, which was the test of whether the constitution is as ergonomic as it claims: memory semantics are transparent, and a milestone that had required manual lifetime management in the compiler’s own source would have been evidence against the design rather than for it.

After N8, in dependency order

Depends onWhy not before
User-defined recordsa decision about value semantics for a kind of value with no existing meaning to breakdone — N9. Value semantics, composed field by field; cycles refused as an impossible layout rather than admitted with a policy
Variants, pattern matching, Option, Resultrecords ✓the shape of a payload is a record’s question first, and it has been answered
Genericsrecords ✓ and variantsnothing to be generic over yet
A lossless CSTnothing in this listthe last AI-native item, and independent of all of it
nazm explain-costthe cost table in spec.md ✓the model is documented; the tool is not written, and is not urgent

After N9, in dependency order

Depends onWhy not before
Variants and pattern matchingrecords ✓done — N10. A discriminant, an exhaustiveness rule and a binding form, and copy and release that act on the active variant alone
Generic containersrecords ✓ and variantsa Vec<Record> is where value semantics usually start to hurt, and it is also what would make a reference cycle expressible again — at which point spec.md’s Cycles has to be satisfied a second time
Copy elision, specifiedrecords ✓research-register.md R1’s original sharp question, still unanswered: a record copy costs one reference adjustment per owning field, and nothing says when the compiler may remove the pair
A lossless CSTnothing aboveunchanged; still independent, still the last AI-native item

After N10, in dependency order

Depends onWhy not before
Generic containersrecords ✓ and variants ✓Vec[T] is now named by two findings rather than argued for: it is what the self-hosted compiler needs before an enum can replace a tagged integer, and it is where value semantics usually start to hurt. It is also what would make a reference cycle expressible again, at which point spec.md’s Cycles has to be satisfied a second time
Option, Result, typed errorsgenericsexpressible monomorphically today — enum MaybeInt { None, Some(value: Int), } — which is the evidence the kernel is ready and also the reason not to bless a built-in one before it can be written once
Copy elision, specifiedrecords ✓ and variants ✓R1’s original sharp question, still unanswered, and now slightly larger: a copy costs one reference adjustment per owning field and, for an enum, a branch as well. Nothing says when either may be removed
A wildcard arm and non_exhaustivevariants ✓deliberately absent. Adding a variant should break importers while the language is young; when it should stop doing that is a design decision, not an omission to fix
A lossless CSTnothing aboveunchanged; still independent, still the last AI-native item

After N11, in dependency order

Depends onWhy not before
Result, Option and typed error propagationgenerics ✓expressible now as ordinary generic enums, which is the evidence the kernel is ready. What is missing is not the type but the decisions around it: where a standard definition lives when there is no standard library, whether ?-style propagation is syntax, and what a failure is when N0405 already stops the program. N11 deliberately left all three alone
Traits, or any constraint on Tgenerics ✓a generic body can do only what every type can, which is the honest limit of N11. A constraint system is a large decision about dispatch, coherence and orphan rules and should be forced by a program that needs == or ordering on T, not by symmetry
Copy elision, specifiedrecords ✓, variants ✓, generics ✓R1’s sharp question is larger again: a Vec of records copies each element on vec_get, by T’s law, and nothing says when the pair may be removed
A compact enum representationvariants ✓, Vec[T] ✓an enum is one slot per variant, and a Vec[Enum] multiplies that by its length. performance.md measures the pressure; nothing here claims it is acceptable at scale
A lossless CSTnothing aboveunchanged; still independent, still the last AI-native item

After N12, in dependency order

Depends onWhy not before
Blocks as values in nazm build, and derived equality on records and enumsrecords ✓, variants ✓the two walls both dogfoods hit. N11 could not turn the compiler’s integer tags into an enum because an enum has no ==; N12 could not turn a single -1 sentinel into an Option because a match arm cannot be a block in the native subset, so the only spelling converts straight back to the sentinel. The interpreter already has blocks as values; the native backends refuse them, which is also why an explicit early return from an arm is written if true { return … } else { return … } there
? on Option, and conversion between error typestraitsboth need a protocol — a carrier ? can dispatch on, a conversion it can call — and a protocol is a trait. N12 refused both rather than special-case them
Traits, or any constraint on Tgenerics ✓unchanged: a constraint system is a large decision and should be forced by a program that needs == or ordering on T. Derived equality on concrete types is the smaller step that does not need one
Mapping a typed error to a process statusResult ✓main still returns Int. Letting it return a Result is a contract with the operating system, not a type rule, and nothing has needed it yet
A compact enum representationvariants ✓, Vec[T] ✓Option[Str] and every Result are now common, and each is one slot per variant; performance.md measures them
Copy elision, specifiedrecords ✓, variants ✓, generics ✓unchanged, and ? adds one retain/release pair per success it passes through
A lossless CSTnothing aboveunchanged; still independent

N12.1 took the first half of the first row. Blocks as values compile natively in both compilers, and the -1 sentinel became an Option. Derived equality is what is left of it.

After N12.1, in dependency order

Depends onWhy not before
Derived equality on records and enumsrecords ✓, variants ✓the wall N11’s dogfood hit and N12.1’s did not remove: the compiler’s node kinds, token kinds and frame kinds are integers compared with == or != at 463 sites in compiler/*.nz (kind == n_block()), and an enum cannot replace them while it has no ==. Rewriting every comparison as a match would be the workaround this milestone refused. Needs no trait: equality on a concrete nominal type, derived from its fields as copy and release already are
? on Option, and conversion between error typestraitsunchanged
Traits, or any constraint on Tgenerics ✓unchanged
Mapping a typed error to a process statusResult ✓unchanged
A compact enum representationvariants ✓, Vec[T] ✓unchanged; Option[Int] now appears inside the compiler too
Copy elision, specifiedrecords ✓, variants ✓, generics ✓unchanged
A lossless CSTnothing aboveunchanged; still independent

After N48: the v1 foundation, and what is deliberately after it

N40–N48 complete the v1 foundation; docs/limitations.md is the one list of what it does not do. What follows is not started and is bounded here so it is not mistaken for v1 scope:

Post-v1 workDepends onWhy not in v1
Function values, closures, traitsa calling convention for captureschanges the language; every layer below would move — N50
Effect polymorphism, attenuation and revocation of capabilitiesfunction values; a capability with a type argumentthe coarse kinds are what N37 settled
Richer information flow: more sinks, declassificationN38’s frameworkone sink was enough to make the framework real
More targets and cross-compilationa foreign linker and runtime per targetthe host is the only verified one
A suspendable-task scheduler (M:N)stack switching or compiled continuationsa worker pool would deadlock blocking programs (§7.46)
A JIT, SIMD, GPU/HPCa reason; area 21none proposed
Pointers, strings and structs across the FFIa layout promise and a borrowed-string typescalars were enough to make the boundary real
Debug variables, a live-debugger workflow, Cranelift DWARFDILocalVariable from MIR localsfunction and statement positions were the declared scope
A package registry and version rangesa resolver that choosesexact path dependencies choose nothing
Formal methodsa semantics to state them againstarea 19’s acceptance is an assessment, not a test count

After N75: N76–N100, closing what is PARTIAL or RESEARCH

One milestone at a time, each constitution first, each ending with its own evidence and the capability row decided against that evidence rather than its title. The order is docs/nazm_N76_N100_FULL_prompts/MASTER_EXECUTION_ORDER.md’s: the front end (N76–N80); execution, runtime and interoperability (N81–N85); embedded, assurance and AI/HPC (N86–N88); tooling, ecosystem, evidence, platforms and contracts (N89–N96); formal trust, the compiler written in Nazm and the interactive tier (N97–N99); and N100, an audit of the whole catalogue that may fail honestly. A row stays PARTIAL, RESEARCH or BLOCKED when that is what its evidence says.

After N100: N101–N108, closing the core

docs/nazm_N101_N108_core_closure_prompts/MASTER_EXECUTION_ORDER.md’s order: evidence closure (N101), the compiler written in Nazm at parity (N102), re-exports (N103), authority (N104), one LIR contract (N105), the default M:N runtime (N106), a core-scope audit (N107) and a release gate over the full catalogue (N108).

After v0.3.0: post-release tracks, not core defects

The core is closed under its declared scope (N108), and v0.3.0 is its first public release (R1). What follows is classified so that nothing reads as missing compiler-core correctness merely because another language has it. Each is a later track or a research item, blocked outside this repository, or a deliberate non-goal; none is promised, and none blocks the release.

AmbitionClassWhy
Distributed runtime, supervision trees, durable actorspost-release tracka runtime layer over structured concurrency; nothing in v0.3 depends on it
Hard real-time and WCET boundsresearchwcet is always null; needs a timing model per target (area 18)
Macros and compile-time metaprogrammingresearchnazm comptime is a command; a macro system is a language decision not yet made (spec.md, Non-goals)
A verified optimizer, more proof systemsblocked / researchno proof assistant here; formal evidence is bounded model checking (area 19)
New architectures and platform portspost-release trackeach needs a machine or emulator to run on; x86_64 Linux first (support.md)
Database and HTTP frameworks, networkingpost-release trackthe standard library has no network authority yet (area 16)
A public package registrypost-release trackthe registry is local; signatures and a remote source come first (area 26)
Multi-agent semantic collaboration, deterministic replayresearchthe semantic tooling (snapshots, deltas, patches) is the substrate; neither is designed
A second GPU providerblockedno Metal or SPIR-V toolchain here (area 21)
sBPF / Solana executionblockedno sBPF toolchain or validator (area 34)
An in-process JITblockedneeds unsafe, which the workspace forbids (area 12)
Trait objects, effect handlers, user effects, implicit-flow trackingresearchN107 checked each and found none a defect or a requirement of the core (audit-n107.md)
Windows, 32-bit hosted, big-endian targetsnon-goalstated reasons in support.md

V1 Gate 1 — core stability and the 1.x constitution — 2026-10-07; awaiting review

The v1 programme’s first gate (its brief is kept outside the tracked tree, and is a goal, not evidence). Language 1.0, toolchain 1.0.0; the semantic epoch (29), nazm.interface/11, runtime ABI 14 and every schema unchanged, each for its own reason (stability.md). stability.md is the 1.x compatibility constitution — the promise, the patch/minor/major lines, and a class for every spec section, schema, command and option; spec.md classifies each of its sections and a test holds it to that. tests/compat/v1/ is the append-only compatibility corpus, pinned by digest. Public outputs that described an earlier language were fixed: the refusal help, the built-in type list in help text and nazm capabilities, 1.5 refused by name as floating point, and four commands’ help. Selfhost claims are scoped to the declared subset; licensing.md is the technical audit, and a licensing decision is required before public release. Found, not fixed: a closure stored into a Vec it captures forms a reference cycle that is never reclaimed — a defect against spec.md’s Cycles, reported for decision (area 4 is PARTIAL). Nothing tagged, pushed or published.

Gate 1-C1 — the reviewer chose cycle prevention, extended to closure environments, over a collector or a narrowed claim. A closure may not capture a value that can hold a function value behind a counted handle (N0616), decided by the captured type where the closure is written, in both compilers; storing a function value is never refused. Semantic epoch 29 → 30. Type::ALL holds all seven capability types, so completion offers them. architecture.md §7.111.

R1 — public release readiness — complete, 2026-10-07; candidate 7a16a40

releases/7a16a40.md the record. No language or runtime semantics changed intentionally. The version is settled — language v0.3, toolchain 0.3.0, tag v0.3.0 — and docs/stability.md keeps the six identities apart; docs/spec.md opens as the v0.3 specification with each section’s kind stated. CI runs the host-safe subset and leaves the contained stages out by reading the guard; it is not the release gate. N108’s lifecycle “timing flake” was an inherited ignored SIGINT, and the test now restores the default itself. A public README, a getting-started page and a tour the suite runs as written, a support matrix checked against the compiler’s table, SECURITY.md and CONTRIBUTING.md. Dates inside a candidate are the commit’s, and a build-input digest covers every tracked file. R1-C1 fixed the one defect R1 found — a function written as a value was missing from the reference index (architecture.md §7.110) — and a claims audit brought the current documents to the compiler. Two assemblies of the candidate were byte-identical; the manifest redigested independently, 220 of 220; five catalogue entries added and caught in their own campaigns. Nothing tagged, pushed or published.

N108 — the core release gate — complete, 2026-10-06; candidate 82936f6

architecture.md §7.109 first; releases/82936f6.md the record. The whole catalogue, contained: 1,268 of 1,268 caught, after 34 entries the campaign could not decide were repaired — killers chosen on macOS that Linux does not see, and nine whose code N90, N104 and N105 had moved. The platform runs found a debugger regression from N105, fixed. Workspace, selfhost, bootstrap, lifecycle, fuzzing, benchmark, platforms and the release assembly pass; the manifest redigested independently, 206 of 206. No class-A row is PARTIAL. Nothing tagged, pushed or published.

N107 — the core’s scope, audited — complete, 2026-10-05; areas 2, 3, 5, 6, 7 VERIFIED

architecture.md §7.108 first; audit-n107.md the table. Every core candidate gap was checked for being a defect first (none was) and then for being required (none is): trait objects, generic traits, default methods, effect handlers, user effects, runtime or linear capabilities, implicit flow. The rows now say what VERIFIED promises — areas 3, 5, 6 and 7 as scoped — and every absent construct is still refused by name. Divergence and implicit flow stay registered research. Twenty-nine VERIFIED, eight PARTIAL, all ecosystem or domain. No code; no version moves. Next: N108.

N106 — the pool by default; two regressions attributed — complete, 2026-10-05; area 13 VERIFIED

architecture.md §7.107 first. N83’s M:N pool is the default runtime on every hosted target with a switch; threads by name, any other name refused (N0404), a program that calls C on threads unless it asks; nazm.cost/2 says which; runtime ABI 14. The channels build regression is the pool’s runtime text, accepted; the check regression is N76’s lossless tree and N80’s provenance, with a sort and SipHash inside them removed (contained compiler/check 213.7 → 180.2 ms), the rest accepted; the bench baseline re-saved. Next: N107.

N105 — one LIR both backends consume — complete, 2026-10-05; area 10 VERIFIED (v2)

architecture.md §7.106 first. An instruction-level LIR in nazm-lir/src/op/, lowered from MIR once, decides every failure, guard, offset, runtime call and retain or release; LLVM prints it and Cranelift translates it, and Cranelift may no longer depend on MIR. A validator and an interpreter of LIR — the oracle, for the sequential subset — with hand-written expectations and a fifth fuzz tier; --layout soa on both backends; nazm.lir/2; the Cranelift object key is the LIR’s digest. Epoch, interface schema and runtime ABI unchanged. Next: N106.

N104 — authority is a parameter — complete, 2026-10-05; area 6 stays PARTIAL

architecture.md §7.105 first. The authority bridge removed: no function exercises its caller’s capabilities; every program in the repository, and the compiler written in Nazm, migrated to take them as parameters; N0369 in both compilers; epoch 29, nazm.inspect/2. Next: N105.

N103 — re-exports — complete, 2026-10-05; area 2 stays PARTIAL

architecture.md §7.104 first. pub use, with chosen names and as; one identity per definition in every output; N0211–N0213; nazm.interface/11, nazm.api-doc/2, epoch 28; both compilers. Not done: check reuse for nazm build and nazm run. Next: N104.

N102 — the compiler written in Nazm at parity — complete, 2026-10-05: 21 of 21 probes

architecture.md §7.103 first. Effects, capabilities, recursion with the stack check, contracts, foreign declarations, @std, traits, closures and function values, &&, || and ! ported into compiler/*.nz, each as the reference has it; the parity record 21 equal, 0 refused, none differs. Selfhost and bootstrap passed contained (C2 = C3, 8cc750c6…, 34 conformance cases, 29 refusals). The cost: 3,400 more lines and about 30 % more check time for the compiler itself (performance.md). Next: N103.

N101 — evidence closure — complete, 2026-10-05

architecture.md §7.102 first. N100’s survivor, n79-a-held-io-cap-is-read-alone, is reachable — N100’s probe read a warm check cache — and has a focused killer. The four without a verdict have focused killers. Every other catalogue entry without one got a killer found by applying it: 175, all caught. 1,254 of 1,255 entries declare a killer; the one that does not is a known survivor with its reason. cargo xtask check refuses an entry with neither. Next: N102.

N100 — the grand audit — complete; the zero-partial objective NOT MET

architecture.md §7.101 and docs/audit-n100.md. Every row audited against executed evidence; twenty-two VERIFIED, fifteen PARTIAL. The combined gate: workspace, selfhost and bootstrap passed contained; of 215 mutants, 210 caught (five after a finding was fixed), one survives, four without a verdict; every container-backed run passed. A release candidate and a human procedure — nothing tagged, pushed or published.

N99 — JIT and REPL v2 — complete as scoped, 2026-10-04; the JIT stays BLOCKED

architecture.md §7.100 first. The REPL, the interpreter and both native backends held to one answer; the JIT’s blocker shown to need unsafe and an absent crate, and its isolated design written. Next: N100, the grand audit.

N98 — the compiler written in Nazm at parity — not accepted: parity measured, 13 of 21 probes

architecture.md §7.99 first. A per-feature parity record, measured contained and gated: 13 equal, 8 refused, none differs. Porting the refused features is the remaining work, and the acceptance criterion is not met. Next: N99, JIT and REPL.

N97 — formal semantics v2 — complete as scoped, 2026-10-04; proofs BLOCKED (no proof assistant)

architecture.md §7.98 first. The formal model extended to loops, mutation, early return and recursion with fuel, and held to the interpreter and the checker over 12,900 programs. No proof: none can be made without a proof assistant, and none is installed. Next: N98, the compiler written in Nazm at full parity.

N96 — smart contracts v2 — complete as scoped, 2026-10-04; area 34 stays PARTIAL, sBPF BLOCKED

architecture.md §7.97 first. The EVM and WebAssembly backends held to the simulator on generated transaction sequences under their reference VMs: 750 transactions, every outcome, code and final state equal, every gas bound held. No language change; events, external calls and sBPF remain out. Next: N97, formal semantics v2.

N95 — the platform matrix v2 — complete as scoped, 2026-10-04; area 33 stays PARTIAL

architecture.md §7.96 first. Every target × backend cell is run-verified, compile-only or unsupported, with its evidence and CPU identity, in one table nazm inspect prints and a test holds the capability matrix to; Windows, 32-bit hosted and big-endian targets are decided non-goals. Not here: an x86_64 Linux runner. Next: N96, smart contracts v2.

N94 — reproducibility and provenance v2 — complete as scoped, 2026-10-04; area 32 stays PARTIAL

architecture.md §7.95 first. A five-part reproducibility model, each part with its own evidence; nazm build --sbom (CycloneDX 1.5); nazm attest sign/verify — in-toto statements signed and verified with OpenSSH. Not here: a transparency log, keyless signing, independent rebuilders. Next: N95, the platform and target matrix v2.

N93 — coverage-guided fuzzing — complete as scoped, 2026-10-04; area 30’s fuzzing stays PARTIAL

architecture.md §7.94 first. A coverage-guided fuzzer of the compiler’s own entry points, built with SanitizerCoverage and run contained by cargo xtask contained fuzz; four targets, 3.9 million executions, no crash; the minimised corpora replayed by the ordinary suite. Not here: sanitizers, Miri, Loom, backend/FFI/registry fuzzing. Next: N94, reproducibility and provenance v2.

N92 — performance evidence v2 — complete as scoped, 2026-10-04; area 28 stays PARTIAL

architecture.md §7.93 first. Every measured section of performance.md is filed in bench/claims.toml as reproducible, dated or unreproduced, held by a gate; nazm.bench/2 records the machine, the spread, sizes, the noise floor and why a reference was not measured; Rust and Go sieve references. Eight current claims stay unreproduced. Next: N93, coverage-guided fuzzing.

N91 — debugger and profiler v3 — complete as scoped, 2026-10-04; area 27 stays PARTIAL

architecture.md §7.92 first. Bindings have lexical scopes under LLVM; Cranelift writes DWARF line tables and subprograms, checked by lldb and a live gdb session; nazm profile --sample attributes a run’s samples to Nazm functions and lines, the runtime, foreign code and the system, with waits counted as blocked (nazm.profile/2). Not here: Cranelift variables, the remaining types, DAP, a Linux sampler. Next: N92, performance evidence v2.

N90 — packages v3 — complete as scoped, 2026-10-04; area 26 stays PARTIAL

architecture.md §7.91 first. The registry resolver backtracks: name order, newest first, the lockfile’s choice first, bounded at 10,000 candidates, and a refusal names the package and every requirement on it with who placed it. nazm update [NAME…] re-resolves without the lockfile’s preference and prints each change. No language or lockfile change. Not here: signatures, a remote registry, features, pre-releases, multi-root workspaces. Next: N91, debugger and profiler v3.

N89 — LSP and MCP workspace editing — complete as scoped, 2026-10-04; area 25 stays PARTIAL

architecture.md §7.90 first. A declared source root is a workspace: an exported entity is renamed in every module under it, validated whole, and a library package’s API is refused; nazm patch apply writes a plan only to the exact bytes it was made from, all or nothing. Not here: an MCP apply, DAP, editor automation. Next: N90, packages v3.

N88 — AI/HPC v2 — complete as scoped, 2026-10-04; area 21 stays PARTIAL

architecture.md §7.89 first. nazm accel runs maps and zips of Int kernels and folds them (--reduce add|min|max) in index order, every run held to the interpreter; a numeric oracle of generated kernels against 128-bit arithmetic on the GPU. nazm.accel/2. No language change. A second provider is BLOCKED here (no Metal compiler, no Vulkan); vector operations in LIR DESIGNED. Next: N89, LSP and MCP workspace editing.

N87 — assurance profiles v3 — complete as scoped, 2026-10-04; areas 19 and 20 VERIFIED as scoped, as enforcement

architecture.md §7.88 first. Contracts — requires and ensures, checked on entry and on every return path, identical on every tier, never compiled out — with calls of literals proved or refused at compile time; nazm obligations and nazm.obligations/1, every obligation proved, checked or unknown; no-unknown-calls in critical and cyber. Semantic epoch 27, nazm.interface/10. Not here: loop invariants, a solver, constant time (RESEARCH), certification. Next: N88, AI/HPC v2.

N86 — embedded v2 — complete as scoped, 2026-10-04; area 18 VERIFIED as scoped

architecture.md §7.87 first. Boards are descriptions (nazm_runtime::board::BOARDS), from which each linker script, runtime and entry is generated; a second architecture family, riscv64gc-unknown-none-elf on QEMU’s RISC-V virt, boots beside AArch64’s with identical output, failures and in-bound stacks at -O0 and -O2, built and run in nazm-qemu:n86; device registers at 8, 16 and 32 bits. Semantic epoch 26, runtime ABI 13. Not here, each DESIGNED with its reason: atomics, interrupts, a heap; and no hardware. Next: N87, the critical and cyber profiles v3.

N85 — FFI and ABI v3 — complete as scoped, 2026-10-04; area 17 VERIFIED as scoped

architecture.md §7.86 first. A practical C ABI subset: opaque handles (extern "C" struct Db;), C-layout structs by borrowed pointer, nullability in the result type (N0409 or None), Str results copied, c_errno(), exports passed to C as callbacks, nazm build --lib --shared, and bindgen reading all of it. The crossing is written as ordinary Core IR, so MIR, LIR and both backends learned only the borrowed struct copy, the errno capture and an export’s address. Semantic epoch 25, nazm.interface/9, runtime ABI 12. Not here: floats, by-value structs, variadics, closures as callbacks, dlopen, other ABIs, the compiler written in Nazm. Next: N86, embedded and bare metal v2.

N84 — the standard library 1.0 — complete as scoped, 2026-10-04; area 16 VERIFIED as scoped

architecture.md §7.85 first. Seventeen modules and 126 public items, frozen by library/std/API-1.0 and a semver policy in spec.md; four representative programs (a CLI tool, a data tool, a concurrent service, a package utility) written against it alone and run on every tier. Not here: networking, cryptography, floats, a faster map, @std in the compiler written in Nazm. Next: N85, FFI and ABI v3.

N83 — the task pool — complete as scoped, 2026-10-04; area 15 VERIFIED as scoped

architecture.md §7.84 first. NAZM_SCHEDULER=pool: tasks on bounded workers, each a guarded stack pinned to its worker, a per-target switch, every wait parking the task; ten thousand tasks alive at once on two workers; the whole CLI suite passes on the pool. Faster spawn (7.4 µs against 25.4 µs). Not here: the default stays a thread per task, no work stealing or preemption, no hand-off for a blocking foreign call, Linux unverified, the interpreter and the compiler written in Nazm unchanged. Runtime ABI 11. Next: N84, the standard library 1.0.

N82 — runtime v2: the runtime as an artifact — complete as scoped, 2026-10-03; area 13 stays PARTIAL

architecture.md §7.83 first. nazm runtime build compiles the whole runtime for a target and profile into libnazmrt.a with a nazm.runtime/1 manifest; nazm build --runtime links it on both backends after checking schema, ABI revision, runtime digest, target, profile, services and archive bytes, and refuses by name otherwise; nazm runtime verify; provenance names the archive. Behaviour is identical over the repository; a cold build is 34 ms faster with it. Not here: a runtime in Rust (one implementation kept), an allocator, a scheduler (N83). Next: N83, the advanced scheduler.

N81 — the backend contract v2, stage one — not accepted, 2026-10-03; area 10 stays PARTIAL

architecture.md §7.82 first, and it says why: LIR now owns a target’s data layout, every byte layout and the ownership table, both backends read them, every native build validates them, and nazm lir prints them as nazm.lir/1; the fuzzer exercises layouts on every tier. Objects are byte-identical on every program in the repository. Not done, by decision: one instruction-level LIR that both backends consume, with an oracle interpreter — a rewrite of both code generators that this programme does not risk the reference compiler for. Next: N82, runtime v2.

N80 — provenance v3 — complete as scoped, 2026-10-03; area 7 stays PARTIAL

architecture.md §7.81 first. Containers by type-keyed cell, calls through values and bounds by type-based targets, closures’ parameters and captures received, fields and variants within a body, one policy engine with checked-paths in cyber, and a chain per origin at every sink (nazm.flow/2). Epoch 24, nazm.check/4. No program in the repository changed verdict. Not here: implicit flow, per-handle precision, labels a program writes. Next: N81, LIR and the backend contract v2.

N79 — effects and capabilities v3 — complete as scoped, 2026-10-03; areas 5 and 6 stay PARTIAL

architecture.md §7.80 first, amended as built. The ambient bridge became a recorded contract: each function’s inherited authority is computed, recorded and shown by nazm inspect, and the authority profile’s explicit-authority refuses it by name. OutCap attenuates IoCap to the standard streams, by passing; nothing widens it back. A function value with fewer effects than expected is accepted where one is passed or returned. Revocation is declared outside the model. Epoch 23. Not here: refusing the bridge by default (the corpus and the compiler written in Nazm rely on it), per-resource capabilities, subsumption inside other types. Next: N80.

N78 — traits and methods — complete as scoped, 2026-10-03; area 3 stays PARTIAL

architecture.md §7.79 first. Nominal traits, impl Trait for Type, recv.m(…), Trait.m(recv, …) and trait bounds; coherence over the compilation (one impl per trait and type, in the trait’s or the type’s module); methods resolved before Core IR — a concrete call is the impl’s function, a call through a bound is CallTrait, resolved per instance by MIR and per value by the interpreter. The same results in the interpreter, LLVM and Cranelift. @std/show is the first standard trait; interfaces carry traits, impls and bounds (/8); epoch 22. Not here: trait objects, default methods, associated items, generic traits, generic function values (N0387 stays outside the model), the compiler written in Nazm (N98). Next: N79, effects and capabilities v3.

N77 — resolution, persisted — complete as scoped, 2026-10-03; area 2 stays PARTIAL

architecture.md §7.78 first. A module that checks cleanly leaves nazm.resolved/1, its names by durable identity, stored with its check (nazm.check/3) so its invalidation is the check’s; the same bytes from two processes and two checkouts. nazm references and nazm resolve read reused modules’ units without checking their bodies, and agree with the language service. The compiler written in Nazm refuses @std/ and package imports by name. Not here: re-export and export under another name (no design, so area 2 stays PARTIAL), a build that skips bodies, persisted locals. Next: N78, traits and methods.

N76 — syntax completion: incremental reparse, finer recovery, \u{…} — complete as scoped, 2026-10-03

architecture.md §7.77 first. nazm_syntax::Revision and Revision::edit: a file’s next parse from its previous one, relexing and reparsing only from the first item an edit can reach to the first old boundary it lands on, held equal to a fresh parse over every .nz file in the repository under seeded edit sequences. Recovery inside record, enum, parameter, argument, initialiser and arm lists, and at a broken use’s ;; the abstract tree’s contract unchanged. \u{…} escapes, epoch 21. nazm lsp synchronises incrementally through the service’s per-document revision. Not here: a hole-tolerant checker, incremental parsing outside an editor’s open document, the compiler written in Nazm (N98). Next: N77, resolution and modules.

N75 — production-readiness audit and release gate — complete: candidate cf664fd, not released, 2026-10-03

An audit, not a feature: every matrix status against its evidence, limitations.md line by line, the security wording of every current document, the schemas against their documentation — four documentation defects fixed. The gate at one commit, contained: the workspace suite, lifecycle, selfhost, bootstrap, the benchmark and the full mutation catalogue, 1,089 of 1,089 caught (one timeout given a killer); nine platform runs and the fuzzers and formal core at release scale on the host. The release assembly found that its script could not copy the conformance corpus’s directories, fixed in cf664fd, which it then assembled and verified; the artefact re-digested independently. docs/releases/cf664fd.md holds the identities, the target table, the accounting, the evidence index and the human release procedure. Nothing is tagged, pushed or published: that is a person’s decision. N49–N75’s programme ends here.

N74 — ecosystem, IDE and migration tooling — complete as scoped, 2026-10-02

architecture.md §7.76 first. nazm init and six templates, each held by its own commands; a library package checked as its modules; nazm doc from the checker’s facts; nazm bindgen for the C subset that crosses, refusing the rest; nazm publish --dry-run; the language service tested across packages; an LSP client for one editor. Not here: a network registry, rename across packages, a debug adapter, an agent-efficiency claim. Next: N75, the release-candidate audit.

N73 — compiler trust and supply chain — complete as scoped, 2026-10-02

architecture.md §7.75 first. A front-end robustness fuzzer and a differential fuzzer across the interpreter and three native tiers, both seeded, with a replayed regression corpus; three injected faults found by them alone. nazm build --provenance writes a deterministic record of a build’s inputs, toolchain and outputs, and --attest-with hands it to a local signer; cargo xtask evidence indexes an evidence bundle with checksums and writes the compiler’s bill of materials from Cargo.lock. Cross-toolchain objects measured and classified. Not here: coverage-guided fuzzing, sanitizers, Miri, Loom. Next: N74, ecosystem.

N72 — sBPF account backend — PARTIAL: analysis and metadata; execution BLOCKED, 2026-10-02

architecture.md §7.74 first. A signed-writes rule refuses a state write no signer decision guards, and account metadata states each instruction’s discriminator, arguments and account constraints. No sBPF toolchain, validator or emulator exists here, and upstream eBPF is not sBPF: the backend is designed by the metadata and not built. Next: N73, compiler trust and supply chain.

N71 — WASM contract adapter — complete as scoped, 2026-10-02

architecture.md §7.73 first. The ordinary WebAssembly backend, unchanged, plus a generated adapter appended to the contract’s own unit: exports per entrypoint, the state across two typed host imports, conservation in the module. The reference host’s run equals the simulator’s. Next: N72, an account-oriented BPF backend.

N70 — EVM backend — complete as scoped, 2026-10-02

architecture.md §7.72 first. Contracts compile directly from Core IR to EVM bytecode — i64 held exactly in 256-bit words, conservation enforced on-chain, selectors from the compiler’s own keccak, storage slots by field name so order and additions move nothing — and run in py-evm with the simulator’s outcomes, codes and storage, inside their stated gas bounds. Next: N71, a WASM contract adapter.

N69 — The Web3 semantic contract model — complete as scoped, 2026-10-02

architecture.md §7.71 first. A contract is ordinary Nazm under a web3 profile of existing rules; its read and write sets are facts, conservative where unseen; a deterministic simulator runs transactions, reverting by code and rejecting any that changes a declared conserved quantity. Static asset linearity is designed. Next: N70, an EVM backend.

N68 — Adaptive representation — complete as scoped, 2026-10-02

architecture.md §7.70 and research register R4 first, with the prior art. A Vec of a record of Ints and Bools has an unobservable layout, so --layout soa stores it one array per field: the same results and failures, the layout in every affected object’s identity, 2.8× on a one-field scan and 2× slower on an all-field one — which is why the compiler does not choose yet. Next: N69, the Web3 semantic contract model.

N67 — GPU/HPC — complete as scoped, 2026-10-02

architecture.md §7.69 first. A kernel is a pure (Int) -> Int function meeting a stated eligibility, refused by name otherwise; nazm accel generates OpenCL C from Core IR carrying checked arithmetic, runs it on the M1 Pro’s GPU with every transfer and the synchronisation in its report, recovers the sequential map’s first failure from a parallel run, and holds every result to the interpreter’s. About 6× one CPU core on a Collatz map. Next: N68, adaptive representation.

N66 — Vectorisation — complete as scoped, 2026-10-02

architecture.md §7.68 first. Checked arithmetic kept every loop scalar; ints_sum_from keeps the ordered checked sum’s meaning while adding a block unchecked only where every partial sum is provably in range, and native builds replace the counted summation loop with it — 1.9× on an M1 Pro at -O2, the same values and failures everywhere. Every other loop’s reason is in nazm explain-cost. Next: N67, GPU/HPC.

N65 — The interactive tier — complete as scoped, JIT BLOCKED, 2026-10-02

architecture.md §7.67 first. A REPL that checks its session as one program on every edit and refuses a redefinition that breaks a caller, by name; comptime for parameterless pure functions, isolated by the authority model itself (not an OS sandbox); a reload check naming what a running image could take. The JIT is blocked by the workspace’s unsafe_code = "forbid", which is the project’s to lift, and is designed. Next: N66, SIMD and vectorisation.

N64 — WebAssembly — complete as scoped, 2026-10-02

architecture.md §7.66 first. wasm32-unknown-unknown through the LLVM backend, carrying checked arithmetic and failure unchanged, with every capability of the outside a nazm_host import present only where used — a module with no IoCap has no write. A reference host grants exactly those. Fourteen corpus programs run as WebAssembly with the interpreter’s output; fifty are refused by part, for want of a heap, which is designed and not built. Next: N65, a JIT and REPL tier.

N63 — Real-time bounds — complete as scoped, 2026-10-02

architecture.md §7.65 first. A realtime profile — embedded plus no blocking, no clock and bounded loops — and a bounds report: exact trip bounds for the counted loop form, call depth, site counts, wcet null. A board build states its stack bound from the code generator’s frames along the deepest path; a painted stack on QEMU stays below it at -O0 and -O2. Measurement is never the bound. Next: N64, WebAssembly.

N62 — Embedded bare metal — complete as scoped, 2026-10-02

architecture.md §7.64 first. aarch64-unknown-none: a board runtime without thread-local storage or a C library, failure on the UART and semihosting’s exit, _start and link.ld, a stack check against the image’s own stack; volatile mmio_read32/mmio_write32 under an MmioCap, refused where there is no device (N0392). A Nazm program boots on QEMU’s virt board and prints through its UART. Atomics, interrupts, a heap and @std designed, not built. Next: N63, real-time bounds.

N61 — Formal semantics — complete as scoped, 2026-10-02

architecture.md §7.63 and docs/formal-core.md first. A core’s typing and evaluation rules, transcribed with no compiler dependency, and five properties checked over all 94,352 programs up to five nodes, holding Nazm’s interpreter and checker to them. Its first run found the transcription wrong against the spec (i64::MIN % -1). A model check, not a proof. Next: N62, embedded bare metal.

N60 — Restriction profiles v2 — complete as scoped, 2026-10-02

architecture.md §7.62 first. pass/fail/unknown verdicts, unknown refused; embedded’s no-recursion over MIR’s direct call graph, unknown through a function value; critical’s no-select; a dependency cannot weaken the root’s profile. Constant-time RESEARCH; bounded loops, queues and tasks to N63. Next: N61, formal semantics.

N59 — Backend performance — complete as scoped, 2026-10-02

architecture.md §7.61 first. Scalar temporaries assigned once and read in their block have no slot in the LLVM emitter: 54 % fewer allocas in the compiler’s own text, a 5 % faster -O0 build, a quarter faster -O0 program, the same output. MIR’s ownership model untouched; Cranelift already SSA. The native build still needs clang for the runtime and the C driver for the link, named by nazm inspect. Next: N60, advanced restriction profiles.

N58 — Debugger and profiler v2 — complete as scoped, 2026-10-02

architecture.md §7.60 first. Int, Bool and Str parameters and bindings described in DWARF; the prologue carries no line, so a breakpoint on a function stops after its slots are written; a subprogram is named by its Nazm name. A live gdb session verified in the Linux container — names, lines, backtraces, stepping and variables; lldb on macOS still blocked by developer mode. nazm profile prints one run’s memory and scheduler counts as nazm.profile/1. Cranelift’s DWARF is BLOCKED by name. Next: N59, backend performance.

N57 — Targets and cross-compilation — complete as scoped, 2026-10-02

architecture.md §7.59 first. Four targets, both backends, from any host in the matrix; an executable where the host links the target, objects and link.txt where it cannot; the triple in every key; nazm inspect names each target’s output. Run-verified on three (host, x86_64 macOS under Rosetta, aarch64 Linux in the container), compile-only on x86_64 Linux. No language change: semantic epoch unchanged. Next: N58, debugger and profiler v2.

N56 — Packages v2: a local registry — complete as scoped, 2026-10-02

architecture.md §7.58 first. A registry is a directory: an index per package and an immutable, digest-checked copy per version. Four requirement forms, solved per name to the lockfile’s version while it satisfies or the highest non-yanked, one version per name, no backtracking. nazm publish and nazm yank; tampering, links, malformed or equivocating indexes, double publishing and name conflicts refused by code. No network, no signatures, no multi-root workspaces; the self-hosted compiler’s package support is DESIGNED. Semantic epoch unchanged: no checker rule moved. Next: N57, cross-compilation.

N55 — FFI v2: C strings in, exports out — complete as scoped, 2026-10-02

architecture.md §7.57 first. A Str argument to C is a borrowed NUL-terminated copy, freed after the call; a NUL byte is refused before C runs. pub extern "C" fn … ! {} = "sym" { … } exports a scalar Nazm function, and a failure inside one ends the process instead of unwinding into C. nazm build --lib -o OUT.a writes a static archive and OUT.h, the same bytes on every build, under both backends. Opaque handles, C structs, callbacks and errno are DESIGNED with their reasons. Runtime ABI 7; semantic epoch 18. Next: N56, packages v2.

N54 — Select, deadlines, cooperative cancellation and counters — complete as scoped, 2026-10-02

architecture.md §7.56 first. One OS thread per task stays: the stackful pool is DESIGNED, its three thread-local prerequisites named, and not built. Built: chan_select_of and chan_select_until over Vec[Chan[T]] with the lowest ready index winning and a closed channel always ready — the cancellation signal — on a runtime-wide event count that cannot lose a wake-up; time_now_ms; TimeCap, held, and critical’s no-ambient-time; NAZM_SCHED_REPORT counters agreeing across the interpreter and both backends. N44’s failure rule unchanged. Runtime ABI 6; semantic epoch 17. Next: N55, FFI v2.

N53 — Runtime crate and generic channels — complete, 2026-10-02

architecture.md §7.55 first. The runtime is its own crate, nazm-runtime — text, inventory, OS adapter and platform entry — depending on nothing of the compiler and consumed by both backends; runtime ABI revision 5, and a digest of what the runtime emits enters every object key beside it. Chan[T] for any T that may cross into a task (N0390 otherwise), with chan_new_of, chan_send_of, chan_recv_of and chan_close_of: one runtime (nz.chanv_*) whose header extends the Int channel’s with the element’s stride and release, so retain and close are shared; a queued value is released by the channel’s last reference, a refused one by its sender. The Int-only Chan and its built-ins are unchanged, and the Nazm-written compiler does not carry the typed channel. Semantic epoch 16. Next: N54.

N52 — Resource cost and information flow v2 — complete, 2026-10-02

architecture.md §7.54 first. Resource sites read off MIR with a count per call that is at-most-once or unknown (nazm explain-cost, nazm.cost/1); a sink registry — path, output, file-data — solved through helpers, closures and modules (nazm explain-flow, nazm.flow/1); str_vouch under a new VouchCap, recorded; three profile rules over the new facts. Containers stay whole-container conservative, by statement. Semantic epoch 15. Next: N53, the runtime crate.

N51 — Effects and capabilities v2 — complete, 2026-10-02

architecture.md §7.53 first. One effect parameter per function, effects E, opaque in its body and bound at each call from its function-typed arguments (N0388, N0389); vec_map, vec_filter and vec_fold take it, so a caller is held to what the function it passes does, and a profile sees it. A closure holds the capabilities visible where it is written, as captured (N0386 narrowed to let mut). Making a value of an undeclared function needs the authority its type’s effects need, which bounds the N37 bridge at the edge N50 opened. Attenuation and revocation deferred with their cost. Semantic epoch 14; interface /7 with * in effect lists. Next: N52, resource cost and information flow.

N50 — First-class functions and closures — complete, 2026-10-02

architecture.md §7.52 first, amended with the code where the code was simpler. Function types fn(T…) -> R ! {e}, named functions as values, closures capturing by copy (N0386 for a let mut binding or a capability), indirect calls through a binding, and N0387 for what cannot be a value. One lowering: the checker declares each closure, Core IR lifts it, MIR adds the environment and a thunk per named function used as a value, and the interpreter and both backends consume that. One closure object, counted in the memory report’s new closures class. @std/seq gained vec_map, vec_filter and vec_fold, plain Nazm. Semantic epoch 13, runtime ABI 4, interface schema kept at /7 with a fifth type shape. Traits and methods are designed and deferred: function values met every need in hand. The compiler written in Nazm has none of it. Next: N51, effects and capabilities v2 — effect polymorphism is what keeps the higher-order library pure-only.

N49 — Language usability and native completeness — complete, 2026-10-01

architecture.md §7.51 first. String escapes (N0004), &&, || and ! (lowered to if in Core IR), native recursion under both backends with a measured per-thread stack guard (N0408, runtime ABI 3), and use "PATH" as NAME; with NAME::item (N0209, N0210). Semantic epoch 12. nazm capabilities now separates the two implementations only by the interpreter’s iteration budget and the native-only foreign call. The compiler written in Nazm refuses all of it by name. Found on the way: an instance that calls itself was declared and defined by one unit, which recursion through a generic function exposed. Next: N50, function values.

N48 — Inspector, debug information, timings, and the v1 release audit — complete, 2026-10-01

architecture.md §7.50 first. nazm inspect prints nazm.inspect/1; nazm build --debug writes DWARF through the LLVM backend, verified statically with lldb; nazm build --timings prints nazm.timings/1. The release audit added docs/limitations.md, release-candidate notes and the human release procedure in docs/releases/, and this section.

N47 — Restriction profiles — complete, 2026-10-01

architecture.md §7.49. general, embedded, critical and cyber: rules with stable ids over the checker’s facts, N0510/N0511, and nazm.profile-report/1. A profile only refuses.

N46 — Packages, locking and reproducible builds — complete, 2026-10-01

architecture.md §7.48. nazm.toml, use "NAME:path", nazm lock, --locked, N0500–N0509, and byte-identical executables from two directories.

N45 — The standard library — complete, 2026-10-01

architecture.md §7.47. Seven @std/… modules of Nazm source, every function’s contract declared.

N44 — Structured concurrency and the scheduler — complete, 2026-10-01

architecture.md §7.46. The OS as scheduler, stated and stress-tested; no cancellation, by decision.

N43 — The runtime constitution — complete, 2026-10-01

architecture.md §7.45. One typed inventory of the runtime, an OS adapter, runtime ABI revision 2 in every object key, and the runtime tested directly.

N42 — The ABI and foreign functions — complete, 2026-10-01

architecture.md §7.44. extern "C" declarations of Int and Bool, the effect foreign and ForeignCap, --link, nazm.interface/7, semantic epoch 11.

N41 — The backend boundary and the Cranelift backend — complete, 2026-10-01

architecture.md §7.43. A Backend trait, a typed runtime registry, and Cranelift 0.136.1 compiling every MIR function, identical to LLVM on all 104 buildable programs.

N40 — MIR, the one lowering for the native backend — complete, 2026-10-01

architecture.md §7.42 was written first. nazm-mir holds MIR: each concrete function — every generic instance included — as basic blocks with exactly one terminator each, typed locals, and every copy, move, drop, scope join and failure edge written out; a validator proves, by a forward dataflow over managed locals, no read of an empty local, no overwrite of an owned one, nothing owned at a return or unwind, and every task list joined. nazm-lir reads MIR only — it no longer depends on nazm-cir and cannot name a Resolution (a cargo xtask check rule) — and its LLVM emitter was rewritten over it. nazm mir prints nazm.mir/1. Each function has an executable digest that formatting, names and effects do not move. The interpreter stays on Core IR, by decision. All 205 sources check, run and build byte-identically to N39, and all 104 buildable programs behave identically. No language change: SEMANTIC_EPOCH stays 10.

SettledWhere
the constitutionarchitecture.md §7.42
the representation, lowering, validator, printer, digestcrates/nazm-mir/
native lowering and emission from MIRcrates/nazm-lir/src/lower.rs, emit.rs
the boundarycargo xtask check core ir boundary, xtask/src/rules.rs

Mutation evidence: fifteen new mutations and 44 historical ones repointed to where their rule lives now, each for a stated responsibility, seven retired; all 59 caught (capability-matrix.md §30).

After N39, in dependency order

No item is chosen here; N39 left these standing, beside N38’s below.

Depends onWhy not before
MIR: places, moves, drops, exclusivityCore IR ✓, its region ownership ✓Core IR says what a region owns; nothing yet needs a place
Digests as cache keys (Core IR, MIR, objects)per-function digests ✓nothing reuses work at this level yet, so nothing could key on them
Persisting Core IR across runsa cache key that covers what lowering readsbuilt from each run’s full check; cheap next to checking
An optimisera level to optimise, and a reasonno pass exists and none was added for a benchmark
The Nazm-written compiler reading Core IRits own checker growing a loweringthe bootstrap compares what it emits, which did not move
Checking cost in one function’s bindingsa scope structure that is not scannedquadratic in bindings per function (performance.md, N39) — the checker’s, predating Core IR

N39 — Core IR constitution and typed lowering v1 — complete, 2026-09-30

One lowering of a checked program, and both backends start from it. architecture.md §7.41 was written first and says what Core IR represents and omits, when it is built, and the invariants a consumer may assume. nazm-cir holds it: typed values — the checker’s types, or never for an if, match or block every path of which transfers — definitions and built-ins by identity, structured regions with explicit completion and a named loop on every break and continue, ? as a match whose error arm returns, comparisons with their law, and each function’s effect contract and authority. nazm-core lowers only after checking succeeded, privately, and a disagreement with the checker is N0900, a compiler defect; the verifier runs on every lowering. The interpreter runs Core IR with slot frames and reads neither the tree nor the resolution; nazm-lir lowers Core IR and no longer depends on nazm-syntax; a cargo xtask check gate, run by the suite too, refuses a position lookup below Core IR. nazm core-ir prints nazm.core-ir/1, deterministic and durable. Each function has a semantic and a body digest: an effect-only change moves only the first, a capability parameter both, provenance neither. Provenance stays a checker fact. All 205 sources check, run and emit IR byte-identically to N38; the interpreter is 16–52 % faster on the bench programs on the host, and mixed — −12 % to +10 % — in the Linux container. No language change: SEMANTIC_EPOCH stays 10, nazm.interface/6 and every tooling schema unchanged.

SettledWhere
the constitutionarchitecture.md §7.41
the representation, verifier, printer, digestscrates/nazm-cir/
the one loweringcrates/nazm-core/src/lower.rs
the interpreter over Core IRcrates/nazm-core/src/eval/
native lowering from Core IRcrates/nazm-lir/src/lower.rs
the boundarycargo xtask check core ir boundary, xtask/src/rules.rs

Mutation evidence: nineteen new mutations, twelve repointed to where their rule lives now, one retired; 37 selected with a stated link each, all caught (capability-matrix.md §30). The MILESTONE gate ran offline and every stage passed; the campaign needed six sessions, 13,876 s. The interpreter is faster on the host and mixed in the Linux container (performance.md, N39).

N40 followed; see above.

After N38, in dependency order

No item is chosen here; N38 left these standing, beside N37’s and N36’s below.

Depends onWhy not before
Implicit flow (conditions, loop bounds)a control-dependence modelexplicit data flow is what v1 can state exactly
Field-, element- and alias-precise provenancea MIR that tracks placesrecords are tracked whole and shared storage is unknown
More sinks, user labels, declassification, sanitisersa policy designone sink is what current semantics justify without an escape hatch
Provenance summaries for foreign codean FFIthere is none

N38 — Provenance and information flow v1 — complete, 2026-09-30

Where a value came from, statically. Four compiler-owned origins — argument, file, authority, unknown — enter only through the built-ins that bring data in and main’s capabilities, and flow by explicit data flow through bindings, operators, calls, records, variants, Result and ?; a condition contributes nothing, and a value read out of a sequence or channel is unknown. Each module’s bodies are reduced to facts kept in its check entry (nazm.check/2), and every run solves the whole program’s summaries from them to the least fixed point, so a callee’s body change reaches a caller the cache reused. One restricted flow: in a function with a declared effect set, the path write_file writes to may not derive from a file’s contents or from shared storage, directly or through any function that writes to a path it is given (N0372). Tools carry it in nazm.context/3, nazm.snapshot/3 and nazm.delta/3. Nothing reaches what runs: the IR is byte-identical under N37 and N38. SEMANTIC_EPOCH 9 → 10; nazm.interface/6 unchanged. All 203 existing sources check exactly as before.

SettledWhere
origins, flows, facts and summariescrates/nazm-sema/src/provenance.rs
the walk, the solve and the restrictioncrates/nazm-core/src/provenance.rs
facts across runscrates/nazm-iface/src/facts.rs, crates/nazm-cache/src/artifact.rs, crates/nazm-cli/src/checking.rs
packets, snapshots, deltascrates/nazm-service/, schema/nazm.{context,snapshot,delta}-3.json
the lawspec.md Provenance: where a value came from, architecture.md §7.40

Mutation evidence: twenty-five new mutations and one retired; 34 selected with a stated link each, all caught (capability-matrix.md §30). The MILESTONE gate ran offline in 7,217 s. Every stage passed but the MCP benchmark’s memory check, which a one-time glibc arena step failed; its law now samples the measured window and allows one such step only with a plateau after it, and the release-benchmark stage passed when run again alone (performance.md).

After N37, in dependency order

No item is chosen here; N37 left these standing, beside N36’s below.

Depends onWhy not before
Attenuation and resource-specific capabilities (a read-only IoCap, one file, one directory)a kind with a resource argumentv1 has no narrower kind to derive one into
Retiring the ambient bridgedeclared sets on the compiler’s own sources, and a migration story1,034 of 1,054 function checks in the tree still declare no set
Runtime or operating-system enforcementa design for what crosses into foreign codethe check is static; nothing at runtime consults a capability
Linear or affine authority, revocationmove semantics, lifetimesa capability copies freely today
Restriction profiles (no IoCap in embedded, no SpawnCap in critical)capabilities ✓, a profile mechanismnothing selects a profile yet
Foreign and unsafe authorityan FFIthere is none to authorise
The Nazm-written compiler reading capabilitiesthe same lexer and parser work as effect setsno source it reads declares one

N37 — Capabilities / authority v1 — complete, 2026-09-30

An effect says what a function does; a capability says what allows it. Two compiler-owned kinds, IoCap and SpawnCap, are built-in types: a function that declares an effect set holds exactly the capability values its scope reaches, and every outside-world built-in, spawn and call of an undeclared function needs the authority for what it does (N0369), checked apart from the effect (N0366) and reported before it. main is the root: the runtime hands it one of each capability it declares, it may take nothing else (N0371), and nothing constructs one (N0370). A function that declares no set is the compatibility bridge — it exercises its caller’s authority — and is bounded so that code with a contract cannot reach authority it does not hold through it, in its module or another. Authority crosses a module as parameter types, in nazm.interface/6 unchanged. The checking is static and a capability erases to a word nothing reads; there is no sandbox. SEMANTIC_EPOCH 8 → 9. Of the 200 .nz sources at N36, 197 check exactly as before; the three that do not are N36’s examples/effects/, which declared effects without authority and now hold it. N36’s wording was corrected so that fn f() -> Int and fn f() -> Int ! {} cannot be read as one.

SettledWhere
capability kinds, sets and the built-in tablecrates/nazm-sema/src/capability.rs, types.rs
possession, forging, main’s parameterscrates/nazm-core/src/check/
the authority check and its witnesscrates/nazm-core/src/effects.rs
the root at runtimecrates/nazm-core/src/eval/, crates/nazm-runtime/src/entry.rs
the lawspec.md Capabilities: what allows a function to act, architecture.md §7.39

Mutation evidence, under the new responsibility law: twenty new mutations and one retired; 33 selected — the twenty and thirteen N36 entries each with a stated link — all caught, 32 at tier 1 and 1 at tier 2 whose killer was then strengthened and verified alone (capability-matrix.md §30). The MILESTONE gate ran offline: 5,737 s of wall time across its stages (performance.md).

After N36, in dependency order

No item is chosen here; N36 left these standing, beside N35’s and N34’s below.

Depends onWhy not before
Capabilities: who may exercise an effectthe effect sets N36 settleddone in N37
Profiles that forbid effects (critical: no io, no spawn; embedded)effect sets ✓, a profile mechanismnothing selects a profile yet
The Nazm-written compiler reading effect setsa lexer token and a parser rule in compiler/*.nz, and a bootstrapN36 avoided migrating the compiler’s sources; none of them declares a set
Declared sets on the compiler’s own exportsthe item abovean undeclared import is every effect to its importer, so 152 of 1,044 function checks in the tree read { io, spawn }
Effect polymorphism and handlersfunction valuesnothing a type argument brings can call anything yet
Divergence, panic and allocation as effectsanswers to spec.md Open — Effectseach is a design question, not an omission
Completion of effect namesa completion site inside an effect settwo names; not worth a new site kind in N36

N36 — Typed effects and the effect system constitution v1 — complete, 2026-09-30

A function may declare the effects it exercises — fn show(n: Int) -> Int ! { io }, ! {} for pure — and every function’s effects are inferred from its resolved calls to the least fixed point over its module. Two effects, both the compiler’s: io, the eight outside-world built-ins, and spawn, a spawn statement and everything its task does. A declared set is a contract the body is checked against (N0366, with a shortest witness); unknown and repeated names are refused (N0367, N0368). Across modules only a declared set travels, persisted in nazm.interface/6, so a caller never reads another module’s body and an undeclared import is every effect. Tools show it: signatures and hover, a packet’s effects (nazm.context/2), an effects snapshot section (nazm.snapshot/2, nazm.delta/2). Nothing reaches what runs: the IR is byte-identical with and without declarations. SEMANTIC_EPOCH 7 → 8. Every one of the 116 existing sources checks exactly as before; none needed a change.

SettledWhere
the syntax, CST node and formattingcrates/nazm-syntax/, grammar.ebnf, guide.md
effect identity and setscrates/nazm-sema/src/effect.rs
inference, the contract and the witnesscrates/nazm-core/src/effects.rs
the interface, /6crates/nazm-iface/src/wire.rs
signatures, hover, packets, snapshots, deltascrates/nazm-service/, schema/nazm.{context,snapshot,delta}-3.json (-2 until N38)
the lawspec.md Effects: what a function may do, architecture.md §7.38

Mutation evidence: seventeen new mutations, two retired, two repointed; 85 selected, all caught, 78 at tier 1 with their killers verified and 7 at tier 2 (capability-matrix.md §30). The MILESTONE gate ran offline: 7,242 s of wall time across its stages (performance.md).

After N35, in dependency order

No item is chosen here; N35 left these standing, beside N34’s and N33’s below.

Depends onWhy not before
The same benchmark on a second model family, through the direct adaptersa key a developer bringsnone was supplied; the OpenAI and Anthropic adapters are tested against recorded responses only
A deterministic run (temperature 0)a provider that takes onethe Claude Code client sets none; the model’s default applied
More trials, and intervals rather than rangesa budget for themtwo trials show a spread, not a significance
Routing a tiny, self-contained task to raw sourceevidence across models, and a rule to testN35 observed one crossover, for one model, between 744 and 6,720 input tokens; it routes nothing
A task wording that keeps builtins out of “definitions” (T2)a new suite version, compared from the startthe frozen suite is not edited after its results
Tool-using and multi-turn agentsa protocol for themN35 measures whether the context alone suffices

N35 — Agent task token, cost and correctness benchmark v1 — complete, 2026-09-29

nazm-agent-bench puts eight tasks over the seven N33 scenarios — understand, edit, diagnose, documentation and test selection, the 123-byte diagnostic among them — to a real model, each with the naive baseline and with nazm repo --task’s context, byte for byte and digest-addressed, one prompt for both. Each answer is scored fact by fact by an offline oracle whose truths come from the authorities; hallucinations are kept apart from misreadings; usage is kept raw and normalised, and dated prices are applied in integer pico-USD, never in an identity. A spend cap is checked before every attempt, transport failures are retried at most twice and never counted incorrect, the journal resumes, and a dry run needs no provider. On claude-haiku-4-5-20251001 through the Claude Code client, two trials: the N33 context solved 12 of 16 requests to 6, with 112 of 116 facts to 95, no hallucination in either arm, 94.36 % fewer input tokens and 95.39 % less cost as billed (92.86 % uncached); correctness was preserved on 7 of 8 tasks, T2 the exception by the pre-declared rule, and the diagnostic the one task where raw source was cheaper. Evaluation tooling only: no crate depends on it, and no grammar, semantics, SEMANTIC_EPOCH (7), nazm.interface/5 or existing schema changed; one new schema.

SettledWhere
the suite, oracles, providers, runner and reportcrates/nazm-agent-bench/, architecture.md §7.37
the dated price listtools/agent-bench/pricing.toml
the resultstools/agent-bench/results/, performance.md
how to run it, and bring a keyrunbook.md, The agent task benchmark
nothing else on the network, nothing depending on itxtask/src/rules.rs, the network reach and tokenizer reach gates

Mutation evidence: sixteen new mutations and an agent profile, all caught at tier 1 with their sixteen killers verified (capability-matrix.md §30). The MILESTONE gate ran offline after the paid run, at 0419b25: 2,977 s of wall time (performance.md). The benchmark spent $1.78 of a $2 cap, pilots included.

After N34, in dependency order

No item is chosen here; N34 left these standing, beside N33’s and N32’s below.

Depends onWhy not before
An agent task benchmark with a real model: tokens, cost, success (G83–G85)task contexts ✓, multi-tokenizer counts ✓nothing has been run against a model, and a model run is its own protocol
Framing and protocol overhead of a model conversationa chosen protocol and modelN34 measures content only, by law
A compact transport for tiny contextsevidence that the fixed overhead matters in a real taskit is 400–700 tokens, constant, and carries the retrieval and reasons the planner’s law requires
An audit of syntax decisions against several tokenizers (the rest of G81)a syntax change to decideno syntax was changed or proposed here
More families (e.g. WordPiece), a model’s own chat templatea reason and a permissive assetthree families are what G82 asks

N34 — Tokenizer-independent context measurement and multi-tokenizer benchmark v1 — complete, 2026-09-29

nazm-tokens measure counts the exact text on standard input under four pinned tokenizers of three families — OpenAI byte-level BPE (cl100k_base, o200k_base), SentencePiece BPE (Mistral-7B-v0.1) and SentencePiece Unigram (T5-small) — offline, with every identity carrying its library, revision, licence, normalisation, special-token policy and asset digest, as nazm.token-cost/1. Content only; framing and unknown pieces beside the count; nothing normalised first; an unknown tokenizer or an altered asset refused by name. The seven N33 tasks, with their baselines unchanged, keep a 72.7–97.5 % reduction under every tokenizer, the one-function diagnostic reported as a stress case. It is a tool beside the compiler: no crate depends on it, and nazm is the same bytes as at N33. No grammar, semantics, SEMANTIC_EPOCH (7), nazm.interface/5 or existing schema changed; one new schema.

SettledWhere
the tokenizers, their identities and the measurementcrates/nazm-tokens/, architecture.md §7.36
the pinned assets and their provenancetools/tokenizers/
one definition of the N33 tasks for both benchmarkscrates/nazm-repo/tests/scenarios/
the benchmarkcrates/nazm-tokens/tests/benchmark.rs, performance.md
no tokenizer outside nazm-tokens, nothing depending on itxtask/src/rules.rs, the tokenizer reach gate
workloads with no networkxtask/src/contained.rs

Mutation evidence: eleven new mutations and a tokens profile, all caught at tier 1 with their twelve killers verified (capability-matrix.md §30). The MILESTONE gate ran offline: 2,090 s of stages, 40.6 minutes of wall time with one documentation fix and its re-run (performance.md).

After N33, in dependency order

No item is chosen here; N33 left these standing, beside N32’s below.

Depends onWhy not before
An agent task benchmark with a real model: tokens, cost, success (G83–G85)task contexts ✓, their byte measurements ✓nothing has been run against a model; bytes are not tokens
Multi-tokenizer measurement of contexts (G81, G82)task contexts ✓tokenizer claims need several tokenizers
Rust semantic entities in the mapa compiler-owned Rust fact sourcethe compiler has no Rust semantics; packages and targets are all the map can own
Project-wide callers and importers of exported definitionsa project/importer boundarycallers are the manifest’s compilations only, as rename’s refusal already records
Transitive or ranked contexta justified boundone step and sixteen members per relationship are the v1 law
A persistent or incremental repository indexmeasurement that forces onea map takes about 0.4 s and a task 0.05–0.6 s in a release build
Documentation links from definitions and diagnosticsan authority that states themno document names a definition or a code structurally today

N33 — Repository context map and minimum task context v1 — complete, 2026-09-29

nazm repo --map lists every entity of the repository with a durable identity — packages and targets, source roots, compilation roots, modules and durable definitions, documents, schemas and mutation profiles — with its authority, its structural relationships and where to retrieve more, and never a body. nazm repo --task answers, for seed ids and an intent, the smallest context the repository can justify: one step from each seed, each item with its reason, class, authority and retrieval, the seed’s exact source and the selected sections’ exact text, under a structural budget whose cut is partial. A goal or a plan never outranks the specification or the evidence; a stale state is refused; a seed is an id and never a path. nazm-mcp adds nazm.repository_map and nazm.task_context. It composes N27, N28, N30 and N32: no grammar, semantics, SEMANTIC_EPOCH (7), nazm.interface/5 or existing schema changed; two new machine schemas.

SettledWhere
the map, the planner, the manifest, the Cargo and catalogue readerscrates/nazm-repo/, architecture.md §7.35
a durable definition’s name range, for asking its packetcrates/nazm-service/src/durable.rs
nazm repocrates/nazm-cli/src/repo.rs, schema/nazm.repository-map-1.json, schema/nazm.task-context-1.json
nazm-mcp: nazm.repository_map, nazm.task_contextcrates/nazm-mcp/src/main.rs, docs/mcp.md
each package’s documentation[package.metadata.nazm] docs in its Cargo.toml
what it costs and savesperformance.md

Mutation evidence: nineteen new mutations and a repo profile; one session verified all 36 declared killers of those nineteen and of the fifteen MCP entries N33’s server change touches, and decided all 34 — caught at tier 1 (capability-matrix.md §30). The MILESTONE gate took 40.5 minutes from empty caches (performance.md).

After N32, in dependency order

No item is chosen here; N32 left these standing. Superseded by “After N33” above, except where this table is the only record of an item.

Depends onWhy not before
Semantic or full-text documentation search (the rest of G78)stable sections ✓ids are exact by design; a search is its own contract
Fine-grained normative rule ids and a rule graph (G79)section anchors ✓ids stop at sections; rule-level identity is a spec-wide decision
Whole-spec deduplication, contradiction detection (G79)a rule graphno rule graph exists
Documentation history and version-change retrievala retention contractnothing is kept between requests, and nothing reads Git
Documentation outside a source checkouta packaging decisionthe corpus is read from a repository’s docs/
Progressive test-detail retrievaltest summaries ✓unchanged since N31
Typed diagnostic facts (expected, actual, entity)the checker recording themunchanged since N30
Patch application, a transactional writepatch plans ✓its own safety milestone
Rename of exported definitionsrename ✓, a project/importer boundaryunchanged since N18
Effect and capability contextthe language owning effects and capabilitiesboth are MISSING as language features
Incremental reparsea lossless CST ✓still no evidence that forces it

N32 — Machine-addressable documentation and selective retrieval v1 — complete, 2026-09-28

The first executable step toward G78, and a narrow one toward G79. nazm docs --index lists Nazm’s own documentation — fourteen canonical documents, each with its authority — as sections with stable ids, titles, parents and digests and no body; nazm docs --section ID returns one section’s own text byte for byte. Ids come from an explicit anchor, the document’s own numbering, or the heading path, never from a line or a hash; a state binds a request to the corpus an index described. A goal is never evidence and a plan never a rule: each section carries its document’s authority. nazm-mcp adds nazm.docs_index and nazm.docs_section, by id and never by path. Compiler semantics and every existing schema are unchanged: SEMANTIC_EPOCH 7, nazm.interface/5; two new machine schemas; spec.md gained forty-three anchor comments and no other change.

SettledWhere
the corpus, its sections, ids, authorities and digestscrates/nazm-docs/, architecture.md §7.34
nazm docscrates/nazm-cli/src/docs.rs, schema/nazm.docs-index-1.json, schema/nazm.docs-section-1.json
nazm-mcp: nazm.docs_index, nazm.docs_sectioncrates/nazm-mcp/src/main.rs, docs/mcp.md
the corpus gatecargo xtask check-corpus
what it costsperformance.md

Mutation evidence: 17 new mutations and one re-pointed; the harness that verifies them was rebuilt first (N32-H: one warm session per gate, runbook.md, The warm-worker law) and gained two of its own. One session verified all 34 declared killers of the 19 new entries and of the 12 MCP entries N32’s server changes touch, around the one injection each verdict came from, and decided all 31 — caught at tier 1 (capability-matrix.md §30). The whole MILESTONE gate took 40.1 minutes (performance.md).

After N31, in dependency order

No item is chosen here; N31 left these standing. Superseded by “After N32” above.

Depends onWhy not before
Progressive test-detail retrievaltest summaries ✓nazm test --json is the detail today; no evidence yet needs a per-case query
Test impact, test-to-definition mappinga relation the compiler ownstests are not tied to definitions
Build and test summaries over MCPa write and execution boundarybuilding writes an executable and tests run programs; the MCP server is read-only
Typed diagnostic facts (expected, actual, entity)the checker recording themunchanged since N30
Further verbosity levels (G75)compact and detail ✓not asked for
Diagnostic or build-log historya retention contractnothing is kept between requests
Patch application, a transactional writepatch plans ✓its own safety milestone
Rename of exported definitionsrename ✓, a project/importer boundaryunchanged since N18
A project or importer boundarya manifest, or a declared universe of rootsnothing says which files may import a module
Fixes of syntax diagnostics as patchesa binding for a recovered compilationunchanged since N29
Effect and capability contextthe language owning effects and capabilitiesboth are MISSING as language features
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓, patch plans ✓each is its own contract
Incremental reparsea lossless CST ✓still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14

N31 — Token-efficient build and test output v1 — complete, 2026-09-28

The first executable step toward G76. --summary-json on nazm check and nazm build prints one nazm.command-summary/1: the command’s own status — one per exit path — and exit status, and a reference to every diagnostic it reported, with N30’s id where N30 indexes it and an explicit command reference where it does not (a missing main, a backend’s refusal). On nazm test it prints one nazm.test-summary/1: counts from each case’s verdict, and only the cases that did not pass, with how each leg ended, read from what the runner did. Summary is an additive view, not a replacement for existing detailed machine output, and absence of diagnostics does not imply command success. nazm-mcp adds nazm.command_summary for check only — building and testing are not read-only. Human output, --json, nazm.test/1, nazm.check-report/1, nazm.build-report/1, every exit status and every existing schema are unchanged: SEMANTIC_EPOCH 7, nazm.interface/5; two new machine schemas.

SettledWhere
command summaries, and their references to N30crates/nazm-service/src/summary.rs, schema/nazm.command-summary-1.json, architecture.md §7.33
`nazm checkbuild –summary-json`
nazm test --summary-jsoncrates/nazm-cli/src/test.rs, schema/nazm.test-summary-1.json
nazm-mcp: nazm.command_summary, check onlycrates/nazm-mcp/src/main.rs, docs/mcp.md
what it costsperformance.md

Mutation evidence: 15 new mutations; 41 killers verified on the final source — the fifteen, the sixteen N30 entries whose order N31 shares, and the ten MCP entries of N27–N30; one targeted campaign of 23, all caught — 21 at tier 1, one each at tiers 2 and 3 (capability-matrix.md §30). Closure correction: every public N31 outcome variant — could_not_build, could_not_run and toolchain_failed among them — has at least one regression test that executes its production branch; the test runner’s driver is a test seam, NAZM_TEST_DRIVER; seven more mutations. 24 killers verified on the final source; a targeted campaign of 14, all caught at tier 1.

After N30, in dependency order

No item is chosen here; N30 left these standing. Superseded by “After N31” above.

Depends onWhy not before
Typed diagnostic facts (expected, actual, entity)diagnostics ✓, the checker recording themno diagnostic carries them today; reading them from prose is refused
Further verbosity levels (explain, and the rest of G75)compact and detail ✓not asked for; each is its own contract
Diagnostic historya retention contractunchanged: nothing is kept between requests
Build and test output redesign (G76)diagnostics ✓done in part by N31: compact command and test summaries
Patch application, a transactional writepatch plans ✓its own safety milestone
Rename of exported definitionsrename ✓, a project/importer boundaryunchanged since N18
A project or importer boundarya manifest, or a declared universe of rootsnothing says which files may import a module
Fixes of syntax diagnostics as patchesa binding for a recovered compilationN28 has no snapshot where syntax needed recovery
Semantic history, or a persistent snapshot storesnapshots ✓unchanged since N28
Effect and capability contextthe language owning effects and capabilitiesboth are MISSING as language features
Test-to-definition mappinga relation the compiler ownsunchanged since N27
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓, patch plans ✓each is its own contract
Incremental reparsea lossless CST ✓still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14

N30 — Compact machine diagnostics and progressive disclosure v1 — complete, 2026-09-28

The first executable step toward G74, G75 and G77. nazm.diagnostic-index/1 is every current diagnostic of a root compilation as compiler-owned facts — id, code, severity, file and byte range, owning definition, fix counts — with no prose; nazm.diagnostic-detail/1 is one of them in full on request, the diagnostic exactly as nazm.diagnostic/1 publishes it, with its places in their files and, for each fix, the N29 selector where a semantic patch is plannable. Compact diagnostics never infer structured semantics from diagnostic prose, and a compiler fix and an N29 semantic patch are distinct capabilities. Syntax diagnostics are indexed, bound to a digest of the loaded sources where N28 has no snapshot. nazm diagnostics prints both; nazm-mcp adds nazm.diagnostics and nazm.diagnostic_detail. nazm.diagnostic/1, nazm check --json, the language server and every existing schema are unchanged: SEMANTIC_EPOCH 7, nazm.interface/5; two new machine schemas.

SettledWhere
the index and detail, from nazm-diag, N22, N24, N28, N29crates/nazm-service/src/diagnostics.rs, schema/nazm.diagnostic-index-1.json, schema/nazm.diagnostic-detail-1.json, architecture.md §7.32
nazm diagnostics [--detail ID --state DIGEST]crates/nazm-cli/src/diagnostics.rs
nazm-mcp: nazm.diagnostics, nazm.diagnostic_detailcrates/nazm-mcp/src/main.rs, docs/mcp.md
what it costsperformance.md

Mutation evidence: 18 new mutations; 26 killers verified on the final source — the eighteen and the eight MCP entries of N27–N29; one targeted campaign of 25, all caught at tier 1 (capability-matrix.md §30).

After N29, in dependency order

No item is chosen here; N29 left these standing. Superseded by “After N30” above.

Depends onWhy not before
Patch application, a transactional writepatch plans ✓its own safety milestone: checking the three freshness layers, writing atomically, and reporting what was and was not written
Rename of exported definitionsrename ✓, a project/importer boundaryone root compilation is not every importer; unchanged since N18
A project or importer boundarya manifest, or a declared universe of rootsnothing today says which files may import a module
Fixes of syntax diagnostics as patchesa snapshot of a recovered compilation, or another bindingN28 has no snapshot where syntax needed recovery
Semantic history, or a persistent snapshot storesnapshots ✓unchanged since N28
Effect and capability contextthe language owning effects and capabilitiesboth are MISSING as language features
Test-to-definition mappinga relation the compiler ownsunchanged since N27
Machine-readable diagnostics beyond nazm.diagnostic/1diagnostics ✓done in part by N30: a compact index and detail
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓, patch plans ✓each is its own contract
Incremental reparsea lossless CST ✓still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14

N29 — Minimal semantic patch plan v1 — complete, 2026-09-27

The first executable step toward G72. nazm.patch/1 is an edit the compiler already validates — N18’s rename, or the fix a current diagnostic carries (N24) — as minimal exact-byte edits, bound to the root’s N28 snapshot digest, each edited file’s BLAKE3 digest and each edit’s expected bytes. N29 plans edits but never applies them: a patch is a proposal bound to exact semantic and source state, not permission to mutate files. Exported rename remains refused, because one root compilation is not a complete importer universe; the language server’s closed-file rule is unchanged. nazm patch rename|fix prints a plan; nazm-mcp adds one read-only planning tool, nazm.semantic_patch, and keeps no plan. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, nazm.context/1, nazm.snapshot/1, nazm.delta/1 unchanged; one new machine schema.

SettledWhere
the patch, nazm.patch/1, from N18/N24/N28crates/nazm-service/src/patch.rs, schema/nazm.patch-1.json, architecture.md §7.31
nazm patch rename, nazm patch fixcrates/nazm-cli/src/patch.rs
nazm-mcp: nazm.semantic_patch, typed, read-onlycrates/nazm-mcp/src/main.rs, docs/mcp.md
what it costsperformance.md

Mutation evidence: 16 new mutations; 30 killers verified on the final source — the sixteen, the nine N18 entries in rename.rs and the five MCP entries of N27 and N28; one targeted campaign of 27, all caught at tier 1 (capability-matrix.md §30).

After N28, in dependency order

No item is chosen here; N28 left these standing. Superseded by “After N29” above.

Depends onWhy not before
Semantic patch plans (G72)rename ✓, quick fixes ✓, snapshots ✓done in part by N29: rename and diagnostic-fix plans, never applied
Rename inference, or definition lineagesnapshots ✓, deltas ✓a key’s continuity is a name in a module; lineage needs a contract of its own
Behavioural or body fingerprints beyond exact sourcea semantic IRN28’s source section is exact bytes; nothing finer is sound without one
Test impact, effect and capability deltasa relation the compiler owns, effects and capabilitiestests are not tied to definitions; effects and capabilities are MISSING as language features
Semantic history, or a persistent snapshot storesnapshots ✓the client keeps its baseline; no evidence yet needs server-side history and its retention contract
Test-to-definition mappinga relation the compiler ownsunchanged since N27
Rename of exported definitionsrename ✓unchanged since N18; a snapshot is of one root, not every importer
Edits of files not openrename ✓, quick fixes ✓unchanged since N18
Incremental reparse, or a persistent analysis for MCPa lossless CST ✓each MCP call re-analyses its root; still no evidence that forces a cache and its freshness contract
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14

N28 — Semantic snapshot manifest and semantic delta v1 — complete, 2026-09-27

The first executable step toward G71. nazm.snapshot/1 is one root compilation’s durable functions, records and enums, by DefKey alone, each with one BLAKE3 digest per section the compiler records — exact source, shape, dependencies, related types, references, callers, callees, diagnostics — taken over identities and counts, never offsets or session ids. nazm.delta/1 compares a baseline snapshot, validated strictly as data, with the current compilation: added, removed, and changed with exactly which sections changed. A rename is removed plus added; a comment or a literal is source alone. N28 reports changes in the semantic surfaces Nazm currently records; it is not a proof of behavioural equivalence, and effects, capabilities, tests, history and behavioural equivalence are unsupported, not unchanged. nazm snapshot and nazm delta print them; nazm-mcp adds two read-only tools and keeps no snapshot — the client keeps its baseline. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, nazm.context/1 unchanged; two new machine schemas.

SettledWhere
the snapshot, nazm.snapshot/1, from N17/N18/N20/N21/N22/N25/N27crates/nazm-service/src/snapshot.rs, schema/nazm.snapshot-3.json, architecture.md §7.30
the delta, nazm.delta/1, and baseline validationcrates/nazm-service/src/delta.rs, schema/nazm.delta-3.json
nazm snapshot --root --json, nazm delta --root --baseline --jsoncrates/nazm-cli/src/snapshot.rs
nazm-mcp: nazm.semantic_snapshot, nazm.semantic_delta, statelesscrates/nazm-mcp/src/main.rs, docs/mcp.md
what it costsperformance.md

Mutation evidence: 20 new mutations and five N25/N27 entries re-pointed onto code N28 now shares; 49 killers verified on the final source; one targeted campaign of 25, all caught at tier 1 (capability-matrix.md §30).

After N27, in dependency order

No item is chosen here; N27 left these standing. Superseded by “After N28” above.

Depends onWhy not before
MCP expansionthe context packet ✓, one read-only tool ✓only where a question needs it; each tool is its own contract
Semantic delta (G71)context packets ✓done in part by N28: snapshots and deltas of the sections the compiler records, not behaviour
Test-to-definition mappinga relation the compiler ownstests are not tied to definitions today
Effect and capability contextthe language owning effects and capabilitiesboth are MISSING as language features
Rename of exported definitionsrename ✓unchanged since N18
Edits of files not openrename ✓, quick fixes ✓unchanged since N18
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓not asked for; each is its own contract
Incremental reparse, or a persistent analysis for MCPa lossless CST ✓each MCP call re-analyses its root; no evidence yet forces a cache and its freshness contract
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14

N27 — Semantic context packet v1 and read-only MCP — complete, 2026-09-27

The first AI-facing semantic unit. nazm.context/1 is one function’s, record’s or enum’s exact source and compact links — identity, kind, name, place — to what it uses, the types it names, what uses it, what it calls and what calls it, and its own diagnostics, all read from the layers that already answer them; effects, capabilities, tests and semantic changes are marked unsupported. Durable identities, source-root-relative paths, one deterministic serialisation. nazm context prints it, and nazm-mcp, on the official Rust SDK, serves it as one read-only stdio tool that reads the disk at every call. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6…; one new machine schema.

SettledWhere
the packet, nazm.context/1, from N17/N18/N20/N21/N22/N25crates/nazm-service/src/context.rs, schema/nazm.context-3.json, architecture.md §7.29
nazm context --root --file --byte --jsoncrates/nazm-cli/src/context.rs
nazm-mcp: one read-only stdio tool, disk per call, no other file readablecrates/nazm-mcp/src/main.rs, docs/mcp.md
what it costsperformance.md

Mutation evidence: 13 new mutations, every killer verified; one targeted campaign of 24 (capability-matrix.md §30). Closure correction: the MCP result carries the packet once, and v1 links only entities with a declaration in a file of the compilation — three more mutations, all 16 killers re-verified on the corrected source, one campaign of 16.

After N26, in dependency order

No item is chosen here; N26 left these standing. Superseded by “After N27” above.

Depends onWhy not before
Rename of exported definitionsrename ✓unchanged since N18
Edits of files not openrename ✓, quick fixes ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope, call, structure, symbols, identifiers, call hierarchy ✓done by N27: one packet, one read-only tool
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓not asked for; each is its own contract
Completion after a comma, at an empty label slot later in a listcompletion at a hole ✓not asked for; N26 answers an empty list only
Incremental reparsea lossless CST ✓a hole’s probe re-checks the compilation (about 43 ms on the compiler); warm edits show no delta; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N26 — Incomplete-source semantic anchors and triggered structure completion — complete, 2026-09-27

Completion now answers right after a . or a ( with nothing written yet: a record’s fields after receiver., an enum’s variants after E. or E[T]., a record’s labels after Name( where the module calls no function Name, and a variant’s payload labels after E.V( in a construction or a pattern. The request runs a completion probe — the same parser told the cursor’s offset, which reads a zero-width empty name there, and the same checker, which anchors the hole where it already decides — and answers with N21’s candidates and an empty range. . is the one trigger character. Nothing is recorded by an ordinary analysis, published from the probe, or kept; the unfinished programs stay invalid and nazm check reports them unchanged. No language, interface, schema, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
a probe parse with a hole at the cursor; ordinary parses unchangedcrates/nazm-syntax/src/parser.rs, crates/nazm-syntax/src/lib.rs, architecture.md §7.28
nazm_core::probe; a bare Name(’s record, recorded only in a probecrates/nazm-core/src/lib.rs, crates/nazm-core/src/check/
completion at a hole from structure::candidates, shared with N21crates/nazm-service/src/incomplete.rs, crates/nazm-service/src/structure.rs
. the one completion triggercrates/nazm-cli/src/lsp.rs
what it costs: a hole’s probe is one parse and check of the compilation; no ordinary-path delta once the hole code was moved out of lineperformance.md

Mutation evidence: 8 new mutations and 2 N21 mutations repointed; every killer verified, the four in the parser again on the final source; one targeted campaign of 28, all caught at tier 1 (capability-matrix.md §30).

After N25, in dependency order

No item is chosen here; N25 left these standing. Superseded by “After N26” above.

Depends onWhy not before
Completion after a bare . or (, and a . triggerstructure ✓done by N26
Rename of exported definitionsrename ✓unchanged since N18; call hierarchy is complete only for the compilation it was prepared in, so it proves nothing about other importers
Edits of files not openrename ✓, quick fixes ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope, call, structure, symbols, identifiers and call hierarchy ✓not started
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓not asked for; each is its own contract
Incremental reparsea lossless CST ✓the interleaved N24/N25 comparison detected no warm-edit delta; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N25 — Semantic call hierarchy: prepare, incoming and outgoing calls — complete, 2026-09-26

An editor can now ask which source functions call a function and which it calls, one level at a time. An item is a function the checker declared from source, prepared from its declaration or a call through the reference index, at its outline symbol’s ranges; an edge is a checked call to such a function, attributed to the body the checker recorded it in, grouped by the function at the other end with every callee name. No per-call state, no graph and no item table: each answer is derived from the current analysis and dropped. An item is bound to the compilation it was prepared in and the generation it was prepared at, and is unanswered after any change or once its root closes. It is complete only for that compilation snapshot — not every caller in a project — so exported rename stays refused. No language, interface, schema, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
prepare_call_hierarchy, incoming_calls, outgoing_calls, Locator; function_symbol shared with the outlinecrates/nazm-service/src/hierarchy.rs, crates/nazm-service/src/symbols.rs, architecture.md §7.27
textDocument/prepareCallHierarchy and callHierarchy/incomingCalls / outgoingCalls, UTF-16, stale item nullcrates/nazm-cli/src/lsp.rs
what it costs: no detected analyse/edit/RSS delta; no persistent state; incoming over the compiler about 0.5 ms; +65,536 bytes of binaryperformance.md

Mutation evidence: 14 new, 2 repointed, all 16 killers verified on the final source on their first run; one targeted campaign of 24, all caught at tier 1, in one session (capability-matrix.md §30).

After N24, in dependency order

No item is chosen here; N24 left these standing. Superseded by “After N25” above.

Depends onWhy not before
Call hierarchychecked calls ✓, references ✓, symbols ✓done by N25
Completion after a bare . or (, and a . triggerstructure ✓needs an anchor for source that does not parse
Rename of exported definitionsrename ✓unchanged since N18
Edits of files not openrename ✓, quick fixes ✓unchanged since N18: neither a rename nor a fix edits a closed file
MCP, semantic context packetsa language service ✓, scope, call, structure, symbols and identifiers ✓not started
semanticTokens/range and /full/deltasemantic tokens ✓no evidence justifies them
Refactors, source actions, fix-allquick fixes ✓not asked for; each is its own contract
Incremental reparsea lossless CST ✓the interleaved N23/N24 comparison detected no warm-edit delta; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N24 — Diagnostic-backed code actions and versioned fix plans — complete, 2026-09-26

The fixes the compiler already attaches to its diagnostics now reach an editor as quick fixes: each current diagnostic the requested range touches has one plan per fix — its applicability, description and precondition, the generation, and one edit tied to the open document’s version with the bytes it replaces — held to the freshness law renames answer to, and sent as a versioned documentChanges edit. Nothing is invented from a code or message, and the server writes nothing. nazm fix’s seven skip reasons each have a test that reaches them, and area 24 is VERIFIED. No language, interface, schema, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, nazm.fix/1, fixpoint 0e1a40e6….

SettledWhere
fix_plans, FixPlan, fix_plan_is_current; file_is_current shared with renamecrates/nazm-service/src/fixes.rs, crates/nazm-service/src/rename.rs, architecture.md §7.26
textDocument/codeAction quick fixes, versioned, UTF-16; no resolve, refactor, source or fix-allcrates/nazm-cli/src/lsp.rs
the seven nazm fix skip reasons, each reached by a testcrates/nazm-cli/src/fix.rs, diagnostics.md
what it costs: no detected analyse/edit/RSS delta; no persistent state; a document’s plans in microseconds, a request about 0.1 ms; +65,536 bytes of binaryperformance.md

Mutation evidence: 17 new, 2 repointed, all 20 affected killers verified on the final source (one after its test was extended to reach the case it guards); one targeted campaign of 29, all caught at tier 1, in one session (capability-matrix.md §30).

After N23, in dependency order

No item is chosen here; N23 left these standing. Superseded by “After N24” above.

Depends onWhy not before
Code actionsa language service ✓, nazm.fix/1 ✓quick fixes done by N24
Call hierarchychecked calls ✓, references ✓, symbols ✓not asked for
Completion after a bare . or (, and a . triggerstructure ✓needs an anchor for source that does not parse
Rename of exported definitions; edits of files not openrename ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope, call, structure, symbols and identifiers ✓not started
semanticTokens/range and /full/deltasemantic tokens ✓a full request is 9 ms on the largest file; no evidence justifies a cache
Incremental reparsea lossless CST ✓the interleaved N22/N23 comparison detected no warm-edit delta; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N23 — Semantic identifier classification and LSP semantic tokens — complete, 2026-09-26

What each identifier of a document is — its class, whether it declares or refers, and the compiler’s identity for what it names — is now answered from what the checker recorded at its exact span: the reference index’s entities, built-in calls, and one narrow new record of the written built-in and type-parameter names the checker resolved. An identifier the checker did not resolve is not classified. semanticTokens/full is that answer under a fixed legend. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
Resolution::written_type, written where the checker resolves a built-in or type-parameter namecrates/nazm-sema/src/resolve.rs, crates/nazm-core/src/check/, architecture.md §7.25
semantic_identifiers, SemanticIdentifier, SemanticClass, Role, SemanticTargetcrates/nazm-service/src/semantic.rs
textDocument/semanticTokens/full under a fixed legend, relative and in UTF-16; no range, no deltacrates/nazm-cli/src/lsp.rs
what it costs: +~180 kB resident with the compiler open (1,989 recorded names); no detected warm-edit delta; a possible sub-millisecond analyse cost not resolved by the measurement; a whole compiler file in 3 ms, 9 ms over the protocol; no binary growthperformance.md

Mutation evidence: 14 new, all 14 direct killers verified on the final source, 2 re-verified; one targeted campaign of 26, all caught at tier 1, in one session (capability-matrix.md §30).

After N22, in dependency order

No item is chosen here; N22 left these standing. Superseded by “After N23” above.

Depends onWhy not before
Semantic tokens, code actionsa language service ✓, symbols ✓semantic tokens done by N23
Call hierarchychecked calls ✓, references ✓, symbols ✓not asked for
Completion after a bare . or (, and a . triggerstructure ✓needs an anchor for source that does not parse
Rename of exported definitions; edits of files not openrename ✓unchanged since N18; workspace symbols cover what is loaded, which is not every possible importer, so they do not lift it
MCP, semantic context packetsa language service ✓, scope, call, structure and symbols ✓not started
Incremental reparsea lossless CST ✓N22 adds no analysis-time work, and the interleaved N21/N22 comparison detected no warm-edit delta; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N22 — Semantic document and workspace symbols — complete, 2026-09-26

Which declarations exist, where each is written and what contains it is now answered from the checker’s definition tables and the parsed items their decl indices name — derived on demand, with nothing kept. One document’s outline is its declarations, nested, in source order; the workspace is every declaration of every file the open documents’ compilations load, once each, identified by file, kind and name span. It is not a project index and does not lift N18’s exported-rename refusal. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
document_symbols, workspace_symbols, Symbol, SymbolKind, WorkspaceSymbolcrates/nazm-service/src/symbols.rs, architecture.md §7.24
textDocument/documentSymbol (nested, or flat for a client without hierarchy) and workspace/symbol (no resolve)crates/nazm-cli/src/lsp.rs
what it costs: no detected analyse/edit/RSS delta in the interleaved comparison; no persistent symbol table; an outline in microseconds, a workspace query 2.2 ms over the compiler as four programs; +65,536 bytes of binaryperformance.md

Mutation evidence: 13 new, all 13 direct killers verified on the final source (one after its killer was moved to the test that observes it), 2 re-verified; one targeted campaign of 24, all caught at tier 1, in one session (capability-matrix.md §30).

After N21, in dependency order

No item is chosen here; N21 left these standing. Superseded by “After N22” above.

Depends onWhy not before
Document and workspace symbolsa language service ✓, structure ✓done by N22
Semantic tokens, code actionsa language service ✓not started
Call hierarchychecked calls ✓, references ✓not asked for
Completion after a bare . or (, and a . triggerstructure ✓needs an anchor for source that does not parse
Rename of exported definitions; edits of files not openrename ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope, call and structure at a position ✓not started
Incremental reparsea lossless CST ✓the contended interleaved N20/N21 comparison detected no N21-specific warm-edit delta; there is still no evidence that forces incremental reparse
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N21 — Typed structure at a position, structure completion, constructor signature help — complete, 2026-09-26

Which record, enum or variant a field, variant or label position belongs to is now answered from identities the checker already recorded, plus one fact it recorded nowhere before — the type an unresolved member name was looked for on, written only where a lookup fails. Completion of fields, variants and labels, and signature help for record and variant constructions, are that answer. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
Resolution::looked_up_on, written where a field or variant lookup failscrates/nazm-sema/src/resolve.rs, crates/nazm-core/src/check/, architecture.md §7.23
structure_at, structure completion, constructor_help, help_atcrates/nazm-service/src/structure.rs, crates/nazm-service/src/signature.rs
fields as Field, variants as EnumMember, constructor help over textDocument/signatureHelpcrates/nazm-cli/src/lsp.rs
what it costs: no detected analyse/edit/RSS delta in the contended interleaved comparison; no persistent clean-code structure table; structure queries measured separately (microseconds, whole-compiler queries dominated by finding the token)performance.md

Mutation evidence: 15 new, all 15 direct killers verified on the final source; one targeted campaign of 34, all caught at tier 1, over three sessions (capability-matrix.md §30).

After N20, in dependency order

No item is chosen here; N20 left these standing. Superseded by “After N21” above.

Depends onWhy not before
Member, variant-dot, construction-label and payload-label completion; signature help for constructionscompletion ✓, signature help ✓, field identity ✓each is a structure-aware contract — the type before ., the record being built — not a call
Document and workspace symbolsa language service ✓not started
Semantic tokens, code actionsa language service ✓not started
Call hierarchychecked calls ✓, references ✓a consumer of the records N20 added, and not asked for
Rename of exported definitions; edits of files not openrename ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope and call at a position ✓not started
Incremental reparsea lossless CST ✓N20 measured a warm edit of the whole compiler at 84.7–86.4 ms on one CPU, 3–5 ms over N19; still no evidence that forces it
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N20 — Call-site semantic query and signature help — complete, 2026-09-26

Which call a position is in, and with which signature, is now answered from what the checker recorded when it checked the call — the resolved callee, the signature its arguments were checked against, what a generic call settled — with the tree deciding only which argument list and which argument. Signature help is that answer rendered by the one signature renderer hover and completion also use. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
CheckedCall and Instantiation, written by the checkercrates/nazm-sema/src/resolve.rs, crates/nazm-core/src/check/, architecture.md §7.22
call_at, signature_help, the structured Signature and its one renderercrates/nazm-service/src/signature.rs
textDocument/signatureHelp, triggered by ( and ,, UTF-16 label offsetscrates/nazm-cli/src/lsp.rs
what it costs: 6 µs a query on the compiler; 2–5 ms more analyse, 3–5 ms more per warm edit, 9 MB more residentperformance.md

Mutation evidence: 14 new, 1 renamed, 1 candidate found equivalent and left uncatalogued; all 16 direct killers verified on the final source; one targeted campaign of 23, all caught at tier 1 (capability-matrix.md §30).

After N19, in dependency order

No item is chosen here; N19 left these standing. Superseded by “After N20” above.

Depends onWhy not before
Signature helpscope at a position ✓needs the call being written and which argument, which the scope does not say
Member, variant-dot, construction-label and payload-label completioncompletion ✓, field identity ✓each is a structure-aware contract — the type of what precedes ., the record being built — not lexical scope
Document and workspace symbolsa language service ✓not started
Semantic tokens, code actionsa language service ✓not started
Rename of exported definitions; edits of files not openrename ✓unchanged since N18
MCP, semantic context packetsa language service ✓, scope at a position ✓not started
Incremental reparsea lossless CST ✓N19 measured a warm edit of the whole compiler at about 81 ms on one CPU; the evidence that would justify it still does not exist
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N19 — Semantic scope-at-position and context-aware completion — complete, 2026-09-25

What may be written at a position is now recorded by the checker as it decides it — frames, visibility, the binding each hides, type parameters, module environments less the names it refused — and read back without resolving anything; completion of a value, a call head or a type is that answer, filtered by what is written, for the current document’s compilation only. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
the scope trace, written by the checker; visible_atcrates/nazm-sema/src/scope.rs, crates/nazm-core/src/check/, architecture.md §7.21
which files needed recoveryAnalysis::syntax_errors in crates/nazm-core/src/lib.rs
scope_at, completion, contexts, completenesscrates/nazm-service/src/completion.rs
textDocument/completion, invoked, whole-identifier replacement in UTF-16crates/nazm-cli/src/lsp.rs
what it costs: 0.7 ms a scope query and 2.1 ms a completion on the compilerperformance.md

Mutation evidence: 14 new, 1 repointed, 1 renamed; all 16 direct killers verified on the final source; one targeted campaign of 17 — 16 caught at tier 1 and 1 at tier 2, no survivor (capability-matrix.md §30).

After N18, in dependency order

No item is chosen here; N18 left these standing. Superseded by “After N19” above.

Depends onWhy not before
Rename of exported definitionsrename ✓needs a provably complete set of importers — a finite project boundary the service does not have; N18 refuses rather than guess
Edits of files that are not openrename ✓the protocol cannot make a closed file’s content a precondition; needs an application path that can, or a client contract that does
Other code actions, structured edits beyond renamea lossless CST ✓, a plan model ✓each needs its own semantic contract
Incremental reparsea lossless CST ✓N18 measured a warm edit of the whole compiler at about 83 ms and a validated rename at about 93 ms on one CPU; the evidence that would justify it still does not exist
Completion, signature helpa language service ✓each needs its own semantic contract — what is in scope at a position — which the resolution does not record
Symbols (document, workspace)a language service ✓not started
Semantic tokensa language service ✓unchanged
MCPa language service ✓not started
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N18 — Safe semantic rename and stale-safe edit plans — complete, 2026-09-25

Every written user-type name and enum qualifier is now an occurrence of the definition it names, which makes the occurrence set complete for every kind of entity; on that, a rename is a validated plan — the entity’s recorded occurrences only, re-checked in memory, partition- preserving, tied to the exact text and version it was made from — for locals and private definitions, served as a versioned WorkspaceEdit. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
the checker records every written type name and qualifier; Enum is an entitycrates/nazm-core/src/check/, crates/nazm-sema/src/{resolve,references}.rs, architecture.md §7.20
coverage per kind, exhaustive; a corpus gate for new positionsReferenceTarget::rename_coverage, crates/nazm-service/tests/references.rs
the plan, its scope rule, its validation and its preconditionscrates/nazm-service/src/rename.rs
prepareRename, rename, versioned documentChanges onlycrates/nazm-cli/src/lsp.rs
what it costs: a rename of the compiler’s private function in about 93 msperformance.md

Mutation evidence: 14 new, all 14 killers verified; one targeted campaign of 18 — 18 caught at tier 1, no survivor (capability-matrix.md §30).

N19 has not started.

After N17, in dependency order

No item is chosen here; N17 left these standing. Superseded by “After N18” above.

Depends onWhy not before
Safe structured edits, renamea lossless CST ✓, references ✓ for the entities whose coverage is completeN17’s occurrence set is complete for functions, locals, variants, fields and payload fields, and turning it into validated edits — and deciding what a rename across files not open means — is its own contract. It is not complete for type names: a record’s name written in an annotation, and the enum name in E.V(…), have no reference identity, so a record or enum rename would miss them. Safe rename is possible only for an entity whose coverage is complete; record and enum rename depends on the checker recording type-name occurrences first. The milestone that adds rename must either add that prerequisite first or refuse rename for every category whose occurrence set is incomplete
Incremental reparsea lossless CST ✓N17 measured a warm edit of the whole compiler at about 81 ms on one CPU, index included; the evidence that would justify it still does not exist
Completion, signature helpa language service ✓each needs its own semantic contract — what is in scope at a position — which the resolution does not record
Symbols (document, workspace)a language service ✓not started
Type names in annotations as referencesreferences ✓the resolution records no entity at a written type name; the checker would have to record one
Semantic tokens, code actionsa language service ✓unchanged
MCPa language service ✓not started
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
? on Option, and conversion between error typestraitsunchanged

N17 — Semantic reference index and references query — complete, 2026-09-25

Given an occurrence that resolves to an entity, where every use of that same entity is in the current program snapshot: one reference index per analysis, derived from the resolution alone, behind LanguageService::references and textDocument/references. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
what a reference is, and the index that reads the resolution backwardscrates/nazm-sema/src/references.rs, architecture.md §7.19
a variable use records which function’s slot it is; a construction label, which fieldLocalRef in crates/nazm-sema/src/resolve.rs, crates/nazm-core/src/check/
definition and references as one lookup; the query over every open compilationcrates/nazm-service/src/service.rs
textDocument/references, includeDeclaration, UTF-16 at the boundary onlycrates/nazm-cli/src/lsp.rs
what it costs: 3.8 ms of index per compiler analysis, 1.8 ms a queryperformance.md

Mutation evidence: 16 new and 1 repointed, all 17 killers verified uncontended; one targeted campaign of 19 — 19 caught at tier 1, no survivor (capability-matrix.md §30).

N18 has not started.

After N16, in dependency order

No item is chosen here; N16 left these standing. Superseded by “After N17” above.

Depends onWhy not before
Incremental reparsea lossless CST ✓N16 measured a warm edit of the whole compiler at about 80 ms on one CPU; the evidence that would justify it does not exist yet
Structured editsa lossless CST ✓, a language service ✓no edit command exists
Completion, signature helpa language service ✓each needs its own semantic contract — what is in scope at a position — which the resolution does not record
References, renamea language service ✓need every use of an identity, across modules not open
Semantic tokens, code actionsa language service ✓unchanged
MCPa language service ✓not started
nazm explain-costnothing aboveindependent

N16 — Language service core and minimal LSP — complete, 2026-09-25

nazm lsp serves diagnostics, definition and hover over an editor’s unsaved buffers, as an adapter over a protocol-independent language service that answers from the loader, parser, checker and resolution every command uses. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
one loader for the CLI and the editor, reading bytes through a Sourcescrates/nazm-service/src/load.rs (moved from nazm-cli)
open buffers, versions, one current analysis per documentcrates/nazm-service/src/service.rs, architecture.md §7.18
one parse-and-check pipeline that also hands back its resolutionnazm_core::analyse
a local’s definition by slot, not by spellingLocalDef::span in crates/nazm-sema/src/resolve.rs
the protocol shell, UTF-16 at the boundary onlycrates/nazm-cli/src/lsp.rs
what it costs: about 80 ms per warm edit of the whole compiler on one CPUperformance.md

Mutation evidence: 14 new, all 14 killers verified uncontended; one targeted campaign of 15 — 15 caught (14 at tier 1, 1 at tier 3, then tier 2 once the moved loader was given back to the cli profile), no survivor (capability-matrix.md §30).

N17 has not started.

After N15, in dependency order

No item is chosen here; N15 left these standing.

Depends onWhy not before
A language serverunits ✓ + durable identity ✓ + reuse ✓ + a lossless CST ✓every listed blocker is met; it must read the checker’s results rather than re-implement them
Incremental reparsea lossless CST ✓N15 parses whole files; the tree is shaped for subtree reuse and does none
Structured editsa lossless CST ✓the tree finds and reproduces a node by position (N15’s test); no edit command exists
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓unchanged since N14
A requirement on a record’s or an enum’s parametera requirement ✓unchanged
Cross-unit inlining of generic instancesnative units ✓unchanged
? on Option, and conversion between error typestraitsunchanged
A compact enum representationvariants ✓, Vec[T] ✓unchanged
Copy elision, specifiedrecords ✓, variants ✓, generics ✓unchanged

N15 — Lossless CST and local error recovery — complete, 2026-09-25

One lossless scan feeds the one parser, which builds the abstract tree and a lossless concrete tree from the same decisions. The tree reproduces every input byte — whitespace, comments, punctuation, refused characters — and a malformed statement no longer costs the rest of its function: it becomes an error node, and what follows it is still syntax. No language, interface, cache-key or bootstrap change: SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6….

SettledWhere
one lossless scan; the parser’s tokens and the formatter’s comments are views of itcrates/nazm-syntax/src/lexer.rs
the tree, its kinds, trivia placement, a wrapper that keeps cstree inside the cratecrates/nazm-syntax/src/cst.rs, architecture.md §7.17
one parser for both trees; statement-level recovery; cascades withheldcrates/nazm-syntax/src/parser.rs
losslessness, recovery, the two trees agreeing, terminationcrates/nazm-syntax/tests/cst.rs, capability-matrix.md area 1
what it costs: 2.0× parse time on real codeperformance.md

Mutation evidence: 16 new and 3 repointed; the 17 of those 19 that list a killer (fourteen distinct tests) verified, uncontended; one targeted campaign of the 26 entries on the syntax crate — 25 caught (19 at tier 1, 6 at tier 2), no survivor, and the known nesting-unbounded MUTANT CRASH unchanged (capability-matrix.md §30).

N16 has not started.

After N14, in dependency order

Depends onWhy not before
A lossless CSTnothing abovestill independent, still the last AI-native item, and now the largest item nothing blocks
nazm explain-costnothing aboveindependent
User-defined traits, or any capability beyond equalitygenerics ✓, a requirement ✓N14 covered the one abstraction a program needed with a built-in requirement, and its dogfood found no code wanting another. The next capability should be forced by code that needs behaviour the language cannot derive — an ordering, a conversion between error types — not by the symmetry of having one bound
A requirement on a record’s or an enum’s parametera requirement ✓refused today; would need every instance checked wherever it is written, and no program needs it
Cross-unit inlining of generic instancesnative units ✓measured by N14: an instance lives in its own unit, so same[Int] costs a call a hand-written same_int does not (performance.md) — with or without a requirement
? on Option, and conversion between error typestraitsunchanged
A compact enum representationvariants ✓, Vec[T] ✓unchanged
Copy elision, specifiedrecords ✓, variants ✓, generics ✓unchanged

Recommended next: a lossless CST — the item nothing blocks and nothing has displaced, now that the equality wall is gone. N15 took it (above). Not traits: no program here yet needs user-defined behaviour abstraction, and N14’s evidence is that the built-in requirement met the need N13 exposed.

N14.1 — Contained performance calibration — complete, 2026-09-25

Tooling, between N14 and whatever follows it; no language, compiler, interface, cache-key or bootstrap change (SEMANTIC_EPOCH 7, nazm.interface/5, fixpoint 0e1a40e6…). A contained workload now runs under a named execution profile — CPU quota, Cargo jobs and test threads as one value — inside the same memory, swap, pid, storage and deadline ceilings. The workspace suite and the selfhost suite default to P4T4 (3.03× and 3.44×, measured); everything else stays P1, mutation because both parallel profiles tried crossed the frozen total-memory gate with identical verdicts.

SettledWhere
ExecutionProfile, P1 and P4T4, one owner for quota, jobs and threads; --profilextask/src/contained.rs, xtask/src/main.rs
the measurements, the gates frozen before selection, why P6 and parallel mutation were refuseddocs/performance.md, Development and evidence pipeline parallelism
a campaign’s identity includes its parallelism and CPU quota; a resume under another profile reuses nothingxtask/src/campaign.rs, xtask/tests/lifecycle.rs
the serial rule, what was relaxed and what was notdocs/runbook.md, Serial execution

No language milestone has started since N14.

N14 — A type parameter may require equality — complete, 2026-09-25

fn same[T: Equality](a: T, b: T) -> Bool { a == b } is valid; without : Equality it is still refused. Every argument, written or inferred, concrete or a caller’s own parameter, is checked against the requirement by N13’s one derivation, so Box[T], Option[T] and Result[T, E] with both required compare in a bounded body and Vec[Int] never satisfies it.

SettledWhere
the rule, one built-in capability, functions only, statically checkeddocs/spec.md, A type parameter may require equality
one set of required parameters, read by N13’s derivation and nowhere elsecrates/nazm-sema/src/udt.rs, generic.rs, architecture.md §7.16
call satisfaction, forwarding, N0364/N0365crates/nazm-core/src/check/
nazm.interface/5, requirements persisted by position; SEMANTIC_EPOCH 6 → 7crates/nazm-iface/src/wire.rs, crates/nazm-cache/src/identity.rs
nothing at run timecrates/nazm-cli/tests/constraints.rs
the same rule in the compiler written in Nazm; a new fixpoint, 0e1a40e6…compiler/, bootstrap.md

Mutation evidence: 22 new and 6 repointed, 27 killers verified; one targeted campaign of 40 — 40 caught (36 at tier 1, 4 at tier 2), no survivor (capability-matrix.md §30). No honest dogfood candidate: the compiler has no generic helper that needs a capability.

N15 has not started.

After N13, in dependency order

Depends onWhy not before
Constrained generics — a way for a definition to require a capability of Tgenerics ✓, derived equality ✓N13’s finding, and the first program that needs one: a concrete Box[Int] compares, and fn same_box[T](a: Box[T], b: Box[T]) cannot, because nothing can say “T has equality”. Equality is the one capability the language now derives for concrete types that a generic body cannot ask for. What the mechanism is — a trait, a built-in bound, something else — is the milestone’s decision, not this table’s
? on Option, and conversion between error typestraitsunchanged
Sequence and channel equalitya decisionstill unmade on purpose: same storage or same contents. N13 refuses it and everything containing it
A compact enum representationvariants ✓, Vec[T] ✓unchanged; an equality helper reads one slot of the one-slot-per-variant aggregate
Copy elision, specifiedrecords ✓, variants ✓, generics ✓unchanged
A lossless CSTnothing aboveunchanged; still independent

Recommended next: constrained generics — recommended from N13’s evidence, not committed to. N14 took it (above). The alternatives are unchanged and smaller: a lossless CST, and nazm explain-cost.

N13 — Derived structural equality — complete, 2026-09-25

== and != apply to two operands of one type when that type has equality, and for a record, an enum or a concrete generic instance it is derived: every field, every payload field of every variant, after substitution. Option and Result get it as the ordinary enums they are. Vec, Ints, Strs, Chan and an unconstrained T do not have it, and neither does anything that contains one.

SettledWhere
the rule, nominal and static over every variantdocs/spec.md, Equality is derived
one derivation beside cleanup and task safety, independent of bothcrates/nazm-sema/src/udt.rs, architecture.md §7.15
the interpreter’s relation, and a native helper per compared type — tags first, then the active slot alonecrates/nazm-core/src/eval/, crates/nazm-lir/src/emit.rs
the same derivation and helpers in the compiler written in Nazmcompiler/analyse.nz, compiler/emit.nz
SEMANTIC_EPOCH 5 → 6; interface schema unchanged at nazm.interface/4crates/nazm-cache/src/identity.rs
the compiler’s completion states an enum, compared with ==compiler/analyse.nz, performance.md
a new fixpoint, 76598c43…bootstrap.md

Mutation evidence: 33 new mutations and 13 repointed, each with its regression test; one targeted campaign of 58 — 57 caught (45 at tier 1, 12 at tier 2, none at tier 3) and one genuine survivor, a use-after-free no supported configuration can observe, kept live as a known limitation (capability-matrix.md §30).

N14 followed it (above).

N12.2 — Mutation harness v2 — complete, 2026-09-25

Evidence infrastructure between N12.1 and N13; no language, compiler, interface, cache-key or bootstrap change. A mutant now stops at the first tier that sees it — a verified killer, then a focused profile, then the workspace suite — and only the workspace suite can report SURVIVED. The same 27 N12.1 mutants took 523 s instead of 10,782 s, and the whole catalogue ran for the first time: 233 of 233 accounted for in 10,686 s.

SettledWhere
tiered escalation, the full strategy kept as the oracle, identical verdicts on a differential samplextask/src/campaign.rs, docs/capability-matrix.md §30
typed killer and profile metadata, validated in cargo xtask check; --verify-killer, --planxtask/src/plan.rs, xtask/mutations/mutations.toml
one subprocess runner: own process group, tree kill at a deadline, a watchdog if the harness diesxtask/src/procs.rs
a journal bound to a campaign identity, --resume, bounded sessionsdocs/runbook.md “Mutation campaigns”
the N13 mutation-authoring workflow: regression test, entry, verified killerdocs/runbook.md
found on the way: N12.1’s group kill did nothing in the container, memory.rs had no deadline, two catalogue entries had drifted, one was equivalentdocs/capability-matrix.md §30

N13 followed it: its mutations arrived with their regression tests and killers verified by --verify-killer (above).

N12.1 — Core prelude identity and native value-block parity — complete, 2026-09-24

No new source concept. The native backends and the compiler written in Nazm now compile every block the language already accepted as a value, and that compiler finds the core prelude by its key rather than by its position.

SettledWhere
one lowering for a value block; Expr::Block and Stmt::Match; the join and ownership at a block’s endarchitecture.md §7.14, crates/nazm-lir
{ as an operand, blockexpr, and its completion, in the compiler written in Nazmcompiler/parse.nz, compiler/analyse.nz, compiler/emit.nz
the prelude keyed @core/prelude and resolved once; a project path cannot hold the keycompiler/module.nz, compiler/analyse.nz
SEMANTIC_EPOCH 5 and nazm.interface/4, both unchanged: no accepted program and no persisted shape movedcrates/nazm-cache/src/identity.rs, crates/nazm-iface
the first Option inside the compiler, replacing a -1 sentinelcompiler/analyse.nz, record_owned; performance.md

N12 — Result, Option, typed error values and ? — complete, 2026-09-24

Typed failure as a value, in both compilers. Result[T, E] and Option[T] are ordinary generic enums declared by a toolchain-owned core prelude that every module imports implicitly; ? propagates the core Result — recognised by definition, never by name or shape — as a match with a return in one arm. No exceptions, no unwinding, no conversion.

SettledWhere
the prelude, its identity and visibility, the reserved names, ?’s rule, order, cleanup and ownershipspec.md, Typed error values
one module with a toolchain-owned key, attached last; ? resolved once and lowered as a matcharchitecture.md §7.13
@core/prelude is disjoint from every project keycrates/nazm-sema/src/key.rs
persisted interfaces share a definition’s identity across one compilationcrates/nazm-iface/src/wire.rs, rehydrate_into
nazm.interface/4 unchanged; SEMANTIC_EPOCH 5crates/nazm-iface, crates/nazm-cache/src/identity.rs
the compiler written in Nazm does all of it, loads the same prelude, and returns its front end as a Resultcompiler/*.nz, bootstrap.md

Two defects found on the way, both fixed and held by tests. Rehydration gave every interface its own copy of the types it mentioned, so a Result carried by a dependency’s interface was not the prelude’s: harmless while no two interfaces shared a type, decisive for ?. And a native build produced an empty unit and object for every module that declared no function; it produces none now.

N11 — Parametric generics and Vec[T] — complete, 2026-09-23

First-order parametric polymorphism, in both compilers. Records, enums and functions declare type parameters; types are applied with […]; a generic definition is checked once, parametrically; call-site type arguments are written or inferred from the arguments, never from the expected result. One generic container, Vec[T], follows the sequence law: a task-unsafe mutable handle whose elements are copied, replaced, appended and removed by T’s own law.

SettledWhere
syntax, identity, parametric checking, inference, Vec[T], the ownership-cycle rulespec.md, Generics
an applied type is an interned entry with substituted fields; completion is a worklistarchitecture.md §7.12
nazm.interface/4: parameters are positions, so renaming changes no bytecrates/nazm-iface/src/wire.rs
monomorphisation, one artefact per instance, symbols from canonical type keys, N0357/N0358crates/nazm-lir/src/instance.rs, symbol.rs
an ownership cycle through a Vec is N0359; acyclic nesting and phantom parameters stay legalcrates/nazm-sema/src/udt.rs
the compiler written in Nazm does all of it, and holds its diagnostics in a Vec[Diag]compiler/*.nz, bootstrap.md

The finding that justified it came true in the dogfood: the self-hosted compiler’s diagnostics were four parallel arrays kept the same length by care, and are one Vec of records now. The finding N11 leaves is the one above — a Vec of diagnostics still cannot be returned as a failure.

The generic conformance corpus found one real defect in the reference backend on its first run: a unit that declared an instance never carried the types in that declaration’s signature, so or_else[Str] taking a Maybe[Str] the caller never bound was declared with <enum>. Fixed in crates/nazm-lir/src/lower.rs, held by a_call_carries_the_types_its_callee_is_declared_with.

N10.2 — Selfhost completion and diagnostic parity — complete, 2026-09-23

The two gaps N10.1 left, both in programs the reference refuses, closed before generics make them expensive. No semantics changed; no accepted program changed meaning, and the Nazm compiler’s IR for every accepted program in the corpora is byte-identical to N10.1’s.

The cause was the same one N10.1 named, one level on. The reference’s Completion has three states and the Nazm checker had two: N10.1 added never completes, and completes with no value was still the type code unknown, which also meant “already reported”. So a value position given nothing was accepted — let x = if c { 1 }; became alloca void — and an if whose branches disagreed was typed by one of them and handed clang a mistyped phi.

SettledWhere
one completion per node, Value, Unit or Diverges, never inferred from the typearchitecture.md §7.11
N0300 for a value position given nothing, decided in one place, at the reference’s spancompiler/analyse.nz, needs_value
the if join in the reference’s order: a branch that leaves defers; two values must agree; a value with nothing is N0302the same
a body and a return are held to the signature, which the Nazm checker had never donethe same
a match refused for its scrutinee checks no arm, as the reference’s does notthe same
a match of no value discards the value its value arms produce, and gives it backcompiler/emit.nz, discard_branch_value

The last is the one emitter change, and it is a consequence rather than a rule: the reference accepts match e { E.A() => int_to_str(i), E.B() => if c { … }, }; as a statement, and once the checker stopped giving that match its value arm’s type, that arm’s value had nowhere to go. The reference’s native backend refuses the shape as outside its subset; the Nazm compiler compiles it and agrees with the interpreter, strings reclaimed.

N10.1 — Transfer expressions and selfhost parity — complete, 2026-09-23

A correction between N10 and N11, and no new language: spec.md is unchanged. N10’s evidence exposed one older divergence, and it had to close before the type system gets more complex, because what it is about — whether an expression produced a value — is what every generic container will ask of every element.

#![allow(unused)]
fn main() {
let v = pick(int_to_str(i), if i == 1 { continue; } else { i });
}

The reference compiled it, and the compiler written in Nazm emitted void %24 as the second argument. The cause was completion not being represented: its checker kept one integer per node, in which a statement, an error and a branch that leaves were all unknown, and it typed an if by its then-branch; its emitter opened every join whether a branch reached it or not. The repair is one bit per node in each — never completes in the checker, is the block live in the emitter, asked in one place — and architecture.md §7.11 says why that and not an enum.

The audit that followed found three more, and each is a transfer rule the reference already had:

FoundSinceNow
a break, continue or return out of a scope did not join it, so a task’s failure was lost and a value printed insteadN7, selfhost onlyjoined, innermost first, as the reference’s join_through
a statement after one that leaves was compiled rather than refused (N0313)always, selfhost onlyrefused, once per run, as the reference refuses it
a value that never arrives was unknown where no type is expected, so a match over one was accepted and a let of one had a slot of no typealways, selfhost onlyInt, the reference’s value_type(e, None)

And one that was not the Nazm compiler’s: == on two strings never gave its operands back, in both native backends, with no transfer anywhere near it. The interpreter was right.

SettledWhere
a transfer is never a value: no operand, no incoming, no store, no call is emitted for itarchitecture.md §7.11
interpreted and compiled, the compiler written in Nazm emits byte-identical IR for every casea_transfer_in_a_value_position_is_never_a_value
the original reproducer is permanent, byte for byte, in the corpus and in the conformance set C2 and C3 compilecrates/nazm-cli/tests/transfers/, compiler/conformance/transfer_argument.nz

What it does not settle is recorded in bootstrap.md: the self-hosted checker still has no Unit rule (N0300, “this produces no value”) and does not compare an if’s two branch types (N0302). Both concern programs the reference refuses, so neither is a divergence in the accepted language — but the compiler written in Nazm fails on them rather than refusing them by name. Both closed by N10.2, above.

N10 — Variants and exhaustive pattern matching — complete, 2026-09-23

enum State { Ready, Done(code: Int), } with match. Closed nominal sum types with named payload fields, qualified construction, exhaustive variant matching with named payload bindings, module visibility, a persisted shape, and native code — in the reference compiler, the interpreter and the compiler written in Nazm.

The milestone asked whether the model N7–N9 built survives the ownership question becoming dynamic. A record owns what all its fields own; an enum owns what the active variant’s fields own, which is a value the program carries rather than a fact about the type. The answer is that Owns gained one variant and no consumer gained a case: copy and release are still one call per site, and the branch lives in a generated helper — in the emitted program, where the recursion already lived.

The asymmetry that fell out of it is worth keeping. Needs cleanup and may cross into a task stayed static and quantify over every variant; copy and destroy became dynamic and act on one. So enum Work { None, Values(xs: Ints), } may not cross into a task even while it holds None — what a spawn is handed is a value of a type, and the guarantee is about the type.

Cycles was satisfied the same way a second time, over one graph: records and enums form a single inline-containment graph, and a cycle anywhere in it is refused (N0336). A choice between leaves is a leaf.

SettledWhere
enum and match as the keywords, Token.Eof() as the constructor, always parenthesisedspec.md, Enums
variant and payload order are not semantic — not in the type, the fingerprint, or the discriminantspec.md; architecture.md §7.11
every variant gets exactly one arm, and there is no wildcard — adding one breaks importers on purposespec.md, Exhaustiveness
the scrutinee is a value the match owns, released after the arm’s result is established§7.11
the discriminant is written first, so cleanup after a failed initialiser dispatches on a valid tag§7.11
nazm.interface/3, closed over the payload types its public surface mentionsarchitecture.md §7.3, extended

Evidence: the numbers are in the milestone report and in bootstrap.md; what they cover is the contained suite, selfhost parity, a new C2 = C3 fixpoint, twenty-two new mutations, and the interface and cache behaviour that variant addition is supposed to move. The compiler written in Nazm uses an enum of its own — and making that one dispatch exhaustive found a defect N9 had shipped, where a record passed to a task produced a wrong answer and leaked its fields. A mutation that survived found a second one, older: leaving a half-evaluated expression by break, continue or return gave back nothing it was holding, in both backends, since N8. spec.md’s rule 4a now says it and architecture.md §7.11 says how.

N9 — User-defined records — complete, 2026-09-23

struct Point { x: Int, y: Int, }. Nominal value records with named fields, named construction, projection, field replacement through a projection path, nesting, module visibility, a persisted shape, and native code — in the reference compiler, the interpreter and the compiler written in Nazm.

The milestone was never about the syntax. It asked whether the memory constitution N7 and N8 built could describe a type whose ownership is composed from arbitrary field types rather than branched on, and the answer is in what did not change: Owns gained one variant and no consumer gained a case. Cleanup, task safety, copy and destroy are all derived from the fields, recursively.

The leak-freedom claim was tested rather than extended, and the constitution’s Cycles was satisfied the first way it offered: a record holds its fields by value, so a containment cycle has no finite layout and is refused (N0336) before anything is lowered. A composition of leaves is a leaf, so the argument survives — and a generic container able to hold a record is what would end it.

SettledWhere
struct as the keyword, record as the category, Point(x: 1, y: 2) as the constructorspec.md, Records
field order is not semantic — not in the type, the fingerprint, or the layoutspec.md; architecture.md §7.10
a projection borrows when its base does, and takes a reference when it does not§7.10
a failure releases the temporaries it was holding — §7.9’s last open limitation§7.10
nazm.interface/2, closed over the field types its public surface mentionsarchitecture.md §7.3, extended

Evidence: 936 tests over 55 suites contained, 22/22 selfhost, C2 = C3 over 12 conformance cases with 6 multi-module, 15 new mutations all caught, and the compiler written in Nazm now uses a record of its own.


Long-running tracks

Concurrency — C-4 and C-5, still not now. What shipped is one POSIX thread per task and nothing more. C-4 is nazm-rt: a scheduler, stacks, channels and a reactor, and the one crate allowed unsafe — which means the workspace’s unsafe_code = "forbid" becomes deny with a narrow allowance that xtask check enforces. It depends on the memory model. C-5 is measurement: spawn-to-first-instruction latency, context-switch cost, and task memory as RSS, not virtual reservation, with page size recorded. No scheduler work starts before C-4’s prerequisite lands; a single-threaded compiler is a perfectly good compiler.

AI-native — one item left. The ~3k-token cheatsheet. The lossless CST shipped in N15; the formatter, grammar artefact, schemas and fixes before it. No language keyword will be added to support the label; if a construct earns its place on semantics it earns it, and “AI-native” is not an argument for syntax.

Backends. LLVM IR as text stays the only backend. Cranelift is an ordering decision, not a rejection — it becomes worth having when one of its four jobs (JIT, comptime evaluator, REPL, hot reload) exists. None does.

Deliberately not next

Effects · capabilities · provenance · traits · methods · closures · exceptions · M:N scheduling · a second backend · GPU or accelerator work · a package manager · a standard library beyond the built-in table and the two-type prelude. Ownership, user-defined types, pattern matching, generics and typed errors left this list as N7–N12 landed them. Typed errors did not bring effects with them: a Result in a signature is a return type, not an effect row, and effects remain MISSING.

Each has a home — capability-matrix.md for status, research-register.md for the ones that are hypotheses, NAZM_LANGUAGE_GOALS.md for why they are wanted eventually. None is blocked by the others in a way that forces it now, and all of them are easier after N1, which is the argument for doing the small thing first.