Stage E amendment: resolve drive_uuid wrinkle via scratch-device mint (FABRIC-3.md §XXXII.2)
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run

Bob's proposal: mint against a "sim thumbdrive" -- a scratch blkio_dev
from the existing blk_subsys_add_raw_device() mechanism (same one the
kernel ramdrive already uses), then hand-transcribe just drive_uuid +
DER cert as FORTH literals into a normal .4th capsule block.

This dissolves the wrinkle the first pass of Q2 left open:
capsule_mint_identity() runs completely unmodified against the scratch
device (same live Zuse-signing op, same rng_get_bytes() draw for
drive_uuid), so vm_identity_from_cert() needs zero changes -- no
origin-aware variant, no content-hash-derived substitute. "Sim"
describes only where the bytes were written, invisible to verify.

Also corrects an error in the first pass: cert production cannot be
"offline" -- capsule_mint_identity() requires Zuse's live in-kernel
signing key, so minting is inescapably a two-boot runtime operation
(mint on boot N, package by hand, birth on boot N+1).

Punch list updated to match. Still design-only, no code.

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 04:01:32 -04:00
co-authored by Claude Sonnet 5
parent 06e2507ce4
commit 60bcdc09a7
+43 -25
View File
@@ -4311,15 +4311,21 @@ seed into a git-committed capsule.
This collapses all four questions: This collapses all four questions:
1. **Packaging -- a new capsule content convention, not a new `mkcapsule` mode or MINT 1. **Packaging -- a new capsule content convention, not a new `mkcapsule` mode.** Correction
variant.** No seed means no secret-handling in the build tool at all: the DER cert to the first pass of this answer: "produced offline" was wrong.
(produced offline by the existing `MINT`/`capsule_mint_identity()` path, Zuse-signed, same `capsule_mint_identity()` requires `issuer_vm->zuse_cert_seed` -- Zuse's live in-kernel
as today) becomes part of a normal `(p)` PRODUCTION capsule's own payload, following the private key -- so minting can only happen at runtime, on a booted Hera with Zuse
same `Block NNNN` convention every capsule already uses for its personality source. authenticated, exactly like a human identity today. No host-side build tool can produce
§XXIV's collision machinery (`check_block_conflicts()`, `mkcapsule --resolve`, this cert. The real shape is two boots: **mint on boot N, package the output as capsule
`capsule-reserved.txt`) already covers this -- it's blind to *content*, only to block source by hand, birth it on boot N+1** once that source has gone through a normal build.
numbers, so a cert-carrying capsule is just another capsule to it. No new collision risk, Captain Bob confirmed (2026-09-16) the packaging step is a hand-copy: mint against a
no change needed to §XXIV's machinery. scratch device (item 2 below), then transcribe just `drive_uuid` (16 bytes) + the DER
cert bytes as FORTH literals into a normal `.4th` block -- no binary packaging, no new
`mkcapsule` mode, no change to the build tool at all. §XXIV's collision machinery
(`check_block_conflicts()`, `mkcapsule --resolve`, `capsule-reserved.txt`) already covers
this once it exists as a `.4th` block -- it's blind to *content*, only to block numbers, so
a cert-carrying capsule is just another capsule to it. No new collision risk, no change
needed to §XXIV's machinery.
2. **Birth -- `capsule_birth_baby()`, unmodified, not `capsule_runcap_birth()`.** 2. **Birth -- `capsule_birth_baby()`, unmodified, not `capsule_runcap_birth()`.**
`capsule_runcap_birth()` was the wrong tool: its own header says a user's identity source `capsule_runcap_birth()` was the wrong tool: its own header says a user's identity source
"never exists at build time" (`capsule_runcap.h:19-20`) -- exactly backwards for a "never exists at build time" (`capsule_runcap.h:19-20`) -- exactly backwards for a
@@ -4334,14 +4340,21 @@ This collapses all four questions:
`vm_identity_from_cert()` has verified the cert. The unattended path calls `vm_identity_from_cert()` has verified the cert. The unattended path calls
`vm_identity_from_cert()` on the capsule's own embedded DER cert immediately after `vm_identity_from_cert()` on the capsule's own embedded DER cert immediately after
`capsule_birth_baby()` returns, then assigns the result the same way. `capsule_birth_baby()` returns, then assigns the result the same way.
**One real wrinkle, not silently resolved:** `vm_identity_from_cert()`'s serial-number **The `drive_uuid` wrinkle flagged in the first pass of this answer is resolved, not
check binds the cert to a physical `drive_uuid` (`homeblocks_sig_t`, 16 bytes) -- a deferred -- Bob's proposal (2026-09-16): mint against a "sim thumbdrive," a scratch
capsule-embedded identity has no physical drive and thus no `drive_uuid` to bind against. `blkio_dev` obtained from the exact same generic RAM-backed mechanism the kernel's own
Either the cert-issuing step needs a different binding value for this identity origin (e.g. ramdrive already uses (`blk_subsys_add_raw_device()`, `capsule_loader.c:100`), sized for
the capsule's own content hash, already the system's universal identity primitive) or just a sig devblock + cert devblock (no seed devblock -- the no-seed decision above means
`vm_identity_from_cert()` needs a origin-aware variant. **Not designed here -- flagged for `capsule_mint_identity()`'s seed-writing step is simply never reached/read back).
the punch list, needs Bob's call on what an unattended identity's cert should bind to `capsule_mint_identity()` runs against this scratch device completely unmodified -- same
before implementation.** live Zuse-signing operation, same `rng_get_bytes()` draw for `drive_uuid`
(`capsule_mint.c:209-213`) as a real thumbdrive gets. This means `drive_uuid` is a genuine
random draw living in a genuine `homeblocks_sig_t`, not a derived or synthetic value --
"sim" describes only *where* the bytes were written (a throwaway RAM buffer instead of
physical media), a property entirely invisible to the verify path.
**`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 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 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 prove anything about itself at attach time (it holds no secret to challenge), so the gate
@@ -4358,14 +4371,19 @@ This collapses all four questions:
**Punch list for implementation (not started, needs explicit authorization per this project's **Punch list for implementation (not started, needs explicit authorization per this project's
standing "plan approval is not a start signal" rule):** standing "plan approval is not a start signal" rule):**
- Decide what an unattended identity's cert binds to instead of `drive_uuid` (item 2's - Build the scratch-device mint path: attach a `blk_subsys_add_raw_device()`-backed buffer
wrinkle) -- Bob's call. sized for sig+cert devblocks only, run `capsule_mint_identity()` against it unmodified
- Define the new capsule content convention for an embedded cert (which block(s), what (live, on a booted Hera with Zuse authenticated -- likely a new FORTH word, or a `MINT`
format) and add build-time production of it (offline `MINT`-equivalent step, not new variant that takes a device handle rather than always resolving one from an attach event).
runtime code). - Hand-transcribe the resulting `drive_uuid` + DER cert bytes out of the scratch buffer as
- Add the unattended-birth call site: `capsule_birth_baby()` + `vm_identity_from_cert()` + FORTH literals into a new `.4th` capsule block, following the existing `Block NNNN`
post-birth `identity` assignment, gated by the explicit invariant already stated above convention -- checked into the repo, picked up by the next `mkcapsule` build like any other
(never touch `g_wirebind_attached_username`/console-pairing). 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 - 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. 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 - Acceptance: 3-arch clean boot with at least one unattended instance born at boot, no console