feat(v4.0.0): the wait replaces looking and the console release; step 6d written up

The engine's console release (v4_fabric_interrupt_error), a device's
pending, and the count of words since a look are removed: nothing uses
them.  MESH.md 4.1, 7b and 7c say what was built, where it differs from
what was approved and why, and what is still a limit; step 6d is marked
built, with the defects found on the way.

make -C v4 test and sanitize at both widths, hosted-check, lint; three
bare-metal boots.  POST 538 of 538, word_count=317,
dict_hash=0x6a39c0bb9d183418 on all six.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-08 01:24:09 -04:00
co-authored by Claude Opus 5.5
parent ec817a8264
commit 2b587206ee
13 changed files with 638 additions and 181 deletions
+113 -53
View File
@@ -104,6 +104,9 @@ word address `base`:
| `base` … `base + V4_PORTS − 1` | Port 0 … port `V4_PORTS − 1` |
| `base + V4_PORTS` | Any port: a read here takes from whichever port has a neighbour writing |
| `base + V4_PORTS + 1` | Which port the last read from "any" came from. Read only. |
| `base + V4_PORTS + 2`, `+ 3` | Who is waiting to write to this node, and who to read from it: section 7a |
| `base + V4_PORTS + 4 + k` | The offer on port *k*: section 7c |
| `base + 2 * V4_PORTS + 4` | The wait: section 7c |
- **A write to a port blocks the node until the neighbour has read it.**
Built 2026-10-05 for one port; the opcode after the write runs when the
@@ -304,7 +307,8 @@ kernel-Hermes's work in v3 and is not decided for the mesh.
gone; and a wait on a node that is alive and stuck is ended by Hera's
killing that node, or from the console. A message that is refused is
told to whoever waits on it, while the node that refuses it has room to
remember that it owes the telling.** As first written the rule was "no
remember that it owes the telling.** (Since step 6d, section 7c, a node
that is stuck also holds up no other node.) As first written the rule was "no
message is lost without its sender being told, and no node waits for
ever"; the review showed that was more than what was built could keep,
and section 7b.7 says exactly where it falls short. It closes two defects
@@ -371,12 +375,12 @@ Two types, beside text (1), output (2) and done (3):
- A NACK owed to this node itself -- its own message came back to it and
was let go here -- is put with its messages waiting, as if it had come
by a port.
- Paying one: if the neighbour it goes by is reading, it is sent. If not,
and that neighbour's number is the higher, it is written all the same,
as any message to it is (section 7a). If its number is the lower, the
NACK stays owed; the node goes on taking in what is written to it and
tries again, and does not sleep while it owes one. One there is no way
for, or whose way is a port with nothing on it, is dropped and counted.
- Paying one: it is offered on the port it goes by, with everything else
the node has to send, and the node sleeps in the wait (section 7c). One
there is no way for, or whose way is a port with nothing on it, is
dropped and counted. (As first mended it was written without looking to
a higher-numbered neighbour and kept back from a lower; step 6d
replaced that.)
- A message is passed on by at most 16 nodes. Its fourth word, the TTL,
carries how many more may pass it on; the node that would be the
sixteenth refuses it as it would one it had no way for. (Ruled
@@ -422,14 +426,11 @@ Two types, beside text (1), output (2) and done (3):
as usual.
- On the two products there is one node, and nobody but the console could
ever answer it: a line typed while it waits does the same.
- **A blocked write (ruled 2026-10-07).** Hera has the lowest number, so
she writes to a neighbour without looking and is blocked until it reads
(section 7a); if it never does, nothing could be typed to her again. So
when a node is blocked writing the first word of a message to another
node, and its console has a line for it, the fabric raises error 21 on
it: it gives that message up and goes on to read the line. Only on the
first word, so that half a message is never left on a wire
(`v4_fabric_interrupt_error`, `v4/include/v4/fabric.h`).
- **A blocked write (ruled 2026-10-07; replaced by section 7c the same
day).** As first mended the fabric raised error 21 on a node blocked on
the first word of a message while its console had a line for it. Since
step 6d no node is blocked on a first word: it offers it and sleeps,
and a console line reaches it as any message does (7c.3).
- **A node waiting to write to a neighbour that has been removed** is told:
the word that says which neighbours are reading also says which ports
have anything on them at all, and with nothing there the wait ends in
@@ -443,22 +444,11 @@ Two types, beside text (1), output (2) and done (3):
console. v3's pool is finite too, 32 messages, and a send beyond it is
refused.
- A node whose neighbour is asleep waits until it is woken (section 4.1).
- **A node that is stuck can hold up its neighbours until it is killed.**
A node cannot tell a neighbour that is busy for a moment from one that
is stuck for good, and there is no clock (ruling 2). So:
- a node that owes a NACK to a stuck neighbour whose number is the
higher is blocked writing it;
- a node that owes one to a stuck neighbour whose number is the lower
goes on taking in what lower-numbered neighbours write to it, but does
not sleep, and a higher-numbered neighbour with something for it
waits;
- a node with a message for a stuck neighbour waits to write it.
Each ends when Hera kills the stuck node: the wire is then empty, the
waiting node is told so (error 18) and goes on. Hera herself can always
be typed to (7b.6). None of this can happen on a node that is gone.
- A node that is waiting for an answer keeps what comes for other nodes
and passes it on when its wait ends, not before.
- ~~A node that is stuck can hold up its neighbours until it is killed.~~
**Closed by step 6d (section 7c).** As step 6c left it, a node that
owed a stuck neighbour a NACK, or had a message for it, was blocked or
went round until Hera killed the stuck node; and a node waiting for an
answer kept back what was passing through it.
- A node that was never told who is on its centre's port believes no GONE.
## 7c. The wait (ruled 2026-10-07)
@@ -525,9 +515,15 @@ a node may offer a word on each of its ports at once.)*
it by its own case 1.
- A node in the wait executes nothing and spends no heat. It shows to its
neighbours as waiting to read.
- With nothing on a port it has an offer on, a node that can take an error
has error 18 raised on it (section 4.1); a bare node waits. A neighbour that
is asleep takes nothing: the offer stands.
- With nothing on a port it has an offer on -- because nothing ever was,
or because what was there has been removed -- a node that can take an
error is woken: the fetch gives 0 and "which port" gives
`2 * V4_PORTS + k`. No error is raised: the node may be in the middle of
something that has nothing to do with that port. A bare node waits. A
neighbour that is asleep takes nothing: the offer stands. *(Changed
while it was built: as approved, error 18 was raised. That ended the
text of a node that merely had a message queued for a neighbour that
was then killed.)*
- `v4_fabric_interrupt_error`, a device's `pending`, and
`v4_node_words_since_look` are removed.
- The lone node of the two products (`v4/system/boot.c`) has the same
@@ -536,30 +532,59 @@ a node may offer a word on each of its ports at once.)*
### 7c.3 The nucleus
- *Beginning a message* (`(GATE)`): offer its first word; if a word comes
instead, take that message in and offer again; when the offer is taken,
write the rest, each word waiting for the neighbour, which has taken the
first and reads to the end.
- *Paying what is owed* (`(PAY)`): every NACK owed is offered at once,
each on the port it goes by (one to a port). A node with nothing to do
that owes one sleeps in the wait; it no longer goes round, and it no
longer writes one without looking.
- *Text from its console for a node that is waiting to begin a message*
ends what the node was doing in error 21, "Interrupted", and is then
done, as in `AWAIT` (7b.6). This is how Hera is typed to while she waits
on a stuck node.
*(Rewritten 2026-10-08 as built. The first form had the node passing a
message on by beginning it at once, as its own text does. That held the
node passing on whenever the node it was for was stuck: text typed for a
stuck node left Hera deaf. So what is passed on waits, offered.)*
- *Beginning a message from text* (`(GATE)`): offer its first word; if a
word comes instead, take that message in and offer again; when the
offer is taken, write the rest, each word waiting for the neighbour,
which has taken the first and reads to the end. With nothing on the
port it is error 18.
- *Text from its console for a node whose text is waiting there* ends that
text in error 21, "Interrupted", and is then done. This is how Hera is
typed to while her line waits on a stuck node.
- *A node with nothing to do* (`(IDLE)`) deals first with what is for
itself, the oldest first. With nothing for itself it offers, all at
once, the first message it has for each port and each NACK it owes, and
sleeps in the wait. What is taken is written and done with; the rest
stays with the messages waiting, in the order it came. A message for a
stuck node waits there and holds up nothing.
- *What a node sends other than from text* goes the same way: how text
ended (type 3), and a GONE. Each is put with the messages waiting and
goes when it can. So a node that did text for a sender that then stuck
is not held by it, and `KILL` is not held by one stuck node from telling
the next.
- *Order.* How text ended is put before the other messages waiting, and a
node does not begin another text from a sender while its answer to that
sender is still with it: what one sender is told comes in the order its
texts were done.
- *A node waiting for an answer* (`AWAIT`) does all of this but begin
text: it looks through the messages waiting for what would end its
wait, offers what is to be passed on and what it owes, and sleeps in
the wait. It no longer keeps back what passes through it.
- `NEIGHBOUR` stays: a node must know who is on its centre's port to
believe a GONE (7b.4). It is no longer needed to write.
### 7c.4 What is still a limit
- A node's own line that must begin a message to a stuck node waits until
Hera kills that node or, on Hera, a line is typed. It takes in
everything sent to it meanwhile, and holds up no one.
- A node in `AWAIT` keeps what comes for other nodes, and what it owes,
until its wait ends (7b.7).
- A node's own text that must begin a message (`SEND`, or what it prints)
to a stuck node waits until Hera kills that node or, on Hera, a line is
typed. It takes in everything sent to it meanwhile, but passes nothing
on until its text ends.
- A line typed at Hera while her text is waiting to begin a message ends
that text, whether the node it waits on is stuck or only busy.
- What a finished text printed is still begun as a message from text is,
toward the console's node: if that node is stuck, nothing could be seen
in any case.
- An answer that reaches a waiting node whose messages waiting are full
is refused, and the wait ends "Message refused".
- A message once begun is written to its end. A node that takes a first
word and is then removed leaves its writer with error 18.
- The messages waiting are finite, 400 cells: a node that is passing on
for a stuck node keeps what is for it until that node is killed, and
with no room left refuses what comes, telling the sender.
### 7c.5 Acceptance
@@ -577,7 +602,8 @@ a node may offer a word on each of its ports at once.)*
5. *Hera.* Waiting to begin a message to a stuck node, she is typed to:
the line that waited ends "Interrupted", and the new line, which kills
the stuck node, is done.
6. *An empty port.* An offer to a port with nothing on it is error 18.
6. *An empty port.* Text that begins a message on a port with nothing on
it ends in error 18.
7. *Nothing deadlocks.* The flood of section 7a's test, 800 messages
among three nodes, comes to rest.
8. *Nothing else changes.* POST 538 of 538, the existing tests, and one
@@ -1195,7 +1221,41 @@ Each is tested, committed and pushed before the next.
8. *Nothing else changes.* POST 538 of 538, the existing tests, and the
same hashes on all six systems.
**6d. The wait (section 7c).** Ruled 2026-10-07; not built.
**6d. The wait (section 7c).** Ruled 2026-10-07. **Built 2026-10-08.**
- *The engine* (`v4/src/node.c`, `fabric.c`): the offer addresses and
the wait; the fabric hands an offer over in one step; a node told
there is nothing on a port it offered on. Removed: the console
release of 7b.6, a device's `pending`, the count of words since a
look.
- *The nucleus* (`v4/capsule/core.v4`, `quit.v4`): `(OFFERS)`, `(GATE)`;
`(IDLE)` as in 7c.3, with `(MINE?)`, `(FWD-SET)`, `(FWD-GO)`,
`(PAY-SET)`, `(PAY-GO)`; `(FINISH)` and `GONE` put what they send with
the messages waiting; `AWAIT` goes on passing on and paying. The
lower-number rule, the looking again, `(PASS-ON)` and `(PAY)` are
gone. The ports moved in the nucleus's map to make room.
- *The lone node* (`v4/system/boot.c`): an offer is served as a write.
- *Found while it was built, and mended, each with a check that failed
first:* a message passed on toward a stuck node held the node passing
it on (7c.3); a node waited on a stuck sender to give it its answer;
with answers queued, a line typed during a wait was done before the
earlier line's answer had gone; a node with two answers it could not
give began no text; `KILL` waited to tell a stuck node, and a typed
line then left the rest untold; removing a node raised "No one on
that port" on the unrelated text of a neighbour with something
queued for it (7c.2). Two commits on the way were wrong as pushed:
`482cc75f` (the first of these) and `1c720ab2` (pushed with
`hosted-check` failing); `35378372` and `ec817a82` mend them.
- *Tests.* `test_fabric.c` 104 checks: acceptance 1, 2, 3, 6, and the
ring, the same-step and the asleep cases. `test_host_mesh.c` 127:
acceptance 4 for a creditor of either number, two refusals owed,
order kept through a node passing on, a waiting node passing on, a
line that waits and is typed to, and 7. `test_host_unit.c` 84:
acceptance 5; a node with answers for two stuck senders; `KILL` with
another node stuck.
- *Verified.* `make -C v4 test` and `sanitize` at both widths,
`hosted-check`, lint; three bare-metal boots, `logs/20261008-011558`
(amd64), `-011833` (aarch64), `-012159` (riscv64). On all six: POST
538 of 538, `word_count=317`, `dict_hash=0x6a39c0bb9d183418`.
7. **A second unit; scaling while running; sleep, wake and kill by
command.**