Make Hermes and Artemis session-less fleet foundation, add STARTUP-BANNER
Per FABRIC-3.md D.7 (birth-by-message-only): the Tripod legs must be alive session-less before any thumbdrive-attach flow has a running Hermes/Artemis to message. kernel_main.c's item 4.2/4.6 self-tests previously birthed both, exercised diagnostics, then explicitly KILLed them before ok> every boot -- production boot never actually kept either alive. Stripped both blocks down to birth-only, diagnostics and KILL removed. Found and fixed a real regression this surfaced, not left broken: Hermes's CD-INIT (message/channel arena init, and the thing that loads lib.4th into her own dictionary) was only ever invoked by the self-test just removed -- nothing in hermes/init.4th itself called it. Added an unconditional CD-INIT call at the end of her own init.4th so a real birth actually initializes her arena, matching how Artemis's own ART-BOOT-ENTRY already runs unconditionally at her own capsule load. Added STARTUP-BANNER (lib.4th): a shared word reading a common IDENTITY-BANNER buffer, printing "(no identity)" until CERTVERIFY/MINT exist to populate it from a thumbdrive's PKI fields -- scaffolding only, per direct instruction. Wired into each Tripod leg's own init.4th (Hera/Hermes/Artemis); Artemis didn't load lib.4th before, added that too. Verified live on all three architectures: BIRTH for both, no KILL anywhere in any log, and an interactive USE round-trip confirmed Hermes is genuinely reachable post-boot, not just logged as born. 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
ad79caeeeb
commit
52eb1bbb20
+20
-160
@@ -176,30 +176,6 @@ static void print_uint(const char *label, uint64_t value) {
|
||||
console_println(buf);
|
||||
}
|
||||
|
||||
#ifdef STARFORTH_ENABLE_VM
|
||||
/**
|
||||
* @brief Verify a known word is still reachable in a VM's dictionary.
|
||||
*
|
||||
* Diagnostic-only: confirms @c vm_find_word() can still walk the chain
|
||||
* from @c vm->latest to a word defined early in Hermes's capsule
|
||||
* (MSG-COOL-ALL, block 4108). Added after item 4.2's self-test bisection
|
||||
* found an amd64-only in-place corruption of an existing dictionary entry
|
||||
* during MSG-DELIVER-ALL -- here/latest stay unchanged (no reallocation),
|
||||
* so a lookup is a cheap signal. NOTE: an earlier version of this comment
|
||||
* attributed the corruption to GDB perturbing execution timing; that is
|
||||
* unconfirmed and more likely just a parity/dict-hash boot-gate failure
|
||||
* triggered by the debugger session itself (a software breakpoint's 0xCC
|
||||
* patch landing in memory the loader then overwrote) -- don't propagate
|
||||
* "timing-sensitive" as an established finding.
|
||||
*/
|
||||
static void hermes_dict_check(VM *hermes_vm, const char *checkpoint) {
|
||||
DictEntry *e = vm_find_word(hermes_vm, "MSG-COOL-ALL", 12);
|
||||
console_puts(" Dict-check ");
|
||||
console_puts(checkpoint);
|
||||
console_println(e ? ": OK" : ": FAIL (MSG-COOL-ALL unreachable)");
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Print a boot-information summary from the UEFI memory map to the console.
|
||||
*
|
||||
@@ -837,157 +813,41 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/* item 4.2 self-test: a REAL birth (not synthetic, unlike 4.1a's --
|
||||
* this exercises capsules/hermes/init.4th's actual migrated code),
|
||||
* exercised then killed again so the resting boot state stays
|
||||
* Hera-alone, per item 0.1's intent. Diagnostic only -- production
|
||||
* boot still never auto-births Hermes (init.4th's BIRTH stays
|
||||
* commented out). */
|
||||
console_println("Hermes 4.2 migration self-test: birthing...");
|
||||
/* Hermes is now a permanent fleet-foundation VM, not self-test
|
||||
* scaffolding -- FABRIC-3.md D.7 (birth-by-message-only, 2026-08-28):
|
||||
* the Tripod legs (Hera/Hermes/Artemis) must be alive session-less so
|
||||
* a later thumbdrive-attach flow has a running Hermes/Artemis to
|
||||
* message. Previously born, exercised, and KILLed by item 4.2's own
|
||||
* self-test every boot; that diagnostic exercising is gone, only the
|
||||
* birth remains. */
|
||||
console_println("Startup: birthing Hermes (fleet foundation)...");
|
||||
vm_interpret(mama, "S\" Hermes\" BIRTH");
|
||||
{
|
||||
VMRegistryEntry entry;
|
||||
if (capsule_vm_find_by_name_nocase("Hermes", &entry) == 0 &&
|
||||
entry.state == VM_STATE_LIVE) {
|
||||
VM *hermes_vm = (VM *)entry.vm_ptr;
|
||||
console_println("Hermes 4.2 self-test: exercising migrated words...");
|
||||
hermes_dict_check(hermes_vm, "at self-test start");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "CD-INIT");
|
||||
print_uint(" DBG err after CD-INIT=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after CD-INIT");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-MSG-TEST . CR");
|
||||
print_uint(" DBG err after MSG-TEST=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after MSG-TEST");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-STATUS");
|
||||
print_uint(" DBG err after STATUS=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after STATUS");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-DELIVER-ALL");
|
||||
print_uint(" DBG err after DELIVER-ALL=", (uint64_t)hermes_vm->error);
|
||||
hermes_dict_check(hermes_vm, "after DELIVER-ALL");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-REDELIVER-NACKED");
|
||||
print_uint(" DBG err after REDELIVER=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-COOL-ALL");
|
||||
print_uint(" DBG err after MSG-COOL-ALL=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "MSG-REAP");
|
||||
print_uint(" DBG err after MSG-REAP=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "CH-COOL-ALL CH-REAP-SAFE");
|
||||
print_uint(" DBG err after CH-COOL/REAP=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "Q.1 3 / COMMON-CH @ CH-HEAT!");
|
||||
print_uint(" DBG err after CH-HEAT!=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "HERMES-STATUS");
|
||||
print_uint(" DBG err after TICK=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
console_puts("Hermes 4.2 self-test: HERMES-K=");
|
||||
vm_interpret(hermes_vm, "HERMES-K .");
|
||||
console_println("");
|
||||
print_uint(" DBG err after HERMES-K=", (uint64_t)hermes_vm->error);
|
||||
/* Side-by-side with the Stadium's own view, same checkpoint --
|
||||
* if these two disagree, HERMES-K's FORTH-side arena scan is
|
||||
* seeing different residents than stadium_resident_sum()'s
|
||||
* ownership+bitmap view (a real, separate finding, not the
|
||||
* Q.SLOT admission-heat fix's job to explain). */
|
||||
print_uint(" DBG stadium_resident_sum(Hermes)=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" DBG stadium_reservoir_peek(Hermes)=", stadium_reservoir_peek(entry.vm_id));
|
||||
/* item 4.2 Done-when: "a resident cell's evict-credit landing
|
||||
* in the correct VM's reservoir ... not just asserted from
|
||||
* reading the code" -- explicitly evict the common channel
|
||||
* (CH-FREE-NODE -> STADIUM-EVICT), a known resident from
|
||||
* CD-INIT's own COMMON-INIT, same credit path stadium_admit()'s
|
||||
* density-fallback eviction uses. resident_sum dropping and
|
||||
* reservoir rising by the same amount is the proof: the freed
|
||||
* cell's heat landed back in Hermes's own reservoir, not lost
|
||||
* or credited to Hera. */
|
||||
console_println("Hermes 4.2 self-test: before eviction:");
|
||||
print_uint(" Hermes resident_sum=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Hermes reservoir=", stadium_reservoir_peek(entry.vm_id));
|
||||
console_println("Hermes 4.2 self-test: forcing an explicit eviction (COMMON-CH)...");
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "COMMON-CH @ . CR");
|
||||
print_uint(" DBG err after COMMON-CH@=", (uint64_t)hermes_vm->error);
|
||||
hermes_vm->error = 0;
|
||||
vm_interpret(hermes_vm, "COMMON-CH @ CH-FREE-NODE");
|
||||
print_uint(" DBG err after CH-FREE-NODE=", (uint64_t)hermes_vm->error);
|
||||
console_println("Hermes 4.2 self-test: after eviction:");
|
||||
print_uint(" Hermes resident_sum=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Hermes reservoir=", stadium_reservoir_peek(entry.vm_id));
|
||||
/* item 4.2 Done-when: both VMs' conservation checks close
|
||||
* independently -- Hermes's own resident+reservoir sum first,
|
||||
* then Hera's again (unaffected by Hermes's activity above). */
|
||||
stadium_words_print_boot_diagnostics(entry.vm_id);
|
||||
vm_interpret(mama, "S\" Hermes\" KILL");
|
||||
console_println("Hermes 4.2 self-test: killed, resting state restored");
|
||||
stadium_words_print_boot_diagnostics(vm_uuid_hera());
|
||||
console_println("Startup: Hermes live");
|
||||
} else {
|
||||
console_println("Hermes 4.2 self-test: birth registry lookup FAILED");
|
||||
console_println("Startup: Hermes birth registry lookup FAILED");
|
||||
}
|
||||
}
|
||||
|
||||
/* item 4.6 self-test: a REAL birth (not synthetic), exercising
|
||||
* capsules/artemis/init.4th's actual migrated block-heat code.
|
||||
* Artemis's own capsule already runs a full self-test plus a
|
||||
* 30-rep stress campaign at load (ART-BOOT-ENTRY / block 4170's
|
||||
* still-enabled ART-STRESS-CAMPAIGN) -- this scaffold only adds
|
||||
* the conservation-check bracketing item 4.2's Hermes self-test
|
||||
* used, not a duplicate exercise. Diagnostic only -- production
|
||||
* boot still never auto-births Artemis (init.4th's BIRTH stays
|
||||
* commented out). */
|
||||
console_println("Artemis 4.6 migration self-test: birthing...");
|
||||
/* Artemis is now a permanent fleet-foundation VM, not self-test
|
||||
* scaffolding -- same reasoning as Hermes's own birth just above
|
||||
* (FABRIC-3.md D.7). Previously born, exercised, and KILLed by item
|
||||
* 4.6's own self-test every boot; that diagnostic exercising is gone,
|
||||
* only the birth remains. Artemis's own capsule still runs its own
|
||||
* self-test plus a 30-rep stress campaign at load
|
||||
* (ART-BOOT-ENTRY/ART-STRESS-CAMPAIGN), unaffected by this change. */
|
||||
console_println("Startup: birthing Artemis (fleet foundation)...");
|
||||
vm_interpret(mama, "S\" Artemis\" BIRTH");
|
||||
{
|
||||
VMRegistryEntry entry;
|
||||
if (capsule_vm_find_by_name_nocase("Artemis", &entry) == 0 &&
|
||||
entry.state == VM_STATE_LIVE) {
|
||||
VM *artemis_vm = (VM *)entry.vm_ptr;
|
||||
console_println("Artemis 4.6 self-test: ARTEMIS-K after boot-time load:");
|
||||
artemis_vm->error = 0;
|
||||
vm_interpret(artemis_vm, "ARTEMIS-K .");
|
||||
console_println("");
|
||||
print_uint(" DBG err after ARTEMIS-K=", (uint64_t)artemis_vm->error);
|
||||
print_uint(" DBG stadium_resident_sum(Artemis)=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" DBG stadium_reservoir_peek(Artemis)=", stadium_reservoir_peek(entry.vm_id));
|
||||
|
||||
/* item 4.6 Done-when: "a resident cell's evict-credit landing
|
||||
* in the correct VM's reservoir", same check 4.2 made for
|
||||
* Hermes. Allocate one fresh block explicitly, confirm the
|
||||
* reservoir/resident split, free it, confirm both settle
|
||||
* back the same way. */
|
||||
console_println("Artemis 4.6 self-test: explicit alloc/free round-trip...");
|
||||
artemis_vm->error = 0;
|
||||
vm_interpret(artemis_vm, "BLK-ALLOC DUP . CR");
|
||||
print_uint(" DBG err after BLK-ALLOC=", (uint64_t)artemis_vm->error);
|
||||
print_uint(" Artemis resident_sum (post-alloc)=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Artemis reservoir (post-alloc)=", stadium_reservoir_peek(entry.vm_id));
|
||||
artemis_vm->error = 0;
|
||||
vm_interpret(artemis_vm, "BLK-FREE");
|
||||
print_uint(" DBG err after BLK-FREE=", (uint64_t)artemis_vm->error);
|
||||
print_uint(" Artemis resident_sum (post-free)=", stadium_resident_sum(entry.vm_id));
|
||||
print_uint(" Artemis reservoir (post-free)=", stadium_reservoir_peek(entry.vm_id));
|
||||
|
||||
console_println("Artemis 4.6 self-test: ARTEMIS-K after round-trip:");
|
||||
artemis_vm->error = 0;
|
||||
vm_interpret(artemis_vm, "ARTEMIS-K .");
|
||||
console_println("");
|
||||
|
||||
/* item 4.6 Done-when: both VMs' conservation checks close
|
||||
* independently -- Artemis's own resident+reservoir sum
|
||||
* first, then Hera's again (unaffected by Artemis's
|
||||
* activity above). */
|
||||
stadium_words_print_boot_diagnostics(entry.vm_id);
|
||||
vm_interpret(mama, "S\" Artemis\" KILL");
|
||||
console_println("Artemis 4.6 self-test: killed, resting state restored");
|
||||
stadium_words_print_boot_diagnostics(vm_uuid_hera());
|
||||
console_println("Startup: Artemis live");
|
||||
} else {
|
||||
console_println("Artemis 4.6 self-test: birth registry lookup FAILED");
|
||||
console_println("Startup: Artemis birth registry lookup FAILED");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user