FABRIC-3.md: close WRITE(10) as built+verified, record the EMPTY-BUFFERS bug find

WRITE(10) moves from "scoped" (§F.1) to "built and verified" (§F.17) -- the graph's original highest-leverage node and single remaining hard blocker is gone. Updates the §E graph (W10 to done, its outgoing edges from "blocks" to "unblocked"), the M2 punch-list checkbox, and the "what the graph makes visible" summary.

Also records a new standalone bug node (EMPTYBUFBUG, matching PROMPTBUG's precedent) for the EMPTY-BUFFERS mass-zero bug found and reported (not fixed) during WRITE(10) validation -- so it isn't lost track of now that the immediate incident (corrupted then restored disk/artemis.img) is resolved.
This commit is contained in:
Robert Allan James
2026-08-28 07:21:02 -04:00
parent 5e9802845a
commit c678211d4f
+60 -11
View File
@@ -115,10 +115,11 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
goal — *"keeps xhci.c decoupled from block_subsystem.c"* — and that decoupling is real,
live on all three arches. Closed as written; no further design work on this node itself.
- [ ] Implement CBW/data/CSW for SCSI WRITE(10) — this is where the earlier "read/write,
unquestionable" requirement actually gets satisfied. Still the single biggest functional
gap in the xHCI driver — blocks writing to a real USB thumb drive at all (`blkio_usb.c` is
read-only today specifically because of this).
- [x] **BUILT + VERIFIED 2026-08-28 (`FABRIC-3.md` §F.17).** CBW/data/CSW for SCSI WRITE(10),
a direct mirror of READ(10) with the data direction flipped. Verified live via a genuine
cold-reboot round-trip on all three architectures (amd64/aarch64/riscv64), not just a
same-session read. `blkio_usb.c` is read-write now; `read_only` flipped to `0`. Real hardware
(Milestone 8) remains untested — QEMU-only so far.
- [ ] Implement basic error/stall recovery (CSW failure status, endpoint stall clear) — at
minimum enough to not wedge the controller on a single bad transfer. **SCOPED 2026-08-27
@@ -1459,7 +1460,7 @@ punch list hides that; a graph doesn't.
```mermaid
graph TD
W10[" WRITE(10) SCSI support<br/>(Milestone 2 — biggest single blocker)"]
W10[" WRITE(10) SCSI support<br/>BUILT + VERIFIED 2026-08-28 (§F.17), all 3 arches"]
HOTPLUG["✅ Hotplug event surfacing<br/>CLOSED 2026-08-27, M2 (§F.3)"]
STALL["❌ USB error/stall recovery (M2)<br/>SCOPED 2026-08-27 (§F.14) — full BOT-spec recovery designed"]
@@ -1490,11 +1491,12 @@ graph TD
ROUNDTRIP["✅ Session state round-trip<br/>across attaches — CLOSED 2026-08-27 (§F.16)"]
POLYBLOCK["✅ Polymorphic block-boundary<br/>behavior — CLOSED 2026-08-27 (§F.16), already true"]
PROMPTBUG["🐛 (Zuse)ok> prompt typo<br/>CLOSED 2026-08-27 (§F.16) — doc-comment only, not live code"]
EMPTYBUFBUG["🐛 EMPTY-BUFFERS mass-zeros every<br/>block on every device (§F.17) — found 2026-08-28, NOT FIXED"]
W10 -->|blocks| BMAPWRITE
W10 -->|blocks| MINT
W10 -->|blocks| DETACH
W10 -.->|blocks real-hardware testing of everything below| M8["Milestone 8 — bare metal"]
W10 -->|unblocked, §F.17| BMAPWRITE
W10 -->|unblocked, §F.17| MINT
W10 -->|unblocked, §F.17| DETACH
W10 -.->|QEMU-verified; real hardware still untested| M8["Milestone 8 — bare metal"]
M6 -->|unblocks| CERTVERIFY
PH8 -->|supplies crypto primitives| CERTVERIFY
@@ -1528,8 +1530,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,BMAPREAD,SSDSCOPE,ROUNDTRIP,POLYBLOCK done
class W10,STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN,MSGMIGRATE,ACLKEY blocked
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE,BMAPREAD,SSDSCOPE,ROUNDTRIP,POLYBLOCK,W10 done
class STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN,MSGMIGRATE,ACLKEY blocked
class MIGSM partial
```
@@ -1607,6 +1609,12 @@ finished). Dashed arrows = softer "gates/informs" relationships.
substantial vision expansion (§D.6): blank-media minting is meant to be an interactive,
Console-driven onboarding form, connecting forward into both `RUNCAP`'s deferred
"default personality content" question and `MINT`'s own scope.
- **`WRITE(10)` (§F.17), the graph's original highest-leverage node, is built and verified —
the whole arc's single hard blocker is gone.** `BMAPWRITE`, `MINT`, and `DETACH`/`EJECT` all
move from "scoped, blocked" to "scoped, genuinely buildable." Validating it surfaced a real,
separate, serious bug (`EMPTYBUFBUG`) — a stark reminder that this pile still has more
surprises in it than the scoping pass alone can find; the "full codebase audit pass" already
flagged as deferred (§D.5) has real work waiting for it.
**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
@@ -2448,3 +2456,44 @@ mediated rather than a direct Hera-side check; how this reconciles with `PENTAGO
Hera↔Console edge, not the other nine.
### F.17 — `WRITE(10)` implemented and verified (2026-08-28) — the graph's last hard blocker, closed
Implemented exactly as scoped in `F.1`, a direct mirror of the existing `READ(10)` machinery
with the data direction flipped: new `XHCI_XFER_BOT_DATA_OUT`/`XHCI_NEXT_ACTION_BOT_DATA_OUT`
states, `xhci_bot_send_write10()`/`xhci_bot_write_block()`/`xhci_bot_write_data_out()`
(`xhci.c`), new `SCSI_CMD_WRITE10` opcode and `BOT_CMD_WRITE10`/`BOT_TUR_CHAIN_WRITE10` enum
values (`xhci_driver.h`, kept as fully separate fields from the `bot_read10_*` ones rather than
renamed/reused, so the already-tested `READ10` path is never touched). `usb_blk_write()`
(`blkio_usb.c`) is real now, no longer the `BLKIO_ENOSUP` stub — `read_only` in `blkio_info()`
flips to `0`, per `F.1` decision 1, now that it's proven.
**Verified live, all three architectures, with a genuine cold-reboot round-trip** — not just a
same-session read, the real proof this class of change needs: `BLK-CONFIRM-FORMAT`'s BAM/reloc
zero-page writes and an explicit block-content write both completed via clean `WRITE10` cycles
(CSW PASS every time), then a full kernel rebuild + fresh boot read the written byte back
correctly — `amd64=65`, `aarch64=170`, `riscv64=201`, each at LBN 32734 on a disposable
`disk/usbwrite-test.img` attached via QEMU `usb-storage`, matching `F.1` decision 2's validation
plan exactly.
**One real methodology finding, not project-specific:** the disposable test drive must be
hotplugged via QMP *after* boot reaches `ok>`, never attached at QEMU launch — attaching before
`xhci_bringup()`'s controller reset means the port already reads as connected when the driver
starts, so no fresh Port Status Change event ever fires and hotplug detection looks broken even
though it isn't (already documented in `project_xhci_milestone_2d_polling`, re-confirmed here
the hard way on the first attempt).
**A real, serious, pre-existing bug found and reported (not fixed) during validation:**
`EMPTY-BUFFERS` (`empty_all_buffers()`, `block_words.c:148-158`) does not implement standard
Forth-79 semantics — it force-writes zero to *every* block on *every* attached device, rather
than discarding cache-slot assignments without writing. Calling it during testing (reasonably
assuming standard semantics) mass-zeroed blocks across the whole system, including
`disk/artemis.img` — ~3.3 million bytes, essentially its entire content region. Restored from
git, confirmed byte-identical to `HEAD`. Avoided for the rest of validation (detach/reattach via
QMP used instead to force a fresh device read, which is non-destructive).
**Consequence for the rest of the graph:** `W10` was the single hub gating `BMAPWRITE`
(already independently confirmed working, §F.12), `MINT`, and `DETACH`/`EJECT`'s flush step —
all three are now genuinely unblocked, not just scoped. Nothing about their own design changes;
they can now actually be built and tested rather than only designed. Real hardware (Milestone
8) remains untested — this verification is QEMU-only, per `F.1`'s own acknowledged scope.