FABRIC-3.md: close Phase C (messaging capsule + idle pump)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
This commit is contained in:
Robert Allan James
2026-08-28 13:02:58 -04:00
co-authored by Claude Sonnet 5
parent 21bca315ff
commit 75311967a7
+45
View File
@@ -2557,3 +2557,48 @@ Artemis→Hera (birth request); how/whether Console fits into this specific flow
already-scoped `MSGMIGRATE` two-hop; whether `CERTVERIFY` (§F.7) itself should now run as
Artemis-mediated logic rather than a bare function call. Capture only, per this arc's own
established discipline — design happens in its own pass.
### Phase C — distributed messaging capsule + idle-loop pump (CLOSED 2026-08-28)
Prerequisite for D.7's message-only flow: every VM needs its own real `MSG-SEND`/`CH-*`
vocabulary and arena, not just Hermes. Extracted the generic messaging vocabulary (arenas,
field accessors, `MSG-ALLOC`/`CH-ALLOC`, `MSG-SEND`/`MSG-DELIVER`/`MSG-TICK`, `CH-ADD-MBR`,
`MSG-BROADCAST`, ~30 words total) out of `capsules/hermes/init.4th` into a new shared
`capsules/common/messaging.4th` (blocks 50035037). Hermes and Artemis each `EXEC` it at
birth and get their own private `MSG-ARENA`/`CH-ARENA` copy (`CREATE` runs per-VM). Hermes
stays the one owner of the canonical `COMMON-CH`; Artemis subscribes into it via `VM-EXEC`
at her own birth (`2 COMMON-CH @ CH-ADD-MBR` run inside Hermes), and Hermes proactively
subscribes Hera (idx 0) herself since Hera always exists first and can't subscribe to a VM
that doesn't exist yet at her own boot.
**Hera does not get her own copy — a real, discovered constraint, not a design choice.**
First attempt loaded `common:messaging.4th` into Hera's own dictionary too, matching "every
VM that gets born must have all these caps." Live-tested and found broken: every
colon-definition that referenced a `STADIUM-*` primitive (`MSG-HEAT@/!`, `CH-HEAT@/!`,
`MSG-COOL-ALL`, `MSG-TICK` itself) was silently missing from Hera's dictionary after boot —
not a compile error, just absent. Root cause, traced via a live serial socket and isolated
word-by-word: `register_child_vm_words()`'s own doc comment
(`mama_forth_words.c`) explains that the eight `STADIUM-*` FORTH words are deliberately
**never** added to `register_mama_forth_words()`, specifically to keep Hera's own
`dict_hash` off item 4.1's baseline. This is a pre-existing, intentional constraint, not a
timing bug — moving the load later in boot (tried first, also failed) didn't help, because
the words are never registered for Hera at all, at any point. Reverted: Hera orchestrates via
`BIRTH`/`VM-EXEC`/`VM-CALL` directly instead (already proven live — `VM-CALL` querying
Hermes's `MSG-K` cross-VM works fine), and the idle-loop pump below explicitly skips her own
registry entry.
**Idle-loop pump** (`repl.c`'s existing `sk_repl_idle()`, ~1s cadence): added
`capsule_vm_registry_get_by_index()` (`capsule_birth.c`/`.h`) for registry enumeration by
birth-order position (no by-index accessor existed before — only by-`vm_id` and by-name).
Each idle beat, Hera walks every live registry entry except her own and `VM-EXEC`s
`MSG-TICK` into it — "fully distributed, Hera pumps each VM's drain," the design confirmed
before Phase A/B began.
Verified clean (zero `UNKNOWN WORD`/`VM-EXEC: ERROR` after birth, `MSG-STATUS` answering
correctly on both Hermes and Artemis) on all three architectures. Commit `21bca31`.
**Still open, unblocked by this:** `WIREBIND`/`BINDSTEP` rebuilt against real messages
instead of direct calls; `common/msg.4th`'s `HERMES-ACK`/`HERMES-NACK` wrappers are now
obsolete (every VM has its own local `MSG-ACK-LAST`/`MSG-NACK-LAST` — no `VM-EXEC`
indirection needed) but the file itself was left in place, unloaded, rather than deleted
unprompted; `capsules/MANIFEST.md`'s "immutable ABI" claim for block 4055 is now stale.