diff --git a/FABRIC.md b/FABRIC.md index f1b7bb6..6cb1c25 100644 --- a/FABRIC.md +++ b/FABRIC.md @@ -1078,6 +1078,67 @@ that matters. The total stays fixed; only the partition shifts. Decide how big the Stadium is at runtime. Do not decide what an entry is, or how entries are addressed, at runtime. +### 17.7 Word-level heat conservation — LEANING, paper only, blocks item 4.1 + +Item 4.1 (hot words onto the Stadium, §25.5) needs `DictEntry.execution_heat` converted into +the Stadium's Q48.16 `heat` field. The obvious move — `q48_from_u64(execution_heat)`, a pure +representation change, no semantics touched — was proposed and **rejected 2026-08-04**: +Captain Bob wants real conservation for word heat too, on the same footing as §19.1's +fleet-level invariant, not just a unit conversion. + +This is open. It is *not* a smaller version of §19.1 — it conflicts with two things already +load-bearing, and both have to be resolved on paper before any code touches Loop #1: + +1. **The promotion threshold breaks.** `hotwords_cache_lookup()` promotes a word on + `execution_heat > HOTWORDS_EXECUTION_HEAT_THRESHOLD` (`50`, absolute, against an unbounded + counter — `physics_hotwords_cache.h:87`). A conserved share of `Q48_ONE` (65536) split + across however many words are resident cannot be compared against `50` in any consistent + way. §17.3, decided the same day this question was raised, says plainly "execution heat + (Loop #1) is what promotes a word" — treating the existing counter, and its absolute + threshold, as the mechanism. Conservation needs a *relative* trigger instead (density-rank + within the resident set, margin above the resident median, something else) — a real + change to Loop #1's promotion rule, not a units change. +2. **`dict_hash` moves.** `capsule_dict_hash_hook()` hashes exactly two things per entry: + name and `execution_heat`. That hash is the parity baseline every item this phase has been + verified against. If `execution_heat`'s value now comes from a transfer instead of an + increment, it changes on every dispatch for a different reason than before, and the + baseline moves in the same commit that introduces the change. The design has to say + explicitly what happens to parity comparisons made before vs. after — not leave it + implicit. + +There's a third thing underneath both: real conservation means the *increment itself* becomes +a *transfer* — heat pulled toward the touched word from the rest of the resident set, or from +the full dictionary, on every single word dispatch. That is the hottest path in the entire VM, +in both hosted and kernel builds, and Loop #1 is one of the seven feedback loops this project +has a formal-verification claim about (0.000% CV across 90 runs). This does not get touched +speculatively. + +**Captain Bob's own first sketch (2026-08-04, to be developed further, not yet a ruling):** a +quantity between 0 and 1, possibly derived from something that already exists as a DoE output +parameter, kept conserved by its own dedicated loop rather than folded into an existing one — +explicitly *not* gated by L8 the way L1–L7 are (§18.1's "L8 cannot be gated... L0 cannot be +gated" bookend structure is the closest existing precedent for an always-on, ungated loop). +`stale_word_ratio` (`doe_metrics.c:273`, `stale_word_count / word_count`, already bounded +[0,1], already flowing into the DoE CSV) is one candidate for "something that already exists" +worth checking against when this gets picked back up — not proposed as the answer, just the +nearest existing fit to "0 to 1, already measured." + +**Open, to settle before item 4.1 writes any Loop #1 code:** + +- What sums to what: per-VM over its resident set? Over the full dictionary? Does the sum + reset on residency change (admit/evict), or is that a different mechanism wearing + conservation's name? +- What replaces the absolute promotion threshold, given a relative/conserved quantity can't + be compared against a fixed constant the way `execution_heat > 50` is today. +- What transfers, from whom, on every dispatch — and its cost, given this sits on the hottest + path in the VM, before it is approved for the dispatch loop in either build. +- What happens to `dict_hash` and to parity comparisons that predate this change. +- Whether this is really a new, ungated loop (a candidate "L9," by the naming scheme in + §18.1) or something that composes into an existing one — not decided here. + +**Nothing in this section authorizes touching `execution_heat`'s current increment +behaviour, Loop #1, or `dict_hash` before this section reads DECIDED.** + --- ## 18. The engine — L0 @@ -3097,6 +3158,13 @@ document and committing that amendment as its own item.* - [ ] **4.1 — Hot words onto the Stadium.** Replaces the round-robin eviction with density ranking. Measurable before and after via `stats.evictions` / `stats.promotions`. *Refs:* §17.3. + + > **Blocked, 2026-08-04, before any code:** converting `execution_heat` into the Stadium's + > `heat` field turned out not to be the simple `q48_from_u64()` scale first assumed — + > Captain Bob wants real word-level conservation, mirroring §19.1's fleet invariant, and + > that conflicts with the existing absolute promotion threshold and moves `dict_hash`. See + > §17.7 (LEANING, paper only) for the open questions. This item does not resume until §17.7 + > reads DECIDED. - [ ] **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.