fix(v4): a killed node's children become Hera's; Review Focus 4 checked

From the final review of MESH step 7.  NODE-KILL left children whose parent
was the dead number, so a node born later under it inherited authority over
them; they are re-parented to Hera.  After UNIT-KILL Hera no longer lists the
removed centre, and a later KILL completes (shown to fail with GONE-DOWN's
unlisting taken out).  test_manage 45/45 both widths; test_host_unit 127/127.

Acceptance: amd64, aarch64, riscv64 clean qemu: ok>, POST 538/538,
dict_hash=0x248b4edc47f4357e on all three; test-32 0 failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-16 20:03:45 -04:00
co-authored by Claude Opus 5.5
parent 9382df69e5
commit 7ad02bf72f
10 changed files with 497 additions and 3 deletions
+2 -1
View File
@@ -25,7 +25,8 @@
* -11 NODE-WAKE ( number -- ) Hera
* -12 NODE-KILL ( number -- ) Hera; not herself; a number not
* live does nothing. The node's
* children are not removed, as v3.
* children are not removed, as v3,
* and become Hera's children.
* -13 NODE-PARITY ( place number -- ) for a node the asker birthed,
* under the number it was born as
* -14 CAPSULE-OPEN ( baddr u -- flag ) any node in the registry: the
+5 -1
View File
@@ -109,9 +109,13 @@ int v4_manage_serve(const v4_manage *m, unsigned place, v4_cell request)
if (request == V4_REQ_NODE_SLEEP) v4_fabric_sleep(m->f, e->place);
else if (request == V4_REQ_NODE_WAKE) v4_fabric_wake(m->f, e->place);
else {
unsigned gone_place = e->place;
unsigned gone_place = e->place, k;
v4_cell gone_number = e->number;
v4_fabric_node *was = v4_fabric_remove(m->f, gone_place);
e->number = 0;
/* its children are not removed (as v3) and become Hera's: a number that is not live is no one's
* parent, so a node born later under it inherits nothing (the final review of step 7) */
for (k = 0; k < m->reg_cap; k++) if (m->reg[k].number != 0 && m->reg[k].parent == gone_number) m->reg[k].parent = me->number;
if (was && m->gone) m->gone(m->self, gone_place, was);
}
return 1;
+5
View File
@@ -717,6 +717,11 @@ int main(void)
CHECK(node_numbered(10)->mem[LOST] == hera_lost && node_numbered(11)->mem[LOST] == 0 && node_numbered(13)->mem[LOST] == 0 && node_numbered(14)->mem[LOST] == 0
&& waiting(10) && waiting(11) && waiting(13) && waiting(14), "nothing was let go in all of this, and all wait again: Hera %ld (%ld before)",
(long)node_numbered(10)->mem[LOST], (long)hera_lost);
/* Review Focus 4 (the final review of step 7): after UNIT-KILL no node still lists a removed node as its
* child -- the next KILL would tell it, and with no way to it that would be an error. */
CHECK(strcmp(tell(10, "20 (WHICH) ."), "-1 ") == 0, "Hera no longer lists node 20 among the nodes she birthed: \"%s\"", printed);
CHECK(told(10, "14 KILL") && node_numbered(14) == NULL && strcmp(tell(13, "1 2 + ."), "3 ") == 0,
"and a KILL after UNIT-KILL tells only the nodes there are: it completes, and the rest go on: \"%s\"", printed);
printf(" %d checks, %d failures\n", checks, failures);
return failures != 0;
+10 -1
View File
@@ -151,7 +151,16 @@ int main(void)
r = birth(a, 13);
CHECK(r >= 0, "node 11 births 13");
push(h, 11);
CHECK(v4_manage_serve(&m, h, V4_REQ_NODE_KILL) == 1 && place_of(h, 13) == r && child(h, 11, 0) == 13, "killing 11 does not kill its child, as in v3");
CHECK(v4_manage_serve(&m, h, V4_REQ_NODE_KILL) == 1 && place_of(h, 13) == r, "killing 11 does not kill its child, as in v3");
CHECK(child(h, 11, 0) == 0 && child(h, 10, 0) == 13, "its child is Hera's now: no number that is not live is anyone's parent");
{
/* A NUMBER USED AGAIN INHERITS NOTHING (the final review of step 7): a node born later as 11 is not
* the parent of the 13 the old 11 birthed, and may not wire it. */
v4_cell again = birth(h, 11), r13 = r;
CHECK(again >= 0 && child(h, 11, 0) == 0, "Hera births a new 11: it has no children");
push((unsigned)again, again); push((unsigned)again, 3); push((unsigned)again, r13); push((unsigned)again, 2);
CHECK(refused((unsigned)again, V4_REQ_NODE_WIRE) && depth((unsigned)again) == 0, "and may not wire the old 11's child");
}
CHECK(place_of(h, 12) == -1 && place_of(h, 10) == (v4_cell)h, "NODE-PLACE of a number not live is -1");
printf(" %d checks, %d failures\n", checks, failures);