FABRIC-3.md: scope ACLKEY (console/VM binding), capture v2.0.0 scope expansion

Second node in the iterative Q&A pass: traced acl_mode/acl_allow/acl_pinned
to DictEntry (per-word, not per-VM) before proposing anything, confirming
"reuse ACL" could only ever mean reuse the pattern, not the data. Decided:
a new VMIdentity type in its own header (mirroring the existing VMUuid
precedent, not another inline VM struct field), Zuse keeps an always-allowed
but explicit-acknowledgment override, and console/VM binding stays freely
retargetable (no one-way pin).

Also captured a scope expansion surfaced during this pass: identity is a
general per-VM primitive needed by Hera/Hermes/Artemis/Console too, not
just user thumbdrives, plus two new standing items (a full codebase
scavenging audit, and v2.0.0 as the eventual release target) in new §D.5.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
Robert Allan James
2026-08-27 11:19:48 -04:00
co-authored by Claude Sonnet 5
parent 4c7a39b5c3
commit 0a65dd7ace
+67
View File
@@ -1528,3 +1528,70 @@ partial write (READ10's PASS/FAILED logic likely transfers unchanged, not indepe
verified); whether a write needs a follow-up `TEST UNIT READY` or cache-flush SCSI command
before the transfer is considered durable on real media (QEMU's `usb-storage` backend may mask
this — a real-hardware-only question, revisit at Milestone 8).
### F.2 — `ACLKEY` (the "bumps and holes" comparison semantics)
Traced against the actual code before asking anything: `acl_mode`/`acl_allow`/`acl_pinned`
(`include/vm.h:343-346`, `src/word_source/acl_words.c`) are **`DictEntry` fields — per word,
not per VM.** There is no VM-level ACL structure anywhere today. So D.3/D.4's "reuse the
existing ACL primitive" resolution can only ever have meant reuse the *pattern* (a cached
decision plus a C-enforced one-way ratchet — `if (e->acl_pinned) return;` at every mutating
primitive) — the actual data has to live somewhere new. `sk_repl_set_active_vm()`
(`starkernel/repl.c:64`) is confirmed to be exactly what its own doc comment says: an
unguarded raw pointer swap, no credential concept at all.
**Decisions made 2026-08-27 (iterative Q&A pass):**
1. **Where the lock lives.** A new dedicated type in its own header —
`include/starkernel/vm_identity.h`, a `VMIdentity { uint8_t owner_pubkey[32]; uint8_t
installed; }` — embedded by value as a field on `struct VM`, exactly the way `VMUuid
stadium_vm_id` (`vm_uuid.h`, its own header, embedded field) already does. **Explicit
standing instruction from Captain Bob**: don't grow `struct VM`/`vm.h` feature-by-feature
with more inline fields — when a feature's data has real shape, it gets its own header and
gets *integrated* as a field, not inlined ad hoc. `VMUuid` was already the right precedent;
`VMIdentity` follows it. Deliberately holds only the public key, not a seed — unlike
Zuse's own `zuse_cert_seed`/`zuse_cert_pubkey` pair, a regular VM's lock never needs to
sign anything itself, so no private material belongs on it at all.
2. **Zuse override.** Zuse keeps an always-allowed override to attach to any VM (consistent
with the existing `emergency_console`/`zuse_session` bypass precedent, and avoids the
bricking risk of Zuse ever being locked out of a VM by its own cert state) — **but the
override must be a distinct, explicit call path** (e.g. a separate function/word, not a
silently-taken branch inside the normal bind check), so invoking it requires a deliberate
acknowledgment rather than happening as a side effect of an ordinary bind attempt. Exact
acknowledgment UX (a confirm prompt? a two-step word?) is not designed yet — the
architectural commitment is only that it can't be silent.
3. **Binding pin.** No pin. `sk_repl_set_active_vm()` stays freely retargetable — matches
today's Tripod-fleet `USE`-word behavior, and is needed for real cases where a single
console legitimately moves between VMs mid-session (Zuse doing maintenance work in another
service VM; a user's console retargeting to update something in a second VM they own). The
credential check runs at each bind call, not just once at first attach.
**Not yet scoped (deferred within this node):** the exact acknowledgment UX for the Zuse
override path; whether `VMIdentity.installed` needs its own one-way fuse semantics (probably
yes — the *lock itself* being immutable once set at a VM's birth is a different axis from
"binding stays retargetable," and shouldn't be conflated with decision 3 above) — worth a
dedicated look when this is actually built, not decided in this pass.
### D.5 — Scope expansion (2026-08-27): identity is common to every VM, not just users
Surfaced while scoping `ACLKEY`, stated directly: *"the whole object is to deliver a
functional Tripod plus identities common to all VM's... this means now that we have to
create certificates for Hermes, Artemis and Console along with Zuse and CaptBob's
'thumbdrives.'"* This reframes `VMIdentity` (F.2 above) from a user-VM-specific mechanism into
the **general per-VM identity primitive** — every node in the pentagon (Hera, Hermes,
Artemis, a user's own VM, the Console) is expected to eventually carry one, not only VMs born
from an attached thumbdrive. Doesn't change F.2's design, just its intended reach — worth
remembering when `VMIdentity` actually gets built, so it isn't accidentally scoped narrower
than this.
**Two new standing items that came with this, both explicitly deferred (not part of the
current iterative pass, recorded so they aren't lost):**
- **A full codebase audit pass**, using this same iterative Q&A workflow, to scavenge for more
"same gap hiding in two places" opportunities the way `ACLKEY` turned out to be one gap
wearing two names (Milestone 5's "key/lock shape" and D.4's "bumps and holes"), and the way
`WRITE(10)` turned out to gate four separate-looking fronts at once. Not scoped, not
started — a future pass of its own.
- **v2.0.0 release target**: once Tripod is functional end to end, every VM has its identity
mechanism, and the codebase/documentation are clean per the above audit, tag a v2.0.0
release. Stated as the destination this whole planning arc is walking toward, not an
immediate next step.