Quartz Language Roadmap
Version: v5.26.0-alpha | Target: v6.0.0 (Launch) Status: Self-Hosted Primary | QSpec 462 files (461 passing, 1 intermittent) | 5,900+ active tests, 9 pending | Stress: 401/0 | Fuzz: grammar-guided + 4-level oracle
LANGUAGE SYNTAX FROZEN (Mar 19, 2026). All hardening phases complete. Syntax audit passed. Now: World-class developer tooling. LSP, VS Code extension, REPL, package manager, then launch.
Latest (Apr 2-3, 2026): P30 Session 4 — 3 compiler bugs fixed, WASM backend fully operational. (1) WASM void-call bytecode validation fix — void functions (fuel_check, etc.) no longer cause “type mismatch: expected i64 but nothing on stack.” All 90+ WASM tests pass (36 extended + 27 core + 27 data). (2) Async eager frame heap overflow ROOT CAUSE —
async f()on function variables allocated 2-slot frame but go_spawn wrote to slot 3 → heap buffer overflow corrupting adjacent frames. Caused all cancel_token SIGBUS/SIGSEGV crashes. Fixed: alloc(2)→alloc(6). (3) Scheduler I/O poller improvements — direct io_map wakeup from try_send/channel_close, atomic kevent register+check, wakeup pipe nudge, 1ms poller timeout, non-blocking pipe drain. Also: split wasm_backend_spec (60 tests, >120s timeout) into wasm_core_spec + wasm_data_spec using q()=str_from_char(34) to avoid parser OOM on escaped quotes. QSpec 461/462 (1 intermittent scheduler hang ~3%, needs park/wake refactor).Previous (Mar 31, 2026): Production Readiness Tier 1 COMPLETE (P23+P25+P26). Non-blocking async TLS:
tls_accept_async,tls_read_async,tls_write_all_async,tls_close_async+ timeout variants (6 tests). Production HTTPS server:http_serve_tls_optswith keep-alive, connection limits, graceful shutdown, load shedding. HTTP hardening: HEAD/OPTIONS auto-handling, chunked transfer decoding, access logging. Structured concurrency:go_scope,go_supervisor,go_scope_timeout,go_racenurseries (7 tests) + QZ7206 bare-go lint rule. Subprocess runner upgraded with OpenSSL auto-linking + codesign. Key discoveries: blocking accept() in go-tasks deadlocks (fixed with non-blocking accept + io_suspend);go_spawn bad()silently fails (parser quirk, needsgo_spawn(bad)); go_race from main thread needs channel-based approach (not polling).Previous (Mar 28, 2026): Concurrency V4 Phase 4 — Language-Level Actors COMPLETE. 21 tests: spawn, stop, supervision (panic recovery), generic actors, init params, async proxies, isolation, Send validation, request-response panic recovery, 10K message stress test.
Previous (Mar 27, 2026): Concurrency V3 COMPLETE. 5 phases, 38 new tests, 8 compiler bugs fixed.
Previous (Mar 26, 2026): World-Class Linter COMPLETE (T4.6b). 24 lint rules (13 Tier 1 text-based + 11 Tier 2 AST-based).
quartz lint --fixauto-repairs 6 rules (bool hygiene, unless, compound assign, .size, endless def, trailing ws)..quartzlintconfig file with rule disable and configurable thresholds. Inline suppression (# lint:disable QZxxxx). 24--explainentries. 109 QSpec tests across 8 files. New Tier 2 rules: QZ7004 unused-var, QZ7203 shadowing, QZ7204 redundant-return, QZ7301 unreachable-code, QZ7302 empty-match-arm, QZ7303 missing-else, QZ7401 unused-param, QZ7402 empty-block, QZ7403 constant-condition, QZ7501 duplicate-import, QZ7502 wildcard-import. Two compiler bugs discovered: (1) multi-line function signatures cause blank “cannot find module” error, (2) UFCS name collision when module name matches common variable names (e.g.,import toml/value).Previous (Mar 25, 2026): World-Class Linter (Phases 0-3) + WASM Runtime + Playground.
quartz lintcommand live with 15 rules producing Rust/Elm-style diagnostics (QZ7xxx codes, colored source context, underlines, suggestions). Two-tier architecture: Tier 1 text-based (13 rules), Tier 2 AST-based (planned).Previous (Mar 25, 2026): WASM Self-Contained Runtime + Playground Integration. Split
codegen_wasm.qz(6,500→2,154 lines) intocodegen_wasm.qz+wasm_runtime.qz(6,300 lines, 93 synthesized functions). 30+ new runtime functions. Fixed 3 compiler bugs: (1) MIR_ALLOC zero-sized allocs, (2)to_strinteger-as-pointer heuristic, (3) UFCS names not synthesized. Playground integrated into Astro marketing site with Monaco editor, 9 showcase examples, ANSI-stripped errors. 36 new WASM tests. Fixpoint verified.Previous (Mar 24, 2026): Zero Pending Initiative — 25 → 9 pending (16 activated, 9 bugs fixed). Session 2: activated htons (pure Quartz byte-swap), variadic extern (native compilation), nested string interpolation (lexer+parser fix). Fixed PCRE2 linking in Quakefile (static lib +
-lpcre2-8). 6 stale bugs marked fixed in roadmap. Remaining 9: 3 regex codegen bug (regex_matchesreturns Vec ptr not count), 5 HTTPS local server infra, 1 TLS hostname validation. All 9 are fixable — none are permanent.Previous (Mar 24, 2026): Zero Pending Initiative — 25 → 11 pending (14 activated). 8 bugs fixed: (1) CRITICAL use-after-free in cache —
tc_compute_interface_hashcalled aftertc_free(4 incr_tier2 tests). (2) Intrinsic name hijacking — userfirst()etc. hijacked by vec intrinsic (targeted 6-name bypass). (3) Arena struct passthrough —@arena SomeStruct{}fell through to malloc. (4) Drop call name mismatch —Arena$dropvsmemory$Arena$drop. (5) QZ1207 missing for no-elseif. (6) QZ1302 closure detection too narrow ingo. (7) QZ0204 ambiguous type inference — new detection for unconstrained type variables. (8) Missing codesign in QSpec subprocess paths. New feature: loop-as-expression withbreak VALUE(parser + MIR + TC).Previous (Mar 23, 2026): Zero Pending Initiative — 145 → 25 pending (120 tests activated). Fixed arena SIGSEGV root cause:
g_mmap_flagsInt-to-String type confusion incodegen_intrinsics.qz. Fixedpool_alloc_countstub. Registeredvolatile_load/volatile_storein TC builtins. Fixedto_str()negative integer SIGSEGV. Wrote test bodies for arenas_spec (10), arenas_advanced_spec (25), arena_blocks_spec (9), volatile_spec (12), pointer_ops_spec (6). Converted iterator_protocol_spec from 38 subprocess tests to direct inline tests (19 active). Discovered:varon struct fields causes compiler infinite loop (pre-existing bug since Mar 12+).$trymacro has runtime bug in closure-calling struct methods (blocks iterator adapters). lli-first QSpec runner in Quakefile.Previous (Mar 21, 2026): T3.4 Linux Validation + CI COMPLETE. UTF-8 string fix. Optional parens + annotation-free style. Platform-aware struct offsets for Linux. 3-platform CI (macOS ARM64, Linux x86_64/ARM64) with cross-compilation via IR artifacts. Fixed UTF-8 double-encoding in lexer and parser (sb_append_char re-encoded raw bytes as codepoints). Optional
()on zero-arg function defs. Homebrew LLVM 21 clang linker hang workaround (_linker()). README rewrite. Style guide updated: prefer omitting type annotations.Previous (Mar 20, 2026): T4.1a/b/d Editor Grammar Sync COMPLETE. TextMate: 3 bug fixes (extern def|fn, bare impl Type, generic impl Trait
for Type) + extern var pattern. Snippets: 2 bug fixes (extend end, extern def) + 8 new (loop, matchopt, matchres, derive, taskgroup, cimport, impltype). Tree-sitter: 3 bug fixes + 12 new grammar rules (loop, yield, select, for-await, cimport, task_group, async/await/go expressions, do_block, symbol, enhanced imports) + highlights/indents sync. Language config updated. All 3 editor integrations synced with frozen syntax. Previous (Mar 20, 2026): T1.3 World-Class REPL Upgrade COMPLETE. 7-phase upgrade (1,112→1,746 lines): (1) termios FFI migration (stty→tcgetattr/tcsetattr, isatty, ioctl TIOCGWINSZ for terminal dimensions), (2) word navigation (Alt-B/F, Ctrl-Left/Right) + reverse history search (Ctrl-R), (3) dynamic tab completion from user-defined preamble names, (4)
:vars/:load/:doc/:resetcommands with builtin docs for 30 stdlib functions, (5) auto type display (=> 42 : Int), elapsed timing (≥1ms), numbered continuation prompts, (6) bracketed paste mode + terminal width truncation, (7) 23 QSpec tests. REPL v0.3.0.Previous (Mar 19, 2026): T4.5a-e World-Class REPL COMPLETE.
quartz replsubcommand with live-as-you-type syntax highlighting (lexer tokenizes on every keystroke), raw-mode line editing (stty + fread, full readline keybindings), tab completion (keywords + builtins + preamble names), history persistence (~/.quartz_history),:type/:time/:help/:state/:clearcommands, lexer-based input classification and multi-line continuation, graceful piped-mode fallback. 6 compiler constraints discovered and documented as CQ.1-6 roadmap items.Previous (Mar 19, 2026): T4.4l-n LSP Final Polish COMPLETE. Three features: (1) Full semantic token coverage — two-pass architecture (lexer→comments→AST upgrades) with dedup, colors keywords/strings/numbers/comments/identifiers. (2) Real inferred-type inlay hints — fixed critical NODE_LET bug (was matching NODE_ARRAY/NODE_SET_LITERAL = zero results), TC re-typecheck captures binding types, hints show
": Int"/": String"/": Vec<Int>"instead of": _". (3) Debounced typecheck-on-edit — 500ms piggyback debounce viatime_mono_ns(), type errors appear without saving. Server v0.3.1.Previous (Mar 19, 2026): T4.3 + T4.4 LSP Advanced & Elite COMPLETE. 8 new LSP features: document highlight, selection range, rename (cross-file), code actions, workspace symbols (fuzzy), code lens (ref counts + run), call hierarchy (incoming/outgoing), type hierarchy (supertypes/subtypes). Workspace scanner infrastructure (file discovery, symbol index, trait-impl index). Fixed NODE_FUNCTION body traversal bug that silently broke semantic tokens and inlay hints inside functions. LSP now handles 22+ protocol methods. Server v0.2.0.
Previous (Mar 19, 2026): LANGUAGE SYNTAX FREEZE. Comprehensive syntax audit complete. All table-stakes features implemented. API naming unified. Ready for tooling phase.
Previous (Mar 19, 2026): Three-Pronged Compiler Dogfooding Initiative COMPLETE. DG.1 interpolation (25 files), MEM profiling (mem_peak_rss + —memory-stats), OPQ opaque pointers (515K refs → 0).
Previous (Mar 18, 2026): Compiler OOM Fix — Deferred Interpolation Desugaring. Parser now emits
NODE_INTERP_STRING(kind 43) instead of buildingstr_concatchains at parse time. Desugaring tostr_concatmoved to MIR lowering — produces byte-identical MIR output. Eliminates ~37,600 intermediate AST nodes (~12 MB effective memory) for the 4,943-interpolationcodegen_intrinsics.qz. Completed DG.1 Phase 4e:codegen_intrinsics.qzstring interpolation migration (4,943"a" + var + "b"→"a#{var}b"conversions). Build no longer OOMs.Previous (Mar 18, 2026): T3c.3 Phase 3 Complete — Dominator-Aware E-Graph Extraction (Cranelift-style).
eg_build_id_block_mapmaps dest_id→block index, Pass 1.5a switched to domtree preorder,eg_writeback_domawaregates CSE forwarding bydomtree_dominates_idx+ instruction-orderseenset,eg_materialize_constcreates MIR constants for e-graph-only values (shift constants for MUL→SHL). Three extraction types active: constant fold (existing), CSE forwarding (new), operator swap with materialization (new). 8 new tests (sibling branches, cross-block, deep reassociation, branched strength reduction). QSpec 406/410, fixpoint verified.Previous (Mar 17, 2026): Bug Batches 1-2 Complete — 10 backlog items resolved.
Previous (Mar 16, 2026): Three Compiler Bugs Fixed + Unicode Cleanup. (1) Bitwise operators (
&,|,^,<<,>>) now produce TYPE_INT in typechecker — opcodes 16-20 were missing from tc_expr match + tc_check_binary + tc_resolve_binary_operand. (2) For-in dispatch handles function call iterables — NODE_CALL branch added to struct_name resolution in mir_lower_stmt_for. (3)sb_append_charencodes full UTF-8 — replaced single-bytetrunc i64 to i8with 4-way encoding (1/2/3/4-byte branches) in both LLVM codegen and C runtime. All workarounds removed:uc_bitorhelper deleted,for x in func()inlined everywhere,sb_append(sb, str_from_codepoint(X))→sb_append_char(sb, X). 17 new tests across 3 spec files. Fixpoint verified, QSpec 406/409.Previous (Mar 16, 2026): HM — World-Class Hindley-Milner Type Inference COMPLETE. 5-phase upgrade: (A) retired infer.qz (-1,243 lines), (B) TYPE_UNKNOWN soundness fix (eliminated wildcard matching, ~90 sentinel updates), (C) structured error tracking with unification failure info, (D) level-based generalization (Rémy 1992), (E) Rank-2 polymorphism infrastructure (forall parsing, skolem variables, tc_subsumes). Single unified inference engine, no soundness escape hatches. Net -1,024 lines. 3 bootstraps, fixpoint verified, QSpec 397/399.
Previous (Mar 16, 2026): Bounded Generic Constraint Validation + Iterator-Bounded Dispatch COMPLETE — fixed string comparison bug (
==→.eq()onstr_byte_sliceresults) intc_validate_trait_boundsthat prevented constraint checking from firing. 3 constraint validation tests activated (traits_spec, stress_type_system_spec, intersection_types_spec). 8 Iterator-bounded generic dispatch tests written and passing — for-in sum, count, break, continue, two Iterator types, empty iterator, adapter chain (MapIter). All existing MIR infrastructure (closure synthesis, for-in closure iteration) works end-to-end. 11it_pending→ active. QSpec 397/397, fixpoint verified.Previous roadmap archived: ROADMAP-v5.26.0.md (3,059 lines of completed work)
Prime Directives
-
World-class only. Every solution must be world-class. No shortcuts, no workarounds, no “good enough.” If you’re at a decision point between the easy path and the harder-but-better path, you take the harder path. Every time. No exceptions.
-
No holes left behind. If you discover a gap — missing abstraction, missing validation, missing test coverage, table-stakes functionality we don’t have — you do one of two things: fill it now with a world-class implementation, or add it to the backlog with a clear description if it’s blocked by another requirement. You never ignore it. You never silently move past it.
-
Deferral requires justification. The only valid reason to defer work is a hard dependency on something that doesn’t exist yet. “It’s faster to skip it” is not a reason. “It’s complex” is not a reason. If it needs to be done, it gets done.
-
No silent compromises. If you’re about to make a tradeoff, say so explicitly. Explain what the world-class approach is, why you’re not doing it right now, and what the plan is to get there. Never quietly settle.
Operational Rules
- Test-Driven Development: Write tests first. Implementation follows specification.
- Fixpoint Validation: After ANY compiler change, run
./self-hosted/bin/quake fixpoint. - Document Changes: Update
docs/QUARTZ_REFERENCE.mdimmediately after language changes. - Incremental Progress: Commit working states. Never leave the compiler broken.
./self-hosted/bin/quake qspec # All tests pass
./self-hosted/bin/quake fixpoint # Fixpoint verified
What’s Done (Summary)
Everything below is COMPLETE and archived. See ROADMAP-v5.26.0.md for full detail.
| Category | Phases | Highlights |
|---|---|---|
| Language Core | P0 (6/6), P1 (4/4), P2 (5/5) | Union/intersection TC, safety audit, generic gaps, concurrency, parser, cross-module |
| Language Features | P2.5 Tiers 0-8 (21/21) | Or-patterns, range step, pattern binding, spread, named args, generators, impl Trait, multi-clause def |
| Async State Machines | ASY Phases 1-10 + Executor (11/11) | True lazy futures with io_suspend(fd) intrinsic, future_poll builtin, conditional pre-poll (eager for pure, lazy for I/O), await-as-suspend in $poll (composed async A→B→C), EventedIo.run() with kqueue/epoll, async TCP wrappers (async_tcp_read/write/accept), async_timeout with deadline, call graph suspendability analysis, async_all/async_race/async_map. Concurrency Runtime: single-threaded event-loop executor (std/async/executor.qz) drives N concurrent futures via kqueue/epoll — executor_spawn/executor_run/executor_run_until. Async HTTP server (http_serve_async) handles concurrent connections without blocking. Async I/O primitives (async_sleep, async_read_file) via pipe+spawn pattern. 43 tests (21 async_spec, 11 io_suspend_spec, 11 executor_spec). |
| Structured Concurrency | CONC Phases 1-7 (7/7), CONC-FIX (5 bugs) | TLS-correct cancel pointers, resource cleanup (channel_free/mutex_free/pool_shutdown), panic safety in pool workers (setjmp/longjmp), scope/supervisor/scope_with_timeout in std/concurrency.qz, cancel_token_with_deadline, RWLock, WaitGroup, OnceCell. Runtime fix (CONC-FIX): pthread_key TLS for jmpbuf/cancel (lli-compatible), atexit pool cleanup, CAS pool init, scheduler reset, subprocess test isolation. 29 new tests + 4 scheduler tests (resource_cleanup_spec, rwlock_spec, structured_concurrency_spec, scheduler_spec). |
| Type System | FIX.6, U.9, F.2, STR2 | H-M completion, intersection types (14/14), generic struct fix, type checks |
| Memory & Safety | S2.5, MS, BC, SAH, T3.1, T3.2 | Borrow checker, move semantics, partial moves, safety audit (12/12 holes), Send/Sync thread safety, arena lifetime safety (QZ1401/QZ1402) |
| Performance | P.5 (3 rounds), M.R (8 phases) | 15.6s -> 2.3s compile (85% reduction), escape analysis, stack alloc, register passing |
| Targets | TGT.1, TGT.2, WASM-RT | WASM (wasmtime verified, 93 synthesized runtime functions, self-contained binaries), C backend (self-compile byte-identical) |
| Developer Experience | DX.1 (7 phases), DX.2 MVP | 355K debug annotations, REPL MVP, VS Code extension (built) |
| Stdlib & Ergonomics | STD.1-8, NET.1-6, LEO, LFA, ASYNC-IO, HTTP-T1 | Full networking/TLS/HTTP, iterator protocol, Optionstd/markdown.qz, static file middleware) |
| Concurrency Moonshot | CONC.1-7 (7/7 done), CONC.8-11 (0/4) | Effect inference, colorless functions, typed channels (Channel |
| Concurrency V4 | Phases 1-4 + Depth Phase 10 (5/5 done) | Park/wake, async mutex/rwlock, async generators, language-level actors (21 tests), process links & monitors (10 tests). 31 actor tests total. See CONCURRENCY_ROADMAP.md. |
| Testing | TEST.1-2, FIX.4-5, STRESS, SPEC.3-5 | 5,307 tests, 401 stress, formal specs, fuzz infrastructure |
| Compiler Engineering | X.1-9, FP, P.2, P.3, G.4, EXTERN-DEDUP, INTERN, OOM-FIX | File decomposition, dispatch extraction, incremental compilation, separate compilation, cast elimination, extern declaration dedup, global shared string interner, deferred interpolation desugaring (NODE_INTERP_STRING — 12 MB memory savings) |
| Syntax Migration | Dollar Purge (Phase A+B), T1.7, T1.8, DG.1 (9 phases) | 22,711 $ → :: in source, Type::method() parser fix, 138 test string edits, $ retained as internal mangling separator, string interpolation migration (DG.1 Phases 1-4i: compound assignment, while-to-for-in, endless def, interpolation across 25 compiler/stdlib/tools files) |
| Opaque Pointers | OPQ Phases 0-4 (Goal A) | Full opaque pointer migration: 515,619 typed pointer refs (225K i64*, 290K i8*) → 0. All codegen files (codegen, codegen_util, codegen_runtime, codegen_intrinsics) emit ptr exclusively. 3-stage bootstrap, LLVM verifier clean. Goal B (provenance preservation) deferred. |
| Memory Profiling | MEM Phases 0-1 | mem_peak_rss() intrinsic (getrusage-backed), --memory-stats CLI flag. Self-compilation profile: 17.6 GB peak RSS. |
| Pre-Freeze Features | B1, L1-L5, L8 | Unsigned comparison fix, octal literals, $try for Result, range patterns in match, \0/\xNN/\u{NNNN} escapes, &=/|=/<<=/>>= operators, T? optional shorthand |
| API Unification | FREEZE | .size() everywhere (purged .len()), .has() for O(1) (Map/Set), .contains() for O(n) (Vec/String). 115 files, 400+ call sites. |
| Dogfooding | DG.1, DF.6-8 | Char literals replace magic numbers, parser int dedup (-70 lines), $try in 10 iterator adapters (-100 lines), 131 UFCS intrinsic registrations |
| Documentation | DOC.1, LFA-F | Reference audit, intrinsics overhaul, architecture docs, collections docs |
Active Roadmap — Stack-Ranked
The organizing principle: make every claim true, then tell the truth about what we built. We don’t water down claims — we implement the features. We don’t add caveats to hide gaps — we fill the gaps. The README should be a statement of fact, not aspiration.
Tier 0: Make the Claims True
Everything we say about Quartz should be verifiable by a hostile stranger in 5 minutes. These items close the gap between what we claim and what we deliver.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 1 | T0.1 — quartz run Command | quartz run hello.qz compiles and executes in one step. quartz build -o hello hello.qz produces a native binary. --release applies opt -O2. Argument forwarding via --. Exit codes propagated. 8 QSpec tests. | TRUNK | 1d | DONE |
| 2 | T0.2 — Union Type Codegen | Phase 1 (compile-time-only) complete: mir_is_union_annotation guards struct-var marking, LLVM codegen handlers for MIR_UNION_WRAP/TAG/UNWRAP prepared. 15/15 tests activated. Phase 2 (runtime tagged representation, match narrowing) deferred — no current tests require it. | TRUNK | 3h | DONE |
| 3 | T0.3 — Bounded Generic Dispatch | Full monomorphization: removed polymorphization gate (PASS 0.9), fixed memo double-check bug, fixed A8 per-param type override for correct multi-impl dispatch. def max<T: Ord>(a: T, b: T) works. Single-trait, multi-trait (T: A + B), multi-type-param (<A: T1, B: T2>), cascading generics, default method override — all working. 14 tests activated across 3 files. | TRUNK | 4h | DONE |
| 4 | T0.4 — Record Type Parameters | TC accepts { x: Int } record annotations in field access, PASS 0.97 registers record-param functions for monomorphization, width subtyping works (extra fields OK). 2/5 tests activated (param + width). Remaining 3 tests are intersection merging (T1.6). | TRUNK | 2h | DONE |
| 5 | T0.5 — Default Optimization Pipeline | quartz run and quartz build -o apply opt -O2 + llc -O2 + --stack-alloc by default. --debug or --no-opt disables optimization. Default experience is now the fast experience — “Run it like C” is true out of the box. | TRUNK | 1d | DONE |
| 6 | T0.6 — Honest Benchmark Table | All 12 benchmarks shown with honest results vs C. 9 at parity, 2 near parity, 1 faster. Methodology documented. No cherry-picking. | TRUNK | 1h | DONE |
| 7 | T0.7 — README Overhaul | Removed all false claims: “no runtime” → “no GC”, removed structural dispatch/union types/row polymorphism claims (not yet implemented), removed fake syntax examples, added “What Quartz IS / IS NOT” section, qualified memory safety (“single-threaded; thread safety pending Send/Sync”), updated Quick Start with quartz run/quartz build -o, corrected all code examples to valid Quartz syntax. Every sentence is now a verifiable fact. | TRUNK | 2h | DONE |
Checkpoint: Tier 0 COMPLETE. Every claim in the README is a verifiable fact. Union types compile, bounded generics dispatch correctly, record parameters accept structs with width subtyping. A hostile HN commenter who tries our examples will find they work exactly as advertised.
Tier 1: World-Class Developer Experience
A world-class language has world-class tooling. Not “functional” — delightful. Every developer touchpoint polished.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 8 | T1.1 — Wire Up Diagnostic Formatter | Connected diagnostic.qz to all compiler error output. 25 raw eputs() calls replaced with diag_emit() across 7 files: macro_expand (12, QZ0501-QZ0512), derive (2, QZ0520-QZ0521), resolver (3, QZ0550-QZ0552), mir_const (5, QZ0600-QZ0602), typecheck_registry (1, QZ0150), mir_lower (1, QZ0603), quartz.qz (1). Added diag_new_simple() for location-less diagnostics. Context threading via module globals + setters. 22 new error codes, 5 new --explain entries (QZ0503, QZ0509, QZ0521, QZ0551, QZ0600). 8 QSpec tests in diagnostic_wiring_spec.qz. 8 intentional eputs kept (5 cache debug, 3 tool stderr forwards). | TRUNK | 3h | DONE |
| 9 | T1.2 — Complete Error Code Documentation | All 56 error codes documented with --explain. Split QZ0106 → QZ0107 for non-exhaustive match (4 emit sites in typecheck_walk.qz). 34 new explain functions added to explain.qz (633 lines, up from 147). Every code has: why-it-happens explanation, triggering example, fix guidance. Dispatcher covers QZ0101–QZ1218. 7 new —explain tests in error_recovery_spec.qz. Fixpoint verified. | WORKTREE | 2h | DONE |
| 10 | T1.3 — World-Class REPL | 7-phase upgrade: termios FFI (stty→tcgetattr/tcsetattr, isatty, ioctl TIOCGWINSZ), word nav (Alt-B/F, Ctrl-Left/Right) + reverse history search (Ctrl-R), dynamic preamble completion, :vars/:load/:doc/:reset commands, auto type display + elapsed timing + numbered continuations, bracketed paste + width truncation, 23 QSpec tests. v0.3.0. | TRUNK | 1d | DONE |
| 11 | T1.4 — Publish VS Code Extension | Extension is built but not on the Marketplace. Build .vsix, register publisher, publish. Then: add problem matchers so compilation errors show inline. Add basic hover documentation for builtins. A developer who opens a .qz file in VS Code should get syntax highlighting automatically — one click install. | WORKTREE | 1d | TODO |
| 12 | T1.5 — Multi-Param Bounded Generics | Completed as part of T0.3 — def process<A: Addable, B: Printable>(a: A, b: B, x: Int) works via the same monomorphization infrastructure. Test activated in stress_type_system_spec.qz. | TRUNK | — | DONE |
| 13 | T1.6 — Intersection Type Record Merging | TC already merges pure record intersections into single record types (line 1824 of typecheck_registry.qz), and PASS 0.97 monomorphization handles record-typed parameters. No compiler changes needed. Verified: 2-record, 3-record, overlapping compatible fields, disjoint fields, 4-field records, parameter position, return position — all work. 10 it_pending → active tests across 3 files (intersection_types_spec 4, record_types_spec 3, stress_type_system_spec 3). | TRUNK | 1h | DONE |
| 14b | T1.7 — QSpec Multi-File Test $ → :: Cleanup | 138 source-string edits across 29 QSpec files + explain.qz. All module$func() patterns in multi-file test strings converted to module::func(). IR assertion strings preserved (module_prefix_spec.qz). One assertion fix (visibility_adv_spec error message match). QSpec 396/397 — sole remaining failure is pre-existing flaky SIGSEGV (operator_traits_spec), not syntax-related. Fixpoint verified. | TRUNK | 2-3h | DONE |
| 14c | T1.8 — :: Qualified Name Parser | Type::method() patterns now parse correctly. Parser disambiguates RHS case: lowercase/underscore → method call (joins to "Type$method", falls through to call handler), uppercase → enum variant (NODE_ENUM_ACCESS, unchanged). Single code block modified in ps_parse_ident_expr. Handles all patterns: Int::triple(7), Val::op_eq(a,b), Type::_private(x), plus existing Color::Red, Option::Some(42). Dollar purge syntax migration complete. | TRUNK | 1h | DONE |
Checkpoint: T1.1, T1.2, T1.3, T1.5, T1.6, T1.7, T1.8 COMPLETE. Error messages wired, all codes documented, REPL world-class (termios FFI, reverse search, word nav, dynamic completion,
:vars/:load/:doc, auto type display, bracketed paste), multi-param generics dispatching, record intersections merging,::qualified names fully working, test strings migrated. Dollar purge 100% complete. Remaining: VS Code publish (T1.4).
Tier 2: Complete Documentation
A world-class language can be learned from its documentation alone. No reading compiler source, no guessing, no tribal knowledge.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 14 | T2.1 — Getting Started Guide | Write docs/GETTING_STARTED.md: per-OS installation (macOS Homebrew, Linux apt/nix, Windows WSL), hello world with expected output, first program (structs, enums, pattern matching, Vec), first QSpec test, compile and run with quartz build/quartz run. Include a validation step so the user knows their install works. This is the front door — it must be flawless. | WORKTREE | 1d | TODO |
| 15 | T2.2 — Standard Library Guide | API docs are auto-generated field tables with zero narrative. Write a real guide: Vec/Map basics with examples, JSON parsing end-to-end, HTTP server, CLI argument parsing with argparse, file I/O patterns. Every stdlib module should have a “how to use this” section with working code. | WORKTREE | 2-3d | TODO |
| 16 | T2.3 — Testing Guide | QSpec is excellent (4/5 rating) but has zero public documentation. Write docs/TESTING.md: framework overview, describe/it API, all assertion functions, subprocess testing for compile-error tests, how to run individual tests, how to create new test files. | WORKTREE | 1d | TODO |
| 17 | T2.4 — FFI Guide | No docs on C interop. Write docs/FFI.md: extern "C" def, CPtr semantics, memory layout (@repr(C), @packed), calling conventions, common patterns (wrapping libc, linking shared libs), safety caveats. FFI is how systems languages prove their worth. | WORKTREE | 1d | TODO |
| 18 | T2.5 — Error Handling Guide | No guidance on error handling patterns. Write docs/ERROR_HANDLING.md: Result<T, E> vs panic, $try macro, custom error types, error propagation patterns, matching on Result. | WORKTREE | 1d | TODO |
| 19 | T2.6 — Debugging Guide | 355K debug annotations, world-class DWARF support — completely undocumented in public docs. Write docs/DEBUGGING.md: lldb workflow, setting breakpoints by file:line, frame variable for struct inspection, enum type info in debugger, backtrace with source locations. This is a genuine differentiator — showcase it. | WORKTREE | 2h | TODO |
| 20 | T2.7 — Examples Directory | No /examples directory. Create 10 real programs: hello world, fibonacci, JSON processor, HTTP server, CLI tool with argparse, file processor, pattern matching showcase, generic data structure, concurrent task group, iterator pipeline. Each with comments explaining Quartz idioms. | WORKTREE | 2d | TODO |
Checkpoint: After Tier 2, someone can learn Quartz from documentation alone. Every feature is explained, every API is documented, every common task has a guide.
Tier 3: Safety & Platform Integrity
A language that claims memory safety must deliver it. No asterisks, no “well, except for threads.”
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 21 | T3.1 — Send/Sync Trait System | Compile-time thread safety enforcement. Send/Sync marker traits registered as built-in traits. tc_type_is_send/tc_type_is_sync classify all types structurally (primitives=Send+Sync, AtomicInt/Mutex/Channel=Send+Sync, Vec/Map/Set/StringBuilder=Send-only, CPtr/Ptr=neither). tc_check_spawn_safety enforces at spawn/taskgroup_spawn boundaries: not-Send → QZ1301 error, Send-but-not-Sync → force-move (prevents aliased mutable access, use-after produces QZ1212). Recursive struct/enum derivation with cycle guards. Explicit impl Send/Sync for T overrides. QZ1301/QZ1302 error docs with --explain. 14 QSpec tests in send_sync_spec.qz. Fixpoint verified, 349/371 QSpec (6 pre-existing concurrency test crashes fixed). | TRUNK | 1d | DONE |
| 22 | T3.2 — Arena Lifetime Safety | Compile-time arena lifetime enforcement. arena_destroy()/arena_reset() now invalidate all arena-allocated pointers — using them after invalidation is a hard error (QZ1401), not a warning. Re-allocation-after-reset is correctly permitted via line comparison (alloc_line < inv_line). Scoped arena name do...end blocks auto-invalidate on exit. Assignment alias propagation tracks y = ptr chains. Per-function arena state reset prevents cross-function contamination. return from scoped arena block is QZ1402 (escape). Pool allocators (pool_new/pool_alloc/pool_destroy) follow the same rules. defer arena_destroy(a) pattern validated as safe. 12 QSpec tests in arena_lifetime_spec.qz, 4 migrated tests in arenas_advanced_spec.qz. Fixpoint verified, no regressions. Deferred: closure capture safety (QZ1403), interprocedural escape analysis, struct field propagation. | TRUNK | 1d | DONE |
| 23 | T3.3 — Multi-Arg Extern Fix | Two interacting bugs: (1) Intrinsic name collision — extern names like send/recv/exit/fread colliding with Quartz intrinsics, misrouted to wrong handler with wrong arg count → crash. Fixed via extern early-return guard before mir_is_intrinsic() in mir_lower.qz. (2) Call-site type mismatch — cg_collect_extern_info only collected variadic externs, so non-variadic externs emitted all-i64 calls against typed declares (i8*, i32). Fixed by collecting ALL externs + storing variadic flag + conditional ... emission. 5 new runtime tests (multi-arg, CPtr, intrinsic collision, IR assertion, variadic regression), 1 pending (custom calling convention). Cross-module extern resolution fixed separately: dual registration in resolver (bare + prefixed name), tc_register_extern_fn_signature_named in typechecker, prefix-stripping fallback in cg_extern_var_index, bare C name emission in codegen. QSpec 397/397, fixpoint verified. | TRUNK | 2h | DONE |
| 24 | T3.4 — Linux Validation + CI | Platform-aware struct offsets (stat.st_size: 96→48 on Linux, dirent.d_name: 21→19 on Linux) threaded through cg_emit_runtime_helpers_2/3 via target parameter. 3-platform GitHub CI: macOS ARM64 (build+QSpec+fixpoint+cross-compile IR) → Linux x86_64 + Linux ARM64 (bootstrap from IR artifact, self-compile, QSpec, fixpoint). LLVM 18 symlinks on Ubuntu. Cross-compilation validated locally. 3-stage bootstrap for function signature change. | WORKTREE | 1d | DONE |
| 25 | T3.5 — Exhaustiveness Completion | Non-exhaustive match detection is incomplete. 2 tests pending. Match exhaustiveness is a core safety feature — the compiler must catch every missing variant. No partial implementations of safety features. | TRUNK | 1-2d | TODO |
Checkpoint: T3.1–T3.4 COMPLETE — Send/Sync marker traits enforce compile-time data race prevention at spawn boundaries. Arena lifetime safety catches use-after-destroy/reset at compile time (QZ1401/QZ1402). Multi-arg extern “C” fix closes both intrinsic routing collision and call-site type mismatch bugs. Linux validated with platform-aware struct offsets + 3-platform CI (macOS ARM64, Linux x86_64, Linux ARM64). Remaining: exhaustiveness completion (T3.5).
Tier 3b: Concurrency Hardening — Design to Crown
The concurrency primitives are world-class in design. These items close the gap between “best design” and “best implementation.”
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 25b | T3b.1 — for await Iterator Protocol | for await x in ch iterates channel values using async recv, suspending the task (not the OS thread) when the channel is empty. break/continue now work correctly inside for-await (break/continue targets were missing). Channel send/close race eliminated via try_recv_or_closed intrinsic that checks buffer count AND closed flag under a single mutex acquisition. 15 tests passing (including break). | TRUNK | 1-2d | DONE |
| 25c | T3b.2 — Preemption Points at Loop Back-Edges | Counter-based yield (every 64 iterations) in async $poll context. MIR generation verified correct (opt -passes=verify clean), standalone preemption tests pass 10/10. Preemption fix landed in T3b.5 endgame (pipe-based completion notification eliminates the data race that caused scheduler SIGSEGV). | TRUNK | 2-3d | DONE |
| 25d | T3b.3 — Production HTTP Server Hardening | Connection limits (sched_set_max_tasks), graceful shutdown (SIGTERM + _http_shutdown_flag), keep-alive (_handle_connection_keepalive), poll-based read/write timeouts, HTTP backpressure (503 load shedding). wrk benchmark validation: bin/bench --http runs plaintext + JSON at 5 concurrency levels (1/10/50/100/256), head-to-head vs Go net/http, results stored in SQLite. | TRUNK | 2-3d | DONE |
| 25e | T3b.4 — Concurrency Stress Test Suite | 8 stress tests across 2 files: scale (100 tasks), producer-consumer (10 channels), fairness (all tasks progress), cancel (graceful shutdown), channel close (contention), for-await scale (multi-producer), plus 6 await-path tests (async+spawn, go+await, spawn+await, already-done, concurrent-10, multi-sequential). All 8 pass reliably — 5/5 runs 100% green. | TRUNK | 1-2d | DONE |
| 25f | T3b.5 — Non-Async await Fix | Replaced busy-poll with pipe-based completion notification (Go-style check-then-park). Three await paths: (1) known-lazy (async/go vars) → mir_emit_completion_await helper, (2) runtime dispatch with scheduler → three-way gate (sched_is_active() → completion-watch or pthread_join), (3) spawn handles → original pthread_join. 3 new intrinsics (completion_block, fd_close, sched_is_active). Fixed go variable tracking (was not marked lazy-async). Fixed 2 pre-existing PHI bugs in completion_unwatch/completion_watch_multi codegen. TOCTOU-safe: double-check frame[0]==-1 after registering watcher. | TRUNK | 1-2d | DONE |
Context: Phases 1-8 of World-Class Concurrency plan + T3b.1-T3b.5 COMPLETE. All concurrency bugs fixed. The await data race that caused all stress test flakiness is eliminated — pipe-based completion notification replaces busy-poll. HTTP server validated under sustained load via
wrkbenchmarks (Quartz vs Gonet/http). QSpec 377/380.
Tier 3c: Technical Honesty — Close the Gap Between Claim and Reality
An adversarial audit (Mar 16, 2026) identified features where the implementation is real but doesn’t fully deliver on the claim. Prime Directive #4 says no silent compromises. These items upgrade partial implementations to world-class.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 33 | T3c.1 — True Hindley-Milner Type Inference | ALL PHASES COMPLETE. Phases 1-4: unified type vars, constraint-based tc_expr, structured fn types + let-polymorphism, lambda param inference. Phase A: retired infer.qz (1,243-line legacy engine). Phase B: TYPE_UNKNOWN soundness (eliminated wildcard matching, ~90 sentinel updates). Phase C: structured error tracking (tc_error_type_mismatch, unification failure info). Phase D: level-based generalization (Rémy 1992 — correct nested let-polymorphism). Phase E: Rank-2 polymorphism infrastructure (forall parsing, skolem variables, tc_subsumes). Single unified inference engine, no soundness escape hatches. Net -1,024 lines. | TRUNK | 1-2w | DONE |
| 34 | T3c.2 — Interprocedural Borrow Checker | ALL PHASES COMPLETE. Function-level borrow summaries (BorrowSummary struct) describe what each function does with its borrowed parameters. Phase 0: data structure + registry plumbing (3-stage bootstrap). Phase 1: summary generation from &T/&mut T param/return annotations with Rust-aligned elision rules (single-borrow-input, self-method, ambiguity). Phase 2: body analysis refines summaries — traces return value borrow chains to parameters. Phase 3: call-site enforcement — summary-aware ephemeral release, pending return borrow propagation to NODE_LET, QZ1220 escape error. Phase 4: elision polish (already solid from Phase 1). Phase 5: transitive propagation fixpoint + cross-module (all modules in one compilation unit). Zero annotations required for functions without borrow params. 19 QSpec tests across borrow_summary_spec.qz and interproc_borrow_spec.qz. Fixpoint verified, no regressions. Deferred: lifetime parameters ('a), reborrowing, struct fields containing borrows, async+borrows, closure borrow capture. | TRUNK | 1w | DONE |
| 35 | T3c.3 — True E-Graph Equality Saturation | ALL PHASES COMPLETE. Phase 1: egraph.qz — ENode/EClass/EGraph with union-find (path halving, union by rank), hashcons, smart constructors (eg_add_binary with inline fold/identity/annihilator/strength-reduce), 7 rewrite rules, amortized congruence closure (eg_rebuild), bounded saturation, cost-based extraction. egraph_opt.qz Pass 1.5a: lightweight reassociation + commutativity CSE. Phase 2: E-graph extraction pipeline — eg_absorb_block (MIR→e-graph bridge with cross-block opaque leaves), eg_writeback_block (conservative constant fold extraction), eg_union node list merging. Phase 3: Dominator-aware extraction (Cranelift-style) — eg_build_id_block_map (dest_id→block index), Pass 1.5a switched to domtree preorder, eg_writeback_domaware with three extraction types: constant fold, dominance-gated CSE forwarding (eg_find_dominating_equivalent with instruction-order seen set), operator swap with materialization (eg_materialize_const for e-graph-only shift constants). Root cause of Phase 2 deferral (function-wide fwd violated dominance invariant) solved by domtree_dominates_idx gate on all fwd writes. 23 QSpec tests (8 new Phase 3 tests). Fixpoint verified, 406/410 QSpec. | TRUNK | 1w | DONE |
| 36 | T3c.4 — Type Annotation Cross-Checking | Subsumed by T3c.1 Phase 2. var y: String = 42 is now a unification failure. | TRUNK | — | DONE (via T3c.1 Phase 2) |
| 37 | T3c.5 — Unicode String Support | ALL PHASES COMPLETE. Phase 1: CodepointIter/CharIndexIter structs implementing Iterator<Int> for zero-allocation lazy codepoint iteration via str_codepoints(s) and str_char_indices(s). Phase 2: Unicode Character Database tables (Unicode 15.0) — 4,281 case mappings, 2,110 category ranges, 1,458 grapheme break ranges, 1,031 decompositions, 1,088 compositions. Generated via tools/gen_unicode_tables.rb. Phase 3: unicode_to_upper/unicode_to_lower with full 1-to-many mapping (ß→SS), unicode_eq_ignore_case, classification (unicode_is_alphabetic/numeric/whitespace/etc.). Phase 4: NFC/NFD normalization (unicode_nfd/unicode_nfc/unicode_eq_canonical) with algorithmic Hangul, CCC-sorted combining marks. Phase 5: UAX #29 grapheme cluster segmentation (str_graphemes/str_grapheme_count) with 14 break categories including emoji ZWJ sequences, regional indicator pairs, Hangul syllables. 76 tests across 5 spec files. Pure stdlib — zero compiler changes, zero bootstrap risk. Three compiler bugs discovered during this work (bitwise TC, for-in dispatch, sb_append_char UTF-8) fixed separately — all stdlib workarounds (uc_bitor, pre-assigned iterators, sb_append(sb, str_from_codepoint(X))) removed. | TRUNK | 1w | DONE |
Checkpoint: T3c FULLY COMPLETE. T3c.1 (H-M inference), T3c.2 (interprocedural borrow checker), T3c.3 (e-graph equality saturation — all 3 phases including dominator-aware extraction), T3c.4 (subsumed by T3c.1), T3c.5 (world-class Unicode). ROW Phases 1-2 COMPLETE. All Tier 3c items done.
Tier 3d: Concurrency Moonshot — Colorless, Protocol-Typed, Effect-Tracked
The first language that is simultaneously colorless (like Go), safe (like Rust), fault-tolerant (like Erlang), and protocol-verified (like no one).
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 38 | CONC.1 — Effect Inference Engine | Multi-effect bitset system (IO/Suspend/Panic/Alloc) with fixed-point call graph propagation. @pure/@io/@suspend annotations verified against inferred effects (QZ1410/QZ1411/QZ1412). --dump-effects CLI flag. Conservative defaults for FFI (IO|Alloc) and indirect calls (IO|Alloc). 9 QSpec tests. | TRUNK | 5-7d | DONE |
| 39 | CONC.2 — Colorless Functions | Functions with EFFECT_SUSPEND auto-compiled as state machines (PASS 1.3). No async keyword needed. go do ... end block syntax with __qz_poll_closure runtime bridge. join() builtin replaces await. Colorless call dispatch inside $poll bodies (mir_emit_colorless_call). Lambda call pipeline (typecheck + MIR). 5 QSpec tests. | TRUNK | 5-7d | DONE |
| 40 | CONC.3 — Typed Channels | Channel<T> ptype with element type checking on send/recv/try_send/try_recv. UFCS methods work with parameterized channels. Send/Sync extended for Channel<T>. Backward compatible with bare Channel. 4 QSpec tests. | TRUNK | 3-5d | DONE |
| 41 | CONC.4 — Protocol Types (Session Types) | protocol Name ... end definitions with send/recv steps. Compile-time enforcement of channel communication order. QZ1401 (incomplete protocol at scope exit), QZ1402 (wrong operation order), QZ1403 (use after completion). Protocol channels are linear — must be fully consumed. 4 QSpec tests. | TRUNK | 7-10d | DONE |
| 42 | CONC.5 — Observability | chan_inspect() prints channel capacity/length/status. sched_dashboard() prints scheduler worker/task/queue state. Built on existing intrinsics. 4 QSpec tests. | TRUNK | 1d | DONE |
| 43 | CONC.6 — Supervision Trees | supervised(max_restarts, body) — retry failed executions with configurable restart budget. Built on existing scope/supervisor. 3 QSpec tests. | TRUNK | 1d | DONE |
| 44 | CONC.7 — Automatic Parallelism | parallel_map(items, f) with true OS-thread parallelism via __qz_spawn_indirect_1 runtime wrapper. parallel_reduce(items, init, f). spawn f(val) now supports function pointer variables (NODE_SPAWN fn-pointer fix). 4 QSpec tests. | TRUNK | 2d | DONE |
| 45 | CONC.8 — Protocol Composition (DFA) | DFA state model with choice ... or ... end (branching) and loop ... end (repetition). Protocol state snapshot/restore for branch analysis. 11 QSpec tests. | TRUNK | 5-7d | DONE |
| 46 | CONC.9 — Effect Bounds on Function Types | Fn(Int): Int @pure syntax. Effect bounds in function type registry. Post-MIR validation pass verifies concrete function’s effects against bound. | TRUNK | 3-5d | TODO |
| 47 | CONC.10 — Task Tree Tracking | Global task registry with parent-child relationships. sched_task_tree() intrinsic prints structured task hierarchy. Updates in sched_spawn and __qz_task_done. | TRUNK | 3-5d | DONE |
| 48 | CONC.11 — Signal-Based Task Dump | SIGUSR1 handler dumps all active tasks to stderr. Worker loop checks dump flag. __qz_dump_tasks() runtime function. | TRUNK | 1-2d | DONE |
Checkpoint: CONC.1-CONC.7 COMPLETE — 33 QSpec tests, fixpoint verified. Quartz has: multi-effect inference with @pure verification, colorless concurrency (no async/await needed), typed channels (Channel
), protocol types (session types with QZ1401/1402/1403), observability (chan_inspect, sched_dashboard), supervision (restart budgets), and automatic parallelism (parallel_map with true OS-thread spawn). Remaining: protocol DFA (CONC.8), effect bounds (CONC.9), task tree (CONC.10), signal dump (CONC.11).
Tier 3e: Concurrency V3 — Close Every Gap (COMPLETE Mar 27, 2026)
Brutal audit against Go, Rust/Tokio, Erlang/OTP, Kotlin, and Swift. 5 phases, 38 new tests, 8 compiler bugs fixed.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 49 | V3.1 — Supervisor Tree Tests | 8 exhaustive tests for supervisor_tree() (ONE_FOR_ONE, ONE_FOR_ALL, REST_FOR_ONE, budget, empty, recover, max_restarts=0). Per-child cancel tokens for orphan cancellation on restart. Fixed 5 codegen bugs: eager future frame (2→5 words), duplicate SSA %td.tid, missing standalone @eputs/@str_from_int for hand-coded scheduler IR, recv PHI predecessor mismatch, empty-children sched_init leak. Also fixed 2 pre-existing structured_scope/structured_supervisor crashes. 13/13 tests. | TRUNK | 1d | DONE |
| 50 | V3.2 — Type-Safe Channels | channel_new<Int>(cap) syntax following vec_new<T>() pattern. Pending ptype for bare channel_new(). Channelsend() — both UFCS (ch.send(42)) and direct (send(ch, 42)) paths. Compile-time rejection verified (6 scenarios). Fixed: direct-call inference was UFCS-only (wrong nesting level). 7/7 tests. Fixpoint verified. | TRUNK | 0.5d | DONE |
| 51 | V3.3 — Result-Based Channel Recv | recv_safe() -> Result<Int, Int> (Ok=value, Err(0)=closed), try_recv_safe() (Err(1)=would-block), async_recv_safe() (io_suspend variant), oneshot_recv_safe(). Correctly handles value -1 and value 0 — eliminates sentinel confusion. In std/channels.qz. 6/6 tests. | TRUNK | 0.5d | DONE |
| 52 | V3.4 — Oneshot Channels | oneshot_new(), oneshot_send() (auto-close), oneshot_recv(), oneshot_recv_safe(). Cross-thread pattern verified. In std/channels.qz. 5/5 tests. | TRUNK | 0.5d | DONE |
| 53 | V3.5 — Lock-Free Broadcast Channels | Two-phase lock-free subscribe (reserve slot → store channel → publish count via atomic). Atomic subscriber count + closed flag. Zero contention on send. 64-subscriber capacity. broadcast_new/subscribe/send/close/subscriber_count. In std/channels.qz. 7/7 tests (including cross-thread). | TRUNK | 0.5d | DONE |
| 54 | V3.6 — mutex_unlock Compiler Bug Fix | mutex_unlock(m) crashed compiler with “index out of bounds” — handler assumed 2 args (Mutex | TRUNK | 0.5h | DONE |
Checkpoint: V3 COMPLETE — 38 new tests across 5 spec files (
supervision_spec,typed_channel_spec,channel_result_spec,oneshot_channel_spec,broadcast_channel_spec). 8 compiler bugs fixed. Fixpoint verified. New files:std/channels.qz(recv_safe, oneshot, broadcast), updatedstd/concurrency.qz(go_spawn, structured_scope/supervisor, supervisor_tree with cancel tokens).
Tier 3f: Concurrency V4 — World’s Greatest (TODO)
After V3 audit, the remaining gaps between Quartz and “world’s greatest concurrency story” for any compiled language.
Tier 1 — Table Stakes (every experienced developer expects these):
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 55 | V4.1 — Select Refinements | Select already existed (parser+MIR+tests). Added: timeout(ms) => body arm, Go-style random arm fairness (circular dispatch + counter), closed-channel awareness (all-closed exits loop). Fixed operator bug (string→OP_*). 8 tests across 2 files. Fixpoint verified. | TRUNK | 1d | DONE |
| 56 | V4.2 — Unbounded Channels | channel_new_unbounded() in std/channels.qz. Large-capacity (1M) wrapper. True lock-free linked queue deferred: hard dependency on linked list data structure that doesn’t exist in Quartz. | TRUNK | 0.5h | DONE |
| 57 | V4.3 — Semaphore | Channel-based counting semaphore in std/sync.qz. semaphore_new(permits), acquire, release, try_acquire, available. 5 tests (including concurrent rate-limiting stress test). | TRUNK | 0.5d | DONE |
| 58 | V4.4 — Barrier | Atomic counter + channel barrier in std/sync.qz. barrier_new(count), barrier_wait(b) returns leader flag. Generation counter for reuse. 2 tests. | TRUNK | 0.5d | DONE |
Tier 2 — Architectural (distinguishes great from good):
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 59 | V4.5 — Async Mutex/RwLock | Suspend task (yield to scheduler) instead of blocking OS thread on lock contention. Prevents worker thread starvation. Requires scheduler-aware lock that parks and re-enqueues the task. | TRUNK | 2-3d | TODO |
| 60 | V4.6 — Stream Abstraction | Async iterators composable into pipelines. Stream<T> with map/filter/take/collect. Built on channels + generators. Equivalent to Rust’s Stream / Kotlin’s Flow. | TRUNK | 2-3d | TODO |
| 61 | V4.7 — Actor Abstraction | Language-level actor Name ... end syntax with compiler-generated message dispatch. 21 tests: spawn, stop, supervision (panic restart), generic actors, init params, async proxies, isolation, Send validation, pending reply cleanup. Phase 10 Links & Monitors (10 tests): bidirectional links, unidirectional monitors, cascade stop, crash sentinels, drain loops, unlink/demonitor. | TRUNK | 3-5d | DONE |
| 62 | V4.8 — Rendezvous Channels | rendezvous_new() in std/channels.qz. Near-CSP: capacity-1 buffer. True zero-capacity (sender blocks until receiver arrives) requires runtime channel restructuring — deferred with justification. | TRUNK | 0.5h | DONE |
Tier 3 — Completeness:
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 63 | V4.9 — Thread-Local Storage | OS thread-local (not task-local). thread_local_new(), thread_local_get(), thread_local_set(). Required for some FFI patterns. | TRUNK | 0.5d | TODO |
| 64 | V4.10 — Priority Scheduling | Task priority levels. go_priority(f, level). Higher-priority tasks dequeued first. | TRUNK | 1d | TODO |
V4 Progress: Actors COMPLETE (21 tests) with Erlang-style links & monitors (10 tests). Remaining V4 items: async mutex/rwlock (Phase 1+2), streams (Phase 3), TLS (Phase 8), priority scheduling (Phase 13). Gap analysis (Mar 28) identified 10 additional depth items needed to close the “world’s greatest” claim — see CONCURRENCY_ROADMAP.md Depth Phases.
Detailed sub-roadmap: See CONCURRENCY_ROADMAP.md for the full plan with architecture, codegen details, file paths, test cases, and dependency graph.
Tier 4: World-Class Developer Tooling
Language syntax is frozen. Now: make the development experience world-class. Every developer touchpoint — from first file open to production deploy — must be polished, responsive, and delightful.
Inspiration: Zeta project (/Users/mathisto/projects/zeta/) has a 10K-line LSP with 43+ methods, semantic tokens, call hierarchy, type hierarchy, inlay hints, code actions, and code lens. This is our benchmark.
Existing assets: VS Code extension at editors/vscode/ (TextMate grammar, snippets, format-on-save, language config). Tree-sitter grammar at editors/neovim/. Self-hosted formatter (tools/fmt.qz) and linter (tools/lint.qz).
Phase 1: Editor Polish & Publish (1-2 days)
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.1a | Update TextMate Grammar | Synced with frozen syntax. Bug fixes: extern fn→def|fn, impl-block now handles bare impl Type + generic impl Trait<T> for Type, added extern var pattern. All keywords already covered (43+). | TRUNK | 2-3h | DONE |
| T4.1b | Update Snippets | Fixed 2 bugs (extend {}→end, extern fn→def). Added 8 new snippets: loop, matchopt, matchres, derive, taskgroup, cimport, impltype. Total: 62 snippets. Language config updated (loop/task_group in folding + indent regexes). | TRUNK | 1h | DONE |
| T4.1c | Publish VS Code Extension | Create icons (light/dark). Write README with screenshots. Add CHANGELOG. Register Azure DevOps publisher. Build .vsix package. Publish to VS Code Marketplace. One-click install. | TRUNK | 3-4h | TODO |
| T4.1d | Update Tree-Sitter Grammar | Synced with frozen syntax. Bug fixes: extern fn→choice('def','fn'), impl-block handles bare impl Type + generics, added compound assignment operators. 12 new rules: loop_statement, yield_statement, select_statement, for_await_statement, cimport_statement, task_group_statement, async_expression, await_expression, go_expression, do_block, symbol, enhanced import_statement. Highlights: @keyword.coroutine for async/await/go/yield, all keywords synced with TextMate. Indents updated. | TRUNK | 2h | DONE |
Phase 2: LSP Server — Core (1 week)
Self-hosted in Quartz. Architecture: quartz --lsp flag → stdio JSON-RPC server. Reuses compiler’s lexer, parser, resolver, and type checker as analysis engine. Incremental: re-lex/parse only changed files; cache module symbol tables.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.2a | LSP Scaffold + Diagnostics | JSON-RPC 2.0 transport over stdio. initialize/initialized/shutdown. Document store (didOpen/didChange/didClose). Compile-on-save → textDocument/publishDiagnostics with file:line:col error locations. This alone makes the extension 10x more useful — red squiggles as you type. | TRUNK | 1d | DONE |
| T4.2b | Hover Documentation | textDocument/hover — hover any identifier → show inferred type, doc comment (##), function signature. For builtins, show intrinsic documentation from docs/INTRINSICS.md. Rich Markdown formatting. | TRUNK | 1d | DONE |
| T4.2c | Go-to-Definition | textDocument/definition — jump to function/struct/enum/trait source location. Cross-module via resolver’s loaded_paths. The resolver already tracks source file origins. | TRUNK | 1d | DONE |
| T4.2d | Completion | textDocument/completion — context-aware: keywords after newline, struct fields after ., enum variants after ::, UFCS methods after ., builtins, imported symbols, in-scope variables. Snippet completions for def, match, if/end patterns. Trigger characters: ., :, #. | TRUNK | 2d | DONE |
| T4.2e | Signature Help | textDocument/signatureHelp — show parameter names and types as you type function arguments. Active parameter tracking (highlight which param you’re on). Trigger on ( and ,. | TRUNK | 0.5d | DONE |
| T4.2f | Document Symbols | textDocument/documentSymbol — outline view: functions, structs, enums, traits, impl blocks, constants in the current file. Powers VS Code’s breadcrumb bar and Outline panel. | TRUNK | 0.5d | DONE |
| T4.2g | Formatting | textDocument/formatting + textDocument/rangeFormatting — wire through quartz --format. On-type formatting for end keyword alignment. | TRUNK | 0.5d | DONE |
Phase 3: LSP Server — Advanced (1 week)
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.3a | Find References | textDocument/references — all usages of a symbol across the project. Inverse of go-to-definition. Cross-module. | TRUNK | 1d | DONE |
| T4.3b | Rename Symbol | textDocument/rename + textDocument/prepareRename — cross-file rename with preview. Rename function → updates all call sites across open docs + workspace files. | TRUNK | 1d | DONE |
| T4.3c | Semantic Tokens | textDocument/semanticTokens/full — rich highlighting beyond TextMate: distinguish local vars vs params vs globals, mutable vs immutable, type names vs value names, function calls vs definitions, builtin vs user-defined. Token types: namespace, type, struct, enum, interface, parameter, variable, property, function, macro, keyword, comment, string, number, operator. | TRUNK | 1d | DONE |
| T4.3d | Inlay Hints | textDocument/inlayHint — ghost text showing inferred types: var x = 42 shows : _. Fixed NODE_FUNCTION body traversal bug. | TRUNK | 1d | DONE |
| T4.3e | Code Actions | textDocument/codeAction — sort imports (source action), add type annotation (quickfix on untyped let/var). | TRUNK | 1d | DONE |
| T4.3f | Workspace Symbols | workspace/symbol — fuzzy project-wide symbol search (Ctrl+T / Cmd+T). Case-insensitive substring + CamelCase hump matching. | TRUNK | 0.5d | DONE |
| T4.3g | Code Lens | textDocument/codeLens — reference counts above function/struct/enum/trait definitions, “Run” above def main. Two-phase resolve for cross-workspace ref counting. | TRUNK | 0.5d | DONE |
| T4.3h | Document Links | textDocument/documentLink — clickable import frontend/lexer paths that open the target file. | TRUNK | 0.5d | DONE |
| T4.3i | Folding Ranges | textDocument/foldingRange — smart folding for def...end, if...end, match...end, struct...end, doc comment blocks, region markers. | TRUNK | 0.5d | DONE |
Phase 4: LSP Server — Elite (stretch, 3-5 days)
Inspired by Zeta’s advanced features. These differentiate “good IDE support” from “world-class.”
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.4a | Call Hierarchy | callHierarchy/incomingCalls + outgoingCalls — who calls this function? What does this function call? Cross-workspace call graph navigation. | TRUNK | 1d | DONE |
| T4.4b | Type Hierarchy | typeHierarchy/supertypes + subtypes — navigate trait hierarchies via trait-impl index built during workspace scan. | TRUNK | 1d | DONE |
| T4.4c | Selection Range | textDocument/selectionRange — smart expand/shrink selection: identifier → expression → statement → block → function → file. | TRUNK | 0.5d | DONE |
| T4.4d | Document Highlight | textDocument/documentHighlight — highlight all occurrences of the symbol under cursor. Read vs write highlighting via deep AST walker. | TRUNK | 0.5d | DONE |
| T4.4e | Inline Completion | textDocument/inlineCompletion — ghost text suggestions for common patterns (match arm completion, function body templates). | WORKTREE | 1d | DONE |
Phase 4b: LSP World-Class Depth (T4.4f-k) — 1-2 weeks
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.4f | Typecheck Diagnostics | Wire typechecker into LSP. Real QZ error codes, “Did you mean?” suggestions, type mismatch detection. Parse diagnostics on every edit, typecheck on save. | TRUNK | 1d | DONE |
| T4.4g | Scope-Aware Completion | Local variables, parameters, workspace symbols, struct field dot-completion. Context-aware trigger character dispatch. | TRUNK | 1d | DONE |
| T4.4h | Cross-File Navigation | Go-to-definition and hover using workspace symbol index. Expression-type hover from local scope walk. | TRUNK | 1d | DONE |
| T4.4i | Incremental Sync + Infra | textDocumentSync:2, incremental change application, request cancellation. | TRUNK | 1d | DONE |
| T4.4j | Diagnostic Quick-Fixes | ”Did you mean?”, “Make mutable” quickfixes from TC error messages. Improved code action pipeline. | TRUNK | 1d | DONE |
| T4.4k | Server v0.3.0 + Polish | Version bump, progress reporting, workspace log messages. Server reports TC initialization status. | TRUNK | 0.5d | DONE |
| T4.4l | Full Semantic Token Coverage | Two-pass architecture: lexer pass (keywords, strings, numbers, identifiers, doc comments) + source scanner (regular # comments) + AST pass (definition-site upgrades). Dedup keeps AST override at each position. All 12 registered token types now emit tokens. | TRUNK | 0.5d | DONE |
| T4.4m | Real Inferred-Type Inlay Hints | Fixed critical bug: kind == 10 or kind == 11 matched NODE_ARRAY/NODE_SET_LITERAL instead of NODE_LET (25) — zero hints produced. TC re-typecheck captures binding types per function. Hints show ": Int", ": String", ": Vec<Int>" instead of ": _". | TRUNK | 0.5d | DONE |
| T4.4n | Debounced Typecheck-on-Edit | 500ms piggyback debounce via time_mono_ns(). Type errors appear after typing pause without explicit save. didSave clears dirty flag to avoid double-run. Sub-second feedback for type errors. | TRUNK | 0.5d | DONE |
Phase 5: REPL (3-5 days)
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.5a | quartz repl Command | Interactive read-eval-print loop. Compile expressions to LLVM IR, execute via lli JIT. Persistent environment across evaluations (accumulate function definitions). Integrated as quartz repl subcommand. In-process lexer-based input classification and multi-line continuation. | TRUNK | 2d | DONE |
| T4.5b | Readline / Linenoise | Raw-mode line editing via stty + fread. Cursor movement (Left/Right/Home/End), Ctrl-A/E/K/U/W/L/C/D keybindings. History with Up/Down navigation, persistence to ~/.quartz_history. Multi-line input detection via lexer block-depth counting. | TRUNK | 0.5d | DONE |
| T4.5c | REPL Syntax Highlighting | Live-as-you-type highlighting via in-process lexer tokenization on every keystroke. Keywords=bright blue, strings=green, numbers=yellow, symbols=cyan, PascalCase types=bright cyan, true/false/nil=magenta, doc comments=dim, errors=red. | TRUNK | 0.5d | DONE |
| T4.5d | :type and :doc Commands | :type expr — probe-based type inference (tries print_int→Int, puts→String, if→Bool, bare→Void). :time expr — timed execution via time_mono_ns. :help, :quit/:q, :clear, :state. | TRUNK | 0.5d | DONE |
| T4.5e | Tab Completion in REPL | Keywords + 30 common builtins + preamble-defined names + REPL command completion. Single match auto-inserts, multiple matches displays candidates. | TRUNK | 0.5d | DONE |
Phase 6: Ecosystem (2-3 weeks)
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| T4.6a | Package Manager | Quartz.toml manifest (name, version, dependencies, build config). quake add <package> command. Git-based registry (no central server initially). Dependency resolution with semantic versioning. quake install fetches and builds dependencies. Lock file for reproducible builds. | TRUNK | 2-3w | TODO |
| T4.6b | Linter Enhancement | DONE. Two-tier architecture: Tier 1 (text-based, 13 rules) + Tier 2 (AST-based, 11 rules) = 24 rules total. quartz lint with --fix (6 auto-fixable rules), --config (.quartzlint config file), --error-format json, inline suppression (# lint:disable QZxxxx). 24 --explain entries for all QZ7xxx codes. 109 QSpec tests across 8 test files. Fixpoint verified. | TRUNK | 1w | DONE (24/24 rules, 109 tests) |
| T4.6c | Doc Generator | quartz doc → static HTML API documentation from ## doc comments. Searchable, cross-linked. Module index, function signatures, type definitions, examples. Hosted alongside the website. | WORKTREE | 1w | TODO |
Checkpoint: After Tier 4, Quartz has world-class editor support (on par with Rust/Go), an interactive REPL, a package manager, enhanced linting, and generated API docs. The developer experience is competitive with any modern language.
Tier 4c: Compiler Quality — Fix Self-Hosting Constraints
Six constraints discovered during REPL development (T4.5) that required workarounds instead of clean implementations. Root cause analysis revealed 6 reported issues reduce to 3 actual bugs + 1 non-issue + 1 one-liner + 1 alias of another.
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| CQ.1 | Cross-Directory Module Imports | Not a bug. Cross-directory imports work via -I paths. Wildcard import (import * from token_constants) causes namespace collision when compiled as part of the compiler; qualified import works fine. REPL keeps inlined constants to avoid the collision. | TRUNK | — | DONE (not-a-bug) |
| CQ.2 | Compound Assignment on Module-Level Vars | Root cause: NK_ASSIGN (kind 26) target str1 was not rewritten by the resolver. Fix: rewrite assignment target name with same resolve_has_prefix + local_lets guards as NK_IDENT. Compound assignment desugars to NODE_ASSIGN, so this fixes +=, -=, *= on module-level vars. | TRUNK | 0.5d | DONE |
| CQ.3 | Module-Level Var Capacity | Not a real capacity limit. The LSP has 27+ module-level vars. The perceived “max ~7” limit was from testing only var reassignment (NODE_ASSIGN, which failed per CQ.2) vs. bare reassignment (NODE_LET, which works via MIR fallback). Fixed by CQ.2. | TRUNK | — | DONE (not-a-bug) |
| CQ.4 | Extern “C” in Imported Modules | Duplicate bare-name extern entries when two modules extern the same C function. Fix: O(n) dedup scan in resolve_collect_funcs before pushing bare-name extern entries. | TRUNK | 0.5d | DONE |
| CQ.5 | Register readline as Builtin | Added readline as alias for read_line in typecheck_builtins, mir_intrinsics, and codegen_intrinsics. | TRUNK | 0.5h | DONE |
| CQ.6 | Module-Level Vec Var Reassignment | Same root cause as CQ.2 — NODE_ASSIGN target not rewritten. Fixed by CQ.2. | TRUNK | — | DONE (same fix as CQ.2) |
REPL simplification DONE: Resolver now rewrites NODE_GLOBAL_VAR/NODE_CONST_DECL/NODE_LET
str1to prefixed names, and collect-before-rewrite ordering prevents double-prefix. Vec-based state workarounds in repl.qz replaced with direct module-level vars. 3-stage bootstrap completed (pre-cq → gen1 with old REPL → gen2 with new REPL → gen3 fixpoint verified).
Tier 5: Launch
| # | Item | Description | Track | Effort | Status |
|---|---|---|---|---|---|
| 29 | T5.1 — Website + Playground | IN PROGRESS. Astro marketing site on GitHub Pages (landing, features, benchmarks, docs). Quartz HTTP server in Docker (dogfooding). Playground integrated (Mar 25): full Monaco editor at /playground, 9 examples (pipes, UFCS, closures, vec literals, structs, collections, pattern matching, composition, bit ops), compile API via quake playground, ANSI-stripped errors, theme-aware. Remaining: download page, polish, final deploy. | WORKTREE | 1-2w | PARTIAL |
| 30 | T5.2 — Flagship Demo Application | Build one real thing that proves Quartz works for real work. Not a toy — something people would actually use. Options: fast JSON CLI tool, lightweight HTTP framework, systems utility. “Built with Quartz” should mean something. | WORKTREE | 1-2w | TODO |
| 31 | T5.3 — Launch Blog Post | The HN narrative. “One developer + Claude built a self-hosting systems language in 90 days.” Credibility: 1,400+ commits, fixpoint proof, three backends, 5,500+ tests. The story is the hook. The compiler is the proof. | WORKTREE | 1d | TODO |
| 32 | T5.4 — Community Infrastructure | Discord or Matrix server, GitHub issue templates, contributing guide, code of conduct. The moment someone is interested, there must be a place to go and a way to participate. | WORKTREE | 1d | TODO |
Pre-Launch Dogfooding (after bugs/pending resolved)
Validate post-feature-freeze Quartz from a user’s perspective. Not compiler-as-dogfood — writing programs as a user would.
| # | Item | Description | Status |
|---|---|---|---|
| DF.1 | Upgrade existing examples | Rewrite brainfuck interpreter, JSON parser, HTTP demo with H-M inference (drop annotations), for x in func() (no pre-assignment), sb_append_char, bitwise ops in helpers. Validates new features compose correctly. | TODO |
| DF.2 | Unicode end-to-end program | Text processing tool exercising codepoint iteration, grapheme segmentation, case folding, string building. grep clone or Markdown processor upgrade for non-ASCII. | TODO |
| DF.3 | Row polymorphism + H-M showcase | Config parser or data transformer using record types through a pipeline of functions. First real test of whether H-M + row types feel good from a user’s chair. Elixir-style data-driven patterns. | TODO |
| DF.4 | Verify existing examples compile | Run all examples/ and benchmarks/ programs against current compiler. Fix any breakage from syntax migration, feature changes, etc. | TODO |
| DF.5 | Macro system design discussion | Evaluate whether macro system can enrich data-driven design patterns (arity overloading, piping, function composition). Current macros: $try, $debug, $assert — procedural-style. Explore syntactic/hygienic macros. | DISCUSS |
| DF.6 | Migrated 25 files from + concat to "#{}" interpolation. Discovered parser bug (nested strings in interpolation → 236 GB OOM). | DONE | |
| DF.7 | Full OPQ Goal A — 515K typed pointer refs → 0 across 4 codegen files. 3-stage bootstrap. Forward-compat with LLVM 17+. | DONE | |
| DF.8 | mem_peak_rss() intrinsic + --memory-stats flag. Revealed 17.6 GB peak RSS. | DONE | |
| DF.9 | Compiler dogfooding: parser nested string fix | Fix the parser to properly handle "#{func("string")}" — track nested string delimiters inside #{}. Currently causes unbounded memory allocation. ~20 blocked migration sites. | TODO |
| DF.10 | Compiler dogfooding: OPQ Goal B | Provenance preservation — eliminate inttoptr/ptrtoint for heap pointers via MIR_TYPE_PTR. Prerequisite: Goal A (DONE). Multi-week MIR-level type system change. | TODO |
| DF.11 | Compiler dogfooding: memory optimization | Based on --memory-stats data (24.2 GB peak RSS). Phase 0: mem_current_rss intrinsic + timing. Phase 1: vec_shrink_to_fit. Phase 2: tc_free after typecheck. Arena allocator upgraded to mmap/munmap (781 MB freed instantly in test). In progress: wiring arenas into compiler phases for phase-based disposal. | IN PROGRESS |
| DF.12 | std/ptr.qz — raw pointer operations module | ptr_store(p, val), ptr_load(p), ptr_offset(p, n), ptr_null(), ptr_is_null(p). Table-stakes for a systems language. Not blocked by anything. | TODO |
| DF.13 | Compiler decomposition refactoring | Break oversized compiler files into smaller modules. Stress-tests the module system (cross-module globals, re-exports, circular deps, name resolution at scale). Key targets: codegen_intrinsics.qz (20K+ lines), typecheck_walk.qz (4K+ lines), mir_lower.qz (large). Pipeline: Lexer → Parser → Desugar → Resolve → TypeCheck → MIR Lower → MIR Opt → E-Graph → Codegen (LLVM/C/WASM). Each stage should be 1-3 files max. Also validates import system handles 30+ module compilation correctly. Expected to surface module system gaps. | TODO |
Deferred (with justification)
Every item below is deferred for a specific, documented reason — not because it’s hard or because we’re cutting corners.
| Phase | Description | Justification for Deferral |
|---|---|---|
| R — Refinement Types | SMT-backed static verification | Hard dependency: requires stable type system (achieved) + SMT solver integration (research phase). No existing infrastructure to build on. |
| GPU — GPU Compute | @gpu attribute + NVPTX backend | Hard dependency: requires NVPTX target support in our LLVM pipeline + compute kernel semantics. Blocked on target infrastructure. |
| AI — AI Integration | @ai annotations, constrained decoding | Hard dependency: requires package manager (T4.1) for AI SDK distribution + runtime FFI to inference engines. |
| ASY V2 — Advanced Concurrency | Work-stealing scheduler | M:N Scheduler COMPLETE (B.1-B.4): sched_init/sched_spawn/sched_shutdown/sched_yield intrinsics. go keyword for lightweight task spawning. kqueue/epoll I/O poller integration (sched_register_io, io_suspend auto-wake). B.3 Work Stealing COMPLETE: Per-worker 256-slot local queues with 4-phase dequeue (local→global→steal→park). World-Class Concurrency Phases 1-8 COMPLETE: task_id race fix (unique IDs via task_id_next atomic intrinsic, set_current_frame for pre-poll), HTTP client one-liners (http_get_body/http_get_result/http_get_or_panic), scheduler-integrated HTTP server (http_serve_concurrent), TCP server (tcp_serve), scheduler fan-out (sched_map), io_suspend-based channel select (zero CPU burn), task_local storage verified, 14 previously-failing QSpec tests fixed. Remaining → Tier 3b: for await, preemption points, HTTP hardening, stress tests. |
| DX.1.5.3 — lldb Formatters | Custom pretty-printers for Quartz types | Hard dependency: requires stable struct layout (achieved) but low impact vs other DX items. Sequenced after T1 DX items. |
| DX.1.6 — Separate Compilation Debug | Per-module debug info | Hard dependency: requires separate compilation to be the default build mode. Currently optional via --separate. |
| TGT.1.7 — WASM Self-Compilation | Self-host the compiler on WASM | Hard dependency: WASI Preview 2 for full filesystem access. Current WASI Preview 1 support is insufficient for self-compilation I/O. |
| Structural Dispatch | Duck-typed method resolution at runtime | Architectural incompatibility: fundamentally conflicts with existential type erasure model. Would require either runtime type information (breaks the “types vanish” guarantee) or vtable infrastructure (dyn Trait — future work after T0.3 bounded generics). 25 tests permanently pending. This is a design decision, not a gap. |
DONE (ROW Phases 1-2). Phase 1: open record syntax, per-field type resolution, row variable infrastructure, row-aware unification (16 tests). Phase 2: full H-M integration — record_field_type_ids, collect_free_vars/occurs_in/substitute/instantiate all recurse into record types, mixed-scheme instantiation (positive=row vars, negative=type vars), field-type unification in tc_rv_unify_records, record display in error messages. 16 tests, QSpec 397/399, fixpoint verified. Remaining deferred: named row variables ({ x: Int | r }), lacks constraints, recursive record types, row vars in trait bounds. | ||
| CHAIN — Chained Field Access on Indexed Expressions | v[i].field should work without intermediate variable | Parser/typechecker limitation: v[i].field and vec_get(v, i).field fail — must write var x = v[i]; x.field. Affects all Vec |
| INTERPROC — Interprocedural Type Inference | Infer function parameter and return types from call sites | Investigate before committing. Most production languages (Rust, Go, Swift, Kotlin) require top-level function signatures and only infer within function bodies. Full interprocedural inference (like OCaml or Haskell’s where clauses) has tradeoffs: slower compilation (global constraint solving), worse error messages (errors surface far from cause), harder separate compilation. Discussion point: is it worth doing for Quartz? The existential type model makes it less impactful (no monomorphization benefit), and the self-hosting compiler already has full annotations. May be best limited to: (1) inferring return types from body when omitted, (2) inferring closure parameter types from call context (already partially done in T3c.1 Phase 4). Full investigation needed before scoping. |
Remaining Known Bugs
| Bug | Severity | Status |
|---|---|---|
clang -O2 -x ir miscompiles self-hosted IR | PARTIALLY FIXED (OPQ Goal A). Opaque pointer migration complete — all 515K typed pointer refs eliminated. IR now uses ptr exclusively. LLVM 21 auto-upgrades typed pointers, so the miscompile was already masked on current toolchain. inttoptr/ptrtoint round-trips remain (Goal B — provenance preservation via MIR_TYPE_PTR — deferred, requires MIR-level type system changes). IR passes opt -passes=verify cleanly. | |
FIXED (Mar 24, 2026). Lexer’s string tokenizer now tracks brace depth inside #{...} and skips inner string literals. Both lexer passes (interpolation detection + string content extraction) and parser expression extractor handle nested strings. "#{func("inner")}" compiles correctly. | ||
extern "C" crashes in multi-module | FIXED (T3.3). Two bugs: (1) intrinsic name collision → extern early-return guard in mir_lower.qz, (2) non-variadic type mismatch → collect ALL externs + conditional ... emission. 5 runtime tests. | |
declare for same extern in multi-module | FIXED. cg_emit_extern_declarations now tracks emitted names via Map, preventing duplicate LLVM IR declarations when the same extern "C" symbol (e.g. fcntl) is declared in multiple imported modules. | |
| FIXED (INTERN). Per-module interners caused invalid state on cache load. Replaced with global shared interner + V4 cache format with ID remapping. | ||
FIXED. LICM loop capped at 10 iterations, DCE loop capped at 20. Cycle warning in eg_resolve path compression. Prevents infinite loops from oscillating rewrites. | ||
| FIXED (duplicate of temp file race). Session-scoped temp files in QSpec runner eliminate temp file collisions between concurrent runs. | ||
await races scheduler workers | FIXED (T3b.5). Replaced busy-poll with pipe-based completion notification. Go-style check-then-park: fast check → completion_watch → TOCTOU guard → read(fd) blocks → cleanup. Zero data races, stress tests 100% reliable. | |
| FIXED (T3b.2/T3b.5). Pipe-based completion notification eliminated the data race in the scheduler re-enqueue path. | ||
FIXED. QSpec temp files now include session ID (epoch ms) in path: /tmp/qspec_{session}_{name}.{ll,o,out,err}. Two concurrent quake qspec runs no longer collide. Session-scoped cleanup at end of suite. | ||
$ syntax | FIXED (T1.7). 138 source-string edits across 29 spec files. All test strings now use :: syntax. | |
FIXED. _async_http_recv_timeout / _async_http_send_timeout now use io_suspend_timeout(fd, timeout_ms, events) which suspends the async task (not the OS thread) via kqueue EVFILT_TIMER / Linux timerfd. | ||
FIXED (CONC-FIX). 7 bugs identified, 5 fixed: (1) @__qz_panic_jmpbuf data race → pthread_key TLS (also lli-compatible), (2) pool workers never shut down → atexit handler, (3) pool init TOCTOU race → cmpxchg CAS, (4) scheduler doesn’t reset init flag → store 0 after cleanup, (5) scheduler tests run in-process → subprocess isolation. Also fixed: @__qz_cancel_ptr thread_local → pthread_key (same lli issue). All 5 concurrency specs now pass. | ||
FIXED. Opcodes 16-20 (&, ` | ||
FIXED. mir_lower_stmt_for handled NODE_STRUCT_INIT and NODE_IDENT for custom iterator dispatch but not NODE_CALL. Added NODE_CALL branch using mir_infer_expr_type. for x in func() now works. | ||
sb_append_char truncates to single byte | FIXED. trunc i64 to i8 discarded bits above 7, making non-ASCII codepoints impossible. Replaced with 4-way UTF-8 encoding (1/2/3/4-byte branches with PHI merge) in both LLVM codegen (codegen_intrinsics.qz) and C runtime (quartz_runtime.c). | |
| FIXED. Bug A: typed vec_get in for-in + TC ptype name fix. Bug B: struct_name resolution for NODE_CALL init. 12/12 tests active and passing. | ||
to_str() SIGSEGV on negative integers | HIGH | FIXED (Mar 23, 2026). to_str() heuristic used unsigned comparison (icmp ugt i64 %val, 65535) to reject small integers, but negative ints (e.g. -3368 = 0xFFFFFFFFFFFFF2D8) are huge unsigned values, passed the check, and if low nibble == 8 (string alignment marker), were dereferenced as string pointers → SIGSEGV. Fix: added icmp slt i64 %val, 0 sign check before unsigned range check in codegen_runtime.qz. |
| FIXED (Mar 23, 2026). Converted from 38 subprocess tests to direct inline tests. 38/38 active, 0 pending. Not a compiler bug — was a test framework design issue. | ||
| FIXED. All 13 fuzz tests passing including seed 42. | ||
FIXED (Mar 24, 2026). Use-after-free: tc_compute_interface_hash(tc, smod) at quartz.qz:712 accessed TypecheckState freed at line 614. Fix: pre-compute interface hashes before tc_free. 7/7 incr_tier2 tests now pass. | ||
| FIXED. g_mmap_flags type confusion fixed (Mar 23). All 9 arena_blocks_spec tests passing. | ||
| FIXED. Multi-param nested dispatch fix (type param→concrete map, mir_resolve_type_param substitution). 7/7 tests passing across multi_param_generic_spec and generic_bounded_loop_spec. | ||
go keyword Send/Sync enforcement | FIXED (Mar 24, 2026). Broadened closure detection in go callee check — any local binding used as callee triggers QZ1302. 2 send_sync tests activated. | |
FIXED. QZ0550 detection in resolver.qz:137-142 with loading stack tracking. Test active at import_errors_spec.qz:117. | ||
FIXED (Mar 25, 2026). codegen_wasm.qz read alloc size from mir_instr_get_int_val (returns 0) instead of mir_instr_get_slot1. All struct and closure allocations were zero-sized, sharing the same memory address. Caused closure env corruption (two closures sharing data) and struct field overwrites. Two-line fix. | ||
to_str integer-as-pointer heuristic | FIXED (Mar 25, 2026). Synthesized to_str checked if value ≥1032 and 8-byte-aligned → treated as string pointer. Any integer like 8080 that happened to be aligned got passed through as a pointer instead of converted to string. Removed heuristic; to_str now always calls str_from_int. | |
FIXED (Mar 25, 2026). UFCS names like Map$get, Vec$push, String$trim were not recognized by _wasm_is_synthesized, fell through to env:: import (unavailable in self-contained mode). Added _wasm_normalize_name that maps Map$X → map_X, Vec$X → vec_X, String$X → str_X. | ||
FIXED (Mar 25, 2026). f64_neg, map_size/keys/values/clear (int-key backend), vec_slice registered in typecheck_builtins.qz but missing from mir_intrinsics.qz → MIR treated them as closure variables → call_indirect on uninitialized table element. Added to all 3 pipeline stages (TC + MIR + codegen). | ||
| Parser: multi-line function signatures | MEDIUM | OPEN (Mar 26, 2026). Multi-line def parameter lists (parameters spanning multiple lines) cause a blank “cannot find module: ” error during import resolution. The parser fails to parse the continuation line as part of the function signature. Workaround: keep all function signatures on a single line. Discovered during T4.6b linter work. |
| UFCS resolver: module name collision | MEDIUM | OPEN (Mar 26, 2026). When a module name matches a common variable name (e.g. import toml/value introduces module value), the UFCS resolver tries to match variable.method() as module$method() and fails. Prevents importing modules named value, result, error, etc. Discovered during T4.6b when import toml/value broke value.to_s() calls elsewhere. Workaround: use import * from wildcard to avoid registering the module name, or rename the module. |
Prioritized Bug & Pending Test Backlog (9 it_pending — all fixable)
Stack-ranked by: correctness bugs > safety holes > usability gaps > quality polish > completeness.
Audit (Mar 24, 2026): Zero Pending Initiative reduced 145 → 9. None are permanently blocked.
NEXT UP: Regex Codegen Fix (3 tests)
Root cause: regex_matches intrinsic at codegen_intrinsics.qz:20284 builds a Vecregex_find_all_pattern results and returns the Vec header pointer. But callers expect a match COUNT (Int), not a Vec. The intrinsic conflates two behaviors: regex_find_all (return Vec) and regex_matches (return count).
Fix: Split the codegen: regex_matches should return the count (%v{d}.count64), NOT the Vec pointer. regex_find_all keeps returning the Vec. Both call @regex_find_all_pattern internally but extract different values.
Files: self-hosted/backend/codegen_intrinsics.qz:20284-20512
Tests: regex_advanced_spec.qz:71-72 (non-capturing groups, backreferences), vec_string_spec.qz:65 (regex_split)
Also needs: Quakefile cache invalidation so PCRE2 linking changes take effect.
HTTPS/TLS Test Server Infrastructure (6 tests) COMPLETE
DONE. All 6 HTTPS/TLS pending tests activated. Local test server infrastructure built using spawn+atomic port signaling pattern.
ssl_set_verify_hostnamewired intotls_connect+tls_connect_timeoutfor hostname verificationtls_ctx_load_cawrapper added for custom CA certificate loadinghttp_get_timeoutadded for HTTP requests with read timeout- Pre-existing cross-module struct field offset bug discovered and worked around (use accessor functions
tcp_fd()/tls_fd()/tls_ssl_ptr()instead of direct.fd/.sslaccess inhttp.qz) - 5 test server helpers:
_http_srv_static,_http_srv_echo_post,_http_srv_redirect,_http_srv_tls_accept,_http_srv_silent - https_spec: GET, POST, 3-hop redirect chain, invalid TLS cert rejection, read timeout
- tls_spec: hostname certificate validation via CN mismatch
Files: std/net/tls.qz, std/net/http.qz, spec/qspec/https_spec.qz, spec/qspec/tls_spec.qz
P0 — Correctness Bugs (must fix, silent wrong behavior or crashes)
| Rank | Item | Tests | What’s Wrong |
|---|---|---|---|
| #1 | FIXED (12/12). Bug A: typed vec_get in for-in + TC ptype name fix for @value struct consistency. Bug B: struct_name resolution for NODE_CALL init. | ||
| #2 | FIXED. Was already working — tests were stale. 2 tests activated. | ||
| #3 | FIXED. Double-drop in break/continue (single-call emit_drops_for_scope). Droppable leak in 4 iteration functions (pop_droppables_for_scope). 2 tests activated. | ||
| #4 | FIXED. TC function lookups now scan backwards (last-wins). Local functions shadow wildcard imports. | ||
| #5 | FIXED. TC extracts inner type from Option |
P1 — Usability Gaps (blocks idiomatic code)
| Rank | Item | Tests | What’s Wrong |
|---|---|---|---|
| #6 | FIXED. TC: resolve ptype annotation via init expression (not tc_type_name_full). MIR: strip generic args before field index lookup. | ||
| #7 | FIXED. Already working after H-M Phase A-E. Test activated. | ||
| #8 | Import: circular detection | 1 | OPEN. Compiler does not detect or error on circular imports. Test converted to it_pending (Mar 23). |
| #9 | FIXED. Already works — arity checking and arity overloading both function across module boundaries. 2 tests activated. | ||
| #10 | FIXED. Parser/MIR/codegen all handle guard expressions on every pattern type. Test activated. |
P2 — Quality Polish (DX, error messages, completeness)
| Rank | Item | Tests | What’s Wrong |
|---|---|---|---|
| #11 | ALL FIXED. QZ0161, QZ0107, QZ0201, QZ0204 (ambiguous type inference — scans unbound type vars at function exit), QZ1207 (no-else linear branch check). | ||
| #12 | Stack traces on panic | 2 (1 remain) | Panic message test activated. Backtrace deferred: pre-existing jmpbuf bug causes longjmp SIGSEGV. Dead duplicate panic handler removed. |
| #13 | ALIAS FIXED — already works end-to-end. Transitive error messages pending (needs resolver import chain context). | ||
| #14 | Generic edge cases (remaining) | 9 (5 remain) | Multi-param nested dispatch FIXED (type param→concrete map in spec_param_types, mir_resolve_type_param substitution). Cross-module generic structs remain. Generic enum match (unwrap_or) FIXED, generic struct return FIXED. |
| #15 | Bounded generic remaining | 6 (4 remain) | Multi-param nested dispatch FIXED. UFCS constraint lookup remains. |
P3 — Feature Completeness (post-launch OK but worth tracking)
| Rank | Item | Tests | Notes |
|---|---|---|---|
| #16 | ALL FIXED. Labeled continue (already worked). Loop-as-expression with break VALUE — parser accepts break expr, MIR stores to _loop_expr_result_var, TC infers type from break values via tc_find_break_value_type. | ||
| #17 | Struct params FIXED (compilation test). Varargs runtime permanently blocked by lli JIT. | ||
| #18 | DONE. crypto_rand_int() intrinsic via arc4random_buf. | ||
| #19 | @cfg advanced | 3 | arch/feature/AND/OR conditions |
| #20 | Platform-specific (lli JIT) | 6 | PCRE2, C macros — permanent platform limits |
Blocked (need infrastructure)
| Item | Tests | Blocker |
|---|---|---|
| DONE. All 6 HTTPS/TLS tests activated. 2 network timeout tests already active. |
Parallel Execution Map
TRUNK (Main Session) WORKTREE (Anti-Gravity)
──────────────────────────────── ────────────────────────────────
✅ TIER 0 COMPLETE (#1-#7)
-> Claims are TRUE
✅ #8 Diagnostic formatter wiring <-> ✅ #9 Error code documentation
✅ #10 REPL world-class #11 VS Code extension publish
✅ #12 Multi-param generics #14 Getting Started guide
✅ #13 Intersection record merging #15 Stdlib user guide
#20 Examples directory
-> Type system COMPLETE, DX WORLD-CLASS
<-> #16 Testing guide
#17 FFI guide
#18 Error handling guide
#19 Debugging guide
-> Documentation COMPLETE
✅ #21 Send/Sync traits <-> #24 Linux validation
✅ #22 Arena lifetime safety #28 Linter enhancement
✅ #23 Multi-arg extern fix
#25 Exhaustiveness completion
-> Safety AIRTIGHT
#26 Package manager <-> #27 LSP server
-> Ecosystem FOUNDATION
<-> #29 Website
#30 Flagship demo app
#31 Launch blog post
#32 Community infra
-> LAUNCH
Estimation Calibration
Empirical data (Dec 2025 - Mar 2026): 1,286 commits in 90 days. One developer + Claude.
| Traditional Estimate | Actual Time | Examples |
|---|---|---|
| ”1 week” | 1-2 days | String comparison audit, bool narrowing, register passing |
| ”2-3 weeks” | 3-5 days | Move semantics (9 phases), borrow checker (5 phases), memory model V2 |
| ”3-4 weeks” | 5-7 days | Standard library (8 modules), formal spec (5 phases), Quake build system |
| ”1-2 months” | 2-3 weeks | Full safety system (S2.1-S2.5), complete type system polish |
Apply this 4x fudge factor to all estimates above.
Launch Readiness Audit
Full adversarial audit: LAUNCH_READINESS_AUDIT.md
Current Grade: B- | After this roadmap executes: A.
Top strengths: self-hosting fixpoint, memory safety, C-competitive performance. This roadmap closes every gap the audit identified — no items deferred without justification.