starkernel: item 4.1 -- hot words onto the Stadium, density-ranked eviction

Punch list §25 item 4.1 complete.
Replaces the round-robin hotwords cache with Stadium density-ranked
admission/eviction on the kernel side, via the §17.7 reservoir mechanism and a
kernel-side word_id -> cell_index map (no DictEntry change, dict_hash
untouched). Adds stadium_birth_hera() to close the cell-0 panic hazard,
STADIUM_WORD_HEAT_QUANTUM/STADIUM_WORD_COOL_RATE_Q48 Kconfig knobs (flagged
untuned), and a stadium_word_forget() FORGET coherence hook to close a
recycled-word_id aliasing gap.

Verified: all five hotwords_cache_* call sites in dictionary_management.c
bypassed under __STARKERNEL__; word dispatch feeds the Stadium at all three
vm_core.c physics_execution_heat_increment() sites; hosted make unaffected;
all three architectures booted to ok> with matching dict_hash
(0x3d4e1daf289da94f) and matching conservation stats (promotions=354
evictions=0, resident_sum=65536 reservoir=0 sum=65536).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-05 13:37:10 -04:00
co-authored by Claude Sonnet 5
parent bd92c57834
commit 3d0b9351bd
19 changed files with 32009 additions and 24 deletions
+80 -17
View File
@@ -1210,6 +1210,45 @@ reservoir-based O(1) touch/cool transfer, Option B's starter-grant admission (no
increment/decay behaviour and `dict_hash` remain explicitly out of scope — nothing in item
4.1 touches either.**
#### Two rulings made during item 4.1's implementation, 2026-08-05
A pre-coding design pass surfaced two problems this section had not accounted for. Both were
taken to Captain Bob before any file was touched; both are now closed.
1. **Cell-0 panic hazard.** `stadium_boot_init()` grants Hera's quota with `free_head = 0` so
the first-ever admission pops cell 0 — documented as preserving item 3.6's "Hera is
patron zero." But nothing had ever actually birthed Hera into the Stadium; item 4.1's
first word dispatch would have made an ordinary, evictable word the accidental occupant
of cell 0, arming `stadium_evict()`'s hard panic guard for the day something tried to
reap it. **Ruled: birth Hera for real, as part of item 4.1** (a deliberate scope addition,
not silently folded in) — `stadium_birth_hera()` admits a pinned, zero-heat, mass-1
candidate into cell 0 before anything else can reach it. Zero heat means no reservoir
transfer is needed for her admission; conservation holds trivially at boot.
2. **Quantum/cool-rate underspecification.** The quantum this section names as
Kconfig-tunable had no defensible starting value, and the cooling coefficient wasn't
named as a *fraction of the patron's own current heat per tick* until this pass — the
naive reading (reusing `execution_heat`'s flat per-tick decay shape directly) can zero a
cell in one tick, since Q48_ONE (65536) is a much smaller number than it looks at a
glance. **Ruled: two new Kconfig knobs**, `STADIUM_WORD_HEAT_QUANTUM` (default 2048 =
Q48_ONE ÷ `HOTWORDS_CACHE_SIZE`, i.e. one "cache slot's worth" of the mechanism this item
retires) and `STADIUM_WORD_COOL_RATE_Q48` (default 21845, reusing
`INITIAL_DECAY_SLOPE_Q48`'s numeric value but reinterpreted as a fraction-of-current-heat
removed per tick, unit-safe for a conserved share — NOT the same quantity as
`execution_heat`'s decay, just a reasonable starting magnitude borrowed from it). Both
flagged in their Kconfig help text as untuned placeholders, DoE work for item 5.1, same
treatment as `STADIUM_MEMORY_PERCENT`.
**Noted in passing, not fixed:** Kconfig/`menuconfig` itself has never been exercised
end-to-end in this repo — every knob added so far, including these two, has only been
verified via its `Makefile.starkernel` default, never through an actual `menuconfig`
`.config` → build round trip. Filed at §25.7.
**Also found, reported not fixed (§25.7):** `stadium_admit()` never writes
`stadium_owner[idx]` on either the free-list-pop or the eviction-fallback path. Harmless
today — every cell's owner byte is already `0` (Hera) from `stadium_boot_init()`, and Hera is
the only VM with a quota — but once item 4.2 restores Hermes, a resident's evict-credit would
flow to the wrong VM's reservoir unless this is fixed first.
---
## 18. The engine — L0
@@ -3226,7 +3265,7 @@ document and committing that amendment as its own item.*
*One subsystem at a time, converted completely. Never two live heat mechanisms at once
(§11).*
- [ ] **4.1 — Hot words onto the Stadium.** Replaces the round-robin eviction with density
- [x] **4.1 — Hot words onto the Stadium.** Replaces the round-robin eviction with density
ranking, via the reservoir mechanism (§17.7) and a kernel-side `word_id → cell_index` map
(no `DictEntry` change, decided 2026-08-05). *Refs:* §17.3, §17.7.
@@ -3235,25 +3274,38 @@ document and committing that amendment as its own item.*
> `stats.promotions`" presumed reusing the old cache's `HotwordsStats`, which this item
> retires on the kernel side rather than extends.
>
> *Done when:*
> - Kernel builds only: `hotwords_cache_lookup()`/`hotwords_cache_evict_*()` call sites in
> `dictionary_management.c` are bypassed under `__STARKERNEL__`, per §17.3's resolution —
> the old cache's *effect* retires there; its code stays compiled and untouched.
> - Word dispatch feeds the Stadium: an already-resident word gets the reservoir-quantum
> touch (§17.7); a non-resident word attempts `stadium_admit()` with a starter-quantum
> candidate on every dispatch (Option B).
> - New Stadium-side promotion/eviction counters exist (same shape as
> `HotwordsStats.promotions`/`.evictions`, not that struct) and are observable via a
> diagnostic word or boot console output.
> - Hosted builds are unaffected — `execution_heat`, the old cache, and its stats keep
> working exactly as today; no shared-source behaviour changes for hosted.
> - All three architectures boot to `ok>`/`zuse)ok>` with logs under `logs/`. `dict_hash`
> is expected to still match the pre-4.1 baseline exactly, since it hashes only name and
> `execution_heat`, and neither changes under this item — a mismatch means something
> leaked into the hashed fields and is a regression, not something to explain away.
> **Done, 2026-08-05.** Two rulings made mid-implementation (§17.7's addendum): Hera is now
> actually birthed into cell 0 (`stadium_birth_hera()`, a deliberate scope addition, not
> silently folded in) closing the cell-0 panic hazard the original design left open; the
> quantum/cool-rate got two new Kconfig knobs (`STADIUM_WORD_HEAT_QUANTUM`,
> `STADIUM_WORD_COOL_RATE_Q48`) with derived-not-fabricated defaults, flagged untuned. A
> third addition, required for the item's own correctness rather than scope creep: a FORGET
> coherence hook (`stadium_word_forget()`, called from `vm_dictionary_untrack_entry()`)
> reclaims a resident word's cell before its `word_id` is recycled, closing an aliasing gap
> of the same shape as the 2026-08-02 `block_words.c` bug.
>
> *Acceptance, verified:*
> - Kernel builds only: all five `hotwords_cache_*` call sites in `dictionary_management.c`
> (not just the two originally named) are bypassed under `__STARKERNEL__`.
> - Word dispatch feeds the Stadium at all three of `vm_core.c`'s
> `physics_execution_heat_increment()` call sites — an already-resident word gets the
> reservoir-quantum touch; a non-resident word attempts Option B starter-grant admission.
> - New Stadium-side promotion/eviction counters (`stadium_words_stats()`) and a
> conservation check are printed to the boot console
> (`stadium_words_print_boot_diagnostics()`) before the REPL starts.
> - Hosted builds unaffected — confirmed via a clean hosted `make`.
> - All three architectures booted to `ok>` with logs under `logs/20260805-130800/amd64/`,
> `logs/20260805-130919/aarch64/`, `logs/20260805-131030/riscv64/`. `dict_hash` is
> identical across all three (`0x3d4e1daf289da94f`) and identical in shape to pre-4.1
> parity output — untouched, as designed. Stadium diagnostics also identical across all
> three: `promotions=354 evictions=0`, `resident_sum=65536 reservoir=0 sum=65536
> (Q48_ONE=65536)` — the conservation invariant closes exactly.
- [ ] **4.2 — Hermes native on the Stadium.** The proving ground; produces the effort
number. *Refs:* §10.
- [ ] **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.**
> Do not begin 4.3 on an unblock-and-go basis the way 4.1 was — raise it and wait.
- [ ] **4.4 — Artemis last.** It works today; it is the thing that cannot be broken.
*Refs:* §10.
@@ -3299,6 +3351,17 @@ so.*
- `src/*.c.bak` files are tracked in git at the `src/` top level.
- The `bump-z` / `bump-y` targets in the hosted `Makefile` reference version macros that do
not exist in the generated `include/version.h`.
- **Kconfig/`menuconfig` has never been exercised end-to-end.** Every Kconfig knob added so
far, including item 4.1's `STADIUM_WORD_HEAT_QUANTUM`/`STADIUM_WORD_COOL_RATE_Q48`, has only
ever been verified via its `Makefile.starkernel` `kconfig_int`/`kconfig_bool` default. Nobody
has run `make -f Makefile.starkernel menuconfig`, changed a value, and confirmed it actually
flows through to a build. Flagged by Captain Bob 2026-08-05.
- **`stadium_admit()` never writes `stadium_owner[idx]`**, on either the free-list-pop or the
eviction-fallback path (found during item 4.1's design pass, 2026-08-05). Harmless today —
every cell's owner byte is `0` (Hera) from `stadium_boot_init()`, and Hera is the only VM
with a quota — but once item 4.2 restores Hermes, a resident's evict-credit (item 4.1's
reservoir accounting in `stadium_evict()`) would flow to the wrong VM's reservoir unless
this is fixed first.
- **Taxonomy and lexicon.** Raised by Captain Bob 2026-08-04, mid-item-3.1. This document's
physics-flavored vocabulary (heat, mass, density, patron, Stadium, and the rest) needs a
glossary that is explicit these are named analogies, not physical claims — and that also