OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon commits / b90eb42

CPP-PORT-DESIGN: R4c-3b-2 done (oplog codecs + readOplog)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b90eb4230d90f2d4cd0f94e8063aae228ce7dff0
by plankatron <fleeky@gmail.com> · 2026-10-06T22:49:52.000Z

Changed files (1) +22 -0

docs/CPP-PORT-DESIGN.md +22 -0
……@@ -3976,6 +3976,28 @@ injected per layer:
39763976 - **Drill r4c3a +6: 18/19 red, 1 equivalent.** The `eagerOpen` survivor was a script gap, fixed
39773977 by the late-consumption script.
39783978 - ctest 87/87.
3979- **R4c-3b-2 DONE 2026-10-06** (keetd d946866): migrations/0's oplog reading.
3980 - **Codecs:** messages.js's `oplog.header` / `oplog.entry` and every part they use. A version-0
3981 header (the oldest hypercore 10) gets its manifest synthesized, as JS does.
3982 - **Oplog functions:**
3983 - `decodeOplogHeader` uses a SIGNED `l >> 2`; `decodeOplogEntry` uses `>>>`.
3984 - `readOplog`: header slots at 0 and 4096; the header bit; entries from 8192; trailing partial
3985 entries dropped; the external header file.
3986 - **Measured on Bare:** for an oplog shorter than 4104 bytes, the slot-2 `uint32` decode throws
3987 outside readOplog's try, inside `fs.readFile`'s callback. bare-fs calls that callback inside its
3988 own `async readFile`, so the result is an UNHANDLED REJECTION, and readOplog never settles. It is
3989 ported as such. Real hypercore-10 oplogs are always ≥ 8192 bytes.
3990 - **Vectors:**
3991 - `vectors/gen/legacy-cores.js` (node, hypercore 10.38.2) writes flushed, unflushed, truncated,
3992 read-only and empty cores. The unflushed ones keep oplog entries.
3993 - `vectors/gen/r4c-oplog.js` runs JS's own readOplog over them, loaded from a copy of
3994 migrations/0/index.js with only an export line appended and absolute requires, plus 18
3995 hand-framed cases built with messages.js's encoders. v0 headers are framed by hand, since no
3996 encoder exists.
3997 - **Test `r4c_oplog`:** 23/23.
3998 - **Drill r4c3b2: 10/11 red, 1 equivalent.** The equivalent is an unsigned header-length shift:
3999 with bit 31 set, JS's negative length passes the bounds check and the decode throws (null),
4000 while the unsigned one fails the bounds check (null). The state is untouched either way.
39794001- **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack
39804002 is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful.
39814003