Files
LithosAnanake/FABRIC-3.5.md
T
Claude bd0c23286c FABRIC-3.5.md §XVI: item 10 settled -- clean shutdown is forced flush + BYE, Hera's is suicide
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
2026-09-18 22:01:00 +00:00

1267 lines
77 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.