FABRIC-3.md: close console-VM + user-VM async relay (§F.22)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b0f12710bb
commit
c9cf9b09d9
+70
@@ -2890,3 +2890,73 @@ console at all in this build — `(do-log-info)` compiles and runs without error
|
|||||||
nothing visible. Not chased; didn't block verification since `ZUSE-SESSION?` gave a direct
|
nothing visible. Not chased; didn't block verification since `ZUSE-SESSION?` gave a direct
|
||||||
answer instead of needing the log line. With this closed, the console-VM + user-VM pair
|
answer instead of needing the log line. With this closed, the console-VM + user-VM pair
|
||||||
(§F.20's own opening vision) is unblocked.
|
(§F.20's own opening vision) is unblocked.
|
||||||
|
|
||||||
|
### F.22 — console-VM + user-VM pair: real async message relay
|
||||||
|
|
||||||
|
§F.20's opening vision picked up: a general-purpose console attaching to any VM with ACL
|
||||||
|
access (`BINDSTEP`, §F.9 — unchanged, stays the cheap direct/admin path) *and* a genuinely
|
||||||
|
new console-VM + user-VM pair talking over real messages, the actual next step toward
|
||||||
|
"message-passing OS." Two shapes were on the table — synchronous `VM-EXEC` relay (low
|
||||||
|
latency, still built on the same primitive real messages use) vs. fully async `MSG-SEND`/
|
||||||
|
`MSG-DELIVER` (architecturally purer, costs the idle-pump's cadence per round trip). **Chosen:
|
||||||
|
Option B, fully async** — confirmed directly: messaging is a general capability every VM
|
||||||
|
already has for its own reasons, not something that should get a console-specific shortcut
|
||||||
|
bolted on beside it.
|
||||||
|
|
||||||
|
**Traced before building** (`vm_interpret()`, `vm.c`/`vm_core.c`): it's pure C, per-line, no
|
||||||
|
per-VM hook for "redirect this whole line elsewhere" — a console that turns keystrokes into
|
||||||
|
messages can't be a new vocabulary alone, it needs an actual new C-level REPL mode. Tracing
|
||||||
|
`MSG-SEND`/`MSG-DELIVER` (Phase C) also confirmed the addressing model already works for this:
|
||||||
|
whichever VM calls `MSG-SEND` both stores the message *and* later delivers it (via its own
|
||||||
|
`MSG-TICK`), and `VM-EXEC` copies the string bytes across the VM boundary at delivery time —
|
||||||
|
so a console VM messaging its paired user VM is exactly the same shape every other message in
|
||||||
|
this system already uses, no new plumbing needed.
|
||||||
|
|
||||||
|
**Built:** new `CONSOLE-CMD-EVENT` message type (`common:messaging.4th`). New
|
||||||
|
`sk_repl_dispatch_line()` (`repl.c`), replacing the direct `vm_interpret()` call in both
|
||||||
|
`sk_repl_step`/`sk_repl_run`: if the active VM's own name has a live `"<name>~user"`
|
||||||
|
counterpart registered, the raw line is wrapped as an `S"`-embedded `CONSOLE-CMD-EVENT
|
||||||
|
MSG-SEND` and interpreted on the console VM instead of run directly — delivery happens later,
|
||||||
|
on that console's own next `MSG-TICK` (Hera's idle pump), via `VM-EXEC` into the paired user
|
||||||
|
VM, identically to every other message. Falls back to direct interpretation with no pairing,
|
||||||
|
or if the line contains a `"` (can't be safely `S"`-embedded yet — a known v1 limitation,
|
||||||
|
warned about explicitly rather than silently mishandled, not chased further this pass).
|
||||||
|
|
||||||
|
New `capsule_console_birth()` (`capsule_console.h/.c`): a bare VM whose only content is
|
||||||
|
loading `common:messaging.4th` — parallel in shape to `RUNCAP`'s user-VM birth but with fixed
|
||||||
|
embedded source instead of a devblock read (no identity, no thumbdrive involved on the
|
||||||
|
console side at all). New `PAIR-TEST` diagnostic word (matches `RUNCAP-TEST`'s own precedent
|
||||||
|
exactly): births both halves and registers the `"<name>~user"` mapping. Not the real pairing
|
||||||
|
call site — that's the eventual attach/onboarding flow — exists to exercise the relay live
|
||||||
|
before that flow exists.
|
||||||
|
|
||||||
|
**A real, serious bug found and fixed live, not assumed away:** `console_set_vm_name()`
|
||||||
|
stored the caller's raw pointer, never copied it. `mama_word_use()` (`USE`) passes a
|
||||||
|
`VMRegistryEntry` field living on its own stack frame — once `USE` returns, that pointer
|
||||||
|
dangles, corrupting the console tag on every subsequent line. Observed directly as garbled
|
||||||
|
`"[[]"` / binary-looking prefixes instead of `"[CaptBob]"` — not a theoretical concern, this
|
||||||
|
broke the very relay mechanism being tested, since `sk_repl_dispatch_line()` reads the same
|
||||||
|
name to find the pairing. Fixed at the source: `console_set_vm_name()` now copies into
|
||||||
|
internal storage. That fix surfaced a **second, related** bug: every `console_get_vm_name()`-
|
||||||
|
based save/restore call site in `mama_forth_words.c` (`BIRTH`, `VM-STEP`, `VM-EXEC`,
|
||||||
|
`CONNECT-HERMES`, `CONNECT-ARTEMIS`) saved only a pointer into that same single internal
|
||||||
|
buffer — an intervening `console_set_vm_name()` call silently corrupted the saved value
|
||||||
|
before the restore ever ran. New `console_save_vm_name()` copies into caller-owned storage;
|
||||||
|
every save/restore site updated to use it.
|
||||||
|
|
||||||
|
**Verified end-to-end, live, not just build-clean:** typed `WELCOME` at a paired console
|
||||||
|
VM — it did not execute directly (no `UNKNOWN WORD`), printed `ok` immediately (queued,
|
||||||
|
genuinely async), and on the *next* idle tick `"[CaptBob~user] Minted identity -- default
|
||||||
|
personality"` appeared on its own — real delivery and execution in the paired user VM through
|
||||||
|
the actual `MSG-SEND`/`MSG-DELIVER` pipeline, not a shortcut standing in for it. Console tags
|
||||||
|
confirmed clean (no garbling) across all three architectures' full regression boot; Hermes/
|
||||||
|
Artemis both birth live, zero unexpected ACL denials or `UNKNOWN WORD`. Commit `b0f1271`.
|
||||||
|
|
||||||
|
**Still open:** the real pairing call site (`PAIR-TEST` is diagnostic scaffolding only, not
|
||||||
|
meant to survive into a real attach flow); the `"` character in a relayed line (falls back to
|
||||||
|
direct interpretation with a warning, not fixed this pass); the idle-pump's ~1s cadence is
|
||||||
|
the console's own round-trip latency for every command now — acceptable for v1 per the
|
||||||
|
async-over-synchronous decision, but a real UX question for later if it proves too slow in
|
||||||
|
practice; whether a console VM should get a default subscription to `COMMON-CH` (skipped in
|
||||||
|
v1 — direct 1:1 console↔user traffic doesn't need it, and it would require resolving an index
|
||||||
|
in Hermes's own routing table for a VM that doesn't have one yet).
|
||||||
|
|||||||
Reference in New Issue
Block a user