Fix EXEC/LOAD block-persistence gap and WIREBIND/USE interpreter-race panic (FABRIC-3.md §XII)
Found live while building a cross-ISA FORTH-79 dictionary exerciser: - capsule_exec_init() zeroed a capsule's block content immediately after running it, so LOAD (a genuine FORTH-79 standard word, ACL-allowed even for locked identities) could never actually read back what EXEC had just written. Removed the clear from capsule_exec_init(); block content now persists like any other Standard BLOCK/BUFFER/UPDATE write. kernel_main.c's own explicit post-birth clear of Mama's init.4th range is untouched. - USE could redirect the console to a WIREBIND identity's VM before that VM's vm_enable_interpreter() step of its own birth sequence had run, causing the next typed line to hit vm_assert_interpreter_enabled() and panic the entire machine -- not the per-session-recoverable ACL-fault path a redirected VM otherwise gets. USE now checks interpreter_enabled first and refuses with a retry message instead. Also includes the amd64/aarch64/riscv64 acceptance boot logs and DoE CSVs from this session. 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
d5722986b2
commit
662ef44e59
@@ -581,8 +581,20 @@ CapsuleRunResult capsule_exec_init(
|
||||
const uint8_t *payload = capsule_get_payload(cap, arena);
|
||||
if (!payload) return CAPSULE_RUN_ERR_INVALID;
|
||||
|
||||
/* Unified: populate block device + execute; then free slots for userspace */
|
||||
/* Populate block device + execute. Block content is left in place
|
||||
* afterward -- capsule_exec_payload() already commits it to real
|
||||
* ramdrive storage (write_ramdrive_block()) specifically so FORTH
|
||||
* code can address it by number; a Standard BLOCK/LOAD on that same
|
||||
* number must be able to read back what EXEC just ran, the same way
|
||||
* any other block-storage write persists until something explicitly
|
||||
* overwrites or blanks it. Previously this called capsule_clear_blocks()
|
||||
* here, zeroing the slots immediately after execution -- that made
|
||||
* capsule content invisible to LOAD the instant EXEC returned, which
|
||||
* is not how FORTH-79 BLOCK/LOAD is supposed to behave, and is also
|
||||
* the reason a FORTH-79/83-locked identity (no EXEC in its own
|
||||
* dictionary, see capsules/acl-std79.4th) had no standard-compliant
|
||||
* way to ever load capsule-authored source: LOAD was on the allowlist
|
||||
* but nothing was ever left for it to find. Found and fixed 2026-09-10. */
|
||||
int rc = capsule_exec_payload(vm, payload, cap->length);
|
||||
capsule_clear_blocks(payload, cap->length);
|
||||
return (rc == 0) ? CAPSULE_RUN_OK : CAPSULE_RUN_ERR_EXEC_FAIL;
|
||||
}
|
||||
|
||||
@@ -483,6 +483,22 @@ void mama_word_use(VM *vm)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Found live 2026-09-10: WIREBIND announces "attached and ready --
|
||||
* USE it to begin" the moment the target VM is registered, but
|
||||
* vm_enable_interpreter() is a separate, later step of that same
|
||||
* birth sequence. USE redirecting here before that step lands means
|
||||
* the very next line typed hits vm_assert_interpreter_enabled()
|
||||
* inside vm_interpret() and calls host->panic() -- a hard, whole-
|
||||
* machine halt, not the per-session-recoverable fault path the REPL
|
||||
* loop otherwise gives a redirected VM. Refuse the redirect instead;
|
||||
* the caller can just retry USE a moment later once birth finishes. */
|
||||
if (entry.vm_ptr && !((VM *)entry.vm_ptr)->interpreter_enabled) {
|
||||
console_puts("USE: ");
|
||||
console_puts(name_buf);
|
||||
console_println(" not ready yet -- still bootstrapping, try again");
|
||||
return;
|
||||
}
|
||||
|
||||
/* BINDSTEP (FABRIC-2.md §F.9/§F.24): if the target has a real
|
||||
* installed identity (WIREBIND set this at attach time), re-verify
|
||||
* it against whatever drive is CURRENTLY attached -- live, not
|
||||
|
||||
Reference in New Issue
Block a user