revert(v4.0.0): step 6d, the wait, is backed out -- two reviews found it unsound

Ruled 2026-10-08.  The engine, the nucleus and their tests are as they
were at dfabfa46, before step 6d; the code of the wait and its tests are
in history at 075385ab..2cf37aab.  The limit of MESH.md 7b.7 stands: a
node that is stuck can hold up its neighbours until Hera kills it.

MESH.md 7c is kept as the record of the design as approved, and 7c.6 says
what was built, what the two reviews found, the cause the findings share
-- a node's message machinery runs on the stacks its text is using, and a
fault abandons whatever was in progress -- and what a second attempt
must settle before anything is built.

Kept from it, in hosted-check: a line that leaves 29 values on the stack,
and WORDS with 26 values on it.  Both hung the products at some commit of
the wait.

make -C v4 test and sanitize at both widths, hosted-check, lint; three
bare-metal boots typing both.  POST 538 of 538, word_count=317,
dict_hash=0xc0769523a47b7dc3 on all six: the hash of step 6c's code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-08 07:31:40 -04:00
co-authored by Claude Opus 5.5
parent 10f5ffd00b
commit 6015c87157
20 changed files with 1108 additions and 1203 deletions
+8 -50
View File
@@ -43,9 +43,6 @@
#define V4_PORTS 8u
#endif
#define V4_PORT_ANY V4_PORTS /* not a port: "whichever port has a neighbour writing" */
#define V4_PORT_OFFER (V4_PORTS + 4u) /* not a port: the offer on port 0; the offer on port k is k further (the wait, below) */
#define V4_PORT_WAIT (2u * V4_PORTS + 4u) /* not a port: the wait */
#define V4_PORT_WAIT1 (2u * V4_PORTS + 5u) /* not a port: the wait for an offer only */
#ifndef V4_NODE_WORDS
#define V4_NODE_WORDS 1024u
@@ -114,10 +111,7 @@ typedef struct {
unsigned last_from; /* the port the last read from "any" took its word from */
unsigned writers; /* bit k: the neighbour on port k is blocked writing to this node */
unsigned readers; /* bit k: the neighbour on port k is blocked reading from this node */
unsigned offers; /* bit k: a word is offered on port k (the wait: docs/v4.0.0/MESH.md 7c) */
v4_cell offer[V4_PORTS]; /* the words offered */
int waiting; /* non-zero: the read it is blocked in is the wait */
int offer_asked; /* non-zero: `asking` stands for the offer on `ask_port` (v4_node_offer_as_write) */
unsigned since_look; /* words taken from this node since it last fetched either of those */
/* DSTACK-DEPTH and RSTACK-DEPTH (D-16). See v4_node_stack_regs_attach. */
v4_cell dstack_reg; /* its word address, or -1 */
@@ -225,6 +219,13 @@ void v4_node_port_attach(v4_node *n, v4_cell base);
/* The neighbour has taken what the node wrote. */
void v4_node_port_served(v4_node *n);
/* How many words the node has had taken since it last looked at its
* neighbours (a fetch of either of the two status addresses). A node that
* looks before it begins a message (MESH.md 7a) and is blocked writing with
* this at 0 is blocked on the first word of the message: nothing of it has
* gone. */
unsigned v4_node_words_since_look(const v4_node *n);
/* THERE IS NO ONE ON THE PORT the node is blocked at -- writing to it, or
* reading from that one port -- and there will not be. A node that can
* take an error (it has an error register and a fault table: node.h,
@@ -235,49 +236,6 @@ void v4_node_port_served(v4_node *n);
* that is not blocked at a port, or is reading "any port". */
int v4_node_port_gone(v4_node *n, v4_cell code);
/* THE WAIT (docs/v4.0.0/MESH.md 7c). After the addresses above come
* base + V4_PORT_OFFER + k the offer on port k: a store here is the word
* the node offers to write to that port. It is
* remembered and waits for nothing.
* base + V4_PORT_WAIT the wait: a fetch here blocks the node until a
* word comes for it on any port, or one of its
* offers is taken, whichever is first.
* base + V4_PORT_WAIT1 the wait for an offer only: as the wait, but
* a word that comes for the node does not end
* it, and a writer to the node is not served.
* It is how the words of a message after the
* first are written by a node that must not be
* faulted if its reader is removed.
* A store to the wait withdraws every offer and waits for nothing.
* A word that came is fetched as from "any port", and "which port" says
* where from. When an offer was taken the fetch gives 0 and "which port"
* gives V4_PORTS + k: the offer on port k. When there turns out to be
* nothing on a port it has an offer on, the fetch gives 0 and "which
* port" gives 2 * V4_PORTS + k. Whichever, every offer the node had is
* withdrawn. Whoever connects the ports does the handing over
* (fabric.h); a node in the wait is blocked reading "any port" as far as a
* writer to it can tell.
*
* 1 if the node is blocked in the wait with nothing given yet. */
int v4_node_in_wait(const v4_node *n);
/* The offer on port k has been taken: the node is unblocked and will fetch
* 0, from V4_PORTS + k. 0 if it is not in the wait or has no offer there. */
int v4_node_offer_taken(v4_node *n, unsigned k);
/* There is nothing on port k, where the node has an offer: a node in the
* wait that can take an error (v4_node_port_gone says which can) is
* unblocked and will fetch 0, from 2 * V4_PORTS + k. No error is raised:
* what the node does about it is its own to say. 0 if it was not done. */
int v4_node_offer_gone(v4_node *n, unsigned k);
/* For a host with one node, whose devices always take what is written: if
* the node is in the wait with an offer, it becomes a blocked write of the
* word offered on the lowest such port -- asking, request, ask_port -- and
* v4_node_port_served then completes the wait as v4_node_offer_taken would.
* 1 if it did. */
int v4_node_offer_as_write(v4_node *n);
/* The neighbour on `port` writes `value`: the node, blocked reading that
* port or "any", is unblocked and will fetch it. */
void v4_node_port_give(v4_node *n, unsigned port, v4_cell value);