FABRIC-2.md: close Fleet heat leak item -- truncation claim doesn't hold

Punch list §B item complete. Full read of capsule_vm_physics.c plus a
worked example show the touch()-fan-out truncation FABRIC.md §20.2
blamed cannot cause conservation drift -- vm_physics_transfer() moves
matched amounts on both sides of every call. Git history rules out a
since-fixed bug: the code predates §20.2's correction unchanged.

The one path that can genuinely drop heat is vm_physics_retire()'s
guarded no-valid-root case, structurally unreachable today (Hera can't
be killed, parent chains can't corrupt). Tracked as its own item in §C.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-13 08:21:32 -04:00
co-authored by Claude Sonnet 5
parent 389ca74d9f
commit 05c8462f2f
+43 -1
View File
@@ -52,12 +52,46 @@ and recorded.
## 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)
- [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
@@ -87,6 +121,14 @@ and recorded.
## 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. Both
triggering conditions are structurally excluded today (`capsule_vm_kill` refuses to kill
Hera; `parent_vm_id` is set once at birth and never rewritten), so this is unreachable
under current invariants, not fixed. Found while investigating the "Fleet heat leak" item
above, 2026-08-13.
- [ ] `arch_mmu_init()` is declared and defined on all three architectures but never called
anywhere — dead code. Found during item 4.3.5a.
- [ ] `include/block_subsystem.h:168`'s `encoding` field (ASCII/UTF-8/binary) is dead