| … | … | @@ -3940,6 +3940,42 @@ injected per layer: |
| 3940 | 3940 | - **One equivalent:** open's thenable hop. Nothing else can share open's own completion |
| 3941 | 3941 | checkpoint; close's hop IS rulered, as the last completion before `ready()`. |
| 3942 | 3942 | - ctest 87/87. |
| 3943 | - **R4c-3b replanned (2026-10-06): the store and the migrations are ONE unit.** The migrations call |
| 3944 | the store's internals (`storage._getHead(view)`, `storage.db`, `core.read()`, `core.write()`, |
| 3945 | `core.createBlockStream()`), and the store runs `migrations/0.store()` on every fresh store. So |
| 3946 | R4c-3b and R4c-3c merge, in this order: |
| 3947 | - **R4c-3b-1:** bare-fs's slice for the migrations. |
| 3948 | - **R4c-3b-2:** the hypercore-10 oplog codecs (messages.js `oplog.header` / `oplog.entry` and their |
| 3949 | dependencies), checked against vectors decoded by JS from oplogs that hypercore 10.38.2 wrote. |
| 3950 | - **R4c-3b-3:** CorestoreStorage + HypercoreStorage + migrations/0 and /1, gated by the async |
| 3951 | `l2_ops` gate on fresh stores and on the hypercore-10 fixtures. |
| 3952 | - **Upstream bugs ported as they are:** |
| 3953 | - `readAll`'s retry passes its `fs.read` arguments in the wrong order (only reached on a |
| 3954 | partial read); |
| 3955 | - `allBits` slices `EMPTY_NODE` (40) bytes, so the empty-page skip never fires while the 4096-byte |
| 3956 | view still reads the page; |
| 3957 | - `store()`'s `head.allocated.cores++` throws a TypeError on any legacy core (measured). |
| 3958 | - **R4c-3b-1 DONE 2026-10-06** (keetd 722a554): bare-fs's slice for the migrations. |
| 3959 | - **readFile:** the fstat size; 8 KiB reads when the size is 0; close in `finally`. |
| 3960 | - **opendir / Dir / readdir:** `uv_fs_readdir` 32 entries at a time, read / close, and Dir's async |
| 3961 | generator, iterated by `for await`. |
| 3962 | - **rm:** lstat; recursive through ENOTEMPTY → readdir → rm each → rmdir; `force` on ENOENT. |
| 3963 | - **rmdir, lstat.** |
| 3964 | - **FileReadStream:** bare-stream 2.13.1's Readable shim over the streamx port. `eagerOpen`; |
| 3965 | `_read(cb)` calls the Node-style `_read(65536)` un-awaited, then `cb(null)`; `_destroy` is |
| 3966 | `(getStreamError, cb)`. |
| 3967 | - **streamx `eagerOpen`,** in the Readable / Writable constructors, as streamx has it. |
| 3968 | - **Gate `tools/df` +2 scripts:** |
| 3969 | - `fsOps`: empty, small and over-8 KiB files; missing paths; recursive / forced rm. |
| 3970 | - `readStreams`: `for await`, and `read()` on `'readable'`, over 150 000 bytes, so 64 KiB |
| 3971 | chunks. Includes a stream consumed only after other fs work: BlockSlicer's shape, which makes |
| 3972 | `eagerOpen` observable. |
| 3973 | - Every fs completion is rulered. |
| 3974 | - 13 scripts / 25 runs identical. The traces mask each run's own directory as `<dir>` in error |
| 3975 | messages. |
| 3976 | - **Drill r4c3a +6: 18/19 red, 1 equivalent.** The `eagerOpen` survivor was a script gap, fixed |
| 3977 | by the late-consumption script. |
| 3978 | - ctest 87/87. |
| 3943 | 3979 | - **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack |
| 3944 | 3980 | is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful. |
| 3945 | 3981 | |