FABRIC-2.md Section U: Artemis USB thumb-drive / home-blocks design

direction notes -- brainstorming only, nothing implemented

Captures the direction from a design conversation immediately following
the ACL-TTL campaign close (Section T): Phase 8 PKI/thumbdrive context,
confirmation that zero USB code exists anywhere in the kernel today,
verification that the block-address-space layout the conversation
converged on independently already matches block_subsystem.h's own
documented (unimplemented) chained-device design almost exactly, and
six requirements gathered in order (no quota for now, re-insertion
consistency, identity-derived not attach-order-derived block ranges,
drive-carries-its-own-map, bidirectional transparent block migration
as a state machine, and sk_repl_idle() as the likely trigger hook --
already an empty coarse-cadence placeholder found during Section R).

Explicitly not a spec or plan of record -- written up so the next
session starts from an accurate baseline instead of re-deriving the
shape from scratch. No code, no design doc, no capsule work started.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-22 06:20:35 -04:00
co-authored by Claude Sonnet 5
parent f2e3bb1a90
commit afe64ba537
+106
View File
@@ -2505,3 +2505,109 @@ deterministic, architecture-independent, now validated across 6 seeds and 3 arch
(18 independent pairs, 36 cells, 17,280 rows) rather than the 3-seed/9-pair figure Section S
first established. No further extension scoped; this closes the ACL-TTL overhead measurement
line of investigation that ran through Sections P, Q, R, S, and this section.
---
## U. Artemis USB thumb-drive / home-blocks design — direction notes, 2026-08-22
**Status: design conversation only. Nothing in this section is implemented.** Captain Bob
opened this as forward-looking brainstorming ("play it by ear") immediately after the ACL-TTL
campaign closed (Section T), explicitly to get the shape on record before building anything —
not a spec, not a plan of record, just the direction as it stands. ACL work (Phase 8 PKI/
thumbdrive itself) is explicitly deferred — "not gonna worry about ACLs quite at this moment"
— this section is about the storage/device side of the same physical thumb drives, which turns
out to be a separate, larger piece of work in its own right.
**Context: this *is* Phase 8.** The ACL system's one remaining open item (word-level ACL,
complete through Phase 7, this file's header) is "PKI / thumbdrive — Ed25519 challenge-
response; user minting by zuse." Two physical USB drives are the plan: one mints/authenticates
Captain Bob's operator identity, the other mints/authenticates the `zuse` superuser identity —
replacing the current software-only `ZUSE-AUTHENTICATE` call (the one Section R had to invoke
directly at the REPL, working around `zuse.4th`'s self-pin bug) with something a physical
device actually has to be present for.
**Current reality: zero USB code exists.** Confirmed by repo-wide search — no `usb.c`,
no xHCI/EHCI/OHCI, nothing, anywhere in `src/starkernel/`. Only PCI enumeration
(`starkernel/pci/pci.c`) and virtio-blk (`starkernel/virtio/virtio_blk.c`) exist today. QEMU
itself can genuinely hotplug a USB device at runtime (`device_add usb-storage,drive=...` or
`usb-host` for passthrough, via QMP/HMP) — the guest sees a real emulated insertion event, not
a scripted fake — but the kernel has nothing to receive it with. This is confirmed to require
a real new subsystem: minimal xHCI controller support (connect/disconnect interrupt) plus USB
mass-storage class (bulk-only transport), and it must be **read/write, not read-only** — "read
write. It has to be. That's unquestionable" — because the drive isn't just carrying a static
credential, it's carrying a live index that has to be written back to as usage grows (see
below). Sized closer to the virtio-blk build-out than to a driver stub.
**The block-address-space design is already there — confirmed against the actual header
comment, not just recalled from memory.** `include/block_subsystem.h`'s own layout comment:
```
LBN 0..2047: FAST RAM (volatile, g.ram_base)
LBN 2048..x: RAMDRIVE (raw RAM buffer, volatile; first attached device)
LBN x..y: DISK IMG (virtio-blk, persistent; second attached device)
LBN y+: USB / future devices (chained, including hot-attach/detach)
```
with `BLK_RAM_BLOCKS=2080` (user-visible LBN 0..2047), `KRD_MAX_BLOCKS=1024` (LBN 2048..3071,
the RAMDRIVE), and the disk image (`disk/artemis.img`, virtio-blk) starting at LBN 3072+. The
phrase *"USB / future devices (chained, including hot-attach/detach)"* is already in the header
comment, unimplemented. `block_subsystem.c`'s own comment calls this "the kernel/Artemis
decoupling boundary: the kernel hands a `blkio_dev*` to `blk_subsys_attach_device()`; Artemis
owns everything below that call" — so the "home blocks" concept (a USB drive's blocks appending
at the next free LBN, becoming that identity's private range) is the intended consumer of a
chain mechanism that already exists, not a new design.
**Requirements gathered, in the order they came up:**
1. **No quota, ad hoc/first-come-first-served allocation.** Only two users right now (Captain
Bob, zuse); not a problem to solve yet. A user can claim as much of the virtual SSD
(`disk/artemis.img`) as they need.
2. **Re-insertion consistency is the hard requirement.** Same user, same drive, same block
mapping every time — rebuilt fresh each session, not trusted from a stale record.
3. **Identity-derived, not attach-order-derived, block ranges.** Flagged as a real tension
against the existing mechanism: `blk_subsys_attach_device()`'s chain currently assigns LBN
ranges by *attach order*, which is fine for the fixed RAM/RAMDRIVE/DISK devices (always
attach in the same order every boot) but wrong for two people's removable drives, whose
insertion order isn't guaranteed session to session. Resolution direction (confirmed
correct by Captain Bob): derive each identity's SSD block range from something on their
Ed25519 credential, not from insertion order, so the mapping is recomputed and verified
fresh each session but always lands on the same answer regardless of who plugged in first.
4. **The drive carries its own map, not the SSD.** The thumb drive keeps "a mini map" of that
user's SSD block allocations — the drive is the source of truth for "what's mine," not a
per-user directory living centrally on the SSD. Plug in, read the map, know instantly which
blocks are yours; unplug, and the SSD doesn't need to remember anything about you until
you're back. This is also the retroactive justification for requirement (read/write,
above) — the map has to grow as the user claims more SSD blocks over time, so the drive
needs to be written back to, not just read once.
5. **Bidirectional, transparent block migration between SSD and drive.** The LBN a user's
FORTH code sees stays fixed and location-transparent; the physical backing (SSD vs. thumb
drive) can migrate underneath it, "so that the user does not know where blocks are being
physically located." Explicitly bidirectional — not strictly SSD-primary/drive-backup —
"we don't want you losing work," so promotion/demotion runs both ways, driven "as much of a
state machine overall as we possibly can." This doesn't require a new abstraction layer:
the block subsystem already separates logical block number from physical backing via each
device's own BAM (`blk_dev_slot_t`), so this is teaching the existing LBN→device mapping
that an entry is allowed to migrate, not inventing a new one.
- **Open, not yet answered:** unclean-removal handling (drive pulled mid-flush, or before a
sync catches up), and whether the promotion/demotion logic should reuse the existing
heat-driven hot/cold state machine already built for dictionary words
(`physics_hotwords_cache.c`'s promote/evict logic, the same one whose `promotions=`/
`evictions=` counters print at every boot) rather than inventing separate block-level
promotion logic. Raised, not settled — Captain Bob's exact words trailed off before
confirming or rejecting this connection; worth returning to explicitly next session.
6. **Trigger mechanism: interrupt-driven, coarse cadence, cheap early-exit.** Not tied to
heartbeat tick volume or every REPL turn — "quick check blocks... done... ignore what we
can... done." This already has an empty seat waiting for it: `sk_repl_idle()` in
`src/starkernel/repl.c` is called at a coarser cadence than the raw per-tick ISR (gated by
`SK_IDLE_BEAT_INTERVAL`), explicitly documented in its own surrounding comment as *"a
separate, deliberately coarser cadence for higher-level subsystem dispatch"* — and it is
currently a no-op placeholder (confirmed empty during the Section R investigation into the
ACL-TTL heartbeat bug). This is the natural home for a cheap "anything dirty? no? done"
block-sync check.
**Not started:** no code, no design doc, no capsule work. This section exists so the next
session can pick up from an accurate baseline rather than re-deriving the shape from scratch.
Natural next steps, none begun: (a) settle the hotwords-cache-reuse question from item 5's
open point, (b) decide on the identity→block-range derivation function (item 3), (c) scope
the minimal USB xHCI + MSC bulk-only read/write driver as its own milestone, sized against
virtio-blk's build-out for comparison.