Release-candidate notes — 82936f6 (the core closure, N101–N108)
Frozen evidence for one tested commit. This file records what was verified at
82936f6d857eca7e3620793655a83b39458652a9 and is not updated as the project moves. Current
implementation truth is ../capability-matrix.md; what is not done is
../limitations.md. The method is architecture.md §7.109.
Nothing has been tagged, pushed or published. This is a candidate. Making it a release is a person’s decision, and the procedure for it is at the end of this file.
What this candidate is
Nazm after the core-closure programme, N101–N108, on top of cf664fd.md’s post-v1
candidate and the N76–N100 programme: every mutant accounted for with no silent tier (N101); the
compiler written in Nazm at full parity, 21 of 21 probes (N102); re-exports with one identity (N103);
authority as a parameter, the inheritance bridge removed (N104); one instruction-level LIR both native
backends translate, with a validator and an interpreter as oracle (N105); the M:N task pool as the
default runtime, and the two performance regressions since N75 attributed (N106); and the core’s scope
audited so that VERIFIED means the promise (N107). N108 adds no feature: it is this gate, and the
defects it found are fixed below.
Identities
| Commit | 82936f6d857eca7e3620793655a83b39458652a9 — the records commit that adds this file changes documentation only |
| Toolchain | rustc 1.98.1, pinned in rust-toolchain.toml |
| Semantic epoch | 29 (crates/nazm-cache/src/identity.rs) |
| Interface schema | nazm.interface/11 |
| Runtime ABI revision | 14 (crates/nazm-runtime/src/lib.rs) |
| LIR document | nazm.lir/2 (each unit’s instructions and digest) |
| Cost document | nazm.cost/2 (the scheduler a program gets) |
| Inspect document | nazm.inspect/2 (no inherits) |
| API document | nazm.api-doc/2 (re-exports) |
| Cranelift | 0.136.1, pinned exactly; its object key is the unit’s LIR digest and TRANSLATOR_REVISION 1 |
| Binary | bin/nazm, Linux aarch64, SHA-256 639a63f4ec61405e38e5cf9fc4522d66d06f7d8be9c99edb6b19c79d7b24957b |
Classification (N108, §7.109)
| Class | Rows | Status at this candidate |
|---|---|---|
| A — core | 1, 2, 2a, 3–9, 10, 10a, 10b, 11–15, 22–24, 29, 30’s mutation half, 31; selfhost parity | every row VERIFIED (2, 3, 5, 6, 7 as scoped by N107: audit-n107.md); no core debt |
| B — ecosystem and domain | 16–21, 25–28, 30’s fuzzing half, 32–34 | eight PARTIAL (21, 25, 26, 27, 28, 32, 33, 34), each with its limitation stated; a release limitation, not core debt |
| C — external blockers | the in-process JIT (area 12), proofs of the formal core, sBPF execution (area 34), a second GPU provider (area 21) | BLOCKED, each by a named cause: unsafe forbidden and no executable-memory crate offline; no proof assistant or solver in the image; no sBPF toolchain offline; no second provider on this host |
Targets, and what was run on each
| target | evidence at this candidate |
|---|---|
aarch64-unknown-linux-gnu | the whole workspace suite, selfhost, bootstrap, every mutation campaign and the release assembly, contained (Debian clang 19.1.7); the M:N pool is the default runtime there |
aarch64-apple-darwin | the host suite and the platform runs below (Apple clang 21) |
x86_64-apple-darwin | built on the host, run under Rosetta by the suite; the pool by default checked by hand (N106) |
x86_64-unknown-linux-gnu | compile-only: no amd64 machine or emulator here |
aarch64-unknown-none, riscv64gc-unknown-none-elf | run-verified on QEMU (nazm-qemu:n86): both boards boot and agree; an image reports on the UART; a run stays inside its stated stack bound |
wasm32-unknown-unknown | run-verified under Node (nazm-wasm:n64): the corpus agrees with the interpreter; an absent authority is an absent import; the contract adapter agrees with the simulator, and on generated sequences |
| EVM bytecode | run-verified in py-evm (nazm-evm:n70): agrees with the simulator inside its gas bounds, and on generated sequences |
| GPU (OpenCL, Apple M1 Pro) | four kernels agree with the interpreter, the reductions and 128-bit arithmetic included |
| Debuggers | a live gdb session (nazm-debug:n58) shows Nazm frames, lines and variables on LLVM; a live session on either backend shows frames and lines |
| sBPF | BLOCKED (class C) |
All fifteen platform runs passed at this commit.
The gate
Contained (Docker, offline, nazm-contained:1.98.1), 2026-10-05/06, serial, from clean worktrees.
The full catalogue ran on the candidate the audit began from (fc509ce, N107’s records); every defect
the gate found was fixed in a commit of its own, and each fix’s reach was gated again on the commit it
made, the last being this one.
| Stage | Commit | Result |
|---|---|---|
| Mutation, the whole catalogue | fc509ce → 82936f6 | 1,268 of 1,268 caught (below) |
Workspace suite (contained tests) | 82936f6 | 2,476 passed, 0 failed, 47 ignored, 198 binaries |
Self-hosting (contained selfhost) | 82936f6 | 43 of 43 |
| Bootstrap C1 → C2 → C3 | 82936f6 | C2 = C3 18481f2a…, byte-identical; 34 conformance cases (14 multi-module) and 29 refusals agree — self-reproduction, not correctness |
Release assembly (contained --profile p4t4 release) | 82936f6 | passed, 1,716 s: fmt, lints, xtask check, the workspace suite, the release build, the bootstrap chain, the benchmark check, 206 files verified against MANIFEST.txt |
xtask check and the docs suite | 82936f6 | passed |
| Platform runs (host and images) | 82936f6 | 15 of 15 |
Lifecycle (xtask --test lifecycle --ignored) | 230324c | 19 of 19 on the second run; the first run’s one failure, a_sigint_during_a_mutant_leaves_it_unfinalized_and_recoverable, finalized its slow fixture before the interrupt arrived, and passed alone twice and in a full rerun — a timing flake of the harness test, recorded, not hidden |
Fuzzing, every target, 300 s each (contained fuzz) | 230324c | five targets, about 3.7 million executions, 0 crashes; run’s 32 hangs are programs that block, which is not a defect (Nazm does not promise deadlock freedom) |
Compiler benchmark (contained bench) | 230324c | nothing slower than N106’s baseline by more than 25 % and 5 ms |
82936f6 changes debug builds only (an ordinary build’s code is byte-for-byte unchanged), and
230324c and b66f50f change tests and the catalogue only, so fuzzing, the benchmark and the
lifecycle suite, run at 230324c, stand for this commit.
What the gate found, every item fixed before the candidate (commit, then what):
82936f6— a debugger stopped on a function’s first line, not its first statement, since N105: the live gdb test (ignored in the suite: it needs the debug image) failed. The prologue’s slot zeroing had become anllvm.memsetthat carried the function’s line, and a guard’s continuation block took whatever line the text showed last. An intrinsic in the prologue now carries no line, and a block restates its statement’s position; two debugger-free tests and two mutants hold both.230324c— the polling-select killer let the order two tasks first ran in decide whether the poller ever gave its worker back, so under the mutant one Linux run in five finished: the sender now waits for the poller, and five runs are required.b66f50f,3b1a500— thirty-four catalogue entries the contained campaign could not decide: every declared killer passed on the mutant on Linux. Sixteen saw their defect on macOS only (glibc keeps a freed block’s bytes; AArch64 does not fault onMIN % -1; one oracle sum let two wrong remainders cancel) and got killers that fail on both; nine survived on macOS too, because N90, N104 and N105 had moved what they attacked — dead code deleted (Index::choose), a rule N105 decided twice decided once, a test added for an origin no program reached, for a requirement filter and for a statement’s debug line; one entry retired as equivalent (n62-every-declaration-is-needed: since N105 a unit declares only what it calls); eight are observable only with macOS tools or Apple’s clang and are verified on the host.c1aef4a,edc31b5— N104’s migration had left three concurrency programs and one scheduler test wrong;edc31b5also, by mistake, carried the deletion of Cranelift’s old lowering, so that commit does not build alone (recorded in N105’s commit).
Mutation catalogue accounting
Every one of the catalogue’s 1,268 entries has a verdict, and every verdict is caught:
| Where the verdict is from | Entries |
|---|---|
Contained, targeted with every killer verified, at fc509ce (campaign ac26ca9e…) | 929 |
Contained, the entries the first campaign had not reached, at fc509ce (campaign b30b7573…) | 294 |
Contained, the repaired entries, at b66f50f (campaign 21698180…) | 22 |
Contained, the polling-select entry with its new killer, at 230324c (campaign aeadf141…) | 1 |
Contained, every entry in the two files 82936f6 changed, at 82936f6 (campaign 2e6968e6…) | 14 |
| On the host (macOS), killer verified: entries only macOS tools or Apple’s clang can observe | 8 |
0 survived, 0 timed out, 0 runner errors, 0 not injected, 0 without a verdict.
Evidence index
target/gates/n108/evidence-82936f6/ — an evidence bundle (nazm.evidence/1), 31 files indexed by
BLAKE3, index.json SHA-256 83c1463ab7c51d83a979857199f3ef13c6d579022f30d23acf02dbaa5f3e4ef6,
verified with cargo xtask evidence --verify: the release’s MANIFEST.txt and PROVENANCE.txt, every
gate stage’s log at 82936f6 and at 230324c, the six campaign journals, the deferred list, the host
precheck and the Linux diagnoses. The artefact itself, nazm-release-candidate.tar.gz (7.4 MB), is
under target/gates/n108/wt-final/target/release-candidate/, which is build output and not tracked.
Independent redigest. The archive was extracted on the host and every file’s SHA-256 recomputed
with Python’s hashlib, not with the tool that wrote the manifest: 206 of 206 match, the only file not
listed is MANIFEST.txt itself, and bin/nazm’s digest is the manifest’s binary-sha.
Known limitations
limitations.md is the list. In the release’s terms: the eight class-B rows’ limitations; the class-C
blockers above; the oracle runs the sequential subset only; the interpreter and the compiler written
in Nazm keep a thread per task; x86_64-unknown-linux-gnu is compile-only here; the archive is not
bit-reproducible (it embeds its run date) and its executables were not tested for it.
The human release procedure
Every step is a person’s, in this order, from a clean checkout of exactly this commit. Stop at the first step that does not pass.
- Check out the commit.
git checkout 82936f6d857eca7e3620793655a83b39458652a9;git status --porcelainmust print nothing. - Build the images (network here and nowhere after):
docker/contained.Dockerfile(nazm-contained:1.98.1), and for the platform runsnazm-qemu:n86,nazm-wasm:n64,nazm-evm:n70andnazm-debug:n58. - Run the gates, contained and offline, each exiting 0:
cargo xtask contained tests;cargo xtask contained selfhost;cargo xtask contained bootstrap;cargo xtask contained bench;cargo xtask contained fuzz 300;cargo test -p xtask --test lifecycle -- --ignored --test-threads 1;cargo xtask checkandcargo test -p nazm-cli --test docs; and the campaign,cargo xtask contained --profile p4t4 mutate --strategy targeted --verify-killers, resumed with--resumeuntil complete — 0 survived and no entry without a verdict, the eight host-only entries checked on macOS. - Run the platform tests on the host:
cargo test -p nazm-cli --test accel --test boards --test contract_property --test debugger --test debugger_v3 --test evm --test freestanding --test realtime --test wasm --test wasm_contract -- --ignored. - Assemble the candidate:
cargo xtask contained --profile p4t4 release(one CPU does not fit the runner’s 2,400 s since the suite grew; four did, in 1,716 s). It tags, pushes and uploads nothing. - Verify independently: extract the archive and compare every file’s SHA-256 with
MANIFEST.txt, both ways; thencargo xtask evidence --verifyover the gate’s evidence bundle. - Decide. Only then, and only by a person: tag, push and publish, with this file beside the artefact. None of this has been done.
Appendix — the workspace suite by crate (added in R1, 2026-10-07)
Appended, not edited: nothing above this heading changed. crates/nazm-cli/tests/counts.rs requires
every release record to state its suite total and a by-group table that sums to it, and this record,
written after the gate, had only the one-line total in the table above — so the docs suite failed
on main from the records commit on, which the gate, run on 82936f6 itself, could not see. These
are the same run’s numbers, read from its log (tests.log in the evidence bundle,
evidence-82936f6/gate-final/), binary by binary, grouped by crate; doc-tests are one row.
2476 passed, 0 failed, 47 ignored.
| Crate | Passed | Ignored |
|---|---|---|
nazm-agent-bench | 21 | 0 |
nazm-bench | 109 | 0 |
nazm-cache | 64 | 0 |
nazm-cir | 0 | 0 |
nazm-cli | 1151 | 22 |
nazm-codegen-clif | 1 | 0 |
nazm-core | 386 | 0 |
nazm-diag | 6 | 0 |
nazm-docs | 25 | 0 |
nazm-formal | 11 | 0 |
nazm-iface | 42 | 0 |
nazm-lir | 23 | 0 |
nazm-mcp | 33 | 2 |
nazm-mir | 1 | 0 |
nazm-package | 24 | 0 |
nazm-repo | 21 | 1 |
nazm-runtime | 8 | 0 |
nazm-sema | 30 | 0 |
nazm-service | 253 | 1 |
nazm-span | 14 | 0 |
nazm-syntax | 101 | 1 |
nazm-tokens | 16 | 1 |
xtask | 136 | 19 |
| doc-tests, every crate | 0 | 0 |