Correct sk_hermes_alloc() to admit a real Stadium patron; add sk_hermes_release() -- FABRIC-3.6.md tasks 2.2 (amended) + 2.3
Real finding, caught before building release on a foundation that
couldn't support it: task 2.2's first cut of sk_hermes_alloc() pulled
reservoir heat but never admitted a real Stadium-floor patron -- just a
local in_use flag. FABRIC-3.5.md SXXXIII.4 item 1 says MSG-FREE-NODE
returns heat "via STADIUM-EVICT", which only means something if
allocation admitted something. SXL.4's own invariant, Sigma(resident
patron heat) + reservoir + consumed == Q48_ONE, cannot balance if held
heat is invisible to every term while held. Flagged to Captain Bob
before proceeding; authorized to correct 2.2 in the same pass as
building 2.3 on top of the fix.
sk_hermes_alloc() now calls stadium_admit() with heat = the pulled
amount, behaviour = STADIUM_BEHAVIOUR_DELIVER (matching messaging.4th's
own SB-DELIVER STADIUM-ADMIT exactly), and identity = the message's own
slot index (matching the FORTH precedent -- caught live in the first
boot of this fix that omitting this made stadium_dispatch()'s existing
DELIVER diagnostic print msg_idx=0 for every message instead of a
distinct value). The returned cell index is stored in the message's
own stadium_cell field. Stadium-floor refusal (independent of reservoir
affordability) rolls back the pull the same way the other refusal
paths already do.
sk_hermes_release() -- the function task 2.3 actually asks for -- calls
stadium_evict() on that cell, which itself returns the departing
patron's remaining heat to its owning VM's reservoir, matching
MSG-FREE-NODE's exact shape. Release does not touch the reservoir
directly.
Self-test (kernel_main.c) extended: keeps every allocated message's
pointer, allocates to exhaustion as before, releases all of them, and
checks the reservoir returns to precisely its starting value.
"Undecayed" is true by construction (no decay/TTL logic exists yet,
task 2.5) -- exact restoration, not approximate.
Three-arch boot clean: amd64/aarch64/riscv64 all reach [zuse@Hera] ok>,
zero UNKNOWN WORD, dict_hash unmoved from task 2.2. All three print
identical PASS arithmetic: reservoir0=65536, reservoir_after_alloc=0,
reservoir_final=65536. No compiler warnings.
stadium_dispatch()'s DELIVER-case console output (one line per
eviction) is pre-existing instrumentation, not new -- confirmed real
and load-bearing per stadium.c's own comment, verbose but expected.
Authorized by Captain Bob ("yes").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9d129fdb1c
commit
2c1dc1753a
+57
-1
@@ -551,8 +551,64 @@ Hestia; headless policy intact.
|
||||
defined as "before and after the alloc/free cycle," not "continuously during." This task's
|
||||
self-test checks reservoir arithmetic directly instead, which is the right instrument for
|
||||
what task 2.2 alone claims.
|
||||
- [ ] **2.3** — Release: return remaining heat via the eviction path. *Check:* reservoir
|
||||
|
||||
**AMENDED 2026-09-20, while starting task 2.3 — see that entry for the full account.**
|
||||
This task's own first cut of `sk_hermes_alloc()` never admitted a real Stadium-floor
|
||||
patron; it only pulled reservoir heat and set a local flag. Corrected in the same commit
|
||||
as task 2.3, since release cannot evict something that was never admitted. The two-term
|
||||
`stadium_conserved()` non-evidence point above still holds — if anything it holds more
|
||||
precisely now that held heat really is off the floor (in the Stadium-admission sense) and
|
||||
not merely absent from a two-term check that never modeled it in the first place.
|
||||
- [x] **2.3** — Release: return remaining heat via the eviction path. *Check:* reservoir
|
||||
restored exactly for an undecayed message.
|
||||
2026-09-20 · `logs/20260920-041455/amd64/`, `logs/20260920-041619/aarch64/`,
|
||||
`logs/20260920-041752/riscv64/` — all three reach `[zuse@Hera] ok>`, zero `UNKNOWN WORD`,
|
||||
`dict_hash` triple unmoved from task 2.2's baseline. All three print
|
||||
`Kernel-Hermes alloc/release self-test: ... PASS` with **identical arithmetic**:
|
||||
`reservoir0=65536 ... reservoir_after_alloc=0 ... reservoir_final=65536` — exact
|
||||
restoration, not approximate.
|
||||
|
||||
**Real finding, not a clean continuation: task 2.2's allocator was missing a step.**
|
||||
§XXXIII.4 item 1 says `MSG-FREE-NODE` returns heat "via `STADIUM-EVICT`" — which only
|
||||
means something if allocation admitted a real Stadium patron in the first place. Task
|
||||
2.2's first cut didn't; it only pulled reservoir heat and flagged a local slot in use.
|
||||
Caught this before writing release on top of a foundation that couldn't support it, per
|
||||
§XL.4's own invariant: held message heat that is neither a resident patron nor reservoir
|
||||
nor `consumed` is invisible to the conservation equation entirely, which cannot be right.
|
||||
Flagged to Captain Bob before proceeding; authorized to correct task 2.2 in the same pass
|
||||
as building 2.3 on top of the fix, rather than patching around the gap.
|
||||
|
||||
**The fix, amending `src/starkernel/vm/kernel_hermes.c`'s `sk_hermes_alloc()`:** after
|
||||
pulling `SK_HERMES_Q_SLOT`, now calls `stadium_admit()` with a `StadiumPatronHeader` whose
|
||||
`heat` is the pulled amount, `behaviour = STADIUM_BEHAVIOUR_DELIVER` (matching
|
||||
`messaging.4th`'s own `SB-DELIVER STADIUM-ADMIT` at its `MSG-ALLOC` site exactly — same
|
||||
enum values, `SB-DELIVER`=1=`STADIUM_BEHAVIOUR_DELIVER`), and `identity` set to the
|
||||
message's own slot index (matching the FORTH precedent, and keeping
|
||||
`stadium_dispatch()`'s existing `DELIVER` diagnostic — "msg_idx=" — meaningful instead of
|
||||
every message printing 0; caught live in the first boot of this fix, since all 32
|
||||
admissions printed `msg_idx=0` before the identity fix). The returned cell index is
|
||||
stored in the message's own `stadium_cell` field. If the Stadium floor itself refuses
|
||||
admission (a third refusal path, independent of reservoir affordability), the pull is
|
||||
rolled back the same way the other refusal paths already do.
|
||||
|
||||
**`sk_hermes_release()`, the new function this task actually asks for:** calls
|
||||
`stadium_evict()` on the message's `stadium_cell` — which itself returns the departing
|
||||
patron's remaining heat to its owning VM's reservoir (`stadium.c`'s own comment: "the
|
||||
departing patron's remaining heat must flow back to its owner's reservoir"), so release
|
||||
does not touch the reservoir directly, matching `MSG-FREE-NODE`'s exact shape
|
||||
(`DUP 5 CELLS + @ STADIUM-EVICT DROP`). Clears the slot regardless of eviction's own
|
||||
return value, since a message asked to be released should not remain allocated either way.
|
||||
|
||||
**Self-test extended, not replaced:** the existing synthetic-VM self-test (task 2.2, `lo=3`)
|
||||
now keeps every allocated message's pointer in an array, allocates to exhaustion exactly as
|
||||
before, then releases all of them and checks the reservoir returns to precisely its
|
||||
starting value. "Undecayed" is true by construction here — no decay/TTL logic exists yet
|
||||
(task 2.5) — so this is exactly the case the check asks for: exact restoration, not
|
||||
approximate. `stadium_dispatch()`'s existing `DELIVER`-case console output (one line per
|
||||
eviction, pre-existing instrumentation, not new) is verbose but expected — confirmed
|
||||
real and load-bearing (`stadium.c`'s own comment: "has been real and live on every boot
|
||||
for weeks"), not something this task introduced. No compiler warnings on either edited
|
||||
file.
|
||||
- [ ] **2.4** — The four counters: `held`, `pulled`, `returned`, `consumed` (§XL.4). *Check:*
|
||||
each increments at exactly one site.
|
||||
- [ ] **2.5** — Decay: apply, and **record the delta into `consumed`** (§XXXVII.3). *Check:*
|
||||
|
||||
Reference in New Issue
Block a user