Spec M1 — lexer, token table, Pratt, AST, dumps, constant-expression codegen - Scope: i64 main() { return 40 + 2; } compiles to .o, links and exits with 42. All of the front-end infrastructure and the back-end skeleton are born here in their final shape. Out of scope (M2+): variables, parameters, calls, if/loop, memory, globals, strings, #include.
Spec M11 — direct executable (mc --exe), no ld - Prerequisite: M10 closed. Goal: mc --exe prog.mc -o prog produces an arm64 MH_EXECUTE Mach-O that the kernel/dyld accept, without ld, with an ad-hoc signature. The .o + ld path remains the default and the one used for bootstrap; --exe is optional until proven stable.
Spec M12 — Tier 3: syntax taught through code (syntax hooks), type aliases, #dylib, - .mc only. Stage0 stays the seed: it knows nothing of #dylib, hooks, or aliases, and never compiles the example (examples/ is outside the check-* targets that run mc0). Motivation: #rule stmt: cannot introduce class/interface (top-level position, variable-length lists, generating compound names). The way out is the same principle as M10: the user writes a .mc module that runs inside the compiler and uses the parser's public API.
Spec M13 (backlog) — sizing a program's memory at compile time - Owner's idea: mc figures out how much memory the compiled program needs and fixes the runtime allocation at compile time (today a program declares u8 heap[N] by hand; the compiler itself uses 32 MiB and touches 14.5 MiB).
Spec M14 — project driver and mc.toml - Goal: a developer with only the mc binary builds a project by running mc build in its directory. Everything lives in src/*.mc (stage0 untouched). The single-file CLI (mc in.mc -o out.o, --exe, --backend=, --dump-*) keeps working unchanged.
Spec M19 — Windows arm64: COFF objects, a kernel32 system layer, lld-link - Goal: [target] os = "windows", arch = "aarch64" in mc.toml makes mc build emit a COFF .obj, link it with lld-link against kernel32.lib, and the result runs on Windows on ARM. The machine is arm64 (unchanged); only the object writer and the system layer are new. Nothing in stage0. Depends on M17 (target registry, machine table).
Spec M20 -- Windows x64: COFF x64 relocations and the Win64 ABI on the x86-64 machine - Goal: [target] os = "windows", arch = "x86_64" in mc.toml makes mc build emit a COFF .obj for AMD64, link it with lld-link against kernel32.lib, and the result runs on Windows on x64. Nothing in stage0/. Depends on M17 (walker + machine table, the x86-64 machine) and M19 (the COFF writer, the kernel32 layer, the sysroot and test scripts). Acceptance is "same as M19" (docs/plan.md). Line references below are to the tree at the M19 merge (77c4a62).
Spec M22 — examples/lang: a higher-level language taught to mc by a prelude - Goal: prove mc is a language generator. Everything in this milestone is developer code — it lives in examples/lang/, uses only the public hooks (M12, M21) and the object primitives, and could be replaced by a different prelude with different semantics without touching src/. A module examples/lang/lang.mc, compiled into a taught compiler (mc build with [compiler].modules), gives programs in examples/lang/*.lx:
Spec M23 — dynamic limits: best-effort sizing with a tolerance, no hard caps - Owner's direction (2026-09-03): limits must be dynamic. mc computes a best-effort estimate of what the build needs, reserves that times 1 + tolerance, and grows if the estimate was short. The only knob is tolerance, a float in [0, 1] in mc.toml. A checker reports how good the estimate was and may, with consent, adjust the tolerance. No per-table caps anywhere in the self-hosted mc.
Spec M24 -- Tier 4: primitives and hardware instructions taught from the surface - Owner's direction (2026-09-04): "capabilities become surface." A developer must be able to introduce NEW PRIMITIVES without touching mc -- new value types (fp8/fp16 for a GPU particle study, i128/u128, floats in general) and hardware-specific instructions (a legacy SSE/MMX op, a new AVX op on a specific CPU) usable on those types -- from the surface, in a module, teachable through mc build [compiler].modules.
Spec M25 -- sysroots and cross-compilation resolution - Owner's direction (2026-09-03, restated 2026-09-04): cross-compiling must not make the developer hunt for files, and everything mc downloads must be checksummed, cached and reproducible. mc redistributes nothing. mingw-w64 import libraries matter for USER programs that need more than kernel32 (msvcrt, user32, ws2_32); the compiler itself never needs them.
Spec M26 — the documentation set - Goal: a developer learns mc from docs/ alone: how to use it in every supported case and what each element of the API means. Written by docs-writer agents against the real compiler (every sample is compiled by scripts/check-docs.sh).
Spec M27 — site/: a static site generator written in mc, the layout and the icon - mc build site renders every doc; mcsite --check clean; two consecutive builds byte-identical; HTML validated (tidy or a validator script), contrast and keyboard navigation reviewed; the icon delivered as icon.svg, favicon.ico/PNGs; screenshots attached to the report when a browser is available.
Spec M28 - mc lsp: the taught compiler as language server - Synthesis of the design panel (three proposals, two judges). Winner: "the parse is the index" - a token log plus two frame edges plus a small module vocabulary, with no change to src/ast.mc. Grafted: the diagnostic/resolution hook wired at the compiler's own name-resolution sites, the two-phase emission that keeps colours alive through a syntax error, the arena bracket in the long-lived process, the CPU guard and mc build --compiler-only.
Spec M31 -- concurrency taught by a module: spawn, intent, await - Owner's test (2026-09-03): a developer must be able to add, from the surface, (1) threads with mutexes and semaphores, (2) spawn f(a) fire-and-forget talking over channels, (3) await res = f() with no async, where the call widens to Intent/Intent<T> and intent is legal only on a local. Non-negotiable: nothing about threads, channels, await or intents enters src/.
Spec M32 — examples/desktop: composing windows with GTK4 from mc (owner's test, 2026-09-03) - Goal: prove that an mc program (and then a taught UI language) can drive a desktop toolkit to compose windows. Toolkit: GTK4 via Homebrew (/opt/homebrew/lib/libgtk-4.1.dylib plus GLib/GObject/ GIO), chosen because its C API uses only integers, pointers and callbacks — everything mc has today (extern, #dylib/[libs]+[externs], &fn, callp). AppKit through objc_msgSend follows after M24 (NSRect travels in v0..v3).
Spec M33 -- WebAssembly: an AST-consuming backend, <sys/wasi>, <sys/browser>, examples/wasm - Owner's direction (2026-09-03, last in the queue): wasm examples for the browser and for WASI, binary .wasm and text .wat, preceded by an architecture sweep saying what the core would need. This spec is that sweep's verdict plus the design. Nothing wasm-specific enters src/ unless it is a generic mechanism paid for by more than one target.
Spec M36 — multi-target builds (owner, 2026-09-03; last in the queue) - Goal: one mc build produces every configured output — macOS, Linux, Windows, wasm32, wasm64 — from one source tree and one mc.toml. Depends on the target registry (M17), the foreign targets (M16, M17, M19, M20, M33) and sysroot resolution (M25).
Spec M37 — mc hosted on Linux (owner's need, 2026-09-04: the cloud only runs Linux) - Goal: the self-hosted compiler runs natively on Linux (x86_64 and aarch64), bootstraps there to its own fixed point, and make check runs its portable subset on a Linux host, so development can happen on a Linux machine with no macOS in the loop after the first published binary.
Spec M38 -- mc hosted on Windows (arm64 and x64) - Owner's rule (2026-09-04): every landed OS/arch gets a release asset of mc itself. Goal: the self-hosted compiler runs natively on Windows on ARM64 and x64, bootstraps there to its own fixed point, mc build spawns lld-link and a taught compiler through kernel32, and mc-<VER>-windows-{arm64,x86_64} are release assets verified on the Windows runners. Depends on M19 (COFF arm64, lib/sys_windows.mc, scripts/sysroot-windows.sh, the windows-11-arm leg), on M20 (x86_64-win machine, coff-obj-x86_64, the x64 leg, lib/sys_windows_start.mc, scripts/test-windows.sh --arch x86_64) and on M37 (the host layer). Line references are to main at 77c4a62 (before M20).
Spec M39 -- an architecture taught from the surface: examples/kernel, a bare-metal RISC-V 64 micro-kernel built by a taught compiler - Owner's need (2026-09-04): a developer wants to use mc for MIPS/AVR/PIC. mc has no native support for those architectures, and the answer must be tooling to add a new backend and new primitives without touching src/ -- not a fourth machine in the compiler. Bare metal is the honest form of the question: a microcontroller has no OS, no linker script we control, and the output is a flash image, not an object.
Spec M4 — tokenizer in .mc (a free cross-check) - Prerequisite: M3. Goal: the first real program in the language, and a cross-check of the lexer: src/lex.mc must be a transliteration of stage0/lex.c, function by function.
Spec M40 -- the narrow word: examples/avr, a bare-metal ATmega328P image built by a taught compiler - Owner's need (2026-09-04): microcontrollers with no OS -- AVR (ATmega328P: 8-bit registers, 2 KiB SRAM, 32 KiB flash, Harvard) and PIC -- where the output is a flash image and the developer adds the target from the surface, as M39 proved for a 64-bit ISA. docs/specs/M39.md D8 approved only this: a sweep that prices the word-size change (G10) before any code. This spec is that sweep.
Spec M41 -- override, debloat and re-arch: <mc/core> becomes composable, and a recreated compiler is smaller than mc by what it omits - Owner's direction (2026-09-04, docs/specs/M40.md § Amendment, quoted): "the developer RECREATES the compiler -- without touching src/ -- with overrides of the core's remaining fixed decisions, new primitives, a new machine, and the REMOVAL of the primitives, writers and machines the target does not use; then builds the program with that compiler." And: "<mc/core> becomes composable (a minimal core -- lexer, parser, resolver, walker, hooks -- with the object writers, the two host machines, the driver, the bundle and the sysroot resolver as parts an entry file includes or omits), and primitives the target does not use can be removed (types and intrinsics unregistered; writers, machines and targets simply not registered). examples/avr is the first recreated, debloated compiler: no Mach-O, ELF64 or COFF writer, no arm64 or x86-64 machine, uptr of two bytes, the AVR machine and its ELF32 writer only."
Spec M42 -- --exe on every host: the ELF executable writer, dynamic first - mc --exe writes a Mach-O executable and nothing else. src/cli.mc used to hardcode bname = "macho-exe"; the fix batch that precedes this milestone makes it resolve the host pair through the target registry and REFUSE when the executable slot is 0. That refusal is honest, and it is a step, not a destination: the slot is 0 for linux/aarch64, linux/x86_64, windows/aarch64 and windows/x86_64 because nobody has written the writer, not because the design forbids one.
Spec M44 -- packages: source distribution, Go-style, from a registry of sources - Owner's request (2026-09-04, translated from the Portuguese): "a package manager for mc, in the style of Go: it provides the source, and the manager is the repository of registered sources." Read as three requirements: (1) a package is SOURCE, fetched as source and compiled by mc like everything else; (2) the model is Go's -- a path-identified source tree, versioned by git tags, minimums in the manifest, a lock that pins content; (3) the manager is a REGISTRY OF SOURCES -- an index that maps a name to where the source is and which versions exist, never a host of binaries.
Spec M45 -- i32, and a call returns what it declares - Owner's ruling (2026-09-04, translated from the Portuguese): "A clear sign that not having a 32-bit primitive is a problem that needs correcting (implement a 32-bit signed integer primitive)." Read as: mc gains a signed 32-bit integer, i32 -- registered by the core itself through the M24 mechanism, not added to the ladder (see the Amendment below, which overrides § 1, § 2, D1, D2 and D12 of this draft) -- and, because the defect that surfaced it is about RETURN narrowing, a call's result takes the callee's DECLARED type, extended from the 32/16/8-bit register view by that type's signedness, for i32 and for the existing u8/u16/u32.
Spec M5.5 — fixes from the M3/M5 reviews + core pieces M6 needs - make stage0 with no warnings, stage0-san, budget (report it), test (mc0 and mc0-san), check-lex; before/after reproductions for A1–A4; cmp of the .o files before/after A5 for every test (except the ones affected by B6, whose only difference is section order); new tests 040-arrinit.mc, 041-udiv.mc, 042-proto.mc, 043-include-norm.mc (+ helper files under tests/inc/).
Spec M5.6 — fixes from the M5.5 review + creat (found during M6-macho) - Acceptance: make stage0 with no warnings, stage0-san, budget, test (mc0 and mc0-san), check-lex; scripts/check-obj.sh BEFORE/AFTER: the .o files change only in __data's alignment (verify that __text, symtab, and relocs are unchanged); repro of item 1 before/after; otool -l for item 2; ls -l of a file written by src/m0.mc showing -rw-r--r--; new test 034-reloc-err.mc — no, errors do not go in the suite; add the case to the report instead. Lines per file.
Spec M9 — #rule (surface piece C) + lib/prelude.mc - Prerequisite: M7 closed (fixed point, golden recorded). This milestone changes stage0 and src/ (the mechanism costs twice), and ends with the fixed point re-verified.