FABRIC-3.md: close emergency-CLI retirement + thumbdrive Zuse (§F.21)

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 16:11:23 -04:00
co-authored by Claude Sonnet 5
parent cc9521d2cc
commit 71b6937deb
+83
View File
@@ -2807,3 +2807,86 @@ first-boot mint routed through `MINT` onto a thumbdrive, block-fence flow retire
CLI removed) is scoped in direction but not yet traced against the actual boot-sequence code
the way `RUNCAP`/`MINT` themselves were before being built (§F.18/§F.19's own discipline) —
that trace-first pass is the next step, not this one.
**Update:** `disk/zuse.img`/`disk/user1.img` committed after this section closed, per direct
instruction. The bigger swap traced and built in §F.21, same pass.
### F.21 — emergency CLI retired; Zuse goes thumbdrive-resident; ACL.4th activated
The trace §F.20 asked for, done before touching code (same discipline as §F.18/§F.19):
`vm->emergency_console` is not a boot-time flag, it's recomputed on *every* REPL iteration
(`repl.c`, both `sk_repl_step` and `sk_repl_run`): `is_hera && !zuse_session → 1`, and when
set it skips ACL enforcement entirely at both the colon-word dispatch point and the outer
EXECUTE path (`vm_core.c`). A real finding this trace surfaced: `capsules/init.4th` had
`ACL.4th`'s own load commented out all session — ACL enforcement was **inactive**, bypass or
no bypass, the whole time, because the policy engine that would ever deny anything had never
loaded. Removing the bypass alone would have changed nothing observable.
**Design, confirmed with Captain Bob before building:** system-resident storage keeps only
Zuse's *public* key, never her seed — the fence remembers "a root identity exists" and what
its pubkey is; the private key lives exclusively on her own minted thumbdrive. New
`zuse_genesis_marker_t` (magic/version/`zuse_pubkey[32]`/crc) takes over the fence's
devblock 0 slot `zuse_cert_devblock_t` used to occupy; that type is kept in the repo, header
marked superseded, no longer written by any path.
**Genesis can't use regular `MINT`** — there's no existing Zuse to sign a cert with yet.
`capsule_mint_identity()` grows a genesis mode: `issuer_vm=NULL` skips the cert build/write
entirely (`cert_offset`/`cert_devblocks` stay 0) and skips the `zuse_cert_installed` check.
Two new optional out-params, `out_pubkey`/`out_seed`, let the caller (genesis's only caller)
install the cert immediately after minting — the seed otherwise never leaves the thumbdrive.
**A real boot-ordering constraint, not assumed away:** `virtio_rng_init()` already precedes
the old Zuse block, and `xhci_bringup()` already precedes `sk_repl_run()` — no reorder was
actually needed. What matters instead: USB attach detection only ever happens inside
`sk_repl_idle()`'s own polling, which doesn't exist yet at kernel_main.c's old one-shot mint
point. So the genesis/attach logic can't be a boot-time step at all, regardless of ordering —
it has to live in the idle loop. New `capsule_zuse_boot_try_attach()` (`capsule_zuse_boot.c`),
called from `sk_repl_idle()` on every fresh attach: no-ops if Zuse already has a cert this
boot; no marker + `HOMEBLOCKS_SIG_BLANK` → genesis-mint, write the marker; marker present +
`HOMEBLOCKS_SIG_OK` + matching pubkey → read the drive's own `user_identity_seed_t`, install
the cert. Either path ends the same way: `vm_zuse_cert_install()` then
`vm_interpret(mama_vm, "ACL-ZUSE-BOOT")` — re-running the *existing* self-activation word
rather than adding new C-side auth logic (`ACL-PIN` only blocks redefinition, not
re-execution, so calling the same policy word again later is the correct, already-designed
way to activate `zuse_session` once a cert exists later than boot).
**A real, previously-dormant bug, found the moment `ACL.4th` actually loaded for the first
time:** `zuse.4th`'s `ACL-ZUSE-BOOT` tried `['] ACL-ZUSE-BOOT ACL-PIN` from *inside its own
still-compiling definition* — the word isn't findable via `['] ` at that point (mid-compile),
so the whole colon-definition silently failed to compile, every boot, for as long as
`ACL.4th` has existed in this repo — just never noticed because nothing ever loaded it.
Fixed: pin *after* the definition closes (`: ACL-ZUSE-BOOT ... ;` then, separately, `[']
ACL-ZUSE-BOOT ACL-PIN`) — it only ever needs to run once anyway, and pinning doesn't block
the re-invocation genesis/attach depends on.
**The bypass itself, removed:** the `emergency_console = is_hera ? ... : 0` assignment
deleted from both `repl.c` call sites. Every word run from Hera's own bare prompt now goes
through ordinary ACL enforcement. `emergency_console` the *field* still exists and is still
set, briefly, by the genuine C-level VM fault handler (`EMERGENCY_CONSOLE_ENABLED`) — a
distinct, narrower mechanism this REPL no longer touches.
**Verified end-to-end, live, not just build-clean:** added `ZUSE-SESSION?` (read-only
diagnostic, matches `ZUSE-PUBKEY@`'s own precedent) to check the chain directly rather than
by inference. Fresh boot, no thumbdrive attached: `ZUSE-SESSION?` reads `0`. Attach a
genuinely blank drive via QMP: genesis mint fires automatically, no typing, console confirms
it; `ZUSE-SESSION?` then reads `-1` (true) — the complete chain (genesis mint → cert install
→ `ACL-ZUSE-BOOT` re-run → `ZUSE-AUTHENTICATE` → `zuse_session=1`) verified working, not
assumed. Clean 3-architecture regression: Hermes/Artemis both birth live, zero ACL denials,
zero `UNKNOWN WORD` beyond the deliberate POST self-test cases (`NOSUCH`/`NONEXISTENT`/
`__acl_deny_test__`) — the first time this whole session `ACL.4th` has actually been
enforcing anything, and nothing broke. Commit `cc9521d`.
**Still open, deliberately not chased in this pass:** the fence marker write itself still
fails ("fence marker write FAILED (not persistent)") — the same pre-existing, already-flagged
anomaly this session has seen with the old block-fence write path too (§ various), now
manifesting through the new marker write instead. Doesn't block same-boot activation (that
reads the freshly-generated data in memory, not the fence), but means the "already minted"
marker doesn't actually survive a reboot in this QEMU test environment yet — the
attach-authenticate path (marker present, matching drive reattached later) is designed and
built but not yet live-verified across a real reboot, blocked on this separate write-path
issue. A second, unrelated, general finding while testing: `LOG-INFO"` output from *any*
FORTH-defined colon-word body (tested standalone, unrelated to Zuse) doesn't appear on the
console at all in this build — `(do-log-info)` compiles and runs without error, just prints
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
(§F.20's own opening vision) is unblocked.