Captain Bob, 2026-09-18. A clean shutdown is a VM termination where flush is forced and the VM says BYE; Hera is the special case that halts the processor instead. Traced, and the ruling is almost entirely existing mechanism. blk_flush(0) is already the documented flush-all sentinel (block_subsystem.c:988-990) and already the Stadium's own write-back action. A child's BYE already terminates it -- system_word_bye sets vm->halted, which mama_forth_words.c's own doc comment describes as the child path. arch_halt() exists on all three architectures (amd64:207, aarch64:126, riscv64:170), so three-arch parity holds without new per-arch work. The one real finding is a behavioural change rather than a gap: Hera's BYE does not halt today, it cold-restarts. mama_word_bye() reaps children then calls arch_cold_reset(). The reaping half already matches the ruling; the terminal action is the opposite of it. Flagged so the change is made knowingly -- CLAUDE.md forbids modifying a registered tested word to "fix" it, and this is a ruled change rather than a fix, but it should not surface first in a diff. Whether suicide replaces BYE or becomes a separate word is left open as item 17, noting cold-restart-on-BYE is plausibly wanted for an operator typing BYE at Hera's REPL. Records a constraint on where the flush goes: system_word_bye lives in shared vendored source that must keep working in the hosted build, so the forced flush belongs in the kernel-side shutdown path, not inside BYE. §VIII.3's bounded-window question answers itself -- the window ends when Hera halts, a bound by construction with no timeout to tune, which is consistent with §XV.3's no-owner invariant. Item 9 is now half-answered. Raises one residual edge as analysis only: if Hera is already dead, nobody performs the halt, leaving a live kernel over an empty floor. An empty floor is arguably a kernel-observable condition rather than a VM's decision, which would terminate without any VM inheriting her authority. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VkM1zHGvBerLF6aqkHPweP
1267 lines
77 KiB
Markdown
1267 lines
77 KiB
Markdown
# FABRIC-3.5.md — the Tripod/kernel reshuffle
|
||
|
||
**Status:** Standalone working document, opened 2026-09-18 by direct instruction ("we write
|
||
this in `FABRIC-3.5.md` as its own document, it's this important"). Topic: **relocating Hermes
|
||
into the kernel, reconstituting the Tripod as Hera/Artemis/Console, generalizing `BIRTH`, and
|
||
adopting one fleet-wide failure/recovery ladder.**
|
||
|
||
**Why 3.5 and not 4, and why not a section of 3.** `FABRIC-4.md` is explicitly the
|
||
lower-discipline scratchpad for theory-stage ideas "caught early... often missing a stated
|
||
'why' on purpose." This is not that: it is a ratified architectural direction with a stated
|
||
shape, and it needs the full discipline every numbered FABRIC document carries. But it is
|
||
also not bare-metal boot, which is `FABRIC-3.md`'s declared topic, and it is not a successor
|
||
to `FABRIC-3.md` — **`FABRIC-3.md` remains open, living, and authoritative for its own
|
||
topic; nothing here supersedes it, and this document does not trigger the
|
||
close-and-carry-forward discipline** the `FABRIC-0` → `-1` → `-2` → `-3` chain used (that
|
||
chain triggers on *closing* a document). It sits at 3.5 because it is a peer in rigor and an
|
||
outsider in topic.
|
||
|
||
**How to use this document.** Same discipline as the rest of the series: write the decision
|
||
and its reasoning down before building, close items with a dated note citing real evidence,
|
||
never silently drop a stale claim. New findings and decisions for the reshuffle get added
|
||
here, not to `FABRIC-3.md`.
|
||
|
||
**Scope discipline, stated up front: this is a reorganization, not an invention.** Per the
|
||
instruction opening it — "most of the underlying logic (Hermes routing, Artemis block I/O,
|
||
Hera lifecycle/ACL, Console framebuffer) already exists and is expected to be relocated and
|
||
rewired rather than rewritten." Any item in this document that turns out to need a genuinely
|
||
new algorithm is by that fact out of scope and gets flagged, not quietly built.
|
||
|
||
**No code is authorized by this document.** Design only. Per Captain Bob's Law
|
||
(`.claude/CLAUDE.md`): never apply a fix not explicitly requested.
|
||
|
||
**Provenance convention used below.** This series distinguishes what was read from what was
|
||
recalled, so each claim says which. **"Traced 2026-09-18"** = the file was read directly while
|
||
writing this document. **"Per §X"** = the fact is reported by an existing FABRIC section that
|
||
did its own end-to-end read; it is cited, not re-verified here. **"Open"** = not decided.
|
||
Several items below are deliberately marked for re-verification before any code is written,
|
||
because a reorganization that trusts a stale map moves the wrong things.
|
||
|
||
---
|
||
|
||
## I. The current shape, traced rather than recalled
|
||
|
||
Before moving anything, what is actually there today. All of §I traced 2026-09-18 against the
|
||
working tree at commit `e56974e`, except where marked.
|
||
|
||
### I.1 — Hermes is a FORTH capsule VM, and the routing layer is FORTH, not C
|
||
|
||
`capsules/hermes/init.4th` is short and load-bearing. Its block 5116 says it outright:
|
||
|
||
> Hermes owns the one real, canonical `COMMON-CH`. Every other VM subscribes into it via
|
||
> `VM-EXEC` (see Artemis's and Hera's own `init.4th`); Hera always exists first, so Hermes
|
||
> adds her here rather than Hera subscribing to a VM that doesn't exist yet at Hera's own
|
||
> birth.
|
||
|
||
It then does `S" common:messaging.4th" EXEC`, `MSG-CD-INIT`, `1 MY-CH-ID !`, and adds members
|
||
`1` and `0` to `COMMON-CH`. That is the whole of Hermes's own identity: it is the VM that
|
||
happens to hold the canonical channel.
|
||
|
||
The mechanism it holds is `capsules/common/messaging.4th` (504 lines) — **generic per-VM
|
||
messaging vocabulary that every participating VM loads its own copy of.** This matters more
|
||
than it first appears. Block 5005 allocates the arenas with `CREATE ... ALLOT`:
|
||
|
||
```
|
||
CREATE MSG-ARENA MSG-MAX MSG-CELLS * CELLS ALLOT
|
||
CREATE CH-ARENA CH-MAX CH-CELLS * CELLS ALLOT
|
||
CREATE MBR-ARENA MBR-MAX MBR-CELLS * CELLS ALLOT
|
||
```
|
||
|
||
`CREATE`/`ALLOT` carves out of *the dictionary of whichever VM is interpreting*. So today
|
||
there is no single routing fabric — there are N per-VM copies of the same vocabulary, and
|
||
Hermes is distinguished only by convention (it holds `COMMON-CH`; it is routing table index
|
||
1). **The arbitration is distributed and conventional, not centralized and structural.**
|
||
|
||
### I.2 — Hermes is a hard, by-name dependency of its peers
|
||
|
||
> **CORRECTED 2026-09-18 by §XIII.1 — this section undercounts.** It names two call sites; the
|
||
> full repo-wide inventory is **14 by-name FORTH references across 5 files, plus 3 C-side
|
||
> sites and a DoE CSV schema site.** The two below are real, are among the only three *live*
|
||
> ones, and remain the sharpest edge — but read §XIII.1 for the actual extent. Left in place
|
||
> rather than rewritten, per this series' own "never silently drop a stale claim" rule.
|
||
|
||
Artemis does not talk to an abstract routing layer. It talks to a VM called `Hermes`, by name,
|
||
via `VM-EXEC`. Two live call sites in `capsules/artemis/init.4th`:
|
||
|
||
- line ~138: `S" 2 ENQUEUE-READY" S" Hermes" VM-EXEC`
|
||
- line ~501: `S" 2 COMMON-CH @ CH-ADD-MBR" S" Hermes" VM-EXEC`
|
||
|
||
Both execute FORTH text *inside Hermes's own dictionary*. Either one breaks the moment
|
||
Hermes is not a VM with a dictionary. This is the single most concrete consequence of the
|
||
move and §III.3 is about it.
|
||
|
||
### I.3 — The routing table pins 0/1/2 and says so
|
||
|
||
`messaging.4th` block 5006, verbatim comment:
|
||
|
||
> VM routing table. §XIX: 16 slots, not 8 — see `FABRIC-3.md`. Hera/Hermes/Artemis stay
|
||
> 0/1/2 (`artemis:init.4th` depends on it); identities get NEW slots 3–10, never renumbered.
|
||
|
||
`VM-NAMES-INIT` registers `Hera` 0, `Hermes` 1, `Artemis` 2, then identities from 3 up via
|
||
`DOE-IDX>MSG-IDX ( doe-idx -- msg-idx ) 2 +`. **"Never renumbered" is an existing, written
|
||
commitment, and the reshuffle walks straight into it** (§IV.2).
|
||
|
||
### I.4 — Message types in use, and the free numbers
|
||
|
||
Traced across `messaging.4th`: `SPAWN-EVENT` 1, `PAUSE-EVENT` 2, `RESUME-EVENT` 3,
|
||
`KILL-EVENT` 4, `CONSOLE-CMD-EVENT` 7, `ELEVATE-REQUEST` 8, `BLK-ATTACH-EVENT` 9. Reserved
|
||
status sentinels at the top of the range: `MSG-NACKED` 253, `MSG-DELIVERED` 255.
|
||
|
||
**5 and 6 are unallocated gaps; 10 is the next in sequence.** Relevant to §VII, which needs a
|
||
number for `SOS`. Also relevant: per §XX, `SPAWN-EVENT` was grepped for every consumer across
|
||
the tree and **has none** — "an unwired placeholder, not working infrastructure." Do not
|
||
model `SOS` on it as though it were a working precedent.
|
||
|
||
### I.5 — `BIRTH` is already VM-agnostic in C; Hera's monopoly is registration-time
|
||
|
||
Per §XX, which read `mama_word_birth` (`mama_forth_words.c:229`, `BIRTH`'s C implementation)
|
||
in full:
|
||
|
||
> It is genuinely VM-agnostic — it operates on whichever `vm` calls it, with no check that
|
||
> the caller is Hera specifically. The only Hera-specific logic anywhere in it is the reverse
|
||
> guard preventing Hera from re-birthing *herself*. `capsule_birth_baby()` treats
|
||
> `vm->stadium_vm_id` generically as "whoever is birthing this VM." So "any VM could
|
||
> theoretically birth another" is already true in the code... Hera's practical monopoly on
|
||
> `BIRTH` is a registration-time fact (only `register_mama_forth_words()` registers it), not
|
||
> a check inside `BIRTH` itself.
|
||
|
||
**This is the single most important pre-existing fact in this document.** §VI is not a
|
||
redesign of `BIRTH`; it is a change to which VMs get it registered, plus an inheritance rule.
|
||
|
||
### I.6 — Console already has a real bind mechanism, built and live-verified
|
||
|
||
Per §XXXII.2, closed 2026-09-16: `CONSOLE-ATTACH ( name-c name-u -- ok? )` exists, is a plain
|
||
unconditional primitive (deliberately *not* an identity capability bit — that was tried and
|
||
rejected on two counts), and was verified end to end on amd64: `UNATTENDED-BIRTH` a VM named
|
||
`bob` → `CONSOLE-ATTACH bob` → `S" bob" USE` → typing `5 6 + .` at the new console relayed to
|
||
and executed on the target identity VM, printing `[zuse@bob~user] 11 ok>`.
|
||
|
||
Also live: `capsule_console_birth()` (minimal relay proxy, bare username) paired to
|
||
`capsule_runcap_birth()` (the real identity, `<username>~user`) by name convention plus one
|
||
`VM-NAME-REG` executed inside the console VM's own dictionary — **confirmed per-console-VM,
|
||
not a global singleton, so after-the-fact pairing already works structurally.**
|
||
|
||
**§V is therefore mostly a promotion of an existing, proven mechanism to an architectural
|
||
role — not new construction.**
|
||
|
||
### I.7 — The headless-until-login invariant
|
||
|
||
Per §VIII.1 (ratified) and §XXXII.2: `g_wirebind_attached_username` is what
|
||
`sk_console_identity_present()` reads (`capsule_wirebind.c:321-327`), and that function is the
|
||
live "no thumbdrive, no prompt" gate. §XXXII.2 states the rule as an explicit invariant for
|
||
any new birth path: **never set that global, never touch the console-pairing mechanism, or you
|
||
bring up a console with no human present and reopen a gate that was deliberately closed.**
|
||
§V and §VI both have to carry this invariant forward.
|
||
|
||
### I.8 — The idle pump, and why Hera is special-cased in it
|
||
|
||
Per §XX: `repl.c`'s idle loop walks the VM registry every idle beat, `VM-EXEC`ing `"MSG-TICK"`
|
||
into every *other* live VM to drain its queue, skipping Hera — because Hera *is* the pump and
|
||
self-targeting `VM-EXEC` would hit a known reentrancy class. Hera instead gets a direct
|
||
`MSG-TICK` word dispatch in her own context, guarded by a fresh `vm_find_word` + `acl_allow`
|
||
check every tick rather than a cached flag.
|
||
|
||
**So there is already a kernel-resident component driving the messaging layer's clock.** The
|
||
pump is in `repl.c`, in C, today. §III is in part an admission that the arbiter's center of
|
||
gravity is already partly there.
|
||
|
||
---
|
||
|
||
## II. What the reshuffle is, in one paragraph
|
||
|
||
Hermes stops being a peer VM on the Stadium floor and becomes a kernel-resident arbiter
|
||
between the floor and the HAL. It stops being a *client* of ACL-checked, Hermes-routed
|
||
messaging and becomes the routing and arbitration layer itself. The Tripod — which was Hera,
|
||
Hermes, Artemis — is reconstituted as **Hera, Artemis, Console**, with Artemis keeping its
|
||
existing storage/block-arbitration role and Console taking the vacated third slot. Console's
|
||
own role widens from owning the drawing fabric to being the **bind point** where users and
|
||
agent VMs (the GPIO VM of `FABRIC-4.md` §2, future networking VMs) attach. `BIRTH` becomes a
|
||
general primitive any VM with standing may invoke, with authority bounded by inheritance
|
||
rather than by a separate check. And every VM in the fleet — current and future — adopts one
|
||
escalation ladder on failure: recover gently, escalate to a from-scratch birth, then fail fast
|
||
and total.
|
||
|
||
---
|
||
|
||
## III. Hermes moves into the kernel
|
||
|
||
### III.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
Hermes is no longer a Tripod VM. It becomes kernel-resident, sitting between the Stadium floor
|
||
and the HAL. **It no longer participates in Hermes-routed, ACL-checked messaging the way the
|
||
other VMs do — it *is* the routing/arbitration layer now, not a client of it.**
|
||
|
||
### III.2 — What that actually changes, structurally
|
||
|
||
The self-reference in "Hermes cannot be a client of Hermes" is the whole point, and it has a
|
||
concrete reading against §I.1: today Hermes holds `COMMON-CH` inside a FORTH dictionary that
|
||
is itself subject to the same ACL and Stadium-heat economy as every other VM's. An arbiter
|
||
whose own arbitration state can be evicted, cooled, or ACL-denied by the mechanism it arbitrates
|
||
is a circular dependency that happens not to have bitten yet. Moving it into the kernel breaks
|
||
the circle by construction.
|
||
|
||
Note this is also what makes §VII's `SOS` exception (Hermes cannot route a message announcing
|
||
its own routing failure) not a special case but a direct corollary — see §VIII.
|
||
|
||
### III.3 — The by-name `VM-EXEC` dependency has to go somewhere. Open.
|
||
|
||
> **SUPERSEDED 2026-09-18 by §XIV.1/§XIV.2 — this question dissolved.** The three options below
|
||
> all assume the existing FORTH callers must be preserved. Captain Bob ruled the FORTH
|
||
> messaging layer legacy, so §XIII.1's inventory becomes input to a dead-FORTH cleanup rather
|
||
> than a migration constraint. Left in place, not rewritten.
|
||
|
||
§I.2's two Artemis call sites are the sharp edge. `S" ..." S" Hermes" VM-EXEC` requires a
|
||
target VM with a dictionary. Three shapes are visible; **none is chosen here:**
|
||
|
||
1. **Kernel primitives replace the by-name calls.** `ENQUEUE-READY` and `CH-ADD-MBR` become
|
||
registered C words callable directly by any VM, and Artemis simply calls them. Closest to
|
||
"relocated, not rewritten"; largest registration-surface change.
|
||
2. **A vestigial `Hermes` name that the kernel answers.** `VM-EXEC` to `Hermes` is intercepted
|
||
and serviced by the kernel arbiter, leaving caller text untouched. Smallest diff, but it
|
||
preserves a fiction and this project has a standing distaste for exactly that
|
||
(§XXXII.2 Q3's rejection of an unreachable gate on doctrine grounds, not just mechanics).
|
||
3. **Artemis subscribes through a new kernel-side registration call at birth**, removing the
|
||
peer-to-peer step entirely.
|
||
|
||
**Decide this on paper before touching code.** Whichever wins, the two Artemis lines and the
|
||
`STARTUP-BANNER`/`LOG-INFO"` scaffolding in `capsules/hermes/init.4th` are the concrete edit
|
||
set, plus whatever else a full grep for `S" Hermes" VM-EXEC` turns up — **that grep has not
|
||
been run exhaustively for this document and must be, repo-wide, before scoping.**
|
||
|
||
### III.4 — The per-VM-arena question. Open, and the biggest unknown here.
|
||
|
||
> **RESOLVED 2026-09-18 by §XIV.1/§XIV.2.** Answered in the "full centralization" direction,
|
||
> but without the migration cost this section feared: with the FORTH legacy there is no live
|
||
> state to port. This was named the root dependency throughout §X; it is closed. Left in
|
||
> place, not rewritten.
|
||
|
||
Per §I.1 the arenas are per-VM dictionary allocations. If arbitration centralizes into the
|
||
kernel, does `MSG-ARENA`/`CH-ARENA`/`MBR-ARENA` centralize with it, or does each VM keep its
|
||
own outbox/inbox with only the *routing* centralized? These are very different amounts of
|
||
work and very different risk:
|
||
|
||
- **Routing-only centralization** keeps `messaging.4th` largely intact, keeps the Stadium heat
|
||
economy's "sender pays" property (per §XX: `STADIUM-RES-PULL`/`-PUSH` operate on the
|
||
*calling* VM's own reservoir), and is genuinely a reshuffle.
|
||
- **Full arena centralization** moves FORTH dictionary state into kernel C, changes every
|
||
VM's `dict_hash`, and needs the three-arch parity story re-established from scratch.
|
||
|
||
**Not decided.** Flagged here because the executive framing ("relocated and rewired rather
|
||
than rewritten") holds comfortably for the first and is strained by the second.
|
||
|
||
### III.5 — Parity consequence, stated so it is not discovered late
|
||
|
||
Any change to what `register_*_words()` registers, or to what `init.4th` loads, changes VM
|
||
dictionary contents and therefore `dict_hash`. §XX's own verification standard applies: the
|
||
property that matters is **identical `dict_hash` across amd64/aarch64/riscv64, not an
|
||
unchanging absolute value.** Expect the absolute hashes to move; require the cross-arch
|
||
identity to hold. Acceptance is the three-arch QEMU boot to `zuse)ok>` with zero
|
||
`UNKNOWN WORD` faults, per `.claude/CLAUDE.md`'s non-negotiable criteria — there is no other
|
||
test.
|
||
|
||
---
|
||
|
||
## IV. The Tripod reconstituted: Hera, Artemis, Console
|
||
|
||
### IV.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
Tripod = **Hera, Artemis, Console.** Artemis keeps its existing role (storage/block
|
||
arbitration) unchanged. Console takes the slot Hermes vacates.
|
||
|
||
### IV.2 — The "never renumbered" collision. Open, needs a ruling.
|
||
|
||
> **DISSOLVED 2026-09-18 by §XIV.1/§XIV.2 — via option 3 below, exactly as this section
|
||
> predicted.** The FORTH routing table is legacy, so the slot-numbering question has no
|
||
> subject. Option 3's own caveat ("settle §III.4 first") was the correct call. Left in place,
|
||
> not rewritten.
|
||
|
||
§I.3's comment commits to Hera/Hermes/Artemis at 0/1/2 and to identities at 3–10 *never*
|
||
being renumbered. Hermes leaving index 1 forces a choice, and the existing comment forecloses
|
||
the laziest option:
|
||
|
||
1. **Console takes index 1.** Tidy, preserves the "Tripod occupies 0/1/2" shape, and requires
|
||
no identity renumbering — but it silently redefines what slot 1 *means*, and
|
||
`artemis:init.4th`'s dependence on the numbering is on 2, not 1, so it may be survivable.
|
||
2. **Index 1 is retired; Console takes a fresh slot.** Honest, costs a slot out of 16, and
|
||
leaves a permanent hole that needs a comment explaining itself forever.
|
||
3. **The routing table stops being a FORTH array at all**, because §III moved routing into the
|
||
kernel — in which case this question dissolves into §III.4's arena question and should not
|
||
be answered separately.
|
||
|
||
**Not decided. Note option 3 makes 1 and 2 moot, so settle §III.4 first.** This ordering
|
||
matters: answering IV.2 before III.4 risks ratifying a table that the kernel move deletes.
|
||
|
||
---
|
||
|
||
## V. Console's role expands: the bind point
|
||
|
||
### V.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
Beyond owning the drawing fabric, Console becomes **the bind point for users and agent VMs** —
|
||
GPIO VM, future networking VMs, and whatever follows. The attach point that was previously
|
||
implicit or undecided now lives here, explicitly.
|
||
|
||
### V.2 — This is mostly promotion of an existing mechanism, not new construction
|
||
|
||
Per §I.6, `CONSOLE-ATTACH` already resolves a target's liveness by name *before* birthing a
|
||
console (so a typo refuses cleanly with no orphaned VM — verified live), and console/user
|
||
pairing already works after the fact. The reshuffle's contribution is **declaring that this is
|
||
the fleet's attach point**, and then asking the question the current mechanism does not yet
|
||
answer: it was built for *human at a console attaching to an identity VM*. An agent VM — a
|
||
GPIO VM per `FABRIC-4.md` §2, pinned and born at boot with no human anywhere near it — is a
|
||
different shape wearing the same word.
|
||
|
||
### V.3 — Genuinely open
|
||
|
||
1. **Does an agent VM bind through `CONSOLE-ATTACH` or through a sibling word?**
|
||
`sk_repl_dispatch_line()`'s pairing check reconstructs the target as
|
||
`console_get_vm_name() + "~user"` (per §XXXII.2, and the cause of a real bug caught live
|
||
when a console was named anything else). A GPIO VM is not a `~user` identity. Either the
|
||
naming convention widens or agent binding takes its own path.
|
||
2. **Does binding an agent VM touch `g_wirebind_attached_username`?** It must not — §I.7. State
|
||
this as an explicit invariant in whatever implements it, exactly as §XXXII.2 required of
|
||
unattended birth.
|
||
3. **Is Console's bind role ACL-gated, and if so where?** Per `.claude/CLAUDE.md`'s hard rule
|
||
and §XXXII.2 Q3's correction: policy belongs in `ACL.4th`, never in C. The shape is
|
||
`' CONSOLE-ATTACH ACL-PIN` (or a sibling word's equivalent) in `ACL.4th`, not a C-side
|
||
capability check — and specifically **not** a `vm_identity_has_cap()` gate, which §XXXII.2
|
||
proved unreachable because `identity.installed` is 0 for Hera/Hermes/Artemis and for every
|
||
console-proxy VM.
|
||
4. **Does Console-as-bind-point survive Console being a Tripod member?** A Tripod VM is pinned
|
||
and born at boot (`session_register()`/`session_set_pinned()`, per `FABRIC-2.md` §H.12
|
||
step 4; "pinned sessions never leave," §H.1 — **cited from `.claude/CLAUDE.md`'s and §XX's
|
||
references, not re-read for this document; verify before relying on it**). Whether the
|
||
drawing-fabric owner and the bind-point arbiter are the same VM or two roles that happen to
|
||
share a name is not settled here.
|
||
|
||
---
|
||
|
||
## VI. `BIRTH` as a general primitive
|
||
|
||
### VI.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
`BIRTH` is a general primitive, not Hera-exclusive. **Any VM with standing can invoke it.** A
|
||
birthed VM inherits its ACL/DNA from the birthing VM. **A VM can never birth something with
|
||
more authority than it itself holds — enforced by inheritance, not by a separate
|
||
authorization check.**
|
||
|
||
### VI.2 — Why this is small in C and large in policy
|
||
|
||
Per §I.5 the C implementation is already VM-agnostic; the monopoly is which registration
|
||
function hands out the word. So the mechanical change is registration, and the design work is
|
||
entirely in the inheritance rule.
|
||
|
||
The rule as stated is elegant precisely because it needs no gate: if a child's authority is
|
||
*derived* from the parent's, "cannot exceed the parent" is not a check that can be bypassed,
|
||
forgotten, or misconfigured — it is a property of how the child is constructed. This is the
|
||
same doctrine §XXXII.2 Q3 landed on from the opposite direction (a bespoke gate that can never
|
||
open is worse than no gate), and the same doctrine `ZUSE-ELIGIBILITY-ADD` already carries.
|
||
|
||
### VI.3 — "ACL/DNA" needs a precise referent. Open, and this is the real work.
|
||
|
||
The system has a **word-level** ACL: four `DictEntry` fields (`acl_ttl`, `acl_allow`,
|
||
`acl_mode`, `acl_pinned`), a C primitive `ACL-INHERIT` (traced 2026-09-18 in `capsules/ACL.4th`'s
|
||
own primitive list, line 6), and the semantics "pin is one-way; inheritance clears pin, copies
|
||
mode" (per `.claude/CLAUDE.md`). What §VI.1 describes is **VM-level** inheritance — a different
|
||
axis. Two things must be settled before any code:
|
||
|
||
1. **Is VM-level DNA just "the child's dictionary is built from the parent's, with per-word
|
||
state carried by the existing `ACL-INHERIT`"?** If yes, this is genuinely a reshuffle and
|
||
the existing primitive does the work. If no, something new is being invented and that
|
||
contradicts this document's own scope discipline — flag it rather than build it.
|
||
2. **Hard constraint:** `.claude/CLAUDE.md` states "Never add `acl_*` fields to `DictEntry`
|
||
beyond the four already present." Any DNA design that wants a fifth per-word field is
|
||
ruled out at the door. If VM-level authority needs state, it belongs on the VM, not on
|
||
every dictionary entry.
|
||
|
||
### VI.4 — "With standing" is undefined. Open.
|
||
|
||
§VI.1 says *any VM with standing*. Standing is not currently a concept in this codebase —
|
||
traced: no such notion appears in the ACL vocabulary or the Stadium words. Candidate readings:
|
||
(a) standing = simply having `BIRTH` registered, which collapses it into §VI.2's registration
|
||
question and makes the phrase decorative; (b) standing = a Stadium-economy property (sufficient
|
||
reservoir to pay for a child, consistent with "sender pays"); (c) standing = an `ACL.4th`
|
||
policy predicate. **Not decided.** (a) is the minimal reading and the one most consistent with
|
||
"do not over-engineer"; (b) is the one most consistent with the rest of the fleet's physics.
|
||
|
||
### VI.5 — Invariants that must survive
|
||
|
||
- The reverse guard preventing Hera from re-birthing herself (per §I.5) still has to hold, and
|
||
now has to hold for *every* birther with respect to itself.
|
||
- `capsule_birth_baby()` must stay the generic path — per §XXXII.2 it is already what every
|
||
`(p)` capsule uses across four call sites, and `capsule_runcap_birth()` was explicitly
|
||
established as the wrong tool for build-time-sourced births.
|
||
- Unattended/agent births must not set `g_wirebind_attached_username` (§I.7).
|
||
- `' BIRTH` must not enter `capsules/ACL.4th` — per `.claude/CLAUDE.md`, `ACL.4th` is shared
|
||
and portable, `BIRTH` is kernel-only, and the file deliberately omits it (comment at ~line
|
||
64). Generalizing `BIRTH` does **not** change this; pin it in a kernel-specific capsule.
|
||
|
||
---
|
||
|
||
## VII. One fleet-wide failure/recovery ladder
|
||
|
||
### VII.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
A single escalation shape, applied consistently across the fleet — current VMs and future ones
|
||
(GPIO, networking, whatever comes):
|
||
|
||
1. **Recover gently first.** For a VM with continuity to preserve (Hera being the type case),
|
||
this means **warm restart — resume with prior state intact.**
|
||
2. **Escalate if gentle recovery fails.** Fall back to a **from-scratch `BIRTH`** — no
|
||
continuity, rebuild fleet-state/trust from nothing.
|
||
3. **Fail brutally once genuinely exhausted.** No lingering, no partial states. Once recovery
|
||
options are spent the failure is **fast and total, not a slow degrade.**
|
||
|
||
The value here is uniformity: one shape for Hera, Hermes, Console and every future VM, instead
|
||
of bespoke handling per component.
|
||
|
||
### VII.2 — `SOS` as a standard message type
|
||
|
||
**Decided:** `SOS` is a standard message type **any** VM can emit — not specific to any one
|
||
component. It applies to non-Tripod VMs and to two of the three Tripod VMs (Hera and Console).
|
||
Hermes is the exception, for a structural reason — §VIII.
|
||
|
||
**Grounding and open points:**
|
||
- It takes a number from §I.4's space. **5 and 6 are unallocated gaps; 10 is next in
|
||
sequence.** Picking a gap vs. appending is a small call but should be made deliberately, not
|
||
by whoever types first.
|
||
- **Do not model it on `SPAWN-EVENT`.** Per §XX that constant has zero consumers anywhere in
|
||
the tree — it is an unwired placeholder. A message type with no dispatcher is exactly the
|
||
failure mode `SOS` cannot afford.
|
||
- **Open: who consumes an `SOS`, and what do they do with it?** The executive framing says
|
||
`SOS` is emitted; it does not say who acts. Given §IX (no VM assumes another's authority),
|
||
the consumer set is constrained but not specified.
|
||
|
||
### VII.3 — The existing precedent this should be reconciled with
|
||
|
||
> **WITHDRAWN 2026-09-18 by §XV.2 — this section's premise is wrong.** It assumed the ladder
|
||
> needs a detection mechanism. Death is compudynamic: no detector, no declarer, nothing to
|
||
> build. The closing claim below ("a recovery ladder with no detection story only ever triggers
|
||
> on failures loud enough to notice by accident") does not hold. The wellness-check idea stands
|
||
> on its own merits, unrelated to this ladder. Left in place, not rewritten.
|
||
|
||
Per §XX, closed as captured-for-later: Captain Bob's self-healing idea — "all VMs participating
|
||
in a wellness check at their nearest participating wellness center" — a distributed
|
||
liveness/failure-detection concept "deliberately not built as part of this fix."
|
||
|
||
**That idea and this ladder are the same problem approached from two ends**: wellness checks
|
||
are how a failure gets *detected*; the ladder is what happens *after*. Neither document has
|
||
reconciled them. **Flagged as open, and as the natural next thing to settle**, because a
|
||
recovery ladder with no detection story only ever triggers on failures loud enough to notice
|
||
by accident.
|
||
|
||
### VII.4 — Open: what "warm restart" concretely means
|
||
|
||
Warm restart implies a state boundary — what is "prior state" for a VM, and where does it live
|
||
across the restart? Candidate anchors traced or cited: the Stadium reservoir/heat state, the
|
||
VM's dictionary, its message arenas (§III.4 — if those centralize into the kernel, warm
|
||
restart gets *easier*, which is an argument to settle §III.4 first), its `identity` struct.
|
||
**Not designed here.** Note also that "fail brutally" must not mean "leave the Stadium's
|
||
conservation invariant K broken" — per `FABRIC-3.md` §XVIII that invariant is continuously
|
||
verified, so a brutal death still has to return what it held. **Cited from §XVIII's heading,
|
||
not re-read for this document; verify before relying on it.**
|
||
|
||
---
|
||
|
||
## VIII. Hermes's exception: the sinking semaphore
|
||
|
||
### VIII.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
**Hermes cannot emit `SOS`**, because Hermes is the message arbiter and it cannot route a
|
||
message announcing its own routing failure. Instead of emitting `SOS`, Hermes **raises a
|
||
semaphore signaling that it is sinking, and holds it until it goes down.** This gives the rest
|
||
of the fleet a window to shut down cleanly rather than going dark with no warning.
|
||
|
||
### VIII.2 — Why this is a corollary, not a special case
|
||
|
||
This is the direct consequence of §III.2. The instant Hermes stops being a client of its own
|
||
routing layer, any failure-announcement it might send has no transport — the transport is the
|
||
thing that failed. A semaphore is the right shape precisely because it is *not* a message: it
|
||
does not require the failed subsystem to work, and a held-until-death signal degrades
|
||
correctly (release = gone) rather than requiring a successful final transmission.
|
||
|
||
Worth stating plainly because it reframes the whole design: **the fleet's failure signalling is
|
||
two mechanisms, not one, and which one a VM uses is determined by whether it is above or below
|
||
the routing layer.** Everything on the Stadium floor sends `SOS`. The arbiter beneath it raises
|
||
a semaphore. That is a clean rule with no exceptions list to maintain.
|
||
|
||
### VIII.3 — Open
|
||
|
||
> **PARTLY SETTLED 2026-09-18 by §XVI.** The second bullet (what a clean-shutdown routine does)
|
||
> is answered: forced `blk_flush(0)`, then `BYE`; Hera's is suicide via a permanent
|
||
> `arch_halt()` loop. The third (is the window bounded) answers itself — the window ends when
|
||
> Hera halts, a bound by construction rather than by timer (§XVI.4). **The first bullet, where
|
||
> the semaphore mechanically lives, remains open.** Left in place, not rewritten.
|
||
|
||
- **Where does the semaphore live, mechanically?** It must be readable by VMs whose messaging
|
||
is dying. Kernel-resident, below the routing layer, is the only coherent answer, but the
|
||
concrete form is unspecified.
|
||
- **What does a VM's "clean shutdown routine" actually do?** §IX makes this fleet-wide
|
||
behavior, so it needs a single definition — and it must satisfy §VII.4's note about the
|
||
conservation invariant.
|
||
- **Is the window bounded?** "Holds it until it goes down" gives no deadline. If Hermes sinks
|
||
slowly, do VMs shut down on the signal alone or wait for release?
|
||
|
||
---
|
||
|
||
## IX. Birther failure: no provisional handoff
|
||
|
||
### IX.1 — Decided (Captain Bob, 2026-09-18)
|
||
|
||
If a VM responsible for birthing/lifecycle decisions (total Hera failure is the type case)
|
||
exhausts its own ladder — warm restart, then from-scratch `BIRTH` — and still cannot recover,
|
||
there is **no provisional handoff of its authority to another VM. No VM assumes partial or
|
||
stolen authority on another's behalf.** Instead, the rest of the fleet runs its own shutdown
|
||
routines — the same clean-shutdown behavior §VIII's sinking semaphore triggers, applied
|
||
fleet-wide.
|
||
|
||
### IX.2 — Why this is consistent rather than merely austere
|
||
|
||
It is the same invariant as §VI, read from the other side. §VI says a VM can never birth
|
||
something with more authority than it holds. §IX says a VM can never *acquire* authority it
|
||
was not born with, even when the holder is gone and the authority is going begging. Together:
|
||
**authority only ever flows down the birth graph, never sideways and never up.** No VM ends up
|
||
holding authority it wasn't born with, and no VM limps in a half-failed state — every path
|
||
terminates in either full recovery or fast, clean termination.
|
||
|
||
That is a strong, checkable property, and it is worth writing down as the thing to defend when
|
||
some future failure mode makes a provisional handoff look temporarily attractive.
|
||
|
||
### IX.3 — Open
|
||
|
||
> **PREMISE REJECTED 2026-09-18 by §XV.2.** The first bullet asks the wrong question. Nobody
|
||
> declares a VM dead — it dies a compudynamic death. The "circular by construction" difficulty
|
||
> was an artifact of assuming death is a judgment someone renders rather than a physical
|
||
> outcome of the physics. Left in place, not rewritten.
|
||
|
||
- **What has standing to declare a birther dead?** Circular by construction: the fleet must
|
||
conclude Hera is gone without Hera participating. Ties directly to §VII.3's undesigned
|
||
detection story.
|
||
- **Does fleet shutdown mean the kernel halts, or that the floor empties and the kernel
|
||
survives?** Materially different outcomes, not specified.
|
||
|
||
---
|
||
|
||
## X. Sequencing — dependencies between the open questions
|
||
|
||
These do not decompose into independent work items; several answers foreclose others. The
|
||
dependency order that fell out of writing this up:
|
||
|
||
1. **§III.4 (arenas: routing-only vs. full centralization) is the root.** It determines
|
||
whether §IV.2's routing-table question exists at all, and materially changes §VII.4's warm
|
||
restart.
|
||
2. **§III.3 (the by-name `VM-EXEC` dependency)** — needs a repo-wide `S" Hermes" VM-EXEC` grep
|
||
first, which has not been done.
|
||
3. **§IV.2 (slot numbering)** — only if §III.4 leaves a FORTH routing table standing.
|
||
4. **§VI.3 (what "ACL/DNA" refers to)** — independent of the above; gates all of §VI.
|
||
5. **§VII.3 (reconciling the ladder with the wellness-check idea)** — gates §VII.2's consumer
|
||
question and §IX.3's declare-dead question, which are the same question twice.
|
||
6. **§V.3 (agent-VM binding)** — needs §VI settled, since an agent VM is birthed before it is
|
||
bound.
|
||
|
||
---
|
||
|
||
## XI. Punch list — design only, no code authorized
|
||
|
||
Nothing here is started. Nothing here authorizes an edit. Numbered for discussion order, not
|
||
execution order.
|
||
|
||
1. ✅ **CLOSED 2026-09-18 (§XIII.1).** Repo-wide by-name Hermes inventory: 14 FORTH sites
|
||
across 5 files, 3 C-side sites, 1 DoE CSV schema site. Only 3 are live. §I.2 corrected.
|
||
2. ✅ **CLOSED 2026-09-18 (§XIII.4).** All three citations verified against source; §V.3.4 and
|
||
§VII.4 may now be relied on.
|
||
3. ⬜ Settle §III.4: routing-only vs. full arena centralization. **Root dependency — do first.**
|
||
4. ⬜ Settle §III.3 given 3.
|
||
5. ⬜ Settle §IV.2 if and only if 3 leaves a FORTH routing table standing.
|
||
6. ⬜ Settle §VI.3: precise referent for "ACL/DNA", against the four-field `DictEntry`
|
||
constraint.
|
||
7. ⬜ Settle §VI.4: what "standing" means, or rule it decorative.
|
||
8. ⬜ Reconcile §VII.3: the ladder vs. the wellness-check detection idea.
|
||
9. ⬜ Assign `SOS` a message-type number deliberately (§VII.2), with a named consumer.
|
||
10. ⬜ Specify the sinking semaphore's mechanism and the clean-shutdown routine (§VIII.3).
|
||
11. ⬜ Answer §IX.3: what declares a birther dead, and what fleet shutdown means concretely.
|
||
12. ⬜ **NEW 2026-09-18 (§XIII.5).** Rule on whether the Console Tripod leg is a *new*
|
||
singleton, distinct from today's plural per-attach console proxies. **Gates §IV.1 and
|
||
§IV.2** — sits above the slot-numbering question, not beside it.
|
||
13. ⬜ **NEW 2026-09-18 (§XIII.2), not part of this reshuffle.** Authorize a
|
||
`capsules/MANIFEST.md` correction pass for two false claims: block 4055's "immutable ABI"
|
||
(`FABRIC-2.md` declared it stale and it was never corrected) and block 2049's stated
|
||
contents. Reported, not fixed, per Captain Bob's Law.
|
||
|
||
**Acceptance for anything that eventually comes out of this list**, per `.claude/CLAUDE.md`'s
|
||
non-negotiable criteria: three-arch QEMU boot (`amd64`, `aarch64`, `riscv64`, one at a time, in
|
||
the foreground, `clean` before `qemu`), all reaching `zuse)ok>` with zero `UNKNOWN WORD`
|
||
faults, logs present under `logs/`, and `dict_hash` identical across all three architectures.
|
||
There is no other test.
|
||
|
||
---
|
||
|
||
## XII. Explicitly not decided anywhere in this document
|
||
|
||
Collected so nothing here is mistaken for settled. **Updated 2026-09-18 after §XV's rulings.**
|
||
Most of this list is now closed — see §XIV.2 and §XV.6 for what resolved, dissolved, or had its
|
||
premise rejected.
|
||
|
||
**Still genuinely open — updated again 2026-09-18 after §XVI settled item 10.**
|
||
- **Item 12 (§XIII.5)** — is the Console Tripod leg a new singleton, distinct from today's
|
||
per-attach proxies? **Now the largest remaining design item**, and still gates §IV.
|
||
- **Item 9 (§VII.2/§XVI.5)** — half-answered. The consumer action is defined for the two
|
||
fleet-fatal cases; open is whether an *ordinary peer's* `SOS` is actionable or merely
|
||
advisory, plus the trivial number allocation.
|
||
- **§VIII.3 first bullet** — where the sinking semaphore mechanically lives. The rest of
|
||
§VIII.3 is settled by §XVI.
|
||
- **Item 16 (§XV.4)** — an implementation check rather than a decision: every message-holding
|
||
teardown path must reach `STADIUM-EVICT`, verifiable via `fleet_conserved`.
|
||
- **Item 17 (§XVI.2)** — does Hera's suicide replace `BYE`'s current cold-restart, or become a
|
||
separate word? Small, but it changes a live registered word either way.
|
||
- **Item 18 (§XVI.7)** — if Hera is already dead, nobody performs the halt. Proposed shape (an
|
||
empty floor as a kernel-observable condition) is **analysis, not a ruling.**
|
||
|
||
§XIII.5's proposed Console resolution shape remains **analysis, not a ruling.** §XIV.4's and
|
||
§XIV.5's proposals were both superseded by §XV.4 and §XV.3 respectively.
|
||
|
||
What **is** decided, all by Captain Bob on 2026-09-18 and recorded in §III.1, §IV.1, §V.1,
|
||
§VI.1, §VII.1, §VII.2, §VIII.1 and §IX.1: Hermes goes into the kernel and becomes the arbiter
|
||
rather than a client; the Tripod becomes Hera/Artemis/Console; Console becomes the bind point;
|
||
`BIRTH` is general with authority bounded by inheritance; the fleet shares one
|
||
gentle→from-scratch→brutal ladder; `SOS` is a standard message type with Hermes excepted via a
|
||
sinking semaphore; and a failed birther's authority is never provisionally handed off.
|
||
|
||
---
|
||
|
||
## XIII. Punch-list items 1 and 2 worked — CLOSED 2026-09-18, with three corrections to this document's own §I
|
||
|
||
Worked per the series' standing discipline: items 1 and 2 were the two pure-investigation
|
||
entries on §XI, carrying no design commitment, so they were executable without a ruling. All
|
||
findings below traced directly against the working tree at `e56974e` on 2026-09-18. **No code
|
||
written, no design question answered, nothing in the tree modified.**
|
||
|
||
### XIII.1 — Item 1 CLOSED: the by-name Hermes inventory. §I.2 undercounted by an order of magnitude.
|
||
|
||
**Correction to §I.2, which is wrong as written.** It claimed the by-name dependency was
|
||
Artemis's "two live call sites" and framed Artemis as *the* dependent. The real inventory is
|
||
**13 by-name FORTH references across 5 files, plus 3 independent C-side sites.** §I.2's two
|
||
sites are real and still the sharpest edge, but they are not the extent of it, and the
|
||
executive framing ("relocated and rewired") has to cover all of it. Full inventory:
|
||
|
||
| # | Site | Call | Live? |
|
||
|---|---|---|---|
|
||
| 1 | `common/msg.4th:7` | `S" MSG-ACK-LAST" S" Hermes" VM-EXEC` | **dead** — §XIII.2 |
|
||
| 2 | `common/msg.4th:10` | `S" MSG-NACK-LAST" S" Hermes" VM-EXEC` | **dead** — §XIII.2 |
|
||
| 3 | `artemis/init.4th:138` | `S" 2 ENQUEUE-READY" S" Hermes" VM-EXEC` | live |
|
||
| 4 | `artemis/init.4th:501` | `S" 2 COMMON-CH @ CH-ADD-MBR" S" Hermes" VM-EXEC` | live |
|
||
| 5 | `process.4th:12` | `S" 1 EVENT-EMIT" S" Hermes" VM-EXEC` (SPAWN) | **dead** — §XIII.2 |
|
||
| 6 | `process.4th:15` | `S" 2 EVENT-EMIT" S" Hermes" VM-EXEC` (PAUSE) | **dead** |
|
||
| 7 | `process.4th:21` | `S" 3 EVENT-EMIT" S" Hermes" VM-EXEC` (RESUME) | **dead** |
|
||
| 8 | `process.4th:26` | `S" 4 EVENT-EMIT" S" Hermes" VM-EXEC` (KILL-VM) | **dead** |
|
||
| 9 | `doe-campaign.4th:6` | `S" Hermes" BIRTH` | not auto-run |
|
||
| 10 | `doe-campaign.4th:7` | `S" LOAD-DOE" S" Hermes" VM-EXEC` | not auto-run |
|
||
| 11 | `doe-campaign.4th:17` | `S" DOE-WORK" S" Hermes" VM-EXEC` | not auto-run |
|
||
| 12 | `doe-campaign.4th:28` | `S" DOE-WORK" S" Hermes" VM-EXEC` | not auto-run |
|
||
| 13 | `doe-campaign.4th:54` | `S" 1959 1 EXEC-DOE" S" Hermes" VM-EXEC` | not auto-run |
|
||
| 14 | `messaging.4th:77` | `S" Hermes" 1 VM-NAME-REG` | live (§I.3) |
|
||
|
||
**The good news is real: only 3 of the 14 are live production paths** (#3, #4, #14). Seven are
|
||
dead code (§XIII.2), four are in a campaign orchestrator `docs/working/architecture/
|
||
DOE-LIBRARY-HOWTO-20260819.md` itself records as "Not auto-run anywhere." **This materially
|
||
lowers the estimated cost of §III.3** — but it must be re-confirmed rather than trusted, since
|
||
"not auto-run" is a claim about today's boot path, not a guarantee nothing invokes it.
|
||
|
||
### XIII.2 — Seven of those sites are dead code, and `MANIFEST.md` carries a claim FABRIC-2 already declared stale
|
||
|
||
**`common/msg.4th` is loaded by nothing.** Traced: `S" common:msg.4th" EXEC` appears exactly
|
||
once in the tree — inside `common/msg.4th`'s own header comment, as usage documentation. No
|
||
capsule EXECs it. `capsules/init.4th` (block 2049) loads `ACL.4th`, `block-acl.4th`,
|
||
`zuse-eligibility.4th`, `lib.4th`, `fabric.4th`, `font.4th`, `common:messaging.4th` — and
|
||
nothing else.
|
||
|
||
This is **already known and already written down.** `FABRIC-2.md:2770-2773` states it
|
||
outright: the `HERMES-ACK`/`HERMES-NACK` wrappers "are now obsolete (every VM has its own
|
||
local `MSG-ACK-LAST`/`MSG-NACK-LAST` — no `VM-EXEC` indirection needed) but the file itself
|
||
was left in place, unloaded, rather than deleted unprompted; `capsules/MANIFEST.md`'s
|
||
'immutable ABI' claim for block 4055 is now stale." `messaging.4th:411` carries the same note
|
||
from the other side: "common:msg.4th's HERMES-ACK/NACK indirection is retired."
|
||
|
||
**`capsules/MANIFEST.md` was never corrected.** Line 317 still reads: "Immutable: this is the
|
||
cross-VM ACK/NACK ABI. Every messaging VM (Hera, Hermes, Artemis) loads this at birth.
|
||
Changing the block or the word names breaks the Hermes delivery protocol." That is false on
|
||
every clause. A second MANIFEST claim also fails against the source: line 52 describes block
|
||
2049 as loading "compudynamics, VM-INIT, lib, common:msg, fleet-k, process; BIRTHs Artemis +
|
||
Hermes" — `init.4th` block 2049 loads none of `common:msg`/`process` and contains no `BIRTH`
|
||
at all (Hermes and Artemis are birthed from C — §XIII.3).
|
||
|
||
**`process.4th` is likewise EXEC'd nowhere**, making sites #5–#8 dead with it.
|
||
|
||
**Reported, not fixed**, per Captain Bob's Law ("if you identify a bug, report it; do not fix
|
||
it unless the user says to"). Flagged here because a reshuffle that reads `MANIFEST.md` as
|
||
current will conclude the ACK/NACK path is a live immutable Hermes ABI and scope around a
|
||
constraint that stopped existing in `FABRIC-2.md`'s era. **Recommend a MANIFEST.md correction
|
||
pass as its own authorized item; it is not part of this reshuffle.**
|
||
|
||
### XIII.3 — The Tripod is hardcoded as a name-triple in C, in three independent places
|
||
|
||
Not previously recorded in this document. Each is an edit site the moment the Tripod's
|
||
membership changes (§IV.1):
|
||
|
||
1. **`capsule_birth.c:793-796`** — `is_fleet_foundation` is literally
|
||
`vm_name_prefix_eq_nocase(capsule_name, "Hera") || ... "Hermes" || ... "Artemis"`. It gates
|
||
`StadiumPatronHeader` setup and the `session_register()`/`session_set_pinned()` pinning
|
||
calls. **This is the Tripod, encoded as a string test.** Swapping Hermes for Console is a
|
||
one-line change here — and that single line is what makes a VM pinned.
|
||
2. **`kernel_main.c:864-874`** — `vm_interpret(mama, "S\" Hermes\" BIRTH")` plus a
|
||
`capsule_vm_find_by_name_nocase("Hermes", ...)` liveness check and console banner. The
|
||
comment cites `FABRIC-2.md` D.7 (birth-by-message-only, 2026-08-28): the Tripod legs "must
|
||
be alive session-less so a later thumbdrive-attach flow has a running Hermes/Artemis to
|
||
message." **Note the stated rationale for Hermes being born early is precisely that other
|
||
flows need it available — which a kernel-resident arbiter satisfies trivially and
|
||
permanently.** §III is consistent with D.7's intent, not in tension with it.
|
||
3. **`kernel_main.c:1007-1009`** — `sk_vm_switch_signal_register(hermes_entry.vm_id)`, the
|
||
preemptive context-switch registration from `FABRIC-3.md` §XXVIII.
|
||
|
||
**A fourth site is not code but schema, and is the expensive one: `doe_log.c`.** The per-tick
|
||
DoE CSV hardcodes the Tripod across six columns — 16/17/18 (`hera_heat_q48`,
|
||
`hermes_heat_q48`, `artemis_heat_q48`, populated by `doe_log_heat_by_name("Hera"/"Hermes"/
|
||
"Artemis")` at lines 206-208) and 23/24/25 (`switch_*_readiness`), with column 22 documented
|
||
as "0=Hera, 1=Hermes, 2=Artemis by current registration order." **Changing Tripod membership
|
||
changes the DoE CSV schema**, which bears directly on comparability with every campaign
|
||
already run (§XXXIV/§XXXV's segmented per-ISA design in `FABRIC-3.md` is mid-flight). Flagged
|
||
as a real cost, not a blocker, and **not** something to resolve by quietly renaming a column.
|
||
|
||
### XIII.4 — Item 2 CLOSED: all three flagged citations verified against source
|
||
|
||
§XI item 2 flagged three citations this document took from headings and `.claude/CLAUDE.md`
|
||
rather than from the source. All three check out; §V.3.4 and §VII.4 may now be relied on.
|
||
|
||
- **`FABRIC-2.md` §H.1** — real, at line 3699, "Session = Stadium patron, admission restated."
|
||
The pinning claim is at line 3713: pinned sessions are exempt from "the normal departure
|
||
path (heat decay / `COOL`): they never leave, permanently." Confirmed as §V.3.4 used it.
|
||
- **`FABRIC-2.md` §H.12** — real, at line 4057, "Implementation punch list (2026-09-03)."
|
||
Independently corroborated from the code side: `capsule_birth.c:785-788` cites "§H.12 step 4"
|
||
by name for the `session_register()`/`session_set_pinned()` soft-fail convention.
|
||
- **`FABRIC-3.md` §XVIII** — confirmed. `K` is `vm_physics_fleet_heat_sum()` over **all** live
|
||
VMs, which the reservoir-transfer accounting holds exactly at `Q48_ONE`, surfaced as the
|
||
`fleet_k_q48`/`fleet_conserved` CSV columns. §VII.4's warning stands as written: a brutal
|
||
death must still return what it held, or it breaks a continuously-verified invariant.
|
||
|
||
### XIII.5 — New finding, and the most consequential of this pass: Console today is plural, ephemeral, and capsule-less
|
||
|
||
**This was not known to §IV or §V when they were written, and it changes what §IV.1 is asking
|
||
for.** Traced in `capsule_console.c`:
|
||
|
||
- **Console has no capsule.** `capsules/` contains `hermes/` and `artemis/` directories but
|
||
**no `console/`**. A console VM's entire personality is a 3-line C string literal,
|
||
`CONSOLE_IDENTITY_SRC` (`capsule_console.c:28-31`): `Block 4997`, `S" common:messaging.4th"
|
||
EXEC`, `MSG-CD-INIT`. That is all of it.
|
||
- **Console is deliberately *not* on the routing table.** The source comment is explicit: "No
|
||
`COMMON-CH` subscription: a console's own traffic is direct 1:1 with its paired user VM
|
||
(`CONSOLE-CMD-EVENT`), not broadcast, so there's no need to resolve an index in Hermes's own
|
||
routing table for it."
|
||
- **Console is plural and per-attach.** `capsule_console_birth(const char *console_name, ...)`
|
||
is called from three sites (`capsule_wirebind.c:245`, `mama_forth_words.c:1591` and `:2015`)
|
||
and mints a fresh heap-built single-entry capsule directory each time. There are as many
|
||
console VMs as there are attachments.
|
||
|
||
**Consequence.** Hera, Hermes and Artemis are singular, pinned, born-at-boot, capsule-backed,
|
||
routing-table-indexed. Console today is **none of those five things.** So §IV.1's "Console
|
||
takes the vacated third slot" is **not** a relocation of an existing pinned VM — as stated it
|
||
would create a Console that does not currently exist. That is worth naming plainly, because it
|
||
is the one place this document's "reorganization, not invention" scope discipline is genuinely
|
||
strained.
|
||
|
||
**The shape that resolves it without inventing anything** — offered as analysis, **not
|
||
ratified, Captain Bob's call**: distinguish **Console** (singular, pinned, capsule-backed, the
|
||
Tripod leg — owns the drawing fabric and is the bind point, per §V.1) from **console proxies**
|
||
(plural, ephemeral, per-attach — exactly what `capsule_console_birth()` mints today,
|
||
unchanged). The Tripod leg is new; the proxies are untouched. This reading makes §V.1's "bind
|
||
point" precise: the leg is what you bind *to*, the proxy is what binding *produces*.
|
||
|
||
### XIII.6 — §V and §VI are load-bearing for each other, which neither section noticed
|
||
|
||
If Console is the bind point (§V.1), it is Console that must mint console proxies — and
|
||
minting a VM is `BIRTH`. Today all three `capsule_console_birth()` call sites run in Hera's or
|
||
the caller's context. **So "Console is the bind point" cannot be implemented while `BIRTH`
|
||
remains Hera-exclusive; it requires §VI.1's generalization.** They are one change, not two.
|
||
|
||
Mechanically this already works, which strengthens both: two of the three call sites pass
|
||
`vm->stadium_vm_id` — *whichever VM invoked* — rather than a hardcoded Hera
|
||
(`capsule_wirebind.c:245` passes `mama_vm->stadium_vm_id` because that path genuinely is
|
||
Hera's). That matches §I.5's finding that `capsule_birth_baby()` treats `stadium_vm_id`
|
||
generically as "whoever is birthing this VM." **Parentage is already generic; only
|
||
registration is not.**
|
||
|
||
This also supplies the first concrete answer to §VI.4's open "what is standing": Console needs
|
||
`BIRTH` to do its declared job, so it has standing by role. That is evidence for reading (a)
|
||
(standing = having `BIRTH` registered), not a ruling.
|
||
|
||
### XIII.7 — Effect on §X's sequencing
|
||
|
||
Nothing found here dislodges §III.4 as the root dependency. Two adjustments:
|
||
|
||
- **§III.3 is cheaper than §I.2 implied** (3 live sites, not a broad web) and can be scoped as
|
||
soon as §III.4 lands.
|
||
- **§IV.1 needs a prior ruling that §IV.2 does not cover**: is the Tripod's Console leg a *new*
|
||
singleton distinct from today's proxies (§XIII.5)? That question sits *above* the slot
|
||
numbering, not beside it. **Added to the punch list as item 12.**
|
||
|
||
### XIII.8 — Punch-list status after this pass
|
||
|
||
- ✅ **Item 1 CLOSED** — inventory complete (§XIII.1), 14 FORTH sites + 3 C sites + 1 CSV
|
||
schema site; §I.2 corrected.
|
||
- ✅ **Item 2 CLOSED** — all three citations verified against source (§XIII.4).
|
||
- ⬜ **Item 12, NEW** — rule on §XIII.5: is the Console Tripod leg a new singleton, distinct
|
||
from today's per-attach proxies? **Gates §IV.1 and §IV.2.**
|
||
- ⬜ **Item 13, NEW, not part of this reshuffle** — authorize a `capsules/MANIFEST.md`
|
||
correction pass for the two false claims in §XIII.2 (block 4055 "immutable ABI"; block 2049
|
||
contents). Reported, not fixed.
|
||
|
||
Items 3–11 unchanged and still open.
|
||
|
||
---
|
||
|
||
## XIV. Two rulings that collapse the root dependency (Captain Bob, 2026-09-18)
|
||
|
||
### XIV.1 — RULING: the existing FORTH messaging layer is legacy. Kernel Hermes is greenfield.
|
||
|
||
**Captain Bob, 2026-09-18, verbatim:** "as far as Hermes the VM and Hermes the kernel
|
||
component, forget all the forth existing and call it legacy for now. We'll do a code cleanup
|
||
for all the dead FORTH anyway."
|
||
|
||
So kernel-Hermes is **not** a migration of `capsules/common/messaging.4th`. It is a new C
|
||
implementation; the FORTH messaging layer becomes legacy on arrival and is retired by a
|
||
separate dead-FORTH cleanup pass. This reverses the framing §III.3 and §III.4 were built on —
|
||
both assumed the existing FORTH had to be carried across.
|
||
|
||
### XIV.2 — What this collapses
|
||
|
||
Four of this document's open questions dissolve rather than get answered:
|
||
|
||
- **§III.4 (the root dependency) — RESOLVED by fiat, in the "full centralization" direction,
|
||
but without the migration cost that made it frightening.** The kernel owns message and
|
||
channel state; `messaging.4th`'s per-VM `CREATE`/`ALLOT` arenas are legacy, not something to
|
||
centralize. §III.4 feared a painful port of live FORTH state; there is no port.
|
||
- **§III.3 (the by-name `VM-EXEC` dependency) — dissolved.** The three-option framing
|
||
(kernel primitives / vestigial name / birth-time registration) was about preserving callers.
|
||
With the FORTH legacy, §XIII.1's 14-site inventory stops being a migration constraint and
|
||
becomes an input to the cleanup pass. **§XIII.1's inventory is still the right list — its
|
||
purpose changed, not its content.**
|
||
- **§IV.2 (routing-table slot numbering) — dissolved, exactly as §IV.2's own option 3
|
||
predicted:** "the routing table stops being a FORTH array at all... in which case this
|
||
question dissolves into §III.4's arena question." It did. `VM-NAMES-INIT`'s 0/1/2 pinning and
|
||
the "never renumbered" commitment are legacy artifacts, not constraints on the new design.
|
||
- **§XI item 13 (the `MANIFEST.md` corrections) — absorbed.** Bob's "we'll do a code cleanup
|
||
for all the dead FORTH anyway" covers §XIII.2's findings. Still worth doing deliberately;
|
||
no longer a separate ask.
|
||
|
||
**§XIII.1, §XIII.2 and §XIII.3 keep their value** — the C-side sites (§XIII.3) are *not*
|
||
legacy and remain real edit sites, and the dead-FORTH inventory now feeds the cleanup.
|
||
|
||
### XIV.3 — RULING: Artemis is the persistence path. And it needs no layering inversion.
|
||
|
||
**Captain Bob, 2026-09-18:** "For persistence though, use Artemis as much as possible. We're
|
||
good with that part for sure." Ratified.
|
||
|
||
**A layering question this raises, traced 2026-09-18 and answered cleanly.** Artemis is a VM on
|
||
the Stadium floor; kernel-Hermes sits *below* the floor. "Persist via Artemis" reads at first
|
||
like an inversion — the kernel arbiter calling up into a floor VM. It is not, because storage
|
||
is already two layers, not one:
|
||
|
||
- **The block subsystem is kernel/shared C, below the floor:** `src/block_subsystem.c`,
|
||
`src/blkio_*.c`, `src/starkernel/virtio/virtio_blk.c`. `capsule_loader.c:98-100` calls
|
||
`blk_subsys_init()` and `blk_subsys_add_raw_device()` directly, with no Artemis involved at
|
||
all.
|
||
- **Artemis is the storage *policy arbiter* on the floor:** it owns attach/registration
|
||
(`blk_subsys_attach_device()` via the `BLK-ATTACH` primitive — `repl.c:525-531` states it
|
||
outright, "Artemis's own domain now, not Hera's") and the on-disk Artemis format.
|
||
|
||
So the ruling is satisfiable without inversion, by keeping the two straight: **floor-level and
|
||
fleet persistence goes through Artemis, its domain and its format; anything kernel-Hermes
|
||
itself needs uses the same block subsystem Artemis is built on — never a new one, and never by
|
||
messaging Artemis.**
|
||
|
||
Worth recording that the kernel *already* calls up into Artemis by name today
|
||
(`repl.c:539-541`, `S" %llu HERA-BLK-ATTACH-REQ" S" Artemis" VM-EXEC`), with a comment
|
||
explaining it is a direct `VM-EXEC` rather than a real message because Hera can't use her own
|
||
`MSG-SEND` there. That precedent exists; this section is about not *depending* on it.
|
||
|
||
### XIV.4 — The one real hazard in the persistence ruling, and the shape that avoids it
|
||
|
||
**Kernel-Hermes must not depend on Artemis for the persistence it needs during its own
|
||
failure.** This is the same structural trap as §VIII: if Hermes must write something at death
|
||
and reaching Artemis requires routing, the dependency closes a circle on exactly the mechanism
|
||
that is broken. §VIII solved the *signalling* case with a semaphore; the persistence case
|
||
needs the same discipline rather than a second special case.
|
||
|
||
**Recommended shape — analysis, not a ruling, Captain Bob's call: kernel-Hermes holds only
|
||
reconstructible state.** If the arbiter's routing state can be rebuilt from the live VM
|
||
registry (which `capsule_birth.c` already maintains as the authority on who exists), then:
|
||
|
||
- Hermes has nothing that *must* be persisted, so the Artemis dependency never arises.
|
||
- §VII.4's "what does warm restart mean for Hermes" becomes trivial — rebuild from the
|
||
registry, no saved state to reconcile.
|
||
- Losing in-flight messages when the arbiter dies is consistent with §VII.1 step 3's "no
|
||
lingering, no partial states," and with §VIII's clean-shutdown window.
|
||
|
||
This costs message durability across an arbiter death. **Flagged as the real trade**, and the
|
||
one to rule on: if in-flight messages must survive Hermes dying, Hermes needs durable state,
|
||
and that durable state cannot route through Artemis at death-time.
|
||
|
||
### XIV.5 — Still open, and now more urgent, not less: the scheduler firewall
|
||
|
||
Raised 2026-09-18 and **not yet ruled on**. Recorded here because §XIV.1 changes its timing.
|
||
|
||
The fleet already has a scheduler: §XXVIII built timer-driven preemption, and `MSG-SEND`
|
||
(`messaging.4th` block 5021) already calls `SWITCH-MARK-WORK` → `sk_vm_switch_signal_mark_work()`,
|
||
setting `has_work` on the target's switch slot; `sk_vm_switch_signal_tick()` switches when
|
||
`readiness >= SK_SWITCH_READINESS_THRESHOLD` **and** `has_work`. **Message arrival is already
|
||
a scheduling input.** This directly contradicts `VM-PHYSICS-DYNAMIC-FLEET-DESIGN-20260705.md`'s
|
||
"Explicitly not wanted: a VM scheduler. Nothing gets built that decides whose turn it is to
|
||
execute" — a live tension in the project that predates this document and is not this
|
||
document's to resolve, but is this document's to not make worse.
|
||
|
||
**Why §XIV.1 sharpens it.** Today that coupling runs FORTH `MSG-SEND` → C primitive → switch
|
||
slot. With the FORTH legacy, **kernel-Hermes becomes the caller of
|
||
`sk_vm_switch_signal_mark_work()` directly** — eligibility marking moves inside the arbiter.
|
||
That is the consolidation to guard against, and it happens by default unless the boundary is
|
||
stated up front. Greenfield is the right time to state it; retrofitting it later is how this
|
||
becomes a conventional scheduler by accident.
|
||
|
||
**Proposed invariant, for ruling:** *kernel-Hermes carries, resolves and ACL-checks. It
|
||
publishes facts — "this VM has mail" — and never reads readiness, never orders traffic by
|
||
priority, and never decides turn order. `switch.c` remains the sole owner of "who runs next."*
|
||
|
||
The argument for it is empirical and from this project's own history: §XXVIII.2 is a record of
|
||
switch-storms caused by **two sources of truth disagreeing** about who was running
|
||
(`vm_log_attributed_vm()` vs. the real trampoline state) — QEMU pinned near 100%, serial log
|
||
frozen solid. This codebase punishes duplicated authority with hangs. Two deciders would be
|
||
worse than one scheduler.
|
||
|
||
### XIV.6 — Punch list after these rulings
|
||
|
||
- ✅ **Item 3 (§III.4, the root) — RESOLVED** by §XIV.1. Kernel owns messaging; FORTH is legacy.
|
||
- ✅ **Item 4 (§III.3) — DISSOLVED** by §XIV.1; §XIII.1's inventory becomes cleanup input.
|
||
- ✅ **Item 5 (§IV.2) — DISSOLVED** by §XIV.1, as §IV.2 option 3 predicted.
|
||
- ✅ **Item 13 — ABSORBED** into the dead-FORTH cleanup pass.
|
||
- ⬜ **Item 14, NEW** — rule on §XIV.5's scheduler firewall invariant. **Raised, not ruled.**
|
||
- ⬜ **Item 15, NEW** — rule on §XIV.4: does message durability survive an arbiter death? If
|
||
yes, Hermes needs durable state that cannot route through Artemis at death-time.
|
||
- ⬜ Items 6, 7, 8, 9, 10, 11, 12 unchanged and still open.
|
||
|
||
**Note the shape of what remains.** With the root dependency resolved, the surviving open
|
||
items are no longer about *mechanism* — they are about *authority*: who may birth (6, 7), who
|
||
decides a VM is dead (8, 11), who owns turn order (14), and what survives a death (15). That
|
||
is a better class of question to be left with, and §IX's "authority only ever flows down the
|
||
birth graph" is the principle most of them should be tested against.
|
||
|
||
---
|
||
|
||
## XV. The authority questions, answered (Captain Bob, 2026-09-18)
|
||
|
||
§XIV.6 observed that the surviving open items were no longer about mechanism but about
|
||
authority — who may birth, who declares a VM dead, who owns turn order, what survives a death.
|
||
All four are answered here, and three of the four are answered by **rejecting the question's
|
||
premise** rather than by naming an owner. That pattern is the finding.
|
||
|
||
### XV.1 — RULING: any VM may birth a near-clone of itself, carrying its own ACL DNA
|
||
|
||
**Captain Bob, verbatim:** "Any VM can birth another VM that is almost a clone of itself with
|
||
its own ACL DNA whatever ya wanna call it."
|
||
|
||
This closes **§VI.3** and **§VI.4** together:
|
||
|
||
- **§VI.3 ("ACL/DNA" needs a precise referent) — ANSWERED: inheritance by copy, from the
|
||
parent.** The child is *almost a clone* of its birther: it starts from the parent's own
|
||
state and carries **its own** DNA — a copy it owns and may diverge, not a shared reference
|
||
to the parent's. This is the reading §VI.3 hoped for: it uses the existing word-level
|
||
`ACL-INHERIT` semantics (pin cleared, mode copied) rather than inventing a VM-level
|
||
construct, so it stays inside the "reorganization, not invention" scope, and it does not
|
||
need a fifth `acl_*` field on `DictEntry` (the constraint §VI.3 flagged).
|
||
- **§VI.4 ("standing" is undefined) — ANSWERED: standing is decorative.** "Any VM can birth"
|
||
confirms reading (a) — standing means nothing more than having `BIRTH` registered. Per §I.5
|
||
the C implementation is already VM-agnostic, so this is a registration change, exactly as
|
||
§VI.2 predicted. No Stadium-economy gate, no `ACL.4th` predicate. Consistent with
|
||
`.claude/CLAUDE.md`'s "do not over-engineer — if the user says 'BIRTH is a primitive', that
|
||
is the complete specification."
|
||
|
||
**Why the authority bound still holds without a check.** A near-clone cannot exceed its parent
|
||
because it is *built from* the parent. §VI.1's "enforced by inheritance, not by a separate
|
||
authorization check" is therefore literal, not aspirational — there is no gate to bypass
|
||
because there is no gate.
|
||
|
||
### XV.2 — RULING: nobody declares a VM dead. It dies a compudynamic death.
|
||
|
||
**Captain Bob, verbatim:** "Nobody declares a VM dead, it died a compudynamic death."
|
||
|
||
**This rejects the premise of §IX.3 and of §VII.3's detection gap, and both were wrong to ask
|
||
what they asked.** §IX.3 asked "what has standing to declare a birther dead?" and called it
|
||
"circular by construction." The circularity was an artifact of assuming death is a *judgment*
|
||
someone renders. It is not: death is a physical outcome of the compudynamics — heat exhausts,
|
||
the reservoir empties, the patron leaves the Stadium floor. There is no detector, no quorum, no
|
||
supervisor, and nothing to build.
|
||
|
||
**This retires the largest scheduler-shaped risk in the whole design.** §VII's ladder appeared
|
||
to need a supervisor — some component watching liveness and deciding to escalate — and §XIV.5
|
||
warned that a supervisor with a timer is a scheduler's twin. With death compudynamic, **that
|
||
component does not exist and is not needed.** The ladder is self-applied while a VM is alive;
|
||
once it is dead it is dead, which is exactly §VII.1 step 3's "fast and total, not a slow
|
||
degrade." No actor, no handoff (§IX.1 already forbade one), no partial states.
|
||
|
||
**Consequence for §VII.3.** The "wellness check at the nearest participating wellness center"
|
||
idea recorded in `FABRIC-3.md` §XX does **not** need to be reconciled with this ladder as a
|
||
detection mechanism, because no detection mechanism is required. It remains an independent idea
|
||
on its own merits. §VII.3's framing ("a ladder with no detection story only fires on failures
|
||
loud enough to notice by accident") was built on the same wrong premise and is withdrawn.
|
||
|
||
### XV.3 — RULING: nobody owns turn order. Turn order is compudynamic.
|
||
|
||
**Captain Bob, verbatim:** "Nobody owns the turn order. The turn order is compudynamic."
|
||
|
||
This answers **§XIV.5 (item 14)** with a stronger invariant than the one proposed there. §XIV.5
|
||
suggested a firewall — *"`switch.c` remains the sole owner of who runs next."* That named an
|
||
owner, and naming an owner is what a conventional scheduler is. **The correct invariant names
|
||
none:**
|
||
|
||
> **Turn order is an emergent output of the compudynamics, not a decision any component makes.
|
||
> Kernel-Hermes publishes facts into that system — "this VM has mail" — and computes no
|
||
> ordering. Neither does anything else.**
|
||
|
||
This is consistent with the project's own standing position, independently of this document:
|
||
`FABRIC-3.md` §XIX records the design direction as "fix the gap **without a scheduler**," with
|
||
the reasoning that "a fixed round-robin across identities would just be a different hardcoded
|
||
policy — not in the spirit of" the design. §XV.3 is that same position restated for the
|
||
reshuffle.
|
||
|
||
**One honest observation, offered as a flag rather than an objection.** Traced 2026-09-18:
|
||
`sk_vm_switch_signal_tick()` gates on `readiness >= SK_SWITCH_READINESS_THRESHOLD && has_work`,
|
||
and `SK_SWITCH_READINESS_THRESHOLD` is `50u`, a hardcoded constant
|
||
(`capsule_vm_switch_signal.c:52`). That is a fixed policy sitting in the middle of a
|
||
mechanism this section calls compudynamic — the same category §XIX rejected as "a different
|
||
hardcoded policy."
|
||
|
||
The layering does reconcile: the compudynamic **turn-attractor** (§XIX/§XXI) decides what work
|
||
is assigned, and the CPU-level switch signal is the mechanical follower that moves the
|
||
processor. Turn order in the meaningful sense is the attractor, and it is compudynamic as
|
||
ruled. But the constant `50` is a real seam, and it is the exact place where a hardcoded policy
|
||
could quietly start deciding turns. **Flagged for later, not proposed as work here** — it
|
||
predates this reshuffle and is `FABRIC-3.md` §XXVIII's own territory. Noted so it is not
|
||
discovered later and mistaken for something this document introduced. (`FABRIC-4.md` §1's
|
||
fixed-then-adaptive `rate` graduation is the precedent for how such a constant earns its way
|
||
to adaptive: measure against a fixed baseline first, self-tune only after.)
|
||
|
||
### XV.4 — §XIV.4 reframed: the question was persistence; the answer is conservation
|
||
|
||
§XIV.4 asked whether in-flight messages must survive an arbiter's death, and warned that
|
||
answering "yes" would force Hermes to hold durable state it could not safely write through
|
||
Artemis at death-time. **Captain Bob, on that item: "What survives the death of what? I don't
|
||
understand that last part."** Fair — it was posed as a persistence question, which is the wrong
|
||
frame and the reason it read as opaque.
|
||
|
||
**The right frame, given §XV.2.** A message is not only content; it is *heat*. Traced
|
||
2026-09-18 in `capsules/common/messaging.4th`: `MSG-ALLOC` pulls `Q.SLOT` from the caller's own
|
||
reservoir before admitting a message (rolling back via `STADIUM-RES-PUSH` on refusal, line
|
||
127), and `MSG-FREE-NODE` releases it with `STADIUM-EVICT` (line 135-136). An arbiter dying
|
||
while holding N messages is holding **N × `Q.SLOT` of fleet heat.**
|
||
|
||
So the question is not "must the payloads be saved." It is:
|
||
|
||
> **Does a dying arbiter return the heat its undelivered messages were holding?**
|
||
|
||
- **Payloads may vanish.** Consistent with §VII.1 step 3's "no lingering, no partial states."
|
||
- **The heat may not.** `K` = `vm_physics_fleet_heat_sum()` is held at `Q48_ONE` and
|
||
continuously verified (`FABRIC-3.md` §XVIII, `fleet_k_q48`/`fleet_conserved`). Heat that
|
||
dies with the arbiter is heat that breaks a live invariant.
|
||
|
||
**The answer to "what survives the death of what" is therefore: nothing survives except K.**
|
||
|
||
**This dissolves §XIV.4's hazard rather than resolving it.** There is nothing to persist, so
|
||
there is no death-time write, so there is no circular dependency on Artemis, so the
|
||
stateless-arbiter shape §XIV.4 recommended is simply correct rather than a trade-off. And since
|
||
death is compudynamic (§XV.2), a VM's death *is* already a Stadium eviction event — returning
|
||
heat is not a special case bolted onto death, it is what dying consists of. **§XIV.3's
|
||
"Artemis for persistence" ruling stands untouched and applies to fleet/floor persistence; the
|
||
arbiter simply never needed any.**
|
||
|
||
**The one thing to verify when this is eventually built** (not a design question, an
|
||
implementation check): that every message-holding structure's teardown path actually reaches
|
||
`STADIUM-EVICT`, so a mass teardown returns heat rather than leaking it. `fleet_conserved`
|
||
already makes that directly testable — a leak shows up as K ≠ `Q48_ONE`, not as a silent
|
||
error. Added as punch item 16.
|
||
|
||
### XV.5 — What these four rulings have in common
|
||
|
||
Three of the four answers reject the question rather than answer it. There is no death
|
||
declarer, no turn-order owner, and nothing to persist — and in each case the thing that seemed
|
||
to need an authority turned out to be an outcome of the physics instead. The one question that
|
||
*was* answered directly (§XV.1, who may birth) was answered with "anyone," which also declines
|
||
to create an authority.
|
||
|
||
**That is the actual defence against becoming a conventional scheduler**, and it is stronger
|
||
than the firewall §XIV.5 proposed. A firewall constrains a component that owns something. These
|
||
rulings mean **there is no owner to constrain.** The design's protection is structural, not
|
||
procedural: authority only ever flows down the birth graph (§IX.2), and everything else —
|
||
death, turn order, conservation — is physics rather than policy.
|
||
|
||
### XV.6 — Punch list after these rulings
|
||
|
||
- ✅ **Item 6 (§VI.3, "ACL/DNA" referent) — ANSWERED** (§XV.1): inheritance by copy; existing
|
||
`ACL-INHERIT` semantics suffice; no fifth `DictEntry` field.
|
||
- ✅ **Item 7 (§VI.4, "standing") — ANSWERED** (§XV.1): decorative; reading (a) confirmed.
|
||
- ✅ **Item 8 (§VII.3, ladder vs. detection) — WITHDRAWN** (§XV.2): premise wrong, no detection
|
||
mechanism required.
|
||
- ✅ **Item 11 (§IX.3, who declares a birther dead) — PREMISE REJECTED** (§XV.2): nobody;
|
||
compudynamic death.
|
||
- ✅ **Item 14 (§XIV.5, scheduler firewall) — ANSWERED** (§XV.3), with a stronger invariant
|
||
than the one proposed: no owner, not a named owner.
|
||
- ✅ **Item 15 (§XIV.4, message durability) — DISSOLVED** (§XV.4): reframed from persistence to
|
||
conservation; nothing survives but K.
|
||
- ⬜ **Item 16, NEW** (§XV.4) — implementation check, not a design question: verify every
|
||
message-holding teardown path reaches `STADIUM-EVICT` so mass teardown returns heat.
|
||
Testable directly via `fleet_conserved`.
|
||
- ⬜ **Item 9** (§VII.2 — `SOS` message-type number and its consumer) — still open. Note §XV.2
|
||
narrows it: with no death-declarer, an `SOS` consumer cannot be a supervisor, so the question
|
||
is now specifically what a *peer* does on receipt.
|
||
- ⬜ **Item 10** (§VIII.3 — the sinking semaphore's mechanism, the clean-shutdown routine's
|
||
definition, and whether the window is bounded) — still open, and now the largest remaining
|
||
design item.
|
||
- ⬜ **Item 12** (§XIII.5 — is the Console Tripod leg a new singleton, distinct from today's
|
||
per-attach proxies?) — still open, and still gates §IV.
|
||
|
||
**Remaining open: items 9, 10, 12, 16.** Item 10 is the substantive one; 9 is downstream of it,
|
||
12 is independent, and 16 is a build-time check rather than a decision.
|
||
|
||
---
|
||
|
||
## XVI. Item 10 settled: clean shutdown is forced flush + `BYE`; Hera's is suicide (Captain Bob, 2026-09-18)
|
||
|
||
**Captain Bob, verbatim:** "A clean shutdown is a VM termination where flush is forced and the
|
||
VM says BYE. Hera is the special case that should just halt the processor. Call it suicide I
|
||
guess."
|
||
|
||
This settles §VIII.3's second open point (what a clean-shutdown routine concretely does) and,
|
||
as a consequence, its third (is the window bounded). Traced 2026-09-18: **the ruling is almost
|
||
entirely existing mechanism, with exactly one behavioural change to a word that already
|
||
exists.**
|
||
|
||
### XVI.1 — Every piece of this already exists
|
||
|
||
- **Forced flush — `blk_flush(0)`.** `block_subsystem.c:988-990`; the source comment states it
|
||
directly: "**0 is the 'flush all' sentinel**." Already called that way at
|
||
`block_subsystem.c:849`, and already the Stadium's own write-back action for
|
||
`STADIUM_BEHAVIOUR_MIGRATE` (`stadium.c:336`, `:373`). Nothing new to build.
|
||
- **A child VM's `BYE` — `system_word_bye()`** (`src/word_source/system_words.c:143-147`):
|
||
sets `vm->halted = 1`, signalling the REPL to stop. That is already precisely "a VM
|
||
termination." Confirmed by `mama_forth_words.c:2262-2263`'s own doc comment: "In child VMs
|
||
this word is never registered; children use the standard `system_word_bye` which sets
|
||
`vm->halted` and returns to the parent's REPL."
|
||
- **Halting the processor — `arch_halt()`**, declared at `include/starkernel/arch.h:64` and
|
||
implemented on **all three architectures** (`amd64/arch.c:207`, `aarch64/arch.c:126`,
|
||
`riscv64/arch.c:170`). Three-arch parity already holds, so the non-negotiable acceptance
|
||
criteria are satisfiable without new per-arch work.
|
||
|
||
**So a child VM's clean shutdown is `blk_flush(0)` then `BYE`** — two existing calls in
|
||
sequence. This sits comfortably inside the "reorganization, not invention" scope discipline.
|
||
|
||
### XVI.2 — The one real change: Hera's `BYE` does not currently halt. It cold-restarts.
|
||
|
||
**This is the finding of this section, and it is a behavioural change to a live, registered
|
||
word — not a gap to fill.** `mama_word_bye()` (`mama_forth_words.c:2265-2271`) is Hera's own
|
||
`BYE`, and its doc comment says outright: "**Hera-only: reap all children then cold-restart the
|
||
machine.**" The body is exactly two actions:
|
||
|
||
```c
|
||
capsule_vm_kill_all_nonmama(); /* "BYE: reaping children" */
|
||
arch_cold_reset(); /* "BYE: cold restart" */
|
||
```
|
||
|
||
Against Bob's ruling:
|
||
|
||
- **`capsule_vm_kill_all_nonmama()` already matches** the "fleet shuts down" half. (The
|
||
contract is documented downstream too — `include/starkernel/capsule_birth.h:339` describes
|
||
it as called "from Hera's BYE immediately before `arch_cold_reset()` to reap all children.")
|
||
- **`arch_cold_reset()` does not match.** The ruling is *halt*, not restart. A cold reset
|
||
reboots the machine; suicide stops it. These are opposite outcomes, and today's code does the
|
||
wrong one.
|
||
|
||
**Implementation shape, traced:** `arch_cold_reset()` is `__attribute__((noreturn))`
|
||
(`arch.h:67`), but `arch_halt()` is **not** — it halts only until the next interrupt and is
|
||
called once per idle iteration in normal use (`amd64/arch.c:200-205`'s own comment). A
|
||
permanent halt is therefore `arch_disable_interrupts()` followed by a `for(;;) arch_halt();`
|
||
loop — which is exactly the pattern amd64's *own* `arch_cold_reset()` already uses as its
|
||
unreachable fallback (`for (;;) __asm__ volatile ("cli; hlt");`, `arch.c:218`) and the same
|
||
shape the kernel panic path uses. **No new primitive; an existing pattern applied
|
||
deliberately.**
|
||
|
||
**Flagged for a conscious decision, not resolved here.** `.claude/CLAUDE.md` carries a hard
|
||
rule: "Never modify a registered, tested word to 'fix' it." This is not a fix — it is a ruled
|
||
behavioural change — which is a different thing, and the rule's own reasoning ("the problem is
|
||
almost certainly in the caller") does not apply. But the change is real and should be made
|
||
knowingly rather than discovered in a diff. **Whether Hera's suicide is spelled as a changed
|
||
`BYE` or as a separate word leaving `BYE`'s cold-restart intact is an implementation choice,
|
||
and is not decided here.** Worth noting that cold-restart-on-`BYE` is plausibly wanted behaviour
|
||
for an interactive operator typing `BYE` at Hera's REPL, which is an argument for two words
|
||
rather than one.
|
||
|
||
### XVI.3 — A shared-source constraint on where the flush goes
|
||
|
||
`system_word_bye()` lives in `src/word_source/system_words.c` — **vendored/shared source that
|
||
must compile and behave correctly in the hosted build as well as the kernel**
|
||
(`.claude/CLAUDE.md`: gate kernel-only code with `#ifdef __STARKERNEL__`). Forcing a
|
||
`blk_flush(0)` inside `system_word_bye()` itself would change hosted-build behaviour for a word
|
||
that has nothing to do with this design.
|
||
|
||
**So the forced flush belongs in the kernel-side shutdown path that calls `BYE`, not inside
|
||
`BYE`.** Stated here as a constraint on implementation so the obvious-looking edit is not made
|
||
in the obvious-looking place.
|
||
|
||
### XVI.4 — §VIII.3's third question answers itself: Hera's halt is the bound
|
||
|
||
§VIII.3 asked whether the shutdown window is bounded, noting that "holds it until it goes down"
|
||
gives no deadline. **It is bounded, and by construction rather than by a timer: the window ends
|
||
when Hera halts the processor.** Children flush and say `BYE`; Hera reaps whatever remains and
|
||
stops the machine. There is no deadline to choose, no timeout to tune, and — consistent with
|
||
§XV.3 — nothing that has to *decide* when time is up. The sequence terminates because its last
|
||
step is physically terminal.
|
||
|
||
This also satisfies §VII.1 step 3's "no lingering, no partial states" literally: after
|
||
`arch_halt()` in a disabled-interrupt loop there is no state left to linger in.
|
||
|
||
### XVI.5 — Item 9 is now half-answered
|
||
|
||
§VII.2 left two questions on `SOS`: which message-type number, and "who consumes an `SOS`, and
|
||
what do they do with it?" **The second is answered for the two fleet-fatal cases:** on Hermes's
|
||
sinking semaphore (§VIII.1) and on total birther failure (§IX.1), the response is now concrete
|
||
— forced flush, `BYE`, and Hera's suicide as the terminal step.
|
||
|
||
**Still genuinely open, and narrower than before:** what a peer does on receiving an *ordinary*
|
||
VM's `SOS`. A single non-Tripod VM in trouble is presumably not fleet-fatal, so "everyone
|
||
shuts down" cannot be the universal answer — but §XV.2 rules out the obvious alternative, since
|
||
with no death-declarer an `SOS` consumer cannot be a supervisor that decides another VM's fate.
|
||
The remaining question is therefore specifically: **is a peer's `SOS` actionable at all, or is
|
||
it purely advisory/diagnostic?** Plus the trivial number allocation (§I.4: 5 and 6 are
|
||
unallocated gaps, 10 is next in sequence).
|
||
|
||
### XVI.6 — Punch list after this ruling
|
||
|
||
- ✅ **Item 10 (§VIII.3) — SETTLED** (§XVI). Clean shutdown = `blk_flush(0)` + `BYE`; Hera =
|
||
suicide via a permanent `arch_halt()` loop. Window bounded by Hera's halt (§XVI.4). All
|
||
mechanism exists on all three architectures.
|
||
- 🔶 **Item 9 (§VII.2) — HALF-ANSWERED** (§XVI.5). Consumer action defined for the two
|
||
fleet-fatal cases. Open: whether a peer `SOS` is actionable or advisory, plus the number.
|
||
- ⬜ **Item 12 (§XIII.5)** — Console Tripod leg: new singleton or not? Unchanged; still gates §IV.
|
||
- ⬜ **Item 16 (§XV.4)** — implementation check: teardown paths must reach `STADIUM-EVICT`.
|
||
- ⬜ **Item 17, NEW** (§XVI.2) — decide whether Hera's suicide replaces `BYE`'s cold-restart or
|
||
becomes a separate word. Small, but it changes a live registered word either way.
|
||
|
||
### XVI.7 — One residual edge, raised not answered
|
||
|
||
**If Hera is already dead, nobody performs the halt.** §XV.2 makes death compudynamic and §IX.1
|
||
forbids any VM assuming her authority, so on total Hera failure there is no actor left to run
|
||
`arch_halt()`. The machine would be a live kernel with an empty Stadium floor — which is
|
||
precisely the "lingering, partial state" §VII.1 step 3 rules out.
|
||
|
||
The shape that resolves it without violating §IX: **an empty floor is a kernel-observable
|
||
condition, not a VM's decision.** The kernel noticing "no live VMs remain" and halting is not a
|
||
VM inheriting Hera's authority — it is the machine having nothing left to run. That keeps
|
||
authority flowing only down the birth graph (§IX.2) while still terminating.
|
||
|
||
**Offered as analysis, not a ruling — Captain Bob's call.** Added as punch item 18.
|