From 3f74ff0f786ce9d89dac62ad498d3f627b776b4a Mon Sep 17 00:00:00 2001 From: Robert Allan James Date: Fri, 28 Aug 2026 18:29:26 -0400 Subject: [PATCH] =?UTF-8?q?FABRIC-3.md:=20close=20BINDSTEP=20+=20fence-per?= =?UTF-8?q?sistence,=20identity=20arc=20done=20(=C2=A7F.24)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD --- FABRIC-3.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/FABRIC-3.md b/FABRIC-3.md index 3a93d6e..4f2af80 100644 --- a/FABRIC-3.md +++ b/FABRIC-3.md @@ -3002,3 +3002,61 @@ re-attach check that closes this whole identity arc is the one piece left. The f persistence gap (§F.21) still means Zuse can't re-authenticate across a real reboot in this QEMU environment — worked around for this verification the same way, via a fresh genesis mint within the same boot session, not fixed here. + +### F.24 — `BINDSTEP` + the fence-persistence root cause: identity arc closed + +Two items, closed together, both directly instructed: the fence-marker persistence gap +(§F.21/§F.23's own "still open") and `BINDSTEP` (§F.9's own decisions, never wired to a real +call site). Neither turned out to need new design — both were assembly and one real bug hunt. + +**Fence-persistence root cause, traced rather than reformatted blind:** `meta_fence_blocks` +(the field `blk_meta_zone_write()`'s own bounds check gates on) was carved out of what used to +be unused padding in `blk_volume_meta_t` — the code's own comment already documented this +exact risk. `disk/artemis.img` was formatted before that field existed, so the on-disk bytes +at that offset have always read back as `0`, and `blk_format_or_load_disk()`'s existing-volume +path (`magic`/`version` match) never recomputes it — only a *fresh* format does. Every "fence +write FAILED" message this entire session, the old `zuse_cert_devblock_t` flow and the new +`zuse_genesis_marker_t` alike, traces to this one thing, not a timing bug or a QEMU quirk. +**Why an in-place patch was refused even though it's tempting:** setting `meta_fence_blocks` +alone without redoing the rest of the geometry risks the fence region overlapping data already +allocated near the top of the volume under the *old*, un-fenced layout — a real, if low- +probability, corruption risk for a one-field edit that looks harmless. The only provably safe +fix is a genuine reformat, confirmed explicitly before doing it (discards 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 cycle — mint once, reboot, +reattach, re-authenticate — works for the first time this whole session: `"Zuse: identity +confirmed from attached thumbdrive"`, `ZUSE-SESSION?` goes `0` → `-1` with **no re-minting**. + +**`BINDSTEP`:** `capsule_wirebind_verify_cert()` extracted out of `capsule_wirebind_try_attach()` +into 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 — one code path, not two +that could quietly drift apart. `mama_word_use()` (`USE`) now re-verifies live, not cached +(§F.9 decision 1), whenever the target 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 bare console VM) stays freely targetable — unchanged, per §F.9 +decision 2. + +**Two related bugs found and fixed live while testing `BINDSTEP`, not assumed away:** `USE` +was Mama-only — 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 a plain `UNKNOWN WORD`. Corrected directly: +`USE` isn't console-specific, it should work VM-to-VM universally, the same way `VM-EXEC` +already does — now registered in `register_child_vm_words()` too. That alone wasn't +sufficient: the console relay (`sk_repl_dispatch_line()`, §F.22) 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; it +now always runs directly, never relayed. + +**Verified live, the full matrix, not just the happy path:** `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 — exact text: `"USE: +FinT~user refused -- no matching identity currently attached"`. Clean 3-architecture +regression, including confirming the reformatted `disk/artemis.img` 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. Commit `09d78c9`. + +**The whole identity/messaging arc opened at §F.20 is closed, end to end, for the first time:** +`CERTVERIFY` → `RUNCAP` → `MINT` → the console/user pair → `WIREBIND` → `BINDSTEP` → +persistence across a real reboot. Every phase closure from §F.18 onward flagged the next gap; +none remain flagged as "still open" in this chain.