feat(log): LOG-FLUSH -- a VM's log records reach Artemis's log ring; and the ring keeps its order when it grows
FABRIC-3 SXXXII.4's deferred LOG-FLUSH, built to the 2026-10-14 rulings (SXXXVIII): everything a VM logs, at or above the log level, goes into its own buffer; it goes to Artemis on LOG-FLUSH, when full, and at once on an ERROR, as one kernel-Hermes LOG_BATCH message she writes on her own turn, the source being the sender the kernel stamped. Records that cannot go yet are counted and reported with the next flush. LOG-SHOW (Hera only) reads the ring back -- it had no reader. Found by the first test that filled it: ring growth overwrote the oldest record and put blank slots inside the live range. Fixed test first. Three ISAs: POST 1052 passed; new parity baseline word_count=526 hash=0x82f4ae7cb2e2d424 (deliberate). CLAUDE.md: Phase 8 PKI closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5e26fad30d
commit
4da370f492
+44
-1
@@ -4602,7 +4602,7 @@ call sites (`repl.c` has 18); most are direct interactive replies already correc
|
||||
this rule -- reclassifying the specific sites that aren't is Stage D's job (the same files Stage
|
||||
C's triage already walks), not repeated here.
|
||||
|
||||
**Decision on the two §XXVII gaps: fix eviction now, defer `LOG-FLUSH` again.**
|
||||
**Decision on the two §XXVII gaps: fix eviction now, defer `LOG-FLUSH` again.** *`LOG-FLUSH` built 2026-10-14 -- §XXXVIII.*
|
||||
`LOG-FLUSH` needs real new machinery first -- the per-VM log buffer its own doc comment already
|
||||
presumes (`vm_log_buffer.h`) does not exist anywhere in the tree, confirmed by grep; building it
|
||||
means designing that buffer format and the flush word together, genuine feature work deserving
|
||||
@@ -5633,3 +5633,46 @@ kernel's freestanding `snprintf` does not do.
|
||||
|
||||
**Found, not fixed (pre-existing, unrelated):** Hera prints two and Hestia three `( Unterminated
|
||||
comment` warnings at every boot, in logs from before this work too.
|
||||
|
||||
## XXXVIII. `LOG-FLUSH` built: a VM's log records reach Artemis's log ring (2026-10-14)
|
||||
|
||||
Deferred in §XXXII.4 as its own initiative; Captain Bob, 2026-10-14: build it before the
|
||||
bare-metal builds. His rulings: **everything the VM logs** goes in its buffer (at or above the
|
||||
log level -- the one, global `LOG-LEVEL!` setting, the same filter `log_message()` applies);
|
||||
it goes to disk **on `LOG-FLUSH`, when the buffer fills, and at once on an ERROR record**.
|
||||
|
||||
**Built.**
|
||||
- Each VM has a buffer of its own (`VM.log_buf`, 900 bytes, packed records: level, timestamp,
|
||||
length, text; `vm_log_buffer.c`/`.h`). `log_message()` (`shim.c`) adds every record it prints
|
||||
to the buffer of the VM it is attributed to (`vm_log_attributed_vm()`); a record made outside
|
||||
any VM's text -- the kernel's own -- belongs to none and is not kept.
|
||||
- A flush is one kernel-Hermes message to Artemis, type `SK_HERMES_MSG_TYPE_LOG_BATCH` (10), the
|
||||
one message type that is not FORTH text: `sk_hermes_drain_checkpoint()` hands it to
|
||||
`vm_log_batch_deliver()`, which writes each record with `log_region_append()` -- in Artemis's
|
||||
own context, on her turn (§XXXVI). The record's source is the sender the kernel stamped on the
|
||||
message, never a name the sender gives: a VM cannot write under another's name.
|
||||
- Nothing is lost silently: records that cannot go (Artemis not yet live -- all of Hera's POST --
|
||||
or the send refused) are counted, and the next flush that can be sent leads with "N log
|
||||
records not sent: Artemis not ready" (175 at a normal boot).
|
||||
- `LOG-FLUSH ( -- )`, every VM. `LOG-SHOW ( n -- )`, Hera only: the newest n records, oldest of
|
||||
them first, as source, level, text -- added because the ring had no reader at all, so nothing
|
||||
written there could be read or checked (`log_region_read_recent()`). Hera only because it shows
|
||||
every VM's records, and Hera's console is Zuse's.
|
||||
|
||||
**A real defect in the ring, found by the first test that filled it:** growth
|
||||
(`log_region_append()`) claimed to be "safe regardless of wrap state" and was not. The ring is
|
||||
full when it grows, so head == tail; nothing moved and tail stayed put, so the next write
|
||||
overwrote the oldest record and the new, blank slots read back as records inside the live
|
||||
range. 30 records written to a fresh ring read back as 28 of them and 12 blank
|
||||
(`logs/20261014-115648`; also `-115434` on a ring already damaged by an earlier test). Fixed:
|
||||
the records from head on move up by the slots added, and the next write goes into the gap (with
|
||||
head at 0 -- the only case growth meets, since nothing is evicted before the ring is at its full
|
||||
size -- simply at the old end). §XXXII.4 had flagged eviction as never live-exercised.
|
||||
|
||||
**Verified.** Test first: `LOG-FLUSH` and `LOG-SHOW` unknown (`logs/20261014-114028`). Then:
|
||||
Hera's WARN probe and her boot warnings, under source `Hera`, after `LOG-FLUSH`; identity `00`'s
|
||||
ERROR probe, sent by itself at once, under source `00` (`-114847`); the lost-records notice
|
||||
(`-115434`); 30 records through a growth, in order, no blank, on amd64 (`-115841`), aarch64
|
||||
(`-120526`) and riscv64 (`-120746`). Standard acceptance, all three ISAs: `zuse@Hera`, POST 1052
|
||||
passed, no unknown word, **new baseline `word_count=526 ... hash=0x82f4ae7cb2e2d424`**
|
||||
(deliberate: Hera's new words) (`logs/20261014-120027`, `-120148`, `-120356`).
|
||||
|
||||
Reference in New Issue
Block a user