diff --git a/FABRIC-3.md b/FABRIC-3.md index d6ed615..d072daf 100644 --- a/FABRIC-3.md +++ b/FABRIC-3.md @@ -265,11 +265,44 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR Conservation intact, no panic. Clean zero-warning compile and clean boot on all three architectures. -- [ ] Extend `acl_pinned`'s one-way-ratchet mechanism (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). +- [x] **Resolved (2026-08-26): reuse `acl_pinned` directly, no new flag needed.** The open + question assumed credential data "isn't a dictionary word" — but the design already chosen + for it (`ZUSE-CERT-LO`/`HI`, `ACL-CA-KEY-LO`/`HI`) are `CONSTANT` words, i.e. real + `DictEntry`s. `acl_pinned`'s enforcement is more general than assumed: `vm_create_word()` + (`dictionary_management.c:394-404`) — the single choke point every word-defining construct + goes through — unconditionally refuses to let *anything* shadow a pinned name ("Pin is + permanent: no word may shadow a pinned entry — ever, by anyone"), a real general + redefinition guard, not just an ACL-mode-change lock. `zuse.4th`'s `ACL-ZUSE-BOOT` already + pins both cert constants today — the mechanism is already wired for this. + + **Real gap surfaced along the way, not yet fixed:** `ACL-ZUSE-BOOT` self-activates and pins + `ZUSE-CERT-LO`/`HI` unconditionally on *every* boot — before any legitimate minting step + could ever run, permanently locking in the `0` placeholder on the very first boot. The boot + sequence needs to distinguish "already minted, pin it" from "not yet minted, don't pin yet" + before minting can work at all. + + **This directly shaped the next design pass (2026-08-26, Captain Bob):** a dedicated + `disk/zuse.img` QEMU test thumbdrive, "bleachable" back to pristine/unminted state for + repeated first-boot testing; a one-time first-boot mint-Zuse flow (mint → write real cert → + blow the fuse → *then* pin, resolving the gap above); a separate, ongoing `S" name" MINT` + word for an authenticated Zuse session to mint additional regular users; and a Zuse recovery + path, explicitly flagged as unresolved and risky if rushed — not to be designed casually, + since the earlier "no software recovery, mint a new one" rule existed specifically to close + a hole a careless recovery path could reopen. + + **First piece implemented (2026-08-26): the `zuse.img` bleach mechanism.** + `disk/zuse.img` (64MB, blank, matching the existing USB-fixture convention exactly — see + `disk/README.md`) + `scripts/bleach_zuse_img.sh` (idempotent reset back to blank). Verified + live: hot-attached via QMP (same method as the warn-and-refuse verification above) — reads + back as `HOMEBLOCKS_SIG_BLANK` (`xhci: USB drive not recognized (blank or foreign media)`), + correctly simulating a genuine first boot. Deliberately flat/raw, not GPT-partitioned, + matching `homeblocks_sig_check()`'s current `sig_start_fblock=0` call site — both move to a + real GPT-partition-relative offset together once a parser exists, not attempted here. No + kernel code touched this step (host-side test tooling only), so no 3-arch acceptance boot + needed — single live amd64 QMP-hotplug confirmation is the right verification tier. + + **Still open, not attempted:** the mint-then-pin boot-sequence fix itself, the `MINT` word, + and the Zuse recovery path. ### From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding diff --git a/disk/README.md b/disk/README.md index 2b43943..5020db7 100644 --- a/disk/README.md +++ b/disk/README.md @@ -83,6 +83,21 @@ carrying timestamp noise in git history. `BLK-CONFIRM-FORMAT`-committed in the repo copy — commit that step live if reusing this fixture for further reloc-table testing. +- `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). 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 diff --git a/disk/zuse.img b/disk/zuse.img new file mode 100644 index 0000000..51c513d Binary files /dev/null and b/disk/zuse.img differ diff --git a/scripts/README.md b/scripts/README.md index 9ea3d6e..5a99f14 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -24,6 +24,12 @@ Utility scripts for building, profiling, DoE experiments, and documentation. | `rundisk.sh` | Boot a disk image in QEMU | | `qemu_screenshot.sh` | Capture QEMU serial output | +## Phase 8 / identity testing scripts + +| Script | Purpose | +|--------|---------| +| `bleach_zuse_img.sh` | Reset `disk/zuse.img` back to pristine/unminted (blank) state, for repeatable first-boot mint-flow testing | + ## FORTH capsule scripts | Script | Purpose | diff --git a/scripts/bleach_zuse_img.sh b/scripts/bleach_zuse_img.sh new file mode 100755 index 0000000..4239b69 --- /dev/null +++ b/scripts/bleach_zuse_img.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# bleach_zuse_img.sh - Reset disk/zuse.img back to pristine/unminted state. +# +# disk/zuse.img simulates the physical Zuse superuser thumbdrive for QEMU +# testing (FABRIC-3.md, Phase 8 kickoff). "Bleaching" it means restoring the +# all-zero blank state homeblocks_sig_check() reads as HOMEBLOCKS_SIG_BLANK +# -- i.e. simulating a genuine first boot, so the one-time mint-Zuse flow can +# be exercised repeatedly during development without hand-regenerating the +# whole image each time. +# +# Deliberately a flat/raw image, not GPT-partitioned, matching the same +# simplifying assumption homeblocks_sig_check()'s current call site in +# repl.c uses (sig_start_fblock=0) -- both will need to move to a real +# GPT-partition-relative offset together, once a GPT parser exists. Not +# invented ahead of that work here. +# +# Usage: scripts/bleach_zuse_img.sh [path] +# path Optional override; defaults to disk/zuse.img relative to repo root. + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +IMG="${1:-$REPO_ROOT/disk/zuse.img}" +SIZE_MB=64 + +if [ -e "$IMG" ] && [ ! -f "$IMG" ]; then + echo "bleach_zuse_img: refusing to overwrite non-regular-file '$IMG'" >&2 + exit 1 +fi + +dd if=/dev/zero of="$IMG" bs=1M count="$SIZE_MB" status=none +echo "bleach_zuse_img: $IMG reset to ${SIZE_MB}MB blank (pristine/unminted)"