Where this is at the end of the session, and the three things waiting on a decision

This commit is contained in:
Joseph Ferano 2026-09-14 09:50:42 +07:00
parent 0661e6042e
commit 3b1d3e82b5

75
NEXT.md
View File

@ -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