8 Commits

Author SHA1 Message Date
635d12782d The globals a stopped stack reaches, in one section and not under a frame
A global is program state a frame happened to touch, not part of it, so
nesting it under one implies an ownership that is not there and repeats the
name once per frame that reads it. One section instead, holding the union of
the globals every frame on the stack references — the compiler does the
choosing, since Reach.expr_refs already answers a body's reference set, and
listing every global a program has would bury the one that matters under the
prelude's PRNG state.

Each entry says which frames touch it, by the index the stack section already
numbers them with, which recovers what per-frame nesting would have told you
at no cost in duplication. Ordered by the innermost frame that touches it:
a deep stack makes the union large and proximity to the error is what puts
the likely culprit on top.

Simpler than locals, because a global is reached by name rather than by
address. Emit.redefinition writes a global the host has as external, so the
thunk binds to the program's own storage and nothing is asked of the stopped
thread — no dev-slot round trip and no not-yet-bound case to refuse.

A frame that cannot be attributed contributes nothing and is named in
:skipped; the union being incomplete and the union being complete are
different answers. The hole in that is stated rather than papered over:
slot_fingerprint hashes a body's slots, which is the right cut for locals and
not for this, so a body that names different globals while binding the same
locals is not caught. The test drives the case that is.

MANUAL.md also loses a stale paragraph claiming the fingerprint check never
fires with a failing test pinned to it. It fires, and test_dev covers it.
2026-09-12 16:22:58 +07:00
64342c406e The manual says how a form is indented, and NEXT loses what landed
The indentation rules were written and tested but never described anywhere a
user would look. MANUAL.md had no section on editing at all — it starts at
`C-c C-c' and assumes the file is already written — so the rule that cost the
friction, a binding vector lining up name under name, was only visible by
trying it.

What is written down is what was checked, not what the port was aimed at: the
call fallback, the `handler-bind' clause vector, `defn' parameter alignment
with a return type after it, and `restart-case' clause bodies were each
reindented from scratch and the manual quotes the result.

NEXT.md keeps the half of the field-label handover that is still open. The
printer in render.ml has to move in the same commit as the inspector that
parses it, and that is the inspector lane's; the font-lock half is done here,
so only that half is struck.
2026-09-12 16:17:04 +07:00
8d56bd0ced TAB folds a frame, which is what the header always said it did 2026-09-12 12:31:16 +07:00
4857db1fc4 A breakpoint, which is only error under a restart-case 2026-09-12 12:25:08 +07:00
81d46c342e The stack section draws the frames it was written for
The web build's three artifacts are ignored alongside the native executables:
a page, its loader and the module are output, not source.
2026-09-12 12:16:30 +07:00
404b8559c5 The conditions buffer names and types the fields it used to refuse
C-c C-b asks layout with the condition's own name and draws the fields under
it. The values stay refused, by name, because the shape of a condition is a
fact about the build and its contents are a fact about the stopped frame — and
only one of those is knowable today. A layout the daemon refuses is nil rather
than an error: the buffer already draws a section saying why one is empty, and
failing the whole command would take away the restarts over an annotation.
2026-09-12 10:39:22 +07:00
3afce2aeac Never restarting is the thesis; say where the holes in it are
The manual described the signature-change refusal as though it were the
design. It is not, and session.ml already said so at the refusal: a
signature change should make a new version, leave old callers on the old
one, and warn at the stale sites. plan.org calls it signature generations
and stale-caller warnings, and it is milestone 7's unfinished half.

The struct-layout rejection is the decided one and stays. Conflating them
made a placeholder look like a rule.
2026-09-12 09:38:26 +07:00
64ce9ec05b A manual for the Emacs side, in plain language
The site's Emacs section is a key table and four paragraphs -- a
reference for someone who already knows the shape. This is the other
document: how to set it up, what the loop actually is, what each buffer's
own keys do, and what to do when something is refused.

The three buffer keymaps were never written down anywhere a user would
look; they were only in the define-key calls.
2026-09-12 09:31:27 +07:00