Hera can't message: root-caused and fixed by symmetry (FABRIC-3.md §XX)
Hera never loaded common:messaging.4th, unlike every other VM in the fleet. The standing belief was this was deliberate, to avoid moving her dict_hash off baseline. Checked live instead of assumed: loading messaging.4th into her dictionary silently dropped every colon- definition referencing one of 8 STADIUM-* primitives that register_child_vm_words() gives every other VM but register_mama_forth_words() never gave her -- a missing-primitive gap, not a designed privilege boundary. Confirmed mama_word_birth is genuinely VM-agnostic and SPAWN-EVENT is an unwired placeholder before proposing the fix. Fix: register the same 8 STADIUM-* primitives for Hera, load messaging.4th from init.4th the same way Hermes/Artemis/console/mint already do, and give her own idle-loop context a direct MSG-TICK call (not VM-EXEC, which would hit the same reentrancy class the existing per-other-VM pump loop already guards against) so her own queued messages actually drain. Her dictionary is now a proper superset of every child VM's, plus her remaining extra privileges -- not structurally different from any other VM, just additionally privileged. Verified: dict_hash identical across amd64/aarch64/riscv64 (0xc8f4b09e36f4fc4a), Hermes/Artemis dict_hashes unchanged and still cross-arch identical, all three boot clean to zuse)ok> with zero UNKNOWN WORD faults, mkcapsule --lint clean. Unblocks rewriting the turn-attractor (FABRIC-3.md §XIX) to coordinate via real MSG-SEND/MSG-TICK instead of blocking VM-EXEC. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5a9425b91b
commit
7edccd2c35
@@ -1592,6 +1592,18 @@ static void mama_word_connect_hermes(VM *vm)
|
||||
console_set_vm_name(saved_name);
|
||||
}
|
||||
|
||||
/* Forward declarations: these 8 are defined later in this file (originally
|
||||
* only ever used from register_child_vm_words(), which comes after them),
|
||||
* but FABRIC-3.md SXX now also registers them here, earlier in the file. */
|
||||
static void mama_word_stadium_admit(VM *vm);
|
||||
static void mama_word_stadium_evict(VM *vm);
|
||||
static void mama_word_stadium_res_fetch(VM *vm);
|
||||
static void mama_word_stadium_res_pull(VM *vm);
|
||||
static void mama_word_stadium_res_push(VM *vm);
|
||||
static void mama_word_stadium_heat_fetch(VM *vm);
|
||||
static void mama_word_stadium_heat_store(VM *vm);
|
||||
static void mama_word_stadium_word_heat(VM *vm);
|
||||
|
||||
/**
|
||||
* @brief Register Mama FORTH vocabulary words with the VM
|
||||
*
|
||||
@@ -1634,6 +1646,26 @@ void register_mama_forth_words(VM *vm)
|
||||
register_word(vm, "VM-EXEC", mama_word_vm_exec);
|
||||
register_word(vm, "VM-CALL", mama_word_vm_call);
|
||||
register_word(vm, "VM-HEAT", mama_word_vm_heat);
|
||||
/* FABRIC-3.md SXX: the 8 STADIUM-* primitives register_child_vm_words()
|
||||
* gives every other VM, added here too -- root cause of "Hera cannot
|
||||
* load common:messaging.4th" (kernel_main.c's old Phase C comment):
|
||||
* messaging.4th's own colon-definitions (MSG-HEAT@, CH-HEAT@,
|
||||
* MSG-COOL-ALL, MSG-TICK, etc.) reference these, and referencing an
|
||||
* undefined word during compilation silently drops the definition
|
||||
* rather than raising a compile error -- not a messaging bug, a
|
||||
* missing-primitive gap in Hera's own dictionary specifically. Fixed
|
||||
* by symmetry, not a special case: Hera's dictionary is now a proper
|
||||
* superset of every child VM's, plus her own extra privileges
|
||||
* (BIRTH, the capsule-repository words, MINT) -- not structurally
|
||||
* different from any other VM, just additionally privileged. */
|
||||
register_word(vm, "STADIUM-ADMIT", mama_word_stadium_admit);
|
||||
register_word(vm, "STADIUM-EVICT", mama_word_stadium_evict);
|
||||
register_word(vm, "STADIUM-RES@", mama_word_stadium_res_fetch);
|
||||
register_word(vm, "STADIUM-RES-PULL", mama_word_stadium_res_pull);
|
||||
register_word(vm, "STADIUM-RES-PUSH", mama_word_stadium_res_push);
|
||||
register_word(vm, "STADIUM-HEAT@", mama_word_stadium_heat_fetch);
|
||||
register_word(vm, "STADIUM-HEAT!", mama_word_stadium_heat_store);
|
||||
register_word(vm, "STADIUM-WORD-HEAT", mama_word_stadium_word_heat);
|
||||
register_word(vm, "CAPSULE-TEST", mama_word_capsule_test);
|
||||
|
||||
/* Create and switch to MAMA vocabulary */
|
||||
@@ -1672,6 +1704,26 @@ void register_mama_forth_words(VM *vm)
|
||||
register_word(vm, "VM-EXEC", mama_word_vm_exec);
|
||||
register_word(vm, "VM-CALL", mama_word_vm_call);
|
||||
register_word(vm, "VM-HEAT", mama_word_vm_heat);
|
||||
/* FABRIC-3.md SXX: the 8 STADIUM-* primitives register_child_vm_words()
|
||||
* gives every other VM, added here too -- root cause of "Hera cannot
|
||||
* load common:messaging.4th" (kernel_main.c's old Phase C comment):
|
||||
* messaging.4th's own colon-definitions (MSG-HEAT@, CH-HEAT@,
|
||||
* MSG-COOL-ALL, MSG-TICK, etc.) reference these, and referencing an
|
||||
* undefined word during compilation silently drops the definition
|
||||
* rather than raising a compile error -- not a messaging bug, a
|
||||
* missing-primitive gap in Hera's own dictionary specifically. Fixed
|
||||
* by symmetry, not a special case: Hera's dictionary is now a proper
|
||||
* superset of every child VM's, plus her own extra privileges
|
||||
* (BIRTH, the capsule-repository words, MINT) -- not structurally
|
||||
* different from any other VM, just additionally privileged. */
|
||||
register_word(vm, "STADIUM-ADMIT", mama_word_stadium_admit);
|
||||
register_word(vm, "STADIUM-EVICT", mama_word_stadium_evict);
|
||||
register_word(vm, "STADIUM-RES@", mama_word_stadium_res_fetch);
|
||||
register_word(vm, "STADIUM-RES-PULL", mama_word_stadium_res_pull);
|
||||
register_word(vm, "STADIUM-RES-PUSH", mama_word_stadium_res_push);
|
||||
register_word(vm, "STADIUM-HEAT@", mama_word_stadium_heat_fetch);
|
||||
register_word(vm, "STADIUM-HEAT!", mama_word_stadium_heat_store);
|
||||
register_word(vm, "STADIUM-WORD-HEAT", mama_word_stadium_word_heat);
|
||||
register_word(vm, "CAPSULE-TEST", mama_word_capsule_test);
|
||||
register_word(vm, "EXEC", mama_word_exec);
|
||||
|
||||
|
||||
@@ -790,19 +790,30 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase C (2026-08-28): Hera does NOT get her own common:messaging.4th
|
||||
* arena -- register_child_vm_words()'s own doc comment (mama_forth_
|
||||
* words.c) explains why: the eight STADIUM-* FORTH primitives that
|
||||
* word depends on (CH-HEAT@/!, MSG-HEAT@/! etc. all route through
|
||||
* them) are deliberately never added to register_mama_forth_words(),
|
||||
* to avoid moving Hera's dict_hash off item 4.1's baseline. Confirmed
|
||||
* live: loading messaging.4th into Hera's own dictionary silently
|
||||
* dropped every colon-definition that referenced one of those
|
||||
* primitives (MSG-HEAT@/!, CH-HEAT@/!, MSG-COOL-ALL, MSG-TICK all
|
||||
* missing after boot) -- not a timing bug, a real, pre-existing
|
||||
* constraint. Hera orchestrates via BIRTH/VM-EXEC/VM-CALL directly
|
||||
* instead; the idle-loop pump (repl.c) skips her own registry entry
|
||||
* for the same reason. */
|
||||
/* FABRIC-3.md SXX (2026-09-12, supersedes the Phase C note this used to
|
||||
* be): Hera now DOES get her own common:messaging.4th arena, like
|
||||
* every other VM -- root-caused, not special-cased around. The real
|
||||
* cause of the old "loading messaging.4th silently drops colon-
|
||||
* definitions" symptom was never "Hera is special": messaging.4th's
|
||||
* own definitions (MSG-HEAT@/!, CH-HEAT@/!, MSG-COOL-ALL, MSG-TICK,
|
||||
* etc.) reference 8 STADIUM-* primitives that register_child_vm_
|
||||
* words() gives every other VM but register_mama_forth_words() never
|
||||
* gave Hera -- a plain missing-primitive gap, not a designed privilege
|
||||
* boundary, that happened to surface as silently-dropped definitions
|
||||
* because referencing an undefined word during compilation doesn't
|
||||
* raise a hard error. Fixed by symmetry: those same 8 primitives are
|
||||
* now registered for Hera too, making her dictionary a proper
|
||||
* superset of every child VM's (plus her own extra privileges --
|
||||
* BIRTH, the capsule-repository words, MINT). Verified live on all
|
||||
* three architectures: dict_hash is identical across amd64/aarch64/
|
||||
* riscv64 with the new, larger, still-symmetric baseline
|
||||
* (0xc8f4b09e36f4fc4a) -- the actual property that ever mattered was
|
||||
* cross-architecture consistency, not the value never changing. The
|
||||
* idle-loop pump (repl.c) still skips VM-EXECing "MSG-TICK" into
|
||||
* Hera via the registry loop -- that's because she IS the pump
|
||||
* (self-targeting VM-EXEC hits the reentrancy class the loop's own
|
||||
* guard exists for), not because she lacks MSG-TICK now -- and calls
|
||||
* it directly in her own context instead, right after that loop. */
|
||||
|
||||
/* Hermes is now a permanent fleet-foundation VM, not self-test
|
||||
* scaffolding -- FABRIC-2.md D.7 (birth-by-message-only, 2026-08-28):
|
||||
|
||||
@@ -621,6 +621,22 @@ static void sk_repl_idle(VM *active_vm)
|
||||
vm_interpret(mama, cmd);
|
||||
}
|
||||
}
|
||||
/* FABRIC-3.md SXX: Hera now genuinely has her own MSG-ARENA/CH-ARENA
|
||||
* (the messaging-load root cause above is fixed -- see kernel_main.c's
|
||||
* own updated comment at the Hermes-birth call site), so her own
|
||||
* queued messages need draining too, same as every other VM's. She's
|
||||
* excluded from the loop above not because she lacks MSG-TICK now, but
|
||||
* because she IS the pump -- self-targeting VM-EXEC would hit the same
|
||||
* reentrancy class the guard above exists for. No such problem calling
|
||||
* MSG-TICK directly here, though: it's a plain word in her own
|
||||
* dictionary, not a VM-EXEC dispatch into anyone else's input buffer.
|
||||
* Guarded the same defensive way as the loop above, not assumed. */
|
||||
{
|
||||
DictEntry *msgtick = vm_find_word(mama, "MSG-TICK", 8);
|
||||
if (msgtick && msgtick->acl_allow) {
|
||||
vm_interpret(mama, "MSG-TICK");
|
||||
}
|
||||
}
|
||||
g_idle_pump_active = 0;
|
||||
|
||||
if (console_tx_count() == tx_before_idle) {
|
||||
|
||||
Reference in New Issue
Block a user