Commit Graph

1252 Commits

Author SHA1 Message Date
f8fc04840a fed-prims: Phase F — RSA-SHA256 PKCS#1 v1.5 verify, pure OCaml, RSA-2048 vector
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m9s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 17:32:35 +00:00
76d1e9f53a fed-prims: Phase E — Ed25519 verify (RFC 8032), pure-OCaml bignum + edwards25519
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m2s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 17:05:59 +00:00
d8b57784fe fed-prims: Phase D — CIDv1 (multihash + base32 multibase), pure OCaml, canonical IPFS vectors
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m2s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 16:36:42 +00:00
bcaaa11916 fed-prims: Phase C — dag-cbor encode/decode, pure OCaml, RFC 8949 vectors + determinism
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m8s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 16:10:36 +00:00
451bd4be62 fed-prims: Phase B — SHA3-256 (Keccak-f[1600]), pure OCaml, 4 NIST vectors
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 2m41s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:43:51 +00:00
19932a42a9 fed-prims: Phase A — SHA-256 + SHA-512, pure OCaml, 7 NIST vectors
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m33s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:17:35 +00:00
3629dd96a9 fed-prims: bootstrap plan + loop briefing
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 3m53s
Pure-OCaml crypto/CBOR/CID/Ed25519/RSA + native HTTP server in
hosts/ocaml/, the host-primitive surface Erlang Phase 8 BIFs and
fed-sx Milestone 1 are blocked on. WASM-safe lib boundary enforced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:00:33 +00:00
f026177e63 vm-ext: phase E — JIT skips lambdas containing extension opcodes
Adds Sx_vm.bytecode_uses_extension_opcodes — an operand-aware
bytecode scanner that walks past CONST u16, CALL_PRIM u16+u8, and
CLOSURE u16+dynamic upvalue descriptors so operand bytes that happen
to be ≥200 don't false-positive as extension opcodes.

jit_compile_lambda calls the scanner on the inner closure's bytecode.
On hit it returns None — the lambda then runs through CEK
interpretation. The VM's dispatch fallthrough still routes the
extension opcodes themselves through the registry; this change just
prevents the JIT from claiming code it has no plan for.

Tests: 7 new foundation cases — pure core eligible, head/middle/
post-CLOSURE detection, CONST + CALL_PRIM + CLOSURE-descriptor false-
positive avoidance. +7 pass vs Phase D baseline, no regressions
across 11 conformance suites.

Loop complete: acceptance criteria 1-4 met. Hand-off to the Erlang
loop — lib/erlang/vm/dispatcher.sx's Phase 9b stub can now be
replaced with a real hosts/ocaml/lib/extensions/erlang.ml consumer.
2026-05-15 01:53:39 +00:00
f3192f7fda vm-ext: phase D — extensions/ subtree + test_ext + opcode_name lookup
lib/extensions/ becomes the new home for VM extensions, wired in via
(include_subdirs unqualified). README documents the registration
pattern, opcode-ID range conventions (200-209 guest_vm, 210-219
inline test, 220-229 test_ext, 230-247 ports), and naming rules.

extensions/test_ext.ml is the canonical worked example — two
operand-less opcodes (220 push 42, 221 double TOS) carrying a per-
extension state slot (TestExtState invocation counter). Test_ext.register
called from run_tests.ml at the start of the Phase D suite, on top of
the inline test_reg from earlier suites (disjoint opcode IDs).

Sx_vm.opcode_name now consults extension_opcode_name_ref (forward ref
in the same style as extension_dispatch_ref), so disassemble shows
extension opcodes by name instead of UNKNOWN_n. Registry maintains
name_of_id_table and installs the lookup at module init.

Tests: 5 new foundation cases — primitive resolves test_ext name,
end-to-end bytecode (push + double + return → 84), disassemble shows
"test_ext.OP_TEST_PUSH_42" / "test_ext.OP_TEST_DOUBLE_TOS",
unregistered ext opcodes still fall back to UNKNOWN_n, invocation
counter records the two dispatches. +5 pass vs Phase C baseline, no
regressions across 11 conformance suites.
2026-05-15 01:05:30 +00:00
57af0f386f vm-ext: phase C — extension-opcode-id SX primitive
Registers extension-opcode-id from sx_vm_extensions.ml module init.
Lives downstream of both sx_primitives and sx_vm to avoid a build
cycle. Accepts a string or symbol; returns Integer id when the opcode
is registered, Nil otherwise.

Compilers (lib/compiler.sx) call this to emit extension opcodes by
name. Returning Nil rather than failing on unknown names lets a port's
optimization opt in per-build — missing extensions degrade to slower
correct execution.

Tests: 5 new foundation cases — registered lookup, unknown → nil,
symbol arg, zero-arg + integer-arg rejection. +5 pass vs Phase B
baseline, no regressions across 11 conformance suites.
2026-05-15 00:16:03 +00:00
8c33a6f8d5 vm-ext: phase B — extension registry module
sx_vm_extension.ml: handler type, extensible extension_state variant,
EXTENSION first-class module signature.

sx_vm_extensions.ml: register / dispatch / id_of_name /
state_of_extension. install_dispatch () runs at module init,
swapping Phase A's stub for the real registry. Rejects out-of-range
opcode IDs (must be 200-247), duplicate IDs, duplicate names, and
duplicate extension names.

Tests: 9 new foundation cases — lookup hits/misses, end-to-end VM
dispatch including opcode composition, all four rejection paths.
+9 pass vs Phase A baseline, no regressions across 11 conformance
suites.
2026-05-14 23:28:24 +00:00
cf597f1b5f vm-ext: phase A — extension dispatch fallthrough in sx_vm.ml
Adds Invalid_opcode of int exception and extension_dispatch_ref forward
ref (default raises Invalid_opcode op), plus the |op when op >= 200 arm
before the catch-all in the bytecode dispatch loop. Partition comment
documents 1-199 core / 200-247 extensions / 248-255 reserved.

Phase B will install the real registry's dispatch into the ref at module
init, replacing this stub.

Tests: 4 new foundation cases (Invalid_opcode for 200/224/247, Eval_error
for 199 to pin the threshold). +4 pass vs baseline, no regressions.
2026-05-14 22:29:50 +00:00
183bfeebe1 vm-ext: bootstrap loops/sx-vm-extensions plan + loop briefing
plans/sx-vm-opcode-extension.md ports over from loops/erlang (f6a68656)
with the opcode partition adjusted to match real VM usage: 1-199 core
(current ceiling 175 = OP_DEC), 200-247 extensions, 248-255 reserved.

plans/agent-briefings/sx-vm-extensions-loop.md captures the per-fire
workflow and ground rules.
2026-05-14 22:29:15 +00:00
97c800a36b Merge lib/guest/test-runner into architecture: test-runner.sx + Kernel migration (POC) 2026-05-14 20:18:03 +00:00
0526f796f4 Merge lib/guest/quoting into architecture: quoting.sx + Kernel/Scheme migrations 2026-05-14 20:17:58 +00:00
e5d751c5fb Merge lib/guest/method-chain into architecture: class-chain.sx + Smalltalk/CLOS migrations 2026-05-14 20:17:50 +00:00
8525165594 Merge loops/minikanren into architecture: Phase 5 disequality + Phase 6 FD constraints + Phase 7 SLG tabling
Phase 5: =/= disequality with constraint store.
Phase 6: bounds-consistency for fd-plus/fd-times, send-more-money, Sudoku 4x4, N-queens FD.
Phase 7: SLG-style tabling with in-progress sentinel + fixed-point iteration (Fibonacci + Ackermann canaries green).
2026-05-14 20:11:18 +00:00
f62df8d64e Merge hs-f into architecture: JIT Phase 2/3 + native unwrap sweep + dict-eq fix
JIT Phase 2 (LRU eviction) + Phase 3 (manual reset), lib/jit.sx convenience layer,
21 host-* natives ABI-compatible with WASM kernel handles, dict-eq fix (structural
eq for plain dicts + Integer/Number in equal?), io-wait-event interceptor fix,
HS test runner unwrap shim for post-JIT-P1 value handles.

Conflicts resolved:
- tests/hs-run-filtered.js: combined arch's fake-timer block (for socket RPC tests)
  with hs-f's auto-unwrap shim
- shared/static/wasm/sx_browser.bc.js: took hs-f's regenerated bundle
2026-05-14 20:10:49 +00:00
ca8e6f4da3 Merge loops/scheme into architecture: R7RS-small port, 296 tests across 11 phases 2026-05-14 16:12:50 +00:00
87f503f54b Merge loops/smalltalk into architecture: briefing tweak 2026-05-14 15:32:09 +00:00
90cd0f8f6f plans: kernel-on-sx — log quoting.sx extraction + evaluator.sx decline
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
Updates Phase 7 status:
- env.sx ✓ extracted (three live consumers: Kernel, Tcl, Smalltalk,
  with Scheme also using it directly)
- class-chain.sx ✓ extracted (bonus — not on the original six-file
  list but surfaced by the same chiselling discipline; Smalltalk +
  CLOS consumers)
- quoting.sx ✓ extracted (Kernel + Scheme consumers)
- evaluator.sx DECLINED — too thin to be its own kit; the shared
  content is protocol/API surface, not algorithm. Documented
  in-plan, no file created.
- combiner.sx, short-circuit.sx — still need fexpr-having
  second consumers
- hygiene.sx — still awaits Scheme Phase 6c (research-grade
  scope-set work)

Three kits live, one declined, three still gated.
2026-05-14 07:55:08 +00:00
22411f7f80 hs: port loops/hs RPC test infrastructure to architecture's test runner
Two additions from loops/hs needed for the new WebSocket socket tests:
- unhandledRejection suppressor — synchronous test harness doesn't await RPC promises
- Fake setTimeout/clearTimeout + __hsFlushTimers — drain RPC timeout tests synchronously

Plan update: mark E36 WebSocket as DONE (previously "design-done, pending review").

Skipped: loops/hs's tests/playwright/generate-sx-tests.py — architecture's version
is 1468 lines vs loops/hs's 290; arch's is the further-evolved version.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 07:26:43 +00:00
26112f1003 plans: scheme-on-sx progress log — 11 phases done, 296 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
Loop closer documenting what 10 feature commits landed across the
session. Phase-by-phase outcomes captured, including the SX cond
multi-expression bug found and fixed during Phase 4.

Chisel ledger:
- env.sx already EXTRACTED with Scheme as third consumer
- evaluator.sx + quoting.sx second-consumer-ready for follow-on
  kit-extraction commits
- hygiene.sx still awaits the deferred Phase 6c (scope-set work)
- combiner.sx and short-circuit.sx don't apply (Scheme has no
  fexprs and uses syntactic and/or)

Deferred phases listed: full hygiene, nested quasi-depth, R7RS
module rich features, dotted-pair syntax, full call/cc-wind
interaction.

Loop's defining feature: lib/guest CHISELLING discipline — every
commit had a chisel note, and the cumulative work satisfies the
two-consumer rule for three new kit extractions.
2026-05-14 06:53:36 +00:00
5e7d431f15 Merge loops/lua into architecture: features (coroutine, math, string.format, pattern char sets, byte-level chars). GUEST-lex refactor + delay/force to be re-applied in follow-up.
# Conflicts:
#	lib/lua/runtime.sx
#	lib/lua/test.sh
#	lib/lua/tokenizer.sx
2026-05-13 20:59:49 +00:00
88c7ce4068 Merge loops/apl into architecture: Phase 10 runtime gaps (⍸ ∪ ∩ ⊥ ⊤ ⊆ ⍎), life.apl + quicksort.apl run as-written 2026-05-13 20:38:17 +00:00
c19bcc51cb Merge loops/forth into architecture: Hayes conformance 99% (632/638), JIT cooperation, full Forth-2012 core 2026-05-13 20:37:26 +00:00
129f11fdbc Merge lib/tcl/uplevel into architecture: kernel + reflective env extraction (Phase 1-7 kernel, 322+427 tests) 2026-05-13 20:34:07 +00:00
a75b4cbc57 plans: scheme-on-sx — R7RS-small port, second consumer for 3 reflective kits
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 47s
11-phase plan from parser through R7RS conformance. Explicitly maps
which reflective kits Scheme consumes:

- env.sx (Phase 2)        — third consumer, no cfg needed
- evaluator.sx (Phase 7)  — second consumer, unblocks extraction
- hygiene.sx (Phase 6)    — second consumer, drives the deferred
                            scope-set / lifted-symbol work
- quoting.sx (Phase 10)   — second consumer, unblocks extraction
- combiner.sx             — N/A (Scheme has no fexprs)

Correction to earlier session claim: a Scheme port unlocks THREE
more reflective kits, not four. combiner.sx stays Kernel-only.
2026-05-13 19:53:29 +00:00
4fd376a348 Merge loops/datalog into architecture: tokenizer/parser, magic sets, negation, semi-naive (259/259 tests) 2026-05-13 19:52:11 +00:00
95c2d0b64a HS scoreboard: io-wait-event fix landed — both wait regressions cleared
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:33:50 +00:00
4d92eafb36 HS scoreboard: dict-eq fix entry + post-JIT-Phase-2 regression note
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
Records that the 1514/1514 claim was relative to the kernel as of
92619301; the value-handle ABI + numeric tower + JIT Phase 2 commits
introduced three regressions (1 dict-eq, now fixed in 4db1f85f, and 2
event-or-timeout wait tests still pending).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:22:00 +00:00
4563a7ae97 method-chain: plan — current status + future-consumer notes
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 40s
Documents the extraction (Smalltalk + CLOS migrated, kit landed,
counts unchanged), lists plausible third consumers (JS proto chain,
Ruby ancestors, Python MRO), and notes which other patterns stayed
unextracted and why (method-cache invalidation, inline cache, and
the five reflective siblings all need consumers that don't exist
yet in the codebase).

Closes the session's extraction work at five branches: env (3
consumers), class-chain (2), test-runner (POC), plus the chain
of intermediate branches. The Scheme port is the next high-leverage
move; it would unlock four more reflective kits in one stroke.
2026-05-12 21:14:28 +00:00
480462646d Merge loops/js into architecture: var hoisting + ASI + matchAll on top of regex engine / TDZ scaffolding
Combined arch's regex platform dispatch (runtime.sx) with loops/js's var-hoisting transpiler
(transpile.sx) and matchAll string method. Plan checkboxes updated to reflect both done.
Conflicts: lib/js/runtime.sx, lib/js/transpile.sx, lib/js/test.sh, plans/js-on-sx.md.
2026-05-12 20:47:05 +00:00
decaf818fa Merge loops/ocaml into architecture: OCaml-on-SX language port (Phase 5.1 + ~200 baselines)
# Conflicts:
#	plans/ocaml-on-sx.md
2026-05-12 20:39:48 +00:00
03d4e350d7 test-runner: plan — per-guest migration playbook for Phase 2
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Documents what's already done (kit + Kernel 7 files) and what's left
across 7 guests (35 std-pattern files + variant flavours in Tcl/APL).

Each guest is its own commit due to local naming and shape variants.
Prolog is the biggest single migration (23 files). Tcl and APL need
small variant adapters because their failure-records hold strings or
use slightly different signatures.

Reference: /tmp/migrate_harness.py is the regex-driven mechanical
migration tool; works on the standard pattern, skips variants for
human review.
2026-05-12 19:41:29 +00:00
4e904a2782 merge: loops/smalltalk into lib/smalltalk/refl-env — bring in third consumer 2026-05-12 14:50:05 +00:00
dea2a6e390 Merge loops/haskell into architecture: Phase 17 — import decls, type annotations, typecheck 15/15 2026-05-12 14:45:44 +00:00
c27db9b78f reflective: Phase 3 docs — mark env.sx extraction DONE, others still blocked
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
plans/kernel-on-sx.md — Phase 7 header updated from "partial" to
"env.sx EXTRACTED 2026-05-12"; second-consumer-found checkbox ticked
for env.sx specifically. Other five files (combiner, evaluator,
hygiene, quoting, short-circuit) stay blocked pending their own
second consumers.

plans/lib-guest-reflective.md — Phases 1-3 ticked off with date
stamps; Outcome section added summarising the three commits, file
stats (124 LoC, within 80-200 bound), and the third-consumer
adoption protocol (cfg with five keys, no changes to env.sx).
2026-05-12 07:04:17 +00:00
edfc37636f merge: loops/kernel into lib/tcl/uplevel — bring in first consumer for extraction 2026-05-12 06:55:00 +00:00
24d8e362d5 plans: lib-guest-reflective extraction kicked off — Tcl uplevel as second consumer
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s
The kernel-on-sx loop documented six candidate reflective API files
gated on the two-consumer rule. This plan opens that block by
selecting Tcl's existing uplevel/upvar machinery as the second
consumer for env.sx specifically (the highest-fit candidate).

Discovery: Kernel and Tcl have identical scope-chain semantics but
diverge on mutable-vs-functional update. Solution: adapter-cfg
pattern, same as lib/guest/match.sx. Canonical wire shape with
mutable defaults for Kernel; Tcl provides its own cfg keeping
the functional model.

Roadmap: env.sx extracted, both consumers migrated, all tests green.
The other five candidate files (combiner, evaluator, hygiene,
quoting, short-circuit) stay deferred — Tcl has no operatives.
2026-05-11 22:12:26 +00:00
f7bd3a6bf1 kernel: loop summary — 18 commits, 322 tests, 6 reflective API candidates [proposes-reflective-extraction]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 42s
Loop closer documenting what 18 feature commits produced. Kernel-on-SX
is 1,398 LoC substrate + 1,747 LoC tests = 3,145 LoC total. Zero
substrate fixes required across the loop. R-1RK core + extras
implemented. Six proposed lib/guest/reflective/ files awaiting second
consumer. Substrate verdict: env-as-value generalises to
evaluator-as-value; the m-eval demo proves it.
2026-05-11 21:28:10 +00:00
d5d77a3611 kernel: type predicates + metacircular demo + map/filter/reduce fix [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 44s
Five type predicates (number?, string?, list?, boolean?, symbol?).
New tests/metacircular.sx: m-eval defined in Kernel walks expressions
itself, recursing on applicative-call args and delegating to host
eval only for operatives and symbol lookup. 14 demo tests.

The demo surfaced a real bug: map/filter/reduce called kernel-combine
on applicative head-vals directly, which re-evaluates already-
evaluated element values; nested-list elements crashed. Fix: extracted
knl-apply-op (unwrap-applicative-or-pass-through) and use it in all
three combinators before kernel-combine. Mirrors apply's approach.

Added knl-apply-op as a proposed entry in the reflective combiner.sx
API. 322 tests total.
2026-05-11 21:27:23 +00:00
40dff449ef apl: het-inner-product encloses (+4); life.apl restored to as-written
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
apl-inner now wraps its result in (enclose result) when A's ravel
contains any dict element (a boxed array). This matches Hui's
semantics where `1 ⍵ ∨.∧ X` produces a rank-0 wrapping the
(5 5) board, then ⊃ unwraps to bare matrix.

Homogeneous inner product unaffected (+.× over numbers and
matrices still produces bare arrays — none of those ravels
contain dicts).

life.apl restored to true as-written form:
  life ← {⊃1 ⍵ ∨.∧ 3 4 = +/ +/ ¯1 0 1 ∘.⊖ ¯1 0 1 ⌽¨ ⊂⍵}

4 pipeline tests + 5 e2e tests verify heterogeneous case and
that ⊃ unwraps to the underlying (5 5) board.

Full suite 589/589. Phase 11 complete.
2026-05-11 21:19:06 +00:00
67449f5b0c kernel: append + reverse + 11 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
Variadic append concatenates lists; reverse is unary. 307 tests total.
2026-05-11 21:19:01 +00:00
6d8f11e093 kernel: apply combinator + 7 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 32s
(apply F (list V1 V2 V3)) ≡ (F V1 V2 V3). Unwrap applicative first to
skip auto-eval (args are values), then kernel-combine with the
underlying operative. Universal pattern in reflective Lisps —
sketched into the combiner.sx API. 296 tests total.
2026-05-11 21:17:24 +00:00
78dab5b28c kernel: map/filter/reduce + with-env applicative constructor + 10 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Added kernel-make-primitive-applicative-with-env in eval.sx — IMPL
receives (args dyn-env), needed by combinators that re-enter the
evaluator. map/filter/reduce in runtime.sx use it to call user-supplied
combiners on each element with the caller's dynamic env preserved.
Sketched the env-blind vs env-aware applicative split as a new entry
in the proposed combiner.sx reflective API. 289 tests total.
2026-05-11 21:15:54 +00:00
1fb852ef64 kernel: variadic +-*/, chained <>=? + 19 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
knl-fold-app for n-ary fold with zero-arity identity and one-arity
special-case (- negates, / inverts). knl-chain-cmp for chained
boolean comparison. 279 tests total.
2026-05-11 21:13:13 +00:00
b80871ac4f kernel: $let* sequential let + multi-body $let + 8 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
$let* nests env-extensions one per binding — each binding sees earlier
ones. $let now also accepts multi-expression bodies. 260 tests total.
2026-05-11 21:11:01 +00:00
9ff5d1b464 kernel: $and? / $or? short-circuit + 10 tests [shapes-reflective]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Operatives (not applicatives) so untaken args are not evaluated. Empty
$and? = true, empty $or? = false (Kernel identity convention). Returns
last evaluated value, not bool-coerced. Sketched reflective short-
circuit API: identical protocol across reflective Lisps because
operative semantics are forced — an applicative variant defeats the
purpose. 252 tests total.
2026-05-11 21:09:20 +00:00
5fa6c6ecc1 kernel: $cond/$when/$unless + 12 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
Standard Kernel control flow. $cond walks clauses in order with `else`
catch-all; clauses past the first match are NOT evaluated. $when/$unless
are simple guards. 12 tests, 242 total.
2026-05-11 21:08:08 +00:00