Files
LithosAnanake/docs/v4.0.0/plans/2026-10-26-engine-step4-identity-gate.md
T
rajamesandClaude Opus 5.5 5b181458df docs(v4): the identity gate before Part A
Captain Bob, 2026-10-26: "Gate first." Its own plan, with D1-D4 ruled as
recommended: the Zuse check split from the v3 VM; v4 recognises a minted
Zuse only (genesis with Artemis's writes, Phase 5); [zuse@Hera] ok> now;
the minted pair is QEMU's default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 08:35:13 -04:00

175 lines
11 KiB
Markdown

# ENGINE Step 4, ahead of Part A: the identity gate on v4 — Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans (Captain Bob prefers native execution). Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** On bare metal, v4 does what v3 does about identity before its prompt: with no identity
drive the system is headless, with no prompt; when Zuse's minted thumbdrive is attached the kernel
recognises it, and only then is there a console. Pulling the drive ends the session and the system
goes headless again; putting it back brings the prompt back.
**Why now (Captain Bob, 2026-10-26):** "Gate first." Step 4's work goes ahead "only if zuse
thumbdrive is attached so you have zuse. no identity thumb drive equals headless. when a thumb drive
is inserted, only then is there an identity and a console" (2026-10-20, `ENGINE.md` §2). Today the
v4 boot cannot meet that: `sk_v4_run()` (`kernel_main.c:580`) never returns, and it runs before USB
bring-up (`:823`), the heartbeat (`:915`) and the headless wait (`:1927`), so a drive attached to a
v4 boot is never read. The drive exists: `disk/zuse-scratch/` (`1f157e97`), a minted Zuse pair.
**Spec:** `ENGINE.md` §2 (the rulings of 2026-10-20, the identity gate), `MACHINE.md` §5.1, the
step 4 plan (`2026-10-20-engine-step4-node-in-the-vms-place.md`, "The identity gate"),
`V3-PARITY.md` §1 rows 11 and 12.
## What v3 does (read 2026-10-26, `kernel_main.c`, `repl.c`, `capsule_zuse_boot.c`)
1. After POST and the devices: `pci_init`, entropy, Artemis's virtio disk attached, and
`capsule_zuse_boot_load_root_pubkey()` reads Zuse's public key from the genesis marker in the
disk's metadata fence (`blk_meta_zone_read(0)`).
2. Every xHCI controller is found and brought up (`xhci_find_and_map`, `xhci_bringup`); a drive
already in a port is enumerated by the bring-up's port scan.
3. The timer starts, interrupts are enabled ("Heartbeat running.").
4. `sk_repl_headless_wait()`: no banner, no prompt, no input. Every 100 ticks (`sk_repl_idle`):
`xhci_poll_events()`; for each mass-storage device whose attach is pending,
`blkio_usb_open_msc()`, then `homeblocks_sig_check()`; the device is given to the block
subsystem (in v3 by a round trip through the Artemis VM and kernel-Hermes, ending in
`BLK-ATTACH-ACK` on Hera); then `capsule_zuse_boot_try_attach()`:
- genesis marker present and the drive's identity record (magic, version, CRC-64) carries the
marker's public key: "Zuse: identity confirmed from attached thumbdrive"; the cert is
installed (one-way), and `ACL-ZUSE-BOOT` sets Hera's `zuse_session`;
- no marker and a blank drive: genesis — Zuse is minted onto the drive and the marker written
to the disk's fence;
- anything else: nothing.
The wait ends when `sk_console_identity_present()`: Zuse's session, or a `WIREBIND` user.
5. The banner, then `sk_repl_run()`, which re-checks identity before every prompt and while it
waits for a line with nothing typed; when no one is attached it goes back to the headless wait.
A drive pulled out: `blk_subsys_detach_device()`, `capsule_zuse_boot_logout()` ("Zuse: session
ended -- reattach to re-authenticate").
## What v4 does instead (Q1 ruled: Hera, Hermes, Artemis are kernel functions)
The same steps, done by the kernel for the v4 boot, with no v3 `VM` behind them:
- **Artemis is the kernel's**, so the kernel gives an attached drive to the block subsystem itself
(`blk_subsys_attach_device`), with no VM round trip.
- **Zuse's state is the kernel's**, held for the first node, Hera: session, cert installed
(one-way), root public key. Not in the node's memory and not in a v3 `VM`.
- **The prompt loop** in `sk_v4_run()` re-checks identity as `sk_repl_run()` does.
## Decisions for Captain Bob
**RULED 2026-10-26 (Captain Bob): D1 to D4 as recommended** — split the file; recognise only;
`[zuse@Hera] ok>` now; the minted pair the QEMU default.
**D1. The identity check without a VM.** `capsule_zuse_boot_try_attach()` takes Hera's `VM *`
and ends in `vm_interpret(mama_vm, "ACL-ZUSE-BOOT")`; its readers (`genesis_marker_read`,
`read_devblock`, the identity-record checks) are `static`.
*Recommend:* split `capsule_zuse_boot.c` into a check that needs no VM — given the device and
its signature result, it says "Zuse's drive", "genesis-eligible" or "not hers" and hands back
her seed and public key — and v3's `try_attach`, which calls it and does the rest exactly as
now. v4 calls the same check. One copy of code that handles Zuse's private key.
*Cost:* it is a change to a file on v3's path (the plan's rule is "nothing in v3's own path
changes"), with v3's behaviour unchanged; v3 is not part of acceptance, so that is shown by one
`system=v3` boot with the minted pair ("identity confirmed", `[zuse@Hera] ok>`).
*If not:* a v4 copy of the check, beside v3's, until v3 leaves.
**D2. Genesis on v4.** v3 mints Zuse onto a blank drive when the disk has no marker. That writes
the marker to Artemis's disk, and the v4 boot does not write the disk until the owner says it may
(`sk_v4_block_chain`'s comment; Phase 5).
*Recommend:* the gate recognises a minted Zuse only. On v4 a blank pair stays headless, and says
so once ("Zuse: no genesis on this disk -- the system stays headless"). Genesis on v4 comes with
Artemis's writes (Phase 5).
**D3. The prompt.** v3's is `[zuse@Hera] ok>`: the console's line prefix, from the VM name and the
user. Banner and prompt are row 12, Phase 6.
*Recommend:* in this gate, the console's VM name is set to Hera and its user prefix says `zuse`
while her session holds, so the prompt is `[zuse@Hera] ok>` as v3's, from the moment there is an
identity. The banner stays Phase 6. Nothing before the first prompt changes.
*If not:* `ok>` as today, and the prefix with row 12.
**D4. Which disks QEMU boots with.** The gate makes a bare `make ARCH=<isa> clean qemu`, with
today's defaults (the blank `disk/artemis.img` and `disk/thumbdrives/zuse-thumb-ident.img`), stay
headless, so no acceptance boot reaches `ok>`.
*Recommend:* `kernel/Makefile`'s defaults become the minted pair, `disk/zuse-scratch/artemis.img`
and `zuse-thumb-ident.img`. The acceptance rule to put the disk images back as committed before
each ISA then applies to them. `.claude/CLAUDE.md` says so.
*If not:* every acceptance boot passes `ARTDISK=` and `ZUSEDISK=` copies, and `.claude/CLAUDE.md`
says that instead.
**Not in this gate:** `WIREBIND` identities as a way in (Phase 6, with the user's VM born from the
drive), `EJECT`, the banner, `ACL-ZUSE-BOOT` and god-mode (Phase 4, ACL on v4), Artemis's writes and
genesis (Phase 5).
## Global Constraints
As the step 4 plan's, and:
- No kernel unit tests; the tests are QEMU sessions typed to over the serial socket and driven over
QMP (the serial and QMP sockets `kernel/Makefile`'s `qemu` goal opens), each written before the
change and seen to fail.
- The drives attached by QMP during a session are copies of `disk/zuse-scratch/`, in a scratch
directory; the committed pair is never booted directly.
## Tasks
### Task G0: Record
- [ ] **Step 1:** This plan; in the step 4 plan, "The identity gate" points here and the Phases
table puts the gate before Part A; `ENGINE.md` §2 one line saying the gate is built first.
- [ ] **Step 2:** Commit `docs(v4): the identity gate before Part A`.
### Task G1: The check without a VM (D1)
**Files:** `kernel/src/capsule/capsule_zuse_boot.c`, `kernel/include/starkernel/capsule_zuse_boot.h`.
**Interfaces:** Produces
`zuse_drive_t capsule_zuse_boot_check(struct blkio_dev *dev, homeblocks_sig_result_t sig_rc, const homeblocks_sig_t *sig, uint8_t seed[32], uint8_t pubkey[32]);`
with `ZUSE_DRIVE_HERS`, `ZUSE_DRIVE_GENESIS` (no marker, blank drive), `ZUSE_DRIVE_NOT_HERS`;
`int capsule_zuse_boot_root_pubkey(uint8_t pubkey[32]);` (0 = the marker read and checked).
`try_attach` and `load_root_pubkey` call them; their behaviour and messages do not change.
- [ ] **Step 1: Failing test:** a `system=v3` amd64 boot with copies of the minted pair, before
the change: record "Zuse: identity confirmed from attached thumbdrive" and `[zuse@Hera] ok>`
(the reference; this step is the yardstick, not a failure).
- [ ] **Step 2:** Split as above.
- [ ] **Step 3:** The same `system=v3` boot after: the same lines. A blank copy pair: "Zuse: genesis
minted onto attached thumbdrive", as before.
- [ ] **Step 4:** Commit with the two logs.
### Task G2: The gate on the v4 boot
**Files:** `kernel/src/v4/sk_v4.c`, `kernel/include/starkernel/v4/sk_v4.h`, `kernel/src/kernel_main.c`
(the v4 branch only: what `sk_v4_run` is given), a new `kernel/src/v4/sk_v4_identity.c` +
`kernel/include/starkernel/v4/sk_v4_identity.h` (Zuse's state for Hera; the idle beat's USB
servicing for the v4 boot).
**Interfaces:** Consumes G1. `sk_v4_run(chain)` keeps its signature; after `chain()` it: loads the
root public key; brings up every xHCI controller; starts the timer and enables interrupts as v3
does ("Starting heartbeat...", "Heartbeat running."); waits headless; then the prompt loop.
- [ ] **Step 1: Failing tests** (amd64 sessions, before the change):
- `gate_headless`: booted with no Zuse drive (`ZUSEDISK=`), the log has `POST: PASSED` and no
`ok> ` within 60 s of it. Today: FAIL (`ok>` appears).
- `gate_zuse`: booted with copies of the minted pair: "Zuse: identity confirmed from attached
thumbdrive", then `[zuse@Hera] ok> ` (D3), and `3 4 + .` answers `7 ok`. Today: FAIL.
- `gate_hotplug`: booted with no Zuse drive; QMP `blockdev-add` + `device_add usb-storage` of a
copy of the minted Zuse drive → identity confirmed → prompt; a line typed; `device_del` →
"Zuse: session ended -- reattach to re-authenticate", no further `ok> ` for 30 s; added again →
prompt. Today: FAIL.
- [ ] **Step 2:** Build the gate.
- [ ] **Step 3:** The three sessions pass; the v4 suite passes
(`make -C v4 test test-32 sanitize hosted-check`, unchanged: nothing in `v4/` changes).
- [ ] **Step 4:** D4 as ruled (`kernel/Makefile` defaults and `.claude/CLAUDE.md`, or the
command line).
- [ ] **Step 5:** Full acceptance: three `clean qemu` boots with the minted pair, to
`[zuse@Hera] ok>`, `PARITY:V4_POST ... fail=0`, `POST: PASSED`, `dict_hash` unchanged and equal
(`0xfec8c47cfc6f437f`, word_count 317: nothing on the node changes); `gate_hotplug` on aarch64
and riscv64 too; `make -C v4 test-32`, 0 failures. Commit `feat(v4): no identity drive, headless;
Zuse's drive, a console`, then the logs.
## Review Focus
1. **A drive pulled mid-line**: the line in hand finishes; the next prompt is not shown.
2. **A drive that is not Zuse's** (another identity, a blank one, a foreign one): no prompt, no
message beyond v3's.
3. **Zuse's seed** is read into kernel memory only, never into a node's memory, and the cert is
installed once (one-way, as `vm_zuse_cert_install`).
4. **The idle beat while the node runs a line**: USB servicing happens only at the prompt or in
the headless wait, never while the node is mid-line (v3's `g_mama_interpreting` reason).
5. **All three ISAs**: hot attach and detach on aarch64 and riscv64, not only amd64.