You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.