Fix EXEC/LOAD block-persistence gap and WIREBIND/USE interpreter-race panic (FABRIC-3.md §XII)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

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:
Robert Allan James
2026-09-10 16:07:38 -04:00
co-authored by Claude Sonnet 5
parent d5722986b2
commit 662ef44e59
13 changed files with 36605 additions and 7 deletions
+14 -4
View File
@@ -72,8 +72,11 @@ int capsule_load_blocks(const uint8_t *payload, uint64_t length,
* capsule_clear_blocks - Zero all ramdrive slots referenced in a capsule payload
*
* Re-parses the payload for "Block <num>" headers and zeros each
* corresponding 1024-byte ramdrive slot. Called after execution to
* reclaim ramdrive space.
* corresponding 1024-byte ramdrive slot. NOT called by capsule_exec_init()
* (fixed 2026-09-10 -- see its own doc comment): callers that specifically
* want a capsule's block range freed for reuse (e.g. kernel_main.c, right
* after Mama's own init.4th birth, to free that range for interactive
* block-editor use) call this themselves, explicitly, after exec returns.
*
* @param payload Raw capsule payload bytes
* @param length Payload length in bytes
@@ -94,13 +97,20 @@ void capsule_clear_blocks(const uint8_t *payload, uint64_t length);
int capsule_exec_payload(void *vm_opaque, const uint8_t *payload, uint64_t length);
/**
* capsule_exec_init - Load, execute, and clean up an init capsule
* capsule_exec_init - Load and execute an init capsule
*
* Full init sequence:
* 1. Locate capsule by colon-separated name in the capsule directory
* 2. Validate content hash
* 3. capsule_exec_payload: populate block device + execute content
* 4. Zero block slots for userspace (capsule_clear_blocks)
*
* Block content is NOT cleared afterward (fixed 2026-09-10): it stays
* resident in ramdrive storage so a subsequent Standard BLOCK/LOAD on the
* same block number reads back what EXEC just wrote, matching FORTH-79
* block-persistence semantics. Callers that specifically want the old
* "free this capsule's block range" behavior (e.g. kernel_main.c freeing
* init.4th's range for later interactive block-editor use) call
* capsule_clear_blocks() themselves, explicitly, after this returns.
*
* @param vm VM to execute on
* @param capsule_name Colon-separated capsule name, e.g. "init.4th"