From 6a3eb5997fad5391e5d59b3b3f07323c40c46966 Mon Sep 17 00:00:00 2001 From: Robert Allan James Date: Thu, 27 Aug 2026 14:49:52 -0400 Subject: [PATCH] FABRIC-3.md: close BMAPREAD as already-built, fix a real devblock-0 header collision Confirmed the F.12 handoff: cache_load_devblock() already unpacks/validates metadata on load, same "already built" story as BMAPWRITE. But tracing "validate on insertion" surfaced a real, load-bearing conflict unrelated to blk_meta_t: blk_subsys_attach_device() always runs the generic block-subsystem's own STFR/v2 header check at devblock 0, which would always read a home-blocks drive's 'LAHB' magic as "unrecognized" and leave it permanently write-refused (BLK_FMT_PROVISIONAL) -- or, if force-formatted via blk_subsys_confirm_format(), overwrite homeblocks_sig_t outright, since both want the same devblock 0. This was invisible to CERTVERIFY/WIREBIND/RUNCAP/MINT because none of them traced the generic attach path alongside homeblocks_sig_check(). Fixed: homeblocks_sig_t relocates to devblock 1 (a call-site change only, sig_start_fblock was already a plain parameter); MINT must also run the ordinary format-confirm path at devblock 0 so the drive is writable through the normal block-buffer path. --- FABRIC-3.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/FABRIC-3.md b/FABRIC-3.md index e1079b4..a26f129 100644 --- a/FABRIC-3.md +++ b/FABRIC-3.md @@ -159,7 +159,13 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR gets written to the device, real and unstubbed. Blocked only on `WRITE(10)` itself, already modeled in the graph — nothing else stands between this and working. -- [ ] Implement reading/validating the block-map from a drive on insertion. +- [x] **CLOSED 2026-08-27 (`FABRIC-3.md` §F.13) — already built, not a separate item.** + `cache_load_devblock()` already unpacks and validates every devblock's metadata on load. + Tracing "on insertion" surfaced a real, separate, previously-unflagged conflict instead: + `homeblocks_sig_t` and the block-subsystem's own generic `'STFR'`/v2 header both wanted + devblock 0, which would leave a home-blocks drive permanently write-refused or overwrite its + own identity header. Fixed by relocating `homeblocks_sig_t` to devblock 1; `MINT` must also + run the ordinary format-confirm path at devblock 0. - [ ] Design the migration state machine (Section U item 5) — states, transition triggers. Session direction, 2026-08-25: **ACL manages *when* to relocate** (capacity pressure, or a @@ -1438,7 +1444,7 @@ graph TD FIRSTTOUCH["❌ First-touch identity→block-range
allocation (M3) — SCOPED 2026-08-27 (§F.11)"] BMAPFMT["❌ On-drive block-map format (M3)
SCOPED 2026-08-27 (§F.4) — repurpose blk_meta_t"] BMAPWRITE["✅ Write block-map to drive (M3)
CLOSED 2026-08-27 (§F.12) — already built, blocked only on W10"] - BMAPREAD["❌ Read/validate block-map on insert (M3)"] + BMAPREAD["✅ Read/validate block-map on insert (M3)
CLOSED 2026-08-27 (§F.13) — already built"] MIGSM["🟡 Migration state machine (M3)
partially answered: ACL decides *when*"] UNCLEAN["❌ Unclean-removal handling (M3)
DESIGN CLOSED 2026-08-27 (§F.10), code not yet written"] @@ -1471,6 +1477,7 @@ graph TD BMAPFMT --> BMAPWRITE BMAPFMT --> BMAPREAD BMAPFMT --> FIRSTTOUCH + BMAPREAD -.->|found: sig must relocate off devblock 0, §F.13| MINT CERTVERIFY --> RUNCAP RUNCAP --> MINT @@ -1495,8 +1502,8 @@ graph TD classDef unblocked fill:#a83,stroke:#333,color:#fff classDef open fill:#666,stroke:#333,color:#fff classDef partial fill:#883,stroke:#333,color:#fff - class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE done - class W10,STALL,FIRSTTOUCH,BMAPREAD,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN blocked + class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE,BMAPREAD done + class W10,STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN blocked class ACLKEY,MSGMIGRATE,SSDSCOPE,ROUNDTRIP,POLYBLOCK open class MIGSM partial ``` @@ -1559,6 +1566,13 @@ finished). Dashed arrows = softer "gates/informs" relationships. `blk_meta_t` accessors instead of a new table meant "write the map" and "write a block" were never actually two operations. The only reason this hasn't been seen working is `WRITE(10)` itself, already the graph's known hub. +- **`BMAPREAD` closed the same way, but tracing it surfaced a real, load-bearing bug that had + nothing to do with reading at all** (§F.13) — `homeblocks_sig_t` and the block-subsystem's + own generic disk header physically collide at devblock 0. Every earlier node that touched + `homeblocks_sig_t` (`CERTVERIFY`, `WIREBIND`, `RUNCAP`, `MINT`) inherited this without anyone + noticing, because each only traced `homeblocks_sig_check()` itself, never the ordinary attach + path running alongside it. Fixed now (relocate to devblock 1) rather than left to surface + later as a real, confusing runtime failure. **Not yet done:** an ordered plan (which node to attack first, given the graph). Per Captain Bob's own framing, that's the next pass — "start asking and answering questions iteratively @@ -1870,6 +1884,10 @@ resolved before any design decision was needed: cert + identity-source regions; everything past that is the user's own general block-storage pool directly, consistent with `FIRSTTOUCH`'s pool clarification in §F.6). No GPT-parser node needed in the graph at all — this closes that thread rather than deferring it. + **Correction, 2026-08-27 (§F.13): `homeblocks_sig_t` itself moved off devblock 0** to + devblock 1 (forth-block 4) once a real collision with the block-subsystem's own generic + disk header was found — the "devblocks `0..N`" metadata-region framing above still holds, + it just now starts one devblock later than stated here. 2. **Single-device USB driver.** `xhci_dev_t`'s BOT/MSC state (`device_ctx`, `bulk_in_ring`, `bulk_out_ring`, `bot_data_buf`) are singular fields, not per-slot arrays — only one USB MSC device is usable at a time today. This looked like it might conflict with the vision's @@ -2097,6 +2115,44 @@ node may have its own distinct question (e.g. whether a home-blocks drive needs validate-on-insert step beyond ordinary lazy per-devblock read-through-cache), left for its own pass rather than assumed away. +### F.13 — `BMAPREAD` (closed — already built) — and a real header collision found and fixed + +Confirmed the handoff note from `F.12`: `cache_load_devblock()` (`block_subsystem.c:308-322`) +already unpacks and validates every devblock's metadata on load (`meta_from_slice()`, +magic-checked, resets cleanly on a bad/missing magic) — the read side is exactly as "already +built, not a separate item" as the write side. Same closure, no new mechanism needed. + +**But tracing "validate on insertion" turned up a real, previously-unflagged conflict that has +nothing to do with `blk_meta_t` at all.** `blk_subsys_attach_device()` — the *general* attach +path every device goes through, USB drives included — always calls `blk_format_or_load_disk()` +(`block_subsystem.c:581-613`), which reads devblock 0 looking for the block-subsystem's own +`'STFR'`/v2 volume header. `homeblocks_sig_t`'s magic is `'LAHB'`, not `'STFR'`, so a minted +home-blocks drive always reads as "unrecognized" here and lands in `BLK_FMT_PROVISIONAL` — +and `blk_get_buffer()` (`block_subsystem.c:894`) **refuses all writes** to a `PROVISIONAL` +slot until `blk_subsys_confirm_format()` is called. That function +(`blk_commit_format()`, `block_subsystem.c:546-571`) writes a fresh STFR header to the *same* +devblock 0 — which would physically overwrite `homeblocks_sig_t`. Neither outcome (stay +`PROVISIONAL` forever, or get STFR-formatted and lose the identity header) works. This was +invisible to `CERTVERIFY`/`WIREBIND`/`MINT` because each only ever traced +`homeblocks_sig_check()` itself, never the generic attach path running alongside it. + +**Decision made 2026-08-27:** `homeblocks_sig_t` relocates to **devblock 1** (forth-block 4), +leaving devblock 0 for the generic STFR/v2 header untouched — no changes to the already-tested +block-subsystem code. `homeblocks_sig_check()` already takes its starting forth-block as a +plain parameter (`sig_start_fblock`, not hardcoded), so this is a call-site change, not a +format-logic change. `MINT` (§F.8) must also run the ordinary `blk_subsys_confirm_format()` +path at mint time (writing a ordinary fresh STFR/v2 header at devblock 0) so the drive is +immediately writable through the normal block-buffer path, in addition to writing +`homeblocks_sig_t`/cert/identity-source starting at devblock 1. `F.8`'s own text has been +corrected in place to point here rather than restate this. + +**Not yet scoped (deferred within this node):** whether `MINT`'s STFR-format-then-sig-write +sequence needs a specific ordering/atomicity guarantee (e.g. what state a drive is left in if +power is lost between the two writes) — real question, not addressed here; the exact +`sig_start_fblock` value call sites (`CERTVERIFY`, `WIREBIND`, `RUNCAP`, `MINT`) all need +updating from their currently-recorded devblock-0-relative assumption to devblock-1, a +mechanical follow-up once any of this is actually coded, not re-litigated here. + ### D.5 — Scope expansion (2026-08-27): identity is common to every VM, not just users Surfaced while scoping `ACLKEY`, stated directly: *"the whole object is to deliver a