Skip to content

0.30.1

Choose a tag to compare

@ShkodnikAI ShkodnikAI released this 12 Oct 11:08
· 71 commits to main since this release
27877b8

Security

  • №658 (gh#1159) — the VM break/continue parity (the behavior change,
    fail-closed; AFFECTS 0.30.0 AND EARLIER on the VM backend; the audit
    guard scenario: a break/continue inside a loop body — top-level,
    inside an if guard, inside a match arm, in a nested loop — was
    silently IGNORED by the VM: the body ran to the condition cap as if
    the statement were absent, and a top-level form kept an unresolved
    Jump(0) placeholder that tripped the infinite-loop guard, while the
    tree-walking backend honored both statements; the X-1/Y-1/Q-1
    silently-wrong control-flow class, the №652-a finding):
    the VM loop
    path mirrors the TW ControlFlow contract 1:1 — every
    break/continue reaches its NEAREST enclosing loop on BOTH backends
    (break exits the loop; continue starts the next iteration — the
    condition re-test for while, the next item for
    each/each_with_index). The compiler now resolves every loop jump
    from the loop-stack entry: the shared statement compiler registers a
    Jump(0) placeholder in the NEAREST entry at any nesting depth and
    the loop compiler patches it from the POPPED entry (the stale-local
    patch loops — the pre-№658 root cause — are gone). The norms
    S-BLK-011/012 + five conformance pairs pin the record; the TW is
    unchanged. Found by №652 (the spec topic 2 probe); the repair follows
    the №651/№629 precedent. The fix lands 2026-10-09 (this PR; after the
    v0.30.0 tag b4b9abb lineage — the published tag is affected on the VM
    backend; no re-tag — the №620 precedent).

  • №651 (gh#1145) — the TW/VM condition parity (the behavior change,
    fail-closed; AFFECTS 0.30.0 AND EARLIER on the VM backend; the audit
    guard scenario: a composite or an opaque value in a condition — e.g.
    if [items] { … } or if hash_password(pw) { … } — silently chose a
    branch on the VM (a non-empty List took THEN, an opaque handle took
    ELSE) while the tree-walking backend refused; the X-1/Y-1/Q-1
    silently-wrong-guard class):
    the VM condition path (the new
    Instruction::JumpIfNotCond, emitted for if / else-if / while / the
    match guards) mirrors the TW Value::as_bool 1:1 — the truthy set of
    a condition is exactly {true Bool, Float ≠ 0.0, non-empty String},
    Unit is falsy, and every composite / opaque / Fluid value refuses
    with the stable [TYPE_MISMATCH] code on BOTH backends (the norm
    S-VAL-013; the №629 loud-refusal class). The soft truthiness of
    &&/|| (the №532 twin, compiled to the legacy JumpIfNot) is
    unchanged and stays pinned. Found by №645 (the spec-carcase
    conformance build, the finding №645-a); the repair follows the №629
    precedent. The fix lands 2026-10-08 (this PR; after the v0.30.0 tag
    6eafee1 — the published tag is affected on the VM backend; no re-tag
    — the №620 precedent).

Fixed

  • #1169/#1170 (the office VM-pilot staging, FO-050; PR — this fix) —
    the VM serve-boot db bootstrap (the interpreter-parity boot path; the
    behavior change, fail-closed at boot; Fixed-class → rides the
    0.30.1 train):
    db { url: env("NAME") } on the VM serve lane
    resolved the URL inside EVERY route handler (the №758 lazy
    first-db-access semantics), so the same read went through the №259
    serve-route gate — without METALOGOS_ENV_ALLOWLIST every request
    500'd with ENV_NOT_PERMITTED (the interpreter resolves the url
    expression at BOOT in the Process context and serves the same file +
    env with 200), and the schema-DDL bootstrap only ran when a request
    first touched the db — on the office's real corpus (30 routes) a
    fresh DB stayed at 0 tables and the first request died with an
    unrelated arity 500 instead of an honest bootstrap diagnostic
    ([vm/db] Connected was already on the boot log — the TW
    registration lane opened the file — while the VM request lane kept
    re-resolving and re-refusing per request). The fix: at VM serve boot
    (run_server + the test harness, on the compiled Program BEFORE it
    is shared) boot_resolve_db_url resolves the env name ONCE in the
    Process (boot) context — the resolved literal replaces db_url_env,
    so the request path performs NO env() reads at all — and replays the
    schema DDL eagerly on a boot connection (same open + WAL +
    DDL-tolerance steps as the lazy open), so a fresh DB carries the
    schema BEFORE the first request (the #1169 interpreter parity); an
    unset variable is a LOUD BOOT error naming the variable and the
    remedy (was: a silent OK boot — the TW registration error line was
    swallowed by the merge, then per-request 500s); a non-sqlite URL is
    the same LOUD boot error it used to be at the first access (№758
    text moved to boot time). The №259 serve-route env gate is
    UNCHANGED for program-level env() calls — the boot read is the
    Process-context class (the №259 contract, the №457 registration
    zone). The lazy per-request connection open stays for requests that
    never touch the db (№409 cost contract); reset_for_reuse semantics
    unchanged (№403 4/4). Contract tests
    metalogos-server/tests/issue_1169_1170_vm_boot_db.rs (T1: the
    db-touching route serves WITHOUT the allowlist — was 500
    ENV_NOT_PERMITTED per request; T2: the fresh DB carries the schema
    table immediately after boot; T3: the unset variable fails the BOOT
    loudly naming the variable — was a silent OK boot; T4: the
    literal-URL twin — no regression on the №758 surface); №758 5/5, №259
    7/7, №160 23/23 (1 ignored), №403 4/4, №457 5/5, №399 4/4 GREEN.
    The TeamSkillWired expects 2 args first-request symptom of #1169
    (the office corpus) is NOT reproduced minimally and is NOT claimed
    fixed — it is expected to disappear with the empty-schema state gone;
    the minimal-repro ask stands in the issue thread.