diff --git a/FABRIC-2.md b/FABRIC-2.md index 7344bb6..508a529 100644 --- a/FABRIC-2.md +++ b/FABRIC-2.md @@ -2966,3 +2966,264 @@ overwritten; the zuse credential, once minted, can never be re-minted. Not started: no code, no capsule work, no hardware testing yet. This section exists so a future session (or Captain Bob re-reading cold) gets the whole shape in one read, rather than needing to reconstruct it by reading U, V, and this section's own cross-references in sequence. + +--- + +## X. Artemis punch list — deep detail, one task at a time, 2026-08-22 + +Requested explicitly: deep, function-level granularity, no code written yet — this is the +task breakdown only. Organized by milestone, in the sequence Section W established. Each +milestone is independently checkable off; sub-items within a milestone are ordered (later +items generally depend on earlier ones in the same milestone unless noted). `[ ]` = not +started, matching this file's existing convention (Section F). Where a task genuinely needs +spec research before it can even be scoped precisely (mostly in Milestone 3, USB hardware), +the research step is its own punch-list item rather than skipped. + +### Milestone 1 — Bare-metal boot from physical USB (demo/"try it" mode) + +Confirmed not gated on any other milestone below (Section W). Smallest, nearest-term, +actionable now. + +- [ ] Confirm which physical machine will receive the first real-hardware boot test (CPU + arch — amd64 assumed given the SanDisk drives on hand, but confirm) +- [ ] Build a fresh `starkernel.iso` via `make -f Makefile.starkernel ARCH=amd64 clean` + + the ISO-build step (already runs as part of `qemu` target — confirm it can be invoked + standalone without also launching QEMU, or just let the `qemu` target build it and + Ctrl-C before the QEMU launch line) +- [ ] Identify the exact block device path for the target USB drive on the host doing the + flashing (`lsblk`/`dmesg` after insertion — care needed, wrong device = data loss on + the wrong disk) +- [ ] `dd if=build/amd64/kernel/starkernel.iso of=/dev/sdX bs=4M status=progress` (or + equivalent) — confirm `dd` is the right tool for an El Torito ISO vs. needing + `isohybrid` or similar preprocessing first (open question, not yet verified either + way) +- [ ] Physically boot the real machine from the flashed drive (BIOS/UEFI boot-order menu, + Secure Boot may need disabling — unknown until tried, per Section W's caveat) +- [ ] Capture what happens with no serial-socket log available (real hardware has no + `qemu-serial-*.sock` to `socat` into) — decide the observation method: onboard + framebuffer/console output only, or a real serial cable to another machine, or nothing + beyond "did it reach `ok>`" +- [ ] Confirm POST reaches the same 1012/0/0 result on real hardware as every QEMU + acceptance run this session +- [ ] Confirm `ok>` prompt is reachable and a basic command (e.g. `HEARTBEAT-TICKS@ .`) works + identically to QEMU +- [ ] Document the result (pass/fail, and if fail, what diverged from QEMU) — first real + external validation this project has ever had outside QEMU TCG emulation + +### Milestone 2 — QEMU monitor/QMP socket (small, unblocks dev-iteration workflow) + +Independent of Milestone 1; useful before Milestone 3's virtual-drive testing starts. + +- [ ] Add `-qmp unix:$QMP_SOCK,server=on,wait=off` to each arch's QEMU invocation in + `Makefile.starkernel`, matching the existing `-chardev socket,id=cserial,...` pattern + already used for the serial console +- [ ] Confirm the QMP socket path gets logged/echoed the same way the serial socket path + already is, so it's discoverable the same way +- [ ] Verify a basic QMP handshake works (`qmp_capabilities` negotiation is required before + any other QMP command — confirm via `socat`/manual JSON, not HMP text commands, since + QMP is JSON-based and HMP is text-based; decide which of the two is actually wanted — + HMP (`-monitor`) is simpler to drive by hand via `socat`, QMP is more scriptable but + needs the capabilities handshake first) +- [ ] Confirm `device_add`/`device_del` works against a trivial device (not USB yet — prove + the mechanism itself first with something simple) before relying on it for Milestone 3 + +### Milestone 3 — USB hardware stack (the hard prerequisite, most granular breakdown) + +Nothing in Section U/V/W's home-blocks thread is testable past this point without it. Ordered +roughly bottom-up: PCI discovery → controller bring-up → command/event rings → port/hotplug +detection → device enumeration → mass-storage class → read/write. + +**3a. Research/spec groundwork (do first, nothing below can be scoped precisely without it)** +- [ ] Confirm xHCI is the right target controller class (vs. EHCI/OHCI) for QEMU's + `qemu-xhci` device and for realistic modern real hardware — xHCI is the USB 3.x + standard and QEMU's default modern USB controller, but confirm no fallback to EHCI is + needed for older/simpler test hardware + before writing controller-bringup code +- [ ] Pull the xHCI register-interface layout (Capability Registers, Operational Registers, + Runtime Registers, Doorbell array — the four MMIO regions) from the xHCI spec; this + project has no existing xHCI reference to build from (unlike virtio-blk, which had the + virtio spec's existing precedent already used in this tree) +- [ ] Decide command-ring and event-ring sizes/allocation strategy up front (fixed small + ring vs. dynamically sized) — affects the memory-management code below + +**3b. PCI discovery** +- [ ] Extend `src/starkernel/pci/pci.c`'s enumeration to recognize the xHCI PCI class code + (Serial Bus Controller / USB Controller / xHCI programming interface) the same way it + already recognizes whatever device classes it currently handles (need to read + `pci.c`'s current class-match logic before extending it, not written from scratch) +- [ ] Read and store the xHCI controller's BAR (memory-mapped I/O base address) from PCI + config space +- [ ] Map that MMIO region into kernel virtual address space (via `vmm.c`'s existing + page-table machinery — confirm the right mapping-request function to call, matching + how virtio-blk's MMIO region gets mapped today as the closest existing precedent) + +**3c. Controller bring-up** +- [ ] Read Capability Registers to learn controller parameters (max device slots, max ports, + max interrupters — needed to size later allocations) +- [ ] Perform xHCI controller reset sequence +- [ ] Allocate and program the Device Context Base Address Array (DCBAA) +- [ ] Allocate and program the Command Ring, write its base address to the Operational + Register `CRCR` +- [ ] Allocate and program at least one Event Ring (segment table + ring buffer), wire it to + Interrupter 0 +- [ ] Set the `RUN/STOP` bit to start the controller +- [ ] Confirm controller reaches a running state (poll a status register, don't assume) + +**3d. Interrupt/event handling** +- [ ] Wire an interrupt handler for the xHCI controller's IRQ line (via existing per-arch + interrupt infrastructure, `starkernel/arch/*/interrupts.c` — same place the timer ISR + already hooks in, per the heartbeat work this session) +- [ ] Implement Event Ring TRB (Transfer Request Block) parsing — at minimum, Port Status + Change events (hotplug) and Command Completion events, to start +- [ ] Implement Event Ring dequeue-pointer update / interrupt-clear sequence so the + controller keeps delivering new events + +**3e. Hotplug detection (the actual trigger for everything in Section U)** +- [ ] On a Port Status Change event, read the corresponding Port Register to determine + connect vs. disconnect +- [ ] On connect: allocate a Device Slot (Enable Slot command via the Command Ring), address + the device (Address Device command), read its device descriptor +- [ ] On disconnect: tear down the corresponding device slot and signal to whatever higher- + level code (Section U's identity/VM logic) that the device is gone — **this is the + first point where Section U/V's design actually gets a real trigger to hang off** +- [ ] Decide and implement where the hotplug event surfaces to the rest of the kernel — + likely a callback registered by whatever owns the home-blocks logic, not xHCI code + calling into block_subsystem.c directly (matching the existing "kernel/Artemis + decoupling boundary" pattern already documented in `block_subsystem.c`) + +**3f. USB device enumeration (post-connect, before it's usable as storage)** +- [ ] Request and parse the device descriptor (confirm vendor/product IDs are even needed, + or if class-only detection suffices for this project's purposes) +- [ ] Request and parse the configuration descriptor +- [ ] Confirm the device reports the Mass Storage class / Bulk-Only Transport subclass/ + protocol (this is the actual "is this a USB drive" check — separate from, and prior + to, Section U item 7's foreign-drive/home-blocks-signature check, which happens one + layer up, after the drive is already known to be USB mass storage) +- [ ] Set the device configuration (SET_CONFIGURATION control transfer) + +**3g. Bulk-Only Transport (BOT) — the actual read/write path** +- [ ] Identify and configure the device's bulk IN and bulk OUT endpoints +- [ ] Implement CBW (Command Block Wrapper) construction and send, for a SCSI READ(10) +- [ ] Implement CSW (Command Status Wrapper) receive and status check +- [ ] Get one real SCSI READ(10) working end to end — first proof the whole stack works, + before write +- [ ] Implement CBW/data/CSW for SCSI WRITE(10) — this is where the earlier "read/write, + unquestionable" requirement actually gets satisfied +- [ ] Implement basic error/stall recovery (CSW failure status, endpoint stall clear) — at + minimum enough to not wedge the controller on a single bad transfer + +**3h. Integration with the existing block subsystem** +- [ ] Wire a working USB MSC device into `blk_subsys_attach_device()` (or + `blk_subsys_add_raw_device()`, whichever fits — confirm which, since USB is + persistent+removable, a hybrid of the two existing categories) — this is the point + where Milestone 3's work actually becomes visible to everything in Section U/V's + block-layout design +- [ ] Confirm a plugged-in USB drive shows up in the LBN chain at the expected offset + (today: attach-order-based, per Section V area A — item below in Milestone 4 changes + this to identity-derived) + +### Milestone 4 — Block subsystem extensions (Section U items 3-6, Section V area A) + +Depends on Milestone 3 existing (needs a real device to test against, though the +identity→range derivation logic itself could be unit-tested against the existing RAM/ +RAMDRIVE/DISK devices first without waiting for USB). + +- [ ] Design the identity→block-range derivation function's exact input/output (Section V + area A open point: currently zero decisions made, not even a function signature) +- [ ] Decide what "identity" means concretely as an input — the Ed25519 public key itself, + a hash of it, something else +- [ ] Implement the derivation function +- [ ] Design the on-drive block-map format (Section U item 4) — what it records (block + ranges claimed? individual block liveness? something else), how it's serialized +- [ ] Implement writing the block-map to a drive +- [ ] Implement reading/validating the block-map from a drive on insertion +- [ ] Design the migration state machine (Section U item 5) — states, transition triggers, + and explicitly settle the still-open question from Section U: does it reuse + `physics_hotwords_cache.c`'s promote/evict logic (confirmed in Section V to be + hardcoded to `DictEntry*`, so "reuse" would mean genericizing it, not a drop-in) or + get its own independent implementation +- [ ] Implement the block-migration function itself (move one block's content + BAM entry + between two attached devices) +- [ ] Implement the `sk_repl_idle()` body — the cheap "anything dirty? no? done" check + (Section V confirmed this hook is empty and ready right now, doesn't even need + Milestone 3 to be written, only to be *tested end to end*) +- [ ] Decide and implement unclean-removal handling (Section U's explicitly flagged open + question — never answered) — at minimum, detect a mid-flush disconnect via + Milestone 3e's disconnect signal and decide what state that leaves affected blocks in + +### Milestone 5 — Drive/credential security (Section U items 7-8, Section V area C) + +- [ ] Design the home-blocks drive signature format (Section U item 7) — reusing + `CAPSULE_MAGIC_PACK`'s pattern (magic + version in a fixed header field) as the + confirmed precedent, applied to a drive's reserved header block instead of a capsule +- [ ] Implement the signature check, called before any write path touches a newly-inserted + drive +- [ ] Implement the warn-and-refuse behavior for blank/foreign/unrecognized media +- [ ] Extend `acl_pinned`'s one-way-ratchet mechanism (Section V area C: already exists, + already proven, just needs applying) to gate zuse credential minting specifically — + confirm whether this literally reuses the existing `acl_pinned` bit on some relevant + `DictEntry`, or needs its own analogous one-way flag on the credential data itself + (the credential isn't a dictionary word, so the existing bit may not directly apply — + open question, not yet resolved) + +### Milestone 6 — Console/VM key-match binding (Section U item 9, Section V area D) + +- [ ] Settle the still-open question from Section U/V: reuse `ACL-PIN`/`acl_allow` directly, + or build a separate key-matching primitive — Section V's finding was that `ACL-PIN` + gates word execution specifically and nothing today gates console-session-to-VM + ownership, so this decision needs to happen before any code gets written here +- [ ] Design the key/lock data shape (what the console presents, what the VM carries, how + they're compared) +- [ ] Wire drive insertion (Milestone 3e's hotplug signal, post-identity-authentication) to + a call into `capsule_birth_baby()` (Section V confirmed this is a real, callable, + on-demand birth path already) to spin up or re-attach that identity's VM +- [ ] Implement the actual attach/bind step — extending `sk_repl_set_active_vm()` (confirmed + to exist, currently an unguarded raw pointer-set) with the key-match check from above, + so a console can only bind to the one VM whose lock matches its key +- [ ] Implement detach behavior on console disconnect or VM teardown + +### Milestone 7 — Kernel/capsule PKI signing chain (Section U items 10-14, Section V area E) + +- [ ] Generate (offline, outside the kernel/repo entirely) the CA root keypair — "stays + unrevocable," never embedded, never loaded by any kernel code +- [ ] Generate an intermediate certificate, signed by the CA +- [ ] Embed the intermediate cert as a capsule blob (mechanically proven already via the + font-capsule precedent — no new embedding infrastructure needed, just a new payload) +- [ ] Implement kernel-boot-time verification of the embedded cert against a hardcoded CA + public key (the CA key itself has to be baked into the kernel some way that isn't + "just another capsule," since capsules are exactly what's being validated — this is a + real bootstrapping/chicken-and-egg design question not yet addressed anywhere in + Sections U/V/W) +- [ ] Implement per-capsule signature verification (Ed25519) at capsule-load time, checked + against the now-verified intermediate cert +- [ ] Add a signing step to the `mkcapsule` build tool (or a separate signing tool) that + produces a signature alongside each capsule's existing xxHash64 +- [ ] Extend `MANIFEST_AUTO.md`'s generation to add a signature-status column, matching the + existing xxHash64 column's generation pattern +- [ ] Implement magic-number-based content-type detection (Section U item 14) — a shared + primitive, per Section V, also usable for Milestone 5's foreign-drive check + +### Milestone 8 — Contributor capsules / trust tiers (Section U items 15-18, Section V area F) + +Explicitly sequenced after Milestone 7 closes. + +- [ ] Create the `capsules/contrib/` directory (mechanically trivial, matches existing + subdirectory convention — the directory itself is not the work, see below) +- [ ] Add a `FLAG_CONTRIB` bit to `mkcapsule.c`'s flag system, assigned by path match + (`contrib/` prefix), same pattern as how `init.4th` already gets `FLAG_MAMA_INIT` +- [ ] Decide and implement one of the four spitballed trust-tier directions from Section U's + third addendum (signature-authority tiers / block-namespace sandboxing / QEMU-vs- + real-hardware conditional enforcement) — none chosen yet, this is a real decision + point, not just an implementation task +- [ ] If block-namespace sandboxing is chosen: extend `mkcapsule`'s existing conflict- + detection logic to also reject a `contrib/`-path capsule claiming blocks outside its + reserved range + +### Milestone 9 — Networking / capsule distribution server + +Explicitly sequenced last, after everything above. Deliberately not broken down further here +— Section W already marks this as "pure concept... no design has been attempted yet beyond +the name and its rough purpose." Punch-listing this in real detail before Milestones 1-8 land +would be premature relative to Captain Bob's own stated sequencing. + +- [ ] (Deferred) Revisit and punch-list this milestone once Milestone 8 closes, not before