docs(v4.0.0): step 6c -- refusals and waits: rulings, design, acceptance and plan
MESH.md 7b: no message is lost without its sender being told, and no node waits for ever. What v3 does, from the code, and what could not be established. A refusal travels back as a NACK; Hera ends a wait on a stuck node by killing it and tells the others it is gone; a line from the console breaks a wait. Step 6c has the acceptance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a425f738a4
commit
6e1ac157c6
@@ -294,6 +294,108 @@ that was to start a node sending). Six from each to each, at once, all
|
||||
arrive. Nothing here makes a sender slow down or send again; that is
|
||||
kernel-Hermes's work in v3 and is not decided for the mesh.
|
||||
|
||||
## 7b. Refusals and waits (ruled 2026-10-07)
|
||||
|
||||
**The rule of this section: no message is lost without its sender being
|
||||
told, and no node waits for ever.** It closes two defects found in what
|
||||
was built: a message arriving at a node with no room for it was dropped
|
||||
and counted, and its sender never knew; and a node waiting for an answer
|
||||
(`AWAIT`) waited for ever if none came. Captain Bob: "no bad code is ever
|
||||
released".
|
||||
|
||||
**v3, as built** (`kernel/include/starkernel/vm/kernel_hermes.h`,
|
||||
`kernel/src/vm/kernel_hermes.c`; `FABRIC-3.5.md` XLIII, XLV):
|
||||
|
||||
- Sending never blocks the sender: kernel-Hermes copies the message into
|
||||
its own pool and queues it for the target, which drains its own queue.
|
||||
- A send that cannot be accepted is refused to the sender at once, with
|
||||
nothing changed: `sk_hermes_send_one` returns failure "on any refusal
|
||||
(bound, reservoir, arena, or destination queue full)".
|
||||
- Nobody waits on a message for an answer. What Hera needs done in another
|
||||
VM now she does with `VM-EXEC`, which the kernel runs there directly.
|
||||
- "A deny is a NACK", message type 23; in the code it is sent in one place,
|
||||
refusing a private-channel request.
|
||||
- Not established from the code: what becomes of messages queued for a VM
|
||||
that is killed; and any live path that expires a queued message (there
|
||||
is a `ttl` field, set to 0, and a decay function called only by boot
|
||||
self-tests).
|
||||
|
||||
**Scope (ruled):** only what closes the two defects. Heat and its ledger,
|
||||
channels, and the ACL question on opening a channel stay for the later
|
||||
step named in section 3; a message still carries its heat, TTL and ACL
|
||||
tag, and nothing acts on them.
|
||||
|
||||
### 7b.1 The rulings
|
||||
|
||||
1. **A refusal travels back as a NACK.** A node that has no room for a
|
||||
message, or is asked to pass one on and knows no way to where it is
|
||||
going, tells the node the message came from. In v3 the sender is
|
||||
refused at once; here the sender may be several nodes away and has
|
||||
finished writing, so the refusal has to travel.
|
||||
2. **Hera ends a wait on a node that is alive and never answers, by
|
||||
killing it.** Only Hera decides a node is gone, as in v3. There is no
|
||||
clock and no time limit.
|
||||
3. **A line from the console breaks a wait.** It is the one way to end
|
||||
Hera's own wait, when she is waiting on a node during a birth or a send.
|
||||
|
||||
### 7b.2 The messages
|
||||
|
||||
Two types, beside text (1), output (2) and done (3):
|
||||
|
||||
| Type | Text | Meaning |
|
||||
|---|---|---|
|
||||
| 4, NACK | one word: a node's number | your message for that node was refused |
|
||||
| 5, GONE | one word: a node's number | that node is gone |
|
||||
|
||||
### 7b.3 A node that cannot take a message, or pass it on
|
||||
|
||||
- It reads the message to its end and counts it in `(LOST)`, as before.
|
||||
- It notes that it owes a NACK, to the message's sender and about the node
|
||||
the message was for. It sends what it owes when it next has nothing else
|
||||
to do: the moment it finds it has no room is the moment it is taking
|
||||
messages in so as to be free to write (section 7a), and it cannot begin
|
||||
a message of its own there.
|
||||
- A NACK or a GONE that cannot be taken or passed on is dropped and
|
||||
counted, and nothing is owed for it: there is no NACK for a NACK.
|
||||
- Part of the queue is kept for NACK and GONE alone, so that ordinary
|
||||
messages cannot take the last of the room.
|
||||
|
||||
### 7b.4 A node that is sent a NACK or a GONE
|
||||
|
||||
- If it is waiting for an answer from that node (`AWAIT`), the wait ends
|
||||
in an error: 19 "Message refused", or 20 "Node gone".
|
||||
- If it is not, a NACK is counted in `(REFUSED)`, and a GONE makes it
|
||||
forget the way to that node.
|
||||
- It acts on a GONE only if it came by the port that leads to everything
|
||||
the node has no other way to — its centre — so that only Hera can
|
||||
declare a node gone. Hera herself has no such port and sends them.
|
||||
|
||||
### 7b.5 Hera
|
||||
|
||||
- She keeps a table of the nodes she has had born: number and place.
|
||||
- `KILL ( n -- )`: she asks the kernel to remove node *n*, forgets her own
|
||||
way to it, and sends GONE about it to every other node in her table.
|
||||
(`KILL` is v3's word and meaning; v3's takes a name, and a mesh node has
|
||||
a number. Ruled 2026-10-07. `SLEEP`, `WAKE` and a second unit are step
|
||||
7.)
|
||||
|
||||
### 7b.6 Breaking a wait from the console
|
||||
|
||||
- Text from the console that reaches a node while it waits for an answer
|
||||
ends the wait in error 21, "Interrupted". The text is then interpreted
|
||||
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.
|
||||
|
||||
### 7b.7 Limits
|
||||
|
||||
- The room kept for NACK and GONE is finite, and so is the list of NACKs
|
||||
a node owes. Past them one is dropped and counted in `(LOST)`. A sender
|
||||
left waiting by that is ended as any stuck wait is: by Hera, or from the
|
||||
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).
|
||||
|
||||
## 8. Storage
|
||||
|
||||
**Ruled 2026-10-06 and 2026-10-07** (Captain Bob). On 2026-10-07 he found
|
||||
@@ -819,6 +921,28 @@ Each is tested, committed and pushed before the next.
|
||||
6. *The suite.* `make -C v4 test` and `sanitize` pass at both widths;
|
||||
`mkcapsule --lint capsules/` is clean.
|
||||
|
||||
**6c. Refusals and waits (section 7b).** Acceptance, approved
|
||||
2026-10-07:
|
||||
1. *No room.* A node's queue is filled; the next message for it is
|
||||
refused, and the sender's `(REFUSED)` count rises by one. A sender
|
||||
that was waiting has its line end "Message refused".
|
||||
2. *No way.* A message for a node nobody has a way to comes back as a
|
||||
NACK in the same way.
|
||||
3. *Killed.* Hera kills a node. A node that was waiting on it, and is
|
||||
not its neighbour, has its line end "Node gone". Afterwards no node
|
||||
has a way to it.
|
||||
4. *Stuck.* A node waits on a node stuck in a loop. Hera kills the
|
||||
stuck node and the wait ends.
|
||||
5. *Hera's own wait.* Hera waits on a stuck node. A line typed at the
|
||||
console ends her wait with "Interrupted", and that line, which kills
|
||||
the stuck node, is then run.
|
||||
6. *The products.* Hosted and bare metal: `5 AWAIT` followed by another
|
||||
line gives "Interrupted" and then runs that line.
|
||||
7. *More refusals than room.* The extra NACK is dropped and counted in
|
||||
`(LOST)`; nothing else goes wrong.
|
||||
8. *Nothing else changes.* POST 538 of 538, the existing tests, and the
|
||||
same hashes on all six systems.
|
||||
|
||||
7. **A second unit; scaling while running; sleep, wake and kill by
|
||||
command.**
|
||||
8. **The hosted product is the five nodes**, on three ISAs: acceptance 1
|
||||
|
||||
Reference in New Issue
Block a user