FABRIC-3.5.md §XXXII: item 22 settled -- retire the pump, the switcher is the sole mover of control

§XXXI.5 found FABRIC-3 carrying an open defect where both the MSG-TICK
pump and the Stage-3/4 switcher can independently move control between
the same VMs, a live instance of what §XV.3 forbids as a principle.
Settled, and the reshuffle turns out to close it rather than inherit it.

Kernel-Hermes publishes eligibility and does not dispatch. The switcher,
which moves control by saving and restoring a per-VM native stack,
becomes the sole path; the pump, which moves control by nested
vm_interpret on the shared kernel C stack, retires.

Three reasons. The pump is already legacy by §XIV.1, existing only to
drain per-VM FORTH queues that kernel-Hermes will hold instead, so
retiring it is a consequence of a ruling already made rather than a new
decision. It is also a known scaling wall: §XXII records it as O(N) per
idle beat with no cap, caught live at just 9 VMs on riscv64 where a
campaign that finished in 200-340s elsewhere never finished at all, then
band-aided with batching that trades per-VM latency for bounded cost,
with its own comment naming hundreds of VMs as the endgame. And "not
observed failing" carries little weight here by FABRIC-3's own finding --
§XXVIII.1 records that Stage 3 emits nothing per switch by default, so a
switch storm and a healthy idle REPL produce an identical serial log, and
the corruption it fixed was live in every previously clean boot.

Reconciles with §XV.3 rather than amending it: moving control is a
mechanism, deciding whose turn it is is a policy. The switcher is the
mechanism; the compudynamics remains the policy and is still owned by
nobody. The defect was never about deciding but about two physical paths
for the same transfer. Also notes this makes §XXIII.4 implementable,
since checking the sinking latch "on giving a VM its turn" silently
assumed a single place where turns are given.

Verifies the dependency: the ruling would strand identity VMs unless the
switcher covers them, and §XXX records Stage 4's WIREBIND-scope extension
as built and verified live. It holds only because Stage 4 landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
This commit is contained in:
Claude
2026-09-19 11:27:04 +00:00
parent afcaeebbc7
commit 7aa9bad243
+105
View File
@@ -3236,3 +3236,108 @@ the ruling. Every design decision stands.
discipline was *verifiable* only while the documents used checkboxes (§XXXI.2). If the series
continues in prose, "what is still open" needs a deliberate mechanism — because two documents
have now closed with items nobody chose to drop.
---
## XXXII. Item 22 SETTLED: retire the pump — the switcher becomes the sole mover of control
§XXXI.5 found that `FABRIC-3.md` carries an open defect — "**both mechanisms can independently
move control between the same VMs**" — which is a live instance of what §XV.3 forbids as a
principle. Settled here, and **the reshuffle turns out to be the thing that closes it rather
than the thing that inherits it.**
### XXXII.1 — The two mechanisms, and why only one should survive
| | How it moves control | Fate |
|---|---|---|
| **The MSG-TICK pump** (`repl.c` idle loop) | `VM-EXEC`s `"MSG-TICK"` into a VM — a nested `vm_interpret()` on the **shared kernel C stack** | **Retired** |
| **The Stage-3/4 switcher** (`sk_vm_context_switch()`) | Saves and restores a **per-VM native stack**, timer-driven | **Sole survivor** |
**RULING: kernel-Hermes publishes eligibility; it does not dispatch.** It marks a target as
having work and the switcher — the one mechanism that moves control — delivers when it next
resumes that VM on the VM's own stack. Two control-movement paths collapse into one.
### XXXII.2 — Three reasons this is the right direction, not merely a tidy one
1. **The pump is already legacy by §XIV.1.** It exists for exactly one purpose: to drain
*per-VM FORTH message queues* by executing `MSG-TICK` inside each VM's dictionary. Once
kernel-Hermes holds the queues, there is nothing for it to drain. **Retiring it is not a new
decision — it is a consequence of a ruling already made.**
2. **The pump is a known scaling wall, already band-aided once.** `FABRIC-3.md` §XXII records
it walking the entire live-VM registry every idle beat, `VM-EXEC`ing into every VM — "O(N)
per tick, forever, with no cap" — **caught live as a real bottleneck at just 9 VMs on
riscv64**, where a campaign that finished in 200–340 s on amd64/aarch64 never finished at
all. Fixed by round-robin batching (`SK_MSG_PUMP_BATCH`), which bounds cost to O(K) **at the
price of per-VM latency depending on registry position.** Its own comment names the
endgame: "the real fleet is headed toward hundreds of VMs, at which point this isn't a
riscv64 quirk — unconditional O(N) per second is a wall on every architecture."
**Retiring the pump removes the wall and the latency tradeoff together.**
3. **"Not observed failing" is worth very little in this specific subsystem**, and
`FABRIC-3.md` says so itself. §XXVIII.1 is a correction to §XXVIII's own "Stage 3 CLOSED"
claim: "Zero fault indicators" was true only of what was *visible*, because "**Stage 3 emits
nothing per switch by default, so a switch storm and a healthy idle REPL produce an
identical serial log.** The corruption below was already live in every one of those 'clean'
Stage 3 boots; nothing in that verification pass could have shown it."
**A defect flagged "not observed failing" in a subsystem that is invisible by default is not
evidence of health.** That is the project's own finding, not an inference.
### XXXII.3 — Reconciling with §XV.3: one *mover*, still no *owner*
§XV.3 ruled that **nothing owns turn order.** Naming the switcher the sole mover looks like it
names an owner. It does not, and the distinction is the one §XV.3 already relies on:
> **Moving control is a mechanism. Deciding whose turn it is is a policy.** The switcher is the
> mechanism. The compudynamics remains the policy, and it is still owned by nobody.
So §XV.3 stands unamended. **The dual-ownership defect was never about deciding** — both the
pump and the switcher move control without either claiming to choose who runs next. It is about
two *physical paths* for the same transfer, which is a correctness problem (stack ownership),
not an authority problem. Collapsing them resolves it without touching the principle.
**And it makes §XXIII.4 implementable.** That section ruled the sinking latch is checked "on
giving a VM its turn" — which silently assumes there is **one** place a VM gets its turn. With
two movers that check has two homes, or one, and misses. **§XXIII.4 already depended on this
ruling without saying so.**
### XXXII.4 — The dependency this rests on, verified
The ruling strands identity VMs unless the switcher covers them. **Checked:** `FABRIC-3.md`
§XXX — "**Stage 4 — WIREBIND-scope extension, built and verified live (2026-09-14/15)**,"
Captain Bob's call to proceed immediately, built in the same one-commit-per-increment
discipline as Stages 0–3.
**So the switcher already covers WIREBIND identity VMs, not just the Tripod fleet.** Had Stage 4
still been the "ratified-decision-only, not implemented" step §XXVIII left it as, this ruling
would have been unbuildable and identity VMs would have lost their delivery path entirely.
**It holds only because Stage 4 landed.**
### XXXII.5 — Open for the build, not decided here
1. **Where the payload waits.** Delivery must still cause the payload to *execute inside* the
target — `messaging.4th` block 5041: "Payload is FORTH text, executed by the receiver, same
as every other message here." Under this ruling the switcher resumes the target on its own
stack, so kernel-Hermes must leave the payload somewhere the target consumes on resume. The
shape of that hand-off is a build decision.
2. **Hera's special case.** Per §XX of `FABRIC-3.md`, Hera is skipped by the pump and instead
gets a direct `MSG-TICK` word dispatch in her own context, because "she *is* the pump" and
self-targeting `VM-EXEC` would hit a known reentrancy class. **With the pump gone, that
special case should go with it** — her queue is kernel-held like everyone's. Confirm rather
than assume.
3. **The reentrancy guards.** `g_mama_interpreting` and `g_idle_pump_active` (`repl.c`) exist
specifically because the pump makes nested `vm_interpret()` calls. They likely retire with
it — **but carefully**, since §XXVIII.2's switch storm lived in this neighbourhood. Remove
only what is provably unreachable, per §XXII's own strip discipline.
### XXXII.6 — Punch list
- ✅ **Item 22 — SETTLED** (§XXXII): retire the pump; the switcher is the sole mover of control;
kernel-Hermes publishes eligibility and does not dispatch. **Folds into the kernel-Hermes
work (item 6) rather than preceding it** — §XXXI.5 filed it ahead on the assumption it was a
separate defect to fix first; it is instead a property of how kernel-Hermes is built.
- ⬜ Items 23–26 unchanged (§XXXI.8): re-home §17.4; consolidate the reported-not-scheduled
registries; decide `FABRIC-2`'s five orphaned design items; reconcile `FABRIC-0`'s seven opens.
**Worth recording as the pattern this makes four of:** §XXXI.5 read as a risk the reshuffle
would walk into. Examined, it is a defect the reshuffle *removes* — because the mechanism that
creates it is the same FORTH messaging layer already ruled legacy. **The gap analysis found a
problem that the design had already solved without noticing.**