FABRIC-3.md §I.3/§I.8: WIREBIND EJECT/detach + EXPIRE re-scoped as logout

Closes §I.3 (Milestone 5 remainder): WIREBIND now tracks which VM is
attached via the home-blocks USB path, and a new EJECT word plus the
existing hot-unplug signal both flush/reset-console/kill through it
(FABRIC-3.md §F.10).

Closes §I.8 (EXPIRE/ACL), re-scoped: the original "admit the zuse
session as a Stadium patron and reap on TTL" plan was invalidated a
second time -- Zuse authenticates directly onto Hera, who is patron
zero and permanently pinned, so there is no patron for a reap sweep to
ever find. Built instead as a detach-triggered logout
(capsule_zuse_boot_logout()), the same trigger EJECT/hot-unplug use for
regular WIREBIND users, so neither identity is a special case. Required
a companion fix: install_and_activate() used to skip re-running
ACL-ZUSE-BOOT whenever the cert was already installed, which made a
logout permanent for the rest of the boot; the outer re-attach gate now
checks zuse_session (clears on logout) instead of zuse_cert_installed
(a deliberate permanent one-way ratchet, left untouched).

Verified 3-arch boot to ok> (amd64/aarch64/riscv64, each in the
foreground) after both steps; logs and DoE CSVs from this session's
verification runs included per this repo's own audit-artifact
convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
This commit is contained in:
Robert Allan James
2026-09-04 09:21:01 -04:00
co-authored by Claude Sonnet 5
parent 34203613bb
commit 60d9c2520e
40 changed files with 165701 additions and 16 deletions
+74 -13
View File
@@ -752,11 +752,20 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
(`mama_forth_words.c:485-500`+) does the live re-verify-and-compare, gated on
`((VM*)entry.vm_ptr)->identity.installed`.
- [ ] Implement detach behavior on console disconnect or VM teardown. **SCOPED 2026-08-27
- [x] Implement detach behavior on console disconnect or VM teardown. **SCOPED 2026-08-27
(`FABRIC-3.md` §F.10)**: a new `EJECT` word — flush via the existing `blk_vm_flush_all()`,
reset the console's active VM if bound to the departing VM, then `capsule_vm_kill()` (already
complete, no new teardown mechanism needed). Needs one small new piece of state `WIREBIND`
must own: which `VMUuid` is currently attached via the home-blocks USB path.
must own: which `VMUuid` is currently attached via the home-blocks USB path. **DONE
2026-09-04**: built exactly as scoped. `capsule_wirebind.c` now owns the tracked `VMUuid`
(set at the end of a successful `capsule_wirebind_try_attach()`); `capsule_wirebind_eject()`
and `capsule_wirebind_unclean_detach()` both resolve it via `capsule_vm_registry_get()`,
reset `sk_repl_get_active_vm()`/`sk_repl_set_active_vm()` if bound, then
`capsule_vm_kill(entry.name)`, then clear the tracked state. `EJECT` registered as a new
Hera-only word (`mama_forth_words.c`, alongside `KILL`). The abrupt path calls
`capsule_wirebind_unclean_detach()` from the existing `bot_msc_detach_pending` hook
(`repl.c`) — no flush attempted there, matching decision 2. Verified 3-arch boot to `ok>`
(amd64/aarch64/riscv64, each in the foreground, `clean qemu`).
### From FABRIC-2.md §X, Milestone 6 — Kernel/capsule PKI signing chain
@@ -1229,6 +1238,18 @@ other three become honest, explicit punch-list items instead of being touched sp
**`EXPIRE` stays explicitly deferred until Phase 8 (PKI/zuse session minting) lands** — not
abandoned, not left ambiguous: revisit it as part of that work, admitting the session itself
(not a word) as the patron, once there is something real for it to represent.
**CLOSED 2026-09-04, and decision 2 above is now shown wrong in a way this session's own
§H.1 had already implied without anyone tracing it back here**: "admit the zuse session as
a Stadium patron" was never buildable — Zuse authenticates directly onto Hera
(`capsule_zuse_boot.c`), and Hera is patron zero, permanently pinned, exempt from `COOL`;
there is no patron for a reap sweep to ever find. `EXPIRE`'s real intent (decision 4: revoke
elevated privilege, drop back to non-zuse) is built instead as a **detach-triggered**
action, not a TTL/reap one — `capsule_zuse_boot_logout()` clears `zuse_session` when Zuse's
own attached drive leaves, the same trigger `EJECT`/hot-unplug already use for regular
WIREBIND users (`FABRIC-3.md` §F.10/§I.3), generalized so neither identity is a special
case. See §I.8 for the full build note, including the `install_and_activate()` re-login fix
this required. Verified 3-arch boot to `ok>`.
- [x] Fixed (2026-08-26): `ONTOLOGY.md` §IX's "words (dictionary, warehouse-resident today,
not yet migrated)" line was stale — corrected to state words are fully migrated and live
via `stadium_word_dispatch()`. Doc-only, no build/boot verification needed.
@@ -1533,14 +1554,14 @@ graph TD
BMAPWRITE["✅ Write block-map to drive (M3)<br/>CLOSED 2026-08-27 (§F.12) — already built, blocked only on W10"]
BMAPREAD["✅ Read/validate block-map on insert (M3)<br/>CLOSED 2026-08-27 (§F.13) — already built"]
MIGSM["🟡 Migration state machine (M3)<br/>partially answered: ACL decides *when*"]
UNCLEAN[" Unclean-removal handling (M3)<br/>DESIGN CLOSED 2026-08-27 (§F.10), code not yet written"]
UNCLEAN[" Unclean-removal handling (M3)<br/>BUILT 2026-09-04 (§F.10) — capsule_wirebind_unclean_detach()"]
ACLKEY["❌ ACL 'bumps and holes' comparison<br/>semantics — SCOPED 2026-08-27 (§F.2)"]
WIREBIND["❌ Wire hotplug → capsule_birth_baby() (M5)"]
BINDSTEP["❌ Extend sk_repl_set_active_vm()<br/>with key-match (M5) — SCOPED 2026-08-27 (§F.9)"]
DETACH[" Detach behavior / new EJECT word (M5)<br/>SCOPED 2026-08-27 (§F.10)"]
DETACH[" Detach behavior / new EJECT word (M5)<br/>BUILT 2026-09-04 (§F.10)"]
EXPIRE["✅ EXPIRE reframed: session end<br/>= VM detach via COOL (§B + D.2)"]
EXPIRE["✅ EXPIRE: session end on device detach<br/>BUILT 2026-09-04 (§B+D.2+H.1+I.8) — COOL for<br/>WIREBIND users, logout for Zuse (no patron of her own)"]
RUNCAP["❌ Runtime capsule construction<br/>from thumbdrive content — SCOPED 2026-08-27 (§F.6)"]
MINT["❌ Ongoing MINT word (Phase 8 + D.3)<br/>SCOPED 2026-08-27 (§F.8) — GPT dropped, single-device confirmed OK"]
PENTAGON["📍 Pentagon: Hera/Hermes/Artemis/<br/>User-VM/Console, K5 (D.2b)"]
@@ -1590,8 +1611,8 @@ graph TD
classDef unblocked fill:#a83,stroke:#333,color:#fff
classDef open fill:#666,stroke:#333,color:#fff
classDef partial fill:#883,stroke:#333,color:#fff
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE,BMAPREAD,SSDSCOPE,ROUNDTRIP,POLYBLOCK,W10 done
class STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN,MSGMIGRATE,ACLKEY blocked
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE,BMAPREAD,SSDSCOPE,ROUNDTRIP,POLYBLOCK,W10,DETACH,UNCLEAN done
class STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,MINT,BMAPFMT,CERTVERIFY,RUNCAP,MSGMIGRATE,ACLKEY blocked
class MIGSM partial
```
@@ -2169,6 +2190,17 @@ the latter, given the single-USB-device constraint confirmed in `F.8` means ther
than one candidate — not committed here); the console message text distinguishing a graceful
eject from an unclean one in the transcript.
**BUILT 2026-09-04, closing this node's remaining deferrals:** the tracked state is
`g_wirebind_attached_vm_id`/`g_wirebind_attached_valid`, static in `capsule_wirebind.c`, set at
the end of a successful `capsule_wirebind_try_attach()`. `EJECT` takes no name argument, per
the leaning above — single-USB-device constraint confirmed still holding. Console text
distinguishes the two paths: `"EJECT: <name> flushed and detached"` vs. `"WIREBIND: <name>
detached without flush (device already gone)"`. Both new entry points
(`capsule_wirebind_eject()`, `capsule_wirebind_unclean_detach()`) share a
`wirebind_resolve_attached()` helper that's idempotent the same way `capsule_vm_kill()` already
is — resolving to nothing tracked, or a since-killed entry, is a clean no-op, not an error.
Verified 3-arch boot to `ok>` (amd64/aarch64/riscv64, each in the foreground).
### F.11 — `FIRSTTOUCH` (identity → system-device block-range allocation)
Traced `g.total_user_lbn` (`block_subsystem.c:634,650,655,677,688,753`) and `blk_meta_t`'s
@@ -4294,12 +4326,14 @@ stale the way the original carry-forwards did.
compudynamics-heat governs *when*; migration itself expected rare, not routine) but no state
machine designed. *(Same location as above.)*
### I.3 — Milestone 5 remainder (BINDSTEP)
### I.3 — Milestone 5 remainder (BINDSTEP) — CLOSED 2026-09-04
- [ ] **`EJECT` / detach behavior.** Scoped 2026-08-27 (§F.10): flush via
- [x] **`EJECT` / detach behavior.** Scoped 2026-08-27 (§F.10): flush via
`blk_vm_flush_all()`, reset the console's active VM if bound to the departing VM, then
`capsule_vm_kill()` (already complete). Needs one new piece of state `WIREBIND` must own —
which `VMUuid` is currently attached via the home-blocks USB path. Not built. *(Full entry:
which `VMUuid` is currently attached via the home-blocks USB path. **DONE 2026-09-04** — see
the full closure note at its original §A location (same line as this item's *(Full entry: ...)*
pointer below); verified 3-arch boot to `ok>`. *(Full entry:
§A, "From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding.")*
### I.4 — Milestone 6 remainder (PKI)
@@ -4341,9 +4375,9 @@ FABRIC-2.md §X, Milestone 8 — Bare-metal boot from physical USB.")*
- [ ] Explicitly deferred until Milestone 7 closes — its own precondition isn't met, nothing
to do here yet. *(Full entry: §A, "From FABRIC-2.md §X, Milestone 9.")*
### I.8 — `EXPIRE` (ACL) — deferred, but its stated blocker is now stale
### I.8 — `EXPIRE` (ACL) — CLOSED 2026-09-04, re-scoped away from the Stadium-patron model
- [ ] Decided 2026-08-26 (§B): a zuse superuser session, not a per-word ACL entry, is the
- [x] Decided 2026-08-26 (§B): a zuse superuser session, not a per-word ACL entry, is the
right unit to admit as a Stadium patron and reap on expiry — but explicitly deferred "until
Phase 8 (PKI/zuse session minting) lands," since building a reap mechanism with nothing real
to feed it would be speculative infrastructure ahead of its only consumer.
@@ -4356,4 +4390,31 @@ FABRIC-2.md §X, Milestone 8 — Bare-metal boot from physical USB.")*
all (`zuse_session` is set once by `ACL-ZUSE-BOOT` and never cleared), and Stadium's own
generic ttl-decrement/reap mechanism still doesn't exist either — both real gaps, narrower
than "Phase 8 doesn't exist," worth re-scoping against before treating this as unblocked.
*(Full entry: §B, "From FABRIC-2.md §... — EXPIRE (ACL).")*
**Invalidated a second time, more specifically, 2026-09-04**: this decision's own premise
(admit the zuse session *as a Stadium patron*) doesn't hold at all, for a structural reason
§H.1 had already stated in general terms without anyone connecting it back to this item —
Zuse authenticates directly onto Hera (`capsule_zuse_boot.c`'s `install_and_activate()` sets
fields on `mama_vm`, not on a session-owning VM of her own), and Hera is patron zero,
permanently pinned, exempt from `COOL`/`stadium_evict()` (§H.1: "pinned sessions simply have
no D.2-style 'ending' at all"). There was never a patron for `EXPIRE` to reap here — not a
missing mechanism, a missing *referent*. **Built 2026-09-04, per direct instruction to build
a real logout rather than re-defer**: `capsule_zuse_boot_logout(mama_vm)`
(`capsule_zuse_boot.c`) clears `zuse_session` — never `zuse_cert_installed`, which stays a
permanent one-way ratchet by design — when Zuse's own attached device detaches, mirroring
D.2's real mechanism (detach-triggered, not TTL) at the point where it actually applies to
her: no Stadium patron, no reap sweep, just the same "session ends on device removal" model
§I.3's `EJECT`/hot-unplug work just built for regular users, generalized so no identity is
handled specially. `EJECT` (`mama_word_eject()`) now calls both
`capsule_wirebind_eject()` and `capsule_zuse_boot_logout()`; the hot-unplug path in
`repl.c` calls both `capsule_wirebind_unclean_detach()` and `capsule_zuse_boot_logout()`; at
most one of each pair ever does anything, per the single-USB-device constraint (§F.8).
**Companion fix required to make this actually work, found while building it**:
`install_and_activate()` used to skip re-running `ACL-ZUSE-BOOT` whenever
`vm_zuse_cert_install()` reported "already installed" (its own deliberate one-way return),
which made a logout permanent for the rest of the boot — no way back in. Now
`ACL-ZUSE-BOOT` always re-runs on a verified re-attach, and
`capsule_zuse_boot_try_attach()`'s own outer gate checks `zuse_session` (clears on logout)
instead of `zuse_cert_installed` (never clears) — the check was always meant to mean
"already logged in this session," not "has ever been minted." Verified 3-arch boot to `ok>`
(amd64/aarch64/riscv64, each in the foreground). *(Full entry: §B, "From FABRIC-2.md §... —
EXPIRE (ACL).")*