Stage E ratified: unattended identity is cert+personality only, no seed (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

Settles all 4 open questions on paper, no code:
- No seed baked into capsules for this pass (Bob's call); runtime-minted
  seed documented as a future, separately-scoped possibility
- Birth via capsule_birth_baby() (unmodified, already generic), not
  capsule_runcap_birth() -- that path requires a real blkio_dev*+
  homeblocks_sig_t* an unattended identity can't provide, and its own
  header says build-time-baked content is exactly the wrong case for it
- Identity population is the same post-birth struct-assignment pattern
  capsule_wirebind.c already uses live (vm->identity = identity)
- §XXIV's block-collision machinery already covers a cert-carrying
  capsule -- no new risk, no change needed there
- ACL gate lives on the attaching human's credentials, since an
  unattended instance holds no secret to prove anything about itself
- xHCI/live-table machinery confirmed irrelevant, independent of the
  seed question

One real wrinkle flagged, not resolved: vm_identity_from_cert()'s
serial-number check binds to a physical drive_uuid an unattended
identity doesn't have -- needs Bob's call before implementation.

Punch list recorded; implementation not started per standing "plan
approval is not a start signal" rule.

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 03:41:10 -04:00
co-authored by Claude Sonnet 5
parent 42d4bf3dad
commit 06e2507ce4
+75
View File
@@ -4297,6 +4297,81 @@ whatever code implements unattended birth.
unattended identity's own lifecycle (no `blkio_dev`, no device to attach/detach) before
assuming the two paths share no state.
**Ratified, 2026-09-16 -- all four questions settled on paper, no code written.** Traced,
not assumed: `vm_identity.h`'s own header comment says outright "no seed/private material
belongs here at all" (line 29), and `user_identity_seed.h:25` states the running system's own
verify path checks "these two alone" -- cert + pubkey, never the seed. Confirmed live:
`capsule_wirebind_verify_cert()` only ever reads and verifies (§XXVIII's BINDSTEP re-check is
the same function, same direction); nothing in the attach/verify path signs as the identity
being checked. **Decision (Captain Bob, 2026-09-16): unattended identities carry cert +
personality only, never a seed, for this pass.** A future runtime-minted-seed path (an
instance that signs as itself) is a documented possibility, explicitly out of scope here --
if it's ever built, it must mint at runtime into a non-persisted/fenced location, never bake a
seed into a git-committed capsule.
This collapses all four questions:
1. **Packaging -- a new capsule content convention, not a new `mkcapsule` mode or MINT
variant.** No seed means no secret-handling in the build tool at all: the DER cert
(produced offline by the existing `MINT`/`capsule_mint_identity()` path, Zuse-signed, same
as today) becomes part of a normal `(p)` PRODUCTION capsule's own payload, following the
same `Block NNNN` convention every capsule already uses for its personality source.
§XXIV's collision machinery (`check_block_conflicts()`, `mkcapsule --resolve`,
`capsule-reserved.txt`) already covers this -- 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()`.**
`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
build-time-baked unattended capsule, and it hard-requires a real `blkio_dev*` +
`homeblocks_sig_t*` it would have no way to obtain. `capsule_birth_baby()` is already the
generic, capsule-directory-sourced birth path every `(p)` capsule uses (confirmed at 4
existing call sites across `mama_forth_words.c`/`capsule_console.c`); an unattended
identity is just another named capsule going through it, `skip_pki_sig = 0` like any normal
build-time capsule. Identity population is a proven, already-live pattern, not new
invention: `capsule_wirebind.c:272-274` does exactly this today --
`((VM *)user_ctx)->identity = identity;`, a plain post-birth struct assignment once
`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
`capsule_birth_baby()` returns, then assigns the result the same way.
**One real wrinkle, not silently resolved:** `vm_identity_from_cert()`'s serial-number
check binds the cert to a physical `drive_uuid` (`homeblocks_sig_t`, 16 bytes) -- a
capsule-embedded identity has no physical drive and thus no `drive_uuid` to bind against.
Either the cert-issuing step needs a different binding value for this identity origin (e.g.
the capsule's own content hash, already the system's universal identity primitive) or
`vm_identity_from_cert()` needs a origin-aware variant. **Not designed here -- flagged for
the punch list, needs Bob's call on what an unattended identity's cert should bind to
before implementation.**
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.
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):**
- Decide what an unattended identity's cert binds to instead of `drive_uuid` (item 2's
wrinkle) -- Bob's call.
- Define the new capsule content convention for an embedded cert (which block(s), what
format) and add build-time production of it (offline `MINT`-equivalent step, not new
runtime code).
- Add the unattended-birth call site: `capsule_birth_baby()` + `vm_identity_from_cert()` +
post-birth `identity` assignment, 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.
### XXXII.3 -- Primitive error-handling audit: kernel-only scope, real surface counted
**Scope, decided explicitly:** this audit covers kernel-side primitives only --