feat(v4.0.0): a node finds the way -- routes, passing on, SEND; one fault stands

MESH.md step 4. Each node has a table of destinations and the port toward
each, and a port for everything else (ROUTE, DEFAULT-ROUTE, NO-ROUTES). A
message not for this node is passed on whole; one with nowhere to go is
dropped and counted. What text prints and how it ended go back to the node
it came from by the same table. SEND sends text to another node.

test_host_mesh.c: three StarForth nodes in a row behind a console, 28
checks at both widths and under ASan+UBSan. hosted-check on three ISAs.
Bare metal: logs/20261006-115225 (amd64), -115501 (aarch64), -115849
(riscv64).

NOT DONE. Two neighbours that write to each other at once wait for ever:
a write blocks until the neighbour reads, and a node that is writing is
not reading. The last check in test_host_mesh.c shows it (KNOWN FAULT).
MESH.md section 7a sets out the ways out; none is chosen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-06 12:01:32 -04:00
co-authored by Claude Opus 5.5
parent a041b401ea
commit 630d03fa4e
11 changed files with 820 additions and 17 deletions
+71
View File
@@ -213,6 +213,39 @@ outer nodes, and for each other unit the port toward that unit's centre.
A different geometry is a different way of filling in the wiring table
and these tables. Nothing else changes.
## 7a. Two neighbours writing to each other (open; awaits a ruling)
The fault is in section 10, step 4. Three ways out, none built:
**A. A node writes only to a neighbour that is already reading.** The
engine gives a node two more things to fetch, as the F18's `io` register
does: which ports have a neighbour writing, and which have a neighbour
reading. A node with a message to send looks first. If the neighbour is
reading, it writes, and the write does not wait. If the neighbour is
writing to it instead, it takes that message in first, and deals with it,
and looks again. A node therefore holds messages waiting to go, in its own
memory, and what it does when that room is full has to be decided (the
message is lost and counted, as one with nowhere to go is now). Writes
still block, as ruled; a node simply does not start one it cannot finish.
This is how it is done on the chip. It is all in the nucleus but for the
two fetches.
**B. Passing on is not the node's programme's work.** `DECOMPOSITION.md`
6.1 says "the router in each node forwards packets". Read as a thing apart
from the programme -- logic beside the F18 on the FPGA, a part of the
fabric in the model -- it takes in and sends on whatever the programme is
doing, and holds what is for the programme until it reads. The programme's
own writes then never wait on a neighbour's programme. This is more
hardware per node and takes passing-on out of F18 code, and out of what a
capsule can change.
**C. No answer to a `SEND`.** It removes the case found and leaves the
fault: any two messages crossing still stop both nodes. Not offered as a
way out; listed so that it is seen to have been weighed.
Recommended: A. It keeps every ruling as it stands, keeps a node an F18
and nothing more, and what it adds to the engine the chip already has.
## 8. Storage
**Proposal.** A disk is a device on a port. Asking for a block is a
@@ -311,6 +344,44 @@ Each is tested, committed and pushed before the next.
input registers, not a message. A message not for this node, or not
text, is let go: passing it on is step 4.
4. **Finding the way (section 7).**
**Built 2026-10-06; NOT done: one fault stands, below, and it needs a
ruling.** Each node has a table of up to 16 destinations and the port
toward each, and one port for everything else (`ROUTE ( node port -- )`,
`DEFAULT-ROUTE ( port -- )`, `NO-ROUTES`; `(PORT-FOR)` in
`v4/capsule/core.v4`). A message not for this node is written, whole,
to the port its destination's entry names (`(PASS-ON)`,
`v4/capsule/quit.v4`); with no entry and no port for everything else it
is dropped and counted (`(LOST)`). What text prints, and how it ended,
go back to the node the text came from by the same table, so an answer
crosses as many nodes as the text did. `SEND ( baddr u node -- )` sends
text to another node; `(ME)` is a node's own number; `(CONSOLE)`, when
set, is where a node's printing goes instead of to the sender.
`v4/tests/test_host_mesh.c`, 28 checks at both widths and under ASan
and UBSan: three StarForth nodes in a row behind a console; text for
the far one passes through the other two and its answer comes back;
each node keeps its own dictionary; output longer than one message; a
1024-character message passed on whole; a message with nowhere to go
counted; a table changed while running. The single-node products are
unchanged: `hosted-check` on three ISAs; bare metal
`logs/20261006-115225` (amd64), `-115501` (aarch64), `-115849`
(riscv64).
**THE FAULT: two neighbours that write to each other at once wait for
ever.** A write blocks until the neighbour reads (ruling, section 4.1),
and a node that is blocked writing is not reading. Passing a message on
is done here by the node's own programme, so a node cannot pass
anything on, or take anything in, while it waits to write. Found so: the
far node `SEND`s text to the middle one and then goes to send word of
how its own text ended, which goes by the middle one; the middle one has
done the text and goes to answer the far one. Each is writing the first
word of a message to the other. It is not peculiar to `SEND`: any two
messages going opposite ways on one wire at the same moment do it, and
so would a ring of nodes each writing to the next. The last check in
`test_host_mesh.c` shows it and is named KNOWN FAULT; it is there so the
fault is on record and is seen to go.
It is not a slip in the code. It is what blocking writes and a
programme that does one thing at a time give. Section 7 said nothing
about it and should have. What is to be done about it is not decided:
the choices are in section 7a.
5. **Birth and Hera's requests (section 9); the unit of five.**
6. **Storage (section 8).**
7. **A second unit; scaling while running; sleep, wake and kill by