Files
LithosAnanake/FABRIC-2.md
T
Robert Allan JamesandClaude Sonnet 5 b42993322c FABRIC-2.md: close block_subsystem encoding-field item, wider scope found
Investigated 2026-08-13: not just the encoding field -- blk_get_meta()/
blk_set_meta() and the whole blk_meta_t on-disk layout have zero callers.
Captain Bob's ruling: flag and leave as-is, expected to be consumed once
Artemis's design (content-typed/owned/ACL'd blocks) is completed. No
code changed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 09:32:16 -04:00

14 KiB
Raw Blame History

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 §124, 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.14.3.7f, 4.44.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

  • 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.

  • 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

  • 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.

  • 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.

  • 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.

  • hotwords_cache_promote() has a NULL-write bug on a full cache. Unreachable under today's workloads, not fixed.

  • heartbeat_trust() has zero callers — dead code.

  • m5_time_trust/m5_variance are declared and never used.

  • 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).

  • 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.


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.
  • §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.
  • §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.

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.