From 3b1d3e82b5b9b2382580bf1201cb6aedefad41a8 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 14 Sep 2026 09:50:42 +0700 Subject: [PATCH] Where this is at the end of the session, and the three things waiting on a decision --- NEXT.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/NEXT.md b/NEXT.md index 764c6c0..9fe3bc6 100644 --- a/NEXT.md +++ b/NEXT.md @@ -1,3 +1,78 @@ +# Where this is — 2026-09-14 morning, wrap-up + +**Branch `dev-loop` at `0661e60`, working tree clean, every lane merged, nothing running.** +`dune test` is 232 checks and 0 failures, `spike/x86/survey.sh` is 103 MATCH / 0 DIFFER / 0 refused, +`spike/x86/cells.sh` is 4/4, and `web/examples/check.sh` is green. Read this section first; the +sections below it are older and each says so where it matters. + +## What landed since the last handoff + +The backend finished. `lib/x86.ml` now has a redefinition emitter — the counterpart to +`Emit.redefinition`, which is what the whole exercise was for — plus DWARF debug information good +enough that `gdb` and `lldb` name Flan source lines in a backtrace, and it no longer emits registry +calls into a disabled registry in a release build. Two guards that no program reached were +investigated rather than left: `flan_transfer_fail` was correct and now has a probe behind it, and +`"defers on a transfer path nothing reaches"` was simply wrong — any leaf function with a `defer` +reached it, while LLVM compiled the same program — so it is gone. + +Three bugs were found that were not on anyone's list, and they are the reason this session was worth +more than its queue: + +**The daemon had no `SIGPIPE` handling.** A reply written into a socket whose reader had gone killed +the process, and in a merged build that process is the program, the compiler and the listener at +once. So the game died and left a socket on disk with nothing accepting on it, which reported as +`Connection refused` on a path that plainly existed — and that message is what misdirected the last +two investigations into this area. It reproduces in under a second with one client that sends a +request and closes before the reply arrives, which is now a test. + +**A crossed reload was a silent segfault.** `flan build --x86 --dev` followed by `flan reload` built +an x86 host with an LLVM module, and the two conventions disagree on every aggregate, so it died at +the first redefined function taking a struct. Nothing refused it. Each backend now defines a marker +symbol its own modules reference, so the pair is refused at `dlopen`, naming both backends. + +**`web/examples/check.sh` had been failing since 2026-09-12 and nothing noticed**, because it is not +part of `dune test`. A colon-to-dot sweep rewrote the source forms and never touched a recorded +`.out`. That is the same failure mode as the x86 survey's two refusals sitting unseen for a month, +and it is worth fixing structurally rather than one script at a time. + +Also: `ArithError` replaced SIGFPE for a divide by zero, `INT64_MIN / -1` and an out-of-range +float-to-int cast; `lib/cimport.ml` learned the `(Ptr T)`-against-`T *` arm its own comment had been +promising, which closed the raylib codepoint gap entirely; the repository root went from 39 entries +to 23 with the reports moved into `docs/`; 138 stale agent branches and their worktrees were deleted, +taking `.claude/worktrees` from 7.9G to 164M; and there is now a `README.md`, an MIT `LICENSE` and a +logo in `assets/`. + +## Open, and waiting on you + +**`ArithError` established no restarts.** The design agreed at the keyboard was `use-value` +everywhere plus `saturate` where clamping is meaningful. What landed is the condition and the guards +alone, because `runtime/flan_rt.c:70-86` allocates a restart frame in the `restart-case` that offers +it, on that frame's own stack — so the runtime cannot push one on a program's behalf, and offering +`use-value` at a division would mean an alloca plus a push and pop at every division in every checked +build. That is the identical cost `lib/prelude.ml:70-76` already refuses, in prose, for indexing. The +question is whether signal-and-die-with-a-location is enough, or whether you want `saturate` on the +cast arm alone, where clamping is canonical rather than arbitrary. See `docs/handoffs/HANDOFF-arith.md`. + +**Frame descriptions are gated on `--debug`.** They are correct in every build, cost nothing at +runtime, and a release build is where a crash would most want them. One `if` in three places. The +lane gated them only because another lane was measuring backend cost at the time, and that +measurement is now finished. + +**A 2MB font.** `examples/text-codepoints-loading.flan` wants `DotGothic16-Regular.ttf`, which is OFL +and redistributable. The example says on screen when it is missing and runs either way. Vendoring it +is a call about the repository rather than about the port. + +**`emacs-batch-a63bd`** is the one branch not deleted, because it is not merged. It is unfinished work +from an earlier session and nobody has looked at what is on it. + +## The structural thing worth doing next + +Two scripts that check real things — `spike/x86/survey.sh` and `web/examples/check.sh` — each rotted +silently for days or weeks because neither runs unless somebody remembers. `survey.sh` now has a +`@x86` dune alias; `check.sh` has nothing. Neither is in `dune test`, for the good reason that both +are slow. But "slow, therefore never run" is how both of these bugs happened, and a third one is +presumably waiting. + # Overnight, 2026-09-13 into 09-14 — one decision waiting for you **`ArithError` landed, but without the restarts you asked for.** The design agreed at the keyboard was