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>
175 lines
11 KiB
Markdown
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.
|