diff --git a/FABRIC.md b/FABRIC.md index ea6f606..e540b5a 100644 --- a/FABRIC.md +++ b/FABRIC.md @@ -823,8 +823,55 @@ Consequences if this holds: - Pin stops being a general-purpose escape hatch and goes back to meaning what §3 says: invariance, for the few things that genuinely must not vary. -**LEANING.** The mechanism is already built and the fit is clean, but this reframes a -direction stated differently earlier the same day, and it deserves longer than a paragraph. +~~**LEANING.**~~ **DECIDED 2026-08-04**, on paper, before item 4.1's code — settled after +starting that item surfaced this section as its unresolved prerequisite. + +**The core claim stands, for the reason already given above.** The existing cache is +self-contradictory as built: heat gates admission, nothing governs departure, and the +consequence is that the hottest word in the cache can be evicted purely because its slot +came up in the round-robin rotation. Moving words onto the Stadium repairs a real defect, +not a relabeling exercise, and `stats.evictions`/`stats.promotions`/`stats.cache_hits` make +it directly measurable before and after, exactly as this section already argued. + +**What was actually missing was the hosted/kernel split** — §25.5's own header warns +"never two live heat mechanisms at once" (§11), but nothing said which way that resolves, +and the two subsystems involved are not symmetric: + +- `src/physics_hotwords_cache.c` and `src/dictionary_management.c` are vendored, shared + source. `dictionary_management.c` calls `hotwords_cache_lookup()` / + `hotwords_cache_evict_*()` directly in the word-lookup path, **not gated by + `#ifdef ENABLE_HOTWORDS_CACHE`** at the call sites — the toggle only controls the cache's + own internal behaviour, not whether these call sites exist. This file must keep compiling + and working correctly in both the hosted and kernel builds (CLAUDE.md is explicit). +- The Stadium (`stadium.h`/`stadium.c`) is, and by construction of everything built through + item 3.7 can only be, kernel-only — every declaration in it is `#ifdef __STARKERNEL__`. + Nothing in this document has ever proposed a hosted Stadium, and building one is not + something item 4.1 needs to do. +- `ENABLE_HOTWORDS_CACHE` already defaults to **off** in both the hosted `Makefile` and + `Makefile.starkernel` today (`Kconfig.physics`, confirmed against both Makefiles directly + — a stale comment beside the Makefile default claims the opposite, but the actual default + is `n`/`0` in both). So "two live mechanisms" is not a live conflict in the default build + today; it only becomes one once item 4.1's kernel-side migration and the old cache are + both actually exercised at once. + +**Resolution: kernel and hosted diverge, and that is the correct shape, not a compromise.** + +- **Kernel builds:** once item 4.1 lands, the old cache's *effect* is retired under + `__STARKERNEL__` — word patrons migrate onto the Stadium, and + `hotwords_cache_lookup()`/`hotwords_cache_evict_*()`'s call sites in + `dictionary_management.c` are bypassed for the kernel build regardless of the + `ENABLE_HOTWORDS_CACHE` setting. The shared source can stay compiled as-is (untouched, for + hosted's sake) while being functionally inert on the kernel side. Item 4.1 decides the + exact mechanism (a build-time gate, a runtime check, or something else) — not invented + here. +- **Hosted builds: unchanged.** No Stadium exists there, none is being built for it, and the + existing mechanism — including its current off-by-default setting — stays exactly as it + is. This is what keeps CLAUDE.md's dual-target compileability requirement satisfied + without inventing a second Stadium implementation nobody asked for. + +Consequences from above still hold: words need no pin exception (reap event is cooling off +the floor), §16.3's dictionary-parity concern narrows to the hot set alone, and pin goes +back to meaning invariance rather than a general-purpose escape hatch. ### 17.4 Open