LEVIATHAN v962456e · 962456eee1

leviathan-lang.com / docs / known issues

Known issues

Open issues in the compiler and standard library at the commit in the footer, grouped by priority. P0 = wrong output or crash on ordinary programs; P1 = high; P2 = medium; P3 = low.

P0 · critical

  • found 2026-08-06 · Details are in the project bug register.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-09-14 · by the round-2 independent review of branch language-bug-dagon-p05-001 (pre-existing: identical on the branch's base). [P0.1]: the oracle silently discards a write that the checker accepted, which reference §3.7 bans, while all three actively-maintained engines unanimously refuse the same program.
  • found 2026-10-01 · writing the regex replacement row for docs-pipeline doc 01. A capture group in a pattern made only of literal characters captures nothing: Regex("(x)").find("x") matches, but group(1).value is "", and $1 / ${name} in a replacement substitute the empty string. Every engine agrees (the regex engine is prelude code), so the differential corpus cannot see it. [P0.1]: the oracle prints wrong output for ordinary user code, wrong per reference §6.4.6 (groups[1..n] are the capture groups; an unmatched group is "", but this group matched).
  • found 2026-09-03 · by the third fresh-eyes reviewer of perf-epic D9 Stage B, while auditing the guard's G2 conjunct; verified and filed by the round-3-nits pass. PRE-EXISTING and unrelated to D9 Stage B — see "Why D9 neither causes nor changes it" below; it reproduces on the pre-D9 base master c76ed5b byte-for-byte.
  • found 2026-10-02 · by the docs-pipeline smoke session (differential probes for doc examples). int division or remainder of the minimum value by -1 kills the process with SIGFPE (exit 136, core dumped) instead of wrapping. Not catchable: no exception is raised, the engine itself traps. Oracle and --ir reproduced here; the smoke session observed the same on LLVM. [P0.1]: the oracle is wrong for ordinary user code per the reference — §2.2 states MIN / -1 "wraps with no UB and no trap, at every width", and the sized integers do wrap; the 64-bit int is the one width that traps.

P1 · high

  • found 2026-08-01 · Details are in the project bug register.
  • A call through an inferred (var/let) lambda local types as unknown, and numeric OP unknown keeps the numeric operand's type — so a byte-declared variable can hold 500, and an int-declared variable can compute at 8 bits
  • found 2026-08-05 · Details are in the project bug register.
  • found 2026-08-18 · by the fresh-eyes reviewer of perf-epic D4 (typed native entry points), confirmed independently while landing D4's follow-up guard. PRE-EXISTING and unrelated to D4 — it reproduces on the UNTYPED LLVM lane, which D4 does not touch, and predates the whole typed tier. [P1.1]: the LLVM backend, an actively-maintained engine, silently produces a wrong result — exit 0, no diagnostic — for code the checker accepts, and nothing here disputes which behavior is correct (the oracle is ground truth and it raises).
  • found 2026-08-19 · during the perf-epic D3 fresh-eyes review (adversarial ARC-elision audit). Reassigning a for ... in range counter inside the loop body diverges between the oracle and the two lowered engines — a three-engine disagreement on a program the checker accepts, so it is automatically a bug per docs/policies.md §Testing ("the disagreement itself is the evidence"). [P1]: silent wrong answers, no diagnostic, on a construct the checker admits; correctness-class, not a resource defect.
  • found 2026-09-13 · Details are in the project bug register.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-10-02 · . Two bases that declare a field with the same name but DIFFERENT types: every read of the name, through any view, yields the LAST base's slot — the oracle and --ir print s for an int view; LLVM prints 1 for a string view. Reference §4.2 says different-typed same-named members coexist and are resolved by type. [P1.1]: silent wrong value, exit 0, no diagnostic, and the interpreters disagree with LLVM.
  • found 2026-10-02 · . A const instance field whose initializer is an operator over other const fields of the same class reads the wrong value on the oracle and --ir (LLVM is correct). Reference §4.3b (const int BOTH = A | B;) says literals/operators over consts fold. [P1.1]: silent wrong value, exit 0, no diagnostic, two engines.
  • found 2026-10-02 · . A weak field still reads non-None after the last strong reference — a temporary passed as an argument — is gone, on --ir and LLVM; the oracle clears it. [P1.1]: silent wrong value on two actively-maintained engines, no diagnostic (it also means the temporary is never released).
  • found 2026-10-02 · . LLVM selects the wrong operator overload when a class overloads the SAME operator on the right operand's type: it always runs the first-declared overload, whatever the argument type (the oracle and --ir are correct). Ordinary methods overloaded by parameter type dispatch correctly on LLVM; only the symbolic-selector members are affected. [P1.1]: silent wrong value (or an integer read as an object pointer) on an actively-maintained engine, exit 0, no diagnostic. Holds at --opt-level 0 and at the default level.
  • found 2026-07-31 · by the independent reviewer of Sized Numerics S4 (uint), while checking that the deliberate absence of abs/sign on unsigned types surfaces honestly. [P1.1]: emit-C++, an actively-maintained engine, silently produces a wrong result — exit 0, no diagnostic — for code the checker accepts, and nothing here disputes which behavior is correct.
  • found 2026-08-01 · by the orchestrator while probing a review finding against S5. [P1.1]: emit-C++, an actively-maintained engine, silently produces a wrong value — exit 0, no diagnostic — for code the checker accepts, and nothing here disputes which behavior is correct.
  • found 2026-08-20 · by the fresh-eyes review of perf-epic D2 P0b (532ad4b) and verified on that commit. Markers: P1.1 (every actively-maintained engine silently produces a wrong value, exit 0, no diagnostic, for code the checker accepts, and the intended behavior is undisputed — the user's iterator must drive the loop) and P1.2 (the only workaround is a per-use naming convention). Not P0.1: the flip is checker-side and therefore UNIFORM across all engines, so the oracle is not contradicted by anyone. Pre-existing and NOT caused by P0b — identical with and without --unchecked-prelude, the flag that restores the pre-P0 behavior exactly.
  • found 2026-09-02 · by the fresh-eyes reviewer of perf-epic D9 Stage B (21ac3e6), while auditing the D9 guard-algebra REJECT. PRE- EXISTING and unrelated to D9 Stage B — it reproduces on the D9 OFF arm (--typed --no-loop-version) at the review base 1ff1154, is a single element read with NO loop and NO version plan involved, and is a property of perf-epic D4's typed GetIndex fast arm, not of the loop versioner.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-09-15 · Details are in the project bug register.
  • found 2026-10-02 · by the independent review of docs-pipeline doc 02 (--doc-json selector ids). A symbolic selector written with interior whitespace is accepted and declares a member that never dispatches. bool ( < = )(P o) and get ( [ ] )(int i) parse and resolve, but the operator table is keyed by the selector's source text, so a <= b finds no <= and q[1] finds no []. The comparison form fails loud at runtime; the index form is silent — it prints an empty line and exits 0 on the oracle and on --ir. [P1.1]: an actively-maintained engine silently produces a wrong value (exit 0, no diagnostic) for accepted code, and the intended behaviour is not in dispute (the unspaced spelling works). Not checked on emit-C++ / LLVM.
  • found 2026-10-02 · writing the expression-reification reference (docs-pipeline 05g). x is Ns::Class is always false when the tested type is written namespace-qualified — even for the exact runtime type and for a supertype; the unqualified spelling (after uses Ns;) and a match arm Ns::Class => both answer correctly. Oracle, --ir and the LLVM native build all print the same wrong answer, no diagnostic. [P1.1]: an actively-maintained engine silently produces a wrong value (exit 0) for checker-accepted code and the correct answer is not in dispute (a is B over the same class is true). Hits every expr:: tree test (node is expr::Bin), since the node classes live in namespace expr.
  • found 2026-10-02 · by the docs LLVM lane running the operators entry. A class that declares one operator for two different right-hand types ((+)(Money) and (+)(int)) gets the wrong overload on the LLVM lane: a + Money(1) prints a garbage integer when the int overload is declared first, and a + 5 returns the wrong sum when the Money overload is first; the oracle and --ir pick correctly. [P1.1]: LLVM, an actively-maintained engine, silently produces a wrong value for code the checker accepts (exit 0, no diagnostic). A class with one overload per class works on every engine.
  • found 2026-10-02 · by the docs LLVM lane. A binary operator on a class that declares no such operator (p + p) raises a catchable RuntimeException ("no operator '+' on 'Plain'") under --run and --ir, but on the LLVM lane it silently evaluates to an empty value and the program continues. [P1.1]: LLVM silently produces a wrong result (exit 0, no diagnostic); the interpreters define the behaviour.
  • found 2026-10-02 · writing the docs for prelude/regex_api.lev. A Regex returned by regex::compile forgets its pattern and options: pattern() is "" and options() is all-false, although the program it wraps was compiled with them. Matching itself is correct (the compiled program carries the flags); only the introspection accessors are wrong. The constructors report both correctly. All engines agree (prelude code). [P1.1]: a wrong value with exit 0 for checker-accepted code, and the reference (§6.4.6) lists pattern()/options() as plain introspection with no exception for compile.
  • found 2026-10-02 · by docs-pipeline session 05a (LLVM docs lane). std::charFromCode does not range-check on the LLVM backend: a surrogate, a negative number or a value above 0x10FFFF returns a bogus char instead of throwing. The oracle and --ir throw code point N is not a valid Unicode scalar (0..0x10FFFF minus surrogates), which is what the reference documents. [P1.1]: an actively-maintained engine silently produces a wrong value (exit 0, no diagnostic) for checker-accepted code, and the intended behavior is not in dispute.

P2 · medium

  • found 2026-08-20 · Details are in the project bug register.
  • found 2026-08-01 · in the same range-arm audit: a range arm over a bool subject diverges — LLVM matches, oracle/IR/emit-C++ take else. [P2.1]: the engines disagree AND the intended behavior needs a ruling first (a bool range arm is arguably not a legal pattern at all, in which case the real defect is the missing checker diagnostic, [P2.4]); override 2's semantics cap independently pins this at P2.
  • found 2026-08-01 · Details are in the project bug register.
  • found 2026-07-27 · Details are in the project bug register.
  • prelude generates body of rules are GLOBAL: a user method carrying the trigger attribute has its own body silently DISCARDED and replaced by the prelude template
  • found 2026-08-01 · by the orchestrator, triaging the full suite on the merged S6 tree. Marker note: no marker fits cleanly — the failure is loud (a wasm module fails to instantiate, rc 1), no actively-maintained engine per this file's own definition (--ir, emit-C++, LLVM) is wrong, and nothing is silently incorrect. Filed at P2 as the closest honest tier because a lane is red on master and, worse, the same lane reports green in most checkouts while testing nothing (below). Re-tier on owner ruling.
  • found 2026-08-20 · by the fresh-eyes review of perf-epic D2 P0b's follow-up commit. Prelude-span diagnostics raised by the Resolver (and by prelude lexing/parsing) are still rendered against the USER's source file, with the same wrong-line-plus-real-caret symptom that prelude_diag_attribution now pins for the prelude Checker's diagnostics. [P2]: actively misleading diagnostic output — points a real caret at an unrelated line of the user's file — but reachable only through a --prelude <dir> override, so it does not affect ordinary compiles.
  • found 2026-09-13 · by the independent review of fc98d12. [P2.4]: a missing diagnostic — duplicate member declarations should be a compile error and are silently accepted; no distinct-overload program misbehaves.
  • found 2026-09-13 · Details are in the project bug register.
  • found 2026-09-14 · while verifying branch language-bug-dagon-p05-001 (pre-existing: the identical failure set is in the reviewer's base run at 182eb6a). [Override 2, semantics cap]: every probed engine agrees with the current Moby source and disagrees with the committed goldens; which serialization is intended must be decided before the goldens or the source change.
  • found 2026-10-02 · by the docs-pipeline smoke session. string.subStr with a negative length disagrees between engines. The oracle and --ir treat a negative length as "to the end" (reproduced here); the smoke session observed LLVM returning the empty string for the same calls. [P2.1]: engines diverge and the reference does not say what a negative length means, so a ruling must pick the behaviour before a fix is valid. A negative or out-of-range START agrees on all three (subStr(-1, 2) and subStr(5, 2) are "").
  • found 2026-10-02 · by the docs-pipeline smoke session. std::sysWrite(2, …) is written to standard OUTPUT by the oracle and --ir, and to standard error by LLVM. The interpreters collect every sysWrite in one buffer and print it on stdout when the program ends, whatever the descriptor (reproduced here: the text survives 2>/dev/null and vanishes with >/dev/null); a compiled binary writes descriptor 2 directly. [P2.1]: engines diverge on observable behaviour. Consequence for tests: a program that writes to stderr cannot have one .expected across lanes — run_corpus.sh compares 2>&1, run_native_llvm.sh compares stdout only — so doc examples must not write to stderr.
  • found 2026-10-02 · writing the declarations chapter of the docs-pipeline reference. A method returning a class type T does not satisfy an interface requirement T? (the SAME class, optional), on every engine, although reference §4.2 says "T also satisfies required T?". A subclass return (Dog for Animal?) is accepted; an exact class return, and a primitive return, are rejected. [P2.1]: a valid program fails loud on every engine (the checker, before backend selection).
  • found 2026-10-02 · . < (and the other ordering operators) between two enum members or two structs: --run and --ir throw no operator '<' on '<Type>', LLVM prints an empty value and exits 0. Reference §4.2c states enums support ordering by carrier value. [P2.1]: engines diverge, and the documented operator is missing.
  • found 2026-10-02 · . A member with only a get accessor is not read-only: assigning to it is accepted with no diagnostic. When a field of that name backs it, the assignment stores into the field (and the next read still goes through get); when no field backs it, the assignment is silently discarded. Reference §4.6 says "Declaring only get -> read-only; only set -> write-only", but a set-only member reads the raw field. [P2.4]: a missing diagnostic with a correct happy path; every engine agrees.
  • found 2026-10-04 · by the MI composition reviews. A base-qualified method reference var f = c.A::who; raises at run time on every engine (oracle --run, --ir, emit-C++, LLVM), for namespaced and global base classes alike. The direct call c.A::who() works; only the value form (method reference through a base qualifier on an instance) fails. [P2.3]: a documented feature (qualified member access, method references C::m) fails loud on all four actively-maintained engines.
  • found 2026-10-04 · by the MI composition reviews. this.M::A::v — a namespace segment in member position — compiles and reads void (exit 0) instead of being a compile error. A qualifier after . should name a base class (this.A::v, this.N::A::v is not a valid member spelling here either); the checker accepts the extra namespace segment and the read yields void. [P2.4]: missing diagnostic for an unsupported construct. Whether the nested spelling should instead be supported (and read 2) is a language ruling; until then it must at least error rather than read void.
  • found 2026-10-04 · by the MI composition reviews. On an unresolvable spelled qualifier inside a generic body, emit-C++ segfaults while the other engines print void. Two namespaces each define a class A; a generic function reads x.A::v, where the bare qualifier A cannot be resolved to a unique class at run time (no unique class of that bare name). The oracle, --ir and LLVM print void for the read; emit-C++ crashes with SIGSEGV. Related divergence: void.toString() behaves differently across engines (the exact per-engine behavior was not recorded). [P2.1]: engines diverge and a ruling must pick the intended behavior (most likely a compile or run-time error, not void).
  • found 2026-10-05 · by the MI composition batch 2 review. An erased-generic call whose arity matches no method of that name splits the engines: the interpreters run the method with the missing arguments, the compiled engines throw. No multiple inheritance is involved; the baseline before MI composition behaves the same. [P2.1]: silent wrong value on two engines versus a runtime error on the other two.
  • found 2026-10-05 · by the MI composition batch 1 review. A base-qualified member reached through optional chaining (n?.GA::who(), n?.GA::v) ignores the None short-circuit. With n holding None, the call should be skipped and the expression be None (so ?? "none" prints none). Instead the oracle raises cannot resolve call target 'who' (exit 1) while --ir, emit-C++ and LLVM run GA::who on no receiver and print GA. The field read n?.GA::v gives void instead of None on the oracle, --ir and LLVM (so nv ?? -1 prints an empty line, not -1), and emit-C++ crashes with SIGSEGV. Same on master. [P2.1]: engines diverge on a valid program; none prints the expected output.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-08-02 · during perf-research R2 (--check-prelude measurement). A free function shadows a class's own same-named method for bare (unqualified) calls inside that class: the checker resolves against free-function overloads first and hard-errors instead of falling back to the receiver's own member. The engines resolve it the other way (to the method), so this is a checker-vs-engines divergence that rejects a valid program.
  • found 2026-08-02 · during perf-research R2 (--check-prelude). The assignment target's declared type does not provide inference context for a generic constructor, so re-assigning a typed field/local a fresh empty generic is rejected — even though the identical expression is accepted as that field's initializer.
  • found 2026-09-12 · Details are in the project bug register.
  • found 2026-08-02 · during perf-research R2 (--check-prelude). An expression-bodied lambda in a void callback position is rejected when its expression has a value — the value cannot be discarded, so chaining operators (which return the receiver) cannot be used in a void lambda.
  • found 2026-08-15 · during perf-epic C2 (record-row capacity word), PRE-EXISTING and layout-independent — the identical figure was measured at the base commit (63148dc) on the DENSE row and after the change on the record row, so the capacity work neither caused nor moved it. [P2]: resource defect on an actively-maintained engine (LLVM lane), exit 0, correct output; not P1 because no value is ever wrong and growth is bounded per build loop, not per iteration.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-09-14 · while verifying branch language-bug-dagon-p05-001 (test infrastructure, not a compiler bug).
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-10-01 · by the independent review of docs-pipeline doc 02 (leviathan --doc-json). srcExpr (src/meta/AstPrinter.cpp, the source-shaped expression printer behind --expand and, since doc 02, behind every value, default and attribute args string of a --doc-json dump) does not reproduce four literal/expression forms as written: a raw string loses its r prefix AND its quotes, a triple-quoted string is re-quoted with one " around its raw newlines, an interpolated string is printed as the parser's desugared concatenation, and a lambda's parameter types are dropped. For the first two the printed text is not Leviathan at all, so --expand output that contains one does not recompile. [P2.3]: --expand's documented contract (reference, "Rules (Layer B)": "re-emits the post-rules tree as compilable source (the output recompiles and runs identically)") fails loud for a documented literal form; no P0/P1 marker applies — the oracle and every engine run the ORIGINAL program correctly, and the dump's wrong text is exit-0 documentation output, not an engine value.
  • found 2026-10-02 · writing the Pty.onData doc example. Passing a named function (not a lambda) to Pty.onData fails to lower on --ir ("IR: not yet lowerable: name 'show'") while --run accepts it. The same named-function argument works on TcpStream.onData, on Process.onStdout, and on a user class with an identically named method, so only the prelude Pty receiver trips it. [P2.3]: an engine disagreement that fails loud at lowering time, with a one-line workaround; no wrong value is produced.
  • found 2026-10-02 · by docs-pipeline 05j (tutorial migration). A top-level global whose name is also a prelude free function (sum, max) cannot be passed bare as a call argument: the bare name is read as an ambiguous function reference instead of the user's variable. A use inside an expression (sum + 1) or a local of the same name inside a function both work, so it is specific to the bare-argument position. Oracle and --ir give the same error (checker stage). A user global should shadow the prelude name, as a local does.
  • found 2026-10-02 · writing the docs-pipeline library prose (doc 05d). A string interpolation hole holding an Array or a Map is accepted by the checker but fails at run time on the interpreters and prints nothing on LLVM. [P2.1]: the engines diverge and a ruling must say whether a collection interpolates (and how) or is a compile error; Array and Map declare no toString, while Set and Pair do.
  • found 2026-10-02 · writing the docs-pipeline library prose (doc 05d). == between two Array values answers differently per engine: --run and --ir print true for any two arrays (different lengths and contents included), LLVM prints false. [P2.1]: neither behavior is documented, so a ruling must pick one (element-wise equality, or reference identity, or a compile error).
  • found 2026-10-02 · writing the docs-pipeline library prose (doc 05d). Assigning a field of a struct element through an index, a[i].x = v, compiles and does nothing on every engine. The read a[i] yields a copy, so the write lands on a temporary. Exit 0, no diagnostic. [P2.1]: a ruling must choose between supporting the write, and rejecting it at compile time; the intended behavior is open.
  • found 2026-10-02 · writing the statements chapter of the reference. At the outermost level of a script, var, let and using declarations and a bare { ... } block are parse errors ("expected expression"), although the same statements parse inside a function body or inside the body of an if / while. [P2.3]: documented statement forms (var name = expr;, using Type name = expr;, { stmt* }) fail loud at script top level. const var k = 3; and a labeled loop at top level are accepted.
  • found 2026-10-02 · writing the expressions chapter of the reference. A function-typed variable declared at script top level cannot be called: inc(4) fails with "unknown function 'inc'". The same declaration and call inside a function body work. [P2.3]: documented behaviour (a lambda stored in a variable is called like a function) fails loud for script-level variables.
  • found 2026-10-02 · writing the construction entry. Box<string> b = Box::<string>(); followed by a read of the never-assigned T value field prints <object> under --run and an empty string under --ir. [P2.1]: engines diverge on the default of a type-parameter-typed field built through an explicit tuple; the intended default needs a ruling. (Box<string> c = Box(); is empty on both.)
  • found 2026-10-02 · writing the indexing entry. An indexer declared with only get ([]) accepts r[0] = 5; and silently drops the write, and one declared with only set ([]) yields an empty value for w[0]; the reference says a get-only accessor is read-only and a set-only one write-only. [P2.4]: missing diagnostic; the supported forms (get and set together) work.
  • found 2026-10-02 · writing the strictness entry. if, while, ?: and && accept a non-bool condition (int, string) with no diagnostic and treat it as false, although the reference says conditions require bool ("no truthiness"); the oracle and --ir even disagree on string && bool. [P2.1]: a ruling must pick the intended behaviour (compile error per the reference) and align the engines.
  • found 2026-10-02 · by docs-pipeline 06d (std.lev doc examples, engine-differential probe). std::charFromCode does not validate its argument on the LLVM backend. The oracle and --ir throw RuntimeException ("code point N is not a valid Unicode scalar") for a negative value, a value above 0x10FFFF, and a surrogate (0xD800..0xDFFF), as the prelude comment and the reference say. The LLVM backend's inline lowering (LlvmGenOps.cpp, the charFromCode arm) is a pure retag of the int payload to a char with no range check, so it returns a bogus char and never throws; at -O0 and -O2 alike.
  • found 2026-10-02 · while documenting prelude/rest.lev. console << 5 compiles and prints nothing. Console's (<<) declares a string parameter, but a non-string argument is not rejected and not converted: it reaches std::sysWrite(1, s) as an integer, which writes no bytes. A chain such as console << "x" << 5 << "y\n" therefore prints xy with no diagnostic. Oracle, --ir and LLVM agree. A plain function with a string parameter does reject the same call (no overload of 'function' matches the arguments), so the gap is in how an operator-call's argument is checked. [P2.4]: missing diagnostic with a correct happy path (the string case works).
  • found 2026-10-02 · by docs-pipeline session 05a (writing the type chapter's examples). A top-level var or let declaration, and a top-level variable whose declared type is a function type (starts with (), is rejected on every engine, although the same statements work inside a function body or an if block. Priority P2, closest marker P2.3, which does not match exactly: the failure is a loud compile error on every engine, not one. It is documented syntax (the reference's "Type expressions" section shows var/let as inference markers) rejected with a message that points nowhere ("expected expression" at var; "unknown function 'f'" at the first use of a function-typed top-level variable). The intended behavior (accept, or reject with a clear message) is for the owner to pick, so it is capped at P2.
  • found 2026-10-02 · by docs-pipeline session 05a. A non-bool condition in if/while (and as an operand of &&/||) is accepted by the checker, and a non-bool value silently reads as false. The reference states conditions require bool with no truthiness, and ! already enforces this (!0 is "no operator '!' on 'int'"), but if (n) with int n = 5 compiles and takes the else branch on the oracle, --ir and LLVM. Priority P2, marker P2.4 (missing diagnostic; the checker should have rejected the program, so no supported construct depends on the wrong behavior).
  • found 2026-10-02 · by docs-pipeline session 05a. A top-level variable whose name is also an overloaded free function of the standard library (sum, max, min) is rejected when it is passed directly as a call argument. int x = sum; and sum + 1 work; console.writeln(sum) fails with "ambiguous function reference 'sum'; annotate the target function type", because the bare name in argument position resolves to the library's overload set instead of the user's variable. Priority P2, closest marker P2.3, which does not match exactly (a loud error on every engine, not one); the workaround is per-use (rename the variable), which is what keeps it from P3.
  • found 2026-10-02 · by docs-pipeline 06d (engine-differential probe while writing a Channel example). Interpolating an Array into a string ("${a}") throws on the oracle and --ir but silently yields an empty string on LLVM. Array<T> declares no toString, so the interpreters report cannot resolve call target 'toString'; the LLVM backend instead prints nothing for the hole, so a wrong program runs "successfully" there. Either the interpolation should be a compile-time error (preferred: no toString on the type) or all engines should agree on a rendering.
  • found 2026-10-02 · writing the tasks entry of the library reference. On the LLVM backend a task parked on a promise that a timer resolves is resumed late: not when the timer fires, but at the next event-loop wake-up (the next timer, or the end of the loop). The oracle and --ir resume it on time; backend disagreement, so a bug by policy. [P2.2]: two valid programs differ in observable output order on the compiled backend; no data loss, no crash.
  • found 2026-10-04 · by the MI composition reviews. A struct whose lambda field captures this, returned from a function, diverges: LLVM prints 40, the other engines (oracle --run, --ir, emit-C++) print 30. The question is what a lambda that captured this inside a struct sees after the struct is copied/returned: the value at construction (a = 3, giving 30) or the mutated value (a = 4, giving 40). [P2.1] engines diverge and a value-semantics ruling must pick the intended behavior before any fix is valid (override 2 caps the tier at P2). The probe's second case (a S v = S(); v.a = 4; local, no function return) is included as the control; its per-engine outputs were not recorded.
  • found 2026-10-04 · by the MI composition reviews. Base tmp = Base(); inside a derived-class constructor: emit-C++ SIGSEGVs; the other engines (oracle --run, --ir, LLVM) treat it as a base-initializer call and print seen: (empty). The semantics question is whether Base() in that position is a base-constructor call on this or the construction of a new, independent Base object (in which case tmp.k is 5 and the program should print seen: 5). [P2.1]: engines diverge and a ruling must pick the intended behavior (override 2 caps the tier at P2; the emit-C++ crash is the loud half of the divergence and is wrong under either reading).
  • found 2026-10-06 · by the MI composition doc 05 implementer. A base-qualified method call evaluated inside a comptime fold fails, even without distinct members. All four engines reject the program at compile time; the same call at run time works. [P2.4]: a loud failure (no silent divergence), but comptime cannot evaluate code that runs fine at run time.

P3 · low

  • found 2026-08-19 · Details are in the project bug register.
  • found 2026-07-22 · while running the full post-merge suite for the wasm browser-fetch packet.
  • found 2026-07-26 · while running the full ctest gate for the sized-numerics S1 delivery. [P3]: no P0–P2 marker applies — no engine disagrees and no program output changes; the aarch64 corpus lane simply cannot execute what it built.
  • found 2026-07-31 · by the independent reviewer of Sized Numerics S4 (uint). Marker note, stated plainly: no marker in the priority system matches this entry exactly. Output is correct on every engine today, so no P0/P1 marker applies; it is not performance-only (P2.2), no engine diverges (P2.1), no documented feature fails loud (P2.3), and no missing diagnostic is involved (P2.4). It is a latent correctness hazard conditional on the C/C++ toolchain, so it is filed at P3 for triage rather than forced into an ill-fitting tier. Re-tier on owner ruling if wanted.
  • found 2026-10-02 · . A bare block statement { ... } at the top level of a program is a parse error (expected expression); the same block inside a function body is fine. Reference §5 lists { stmt* } as a statement and §4.3b says top-level statements admit the full statement grammar; the reference's own §4.7 example opens a block at the top level. [P2.1] (valid per the reference; fails loud on every engine; capped to P3 because if (true) { ... } is the trivial workaround).
  • found 2026-10-02 · . A default parameter value that is a function call is accepted and evaluated at each call, although reference §4.4/§4.7 says defaults must be compile-time constants. A variable reference as a default is correctly rejected ("a default value must be a compile-time constant"); a call is not. [P2.4]: a missing diagnostic with a correct happy path (every engine agrees).
  • found 2026-08-16 · during perf-epic D1a's ASan/UBSan gate sweep. Marker note: no marker fits cleanly — no engine is wrong, no .lev program misbehaves, and the affected code is the runtime selftest harness rather than an engine.
  • found 2026-08-21 · Details are in the project bug register.
  • found 2026-09-15 · Details are in the project bug register.
  • found 2026-09-14 · Details are in the project bug register.
  • found 2026-10-02 · writing the expression-reification reference (docs-pipeline 05g).
  • found 2026-10-05 · by the MI composition batch 2 implementers. leviathan --resolve tests/docjson/shapes.lev segfaults in RuleEngine::warnDanglingAttrs (called from RuleEngine::run in main). The fixture is written for --doc-json, where it works; the --resolve dump crashes before printing. Reproduces on language-mi-02 (doc 02, which does not touch RuleEngine) and language-mi-03, so it predates MI composition docs 03/04; not checked on an older master. [P3]: a debugging dump flag crashing on one fixture; no user program affected as far as known.