Skip to content

Diluvium 5.5.1_build5

Choose a tag to compare

@github-actions github-actions released this 12 Aug 07:43
4ddd65f

[5.5.1_build5] - 2026-08-12

v5.5.1_build5 · Lua 5.5.1 · bytecode format 0x46

Hibernation is on, and stable is true again.

5.5.1_build4 shipped stable: false for exactly one reason: an
ungated dv_restore with a known corruption path. That block --
profile C of the M0-M7 audit, hibernation at scale -- is closed.
Every confirmed finding from the audit is now fixed, each with a
named test that fails when its fix is removed, and hibernation is
on by default: park an instance, snapshot it, free it, restore the
bytes into a fresh instance and resume, with the failure paths as
tested as the happy one. A restored program that raises gets the
right error with a traceback; a restored pcall still catches and
re-arms the handler it displaced; a woken runaway is stopped with
both residencies charged against the one instruction budget; an
endpoint reference held across the gap still binds; and a
malformed snapshot is refused, never a crash -- the fuzzer's
known-failure set is empty and stays that way.

dvs_allow_hibernation survives as a host's opt-out. The comment
that made it off by default is struck rather than edited, which is
what its own text asked for.

The release also builds out the host story. doc/Hostcall.md
reserves the hostcall encoding -- correlation token required from
the first prototype -- and doc/Host.md states the protocol both
planned hosts implement, the lab JavaScript host and the generic C
one, with the acceptance test that a guest cannot tell them apart.
The swarm layer reaches WebAssembly: a new
diluvium_swarm_wasi.wasm carries it with the host vtable crossing
the boundary as "env" imports, so a swarm can be driven by a
JavaScript host -- which is what lab picks up. And the generic host
itself now exists (host/, make build_host): a deployment is a
supervisor program plus a typed *.host.lua configuration, not C,
with connectors for the wall clock, SQLite and an HTTP listener,
each off until wired and gated by the capability grammar.

Added

  • The generic host (host/, make build_host): the host
    protocol as one configurable binary, so a deployment is a
    supervisor program plus a *.host.lua configuration rather than
    bespoke C. The config is Lua's syntax without its power --
    evaluated in an empty environment, every unknown key refused by
    name -- and typed by a LuaCATS schema (host/types/host.lua).
    Three connectors, all off until wired and each gated by a
    host: capability the same way queues are gated: the wall clock,
    SQLite (sql/query reads, sql/exec writes, confined to one
    file by an authorizer), and an HTTP listener behind a
    TLS-terminating load balancer (a request is a message, a message
    is a response, conn echoed like a hostcall token).
    examples/discofetch/swarmd.c is the bespoke ancestor this
    retires.
  • The swarm layer reaches WebAssembly. dvs.c joins both wasm
    archives, and diluvium_swarm_wasi.wasm is a new artifact
    carrying it plus dvs_shim.c: a JavaScript host cannot make the
    C function pointers dvs_new wants, so the trampolines live on
    the C side as mandatory "env" imports and dvsjs_new stands in
    as the constructor. A separate module on purpose -- mandatory
    imports linked into diluvium_wasi.wasm would have broken
    wasmtime diluvium_wasi.wasm and every other pure-WASI
    consumer, which keep the module they had. The JS binding always
    supplies the trampolines, setSwarmHost installs the real host,
    and instantiate is exported as the layer a host builds on.
  • dvs_set_host_identity: a swarm can hold an identity, and every
    snapshot it takes carries it. A foreign stamp is refused at
    wake, and so is a missing one on a stamped host -- 10.10's
    asymmetry, now true of the swarm layer and not only the ABI
    under it. Not authentication; a label that fails loudly.
  • diluvium_snap_headerusage: read a snapshot's instruction count
    from its header without restoring it. In the header rather than
    the payload so a host deciding whether it can afford to wake a
    cached instance can ask the bytes -- the same reasoning that
    made the budget a query at the swarm layer.
  • doc/Hostcall.md and doc/Host.md: the hostcall request/reply
    encoding with the correlation token reserved before any host
    ships a handler, and the host protocol -- construction, drive
    loop, roster, queue pump, hostcalls, hibernation policy,
    shutdown -- written so the lab JavaScript host and the generic C
    host are two implementations of one contract.
  • Tests for every path the audit found untested, each verified to
    fail with its fix removed: a woken instance still budgeted (the
    test that never existed), a restored program's traceback, a
    restored pcall's handler chain, all four host-identity stamp
    quadrants, a nested coroutine refused by name and capturable
    once dropped, an endpoint reference surviving hibernation, and a
    woken program re-binding its own endpoint with ordering held
    across the gap.

Changed

  • Hibernation is on by default; dvs_allow_hibernation is a
    host's opt-out. The swarm's budget test the audit caught
    certifying only readback now wakes what it caches and asserts
    the counter came through.
  • The snapshot fuzzer labels mutants with the format-2 record
    layout and its known-failure set is empty -- audit S2's two
    crashers are refusals now, and adding an entry to that set needs
    a better reason than a red run.
  • Refusal sentences widened where the checks did: a to-be-closed
    slot can be refused for holding nothing closable, a permanents
    mismatch speaks of named values rather than only C functions,
    and restore refusals gained their own distinctness test.

Fixed

  • Any error raised in any restored program corrupted memory
    (audit finding 0, the reason hibernation shipped off). The
    thread record now round-trips what it dropped, and
    a_restored_program_can_raise -- the first test in the tree to
    ever resume a restored thread into an error -- holds it.
  • A woken instance's instruction budget was never re-armed, and
    the counter did not travel, so a budget quietly became
    per-residency (finding 1). dv_restore arms the count hook and
    the header carries insn_used; both residencies charge one
    limit.
  • A restored program's error was correct but bare (old_errfunc).
    The record carries the thread's error-handler slot and each
    pcall frame's saved one, in slot units so the stream does not
    depend on a build's sizeof; validation refuses rather than
    asserts, which is S2's lesson applied ahead of time.
  • Two malformed snapshots reached an abort instead of a refusal
    (audit S2). A crafted to-be-closed list naming a non-closable
    slot reached the raise inside luaF_newtbcupval, which escapes
    the lock convention -- one extra unlock, the counter at -1, the
    opposite of the leaked lock the audit predicted at the same
    site. diluvium_shim_settbc refuses it first now; the full
    corpus runs 0 crashed.
  • Nested coroutines were captured rather than refused (finding
    14). A program parked holding a suspended coroutine is refused
    by name and told what to do -- let it finish or drop it -- and
    the same program snapshots once it has.
  • An endpoint reference did not survive a snapshot, and bind
    refused it with a false statement (finding 12). The reference
    metatable is the permanent dendpoint.refmt; bind adopts an
    endpoint queue no token claims, which is how a woken program
    re-binds its own endpoint and the only route by which the
    host's drain path returns after a wake; and messages buffered
    before a hibernate drain out in order after it.
  • A crafted to-be-closed count could send record reads four
    gigabytes out of bounds on platforms with a 32-bit unsigned long (pre-existing; LP64 was never affected). Every marked
    slot is a distinct stack slot, so a count above the slot count
    is refused as not credible.

Known issues

  • A sealed program still has no way to ask for the time -- but
    the encoding it will use is now fixed.

    The hostcall needs no ABI: it is a message on a queue the host
    drains and an answer on a queue it pushes to, and
    doc/Hostcall.md now reserves the request and reply shapes with
    the correlation token required from the first prototype. What
    does not exist yet is any host that connects a call: until one
    ships, a program that genuinely needs a clock or a file has
    DV_FLAG_UNSAFE_STDLIB and nothing better, which is exactly why
    that flag is scaffolding rather than a configuration.

  • DV_FLAG_UNSAFE_DEBUG is a real hole, deliberately.

    Unchanged from 5.5.1_build4: a host that sets it gets the whole
    debug library back and, with it, the endpoint forgery route
    and the budget escape. Supported for trusted code; recorded in a
    test rather than only here.

  • The swarm's snapshot cache is in-memory only, and the swarm's
    own topology has no serializer.
    A host may persist any
    instance's snapshot bytes and restore them after a process
    restart -- the header checks make stale or foreign bytes a
    refusal, never a corruption -- but recording which bytes
    belonged to what, and every parent, capability and budget
    relationship around them, is the host's own bookkeeping.
    Instance ids restart with a new swarm, so ids a program
    remembers from a previous life are volatile and must not be
    trusted across generations.

  • The rebuilt u2.funcidx of a restored vararg pcall frame
    differs from the organic value by the argument count -- the
    "agree by construction" claim at the reconstruction site is
    measurably false for vararg callees. Benign on every tested
    path, recorded in doc/Hibernate.md so nobody extending the
    frame rebuild trusts the comment.

Upgrading

Snapshots taken by 5.5.1_build3 or 5.5.1_build4 are refused by
this release.
Three stream changes land together so the cost is
paid once: the snapshot header carries the instruction count
(DILUVIUM_SNAP_FORMAT 2), the thread record carries the error
handler slots (DS_THREAD_VERSION 2), and the endpoint reference
metatable joins the permanents set, which moves the permanents
fingerprint. A restore of older bytes fails cleanly with the
format-mismatch sentence; nothing half-loads. There is no
converter, deliberately: those releases said to treat
dv_snapshot/dv_restore as unsupported, so bytes from them are
exactly the thing a refusal is for.

Bytecode is unaffected. LUAC_FORMAT is unchanged at 0x46;
chunks compiled by build3 or build4 load without recompiling.

Hibernation is on by default. A swarm that relied on the old
refusal as policy should call dvs_allow_hibernation(sw, 0); a
host that called it with 1 keeps working unchanged. The opt-out's
refusal names the call that switched it off rather than pointing
at a defect that no longer exists.

endpoint.bind's failure message changed. It now says the
value "does not carry this runtime's reference identity" instead
of asserting the program built the value itself -- the old text
was false in exactly the case this release fixes. A program
matching on the old wording needs updating; matching on error
prose was never promised to survive.

Built from commit 4ddd65f65d15.

Download guide

Platform File Notes
Linux (standard) diluvium_linux_static_x86_64 Static; works on Ubuntu, Fedora, CentOS, Arch
Raspberry Pi 3/4/5 diluvium_linux_static_aarch64 64-bit OS only
Raspberry Pi Zero diluvium_linux_static_armv7l 32-bit ARM
macOS (Apple silicon) diluvium_darwin_arm64 M1/M2/M3/M4
macOS (Intel) diluvium_darwin_x86_64
Windows diluvium_windows_x86_64.exe 64-bit
WASI diluvium_wasi.wasm Needs a runtime with wasm exception-handling (wasmtime 28+ with -W exceptions=y)
Browser libdiluvium_wasm_unknown.a wasm32-unknown-unknown static library

Each platform also ships a diluvium_compiler_* binary (luac
with the -r analysis report flag) and a libdiluvium_*.a static
library for embedding.

Verifying a download

sha256sum -c SHA256SUMS.txt --ignore-missing

BUILDINFO.txt records the exact commit, build time and workflow run.