Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 06:25
· 18 commits to main since this release

Added

  • BOUNDARY.md §12: the conformance table. Every normative claim in
    §1–§11 (103 rows) classified as compile error, runtime check, test,
    documented-UB-by-design, or gap — with verified citations. The two
    remaining gaps are scheduled v0.4 items and say so in the table.
  • Eight new conformance tests (:rulisp-v04), closing every prose-only
    claim the sweep found: swallowed CallbackError discards the stash;
    swallow-then-fail re-signals the original condition (status 4); a panic
    in a *_free shim is caught and swallowed (new Grenade fixture handle
    whose Drop panics); a poisoned mutex reports rust-panic on the next
    lock; last_error is thread-local AND per-library (concurrent failures
    in wordbag and rx never cross); out-params survive an ERR return
    untouched (FFI-level sentinel test); ECL's missing-C-compiler failure is
    the named manifest-error (injected via c::*cc*).
  • on_dump: <fn> in rulisp::module! — a declared, zero-arg shutdown
    export the loader auto-registers as an image-dump hook (new wire-additive
    manifest key (:on-dump "symbol"); ABI 1 intact). Hooks run in load
    order; a failing hook is warned and skipped — a dump is never wedged by
    its own cleanup. The manifest refuses a declaration whose function takes
    parameters or returns a value (the call goes through a fixed signature),
    and module! rejects it at compile time too. examples/fetch converts:
    its hook quiesces every live tokio runtime, and the suite proves the
    whole story by dumping an image with a request in flight and restoring
    it (the two tests the v0.3 risk table promised).
  • docs/benchmarks.md — a dated, release-profile baseline with the
    method; every number quoted in this changelog traces to it.
  • The ECL CI job is required (was best-effort): 24 consecutive green
    runs since the 0.2 trampoline fix, now including the program-op
    deployment smoke. The workflow documents the demotion procedure.
  • tools/rulisp-audit.sh — BOUNDARY §7 as a command for any glue
    crate (signal-disposition imports on the artifact, tokio signal/process
    features, block_on), run over every example by make audit in CI. A
    self-test builds a library that deliberately imports signal() and
    requires the audit to reject it, so the gate cannot go inert unnoticed
    again. fetch's audit.sh is now a wrapper adding its OpenSSL rule.
  • #[rulisp(constructor, name = "…")] — an explicit Lisp name for a
    constructor. Load-bearing since 0.3 made duplicate :lisp-name a hard
    error: two constructors on one type both derived make-<type>, so a
    second constructor was inexpressible. The attribute grammar is now
    strict — a misspelled key, a non-string name, a name with reader syntax,
    or name on a non-constructor are compile errors (previously unknown
    keys were silently ignored).
  • ECL deployment story (docs/distribution.md Pattern B′): ECL has no
    image dump; applications ship as asdf:program-op executables. The
    documented recipe (:no-uiop t because the distro ECL cannot satisfy
    ASDF's default static link of cmp — no libcmp.a — a prologue
    require, an explicit epilogue entry call, and the dependencies loaded
    before program-op, which the bundled ASDF 3.1.8.8 cannot build from a
    cold cache) is exercised by tests/ecl-program, a minimal consumer the
    ECL CI job builds and runs (make test-ecl-program).
  • The dump/restore test (m7) now really runs on CCL — and Windows —
    instead of passing vacuously off SBCL, with a new assertion: a pre-dump
    handle GC'd after restore must not make a foreign call.

Fixed

  • Two processes sharing one crate cache could crash each other. The
    cache copy was named <crate>-c<n>-<universal-time> with n counted per
    process, so two instances started in the same second wrote the same
    file, and copy-file rewrote a library the other process had already
    mapped — a segmentation fault (found by the ECL deployment verification,
    reproduced 5/5). Copies now carry a per-process tag (pid, or a random
    tag where the host has none), recomputed on image restore; the sweep
    deletes this process's older generations immediately and other
    processes' copies only after an hour, so it can no longer unlink a copy
    another process is about to dlopen.
  • A failed dlopen names the artifact the user asked for, not only the
    cache copy.
  • rulisp's load-time compiles are quiet now: on ECL, compile prints
    per-function notes, so a deployed program printed dozens of lines every
    time it loaded a crate.
  • The loader now rejects (:option :bool) in a hand-written manifest
    (option-inner); previously only the macro refused to emit it.