Punch list item 4 (final): CONSOLE-ATTACH, full unattended-identity flow verified end-to-end
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

Closes FABRIC-3.md §XXXII.2's punch list. CONSOLE-ATTACH ( name-c
name-u -- ok? ) pairs a fresh console VM to an already-live VM
registered as "<name>~user". Deliberately a plain, unconditional
primitive with no VMIdentity capability-bit check -- corrects this
session's own first-pass design (§XXXII.2 amended in the same commit):
identity.installed is 0 for Hera/Hermes/Artemis and for every
console-proxy VM, so a capability-bit gate would be unreachable for
every VM a human actually types at, Zuse included. Matches
ZUSE-ELIGIBILITY-ADD's own "no bespoke gate" precedent in this file;
real gating is `' CONSOLE-ATTACH ACL-PIN` in ACL.4th if ever wanted.

Two real bugs found and fixed via live testing, not assumed correct:
- capsule_birth_baby() never sets a VM's registry name (documented
  gap, same one capsule_runcap_birth()'s own history already hit) --
  UNATTENDED-BIRTH gained a second `name` argument and now calls
  capsule_vm_registry_set_name(new_vm_id, "<name>~user") itself.
- CONSOLE-ATTACH's first draft took an independent console name from
  the target's name. sk_repl_dispatch_line()'s pairing check (repl.c)
  reconstructs the target as console_get_vm_name()+"~user" -- a
  mismatched console name silently falls back to direct interpretation
  with no error. Caught live (typed `5 6 + .` at a mismatched console,
  got a direct `11` instead of a relay) and fixed by collapsing to one
  name argument, matching WIREBIND's own by-construction invariant.

Full end-to-end live verification on amd64: minted a test identity,
UNATTENDED-BIRTH'd it as "bob", CONSOLE-ATTACH'd a console named "bob",
USE'd it, typed `5 6 + .` -- no direct output at [zuse@bob] (relay
path taken), then `[zuse@bob~user] 11 ok>` appeared: the relayed
command executed on the target identity VM itself and printed its own
answer back through the shared console. Hera stayed healthy throughout
(2 2 + . -> 4 after switching back). CONSOLE-ATTACH also verified to
refuse cleanly on a nonexistent target with no orphaned VM. Test
capsule reverted after capture per this project's probe convention --
never committed.

FABRIC-3.md §XXXII.2 fully closed: all 4 original questions ratified,
the mid-course drive_uuid and ACL-bit corrections both recorded
plainly rather than silently folded in, and a doc-accuracy note left
for CLAUDE.md's own stale "1024-byte block limit" framing (mkcapsule's
real limits are range [2048,5120) and 16 content lines/block) --
flagged, not fixed, out of this punch list's scope.

Clean 3-arch qemu boot (amd64/aarch64/riscv64) on the real committed
C-only change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
Robert Allan James
2026-09-16 07:24:27 -04:00
co-authored by Claude Sonnet 5
parent 5879c8b3bc
commit af351bff92
14 changed files with 46188 additions and 34 deletions
+51 -28
View File
@@ -4355,40 +4355,63 @@ This collapses all four questions:
**`vm_identity_from_cert()` needs zero changes** -- no origin-aware variant, no
content-hash-derived substitute. This is a strictly better answer than the deferred
"Bob's call" the first pass of this section left open.
3. **ACL-gated console attachment -- checks the attaching human's own credentials, not the
instance's.** Falls directly out of the no-seed decision: an unattended instance can never
prove anything about itself at attach time (it holds no secret to challenge), so the gate
necessarily lives on the human side -- almost certainly a capability bit
(`VMIdentity.acl_caps`, still unassigned per this header's own "real bits get names only
once the operation gets built" precedent) checked on the attaching human's own verified
identity before the console-birth + `VM-NAME-REG` pairing (§XXXII.2 above) is allowed to
run. Concrete bit value: punch-list item, not decided here.
3. **ACL-gated console attachment -- corrected 2026-09-16: no `VMIdentity` capability bit.**
The first pass of this answer proposed exactly that (a capability bit checked on the
attaching human's own identity) -- wrong on two independent counts, not one. CLAUDE.md's
own hard rule: "ACL policy belongs in `ACL.4th`, never in C." And a mechanical fact traced
live while building `CONSOLE-ATTACH`: `identity.installed` is 0 for Hera/Hermes/Artemis
*and* for every console-proxy VM -- a `vm_identity_has_cap()` gate would be unreachable for
every VM a human actually types at, Zuse included. That isn't a policy disagreement, it's a
gate that can never open. `CONSOLE-ATTACH` is a plain, unconditional primitive (same "no
bespoke gate" doctrine `ZUSE-ELIGIBILITY-ADD` already carries in its own comment);
restricting who may call it, if ever wanted, is `' CONSOLE-ATTACH ACL-PIN` in `ACL.4th`.
4. **§VII's xHCI/live-table machinery -- confirmed irrelevant, independently of the seed
question.** An unattended identity is born from a capsule directory entry, never from a
`blkio_dev*`; it has no physical device to attach/detach and never enters the xHCI
per-device registry at all. This holds regardless of how Q1/Q2 were answered, so it was
never actually contingent on the seed decision above.
**Punch list for implementation (not started, needs explicit authorization per this project's
standing "plan approval is not a start signal" rule):**
- Build the scratch-device mint path: attach a `blk_subsys_add_raw_device()`-backed buffer
sized for sig+cert devblocks only, run `capsule_mint_identity()` against it unmodified
(live, on a booted Hera with Zuse authenticated -- likely a new FORTH word, or a `MINT`
variant that takes a device handle rather than always resolving one from an attach event).
- Hand-transcribe the resulting `drive_uuid` + DER cert bytes out of the scratch buffer as
FORTH literals into a new `.4th` capsule block, following the existing `Block NNNN`
convention -- checked into the repo, picked up by the next `mkcapsule` build like any other
capsule.
- Add the unattended-birth call site: `capsule_birth_baby()` (unmodified) + read the embedded
`drive_uuid`+cert literals back out of the capsule's own arena + `vm_identity_from_cert()`
(unmodified) + post-birth `identity` assignment (`capsule_wirebind.c:272-274`'s pattern),
gated by the explicit invariant already stated above (never touch
`g_wirebind_attached_username`/console-pairing).
- Assign a real `acl_caps` bit for "may attach a console to an unattended instance" and wire
the check into the console-birth + `VM-NAME-REG` path.
- Acceptance: 3-arch clean boot with at least one unattended instance born at boot, no console
attached, verified un-promptable (§VIII.1 gate holds), then a human console attached to it
after the fact via the existing `VM-NAME-REG` pairing mechanism.
**Punch list for implementation -- CLOSED, all 3 items done and live-verified (2026-09-16):**
- ✅ **Scratch-device mint path.** `capsule_mint_identity_scratch()` (`capsule_mint.c`/`.h`) +
`MINT-SCRATCH`/`MINT-SCRATCH-EMIT` (`mama_forth_words.c`). Built on `blkio_ram.c`'s generic
RAM-backed `blkio_dev`, not `blk_subsys_add_raw_device()` as first proposed -- that call
registers into the block-subsystem's own BAM chain, an unrelated persistence layer with no
bearing on `capsule_mint_identity()`'s `blkio_dev*` need. `blkio_ram.c`/`blkio_factory.c`
were vendored, hosted-only source excluded from the kernel build entirely; pulled
`blkio_ram.c` alone in (pure memcpy, no file I/O, freestanding-safe) rather than the whole
factory (which unconditionally references `blkio_file.c`'s real `fopen()`/`fread()`).
Verified live on amd64: two mints produced two genuinely different `drive_uuid`s; the cert's
own embedded ASN.1 serialNumber matched the emitted UUID byte-for-byte.
- ✅ **Hand-transcription.** `MINT-SCRATCH-EMIT` prints `drive_uuid`+cert as ready-to-paste
`CREATE ... C, ...` FORTH literals. **Correction to this section's own doc-comment framing:**
`mkcapsule`'s real constraints, confirmed by the tool itself (not the doc), are block range
`[2048, 5120)` and a hard 16-content-line-per-block cap -- not the 1024-byte-per-block
framing this file's CLAUDE.md counterpart describes. Doc fix needed, out of this punch
list's own scope; noted here so it isn't lost.
- ✅ **Unattended-birth call site.** `UNATTENDED-BIRTH` (`capsule-c capsule-u name-c name-u --
ok?`): `capsule_birth_baby()` unmodified, `vm_identity_from_cert()` unmodified, post-birth
`identity` assignment matching `capsule_wirebind.c:272-274`'s own pattern -- plus a fix
`capsule_birth_baby()` itself needs from every caller (found live, matching
`capsule_runcap_birth()`'s own documented history of the identical gap):
`capsule_vm_registry_set_name(new_vm_id, "<name>~user")`, without which the VM is born but
undiscoverable by name to anything downstream.
- ✅ **Console attachment -- built as `CONSOLE-ATTACH ( name-c name-u -- ok? )`, not an ACL
bit** (Q3 above amended to match). Resolves the target's liveness via
`capsule_vm_find_by_name("<name>~user", ...)` *before* birthing a console, so a typo refuses
cleanly with no orphaned VM -- verified live. Takes exactly one name, not an independently
chosen console name: `sk_repl_dispatch_line()`'s own pairing check (`repl.c`) reconstructs
the target as `console_get_vm_name() + "~user"`, so a console named anything else silently
falls back to direct interpretation with no error -- caught live on the first attempt (typed
`5 6 + .` at a mismatched console and got a direct `11` instead of a relayed one), fixed by
collapsing to a single name argument.
- **Full end-to-end live verification, amd64, 2026-09-16:** minted a test identity ->
`UNATTENDED-BIRTH` (named `bob`) -> `CONSOLE-ATTACH bob` -> `S" bob" USE` -> typed
`5 6 + .` at the new console -> printed nothing at `[zuse@bob]` (confirming the relay path
was taken, not the direct-interpret fallback) -> `[zuse@bob~user] 11 ok>` appeared --
the relayed command actually executed on the target identity VM itself and printed its own
answer back through the shared console, unprompted messaging infrastructure and all. Hera
remained healthy throughout (`2 2 + .` -> `4` after switching back). Test capsule reverted
after capture per this project's own probe convention; nothing about it is committed.
### XXXII.3 -- Primitive error-handling audit: kernel-only scope, real surface counted