FABRIC-3.md: close BMAPWRITE as already-built, correct UNCLEAN's classDef inconsistency

Traced blk_set_meta()/cache_writeback()/blk_flush() before assuming a new write path was needed. BMAPWRITE is already done: BMAPFMT's decision to repurpose the existing blk_meta_t accessors instead of a new table means the flush path that already exists for ordinary block data already covers metadata identically -- real, unstubbed, all the way to dev->write(). The only blocker is WRITE(10) itself, already modeled in the graph. Handoff note for BMAPREAD's own pass: the read side looks like it closes the same way but wasn't confirmed here.

Also corrects a self-inconsistency from the previous commit: UNCLEAN was marked with a "done" checkmark even though its wiring code isn't written yet, unlike BMAPWRITE which really is working code today. Moved UNCLEAN back to the "scoped, not built" bucket alongside BMAPFMT/CERTVERIFY/etc.
This commit is contained in:
Robert Allan James
2026-08-27 14:44:53 -04:00
parent 9c0e583554
commit 198e82a029
+43 -5
View File
@@ -153,7 +153,11 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
its stale POSIX-flavored ownership fields with a pubkey-fingerprint owner + a fast-deny ACL
bit + deliberate reserved slack. Field design done; the actual code edit is not.
- [ ] Implement writing the block-map to a drive.
- [x] **CLOSED 2026-08-27 (`FABRIC-3.md` §F.12) — already built, not a separate item.**
`blk_set_meta()`'s dirty-tracking already flows through the exact same `cache_writeback()`/
`blk_flush()` path ordinary block data uses; the whole devblock (data + metadata) already
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.
@@ -1433,10 +1437,10 @@ graph TD
CERTVERIFY["❌ Zuse-signed user-cert verification (M3)<br/>SCOPED 2026-08-27 (§F.7) — X.509/DER, own trust root"]
FIRSTTOUCH["❌ First-touch identity→block-range<br/>allocation (M3) — SCOPED 2026-08-27 (§F.11)"]
BMAPFMT["❌ On-drive block-map format (M3)<br/>SCOPED 2026-08-27 (§F.4) — repurpose blk_meta_t"]
BMAPWRITE[" Write block-map to drive (M3)"]
BMAPWRITE[" Write block-map to drive (M3)<br/>CLOSED 2026-08-27 (§F.12) — already built, blocked only on W10"]
BMAPREAD["❌ Read/validate block-map on insert (M3)"]
MIGSM["🟡 Migration state machine (M3)<br/>partially answered: ACL decides *when*"]
UNCLEAN[" Unclean-removal handling (M3)<br/>CLOSED 2026-08-27 (§F.10) — same kill path as EJECT, minus flush"]
UNCLEAN[" Unclean-removal handling (M3)<br/>DESIGN CLOSED 2026-08-27 (§F.10), code not yet written"]
ACLKEY["❓ ACL 'bumps and holes' comparison<br/>semantics — SAME GAP in M5 and D.4"]
WIREBIND["❌ Wire hotplug → capsule_birth_baby() (M5)"]
@@ -1491,8 +1495,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,UNCLEAN done
class W10,STALL,FIRSTTOUCH,BMAPWRITE,BMAPREAD,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP blocked
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE done
class W10,STALL,FIRSTTOUCH,BMAPREAD,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN blocked
class ACLKEY,MSGMIGRATE,SSDSCOPE,ROUNDTRIP,POLYBLOCK open
class MIGSM partial
```
@@ -1551,6 +1555,10 @@ finished). Dashed arrows = softer "gates/informs" relationships.
mechanism against the current design. A second, unrelated discovery in the same pass —
`blk_meta_t`'s existing chain fields — turned what looked like a fragmentation problem into
a non-issue for free.
- **`BMAPWRITE` was already done** (§F.12) — `BMAPFMT`'s decision to repurpose the existing
`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.
**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
@@ -2059,6 +2067,36 @@ room (matching the pool-scope clarification in §F.6: the thumb is the default p
node is specifically the *overflow* case) — implied yes by that clarification, not explicitly
re-confirmed here.
### F.12 — `BMAPWRITE` (closed — already built, blocked only on `WRITE(10)`)
Traced `blk_set_meta()`/`cache_writeback()`/`blk_flush()` fully before assuming any new write
path was needed. **Finding: this node is already done.** `blk_set_meta()`
(`block_subsystem.c:1198-1210`) marks the same cache-buffer entry's `meta_dirty` flag that
ordinary block-data writes use; `cache_writeback()` (`block_subsystem.c:274-285`) — called from
both `blk_flush()`'s targeted and flush-all paths, the exact function `blk_vm_flush_all()` and
`SAVE-BUFFERS` already exercise — packs the in-memory `blk_meta_t[]` array back into the
devblock's metadata region (`meta_to_slice()`) and writes the *whole* 4 KiB devblock (data +
metadata together, since they share one physical buffer) via `write_devblock_4k()`, real and
unstubbed all the way down to `dev->write()`.
**Why this closes rather than just narrows:** the M3 item as originally written assumed a
*separate* block-map structure that would need its own bespoke write mechanism. `BMAPFMT`'s
decision (§F.4) to repurpose the already-existing, already-wired `blk_meta_t` accessors instead
of building a new table means "writing the map" and "writing a block" were never actually two
different operations — the infrastructure that already existed for ordinary block persistence
already covers metadata identically, with zero new code. The only reason this hasn't been
observed working end-to-end is the same hard blocker already modeled in the graph: `WRITE(10)`
doesn't exist yet, so `dev->write()` never actually reaches physical media for a USB-attached
drive today. Nothing else stands between this and working.
**Handoff note for `BMAPREAD`'s own future pass:** the read side (`cache_load_devblock()`,
`block_subsystem.c:308-322`) already unpacks and validates metadata (`meta_from_slice()`,
magic-checked, resets to a clean default on a bad/missing magic) on every devblock load — very
likely the same "already built, not a separate item" outcome, but not confirmed here; that
node may have its own distinct question (e.g. whether a home-blocks drive needs an explicit
validate-on-insert step beyond ordinary lazy per-devblock read-through-cache), left for its own
pass rather than assumed away.
### 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