diff --git a/FABRIC-3.md b/FABRIC-3.md
index 09df0a0..69e46b3 100644
--- a/FABRIC-3.md
+++ b/FABRIC-3.md
@@ -1370,3 +1370,116 @@ materializing.
**Next step:** no implementation yet — this section is capture only, per direct request. Next
session should turn D.3/D.4 into an actual scoped, ordered plan (the user's own framing:
"identify gaps, answer what we can, defer what we can't... push the pile out in front of us").
+
+---
+
+## E. The pile as a graph (2026-08-27)
+
+Stated directly: "if this is all documented, scoped and correctly interwoven we can begin
+iterating... I see no reason to not create this as a graph, it might better handle the way I
+think." Auditing D.1-D.4/D.2b against the older Milestone 2/3/5 punch lists (§X in this
+document) confirms the instinct is right, not just stylistic — several items across
+*different* milestones are, on inspection, **literally the same open question**, and one
+single blocker (`WRITE(10)`) gates work in at least four unrelated-looking places. A flat
+punch list hides that; a graph doesn't.
+
+```mermaid
+graph TD
+ W10["❌ WRITE(10) SCSI support
(Milestone 2 — biggest single blocker)"]
+ HOTPLUG["🟡 Hotplug event surfacing
partially addressed, M2"]
+ STALL["❌ USB error/stall recovery (M2)"]
+
+ M6["✅ Milestone 6 — capsule PKI
DONE 2026-08-26"]
+ PH8["✅ Phase 8 — Zuse identity
+ block-fence, DONE 2026-08-26"]
+
+ CERTVERIFY["🔓 CA-signed-cert verification path (M3)
UNBLOCKED by M6, not yet built"]
+ FIRSTTOUCH["❌ First-touch identity→block-range
allocation (M3)"]
+ BMAPFMT["❓ On-drive block-map format (M3)
real design decision, not started"]
+ BMAPWRITE["❌ Write block-map to drive (M3)"]
+ BMAPREAD["❌ Read/validate block-map on insert (M3)"]
+ MIGSM["🟡 Migration state machine (M3)
partially answered: ACL decides *when*"]
+ UNCLEAN["❌ Unclean-removal handling (M3)"]
+
+ ACLKEY["❓ ACL 'bumps and holes' comparison
semantics — SAME GAP in M5 and D.4"]
+ WIREBIND["❌ Wire hotplug → capsule_birth_baby() (M5)"]
+ BINDSTEP["❌ Extend sk_repl_set_active_vm()
with key-match (M5)"]
+ DETACH["❌ Detach behavior (M5)"]
+
+ EXPIRE["✅ EXPIRE reframed: session end
= VM detach via COOL (§B + D.2)"]
+ RUNCAP["❓ Runtime capsule construction
from thumbdrive content (D.4) — new mechanism"]
+ MINT["❌ Ongoing MINT word (Phase 8 + D.3)"]
+ PENTAGON["📍 Pentagon: Hera/Hermes/Artemis/
User-VM/Console, K5 (D.2b)"]
+ MSGSHAPE["✅ Hermes message shape known
(MSG-CELLS, MSG-ALLOC/DELIVER)"]
+ MSGMIGRATE["❓ Message-bus migration of
attach/verify/bind (D.4)"]
+
+ SSDSCOPE["❓ SSD identity-store scope
for regular users (D.4)"]
+ ROUNDTRIP["❓ Session state round-trip
across attaches (D.4)"]
+ POLYBLOCK["❓ Polymorphic block-boundary
behavior (D.1, since 2026-08-25)"]
+ PROMPTBUG["🐛 (Zuse)ok> prompt typo
trivial, independent"]
+
+ W10 -->|blocks| BMAPWRITE
+ W10 -->|blocks| MINT
+ W10 -->|blocks| DETACH
+ W10 -.->|blocks real-hardware testing of everything below| M8["Milestone 8 — bare metal"]
+
+ M6 -->|unblocks| CERTVERIFY
+ PH8 -->|supplies crypto primitives| CERTVERIFY
+ PH8 -->|supplies mint-then-pin precedent| MINT
+
+ BMAPFMT --> BMAPWRITE
+ BMAPFMT --> BMAPREAD
+ BMAPFMT --> FIRSTTOUCH
+
+ CERTVERIFY --> RUNCAP
+ RUNCAP --> MINT
+
+ HOTPLUG --> WIREBIND
+ ACLKEY --> BINDSTEP
+ WIREBIND --> BINDSTEP
+ BINDSTEP --> DETACH
+ DETACH -->|triggers| EXPIRE
+
+ MSGSHAPE --> MSGMIGRATE
+ WIREBIND -.->|hardwired version must exist first| MSGMIGRATE
+ BINDSTEP -.->|hardwired version must exist first| MSGMIGRATE
+ CERTVERIFY -.->|hardwired version must exist first| MSGMIGRATE
+ PENTAGON -->|which of the 10 edges get messaged| MSGMIGRATE
+
+ classDef done fill:#1a3,stroke:#333,color:#fff
+ classDef blocked fill:#a33,stroke:#333,color:#fff
+ 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 done
+ class W10,STALL,FIRSTTOUCH,BMAPWRITE,BMAPREAD,UNCLEAN,WIREBIND,BINDSTEP,DETACH,MINT blocked
+ class CERTVERIFY unblocked
+ class BMAPFMT,ACLKEY,RUNCAP,MSGMIGRATE,SSDSCOPE,ROUNDTRIP,POLYBLOCK open
+ class HOTPLUG,MIGSM partial
+```
+
+**Legend:** ✅ done · 🔓 unblocked-but-not-built · ❌ not started, no open design question left
+(just needs building) · ❓ real open design question, not just missing implementation ·
+🟡 partially addressed · 📍 topology/context node, not a work item itself · 🐛 trivial,
+independent bug. Solid arrows = hard dependency (A must exist before B can be built or
+finished). Dashed arrows = softer "gates/informs" relationships.
+
+**What the graph makes visible that the flat lists didn't:**
+- **`WRITE(10)` is a true hub**, not just "the M2 punch list's biggest item" — it independently
+ gates the block-map write path, `MINT`, detach/flush-back, *and* all real-hardware testing.
+ Landing it once unblocks four separate-looking fronts at once.
+- **`ACLKEY` (the exact ACL comparison semantics) is one node, not two** — Milestone 5's "key
+ and lock data shape" and D.4's "bumps and holes" gap are the literal same open question,
+ asked in two different sessions/documents. Answering it once closes both.
+- **`RUNCAP` (runtime capsule construction) sits on the critical path to `MINT`** — a gap that
+ read as "D.4 leftover detail" is actually load-bearing for the ongoing-minting flow, not a
+ side note.
+- **`MSGMIGRATE` has three separate hardwired prerequisites**, all currently unbuilt — the
+ message-bus migration can't even start until `WIREBIND`/`BINDSTEP`/`CERTVERIFY` exist to
+ migrate *from*, confirming this is correctly the last thing to tackle in this whole area, not
+ a parallel track.
+- **Only `SSDSCOPE`, `ROUNDTRIP`, `POLYBLOCK`, and `PROMPTBUG` are genuinely standalone** —
+ everything else in the pile connects to at least one other node.
+
+**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
+until we've planned as much as possible."