doe_log.c: add vm_name/vm_id_hex identity columns; new calibration workload
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

Adds the identity columns HB-ON's existing per-tick CSV logger
(doe_log_tick_row(), doe_log.c) was missing. Previously every column
described *a* VM's state each row, but nothing said which VM emitted
it -- concurrent VMs' rows were indistinguishable by source. Two new
first columns, vm_name and vm_id_hex, resolved via a reverse lookup on
vm->stadium_vm_id (capsule_vm_registry_get()).

Real bug found and fixed while building this: the freestanding
snprintf here silently prints the literal format string instead of
substituting for %016llx (width+ll+hex unsupported) -- caught by
reading the actual emitted row, not assumed to work. Replaced with a
hand-rolled hex nibble-table loop, the same idiom vm_uuid_format()/
MINT-SCRATCH-EMIT already use.

Corrects FABRIC-3.md's own prior "still not started: CSV driver"
framing: no bespoke CSV emitter is needed for the multiuser DoE at
all -- this per-tick logger already exists, fires automatically inside
every VM's own execution loop, and just needed HB-ON plus these
identity columns to be usable for concurrent workers. Also corrects
doe_log.h's own stale doc comment claiming g_doe_log_enabled defaults
to 1 -- doe_log.c's own source is authoritative: 0, off by default,
matching the HB-ON/HB-OFF naming.

One real, honest limitation recorded rather than smoothed over:
vm_name reads blank for any tick captured during a WORKER-BIRTH'd
capsule's own self-execution at birth time, since capsule_birth_baby()
runs that work (and its heartbeat ticks) before the registry name can
be set. vm_id_hex is unaffected (reads directly from vm->stadium_vm_id)
and still uniquely disambiguates every row -- confirmed live: a
blank-name row's own vm_id_hex matched its later PARITY:KILL line's
vm_id exactly.

New workload-calib1.4th: Bob confirmed the existing 10 workload-N.4th
files aren't fixed. Sized to cross HEARTBEAT_CHECK_FREQUENCY (256
word-executions/tick) many times over while staying far lighter than
RUN-FIB/RUN-CHAOS5, both too slow under TCG for a bounded verification
run. A real, reusable addition, not a throwaway.

Verified live on amd64 via a self-contained one-shot EXEC'd test
(HB-ON, WORKER-BIRTH two calibration workers, HB-OFF, VM-ERROR? on
both, KILL both, completion banner) rather than interactive polling,
which breaks once HB-ON makes the log grow continuously via Hera/
Hermes/Artemis's own background ticks. Clean 3-arch qemu boot on the
real committed change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
Robert Allan James
2026-09-16 09:53:25 -04:00
co-authored by Claude Sonnet 5
parent e33eb36361
commit 41918a28a4
19 changed files with 122255 additions and 5 deletions
+53
View File
@@ -4991,3 +4991,56 @@ no separate "load then call" step is needed for that first run, only for subsequ
**Still not started:** the run-matrix/shuffle/CSV driver itself, the WIREBIND-automation path
for the fixed arm, and the per-VM iteration/touch-count budget's exact value.
### XXXIII.5 -- CSV already exists: HB-ON/doe_log.c, plus identity columns (2026-09-16)
**Correction to XXXIII.4's own "still not started" list:** no bespoke CSV emitter is needed at
all. `doe_log.c`'s `doe_log_tick_row()` already streams a 26-column CSV row to the serial log
on every heartbeat tick, for every live VM (fires automatically inside every VM's own
execution loop, `vm_core.c:908`, no thread or opt-in required) -- entirely independent of
`doe.4th`'s own separate single-VM campaign mechanism. Gated by `g_doe_log_enabled`, toggled by
the existing `HB-ON`/`HB-OFF` FORTH words. **`doe_log.h`'s own doc comment claiming this
defaults to 1 is stale** -- `doe_log.c:97` is authoritative: `g_doe_log_enabled = 0`, off by
default, exactly matching the `HB-ON`/`HB-OFF` naming. (This also resolves the open question
from §XXXIII.1: the mystery per-boot `doe-<arch>-*.csv` this whole session was *not* this
per-tick logger -- confirmed off by default -- so it must be `doe.4th`'s own separate
mechanism, still unexplained but now correctly ruled out as unrelated.)
**Gap found and fixed before this was usable for concurrent VMs:** the existing 26-column
schema had no column identifying *which* VM emitted a row -- columns for Hera/Hermes/Artemis's
own heat are hardcoded by name, but nothing said whose tick this was. Added two columns,
`vm_name` and `vm_id_hex` (both prepended, first two columns), resolved via a reverse lookup
on `vm->stadium_vm_id` (`capsule_vm_registry_get()`). `vm_id_hex` is formatted by hand
(nibble-table loop, same idiom `vm_uuid_format()`/`MINT-SCRATCH-EMIT` already use) after
finding live that this freestanding `snprintf` silently prints the literal format string
instead of substituting for `%016llx` (width+`ll`+hex unsupported) -- caught by reading the
actual emitted row, not assumed to work from the header comment's own claim.
**One real, honest limitation found live, not silently smoothed over:** `vm_name` reads blank
for any tick captured *during* a workload capsule's own self-execution at birth time --
`WORKER-BIRTH` calls `capsule_birth_baby()` (which runs the capsule's self-executing workload,
and thus its heartbeat ticks, synchronously and internally) *before* `capsule_vm_registry_set_
name()` can run, so the name genuinely doesn't exist yet at the moment those early rows are
captured. `vm_id_hex` is unaffected (read directly from `vm->stadium_vm_id`, no registry
lookup needed) and correctly disambiguates every row regardless -- confirmed live: a blank-name
row's own `vm_id_hex` matched its later `PARITY:KILL` line's `vm_id` exactly. Rows remain fully
attributable to a specific worker by ID even when the name column is momentarily empty; a
post-processing script correlating by `vm_id_hex` (not `vm_name`) is the correct approach, not
a workaround for a broken mechanism.
**New workload added, not a throwaway:** `workload-calib1.4th` -- Captain Bob confirmed the
existing 10 `workload-N.4th` files aren't fixed, extend as needed. Sized specifically to cross
`HEARTBEAT_CHECK_FREQUENCY` (256 word-executions/tick) many times over while staying far
lighter than `RUN-FIB` (100,000 iters) or `RUN-CHAOS5` (1,000,000 iters), both of which proved
too slow under TCG for a bounded interactive verification run. A real, reusable addition to the
workload set, not reverted.
**Verified live on amd64, self-contained (not interactive polling):** wrote a one-shot test
capsule (`RUN-IDENTITY-TEST`: `HB-ON`, `WORKER-BIRTH` two calibration workers, `HB-OFF`,
`VM-ERROR?` on both, `KILL` both, print a completion banner) and ran it as a single `EXEC`
call, waiting for its own "IDENTITY-TEST: complete" banner rather than polling per-command --
the same self-contained-driver pattern `doe.4th`'s own `DOE` word already uses, avoiding the
interactive `wait_for_prompt`-by-log-stability heuristic that breaks once `HB-ON` makes the log
grow continuously via Hera/Hermes/Artemis's own background ticks. Confirmed: banner printed,
both workers reported no error, both killed cleanly, Hera stayed healthy throughout
(`5 6 + .` -> `11`). Test capsule reverted after capture; `workload-calib1.4th` kept.