starkernel: item 3.8 -- VM identifiers as UUID/GUID

Punch list §25 item 3.8 complete. Added after starting item 4.1
surfaced the need to thread a vm_id into stadium_admit()'s new quota
parameter; Captain Bob ruled UUID/GUID rather than keeping the
narrower uint32_t.

New VMUuid type (vm_uuid.h/vm_uuid.c): two uint64_t halves, RFC-4122-
shaped for logging. Not real randomness -- checked directly against
QEMU 10.2.1's actual CPU feature set: amd64 RDRAND and riscv64 Zkr are
both real, available features here; aarch64 has no RNG property on any
CPU model including "max" (verified exhaustively via QMP
query-cpu-model-expansion). Captain Bob ruled a uniform fallback
across all three ISAs rather than a per-architecture split.

Fallback is a deterministic PRNG (splitmix64) seeded from the Mama
capsule's content hash, pre-filling a 16-entry FIFO pool at boot and
refilling with another batch of the same stream when exhausted --
exactly the shape requested. Same capsule booted twice produces the
same id sequence, preserving the dict_hash reproducibility this
session has relied on throughout.

Hera keeps a fixed, reserved all-zero id, not drawn from the pool --
capsule_birth.c uses vm_id == 0 as a load-bearing sentinel in three
places (KILL protection x2, fleet heat-fanout parent-chain
terminator), found by reading before writing any code.

Two real sentinel-collision bugs caught before shipping, same class as
STADIUM_CONTAINS_NONE: vm_uuid_none() (all-ones, not all-zero) for
"not yet assigned"/"no VM" placeholders; confirmed item 3.7's quota
table already used an in_use boolean rather than a vm_id sentinel, so
no second collision was actually possible there -- the dead,
never-referenced STADIUM_QUOTA_SLOT_EMPTY macro was removed.

Blast radius larger than first scoped, flagged mid-work rather than
silently absorbed: capsule_vm_physics.c/.h (the fleet heat-transfer
layer item 2.1 modified earlier this session) has its own vm_id-keyed
node table and walks parent_vm_id chains through the same identity
space, so it needed the same change, plus its callers in
mama_forth_words.c and sk_vm_bootstrap.c.

One live FORTH word contract changed, by explicit ruling: CAPSULE-BIRTH
was ( capsule-id -- vm-id ), a single cell -- can't hold 128 bits.
Captain Bob picked pushing two cells ("there is doubles support in the
FORTH std word set anyway"): ( capsule-id -- vm-id-hi vm-id-lo ).
MAMA-VM-ID changed the same way: ( -- 0 0 ).

Verified: full (not standalone-file) kernel rebuild to catch cross-file
breakage given the size of this change -- it surfaced the
capsule_vm_physics.c blast radius a narrower check would have missed.
Three-architecture boot (amd64, aarch64, riscv64), all reaching ok>
with identical dict_hash=0x3d4e1daf289da94f matching the item-3.7
baseline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-04 19:50:34 -04:00
co-authored by Claude Sonnet 5
parent ec2c97ef70
commit 9b305a5be7
20 changed files with 31751 additions and 107 deletions
+76 -1
View File
@@ -3010,7 +3010,82 @@ document and committing that amendment as its own item.*
> cells (M KB)` boot line is unaffected in format — amd64 (`logs/20260804-180453`, `74234
> cells (4639 KB)`), aarch64 (`logs/20260804-180541`), riscv64 (`logs/20260804-180637`).
>
> **Phase 3 core complete, for real this time.** Items 3.13.7 close out §25.4.
> **Correction, 2026-08-04, same day:** starting work on item 4.1 surfaced a further
> prerequisite — see item 3.8 below. §25.4 gained an eighth item.
- [x] **3.8 — VM identifiers as UUID/GUID.** Replaces `capsule_birth.c`'s monotonic
`uint32_t vm_id` with a wider, RFC-4122-shaped 128-bit identifier. Added 2026-08-04 after
starting item 4.1 surfaced the need to thread a `vm_id` into `stadium_admit()`'s new
quota parameter, and Captain Bob ruled UUID/GUID rather than keeping the narrower type.
*Refs:* §22.3 (item 3.7's quota table), capsule_birth.c's VM registry.
> **DONE 2026-08-04.** New `VMUuid` type (`include/starkernel/vm_uuid.h`,
> `src/starkernel/capsule/vm_uuid.c`): two `uint64_t` halves, formatted
> RFC-4122-shaped (`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) for logging.
>
> **Not real randomness — checked directly, not assumed.** This kernel has no RNG source
> at all. Verified empirically against QEMU 10.2.1 rather than guessed: amd64's `RDRAND`
> and riscv64's `Zkr` entropy extension are both real, available CPU features here (QEMU
> accepts `-cpu qemu64,+rdrand` and `-cpu rv64,zkr=true` without error); aarch64 has
> **no** RNG/RNDR property on any CPU model including `max` — checked exhaustively via
> QMP's `query-cpu-model-expansion` against all 23 of `max`'s exposed properties, none
> RNG-related. Captain Bob ruled a uniform fallback across all three ISAs rather than a
> per-architecture split (real RNG on two, something else on the third).
>
> **The fallback is a deterministic PRNG (splitmix64 — public-domain, minimal), seeded
> from the Mama capsule's content hash**, pre-filling a 16-entry FIFO pool at boot
> (`vm_uuid_pool_init()`, called from `capsule_birth_mama()` right after the capsule hash
> is known), refilled with another batch continuing the same stream when exhausted
> (`vm_uuid_next()`) — exactly the shape Captain Bob asked for. Same capsule booted twice
> produces the same id sequence, preserving the run-to-run reproducibility this session's
> `dict_hash` regression check has relied on for every prior item.
>
> **Hera keeps a fixed, reserved id — all-zero — not drawn from the pool.**
> `capsule_birth.c` uses `vm_id == 0` as a load-bearing sentinel in three places, found by
> reading before writing any code: "Hera cannot be killed" (`capsule_vm_kill`), the same
> check in `capsule_vm_kill_all_nonmama`, and the fleet heat-fanout parent-chain
> terminator (`capsule_run.h`'s `parent_vm_id` comment: "self-referential, `parent_vm_id
> == vm_id == 0`"). `vm_uuid_hera()` (all-zero) preserves all three with a cheap
> equality check (`vm_uuid_is_hera()`).
>
> **Two real sentinel-collision bugs caught before they shipped, both the same class of
> mistake `STADIUM_CONTAINS_NONE` was already fixed for once this session:**
> - `vm_uuid_none()` (all-ones) is deliberately **not** all-zero, since all-zero is now
> Hera's reserved value — used for "not yet assigned" placeholders
> (`vm_registry_alloc()`'s embryo `vm_id` before birth completes) and "no VM" logging
> (item 2.2's `FLEET_FULL` refusal, which happens before any VM is allocated).
> - `StadiumVMQuota`'s "slot empty" state was already tracked by an `in_use` boolean
> (item 3.7), not a `vm_id` sentinel value — so no second collision was actually
> possible there; confirmed by re-reading item 3.7's own code rather than assumed, and
> the dead, never-referenced `STADIUM_QUOTA_SLOT_EMPTY` macro item 3.7 defined "just in
> case" was removed as part of this item's cleanup.
>
> **Blast radius, larger than first scoped — flagged mid-work rather than silently
> absorbed:** beyond the originally-flagged `capsule_run.*`/`capsule_birth.*`/`stadium.*`,
> compiling surfaced that `capsule_vm_physics.c`/`.h` (the fleet heat-transfer layer item
> 2.1 modified earlier this session) has its own `vm_id`-keyed node table and walks
> `parent_vm_id` chains via `capsule_vm_registry_get()` — the same identity space, so it
> had to change too (`vm_physics_init`/`_retire`/`_touch`/`_heat_of`/`_find`/
> `_find_root_id`), plus its callers in `mama_forth_words.c` and
> `sk_vm_bootstrap.c`.
>
> **One live FORTH word contract changed, by explicit ruling:** `CAPSULE-BIRTH` was
> `( capsule-id -- vm-id )`, a single cell — can't hold 128 bits. Options were two cells,
> a silent 64-bit truncation, or a separate small FORTH-only handle; Captain Bob picked
> two cells ("there is doubles support in the FORTH std word set anyway"). New contract:
> `( capsule-id -- vm-id-hi vm-id-lo )`, high cell on top, `vm_uuid_none()`'s hi/lo (both
> all-ones) on any failure path including the early bounds-check return. `MAMA-VM-ID`
> changed the same way: `( -- 0 0 )`, both cells zero since Hera's id is all-zero.
>
> **Regression: clean, across a genuinely large diff.** All three architectures boot to
> `ok>` with identical `dict_hash=0x3d4e1daf289da94f`, matching the item-3.7 baseline —
> amd64 (`logs/20260804-194631`), aarch64 (`logs/20260804-194711`), riscv64
> (`logs/20260804-194810`). A full (not standalone-file) kernel rebuild was used to catch
> cross-file breakage before the boot run, given the size of this change; it surfaced the
> `capsule_vm_physics.c` blast radius above that a narrower compile check would have
> missed.
>
> **Phase 3 core complete.** Items 3.13.8 close out §25.4.
---