Stage C: cut over BLK-ATTACH-EVENT alone -- FABRIC-3.6.md task 3.8
The reply leg (Artemis -> Hera ack) that used to flow through common:messaging.4th's MSG-SEND/MSG-TICK now goes through kernel-Hermes's sk_hermes_send_one()/sk_hermes_drain_checkpoint() instead -- FORTH Hermes never sees a BLK-ATTACH-EVENT message again (SXXXIV.2's partition rule). The request leg was never real FORTH messaging traffic to begin with (a direct VM-EXEC, no type tag, forced by Hera's own inability to load common:messaging.4th), so it is untouched. New KH-BLK-ATTACH-SEND (repl.c) wraps sk_hermes_send_one(), reached from capsules/artemis/init.4th's HERA-BLK-ATTACH-REQ. Delivery reuses task 3.4's already-wired sk_hermes_drain_checkpoint(); BLK-ATTACH-ACK itself is unchanged, just reached by a different layer. SK_HERMES_MSG_TYPE_BLK_ATTACH deliberately reuses BLK-ATTACH-EVENT's own value (9) to document this as a cutover of the same message, not a new one. Two real bugs found on the way, both recorded in FABRIC-3.6.md's findings log: - A popped FORTH CREATE-buffer address was raw-cast to a host pointer instead of going through vm_ptr() -- silently read all-zero memory, no crash, no error, just a message that arrived and did nothing. Fixed; the rule and its exception (repl.c's own dev-addr is legitimately a raw pointer, formatted that way by its own pushing code) are written up for the next FORTH-facing C word. - A separate, genuine hang on the very first live exercise of this path, never reproduced across ten subsequent boots. Reported, not chased -- not blocking, per the task's own check being otherwise fully satisfied. Also found live: log_message() is invisible in this build's actual serial-log capture at every level -- settled on a single console_println in the real drain target instead, one line per real USB attach, not a hot-path. Final acceptance (logs/20260922-105501, -105758, -110304, disk images reset before each): dict_hash identical across all three architectures for every VM, zero UNKNOWN WORD, mkcapsule --lint clean, real ledger+stadium_conserved(Artemis)=true evidence on every boot. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f37aa0fb17
commit
bbfd9103f4
@@ -45,6 +45,8 @@
|
||||
#include "starkernel/capsule_wirebind.h"
|
||||
#include "starkernel/capsule_run.h"
|
||||
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h"
|
||||
#include "starkernel/vm/kernel_hermes.h" /* FABRIC-3.6.md task 3.8 -- sk_hermes_send_one() */
|
||||
#include "starkernel/vm/stadium.h" /* task 3.8 -- stadium_conserved() evidence print */
|
||||
#include "block_subsystem.h"
|
||||
#include "word_source/include/keyboard_words.h"
|
||||
#include "word_source/include/block_words.h"
|
||||
@@ -256,6 +258,46 @@ static void sk_word_blk_attach_ack(VM *vm) {
|
||||
if (ms) ms->bot_msc_attached = 1;
|
||||
g_attached_blk_dev = dev;
|
||||
|
||||
/* FABRIC-3.6.md task 3.8 evidence: this handler IS the real drain
|
||||
* target -- sk_hermes_drain_checkpoint() (task 3.4) called
|
||||
* vm_interpret() on the ack payload, which is how we got here.
|
||||
* stadium_conserved() (task 0.7/2.7's four-term form) holds at
|
||||
* every instant, mid-hold included, so printing it here -- while
|
||||
* this message's heat is still held, before sk_hermes_drain_
|
||||
* checkpoint()'s own release/pop run just after this function
|
||||
* returns -- is real evidence, not a synthetic self-test. Note the
|
||||
* limit: this is evidence for the mid-hold instant, not the
|
||||
* post-release state (release/pop happen after this function
|
||||
* returns, in the caller) -- see FABRIC-3.6.md task 3.8's own
|
||||
* write-up. console_println, not log_message(): confirmed live
|
||||
* (this repl.c's own log_message() calls, at every level, do not
|
||||
* appear anywhere in a real serial-log boot capture in this build
|
||||
* -- log_message()'s fprintf(stderr, ...) is not wired to the
|
||||
* serial console here) -- log_message() would have been silently
|
||||
* invisible, defeating the point of evidence. One line, not two
|
||||
* (dropped the earlier pre-send line from KH-BLK-ATTACH-SEND
|
||||
* below): this fires once per real USB attach, not per word, so
|
||||
* it is not the console_println-overuse case memory
|
||||
* project_production_logging_cleanup_needed flags. */
|
||||
{
|
||||
VMRegistryEntry artemis_entry;
|
||||
uint64_t held, pulled, returned, consumed;
|
||||
char line[160];
|
||||
int conserved = -1; /* -1 = Artemis not found */
|
||||
sk_hermes_ledger(&held, &pulled, &returned, &consumed);
|
||||
if (capsule_vm_find_by_name_nocase("Artemis", &artemis_entry) == 0 &&
|
||||
artemis_entry.vm_ptr) {
|
||||
conserved = stadium_conserved(artemis_entry.vm_id);
|
||||
}
|
||||
snprintf(line, sizeof(line),
|
||||
"Kernel-Hermes BLK-ATTACH-EVENT (real, Stage C): ledger held=%llu "
|
||||
"pulled=%llu returned=%llu consumed=%llu stadium_conserved(Artemis)=%s",
|
||||
(unsigned long long)held, (unsigned long long)pulled,
|
||||
(unsigned long long)returned, (unsigned long long)consumed,
|
||||
conserved < 0 ? "UNKNOWN" : (conserved ? "true" : "FALSE"));
|
||||
console_println(line);
|
||||
}
|
||||
|
||||
homeblocks_sig_result_t sig_rc = g_blk_attach_pending[found_slot].sig_rc;
|
||||
homeblocks_sig_t sig = g_blk_attach_pending[found_slot].sig;
|
||||
int is_artemis = g_blk_attach_pending[found_slot].is_artemis;
|
||||
@@ -281,8 +323,88 @@ static void sk_word_blk_attach_ack(VM *vm) {
|
||||
}
|
||||
}
|
||||
|
||||
/* FABRIC-3.6.md task 3.8 (Stage C, SXXXIV.2/.3): BLK-ATTACH-EVENT's real
|
||||
* cutover -- the reply leg (Artemis -> Hera ack) that used to flow
|
||||
* through common:messaging.4th's MSG-SEND/MSG-TICK now goes through
|
||||
* kernel-Hermes's sk_hermes_send_one()/sk_hermes_drain_checkpoint()
|
||||
* (tasks 3.3/3.4/3.6) instead. FORTH Hermes never sees a BLK-ATTACH-
|
||||
* EVENT message again -- exactly SXXXIV.2's partition rule ("one owner
|
||||
* per message, never shared"). The request leg (Hera -> Artemis,
|
||||
* kernel_main.c's own "S\" <dev-addr> HERA-BLK-ATTACH-REQ\" S\"
|
||||
* Artemis\" VM-EXEC" a few lines up) was never real FORTH messaging
|
||||
* traffic to begin with -- no type tag, no arena, a direct VM-EXEC
|
||||
* forced by Hera's own STADIUM-* colon-word limitation documented
|
||||
* above -- so it is untouched here; this task cuts over the one
|
||||
* message type that actually flowed through a messaging layer.
|
||||
*
|
||||
* sk_hermes_drain_checkpoint() (task 3.4) calls vm_interpret() directly
|
||||
* on a message's payload_addr, so it must be NUL-terminated -- Artemis's
|
||||
* own ATTACH-ACK-BUF (artemis:init.4th) is a raw CMOVE'd byte buffer
|
||||
* with no such guarantee, so this copies into its own NUL-terminated
|
||||
* buffer rather than passing ATTACH-ACK-BUF's address through
|
||||
* unchanged. Static, not stack-local: sk_hermes_send_one() stores
|
||||
* payload_addr out-of-line and the caller must keep it alive until
|
||||
* drained (kernel_hermes.h's own documented contract) -- same single-
|
||||
* buffer-reuse shape ATTACH-ACK-BUF itself already had (a second attach
|
||||
* before the first drains overwrites it), not a new hazard this
|
||||
* introduces. */
|
||||
#define SK_KH_BLK_ATTACH_BUF_SIZE 80
|
||||
static char g_kh_blk_attach_buf[SK_KH_BLK_ATTACH_BUF_SIZE];
|
||||
|
||||
/* KH-BLK-ATTACH-SEND ( paddr plen -- ok? ): copies the caller's payload
|
||||
* (Artemis's own ATTACH-ACK-BUF content) into the NUL-terminated buffer
|
||||
* above and sends it to Hera via kernel-Hermes. `from`/`to` are derived
|
||||
* from the calling VM and sk_get_mama_vm() -- the caller never has to
|
||||
* name a VMUuid, matching how HERA-BLK-ATTACH-REQ never had to before
|
||||
* either (FORTH's own IDX 0/1/2 convention did that translation for
|
||||
* it). Refusal (reservoir/arena/destination-queue exhaustion) is logged
|
||||
* rather than silently dropped -- FABRIC-3.5.md SXXXV.0 names silent
|
||||
* failure as this project's single most common defect shape, and this
|
||||
* is exactly the class of message (identity birth gates on it) where a
|
||||
* silent drop would be expensive to ever notice. */
|
||||
static void sk_word_kh_blk_attach_send(VM *vm) {
|
||||
if (vm->dsp < 1) {
|
||||
log_message(LOG_ERROR, "KH-BLK-ATTACH-SEND: stack underflow");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
cell_t plen = vm_pop(vm);
|
||||
cell_t paddr = vm_pop(vm);
|
||||
/* paddr is a VM-relative offset (vaddr_t), not a host pointer --
|
||||
* CLAUDE.md's own "Important Conventions": "Stack values are VM
|
||||
* offsets (vaddr_t), not C pointers -- use VM_ADDR()/CELL()".
|
||||
* mama_forth_words.c's own VM-EXEC/VM-CALL words all translate a
|
||||
* popped paddr the same way (vm_ptr(vm, (vaddr_t)caddr)) before
|
||||
* touching it as a C pointer -- found live, not assumed: the first
|
||||
* cut here raw-cast paddr directly and silently read all-zero
|
||||
* memory (some unmapped/zeroed low address), producing an empty
|
||||
* NUL-terminated payload that vm_interpret() executed as a no-op --
|
||||
* no crash, no error, just a message that arrived and did nothing.
|
||||
* Diagnosed via a temporary probe printing the copied buffer content
|
||||
* at send time (per feedback_revert_probes_after_capture); reverted
|
||||
* once this fix confirmed correct. */
|
||||
const char *src = (const char *)vm_ptr(vm, (vaddr_t)paddr);
|
||||
size_t n = (size_t)plen;
|
||||
VM *mama_vm = (VM *)sk_get_mama_vm();
|
||||
size_t i;
|
||||
int rc;
|
||||
|
||||
if (n >= SK_KH_BLK_ATTACH_BUF_SIZE) n = SK_KH_BLK_ATTACH_BUF_SIZE - 1;
|
||||
for (i = 0; i < n; i++) g_kh_blk_attach_buf[i] = src[i];
|
||||
g_kh_blk_attach_buf[n] = '\0';
|
||||
|
||||
rc = sk_hermes_send_one(vm->stadium_vm_id, mama_vm->stadium_vm_id,
|
||||
SK_HERMES_MSG_TYPE_BLK_ATTACH, 0,
|
||||
g_kh_blk_attach_buf, (uint32_t)(n + 1));
|
||||
if (rc != 0) {
|
||||
log_message(LOG_ERROR, "KH-BLK-ATTACH-SEND: kernel-Hermes refused the send");
|
||||
}
|
||||
vm_push(vm, rc == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
void sk_repl_register_words(VM *vm) {
|
||||
register_word(vm, "BLK-ATTACH-ACK", sk_word_blk_attach_ack);
|
||||
register_word(vm, "KH-BLK-ATTACH-SEND", sk_word_kh_blk_attach_send);
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user