BuildLang Project Status

September 10, 2026 · View on GitHub

Release verification: 2026-09-10 for 1.4.0. The broader architecture audit remains 2026-06-15; dated findings below retain their original scope.

The full local cargo test --manifest-path compiler/Cargo.toml --quiet run with RUSTFLAGS=-Dwarnings passed: lib 1,054, bin 202, cli 390, gpu 12, lexer 53, parser 98, stdio_mode 9; total 1,818 passed, 0 failed, 11 ignored (3 lib, 8 doc). Formatting, repository-art verification, and the optimized strict-warning build also passed. These default-feature checks do not establish optional GPU device behavior, performance superiority, or complete experimental-backend parity.

Development status (2026-07-02): the invariant family is COMPLETE and shipped. Main 1c8c850 carries the full Telos master-plan mandate for the "Scientific Runtime" pillar: Phase A (the receipt export bridge producing WITNESSED Crucible measurements), Phase B (the effect system filling the receipt's input_dataset / seed / determinism fields as capability-derived witnessed absences, fail-closed, plus the declared method and effect-policy chain), and Phase C, the INVARIANT FAMILY, delivered in five reviewed slices: C1 registry + conservation, C2 bounded (discrete maximum principle), C3 energy-identity (a quantitative energy-balance residual, empirically calibrated), C4 multi-column capture + relation (the first invariant whose check the VERIFIER computes across a row's columns), then Phase D: D1 conserved-band (approximate conservation, grounding symplectic integration), D2 non-negative (an absolute lower floor, and the family's first ALGORITHMIC use: a binary search's probe slack stays non-negative under its proven bound), and D3 the reaction-invariant checker (the family applied to a chemistry reaction network via conservation). The family is now EIGHT members: energy-monotone, conservation, bounded, energy-identity, relation, conserved-band, non-negative, and cross_backend_columns_agree (added 2026-07-28 via --cross-backend rust), each with a paired positive/negative kernel, a fixed re-checked tolerance, and a verdict re-derived by re-running the program. Every slice was adversarially reviewed (a real HIGH in Phase B on path-qualified stdin detection, a real MEDIUM in C4 on a sealed-field serde default, a low in D1 on the verify-side column-count contract, plus C1's export-label fix and a D3 wording nit, all confirmed and fixed before merge). Gate at 52d4968: full suite 940/140/309/52/88, corpus 8/8, live matrix green. Both of the master plan's named demos ship: the Hamiltonian runtime branch (the symplectic conserved-band slice) and the reaction invariant checker. Remaining follow-ons (Phase D continued, NOT started): relations beyond per-row agreement (the Carcassi Born-rule identity), a FULL funnel-hashing (arXiv 2501.02305) probe-complexity kernel (the result-bearing-bound concept already ships via non-negative + binary search), and the Lyapunov-decrease certificate (owned by the neighboring proof-surface wedge #10 session, not this repo). Roadmap: docs/superpowers/plans/2026-07-01-research-uplift-backlog.md + the Telos master-plan mandate recorded in the session ledger. The 2026-06-15 wind-down assessment (docs/COMPILER_WIND_DOWN_ASSESSMENT_2026-06-15.md) still governs backend scope: C is the product anchor, Rust is the validation lane.

Update (2026-07-28 to 2026-07-29): the five-modes wave shipped. Four admission blocks now extend the receipt schema beyond the base fields: a seed block for a new Random capability (a witnessed seed, sealed as seed_value), a monte_carlo block (declaration discipline over an estimator's sample count and interval method, never the interval's correctness), a budget block (a declared step ceiling, a DERIVED exhausted flag, and NOT_PROVES_OPTIMALITY on every budgeted receipt), and a cross_backend block (EXECUTED, not DECLARED: --cross-backend rust re-runs both backends at verify and adds the invariant family's eighth member, cross_backend_columns_agree). A separate new Model capability (model_complete, a line-protocol call to BUILD_MODEL_ENDPOINT) is refused outright at both emit and verify (CAPABILITY_INADMISSIBLE): models propose, oracles dispose. docs/FIVE-MODES-TOUR.md chains one receipt per computation mode (deterministic, exact-probabilistic, seeded stochastic, Monte Carlo, budgeted heuristic, plus the cross-backend bonus) into one ordered, tamper-evident bundle via receipt chain. A model boundary receipt (buildlang-model-boundary-receipt/v0, docs/MODEL-RECEIPT.md) can now be a chain member beside a scientific-runtime receipt (receipt chain build's two-schema allowlist); it is a harness-emitted, offline-verified provenance artifact, not scientific evidence, and is not a corpus or --self-test member. Historical baseline: 1704 tests passing, 0 failing, 11 ignored; the example corpus (examples/scientific-corpus.json) is unchanged at 30/30; the verifier --self-test is unchanged at 10/10.

Identity

The Effects Language -- algebraic effects as a first-class feature.

What Works (verified, tested, compiles)

  • Lexer: Complete Unicode-aware tokenizer with comprehensive token types, spans, error recovery. 59 unit tests. The tests/lexer/ integration suite (51 tests, 2026-06-29) is now wired via a [[test]] entry and runs green. Wiring it surfaced and fixed: a stale import (LexerConfig, removed; tokenize_file, unused), a genuinely-stale raw-string test (an r##"..."## case whose body embedded the "## terminator, corrected to r###"..."###), two unicode tests whose non-ASCII characters had been stripped from the source (restored with \u escapes), and a real lexer defect: scan_dsl_block rejected whitespace between name! and the opening delimiter, so the conventional sql! { ... } spacing now lexes the same as sql!{ ... }.
  • Parser: Full recursive descent with Pratt parsing for expressions. Handles functions, structs, enums, match, if/else, loops, effects, generics, patterns. 4 unit tests. The tests/parser/ integration suite (2026-06-29) is now wired via a [[test]] entry and runs green (83 tests); the fails() helper was corrected to detect the error-recovering parser's recorded errors instead of only Err results.
  • Type Checker: Hindley-Milner inference, effect tracking, unification, trait resolution, const generics, higher-kinded types. Function and method signatures now carry declared capability effects, and function effect rows participate in unification so effectful callbacks cannot be accepted by pure fn(...) boundaries. Callbacks such as fn() with FileSystem, inherent methods such as Config.load, associated functions such as Config::load, and trait-object methods such as Loader.load propagate typed accountability through higher-order calls, static method-call syntax, associated-function syntax, and dynamic dispatch, including effectful closure values, pure tuple-struct and tuple-/struct-like enum-variant callback storage, anonymous immediate closure calls, awaited async block effects with latent origin receipts such as task <- read_file, selected async future branch-effect unions for if and match, caller-side callback argument evidence such as run(load_config), tuple-, tuple-struct-, struct-, enum-variant-, slice-, branch-local if let/while let, if/if let/match selected callback, cast selected callback, and reference/dereference selected callback evidence, pure callback casts checked against function effect rows, pipe application checked as effectful function application, ordinary binary operators rejecting function values instead of pretending to compose callbacks, invalid ? and .await use rejected on plain callback values before it can erase effect rows, refreshed provenance for assigned callback aliases, aggregate-member callback slots, whole-aggregate callback assignments, nested-block mutations of outer callback aliases and aggregate slots, conservative source merging for conditional, if let, match, explicit loop break, while, while let, and for assignment into outer callback aliases and aggregate slots, nested aggregate-member provenance, nested if let selected aggregate field provenance, destructured nested aggregate provenance, direct struct-update-expression destructuring provenance, explicit struct-update field replacement, aggregate-literal destructuring, control-flow-selected aggregate provenance pruning, shorthand aggregate-field provenance pruning, stored enum-variant aggregate payload provenance pruning, and same-scope/inner-scope shadowed opaque aggregate provenance pruning, repeated indexed callback arrays, and nested struct-update-inherited callback fields, compile-time include/environment macros gated as direct FileSystem/Environment sources, macro argument token trees scanned with SourceId provenance so ambient helpers, macros, unknown extern calls, and foreign statics cannot hide inside macro invocations or external module files, known effectful build_* C runtime aliases declared in extern blocks classified under their domain capability instead of generic Foreign, and foreign static reads surfaced as direct Foreign boundaries. Interprocedural lifetime analysis: lifetime parameters in function types (FnTy), lifetime-aware call-site borrow tracking, return lifetime validation via unification. Unit tests across multiple files. Unit-annotated numeric types (2026-07-29, checker slice one, EXPERIMENTAL, opt-in): f64<m/s>-style dimension annotations parse through the shipped units::parse_unit grammar and are enforced at every unification boundary (let, assign, argument, return) plus operation-worded checks for +/-/compare and derived dimensions for *//, with ** on a unit-carrying operand a loud UnsupportedConstruct refusal; not claimed: no runtime unit tracking (erased before MIR, byte-identical emitted C), no dimension-variable inference (an unannotated float stays unconstrained, weak mode), and no scientific-runtime receipt derivation (--units stays the receipt's unit source). Detail: docs/DIMENSIONAL-ANALYSIS.md.
  • C Backend: Generates valid C99 from BuildLang source. Handles structs, unions, globals, string tables, branching, all binary/unary ops. 11 unit tests. This is the only backend with end-to-end native execution verified by the compiler test suite.
  • Native FFI (header-backed extern + link): extern blocks accept optional header "..." and link "..." clauses, in either order. The C backend emits the matching #include (angle-bracket form for "<sqlite3.h>", quoted form for "mylib.h"), sorted and de-duplicated for reproducible output, and skips synthesizing a prototype for header-backed functions so the header's real declaration is authoritative. The link clause is carried on GeneratedCode.link_libraries; buildc build passes each library to the C compiler (-lname for gcc/clang/cc, name.lib for MSVC via user_link_flags) and the emitted C records a greppable // buildc-link: name note. This is the native, embedded integration path for any C-ABI library: include, declare, and link in one command. Foreign static declarations are also supported: they lower to external-declaration globals carrying the block's header/link, so the backend includes the header (or emits a bare extern <type> <name>; when none is given) rather than emitting a conflicting definition. Verified at the parser, lowering, C-backend-text, and user_link_flags layers, and end-to-end through buildc build --emit c. Native linking against the third-party library is performed by the user's C toolchain, not the compiler test suite. This is distinct from runtime/ffi.rs, which remains unused by codegen.
  • Native FFI (variadic): extern functions accept a trailing C-style ... (e.g. fn printf(fmt: &str, ...) -> i32). Recorded on FnSig.is_variadic and FnTy.is_variadic, lowered to the MIR signature (C backend emits , ...), and the type checker lets a variadic call pass more arguments than fixed parameters while keeping exact arity for non-variadic calls. Verified end-to-end through buildc check and buildc build --emit c (printf("%d and %d\n", 1, 2) lowers to printf(fmt, 1, 2)).
  • Native FFI (export): extern "C" fn is accepted as a function definition (not only inside extern blocks). A C-ABI definition is lowered with external linkage and a stable, unmangled name, so the C backend emits a non-static function callable from C and any C-ABI consumer. Ordinary functions keep internal (static) linkage. buildc build --emit header writes a main.h declaring the exports (include guard + integer/bool/size typedefs + #ifdef __cplusplus extern "C" guard) so consumers can #include it. This is the reciprocal of header-backed extern blocks; verified via the parser, lowering, and C-backend-text layers and end-to-end through buildc build --emit c and --emit header.
  • Effects: Parse -> type check -> codegen pipeline (setjmp/longjmp C runtime).
  • Programs that compile: Variables, functions, if/else, loops, match, recursion, arithmetic, effects -- all compile to C and execute via buildc build.
  • Auto-compile: buildc build discovers and invokes system C compiler (gcc/clang/MSVC).
  • CLI subcommands: lex, parse, check, build, run, test, repl, version, doctor, corpus, policy, receipt, lsp, fmt, pkg, watch.
  • MIR pipeline: Full MIR builder (codegen/builder.rs, 29 tests), MIR IR (codegen/ir.rs, 31 tests), debug info (codegen/debug.rs, 24 tests), embedded C runtime (codegen/runtime.rs, 7 tests).
  • Macro expansion: Builtin macros, pattern matching, hygiene. Unit tests present.
  • Interprocedural Lifetime Analysis (Phase 1): Lifetime parameters flow through FnTy (function types), enabling precise borrow tracking at call sites. Functions like fn pick<'a, 'b>(x: &'a i32, y: &'b i32) -> &'a i32 correctly propagate only the 'a-linked borrow. Return lifetime mismatches (returning 'b where 'a expected) are rejected with clear errors. 8 new unit tests, 3 integration test programs.
  • Historical CI-shaped cargo baseline (2026-07-02, invariant family complete): lib 940, bin 140, cli 309, lexer 52, parser 88 (0 failed; 3 lib + 8 doc-test ignored) via cargo test from compiler/; cargo fmt --check clean; corpus 8/8. The rise from the 939/81/301 wind-down baseline is Phases A/B/C/D1-D3 of the Telos master-plan mandate: the receipt export bridge, the capability-witnessed receipt fields, and the seven-member invariant family (conservation, bounded, energy-identity, relation, conserved-band, non-negative) with their paired kernels and multi-column capture. (Prior 2026-06-23 baseline was 1002 passed / 0 failed / 11 ignored under a different aggregation.)
  • Historical CI-shaped cargo baseline (2026-07-29, model boundary receipts verify arm): lib 1001 passed, 3 ignored, bin 195 (+10 model_receipt.rs tamper/seal/golden-fixture unit tests), cli 346 (+5 model-receipt CLI integration tests: golden fixture, seal mismatch, resealed field-shape violation, chain-allowlist refusal, propose/dispose chain with a tampered model member), gpu 12, lexer 52, parser 98 -- 1704 passed, 0 failed, 11 ignored total, via cargo test from compiler/; cargo fmt --check clean; buildc receipt corpus examples/scientific-corpus.json 30/30 (unchanged: the model receipt is a different artifact kind, not a corpus member); verifier --self-test 10/10 (unchanged: scientific-runtime-only table); buildc corpus verify (the 8-program semantic corpus, a separate C-backend regression check) stays 8/8. The rise from the 2026-07-02 940/140/309/52/88 baseline above is the five-modes wave (2026-07-28 to 2026-07-29): the Random capability with witnessed-seed receipts, Monte Carlo estimator receipts, budgeted-search receipts, the Model capability's propose/dispose refusal, cross-backend relation receipts through the Rust backend (the invariant family's eighth member), wall-clock metering (runtime_state.wall_seconds, the receipt's first EXECUTED budget fact), executed Monte Carlo intervals with a witnessed denominator (the monte_carlo block's EXECUTED status), split-frontier drop flags (memory pillar increment 5, opt-in), and unit-annotated numeric types (checker slice one, experimental). Detail: docs/FIVE-MODES-TOUR.md.
  • Linear types #[linear] (2026-07-01, experimental — best-effort LINT, not a proven-sound checker): opt-in no-cloning. A #[linear] struct/enum value is tracked as a resource that should be moved/consumed at most once -- the shared foundation for quantum qubit no-cloning, on-chain no-double-spend, and fin-sec resource-handle safety. Now enforced by two layers: the conservative AST gate (sound-over-complete name tracking + containment rule) AND a new MIR affine/borrow checker (codegen/analysis/linear.rs, built on the reusable codegen::analysis dataflow substrate) that runs post-lowering and closes the classes the name tracker cannot follow -- move-out-of-shared-borrow (incl. laundered through aggregates/returns and higher-order fn-pointers), field-extract from an owned linear aggregate, generic deref-and-return, and struct/enum record-pattern-through-&. Verified by repeated empirical adversarial sweeps (buildc check on constructed clones, confirmed with buildc run). Not yet fully sound (do NOT claim a soundness guarantee): known residual = &mut-match payload move + un-enumerated advanced corners; a complete affine checker is a deliberate multi-brick effort (cf. Rust's borrow checker). Honest scope: docs/LINEAR-TYPES.md. Ordinary types are unaffected (copy-like reuse preserved).
  • Multiple dispatch (2026-07-01, static): Julia-style — multiple functions may share one name, and a call selects the method by the tuple of ALL argument types (not just the receiver), resolved statically via one shared resolver (types/dispatch.rs) used by both the checker and codegen. Specificity: exact > coercion/concrete > generic; ambiguity and no-match are ERRORS (never a silent pick). Generic and concrete defs of a name compose (concrete wins when it matches, else the generic monomorphizes). Backward-compatible: only overloaded (2+ def) names are mangled, so single-def names and extern "C" FFI are byte-identical (verified by a 22/22 differential C sweep). Deferred: operator overloading on both operands (still left-operand-only), and dynamic runtime-type dispatch (no runtime type descriptors yet). Details: docs/MULTIPLE-DISPATCH.md.
  • Math syntax (2026-07-01, Pillar B): four additive, backward-compatible features (each verified by a differential C sweep showing existing programs unchanged). (1) Broadcasting operators .+ .- .* ./ over fixed-size Array<T,N> (the type of an array literal [..]), including scalar broadcast in both directions; length agreement is a COMPILE-TIME check carried in the Array<T,N> type (no runtime dimension check), and codegen desugars each operator into an unrolled array of per-element SCALAR MIR ops, so the broadcast ops never reach any backend. (2) linalg stdlib module (stdlib/linalg.bld): free functions vec_add/sub/mul/div, vec_scale, vec_scalar_add, vec_dot, vec_sum, vec_norm over the dynamic Vec<f64>, no compiler/runtime change. (3) ** power wired to the pre-existing BinOp::Pow (right-associative, -2 ** 2 == -4; prefix **x stays double-deref, so no pointer code changes). (4) Unicode operator aliases × · ∙ -> *, ÷ -> /, − -> -. Honest scope: this is elementwise broadcasting over FIXED-SIZE arrays plus a 1-D vector library over DYNAMIC Vec<f64> (two distinct surfaces: operators work on array literals, the library on Vec; a Vec cannot yet use .+), NOT Julia-parity linear algebra. Deferred: dynamic-Vec broadcasting operators, a true 2-D Matrix{T} with linear algebra (no N-D MIR type exists), f32 element parity, and broadcast comparisons/.^. Details: docs/MATH-SYNTAX.md.
  • Scientific-runtime receipt + invariant family (2026-07-02, accountable compute): buildc run --emit-receipt <path> compiles and runs a .bld program, captures its numeric stdout as a measurement series, checks a stated invariant over that series, and emits a sealed, re-checkable JSON receipt (buildlang-scientific-runtime-receipt/v0). buildc receipt verify RE-RUNS the program, re-derives the source and effect-policy facts, and re-checks the invariant verdict (drift, tamper, or source change fails with a typed failure_class; version drift WARNs). The invariant family now has EIGHT members, each a fixed re-checked tolerance and a paired positive/negative kernel: energy-monotone (non-increasing), conservation (constant within tol of the initial value), bounded (never exceeds the initial value: the discrete maximum principle), energy-identity (a QUANTITATIVE per-step energy-balance residual held at roundoff, the FTCS discrete analogue of d/dt integral(u^2) = -2*alpha*integral(u_x^2)), relation (--columns N: the VERIFIER checks the columns of each row agree, so a program printing two independent computations of a quantity cannot hide a divergence), conserved-band (APPROXIMATE conservation within a fixed error budget, e.g. a symplectic leapfrog integrator's energy oscillating in an O(dt^2) band while explicit Euler drifts out), non-negative (an absolute lower floor: no value drops below zero, the companion to bounded and the family's first ALGORITHMIC use, witnessing that a binary search's probe-count slack stays non-negative under its proven bound), and cross_backend_columns_agree (--cross-backend rust: the VERIFIER re-runs the kernel through BOTH the C and Rust backends and checks their interleaved columns agree within tolerance, added 2026-07-28). Beyond physics kernels (heat, rotation, oscillator, symplectic) it also ships a reaction-network demo (A + B <=> C atom balance) and a cross-column relation demo. The receipt also carries capability-derived witnessed-absence fields (input_dataset / seed / determinism, fail-closed from the effect system) and a receipt export bridge that re-verifies and emits WITNESSED Crucible measurements. Additive: run without --emit-receipt is byte-identical; the buildlang-check-receipt/v1 verify path is unchanged. Honest scope: the receipt witnesses that the compiled program's OBSERVED OUTPUT SERIES satisfies (or expectedly violates) the invariant; it does NOT prove PDE correctness and does NOT claim a physical law (every receipt carries the NOT_A_NEW_PHYSICAL_LAW label). Four admission blocks (2026-07-28 to 2026-07-29) now extend the schema beyond the base fields, each declared all-or-nothing and re-checked against its own FIELD_CONTRACT_VIOLATION shape contract: seed for the new Random capability (a witnessed seed, a NOT_APPLICABLE/SEALED/UNSEEDED trichotomy), monte_carlo (--mc-estimator/--mc-samples/--mc-interval, sealing an estimator's declaration discipline over its denominator and interval method, never the interval's correctness), budget (--budget-steps/--budget-consumed, a DERIVED exhausted flag, NOT_PROVES_OPTIMALITY on every budgeted receipt, plus an optional --budget-wall-seconds ceiling), and cross_backend (--cross-backend rust, EXECUTED not DECLARED, re-run through both backends at verify). A separate new Model capability (model_complete, a line-protocol call to BUILD_MODEL_ENDPOINT) is refused outright at both emit and verify (CAPABILITY_INADMISSIBLE): models propose, oracles dispose, so no receipt can ever carry a Model-observing run. The example corpus (examples/scientific-corpus.json) is now 30 members and the verifier --self-test covers nine tamper cases; a chained walkthrough of all five computation modes plus the cross-backend bonus lives in docs/FIVE-MODES-TOUR.md. Deferred (Phase D continued): the Carcassi Born-rule identity, a full funnel-hashing probe-complexity kernel (the concept ships via non-negative + binary search), and the full 7-layer richness. Details: docs/SCIENTIFIC-RECEIPT.md.
  • Verifier falsification, research-uplift wave 1 (2026-07-01): every buildc verification surface can now demonstrably FAIL (the governing lesson from the research-corpus audit: a verifier that structurally cannot fail proves nothing). Concretely: (1) the semantic-corpus capability gate is genuinely RE-DERIVED through the type checker per program (previously an author-side "passed" stamp that verify string-compared), with a per-program manifest-surface cross-check and a full surface-to-capability vocabulary; (2) the C/Rust execution receipts gained their first tamper tests (stdout, pass count, program list, capability metadata, gate stamp, per-program surface); (3) every scientific-receipt verify failure carries a stable machine-readable failure_class (including a sealed exit-code re-check, RERUN_EXIT_MISMATCH); (4) receipts AND policy files load through a strict duplicate-key-rejecting JSON parser (last-duplicate-wins parsing is a seal-forgery vector); (5) corpus verify --write verifies in memory before persisting. One adversarial review round (8 confirmed findings) fully adjudicated before merge. Details: the wave-1 section of docs/superpowers/plans/2026-07-01-research-uplift-backlog.md.
  • Native FFI update (2026-06-29): added tests for the header "..." / link "..." clauses, foreign static support, extern "C" fn exports, the --emit header export header, and C-style ... variadics (parser, lowering, C-backend/GeneratedCode, type checker, user_link_flags). The orphaned parser (83) and lexer (51) integration suites were also wired into Cargo. cargo test --quiet from compiler/ stays green (lib 784, bin 44, cli 260, lexer 51, parser 83; 0 failed) and RUSTFLAGS=-Dwarnings cargo build is clean.
  • Warning-clean baseline (2026-06-15): the prior 868-test suite passed with RUSTFLAGS=-Dwarnings; re-run before making a current warning-clean claim.
  • Wind-down assessment (2026-06-15): see docs/COMPILER_WIND_DOWN_ASSESSMENT_2026-06-15.md. Broad language/backend expansion should pause; C remains the product anchor, Rust remains an experimental validation lane, and x86/x64 remains preserved backend research.

What's Partial (has real code, wired into CLI but not end-to-end verified)

  • Rust Backend (subset-based): Emits Rust source from MIR and is wired into the CLI via buildc build --target rust / --target rs. Generated Rust is validated with rustc --emit=metadata for 14 subset tests covering scalar branching, references, structs/arrays, struct-field references, repeated non-Copy struct arrays, reused structs after assignment and by-value calls, reused tuple values after by-value calls, reused non-Copy values after field assignment, reused non-Copy struct and tuple aggregate fields, reused non-Copy nested field access, reused non-Copy dereference, and a lifetime smoke program. A narrower semantic-corpus execution slice compiles generated Rust to executables and asserts stdout for 8 programs: scalar branching, reference mutation, structs/arrays, tuple ownership reuse, struct aggregate reuse, field assignment reuse, nested field reuse, and dereference reuse. The semantic corpus manifest also drives a Rust execution test so manifest paths, expected stdout, backend lowering, and executable behavior stay coupled; manifest contract, receipt consistency, and metadata tests keep the manifest and Rust execution receipt aligned. Unsupported MIR returns a codegen error rather than silent fallback. The receipt layer now consumes this lane via --cross-backend rust (cross-backend relation receipts, 2026-07-28).
  • x86-64 Backend (1,716 lines, 22 tests): Generates assembly from MIR. Wired into CLI via buildc build --target x86-64. No linker integration yet - outputs .s assembly.
  • ARM64 Backend (1,718 lines, 21 tests): Generates assembly from MIR. Wired into CLI via buildc build --target arm64. No linker integration yet - outputs .s assembly.
  • WASM Backend (2,215 lines, 11 tests): Generates WebAssembly binary from MIR with WASI support. Wired into CLI via buildc build --target wasm. No end-to-end .wasm execution test.
  • LLVM Backend (3,041 lines, 11 tests): Generates LLVM IR text from MIR. Wired into CLI via buildc build --target llvm. Optionally compiles to executable with clang. Requires external LLVM tools.
  • SPIR-V Backend (5,417 lines, 7 tests): Generates SPIR-V binary for Vulkan compute. Wired into CLI via buildc build --target spirv. No Vulkan validation test.
  • x86-64 Instruction Encoder (2,123 lines, 38 tests): Encodes x86-64 instructions to binary machine code. Works in isolation but no linker/loader to produce executables.
  • ARM64 Instruction Encoder (2,073 lines, 32 tests): Encodes ARM64 instructions to binary. Same limitation.
  • LSP Server (7,717 lines, 45 tests): Provider implementations exist for completion, hover, compiler-backed diagnostics, go-to-definition, symbols, semantic tokens v0, formatting, folding ranges, code actions, and rename. Wired into CLI via buildc lsp; the raw dispatch path now uses structural JSON-RPC parsing and has a semantic-corpus LSP dispatch receipt for lifecycle, document sync, provider requests including textDocument/semanticTokens/full and opened-document workspace/symbol, code actions, rename, and compiler-backed diagnostic notifications. End-to-end VS Code extension behavior, full compiler-backed semantic token indexing, and global workspace-symbol indexing are not yet receipt-verified.
  • Formatter (1,657 lines, 11 tests): Code formatter with configurable style. Wired into CLI via buildc fmt <file>. Supports --check and --write flags.
  • Package Manager (3,503 lines, 24 tests): Manifest parsing (Build.toml), semver, lockfile, dependency resolution. Wired into CLI via buildc pkg. No registry exists yet.
  • Runtime: FFI (1,118 lines, 7 tests): Calling convention definitions, type layout, ABI classification. Not used by any code generation backend.
  • Runtime: GC (789 lines, 4 tests): Reference counting with cycle detection design, in Rust (a compiler-internal model, not the C that runs in compiled programs). Not linked into compiled programs. Verified gap (2026-06-30): the MIR builder inserts no Drop terminators and the C backend's Drop arm is a no-op, so the runtime's build_*_free functions are never called and compiled programs do not reclaim heap memory (a 3-String program lowers to 9 allocations, 0 frees). Closing this "memory pillar" needs ownership-based drop insertion or a C-level GC; design, soundness rule, bounded first step, and ASan verification plan are in docs/MEMORY-PILLAR-DESIGN.md. First sound drop-insertion increment SHIPPED behind the opt-in BUILDLANG_EXPERIMENTAL_FREE flag (default off, baseline untouched): a conservative analysis (freeable_owned_string_locals) + complete use scan + build_string_free emission at returns; 3 unit tests, full suite green, and corpus c-execution stays 8/8 with the flag enabled. Coverage is deliberately narrow (frees only entry-block-defined, never-referenced owned BuildString locals); broadening is tracked in the design doc. Increment 4 (2026-06-30, feat/mir-affine-foundation): a reusable codegen::analysis module (backward MIR liveness compute plus a borrow-aware buffer-liveness overlay) was extracted from the C backend so both drop insertion and a future MIR linear checker can consume it. On that substrate, increment 4 frees heap-string owners whose live range SPANS multiple blocks (the case the single-block block-scoped rule declines) at the unique block where the buffer dies on every incoming edge, via a terminal/clean death-frontier rule with a loop-header exclusion (never frees at a re-entrant block, closing a double-free an adversarial pass caught). It is additive and disjoint from increments 1-3 (each buffer is freed by exactly one increment) and stays behind BUILDLANG_EXPERIMENTAL_FREE (default off; the verified baseline is unchanged). Verified: ASan-clean on a 1,000,000-iteration multi-block allocating loop (zero use-after-free, zero double-free); buildc corpus verify 8/8 with the flag on and off; and a six-lens adversarial pass found no production-reachable unsound free. Increment 5 (2026-07-29, feat/drop-flags) ships flag-guarded frees for split and conditional death frontiers behind the same opt-in flag: a per-buffer uint8_t __bl_live_N drop flag, set immediately after the owner's unique allocation or move-acquire, tested and cleared at every free; frees land at non-re-entrant death-frontier blocks (no dominance or uniqueness requirement, unlike increment 4) plus a guarded Return backstop that reclaims paths bypassing every frontier site. Verified: ASan-clean on two 1,000,000-total-iteration real-program fixtures (one conditional-use, one conditional-allocation, each an on/off pair run twice under /fsanitize=address), plus a six-lens adversarial pass in an isolated worktree (nested-loop and early-return ASan stress cases, both clean; two mutation runs each caught the intended hazard, double-free and bad-free); buildc corpus verify 8/8 with the flag on and off; full suite 1,613 passed, 0 failed. Remaining declines: escaping/reassigned/multi-move-tainted owners (unchanged from increments 1-4); allocations outside the closed 6-name allocates_owned_string list; re-entrant frontier sites (loop headers, self-loops: only the Return backstop reclaims those, so a loop whose only death frontier is its header still leaks per-iteration, safe, and relaxing this is a named follow-up now that the flag makes it soundness-feasible); the not-moved path of a conditional move (the source is excluded wholesale); BuildVec/BuildMap/hvec buffers (build_vec_free/build_hvec_free remain dead code, strings only across all five increments); C backend only, the MIR builder still inserts no Drop terminators. The "memory pillar" is NOT done and the flag is NOT default-on.
  • Runtime: Async (1,256 lines, 6 tests): Work-stealing scheduler design. Parser and type-checker surfaces exist for async blocks and .await, including delayed capability-effect accountability on awaited futures, latent ambient source provenance in await diagnostics/receipts, branch-effect unioning for if/match selected async futures, and rejection of concrete non-future .await operands before they can launder callback effects, but the async runtime is not linked into compiled programs and async execution is not end-to-end verified.

What's Aspirational (architecture exists, doesn't function)

  • Self-hosted compiler (buildlang/src/, 217,961 lines): Complete compiler written in BuildLang (lexer, parser, AST, types, HIR, MIR, codegen for x86_64/AArch64/WASM, driver, LSP, package manager, formatter, linter, test framework, build system, doc generator). Cannot be compiled or executed. The Rust compiler does not support the .bld module system, import syntax, or standard library used by this code.
  • Self-hosted stdlib (buildlang/stdlib/, 26,124 lines): Core library (Option, Result, Iterator, primitives, memory, pointers), Alloc library (Box, Vec, String, Rc), Std library (fs, thread, sync, net, time, process). Modeled after Rust's standard library. Cannot be compiled or executed.
  • Self-hosted test suite (buildlang/tests/, 7,505 lines): Test framework and test cases for the self-hosted compiler. Cannot be executed.

Honest Line Counts

  • Compiler source (Rust, compiler/src/**/*.rs): 88,946 lines -- STATUS: working core (lexer, parser, types, C backend), partial other backends/tools
  • Compiler test sources (Rust, compiler/tests/): 10,976 lines -- STATUS: working
  • Compiler tree total (tracked Rust under compiler/, excluding build output): 100,171 lines across 92 files
  • Self-hosted compiler (BuildLang, buildlang/src/): 217,961 lines -- STATUS: aspirational, cannot compile
  • Self-hosted stdlib (BuildLang, buildlang/stdlib/): 26,124 lines -- STATUS: aspirational, cannot compile
  • Self-hosted tests (BuildLang, buildlang/tests/): 7,505 lines -- STATUS: aspirational, cannot execute

What the CLI Actually Does Today

buildc lex <file>          # Tokenize and print tokens
buildc parse <file>        # Parse and print AST
buildc check <file>        # Type-check
buildc build [path]        # Compile to C, invoke C compiler, produce executable
buildc build --target llvm # Compile to LLVM IR (.ll), optionally link with clang
buildc build --target x86-64  # Compile to x86-64 assembly
buildc build --target arm64   # Compile to AArch64 assembly
buildc build --target wasm    # Compile to WebAssembly (.wasm)
buildc build --target spirv   # Compile to SPIR-V binary (.spv)
buildc build --target hlsl    # Compile to HLSL shader
buildc build --target glsl    # Compile to GLSL shader
buildc run <file>          # Compile and run (C backend)
buildc repl                # Interactive REPL
buildc lsp                 # Start Language Server Protocol server
buildc fmt <file>          # Format BuildLang source code
buildc pkg init            # Initialize Build.toml manifest
buildc pkg add <name>      # Add a dependency
buildc pkg resolve         # Resolve dependencies and generate lockfile
buildc pkg search <query>  # Search the package registry
buildc watch [path]        # Watch files and recompile on change
buildc doctor              # Diagnose compiler/toolchain/backend readiness
buildc policy list         # List built-in check policy profiles
buildc policy print <name> # Emit a built-in check policy profile as JSON
buildc policy scaffold <receipt.json> # Scaffold an exact strict policy from receipt evidence
buildc receipt verify <receipt.json> [--json]  # Verify a saved check receipt against current source inputs
buildc corpus verify       # Verify semantic corpus receipts and C stdout
buildc corpus verify --root <dir> --write  # Verify a corpus copy and refresh its C receipt
buildc version             # Print version

Not yet wired: doc subcommand. All other subcommands have CLI entry points. buildc test is a legacy fixture runner, not the current release gate; a live run on 2026-06-15 starts 137 tests and stops at tests/programs/04_if_else.bld because older fixtures predate explicit Console capability annotations, reporting 3 passed, 1 error, and 16 skipped before aborting. buildc lint provides type errors + style warnings with file:line:col positions. buildc lsp starts the current stdio server loop, and the raw dispatch path now covers lifecycle, document sync, completion, hover, definition, references, document symbols, opened-document workspace symbols, semantic tokens v0, formatting, folding ranges, code actions, rename, and compiler-backed diagnostics through structural JSON-RPC parsing. End-to-end VS Code extension behavior is still not receipt-verified.

Output Optimization

  • Dead local elimination: Removes unused MIR temporary declarations
  • Trivial goto elimination: Removes sequential goto→label pairs from MIR block boundaries
  • Copy propagation: Framework implemented, needs MIR-level dataflow analysis (disabled)

Standard Library

Automatic stdlib resolution from any directory via find_stdlib_path(). 13 modules (890 lines) in stdlib/: core, math, string_utils, algorithms, bitwise, effects, graphics, io, iter, option, result, sorting, strings. Module import call rewriting maps bare function names to prefixed versions.

Summary

The semantic corpus now also checks a buildlang-symbol-graph-receipt/v0 artifact for source/MIR/effect symbol evidence without claiming call graph or package API completion. LSP readiness is tracked separately through the checked buildlang-lsp-dispatch-receipt/v0 artifact and still excludes end-to-end VS Code extension verification.

BuildLang has a working compiler core (lexer -> parser -> type checker -> MIR -> C backend -> executable) with the 1.4.0 local baseline (2026-09-10) of 1,818 tests passed, 0 failed (11 ignored) via cargo test --quiet with RUSTFLAGS=-Dwarnings from compiler/ (per-target splits appear in the release verification above). It can compile and run real programs with variables, functions, control flow, pattern matching, recursion, and algebraic effects. C, LLVM, x86-64, ARM64, WASM, SPIR-V, HLSL, GLSL, and Rust are accessible from the CLI via buildc build --target <target>, but with different maturity levels. The C backend is production-verified and now has a semantic-corpus C execution receipt matching the current 8-program corpus; buildc run uses per-run temp build directories so concurrent C receipt probes avoid shared temp C/PDB collisions; buildc corpus verify validates the semantic corpus manifest, C/Rust receipts, and real C-backend stdout, accepts explicit corpus roots, and can refresh the C receipt for copied corpus fixtures after C stdout passes. The same corpus path now carries a buildlang-substrate-receipt/v0 aggregation receipt that checks source-set size, backend maturity, memory gaps, representation fallback policy, and evidence commands without promoting experimental backends. Its representation surface is now backed by a checked buildlang-mir-representation-receipt/v0 artifact that recomputes per-program MIR operation families, symbols, memory-surface flags, and control-flow summaries during buildc corpus verify. The same verification path now also checks a buildlang-memory-layout-receipt/v0 artifact that binds the corpus memory surface to manifest tags, MIR-derived memory flags, ownership/layout classification, digest evidence, and explicit known gaps without claiming byte-level ABI layout or full borrow proof. buildc receipt verify re-checks saved source-bound check receipts against current source inputs, policy/profile digests, replayed effect/accountability surfaces, optional required built-in profile identity, and optional required policy digest, with optional JSON verification reports for CI; check policies now validate referenced effect names against built-in capabilities and the checked source graph so misspelled gates fail instead of silently weakening enforcement, can require allowed_effects to be authoritative even when empty, can require explicit direct/propagated provenance allowlists, can constrain direct capability boundaries to exact ambient helper/macro/FFI sources, can classify compile-time ambient macros such as include_str! and env! under FileSystem/Environment, can scan macro argument token trees with SourceId provenance so println!(read_file(...)) requires both Console and FileSystem in entry sources and external module files and unknown extern calls/statics surface as Foreign, can classify known effectful build_* C runtime helper aliases declared in extern blocks under their real domain capability instead of generic Foreign, can preserve qualified ambient helper paths such as io::read_file in diagnostics, receipts, and scaffolded source allowlists, can reject effectful callbacks passed into pure fn(...) boundaries instead of erasing effect rows, and can preserve delayed or propagated capability evidence across callbacks, closures, aggregates, async awaits, branches, loops, casts, refs/derefs, pipes, assignments, selected aggregate fields, returned functions, and exact source allowlists. The built-in strict-accountability policy profile packages required effect inventory, digest, provenance, source, and coverage requirements into a named adoption gate for teams that want no ambient IO without exact allowlists, and buildc policy scaffold can turn observed receipt evidence into an exact strict policy skeleton for review while preserving pure receipts against later effect drift. buildc doctor reports local toolchain, stdlib, registry, optional backend tools, and backend maturity for adoption diagnostics; tested quickstart examples cover first-run CPU execution, mutable control flow, algebraic effects, and HLSL shader output; the Rust backend is subset-validated with rustc --emit=metadata and has a narrower generated-executable stdout smoke layer over the same semantic corpus plus manifest contract/receipt consistency/metadata guards; LLVM can optionally link with clang; native/WASM backends output assembly/binary for external toolchain linking. Formatter and package-manager entry points (buildc fmt, buildc pkg) are wired into the CLI, but the package manager has no live registry. buildc lsp starts the current stdio server loop, dispatches the checked raw LSP receipt sequence through structural JSON-RPC parsing, emits compiler-backed diagnostics, and returns receipt-verified semantic tokens v0 plus opened-document workspace symbols; full compiler-backed semantic token indexing, global workspace-symbol indexing, and end-to-end VS Code extension verification remain open. The self-hosted compiler and standard library (244,085 lines of .bld code) represent an ambitious long-term vision but cannot be compiled or executed today.