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:
+43
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user