Real per-VM log persistence: source attribution + ACL pin (FABRIC-3.md §XXVII)
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

Wires the previously-unused vm_log_attributed_vm() into LOG-APPEND's kernel
primitive so persisted log records carry a trustworthy source (the real
attributed VM's registry name, or "HADES" pseudo-source) instead of a
caller-supplied, trivially forgeable string. Drops src-addr/src-u from
LOG-APPEND's stack signature accordingly. Pins LOG-APPEND via bare ACL-PIN
in Artemis's own init.4th, matching BIRTH/CAPSULE-BIRTH's precedent for a
privileged word that can't reach the shared, host-portable ACL.4th.

Also fixes two console-banner nitpicks: a mis-rendering em dash (U+2014)
in the boot banner, and drops "Emergency" from the CLI banner text.

Doc corrections to artemis_sig.h/zuse_eligibility_list.h reconciling the
three fixed devblock ranges now in play. LOG-FLUSH (the intended normal
entry point) and level-aware log eviction remain open, flagged not fixed.

Re-verified clean boot to ok> on all 3 architectures after every change.
riscv64 showed one new, unrelated virtio_blk write-timeout anomaly during
Artemis's early physics self-test (self-recovered, boot unaffected,
sector doesn't map to the log region) -- flagged, not investigated.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016UNhH1mhi52i6Qihh7ZV5S
This commit is contained in:
Robert Allan James
2026-09-13 08:56:33 -04:00
co-authored by Claude Sonnet 5
parent 61755fde78
commit 2a30212bd3
28 changed files with 63928 additions and 2051 deletions
+63
View File
@@ -14,6 +14,13 @@
#include "../../include/log.h"
#include <stdint.h>
#ifdef __STARKERNEL__
#include "starkernel/log_region.h"
#include "starkernel/log_attrib.h" /* vm_log_attributed_vm() */
#include "starkernel/capsule_birth.h" /* capsule_vm_registry_get, VMRegistryEntry */
#include <string.h> /* strlen */
#endif
/* ── Level constants ─────────────────────────────────────────────────── */
/** @brief LOG-ERROR ( -- n ) Push the @c LOG_ERROR level constant. */
@@ -188,6 +195,58 @@ static void log_word_test_str (VM *vm) { log_str_emit(vm, LOG_TEST); }
/** @brief LOG-DEBUG-STR ( c-addr u -- ) Log string from stack at DEBUG level. */
static void log_word_debug_str(VM *vm) { log_str_emit(vm, LOG_DEBUG); }
/* ── (LOG-APPEND-RAW) ( level timestamp msg-addr msg-u -- ) ── */
/*
* Kernel-only. Writes one record directly to Artemis's on-disk log ring
* (log_region.c) -- the primitive LOG-APPEND (capsules/artemis/init.4th)
* wraps this with the FORTH-level word name callers actually use.
* Deliberately does NOT call log_message() anywhere in this path (see
* log_region.c's own doc comment on why) -- errors are reported back via
* vm->error, never logged.
*
* Source is NOT a caller-supplied parameter -- an earlier revision took
* source-addr/source-u off the stack, which let any caller claim to be
* any source. It is derived from vm_log_attributed_vm() (log_attrib.h)
* instead: the real VM currently executing, looked up by name via the
* VM registry, or the fixed "HADES" pseudo-source when no VM is attributed
* (matching log_attrib.h's own documented convention).
*/
#ifdef __STARKERNEL__
static void log_word_append_raw(VM *vm)
{
if (vm->dsp < 3) { vm->error = 1; return; }
cell_t msg_u = vm_pop(vm);
cell_t msg_addr = vm_pop(vm);
cell_t timestamp = vm_pop(vm);
cell_t level = vm_pop(vm);
if (msg_u < 0) { vm->error = 1; return; }
if (msg_addr < 0 || (msg_addr + msg_u) > (cell_t)VM_MEMORY_SIZE) { vm->error = 1; return; }
const char *msg = (const char *)&vm->memory[msg_addr];
char source[VM_NAME_MAX];
VM *attrib = vm_log_attributed_vm();
VMRegistryEntry entry;
if (attrib && capsule_vm_registry_get(attrib->stadium_vm_id, &entry) == 0) {
size_t i = 0;
for (; i < sizeof(source) - 1 && entry.name[i]; i++) source[i] = entry.name[i];
source[i] = '\0';
} else {
const char *hades = "HADES";
size_t i = 0;
for (; i < sizeof(source) - 1 && hades[i]; i++) source[i] = hades[i];
source[i] = '\0';
}
if (log_region_append((uint8_t)level, (uint64_t)timestamp,
source, (uint32_t)strlen(source),
msg, (uint32_t)msg_u) != 0) {
vm->error = 1;
}
}
#endif
/* ── Registration ────────────────────────────────────────────────────── */
/**
@@ -233,4 +292,8 @@ void register_log_words(VM *vm)
register_word(vm, "LOG-INFO-STR", log_word_info_str);
register_word(vm, "LOG-TEST-STR", log_word_test_str);
register_word(vm, "LOG-DEBUG-STR", log_word_debug_str);
#ifdef __STARKERNEL__
register_word(vm, "(LOG-APPEND-RAW)", log_word_append_raw);
#endif
}