Live console/framebuffer stack has zero dirty-region or heat/decay instrumentation (grepped framebuffer.c/vt100.c/console.c). True prerequisite is item 1.11 (dirty-event granularity), still unstarted, not 'the framebuffer work' generally, which has since shipped. Left open.
359 lines
25 KiB
Markdown
359 lines
25 KiB
Markdown
# FABRIC-2.md — the Stadium, continued
|
||
|
||
**Status:** Living working document, opened 2026-08-12 as the successor to `FABRIC.md`
|
||
(now closed/archival — see its own header). This document does not repeat `FABRIC.md`'s
|
||
design argument or history; it restates only outcomes, with pointers back to the section
|
||
that derived them. Read `FABRIC.md` for the "why," this document for the "what's left."
|
||
|
||
**Provenance.** Everything below came from a full, non-sampled read of the entire 7,595-line
|
||
`FABRIC.md` on 2026-08-12, looking for anything not yet resolved: unchecked punch-list
|
||
items, the architectural "### N.N Open" subsections in §1–24, the §25.7 "reported, not
|
||
scheduled" list, and any other "not yet"/"deferred"/"still open" language in the document.
|
||
Item numbers below are carried forward unchanged from `FABRIC.md` where one already existed,
|
||
for traceability — this is not a renumbering.
|
||
|
||
**How to use this document going forward.** New findings, new punch-list items, and new
|
||
decisions get added here, not to `FABRIC.md`. Follow the same discipline `FABRIC.md` §25.0
|
||
established (read it there — it isn't repeated here) for how work gets picked up, closed,
|
||
and recorded.
|
||
|
||
---
|
||
|
||
## A. Blocked or scoped, not started
|
||
|
||
- [ ] **1.11 — Dirty-event granularity.** Leaning region-based. Blocked on item 4.3 — settled
|
||
as part of the console migration, not speculatively before it. *Refs (FABRIC.md):* §17.5,
|
||
§23.2, §23.4 #1.
|
||
|
||
- [ ] **4.3 — Console.** Umbrella item; settles 1.11 as part of the work. Nearly everything
|
||
under it (4.3.1–4.3.7f, 4.4–4.4ac) is done — the parent stays open only because 4.4s below
|
||
is still blocked and nothing has formally closed the umbrella. *Refs (FABRIC.md):* §17.5,
|
||
§27.
|
||
|
||
- [ ] **4.4s — `(user)` prompt segment.** Scoped, blocked, not started. Extends 4.4's prompt
|
||
format. *Refs (FABRIC.md):* §27.8, 4.4.
|
||
|
||
- [ ] **4.6 — Artemis last.** It works today; it is the thing that cannot be broken. Not
|
||
started.
|
||
|
||
- [ ] **5.1 — Re-run the DoE on the new substrate.** A green POST suite is not evidence that
|
||
determinism holds under the Stadium migration — needs its own campaign. Not started.
|
||
|
||
- [ ] **5.2 — Isabelle/HOL.** One datatype, one index space, one conservation theorem. Not
|
||
started.
|
||
|
||
- [ ] **5.3 — Shrink the subsystem documents.** `ARTEMIS.md`, `HERMES.md`, `CONSOLE.md`,
|
||
`TRIPOD.md` need trimming now that `FABRIC-2.md` (via `FABRIC.md`) is the design-of-record.
|
||
Not started. **Specific pending edit found within this item:** `TRIPOD.md`'s own Immediate
|
||
Goal section still describes Hera spawning Hermes and Artemis automatically at boot — item
|
||
0.1 undid that behavior, and the doc was never updated to match.
|
||
|
||
---
|
||
|
||
## B. Live and unmeasured — deferred while Tripod was pruned to Hera-alone, now genuinely live since item 4.2 restored Hermes
|
||
|
||
- [x] **Fleet heat leak.** Integer-truncation drift in `vm_physics_touch()` (FABRIC.md §20.2)
|
||
was explicitly noted as invisible with only Hera resident, and "becoming measurable the
|
||
moment Phase 4 restores Hermes/Artemis." Phase 4 has now restored Hermes (item 4.2). This
|
||
is the single most concrete open item carried into this document — real, live, and
|
||
unmeasured.
|
||
|
||
> **INVESTIGATED 2026-08-13 — §20.2's truncation claim does not hold; no live drift risk
|
||
> exists today.** Full read of `capsule_vm_physics.c`: every write to
|
||
> `execution_heat_q48` goes through exactly one of `vm_physics_init()` (birth),
|
||
> `vm_physics_transfer()` (`:176-183`), or `vm_physics_retire()`'s zero-out after transfer
|
||
> (`:277`) — confirmed via a repo-wide grep, nothing else touches the field.
|
||
> `vm_physics_transfer()` moves an identical amount off `from` and onto `to` in the same
|
||
> call (`from -= moved; to += moved`), unconditionally. The touch() fan-out (`:334`,
|
||
> `share = (moved_total * heat) / others_total`) truncates per-VM, so `sum(shares) <
|
||
> moved_total` — but each `share`, truncated or not, is what actually leaves its VM *and*
|
||
> what actually arrives at the touched VM, via the same `vm_physics_transfer()` call. A
|
||
> worked example: others_total=10 (A=5, B=5), moved_total=7 → share_A=share_B=3, sum is 6
|
||
> not 7. Fleet sum before = 10+target; after = (2+2)+(target+6) = 10+target. Identical. The
|
||
> truncation is a rate-fidelity shortfall (the touched VM pulls in less than the physics
|
||
> model intended) — it cannot move the fleet-wide sum, because nothing is ever subtracted
|
||
> from one place without the identical amount landing at exactly one other. This matches
|
||
> the header's own contemporaneous claim (`capsule_vm_physics.h:31-33`): conservation is
|
||
> "held by construction: every state change is a balanced transfer." Git history rules out
|
||
> a since-fixed bug: `vm_physics_transfer()` and the touch() loop are unchanged since the
|
||
> file's creation (`a5ed8c3`, 2026-08-01), predating §20.2's correction (`055e944`,
|
||
> 2026-08-03) — the claim was made about the exact code read here, not an earlier version
|
||
> of it.
|
||
>
|
||
> **The one path that can genuinely drop heat** is `vm_physics_retire()`'s guarded
|
||
> "no valid root" case (`:271-275`) — the dying VM's remainder has nowhere
|
||
> conservation-preserving to go if it IS the root, or its parent chain is broken. Both are
|
||
> structurally excluded today: `capsule_vm_kill` refuses to kill Hera, and
|
||
> `parent_vm_id` is set once at birth and never rewritten, so a well-formed chain can't
|
||
> corrupt itself. Real in principle, unreachable under current invariants — tracked
|
||
> separately in §C below rather than as a live measurement task.
|
||
>
|
||
> FABRIC.md §20.2 itself should eventually be corrected to match (currently still asserts
|
||
> the truncation causes monotonic drift); not done here to keep this document's discipline
|
||
> of not editing `FABRIC.md` further.
|
||
|
||
- [x] **Multi-VM heartbeat ownership.** Whose `tick_target_ns` drives the one physical timer
|
||
(FABRIC.md §26.5) has only one answer while Hera is the only VM; explicitly "not resolved
|
||
for when Hermes/Artemis return." Hermes has returned (item 4.2). Same situation as the
|
||
fleet heat leak above — a deferral whose triggering condition has since become true.
|
||
**Ruled:** there is exactly one physical timer, so exactly one VM may write its re-arm
|
||
period — never whichever VM's `vm_tick()` happened to run last. Hera is the fixed point
|
||
everywhere else in this design (patron zero, sole capacity arbiter, sole birther/killer of
|
||
VMs — see FABRIC.md §20.2, §26), so she is the sole owner here too. Every other VM's Loop
|
||
#7 (`vm_tick_inference_engine()`) still adapts its own `vm->heartbeat.tick_target_ns`
|
||
exactly as before — that per-VM bookkeeping is correct and untouched — it simply never
|
||
reaches the shared physical re-arm; only Hera's does.
|
||
*Done when:* `vm_tick_inference_engine()` gates the physical-timer re-arm behind
|
||
`vm_uuid_is_hera(vm->stadium_vm_id)`, and a three-arch QEMU boot with Hermes live (item
|
||
4.2) is clean.
|
||
*Refs (FABRIC.md):* §20.2, §26.5.
|
||
|
||
> **DONE 2026-08-13.** `vm_tick_inference_engine()`
|
||
> (`src/starkernel/vm/vm_runtime.c:766`) now wraps the kernel-base re-arm block in
|
||
> `if (vm_uuid_is_hera(vm->stadium_vm_id))`, using the existing
|
||
> `vm_uuid_is_hera()` (`src/starkernel/capsule/vm_uuid.c:51`) already used the same way at
|
||
> the birth/kill call sites in `capsule_birth.c` and `capsule_vm_physics.c`. Three-arch
|
||
> acceptance boot, all clean to `ok>`, Hermes live and self-testing in every log:
|
||
> `logs/20260813-075940/amd64`, `logs/20260813-080125/aarch64`,
|
||
> `logs/20260813-080257/riscv64`. Committed `bcc72d0`.
|
||
|
||
---
|
||
|
||
## C. Reported bugs and dead code, not yet fixed
|
||
|
||
- [x] **`vm_physics_retire()`'s dropped-remainder case.** (`capsule_vm_physics.c:271-275`)
|
||
If the dying VM is itself the fleet root, or its parent chain is broken, its remaining
|
||
heat has nowhere conservation-preserving to go and is zeroed instead of transferred — a
|
||
genuine, if narrow, violation of the `sum(execution_heat) == Q48_ONE` invariant. Found
|
||
while investigating the "Fleet heat leak" item above, 2026-08-13.
|
||
|
||
> **CORRECTION, same day:** the "structurally excluded" framing this item originally had
|
||
> was wrong — the Hera case *was* reachable. `mama_word_kill()`
|
||
> (`mama_forth_words.c:520-530`) called `vm_physics_retire(entry.vm_id)` for any live-state
|
||
> VM found by name, with no Hera check, *before* `capsule_vm_kill()`'s own Hera guard
|
||
> (`capsule_birth.c:313-316`) ever ran. `S" Hera" KILL` therefore hit
|
||
> `vm_physics_retire()` with Hera's own id; her self-referential `parent_vm_id` made
|
||
> `vm_physics_find_root_id()` return her own id immediately, `root` came back `NULL`, and
|
||
> the fleet's entire `execution_heat_q48` sum was silently zeroed — with only the
|
||
> harmless-looking "cannot kill Hera" message as visible output, since that guard runs
|
||
> second. The broken-parent-chain half of this item remains genuinely unreachable
|
||
> (`parent_vm_id` is set once at birth and never rewritten); only the Hera half was live.
|
||
>
|
||
> **DONE 2026-08-13.** Fixed by excluding Hera from the retire call at the one call site,
|
||
> mirroring `capsule_vm_kill()`'s existing guard: `mama_forth_words.c`'s
|
||
> `capsule_vm_find_by_name_nocase(...) && entry.state == VM_STATE_LIVE` condition gained
|
||
> `&& !vm_uuid_is_hera(entry.vm_id)`. No change to `vm_physics_retire()` or
|
||
> `capsule_vm_kill()` itself. Three-arch acceptance boot, all clean to `ok>`:
|
||
> `logs/20260813-083429/amd64`, `logs/20260813-083551/aarch64`,
|
||
> `logs/20260813-083738/riscv64`. Committed `db66406`.
|
||
- [x] **`arch_mmu_init()` — TODO, not accidental dead code.** Declared (`arch.h:73`) and
|
||
defined on all three architectures (`amd64/arch.c:246`, `aarch64/arch.c:169`,
|
||
`riscv64/arch.c:179`) but never called anywhere — confirmed by repo-wide grep, 2026-08-13.
|
||
Each definition is a real doc-commented no-op stub ("paging will be wired up in later
|
||
milestones" / "MMU bring-up deferred" / "Sv39/Sv48 bring-up deferred"), and each comment
|
||
describes it as satisfying "the common `arch_mmu_init()` call site shared across all three
|
||
ISAs" — a call site that does not exist anywhere in the tree today. `vmm.c` (M3) handles
|
||
page-table management independently and does not need this hook to function. Captain Bob's
|
||
call, 2026-08-13: leave the three stubs in place as scaffolding for a future per-arch MMU
|
||
milestone rather than deleting or wiring in a no-op call site now — ruling recorded, closed
|
||
as investigated/not-a-bug rather than left open. Found during item 4.3.5a.
|
||
- [x] **`include/block_subsystem.h:168`'s `encoding` field (ASCII/UTF-8/binary) is dead
|
||
metadata — nothing reads or writes it.** (FABRIC.md §27.6) Investigated 2026-08-13, scope
|
||
turned out wider than the field itself: `blk_get_meta()`/`blk_set_meta()`
|
||
(`src/block_subsystem.c:881,903`) are the only public API for the whole `blk_meta_t`
|
||
struct and have **zero callers anywhere in the tree** — not just `encoding` but
|
||
`content_type`, `content_length`, `owner_id`, `permissions`, `acl_block`, `signature`,
|
||
`entropy`, `hash`, the chain fields, and `app_data[15]` are all unused. The struct is a
|
||
real fixed on-disk byte layout (packed 341 bytes/block into `META_REGION_OFFSET`,
|
||
`src/block_subsystem.c:69-71`), serialized via `meta_to_slice()`/`meta_from_slice()`
|
||
during cache writeback/load — so it isn't free-standing dead code to delete, removing a
|
||
field would shift every subsequent field's on-disk offset. **Ruling (Captain Bob,
|
||
2026-08-13): flag and leave as-is** — this metadata subsystem is scaffolding expected to
|
||
get consumed once Artemis's design (content-typed/owned/ACL'd blocks) is completed, not a
|
||
bug to fix now.
|
||
- [ ] `tools/README.md` documents a `fbtest.c` example that does not actually exist in
|
||
`tools/` — stale-doc discrepancy. Confirmed 2026-08-13, and the discrepancy is two-sided:
|
||
`git log --all` shows `fbtest.c` was never added to the repo at any point — the table
|
||
entry describes a tool that was documented but never built. Meanwhile `tools/ttftest.c`
|
||
(added `5f6cc05`, item 4.3.7, TrueType parser core test) is a real tool that exists on
|
||
disk but has no README table entry at all. Left unfixed pending explicit instruction
|
||
(README edit would be a fix, not just an investigation).
|
||
- [x] **`hotwords_cache_promote()` has a NULL-write bug on a full cache.** Confirmed
|
||
2026-08-13: the full-cache branch (`src/physics_hotwords_cache.c:362-371`) writes `word`
|
||
into `cache->cache[cache->lru_index]` unconditionally once `cache->cache_count >=
|
||
HOTWORDS_CACHE_SIZE` — it does not check `word` for NULL on that path, unlike the
|
||
slot-available branch below it, which does. A NULL `word` would silently evict a live
|
||
cache entry and replace it with NULL. Confirmed unreachable in practice: all four call
|
||
sites (`physics_hotwords_cache.c:284`, `physics_execution_hooks.c:140`,
|
||
`rolling_window_of_truth.c:787`, `src/starkernel/vm/vm_core.c:731`) only call
|
||
`hotwords_cache_promote()` after a `DictEntry*` NULL check has already passed. **Ruling:**
|
||
flag and leave as-is, matching the `arch_mmu_init()`/block_subsystem precedent — real
|
||
defect, no live trigger, not fixed without explicit instruction.
|
||
- [x] **`heartbeat_trust()` has zero callers — dead code.** Stale claim, corrected 2026-08-13:
|
||
`heartbeat_trust()` (`src/starkernel/heartbeat.c:205`) is called from
|
||
`src/starkernel/kernel_main.c:913`, printed as the `trust=0x...` field of the M5
|
||
heartbeat boot-milestone diagnostic line, alongside tick count and variance. Not dead
|
||
code — closed as investigated/not-a-bug.
|
||
- [x] **`m5_time_trust`/`m5_variance` are declared and never used.** Confirmed 2026-08-13:
|
||
repo-wide grep for both names turns up only their own declarations
|
||
(`include/vm.h:315-316`) — no reader, no writer, anywhere. Genuinely dead struct fields.
|
||
**Ruling:** flag and leave as-is, same precedent as the other Section C dead-code items —
|
||
not removed without explicit instruction.
|
||
- [ ] `src/*.c.bak` files (`vm.c.bak`, `doe_metrics.c.bak`, `inference_engine.c.bak`) remain
|
||
tracked in git at `src/` top level. Repo hygiene debt, not intentional (also noted in
|
||
`.claude/CLAUDE.md`).
|
||
- [ ] `bump-z`/`bump-y` Makefile targets reference `STARFORTH_VERSION_MAJOR`/`MINOR`/`PATCH`/
|
||
`STARFORTH_VERSION_STRING` fields that don't exist in the actual generated
|
||
`include/version.h` (also noted in `.claude/CLAUDE.md`).
|
||
- [x] **Kconfig/`menuconfig` has never been exercised end-to-end.** Every 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` default. Nobody has run
|
||
`make -f Makefile.starkernel menuconfig`, changed a value, and confirmed it flows through
|
||
to a build. Flagged by Captain Bob 2026-08-05.
|
||
|
||
> **DONE 2026-08-13.** The vendored `tools/kconfig` build had never actually succeeded on
|
||
> this machine — `bison`/`flex` were missing, installed with Captain Bob's go-ahead.
|
||
> `mconf` needs an interactive TTY this environment doesn't have, so the exercise used
|
||
> `conf` directly (same underlying engine `menuconfig` calls) rather than the ncurses
|
||
> frontend itself. `make -f Makefile.starkernel ARCH=amd64 kernel_amd64_defconfig`
|
||
> generated `build/amd64/.config` correctly (`CONFIG_SK_PARITY_DEBUG` unset, matching
|
||
> Kconfig's `default n`). Hand-editing that line to `CONFIG_SK_PARITY_DEBUG=y` and
|
||
> re-running the kernel build showed the real compile line for
|
||
> `src/starkernel/vm/parity.c` gained `-DSK_PARITY_DEBUG=1` (was `=0`), and the object
|
||
> compiled clean with it; reverting the line back to unset flipped the flag back to
|
||
> `=0`. Confirms the `mk/Kconfig.mk` bridge and `kconfig_bool` macro genuinely wire a
|
||
> `.config` change through to `-D` flags in both directions — this had never been
|
||
> verified before. One caveat found in passing, not itself a bug: invoking
|
||
> `tools/kconfig/conf` directly (bypassing the Makefile) writes a stray `.config` +
|
||
> `include/config/`/`include/generated/` at the repo root instead of under `build/`,
|
||
> since it doesn't pick up the `KCONFIG_CONFIG`/etc. env vars `mk/Kconfig.mk` exports —
|
||
> only matters if invoking `conf` by hand outside the Makefile targets, as done here;
|
||
> cleaned up before committing. No `.config`/`build/` artifacts committed — both are
|
||
> gitignored working state.
|
||
|
||
---
|
||
|
||
## D. Design questions still genuinely open
|
||
|
||
- [ ] **§12 Q5 — the full eight-loop interference analysis has not been done.** Its stated
|
||
blocker ("no real time base on all three ISAs") is gone — Phase 0 completed that — so this
|
||
is now unblocked and simply never picked back up.
|
||
|
||
> **ANALYSIS DONE 2026-08-13 — found a real violation of §22.4's required ordering, left
|
||
> open pending Captain Bob's call on how to handle it.** Traced every loop's actual firing
|
||
> cadence from source (`src/starkernel/vm/vm_core.c`, `vm_runtime.c`,
|
||
> `capsule_vm_physics.c`), in execution counts, not the nominal per-loop constant names:
|
||
>
|
||
> - **Cadence 1 execution:** Loop #1 (heat), Loop #2 (rolling-window record), Loop #4
|
||
> (pipelining) — every word dispatch.
|
||
> - **Cadence `HEARTBEAT_CHECK_FREQUENCY` = 256 executions:** Loop #3 (background decay,
|
||
> batched), `rolling_window_service()`, `dict_adaptive_optimization_pass()`, L8 Jacquard
|
||
> vote, fleet-capacity-counter increment — all five in the same `vm_heartbeat_run_cycle()`
|
||
> call, zero separation between them.
|
||
> - **Cadence `HEARTBEAT_INFERENCE_FREQUENCY` ticks × 256 = 256,000 executions:** Loop #5
|
||
> (window width) + Loop #6 (decay slope) + Loop #7 (adaptive heartrate) — all three
|
||
> merged into one `vm_tick_inference_engine()` call, zero separation between them.
|
||
>
|
||
> Two real findings, not just tidiness:
|
||
>
|
||
> 1. **The fleet-capacity loop can fire *faster* than a VM's own heat loop, not slower —
|
||
> the opposite of §22.4's "capacity must be the slower loop."** §22.4 cites
|
||
> `vm_physics_heartbeat_tick()` (`capsule_vm_physics.c:454-459`) by name as the existing
|
||
> precedent for the required 1000:1 separation. But that function is called from *every*
|
||
> live VM's own `vm_heartbeat_run_cycle()` (`vm_runtime.c:502`), incrementing one shared
|
||
> global `fleet_heartbeat_tick_count`, and fires `vm_physics_tick()` once that shared
|
||
> counter — fed by all VMs at once — reaches `HEARTBEAT_INFERENCE_FREQUENCY` (1000). A
|
||
> lone VM needs 1000 of *its own* 256-execution cycles to trip its own inference gate;
|
||
> with `STADIUM_MAX_VM_COUNT`'s real default of 4 (Hera + 2×Hermes + Artemis, Tripod's
|
||
> actual topology), the shared fleet counter can reach the same threshold up to ~4×
|
||
> sooner in wall-clock terms. So in a live multi-VM fleet, capacity arbitration can run
|
||
> *more* often in real time than any individual VM's own heat-inference loop, not less —
|
||
> exactly the ordering §22.4 calls "required, not preferred" because getting it backwards
|
||
> "produces a system that thrashes while every individual rule looks correct."
|
||
> 2. **The fix §22.4 already specified was never actually built.** §22.4's own resolution
|
||
> text says the capacity-tick should get "its own named constant rather than literally
|
||
> sharing `HEARTBEAT_INFERENCE_FREQUENCY`... named and made a Kconfig symbol at
|
||
> implementation time (item 3.1)." `STADIUM_CAPACITY_TICK` exists in `Kconfig.kernel`
|
||
> exactly as promised, default 1000 matching the cited precedent — but repo-wide grep
|
||
> confirms it is never read by any code path. Its only other appearance is a
|
||
> compile-time static assertion in `include/starkernel/vm/stadium.h:118` checking it's
|
||
> `> 0`, which gates nothing at runtime. `vm_physics_heartbeat_tick()` still literally
|
||
> shares `HEARTBEAT_INFERENCE_FREQUENCY`, i.e. the code is still in the
|
||
> *pre-implementation* state §22.4 described as its starting precedent, not the resolved
|
||
> design it specified.
|
||
>
|
||
> Also found in passing, minor and not a correctness issue: `vm_tick()`'s own header
|
||
> comment (`vm_runtime.c:104`, "Aggregates all periodic optimization tasks (Loop #3 and
|
||
> Loop #5) into one place") is stale — Loop #3 is not called inside `vm_tick()`, it's
|
||
> called separately from `vm_heartbeat_run_cycle()` on the faster 256-execution cadence,
|
||
> not the 256,000-execution one `vm_tick()` itself gates.
|
||
>
|
||
> Where this leaves Q5: within a single cadence tier (the 256-execution cluster, or the
|
||
> 256,000-execution cluster), several nominally-distinct loops share one gate with zero
|
||
> separation between them — apparently intentional unification (Phase 2's "Unified
|
||
> Inference Engine" merged #5/#6, L8 explicitly reads #1–#7's latest outputs each vote),
|
||
> not obviously a bug. *Between* tiers, separation is comfortably past the order-of-magnitude
|
||
> minimum (256:1 and 1000:1). The one place separation is required by name and is not
|
||
> actually present is the heat/capacity pair finding #1 above — that's the concrete,
|
||
> verified answer to "the risk is interference." **Left open, not fixed**, per this
|
||
> document's discipline — whether to wire `STADIUM_CAPACITY_TICK` in for real (giving Hera
|
||
> her own slower cadence independent of per-VM tick counts) or something else is Captain
|
||
> Bob's call, not made here.
|
||
- [ ] **§17.4 — the framebuffer utility's internal heat/decay dynamics are undesigned.**
|
||
Explicitly "Open, deferred": not a Stadium patron, but what physics (if any) governs it
|
||
internally was never designed. Not blocking anything.
|
||
|
||
> **CHECKED 2026-08-13, still correctly not ripe — precondition refined, item left open.**
|
||
> The actual FABRIC.md text (end of §17.5, not really §17.4 — that section number is a
|
||
> loose reference to the same "OPEN, deferred" paragraph) is explicit: "What those
|
||
> dynamics are is a question for when the framebuffer work actually happens... it should
|
||
> not be designed speculatively now." The console/framebuffer work (item 4.3/4.4 series)
|
||
> has since substantially shipped and is live, which looks at first glance like that
|
||
> precondition is now met. It isn't: grepped `src/starkernel/hal/framebuffer.c`,
|
||
> `vt100.c`, `console.c` (1,800 lines total) for `heat`/`decay`/`dirty` — zero hits. Every
|
||
> write is immediate-mode (`fb_scroll_rows()`, `fb_scroll_rect()`, direct glyph blits at
|
||
> the point of writing); there is no damage list, no dirty-region tracking, nothing a
|
||
> per-region heat/decay scheme would even attach to yet. That's consistent with Section
|
||
> A's item 1.11 (dirty-event granularity) still being unstarted — this item's true
|
||
> prerequisite is 1.11, not "the framebuffer work" in general as originally framed here.
|
||
> Designing framebuffer-internal physics before the dirty-event mechanism they'd govern
|
||
> exists would be exactly the speculative work FABRIC.md warns against. Left open, framing
|
||
> corrected: blocked on item 1.11, not merely deferred.
|
||
- [x] **§23.4 #2 — cell-size validation against a real message shape.** "Check that a typical
|
||
message still fits in one cell" was never done — item 3.1's own done-note confirmed no
|
||
message-patron struct existed yet at the time. This is now checkable: item 4.2 built
|
||
Hermes's actual message/channel structures on the Stadium, so the 32-byte inline payload
|
||
can finally be validated against something real instead of a hypothetical.
|
||
|
||
> **SETTLED 2026-08-13, but not as originally framed.** Read Hermes v1's real message
|
||
> struct (`capsules/hermes/init.4th`, blocks 4100/4105/4143, item 4.2): `MSG-CELLS` is 9
|
||
> cells — `TYPE, FROM, TO, PADDR, PLEN, STADIUM-CELL, SEQ, CH, ORIG-TYPE` — at 8 bytes/cell
|
||
> (`cell_t` is `int64_t`/`long`, `include/vm.h:71-75`), i.e. **72 bytes**, already over
|
||
> §23.3's whole proposed 64-byte cell before any payload. And the payload itself is
|
||
> **not inline at all**: `MSG-SEND` (`:208-213`) takes a caller-supplied `paddr plen` —
|
||
> wherever the caller already put the bytes (a string literal via `S"`, a block buffer) —
|
||
> and stores only the pointer and length in the struct. There is no fixed-size inline
|
||
> payload field to check a message against. So §23.4 #2's literal question ("does a
|
||
> typical message fit in the 32-byte inline payload") is **moot, not answered**: the
|
||
> shipped design didn't adopt §23.3's speculative 64-byte-cell/32-byte-inline-payload
|
||
> scheme for messages at all, it used a larger fixed control block plus out-of-line
|
||
> pointer/length indirection instead. Closing as settled-by-divergence — the real
|
||
> implementation went a different direction than the design question assumed, which is
|
||
> itself the answer; §23.3's cell-size numbers were never made load-bearing for Hermes
|
||
> messages and nothing here depends on reconciling them.
|
||
|
||
---
|
||
|
||
## E. Documentation debt
|
||
|
||
- [ ] **Taxonomy / glossary.** Captain Bob's own flag, 2026-08-04: the physics vocabulary
|
||
(heat, mass, density, patron, Stadium, and Kconfig knob names built on it) needs an
|
||
explicit glossary stating these are named analogies, so code, Kconfig, and documentation
|
||
terminology don't drift apart over time. Never scoped into any phase. Real, acknowledged
|
||
debt: "I guess that we didn't finish out FABRIC.md quite as much as we thought."
|
||
- [ ] **ACL-RWT DoE overhead re-measurement.** The measured overhead numbers in
|
||
`.claude/CLAUDE.md` ("+0.0054%–+0.0088%") were all captured at `-O0`, before item 4.5
|
||
enabled real compiler optimization. Nobody has re-measured, or even confirmed the old and
|
||
new numbers are comparable at all. Flagged in passing during item 4.5f, never formally
|
||
scoped.
|