| … | … | @@ -4159,6 +4159,38 @@ injected per layer: |
| 4159 | 4159 | re-checks sr:H6 / H10 / H12, `_resolveBlocksLocally` sr:H16), R4g (corestore: async |
| 4160 | 4160 | ready / close / get with `preload`, the GC close race sr:H1-H4, H13) and R4h (bee / blobs' |
| 4161 | 4161 | synchronous-completion assumptions sr:H14) follow, each moving the frontier up. |
| 4162 | - **R4c-4a DONE 2026-10-07** (keetd 8937d35, 602fdc9). |
| 4163 | - **Step 1 (8937d35):** lib/keys.js and the shared types (`Change`, `Dependency`, `CorePtr`, |
| 4164 | `TreeCacheStats`, the `hs` alias) moved to `storage/include/hc/storage_keys.h` + `hc_storage_keys`; |
| 4165 | `hc_storage` no longer links `hc_l2`, which aliases them until R4c-4e. The keys' throws became |
| 4166 | `JsError("Error", …)`: each is a plain Error in JS (index-encoder 3.5.0, compact-encoding 3.5.0's |
| 4167 | `outsideUintRange` / fixed's `Out of bounds`, keys.js:253). ctest 89/89. |
| 4168 | - **Step 2 (602fdc9): tools/st absorbs M4a, plus the store paths no gate reached.** |
| 4169 | - M4a's ten scenarios moved to `tools/st/m4a-scenarios.js`; `gen-storage-ops.js` writes them |
| 4170 | byte-identically (checked), `gen-st.js` replays them as `m4a_*` with a `waitAll` after every op (M4a's |
| 4171 | driver awaits each), `open` = new + ready, `close` = every live core in Map order, then the store. |
| 4172 | - st-gate.sh: RocksDB OPTIONS identical (version lines aside; 652 lines per run), M4a's cross-open |
| 4173 | (each side opens the other's `m4a_basic` store writable), the C++ trace capped at 8 GB of address space. |
| 4174 | - New scripts: `recover` (`_maybeRecover`: setRecovering at a pinned Date.now, RECOVERING unlinked), |
| 4175 | `openFail` / `alwaysRecover` (`_maybeRecoverLater` after a corrupt CURRENT), `onresume`, `closing` |
| 4176 | (streams / reads while a session, then the store, close), `closedSnapshot`. |
| 4177 | - `rt::Runtime::pinNow` (JS's `Date.now = fn`), beside `pinRandom`. |
| 4178 | - **Port bugs the new scripts found (fixed):** |
| 4179 | - a stream on a closed HypercoreStorage: JS throws `TypeError: Cannot read properties of null |
| 4180 | (reading 'iterator')` synchronously (close() nulls the view); keetd called a member through the null |
| 4181 | `ViewPtr`, which happened to reach `dbClosing` and return a CloseErrorStream (undefined behaviour); |
| 4182 | - `snapshot()`: JS evaluates `db.snapshot()` before `this.view.snapshot()`; C++ left the |
| 4183 | `make_shared` argument order unspecified. MEASURED: on a closed storage `db.snapshot()` throws |
| 4184 | `RocksDB session is closed` first. |
| 4185 | - Harness bug: the C++ driver read timestamps as `int` (`json::value`'s default type); every earlier st |
| 4186 | script had timestamp 0. |
| 4187 | - st gate 50/50 (24 scripts × real / virtual, cross, total). Drill r4c4a 11/11 red. First-run survivors |
| 4188 | were gate gaps (#107 lesson 5): `RECOVERING` and the `.log` files live in db/, which the listing skips |
| 4189 | → a `dbFiles` probe. One mutant (re-entrant atom flush) recursed to 21 GB RSS → the cap. ctest 89/89. |
| 4190 | - **Order changes (both from the frontier rule: core runs on l2 until R4c-4d):** the M4a gate, `l2_ops` |
| 4191 | and the l2 / m5g1a / m5g3a drill sets are deleted at R4c-4e, not here (they are l2's only direct gate |
| 4192 | while core still uses it); the M4d kill-point hook moves into rn at R4c-4d (the appender writes through |
| 4193 | core). |
| 4162 | 4194 | - **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack |
| 4163 | 4195 | is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful. |
| 4164 | 4196 | |