§H.12 step 4: Hera registers as session zero; punch list to checkboxes

Rewired stadium_birth_hera() to admit unpinned then register through
session_register()/session_set_pinned() instead of setting
STADIUM_FLAG_PIN directly on the candidate header. Self-referential
parent (vm_uuid_hera(), vm_uuid_hera()), matching capsule_run.h's
parent_vm_id == vm_id root convention. Soft-fail, non-fatal, if
session_register() fails -- Hera's actual Stadium admission is what the
patron-zero invariant is about. Wired session_boot_init() into
kernel_main.c right after stadium_boot_init(), before stadium_birth_hera().

Also converted §H.12's punch list from bold "DONE" markers to this
document's established - [ ]/- [x] checkbox convention (already used
throughout §A), for consistency.

Verified 3-arch boot to ok> (amd64/aarch64/riscv64), no soft-fail message
on any arch, Hermes/Artemis births unaffected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-03 06:15:53 -04:00
co-authored by Claude Opus 5
parent a621131ef6
commit 67793ea4a1
11 changed files with 27673 additions and 64 deletions
+72 -62
View File
@@ -3941,80 +3941,90 @@ identity work lands") — wiring real identities into them is part of this refac
work, not new invention.
**Phase 1 — Session struct + pin-authority choke point**
1. **DONE 2026-09-03.** `include/starkernel/session.h`: `Session{vm_id (VMUuid), pinned (int),
parent (VMUuid), name (fixed buffer, `SESSION_NAME_BUF`=64), identity (VMIdentity,
embedded)}`. Type only, no logic. No callers yet, so this acceptance run only confirms the
header itself is syntactically clean and doesn't break the build. Verified 3-arch boot to
`ok>` (amd64/aarch64/riscv64).
2. **DONE 2026-09-03, one deviation from the original wording.** `src/starkernel/vm/session.c`
+ `session_boot_init()`/`session_find(VMUuid)`/`session_register(...)`. Not a fixed-size
array as originally written here — found `stadium.c`'s own `StadiumVMQuota` table had
already been moved off a fixed array to a `kmalloc`'d-at-boot, budget-sized one (same
"population isn't knowable in advance" reasoning), so `session.c` mirrors that current
precedent instead: `session_boot_init()` sizes the slot table from `stadium_max_vm_count()`,
must run after `stadium_boot_init()`. Added `session.c` to `Makefile.starkernel`'s explicit
`LOADER_EXTRA_SRCS`/`KERNEL_EXTRA_SRCS` list (not a wildcard build). No callers yet.
Verified 3-arch boot to `ok>`.
3. **DONE 2026-09-03, one addition found necessary.** `session_set_pinned()`/
`session_is_pinned()` implemented — the pin-authority choke point (H.2/H.10).
`session_is_pinned()` answers from `Session.pinned` directly (the authoritative copy, no
Stadium re-derivation); `session_set_pinned()` writes both `Session.pinned` and the
mirrored `STADIUM_FLAG_PIN` bit on the session's own patron header, so Stadium's own
internal eviction/admission logic (which must stay self-contained, no call back into
session.c) keeps seeing a correct bit. **Addition**: `Session` needed a `stadium_cell`
field (index into `stadium_cells()`) that wasn't in the original §H.2 field list — the
choke point can't reach the right patron header without it. Necessary plumbing, not a new
session-level concept, so not treated as reopening §H.2's design. Also moved
`STADIUM_FLAG_PIN`'s `#define` from a `stadium.c`-private constant to `stadium.h` (public)
so `session.c` can reference it without duplicating the definition. Verified 3-arch boot to
`ok>`.
4. Rewire `stadium_birth_hera()` to register through `session_register()`/
`session_set_pinned()` instead of setting `STADIUM_FLAG_PIN` directly — Hera becomes
session zero.
- [x] **1. DONE 2026-09-03.** `include/starkernel/session.h`: `Session{vm_id (VMUuid), pinned
(int), parent (VMUuid), name (fixed buffer, `SESSION_NAME_BUF`=64), identity (VMIdentity,
embedded)}`. Type only, no logic. No callers yet, so this acceptance run only confirms the
header itself is syntactically clean and doesn't break the build. Verified 3-arch boot to
`ok>` (amd64/aarch64/riscv64).
- [x] **2. DONE 2026-09-03, one deviation from the original wording.**
`src/starkernel/vm/session.c` + `session_boot_init()`/`session_find(VMUuid)`/
`session_register(...)`. Not a fixed-size array as originally written here — found
`stadium.c`'s own `StadiumVMQuota` table had already been moved off a fixed array to a
`kmalloc`'d-at-boot, budget-sized one (same "population isn't knowable in advance"
reasoning), so `session.c` mirrors that current precedent instead: `session_boot_init()`
sizes the slot table from `stadium_max_vm_count()`, must run after `stadium_boot_init()`.
Added `session.c` to `Makefile.starkernel`'s explicit `LOADER_EXTRA_SRCS`/
`KERNEL_EXTRA_SRCS` list (not a wildcard build). No callers yet. Verified 3-arch boot to
`ok>`.
- [x] **3. DONE 2026-09-03, one addition found necessary.** `session_set_pinned()`/
`session_is_pinned()` implemented — the pin-authority choke point (H.2/H.10).
`session_is_pinned()` answers from `Session.pinned` directly (the authoritative copy, no
Stadium re-derivation); `session_set_pinned()` writes both `Session.pinned` and the
mirrored `STADIUM_FLAG_PIN` bit on the session's own patron header, so Stadium's own
internal eviction/admission logic (which must stay self-contained, no call back into
session.c) keeps seeing a correct bit. **Addition**: `Session` needed a `stadium_cell`
field (index into `stadium_cells()`) that wasn't in the original §H.2 field list — the
choke point can't reach the right patron header without it. Necessary plumbing, not a new
session-level concept, so not treated as reopening §H.2's design. Also moved
`STADIUM_FLAG_PIN`'s `#define` from a `stadium.c`-private constant to `stadium.h` (public)
so `session.c` can reference it without duplicating the definition. Verified 3-arch boot to
`ok>`.
- [x] **4. DONE 2026-09-03.** Rewired `stadium_birth_hera()` to admit unpinned then register
through `session_register(vm_uuid_hera(), vm_uuid_hera(), "Hera")` (self-referential
parent, matching `capsule_run.h`'s `parent_vm_id == vm_id` root convention) +
`session_set_pinned(vm_uuid_hera(), 1)` — Hera is session zero. `stadium_admit()` confirmed
to have no admission-time-special pin handling (just copies the candidate header), so
admit-unpinned-then-pin-after is safe. Soft-fail (logged, non-fatal) if `session_register()`
fails — Hera's actual Stadium admission already succeeded and is what the patron-zero
invariant is about. Wired `session_boot_init()` into `kernel_main.c` right after
`stadium_boot_init()`, before `stadium_birth_hera()`. Verified 3-arch boot to `ok>`, no
soft-fail message logged on any arch (registration succeeded), Hermes/Artemis births
unaffected.
**Phase 2 — Pin Hermes/Artemis (Correction 1 above)**
5. In `capsule_birth.c`'s existing generic admission block, add a name check ("Hera"/
"Hermes"/"Artemis" → pinned, everything else → unpinned) routed through
`session_register()`/`session_set_pinned()`.
6. Confirm (boot-log/diagnostic) Hermes and Artemis now admit pinned; ordinary births still
admit unpinned.
- [ ] **5.** In `capsule_birth.c`'s existing generic admission block, add a name check
("Hera"/"Hermes"/"Artemis" → pinned, everything else → unpinned) routed through
`session_register()`/`session_set_pinned()`.
- [ ] **6.** Confirm (boot-log/diagnostic) Hermes and Artemis now admit pinned; ordinary
births still admit unpinned.
**Phase 3 — Session fields wired at birth**
7. Populate `Session.parent` from the birthing VM's `stadium_vm_id`.
8. Populate `Session.name` from the capsule's own name string (already available at this
point in `capsule_birth.c`).
9. Confirm `Session.identity` defaults to `installed=0` correctly (no behavior change
expected yet).
- [ ] **7.** Populate `Session.parent` from the birthing VM's `stadium_vm_id`.
- [ ] **8.** Populate `Session.name` from the capsule's own name string (already available at
this point in `capsule_birth.c`).
- [ ] **9.** Confirm `Session.identity` defaults to `installed=0` correctly (no behavior
change expected yet).
**Phase 4 — Creator-ceiling enforcement (H.3, birth-time snapshot)**
10. `dictionary_snapshot_acl_from_parent(child, parent)`: for each word also present in the
parent's dictionary, copy `acl_allow`/`acl_mode`/`acl_pinned`/`acl_ttl` into the child's
matching entry.
11. Call it once, right after a child's dictionary finishes loading in `capsule_birth.c`.
- [ ] **10.** `dictionary_snapshot_acl_from_parent(child, parent)`: for each word also present
in the parent's dictionary, copy `acl_allow`/`acl_mode`/`acl_pinned`/`acl_ttl` into the
child's matching entry.
- [ ] **11.** Call it once, right after a child's dictionary finishes loading in
`capsule_birth.c`.
**Phase 5 — `BMAPFMT` (§F.4/§H.6, independent, can run any time)**
12. Edit `blk_meta_t` in `include/block_subsystem.h`: replace the old 4 ownership fields with
`owner_fp[8]`/`acl_allow`/`acl_ttl` (u32)/`acl_reserved[3]`/`reserved_future`. Verify
size/offsets with `offsetof`/`sizeof`, not by hand (see the `blk_volume_meta_t` padding-bug
lesson, [[project_phase8_milestone6_complete]]).
13. Define the three `flags` bit constants (`CLAIMED`=0/`MIGRATING`=1/`STALE`=2).
14. Add C get/set accessors for the new fields in `block_subsystem.c`.
15. Add FORTH wrappers (`BLK-ACL-ALLOW@`/`!`, `BLK-ACL-TTL@`/`!`, `BLK-OWNER@`).
16. Add a new policy capsule (mirroring `ACL.4th`) with a real fast-deny check on top — no
stub, per this project's standing "no stubs or TODOs, ever" rule (§C).
- [ ] **12.** Edit `blk_meta_t` in `include/block_subsystem.h`: replace the old 4 ownership
fields with `owner_fp[8]`/`acl_allow`/`acl_ttl` (u32)/`acl_reserved[3]`/`reserved_future`.
Verify size/offsets with `offsetof`/`sizeof`, not by hand (see the `blk_volume_meta_t`
padding-bug lesson, [[project_phase8_milestone6_complete]]).
- [ ] **13.** Define the three `flags` bit constants (`CLAIMED`=0/`MIGRATING`=1/`STALE`=2).
- [ ] **14.** Add C get/set accessors for the new fields in `block_subsystem.c`.
- [ ] **15.** Add FORTH wrappers (`BLK-ACL-ALLOW@`/`!`, `BLK-ACL-TTL@`/`!`, `BLK-OWNER@`).
- [ ] **16.** Add a new policy capsule (mirroring `ACL.4th`) with a real fast-deny check on
top — no stub, per this project's standing "no stubs or TODOs, ever" rule (§C).
**Phase 6 — Zuse eligibility list (H.5)**
17. Extend the metadata-fence record format with a new growable `owner_pubkey[32]`-list
record type.
18. Implement read/add/membership-check functions in C.
19. Add a Zuse-only FORTH word to add an entry, gated by `zuse_session`.
- [ ] **17.** Extend the metadata-fence record format with a new growable
`owner_pubkey[32]`-list record type.
- [ ] **18.** Implement read/add/membership-check functions in C.
- [ ] **19.** Add a Zuse-only FORTH word to add an entry, gated by `zuse_session`.
**Phase 7 — Message card gate + `ELEVATE-REQUEST` (H.8)**
20. Add the initiator-only ACL gate at `CH-REQUEST`'s entry point (default-permissive
baseline, real hook point established).
21. Define `ELEVATE-REQUEST` and a minimal real handler checking the eligibility list,
granting via `ACL-ALLOW!`/`ACL-TTL!` on match.
22. Add the FORTH entrypoint a session actually calls to send one.
- [ ] **20.** Add the initiator-only ACL gate at `CH-REQUEST`'s entry point
(default-permissive baseline, real hook point established).
- [ ] **21.** Define `ELEVATE-REQUEST` and a minimal real handler checking the eligibility
list, granting via `ACL-ALLOW!`/`ACL-TTL!` on match.
- [ ] **22.** Add the FORTH entrypoint a session actually calls to send one.
**Excluded, per H.11's deferred items 1011**: VM card multi-owner support, live-console
`sudo`-style elevation, pre-signed capability tickets.