Files
LithosAnanake/disk
Robert Allan JamesandClaude Sonnet 5 09d78c99d0 BINDSTEP + fence-persistence fix: identity arc closed end to end
Two items, closed together per direct instruction.

1. Fence-persistence root cause, found and fixed: meta_fence_blocks
   (the field gating whether blk_meta_zone_write() can succeed at all)
   was carved out of what used to be unused padding in blk_volume_meta_t
   -- the code's own comment already documented this. disk/artemis.img
   was formatted before that field existed, so its on-disk bytes there
   have always read back as 0, and the existing-volume load path
   (blk_format_or_load_disk()) never recomputes it -- only a fresh
   format does. Every "fence write FAILED" message this entire session,
   old block-fence flow and new zuse_genesis_marker_t alike, traces to
   this one thing. Patching the field in place without redoing the rest
   of the geometry would risk corrupting whatever's already allocated
   near the top of the volume, so the only safe fix is a genuine
   reformat -- done, with explicit confirmation, since it discards
   disk/artemis.img's accumulated persistent test state (regenerated
   fresh at next boot regardless, not real data). Verified: fence write
   now succeeds with no failure suffix, and the full mint-once ->
   reboot -> reattach -> re-authenticate cycle works for the first time
   this session ("Zuse: identity confirmed from attached thumbdrive",
   ZUSE-SESSION? goes 0 -> -1 without re-minting).

2. BINDSTEP (FABRIC-3.md §F.9): capsule_wirebind_verify_cert() extracted
   as a shared function so WIREBIND (the original attach) and BINDSTEP
   (every USE of an identity-locked VM) check the exact same thing the
   exact same way. mama_word_use() now re-verifies live, not cached,
   whenever the target VM has VMIdentity.installed=1 -- reads whatever
   drive is CURRENTLY attached, re-verifies its cert, compares owner
   pubkey against the target's own installed identity, refuses on any
   mismatch or no drive attached. A target with installed=0 (Hera,
   Hermes, Artemis, any console VM) stays freely targetable, unchanged.

Two related bugs found and fixed live while testing BINDSTEP, not
assumed away: USE was Mama-only, so a console-paired session (§F.22)
had no way back to Hera at all -- any attempt to call USE from inside
a console VM hit "UNKNOWN WORD: USE", a genuine dead end. Per direct
instruction, USE isn't console-specific -- it should work VM-to-VM
universally, same as VM-EXEC already does -- so it's now registered in
register_child_vm_words() too. That alone wasn't enough: the console
relay (sk_repl_dispatch_line()) would have captured a bare USE call and
sent it to the paired user VM as a message instead of running it.
Fixed with a small suffix-match guard (sk_repl_line_calls_use()) --
real FORTH syntax always puts USE last, so a trailing-token check
reliably recognizes it without needing a full tokenizer, and it always
runs directly, never relayed.

Verified live end to end: USE on an unlocked VM works unconditionally;
USE escaping a console back to Hera now works; USE on an identity-
locked VM succeeds while its own drive is attached and is refused
once detached ("USE: FinT~user refused -- no matching identity
currently attached"). Clean 3-architecture regression, including
confirming disk/artemis.img's reformatted geometry loads correctly as
an already-recognized volume ("Artemis: LithosAnanke disk -- resuming")
on aarch64 and riscv64 too, not just the amd64 boot it was reformatted
under.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
2026-08-28 18:28:53 -04:00
..

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. 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).
  • 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-3.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.

  • zuse.img — 64MB raw image simulating the physical Zuse superuser thumbdrive for QEMU testing (FABRIC-3.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.