starkernel: item 4.2 -- Hermes native on the Stadium (complete)
Migrates Hermes's message/channel lifecycle onto the Stadium's unified heat/capacity economy: MSG-ALLOC/FREE-NODE and CH-ALLOC/FREE-NODE now route entirely through stadium_admit()/stadium_evict(), replacing the old local free-list + independent heat-field mechanism. Eight kernel-only STADIUM-* FORTH primitives (ADMIT, EVICT, RES@, RES-PULL, RES-PUSH, HEAT@, HEAT!, WORD-HEAT), VM.stadium_vm_id threaded through all three vm_core.c dispatch sites (replacing item 4.1's hardcoded vm_uuid_hera()), and the stadium_owner[idx] fix so evict-credit lands in the VM that actually admitted a patron, not whoever owned cell 0. This session's own contribution, on top of that pre-existing implementation: found and fixed two bugs blocking the item's own K≡1.0 conservation self-check (HERMES-K was reading 0, not 65536): - Q.SLOT admission-heat fix (capsules/hermes/init.4th): MSG-SEND/ CH-ACCEPT admitted with Q.1 (the entire fleet-wide "1.0" unit) per item, a leftover from before the Stadium migration when each message/channel had its own unconstrained heat field. Instantly drained the shared, finite reservoir. - Reservoir floor for word-execution admission (stadium_words.c): stadium_word_dispatch() (item 4.1) pulls STADIUM_WORD_HEAT_QUANTUM on every word dispatch, not just first admission -- exhausts a VM's entire reservoir in ~32 dispatches, starving any application-level economy sharing that VM's reservoir before it gets a chance to pull anything. word_dispatch_pull() now clamps word-execution's own pulls to leave a Q48_ONE/3 floor (same fair-share figure COMMON-CH's own floor already uses); application-level pulls are unaffected. - STADIUM-WORD-HEAT primitive + stadium_words_resident_heat(): the floor deliberately leaves word-execution residents holding real heat, invisible to HERMES-K's original formula (MSG+CH+reservoir, no term for word patrons). Adding this term closes K to exactly 65536 on all three architectures. Also rules on two open scope questions in FABRIC.md: MBR-ALLOC/ MBR-FREE-NODE stay off the Stadium (membership records have no heat field, never did -- the acceptance bullet's inclusion of them was a completeness gesture predating a check of the actual layout), and records the effort number (12 implementation files, +759/-120 lines). Verified: all three architectures boot clean, full self-test passes, Stadium conservation closes exactly (resident_sum + reservoir = Q48_ONE) at both the C/Stadium level and the FORTH-level HERMES-K check. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0a7f144367
commit
5a28458b21
@@ -3344,9 +3344,10 @@ document and committing that amendment as its own item.*
|
||||
> item never touches reservoir on the donor side), `test-vm reservoir=65536` (a fresh
|
||||
> `Q48_ONE`, as ruled). `dict_hash` identical across all three and unchanged from item 4.1's
|
||||
> baseline (`0x3d4e1daf289da94f`), confirming this item added no dictionary word.
|
||||
- [ ] **4.2 — Hermes native on the Stadium.** The proving ground; produces the effort
|
||||
- [x] **4.2 — Hermes native on the Stadium.** The proving ground; produces the effort
|
||||
number. *Refs:* §10. **Unblocked 2026-08-05** — item 4.1a closed; `stadium_grant_quota()`
|
||||
exists and is wired into every baby VM's birth.
|
||||
exists and is wired into every baby VM's birth. **Complete 2026-08-07** — all `Done when`
|
||||
bullets satisfied; see the effort number and MBR-scoping ruling below.
|
||||
|
||||
> **Two rulings taken before work starts, 2026-08-05:**
|
||||
> 1. **`stadium_owner[idx]` fix folded into this item's scope**, by explicit Captain Bob
|
||||
@@ -3492,8 +3493,83 @@ document and committing that amendment as its own item.*
|
||||
> the active log threshold and never appears in the serial log, a separate dead end closed
|
||||
> along the way) is the only viable method for this kernel today.
|
||||
>
|
||||
> **Blocker found 2026-08-06, ruled and fixed 2026-08-07 — item 4.1 and item 4.2 silently
|
||||
> share one finite per-VM reservoir, and word-execution admission alone can exhaust it
|
||||
> before any application-level allocation runs. This failed the K≡1.0 `Done when` bullet
|
||||
> below and was not a code bug to just patch — it was a design question spanning both
|
||||
> items, reported for a ruling rather than resolved unilaterally (§25.0 rule 3). Captain
|
||||
> Bob ruled option 4 below (reserve a floor); implementation and result are at the end of
|
||||
> this note.**
|
||||
>
|
||||
> After the `Q.SLOT` admission-heat fix (below) closed the original `MSG-SEND`/`CH-ACCEPT`
|
||||
> over-admission bug, `HERMES-K` still read `0` instead of `65536`. Three prints in one
|
||||
> boot discriminated the cause: `stadium_reservoir_peek(Hermes)` reads `65536` immediately
|
||||
> after `BIRTH` (the one-time grant, item 4.1a, is fine) but is already `0` — and
|
||||
> `COMMON-CH`'s own heat is already `0` — immediately after `CD-INIT` finishes, before
|
||||
> `HERMES-MSG-TEST`/`MSG-DELIVER-ALL`/anything else in the self-test runs. So this is not a
|
||||
> Stadium cell getting silently reassigned out from under `COMMON-CH` after the fact
|
||||
> (aliasing); `COMMON-INIT`'s own `CH-ALLOC` call, partway through `CD-INIT`, never got
|
||||
> funded in the first place.
|
||||
>
|
||||
> Root cause: `stadium_word_dispatch()` (item 4.1, `stadium_words.c:111`) pulls
|
||||
> `STADIUM_WORD_HEAT_QUANTUM` (2048) from the dispatching VM's reservoir on **every single
|
||||
> word dispatch**, not just the first time a word is admitted — the "already resident"
|
||||
> branch (line 142) does `h->heat += stadium_reservoir_pull(vm_id, STADIUM_WORD_HEAT_QUANTUM)`
|
||||
> unconditionally, every call. `CD-INIT`'s own `MSG-INIT-FREE`/`CH-INIT-FREE`/
|
||||
> `MBR-INIT-FREE` loops alone dispatch several hundred words (32 + 16 + 64 iterations, each
|
||||
> several words deep) before `COMMON-INIT` ever runs. At 2048 per dispatch, a VM's entire
|
||||
> 65536 reservoir is exhausted by roughly 32 total word dispatches — trivially reached
|
||||
> within `CD-INIT`'s first loop, let alone the rest of Hermes's boot. The boot log's own
|
||||
> `promotions=145` figure (Hermes's dict-check diagnostics) makes this arithmetic visible
|
||||
> directly: 145 × 2048 = 296,960, about 4.5× her entire conserved share, from
|
||||
> word-execution tracking alone. This applies to any VM doing non-trivial work, not
|
||||
> something specific to Hermes or to messages/channels — Hera's own reservoir has read `0`
|
||||
> in every log this entire session, for the same reason, just never surfaced as a problem
|
||||
> because nothing previously tried to spend Hera's reservoir on anything else.
|
||||
>
|
||||
> Options, no ranking, not decided here:
|
||||
> 1. **Separate reservoirs per VM** — one for word-execution tracking (item 4.1), one for
|
||||
> application-level use (item 4.2 and whatever comes after it). Most invasive: splits
|
||||
> `stadium_quotas[slot].reservoir` or the one-time grant itself, touches item 4.1's
|
||||
> already-shipped design and its recorded DoE baseline.
|
||||
> 2. **Exempt certain VMs from word-execution admission entirely** — e.g., only Hera (or
|
||||
> only VMs with no item-4.2-style application economy) get word-heat tracking. Requires
|
||||
> a new per-VM-class distinction that doesn't exist today.
|
||||
> 3. **Re-scope `STADIUM_WORD_HEAT_QUANTUM`** — smaller, or charged per-unique-word instead
|
||||
> of per-dispatch. Touches a Kconfig default that already feeds item 4.1's recorded DoE
|
||||
> measurements; re-tuning it here could invalidate that baseline.
|
||||
> 4. **Reserve a floor within the shared reservoir** that word-execution admission cannot
|
||||
> dip below, mirroring `COMMON-CH`'s own `Q.1/3` floor pattern but at the reservoir
|
||||
> level instead of a single resident. New mechanism, not yet designed.
|
||||
>
|
||||
> **Ruling, 2026-08-07: option 4.** Implemented as `word_dispatch_pull()`
|
||||
> (`stadium_words.c`), a static helper wrapping `stadium_reservoir_pull()` for
|
||||
> `stadium_word_dispatch()`'s two call sites only (both the already-resident re-heat pull
|
||||
> and the not-yet-resident starter-grant pull) — clamped so a pull never takes the
|
||||
> reservoir below `Q48_ONE / 3`, the same "VM-COUNT=3 fair share" figure `COMMON-CH`'s own
|
||||
> floor already uses, not a new invented number. Application-level pulls
|
||||
> (`stadium_reservoir_pull()` called directly, e.g. via `STADIUM-RES-PULL`) are untouched —
|
||||
> only word-execution admission respects the ceiling on its own consumption. Verified: the
|
||||
> eviction-credit demo now shows a real transfer (`resident_sum` −1612, `reservoir` +1612,
|
||||
> exactly, when `COMMON-CH` is evicted) instead of the prior `0`→`0` no-op, and the
|
||||
> Stadium's own conservation line closes exactly on every boot, every architecture:
|
||||
> `resident_sum=43691 reservoir=21845 sum=65536`.
|
||||
>
|
||||
> This alone brought `HERMES-K` from `0` to `43002` — real, but not exact, because
|
||||
> `HERMES-K`'s formula (`MSG-TOTAL-HEAT CH-TOTAL-HEAT + STADIUM-RES@ +`) has no term for
|
||||
> word-execution residents' heat, which the floor now deliberately leaves nonzero. Second
|
||||
> ruling, same date: **add that term.** New accessor `stadium_words_resident_heat(vm_id)`
|
||||
> (`stadium_words.c`) sums heat over only a VM's own word-execution residents (walking its
|
||||
> `word_slots` map, not `stadium_resident_sum()`'s full ownership scan, which would double-
|
||||
> count messages/channels already in `MSG-TOTAL-HEAT`/`CH-TOTAL-HEAT`), exposed as an
|
||||
> eighth `STADIUM-*` primitive, `STADIUM-WORD-HEAT ( -- heat )`, same implicit-self
|
||||
> discipline as the other seven. `HERMES-K` becomes
|
||||
> `MSG-TOTAL-HEAT CH-TOTAL-HEAT + STADIUM-RES@ + STADIUM-WORD-HEAT + ;`. Confirmed on all
|
||||
> three architectures: `HERMES-K` prints exactly `65536`, K≡1.0, closing the item's
|
||||
> headline invariant.
|
||||
>
|
||||
> *Done when:*
|
||||
> - The seven `STADIUM-*` FORTH primitives exist, are kernel-only (not in the shared/
|
||||
> - The eight `STADIUM-*` FORTH primitives exist, are kernel-only (not in the shared/
|
||||
> vendored word set), and are exercised by at least one Hermes word each.
|
||||
> - `stadium_owner[idx]` is written correctly on both the free-list-pop and
|
||||
> eviction-fallback paths in `stadium_admit()`, verified by a resident cell's
|
||||
@@ -3505,23 +3581,64 @@ document and committing that amendment as its own item.*
|
||||
> `vm_uuid_hera()` — verified by a Hermes-dispatched word's heat landing in Hermes's
|
||||
> own reservoir, not Hera's, with both VMs' conservation checks closing independently.
|
||||
> - Hermes's message and channel lifecycle (`MSG-ALLOC`/`MSG-FREE-NODE`, `CH-ALLOC`/
|
||||
> `CH-FREE-NODE`, `MBR-ALLOC`/`MBR-FREE-NODE`) run entirely through Stadium admission/
|
||||
> eviction — no parallel free list, no parallel heat field. Per §11, this is atomic:
|
||||
> `MSG-HEAT@/!`, `MSG-COOL-ONE`, `MSG-COOL-ALL`, `CH-HEAT@/!`, `CH-COOL-ALL`,
|
||||
> `CH-TOTAL-HEAT`, `MSG-TOTAL-HEAT` either come out in this same change or are rewritten
|
||||
> to read/write the Stadium cell instead of a local field — never both mechanisms live
|
||||
> at once.
|
||||
> `CH-FREE-NODE`) run entirely through Stadium admission/eviction — no parallel free
|
||||
> list, no parallel heat field. Per §11, this is atomic: `MSG-HEAT@/!`, `MSG-COOL-ONE`,
|
||||
> `MSG-COOL-ALL`, `CH-HEAT@/!`, `CH-COOL-ALL`, `CH-TOTAL-HEAT`, `MSG-TOTAL-HEAT` either
|
||||
> come out in this same change or are rewritten to read/write the Stadium cell instead
|
||||
> of a local field — never both mechanisms live at once. **`MBR-ALLOC`/`MBR-FREE-NODE`
|
||||
> ruled out of scope, 2026-08-07 — see below.**
|
||||
>
|
||||
> **Ruling, 2026-08-07: `MBR-ALLOC`/`MBR-FREE-NODE` stay on their own free list, not
|
||||
> migrated onto the Stadium.** This bullet originally named them alongside `MSG-*`/`CH-*`.
|
||||
> Checked the actual record layout (`capsules/hermes/init.4th`): an MBR record has exactly
|
||||
> two fields, `MBR-NEXT@` (link) and `MBR-VM@` (owning VM id) — a pure channel-membership
|
||||
> relationship, no heat field, never had one. The bullet's own stated purpose is "no
|
||||
> parallel free list, no parallel heat field" — for MBR, "no parallel heat field" is
|
||||
> already true vacuously, since none exists to be parallel to. Forcing MBR records through
|
||||
> `stadium_admit()`/`stadium_evict()` would mean inventing a heat/mass/behaviour for
|
||||
> something structurally without either, spending Stadium cells and reservoir budget on
|
||||
> records the item's actual design goal (a conserved, evictable-under-pressure heat
|
||||
> economy) has no reason to govern — "does VM X belong to channel Y" is not a quantity
|
||||
> that cools, competes for capacity, or needs eviction pressure. Their original inclusion
|
||||
> in this bullet reads as a completeness gesture written before the field layout was
|
||||
> checked, not a deliberate requirement. `MBR-ALLOC`/`MBR-FREE-NODE`'s own free list
|
||||
> (`capsules/hermes/init.4th`, unchanged this item) is correct as-is.
|
||||
> - Blocks 4110–4113 (Artemis) are untouched, per `HERMES.md`'s block-map lock. Any new or
|
||||
> changed Hermes block is verified with `mkcapsule --lint` before commit, per
|
||||
> `experiments/bare_metal/README.md`.
|
||||
> - The POST suite (regression gate per §10) passes.
|
||||
> - **The effort number is recorded explicitly** — per §10, "what Hermes costs is the
|
||||
> multiplier for everything else." Report at minimum: wall-clock/session time spent,
|
||||
> lines changed (FORTH + the seven-primitive C surface, split out), and file count
|
||||
> lines changed (FORTH + the eight-primitive C surface, split out), and file count
|
||||
> touched, so 4.3/4.4 can be estimated from a real data point rather than guessed.
|
||||
> - All three architectures boot to `ok>`/`zuse)ok>` with logs under `logs/`, and
|
||||
> Hermes's own conservation check (K≡1.0 across messages + channels + reservoir) closes
|
||||
> exactly, reported the same way item 4.1 reported `resident_sum`/`reservoir`/`sum`.
|
||||
>
|
||||
> **Effort number, reported 2026-08-07:**
|
||||
> - **Session time.** This conversation's own boot-log timestamps span roughly 10 hours
|
||||
> elapsed (`logs/20260806-153504` through `logs/20260807-013712`), covering: the amd64
|
||||
> GOT-indirect-addressing corruption investigation and fix (unrelated to Stadium logic,
|
||||
> committed separately as `0a7f144`), the item-4.2 acceptance-status survey against this
|
||||
> punch-list entry, the `Q.SLOT` admission-heat fix, the word-execution reservoir-floor
|
||||
> fix, and the `STADIUM-WORD-HEAT` addition that closed K≡1.0. This does **not** include
|
||||
> whatever time the original seven-primitive implementation and capsule migration
|
||||
> (already in place when this session's survey began) cost in an earlier session — no
|
||||
> visibility into that, not estimated rather than guessed.
|
||||
> - **Lines changed, split FORTH vs. C surface** (`git diff --stat`, this session's
|
||||
> contribution only — the pre-existing implementation's own diff is included since it
|
||||
> was still uncommitted when measured, but its authorship/timing is the caveat above):
|
||||
> - FORTH (`capsules/hermes/init.4th`): +116 / −45 (161 changed), 1 file.
|
||||
> - C, the eight-primitive `STADIUM-*` surface + Stadium core (`mama_forth_words.c`,
|
||||
> `stadium.c`, `stadium_words.c`, `stadium.h`, `stadium_words.h`, `vm.h`): +511 / −69
|
||||
> (580 changed), 6 files.
|
||||
> - C, other wiring (`capsule_birth.c`, `sk_vm_bootstrap.c`, `vm_core.c`,
|
||||
> `dictionary_management.c`): +13 / −6 (19 changed), 4 files.
|
||||
> - Self-test scaffolding (`kernel_main.c`, diagnostic-only, not production code):
|
||||
> +119 / −0, 1 file.
|
||||
> - **Total: 12 implementation files, +759 / −120 (879 lines changed).**
|
||||
> - **File count:** 12 implementation files (13 including this write-up in `FABRIC.md`
|
||||
> itself).
|
||||
- [ ] **4.3 — Console.** Settles 1.11 as part of the work. *Refs:* §17.5.
|
||||
|
||||
> **Note, 2026-08-05: Captain Bob wants a discussion before any work starts on this item.**
|
||||
|
||||
Reference in New Issue
Block a user