Scope VM fault halt to the faulting identity's own session (FABRIC-3.md §XI.4)
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

A standalone WIREBIND identity (no Zuse, USE'd in directly) hitting an
ACL-denied word halted the entire machine -- Hera, Hermes, Artemis, all
of it -- instead of just that identity's own session. sk_fault_handler()
was being called unconditionally on whichever VM's ->error was set, with
no distinction between Hera's own root session (where "no fallthrough
surface" is the correct, deliberate fail-closed behavior) and a
USE'd-in guest identity (which should recover and resume at its own
prompt instead of taking the fleet down with it).

Both call sites (sk_repl_step, sk_repl_run) now compare the faulting VM
against Hera before deciding: Hera's own session still halts by design;
any other VM prints a recovery message, clears its fault state, and
continues.

Also: mint identities 01-06 with the same FORTH-79/83 restricted
personality identity 00 already had, verified via the fixed fault
scoping above (which this verification pass surfaced).

Verified live on amd64 (both the Hera-halts and identity-recovers
branches); three-arch clean qemu acceptance passed (riscv64's first
attempt hit an unrelated virtio_blk I/O timeout hang, a known QEMU/TCG
flake -- a clean retry booted normally).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ec88YKxxhZGG1RNnune78
This commit is contained in:
Robert Allan James
2026-09-09 20:41:51 -04:00
co-authored by Claude Sonnet 5
parent 9bcc70647b
commit d6661b5eed
27 changed files with 72093 additions and 5 deletions
+46 -4
View File
@@ -1165,8 +1165,19 @@ int sk_repl_step(VM *vm)
/* Wired 2026-09-05: sk_fault_handler() existed but was never
* called from here -- the "halts VM on error" half of this
* function's own doc comment was aspirational, not real, until
* now. Real for the headless-until-login default. */
sk_fault_handler(vm);
* now. Real for the headless-until-login default.
*
* FABRIC-3.md, 2026-09-09: scoped to Hera's own session only --
* see sk_repl_run()'s matching fix (and its own doc comment) for
* why a non-mama target must recover instead of halt here too. */
if (vm == (VM *)sk_get_mama_vm()) {
sk_fault_handler(vm);
} else {
console_println("VM fault -- session recovered, resuming");
vm->error = 0;
vm->halted = 0;
vm->abort_requested = 0;
}
#endif
} else {
console_puts(" ok\n");
@@ -1253,8 +1264,39 @@ void sk_repl_run(VM *vm)
active->error = 0;
#else
/* Wired 2026-09-05, same as sk_repl_step()'s matching branch
* above -- sk_fault_handler() existed but was never called. */
sk_fault_handler(active);
* above -- sk_fault_handler() existed but was never called.
*
* FABRIC-3.md, 2026-09-09: live-caught -- a standalone
* WIREBIND identity (no Zuse involved at all, USE never
* typed) hitting a denied word halted the *entire machine*,
* not just that identity's own session. Root cause: this
* loop's own exit condition (`while (!vm->halted)` above)
* checks vm -- Hera, the loop's original owner -- but
* sk_fault_handler() was being called on `active`, which
* capsule_wirebind's own attach flow had already redirected
* to the new identity's own VM (sk_repl_set_active_vm()) by
* the time any command could be typed. Setting active->halted
* left Hera's own vm->halted untouched -- the loop kept
* running -- but every subsequent iteration kept re-selecting
* the same now-halted, never-recovering `active`, producing
* no further output and no further progress: a de facto full
* freeze despite Hera's own loop technically still spinning.
* Captain Bob, 2026-09-09: "scope the halt to just that
* identity's session gracefully and restart the session or
* resume it." Hera's own direct session (active == vm) keeps
* the strict "no fallthrough surface" halt -- a fault in the
* root console is a genuine full-system emergency -- but any
* redirected (WIREBIND/USE'd) identity's own fault now
* recovers instead: clear the fault state and let that same
* identity keep going at its own prompt next iteration. */
if (active == vm) {
sk_fault_handler(active);
} else {
console_println("VM fault -- session recovered, resuming");
active->error = 0;
active->halted = 0;
active->abort_requested = 0;
}
#endif
} else {
console_puts(" ok\n");