Boots amd64 with Zuse's bleached thumbdrive, confirms live: fresh 1 GiB
disk/artemis.img formats ("Artemis: blank disk -- formatting"), Zuse
genesis-mints onto it ("Zuse: genesis minted onto attached thumbdrive",
root CA written to the new fence's devblock 0), session authenticates
(zuse@Hera ok>). With Zuse live, mints the other 8 identities (bob, 00-06)
one at a time via QMP-driven xHCI hotplug + MINT at the console, each
confirmed by its own "MINT: identity minted" log line before detaching
and moving to the next. Clean BYE shutdown, zero leaked qemu/socat
processes, all 9 images verified nonzero.
Root cause confirmed live before executing: Zuse's genesis marker lives
on artemis.img's own fence (devblock_from_top=0), not on her thumbdrive
-- with the marker gone, her old drive could not have re-authenticated
regardless of its own content, confirming re-mint was genuinely required.
FABRIC-3.md §XXXV.7/.8, disk/README.md updated with the full account.
Serial log preserved: logs/20260917-114652/amd64/.
Still open: the block-backed DoE persistence writer itself is unbuilt
(design only); ZUSE-ELIGIBILITY-ADD (elevation eligibility, narrower
than baseline auth) not re-populated for any of the 8; old 30 MiB
artemis.img backup disposal undecided.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
183 lines
12 KiB
Markdown
183 lines
12 KiB
Markdown
# disk/
|
||
|
||
QEMU disk images used for Artemis (block-storage VM) persistence testing.
|
||
Mounted via `Makefile.starkernel`'s `ARTDISK` variable (default
|
||
`disk/artemis.img`) as a `virtio-blk-pci` device on all three
|
||
architectures' kernel QEMU boots — not `scripts/rundisk.sh`, which targets
|
||
a separate, currently-unused `disks/` (plural) directory for the *hosted*
|
||
VM's `--disk-img=` flag instead.
|
||
|
||
- `artemis.img` — standard Artemis persistence test disk. **Rebuilt fresh at
|
||
1 GiB, 2026-09-17** (FABRIC-3.md §XXXV.6): the prior 30 MiB image was
|
||
three orders of magnitude too small for the block-backed per-ISA DoE
|
||
persistence design (§XXXV.2 — measured 516 MB for just 8 trials of raw
|
||
per-tick data against a 30 MiB device). Rather than migrate the existing
|
||
image's top-of-device system-metadata fence to new geometry (fence
|
||
addressing is relative to `total_devblocks`, so a resize alone would shift
|
||
every existing fence consumer onto the wrong physical bytes), Captain Bob
|
||
ratified building a brand-new blank image and re-minting Zuse + all
|
||
thumbdrive identities fresh against it, since re-minting invalidates the
|
||
prior identities regardless of whether a migration is attempted. Blank
|
||
(all zero) at creation, same as every other fresh-format fixture below.
|
||
**Formatted and re-minted live, same day**: booted amd64 with Zuse's
|
||
(freshly bleached) thumbdrive attached at launch — `Artemis: blank disk --
|
||
formatting` confirmed the fresh format, `Zuse: genesis minted onto
|
||
attached thumbdrive` confirmed her genesis mint (root CA — her
|
||
`zuse_pubkey` — written to this image's own devblock 0, per
|
||
`capsule_zuse_boot.c`'s `genesis_marker_read()`/`install_and_activate()`),
|
||
and the `zuse@Hera ok>` prompt confirmed her session authenticated. The
|
||
other 8 identities (`bob`, `00`–`06`) were then minted one at a time via
|
||
QMP-driven xHCI hotplug (`drive_add`/`device_add` per drive, `MINT` or a
|
||
`MINT-NUM` helper word at the live console, `device_del`/`drive_del` to
|
||
detach before the next) — all 9 `MINT: identity minted` confirmations
|
||
present in `logs/20260917-114652/amd64/qemu-amd64-20260917-114652.log`,
|
||
clean `BYE` shutdown, no leaked qemu/socat processes. The superseded
|
||
30 MiB image is preserved, not deleted, as
|
||
`artemis-30mb-pre-1gib-backup.img` (below).
|
||
- `artemis-30mb-pre-1gib-backup.img` — the pre-2026-09-17 `artemis.img`
|
||
(30 MiB), preserved rather than deleted when `artemis.img` was rebuilt
|
||
fresh at 1 GiB (see above). Kept for reference / possible forensic
|
||
recovery of the prior Zuse/thumbdrive identity state; disposal is a
|
||
separate, still-open decision (FABRIC-3.md §XXXV.7), not made here.
|
||
- (superseded, kept for history) `artemis.img` was previously **reformatted
|
||
2026-08-02**: this image had been stuck in a corrupted state (valid
|
||
`LithosAnanke` magic header, but data not matching what
|
||
`ART-READ-TEST` expects) since before this repo's own git history
|
||
begins (`git log` shows it already broken at the initial commit,
|
||
carried over from the pre-split monorepo). Chasing down the resulting
|
||
persistent `FAIL: persist-read` traced to the *data*, not the code —
|
||
the write→reboot→read round trip works correctly on a fresh image
|
||
(see `artemis-debug-roundtrip.img` below). Reformatted by blanking the
|
||
file and letting a normal boot format+write-test it; verified
|
||
`PASS: persist-read` on amd64, aarch64, and riscv64 against the same
|
||
image afterward (cross-arch resume, matching the arch-neutral on-disk
|
||
format `.claude/ARTEMIS.md` specifies). This history now applies to
|
||
`artemis-30mb-pre-1gib-backup.img`, not to the current `artemis.img`.
|
||
- `artemis-debug-roundtrip.img` — round-trip regression fixture created
|
||
during that investigation. Known-good: format → self-test → write-test
|
||
→ reboot → resume → `PASS: persist-read`, confirmed 3 times in a row.
|
||
Keep this in a passing state; if a future change breaks it, that's a
|
||
real regression, not a stale-fixture artifact like `artemis.img` was.
|
||
- `artemis-persist-test.img` — persistence round-trip test image
|
||
(pre-existing; history/state not re-verified during the above
|
||
investigation).
|
||
- `artemis-poison.img` — a separate test image (exact scenario not
|
||
documented elsewhere in the repo as of this writing; name suggests an
|
||
adversarial/corruption test, not confirmed).
|
||
- `artemis-unrecognized-test.img` — exercises `ART-HALT-UNRECOG`
|
||
(`.claude/ARTEMIS.md` acceptance criterion #6). **Regenerated
|
||
2026-08-02**: the previous copy of this file had itself been silently
|
||
reformatted by a since-fixed bug in the *generic* block subsystem
|
||
(`src/block_subsystem.c`) — it carried a valid low-level `'STFR'`/v2
|
||
header despite being meant to represent foreign disk content, direct
|
||
forensic evidence of the bug described in `.claude/ARTEMIS.md`'s
|
||
Build Status item 6. Regenerated as 30MB of a repeating
|
||
`POISON-UNRECOGNIZED-DISK-TEST-FIXTURE--NOT-BLANK-NOT-STFR-NOT-ARTEMIS--`
|
||
ASCII pattern — deliberately neither blank, nor the block subsystem's
|
||
own `'STFR'` magic, nor Artemis's `"ARTEMIS\0"` marker. Verified on
|
||
amd64 and riscv64 post-fix: boot correctly halts
|
||
(`ARTEMIS HALT: unrecognized disk content`) and the file's sha256 is
|
||
now byte-for-byte identical before and after boot. Keep this fixture
|
||
in this poisoned state — if a future change makes its sha256 change
|
||
across a boot, that is exactly the regression this fixture exists to
|
||
catch.
|
||
|
||
Note on incidental header churn: `artemis.img` picks up a few changed
|
||
header bytes on every ordinary boot even though no user data changes —
|
||
`blk_subsys_attach_device()` always records a fresh `mounted_time` on a
|
||
successfully recognized disk, which gets flushed at shutdown. This is
|
||
expected bookkeeping, not a bug; revert it before committing rather than
|
||
carrying timestamp noise in git history.
|
||
|
||
- `usb-thumbdrive-test.img` — 64MB raw image backing a QEMU `usb-storage`
|
||
device attached to the xHCI controller's bus (`xhci0.0`) for Milestone 2e/
|
||
2h hotplug testing, added 2026-08-22. Blank (all zero) — `blkio_usb.c` +
|
||
`blk_subsys_attach_device()` wiring (Milestone 2h, done 2026-08-25) attach
|
||
it as `BLK_FMT_PROVISIONAL` every time, which is the intended, exercised
|
||
state; not yet `BLK_FMT_FORMATTED` via `BLK-CONFIRM-FORMAT`.
|
||
- `usb-thumbdrive-test2.img` — 64MB raw image, added 2026-08-25 for
|
||
Milestone 2h hot-detach/re-attach verification. Filled with a repeating
|
||
`HOTDETACH-REATTACH-FIXTURE-2026-08-25--` ASCII pattern, deliberately
|
||
distinguishable from `usb-thumbdrive-test.img`'s all-zero content — the
|
||
point is proving a block read *after* detaching `usb-thumbdrive-test.img`
|
||
and re-attaching this one actually returns this pattern rather than
|
||
silently replaying the old device's cached (all-zero) content, which is
|
||
exactly the class of bug a same-LBN-range device swap can cause if the
|
||
VM block window cache (`vm->blk_vm_cbuf[]`) isn't re-validated on a hit.
|
||
- `artemis-reloc-test.img` — 64MB raw image, added 2026-08-25 for single-block
|
||
relocation (`RELOCATE-BLOCK`) persistence verification. Blank at creation;
|
||
a genuinely *fresh* volume was required (not `artemis.img`) because
|
||
relocation-table capacity (`reloc_start`/`reloc_devblocks` in
|
||
`blk_volume_meta_t`) is only reserved by `blk_compute_fresh_geometry()` on
|
||
a fresh format — `artemis.img` predates the feature and correctly reads
|
||
back `reloc_devblocks=0` from what was previously unused header padding.
|
||
Attach via `make -f Makefile.starkernel ARTDISK=disk/artemis-reloc-test.img
|
||
...` (the Makefile's `ARTDISK` var is `?=`-overridable). Not yet
|
||
`BLK-CONFIRM-FORMAT`-committed in the repo copy — commit that step live if
|
||
reusing this fixture for further reloc-table testing.
|
||
|
||
- `artemis-metafence-fresh.img` — 30MB raw image, blank at creation,
|
||
added 2026-08-26 for the top-of-device system-metadata fence
|
||
(`meta_fence_blocks` in `blk_volume_meta_t`, FABRIC-2.md Phase 8 §C).
|
||
Same reasoning as `artemis-reloc-test.img` above: the fence is only
|
||
initialized to `BLK_META_FENCE_INIT` (128) by
|
||
`blk_compute_fresh_geometry()` on a fresh format, so a genuinely blank
|
||
volume was needed to exercise that path. Verified round-trip: fresh
|
||
format writes 128 (confirmed via direct byte read at header offset 184,
|
||
independent of kernel self-report), a second boot without reformatting
|
||
reads it back unchanged. Keep in its formatted (`meta_fence_blocks=128`)
|
||
state — a future change that resets or corrupts this on reload is a
|
||
real regression.
|
||
- `artemis-metafence-test.img` — 30MB raw image, a direct copy of the
|
||
pre-existing (pre-fence) `artemis.img`, added 2026-08-26 alongside the
|
||
fixture above to verify the *other* direction: an old volume that
|
||
predates `meta_fence_blocks` correctly reads it back as 0 (graceful
|
||
default via zeroed former padding, not corruption) rather than crashing
|
||
or misreading adjacent fields.
|
||
|
||
- `thumbdrives/` — the 9 **real** identity thumbdrive images (`zuse-thumb-
|
||
ident.img`, `bob-thumb-ident.img`, `00-thumb-ident.img`–`06-thumb-
|
||
ident.img`), 64 MiB each, minted via the actual kernel `MINT` word (not
|
||
blank placeholders). **Bleached and re-minted fresh, 2026-09-17**
|
||
(FABRIC-3.md §XXXV.6/§XXXV.8): required alongside the `artemis.img`
|
||
rebuild above, since Zuse's own genesis marker lives on `artemis.img`,
|
||
not on any thumbdrive — with that marker gone, none of these 9 images'
|
||
prior certs could authenticate against the new disk regardless of their
|
||
own on-drive content, and `capsule_mint_identity()` refuses to mint over
|
||
an already-recognized drive, so all 9 had to be blanked first. Same
|
||
verification convention as the original 2026-09-06 mint
|
||
(`project_thumbdrive_identities_minted_20260906.md`): nonzero-byte count
|
||
in each image's first 6 devblocks confirms real identity data present.
|
||
- `zuse.img` — 64MB raw image simulating the physical Zuse superuser
|
||
thumbdrive for QEMU testing (FABRIC-2.md, Phase 8: `zuse.img` "bleach"
|
||
mechanism, added 2026-08-26). **64MB is only this fixture's size, not a
|
||
constraint on real home-blocks thumbdrives** (Captain Bob, 2026-08-26) —
|
||
the design is not bound to any particular drive size; `homeblocks_sig_t`'s
|
||
own `metadata_devblocks` field records whatever size is actually observed
|
||
on a real drive, nothing in the format hardcodes one. 64MB here is purely
|
||
an arbitrary QEMU-test convenience (matching `usb-thumbdrive-test.img`'s
|
||
existing precedent for BOT driver testing scale); use
|
||
`scripts/bleach_zuse_img.sh --size-mb N` for a different test size. Blank
|
||
(all zero) at creation — reads back as `HOMEBLOCKS_SIG_BLANK` via
|
||
`homeblocks_sig_check()`, confirmed live (`xhci: USB drive not recognized
|
||
(blank or foreign media)`), simulating a genuine first boot for exercising
|
||
the still-to-be-built one-time mint-Zuse flow. **"Bleach" it back to this
|
||
pristine/unminted state with `scripts/bleach_zuse_img.sh`** before each
|
||
first-boot test run, rather than hand-regenerating the file — same
|
||
all-zero content either way, the script just makes the reset a single
|
||
documented, repeatable command. Deliberately a flat/raw image, not
|
||
GPT-partitioned, matching `homeblocks_sig_check()`'s current call site
|
||
(`repl.c`, `sig_start_fblock=0`) — both will move to a real
|
||
GPT-partition-relative offset together once a GPT parser exists, not
|
||
attempted ahead of that.
|
||
|
||
**Convention, standing as of 2026-08-22: every virtual disk/thumb-drive image
|
||
used for testing — Artemis persistence disks above, and USB Mass Storage
|
||
backing images alike — lives in this directory and is a tracked, committed
|
||
file, never scratchpad.** This was already `artemis.img`'s convention;
|
||
`usb-thumbdrive-test.img` and any future USB test images follow the same
|
||
rule. Confirmed no `.gitignore` in this repo excludes `disk/*.img`.
|
||
|
||
These are regenerable QEMU raw disk images, not source — see
|
||
`.claude/ARTEMIS.md` for the storage model they exercise.
|