FABRIC.md §20 — VMs are patrons

§17 named four patrons and omitted the only kind already implemented. §9's
admission table has always included VM, and §6 says Hera becomes the first
entry; neither reconciles with a four-patron taxonomy.

This is a finding rather than a proposal. vm_physics_fleet_heat_sum() already
sums execution_heat_q48 across live VMs against Q48_ONE -- that is a Stadium's
K over VM patrons, and §19.1's definition was derived from it.

Two consequences:

- The outer level is unbounded. The VM physics registry is a kmalloc-backed
  linked list, self-described as "unbounded, not a fixed array", so heat is
  renormalised to 1.0 however many VMs exist. By §2's own test, fleet K is
  currently bookkeeping -- VM-CONSERVED? cannot fail. This also explains why
  the Artemis campaign's K-invariance arm found nothing: the quantity cannot
  vary. Bounding the population is what would make it measurable.

- Nesting is half-built. Outer Stadium holds VM patrons; each VM's inner
  Stadium holds words, blocks, ACLs and messages. That is §12 Q6's nested
  option with the outer level already present. LEANING nested.

Proposes VM mass = the capacity share Hera allocated, making §7 concrete and
giving Hera a lifecycle signal that distinguishes starved from small. Marked
proposal: VMPhysics has no share field today.

Resolves §20.5 #3: Hera is pinned, and any attempt to evict her is a kernel
panic asserted at the eviction site, not filtered out of the candidate set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-03 10:02:52 -04:00
co-authored by Claude Opus 5
parent 85f59fca2e
commit 1a5cd3fc74
+133
View File
@@ -1051,3 +1051,136 @@ noun was overloaded.
(`capsule_vm_physics.c:272`), which §18.5 forbids for anything influencing patron state.
**The transfer rule must be restated on tick count before L0 can use it.** This is the
single most concrete piece of work this section implies.
---
## 20. VMs are patrons
§17 named four patrons: blocks, words, ACLs, messages. That list is incomplete, and the
omission matters because the missing kind is the only one already implemented.
§9's admission table has always included VM — heat means *runs often*, reap is *death by
cooling* — and §6 states it directly: *"Hera becomes the first entry in it."* Those cannot
be reconciled with a four-patron taxonomy. **VMs are patrons.** Chronologically they are
the first ones.
**DECIDED.**
### 20.1 This is a finding, not a proposal
The outer Stadium already exists in working code:
- `vm_physics_fleet_heat_sum()` sums `execution_heat_q48` **across live VMs**, and
`vm_physics_conserved()` tests that total against `Q48_ONE`
(`capsule/capsule_vm_physics.c:456-461`).
- That is a Stadium's K, computed over VM patrons. §19.1's definition of K was derived
from it.
- Hera already reaps VMs; `TRIPOD.md` makes governing existence her defining contract.
So the mechanism §19 describes is not novel at the VM level. It is running now.
### 20.2 But the outer level is unbounded — fleet K is currently bookkeeping
`capsule_vm_physics.c:71-72` describes the VM physics registry plainly:
> *kmalloc-backed linked list, same pattern as capsule_birth.c's
> vm_registry_head/vm_registry_count — **unbounded, not a fixed array**.*
Heat is normalised to 1.0 regardless of how many VMs exist. Conservation therefore holds
*trivially*, by renormalisation, rather than because anything is constrained. Measure it
and it cannot fail.
§2 anticipated exactly this:
> *The bound is real and inescapable, and it is what gives K≡1.0 a fixed denominator.
> Without a hard outer wall, K is bookkeeping rather than a conservation law.*
**By the design's own test, the fleet K measured to date is bookkeeping.** This is not a
reason to distrust the DoE results — they measured what they measured, and per-VM physics
is real — but it does mean `VM-CONSERVED?` cannot currently fail, and should not be cited
as evidence that conservation is being *enforced*.
This is the same shape as §17.3's finding about the hot-words cache: adopting the Stadium
repairs a defect rather than renaming a mechanism. Here the repair is larger, because
bounding the VM population is what converts fleet K from an identity into a constraint.
**Consequence for the campaign:** any future claim resting on fleet K needs the bound in
place first, or it is a claim about arithmetic rather than about the system.
### 20.3 Nesting — §12 Q6 is less open than it looks
If VMs are patrons, the structure follows without further invention:
```
Outer Stadium patrons: VMs ← exists today (unbounded)
└── per-VM Stadium patrons: words, blocks,
ACLs, messages ← to be built
```
K conserved at each level, with messages as the only thing crossing a boundary. That is
precisely §12 Q6's *nested* option — *"K conserved at each level with messages as the only
thing crossing a boundary, which would mean no shared-memory atomicity is ever needed"* —
and the outer level is already there.
This does not close Q6 by itself, but it changes the question. The choice is no longer
between two greenfield designs; it is whether to formalise a nesting that is already half
built, or to collapse it into a single region and discard the level that works.
**LEANING nested.** See §20.5 for what still has to be settled.
### 20.4 A VM's mass is the capacity share Hera allocated it — PROPOSAL
Marked as proposal, not finding: `VMPhysics` currently holds only `execution_heat_q48`,
`last_active_ns` and `is_live` (`capsule_vm_physics.c:59-63`). There is no share field.
§7 says Hera's job is arena distribution, and that *allocating a VM's share is birthing
it*. If that share is the VM's mass, §19's density definition applies unchanged at the
outer level, and §7 stops being abstract.
The payoff is that Hera gets a strictly better lifecycle signal than heat alone:
| VM | Heat | Mass | Density | Reading |
|---|---|---|---|---|
| small, quiet | low | low | moderate | healthy — dense enough, merely small |
| big, idle | low | high | **low** | **sparse — reap or shrink** |
| small, busy | high | low | **high** | dense — a candidate to grow |
Heat alone cannot distinguish *starved* from *small*. Density can. `TRIPOD.md` states that
Hera uses the fleet K view for exactly this question — *"Is a child VM healthy? Is a child
VM starved?"* — and density is the quantity that actually answers it.
Note this stays within `TRIPOD.md`'s constraint that fleet K is **lifecycle telemetry, not
a dispatch mechanism**. Density informs whether a VM should exist or change size. It never
decides where work goes; that remains capability-based routing.
### 20.5 Open
1. **Bounding the VM population.** What is the outer Stadium's capacity, and what happens
at the bound — birth refused, or coldest VM reaped? The latter is consistent with §19.3
but means a VM can die because a new one was born, which needs to be an explicit,
stated behaviour rather than an emergent surprise.
2. **Is a VM's mass its allocated share, or one cell?** §20.4 proposes the share. The
alternative — every VM is one entry regardless of size — is simpler but throws away the
distinction in the table above, which is the reason to do this at all.
3. ~~**What is Hera's own mass?**~~ **RESOLVED — Hera is pinned, and her eviction is a
panic.**
She is the first patron and she governs the rest, so she is subject to §3's pin wire:
invariance, not longevity. That is the correct use of pin rather than an exception to
the rules.
But pinning alone is a silent guarantee, and a silent guarantee that fails under load is
worse than none. **If the engine ever selects Hera for eviction, that is a kernel
panic**, not a skipped iteration and not a logged warning. The condition is
unreachable by construction; reaching it means the invariant is already broken and
continuing would run the system without a governor.
State it as an assertion at the eviction site, not as a filter on the candidate set —
filtering hides the bug, asserting reports it.
Her mass is still whatever §20.4 resolves for VMs generally. Pinning governs whether she
can depart, not how much room she takes.
4. **Does the nesting recurse further?** A VM's Stadium holds patrons; if one of those
patrons were itself a VM, the structure is a tree rather than two levels. Nothing
currently requires this, and §11 would call it speculative generality — but it should be
ruled out deliberately, since the boot order in §6 does not forbid it.