docs(v4.0.0): the root causes behind the wait's faults, and the boots of the code that mends them

MESH.md 7c.7: the stacks doubled in scratch and each path measured -- the
size was never the cause; EMIT's overrun of the output buffer, and a
message's first word moving before there was room for the rest; what is
left for a second design; the depth sweep.

Three bare-metal boots of 0d91608f typing the deep-stack lines: POST 538
of 538, word_count=317, dict_hash=0x3629660aa2dc6823 on all six.  Three
earlier amd64 boots of the same code, whose typed session was wrong, are
kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-08 12:25:19 -04:00
co-authored by Claude Opus 5.5
parent 0d91608f39
commit 8967c93241
7 changed files with 1358 additions and 0 deletions
+56
View File
@@ -646,6 +646,62 @@ every node present.
Two guards from this are kept in `hosted-check`: a line that leaves 29
values on the stack, and `WORDS` with 26 values on it.
### 7c.7 The root causes, found and mended in the code as it stands (2026-10-08)
Captain Bob asked for the root cause before deciding whether to make the
stacks bigger. Both stacks were doubled in scratch copies of the code,
of this code and of the wait's, and each path measured: the prompt and
the interpreter need four cells of the data stack, printing six (the
wait's code seven), and nine entries of the return stack, whatever the
size. **The size was never the cause.** Doubling moved the faults from
26 to 28 values to 58 to 60 and removed none. Two defects were, and both
were in this code too:
1. **`EMIT` ran past the output buffer.** It stored its character and
only then looked whether the buffer was *exactly* full. A flush that
ended in a fault -- the stack too deep to begin a message -- left the
buffer full; the fault's own message was then put past its end, and
`(OUT^)` was never again at the end to be flushed. Here the 28 cells
after the buffer happen to be unused and the longest error message is
shorter, so nothing showed. The wait had moved the ports into those
cells: the characters were stored into port addresses and the node
blocked writing to a port. **That was the hang.** Mended: `EMIT` sends
a buffer it finds full before it stores.
2. **A message's first word moved before there was known to be room for
the rest.** Once a first word is read or written both ends are
committed. `AWAIT`, and `(GATE)` when a neighbour is writing, read one
and then used stack that had not been tried: with 27 or 28 values on
the stack, or 28 or 29 calls deep, a line typed during `AWAIT` was
taken and never answered. Writing was safe only by the order things
happened to be done in; the wait's code needed one cell more after the
first word than before it. Mended: `(ROOM)` tries six cells and four
return entries before a first word is read from within text, and
`(GATE)` tries the three its writing needs before a first word goes.
If they are not there the text ends "Stack overflow" with nothing on
a wire.
**Not mended, and left for a second design of the wait:** a message has
no way to be given up part way. On a mesh, if a fault does come after a
first word, the reader waits for a rest that never comes and takes the
next message's words for it.
**The test that was missing.** `v4/tools/depthsweep.py` runs every
message path of the hosted product -- printing, `WORDS`, a line typed
during `AWAIT`, `SEND`, a write to an empty port, an unknown word -- with
the data stack at every depth from ten below its end to two past it, and
from that many calls deep. Each line typed must be answered and the node
must come back. `hosted-check` runs it: 164 runs. `test_host_quit.c`
checks that nothing is ever put past the end of the output buffer.
**Verified.** `make -C v4 test` and `sanitize` at both widths,
`hosted-check`, lint; three bare-metal boots, `logs/20261008-121610`
(amd64), `-121857` (aarch64), `-122251` (riscv64), each typing 29 values
on a line, `WORDS` with 26 on the stack, and `AWAIT` with 27 followed by
a line. POST 538 of 538, `word_count=317`,
`dict_hash=0x3629660aa2dc6823` on all six. (`logs/20261008-120121`,
`-120624` and `-121117` are amd64 boots of the same code in which the
typed session did not put the wait on a deep stack; they are kept.)
## 8. Storage
**Ruled 2026-10-06 and 2026-10-07** (Captain Bob). On 2026-10-07 he found