OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon commits / c99a845

CPP-PORT-DESIGN: R4c-4c done (async l3, every caller on it, sync readers deleted)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c99a8452f7ff592a903eea369cd9658b6d16749f
by plankatron <fleeky@gmail.com> · 2026-10-07T21:49:07.000Z

Changed files (1) +48 -0

docs/CPP-PORT-DESIGN.md +48 -0
……@@ -4219,6 +4219,54 @@ injected per layer:
42194219 the JS side of the core gate's hops mode (R4c-4d).
42204220 - **Not measured here:** `waitForRecovery` with a pending op — it waits on a replicator's recovery peers
42214221 (R4f's pipe scenarios).
4222- **R4c-4c DONE 2026-10-07** (keetd 8bb9b66, 767bd8d, 1f0ce8d, 1eea9ec, 41ee215, 9673499, bb707dd): l3 is
4223 async, ported line by line from merkle-tree.js, and every caller uses it.
4224 - **4c-1:** `wire::Node` IS `hs::CoreTreeNode` (JS has one node object for storage and the wire), so a
4225 storage read's promise is l3's promise with no conversion hop. hc_l3 links the schema library.
4226 - **4c-2: the async API** (`hc/merkle.h`, `l3/src/merkle_tree.cpp`; the pure helpers shared through
4227 `merkle_detail.h`):
4228 - `Rx` (CoreRX: getters queue, `tryFlush`, `destroy`), `TreeStorage` (`read()`), `SessionView` (a session
4229 read LIVE: `SessionState` and `TreeBatch` implement it);
4230 - `TreeBatch` (MerkleTreeBatch / ReorgBatch: get, byteRange, byteOffset, downgrade, restore, seek, update +
4231 `_update` with JS's `startingDiff` identity check), `ByteSeeker`, `TreeProof` + `settle` / settleProof,
4232 and the statics. JS's two reader shapes (one rx per batch vs one per node); the proof's reads queued
4233 on the caller's rx in JS's push order; async vs plain functions kept; the NaN quirk.
4234 - **Gate `r4c_mt`** (tools/mt: gen-mt.js, mt-trace.js, mt-trace.cpp, mt-gate.sh): 6 scripts × real /
4235 virtual vs hypercore 11.37's merkle-tree.js over hypercore-storage, traces identical line for line
4236 (hops included). The seek-proof quirk (R4c-4b) reproduces by construction. Drill r4c4c 11/11; its
4237 first-run survivor was a script gap (no offset past the first root), fixed.
4238 - **4c-3: every caller on the async API**, inside `scaffold::Sync` scopes (the frontier rule):
4239 - `SessionState` is the live `merkle::SessionView`; `Core::session()` returns the state.
4240 - `hc/merkle_l2.h` (temporary, deleted at R4c-4d): `L2Rx` behaves as hypercore-storage's CoreRX does.
4241 Its getters (tree nodes and blocks) QUEUE in call order, `tryFlush` resolves them in that order, and a
4242 getter after the flush rejects with the freed view's TypeError. A first version resolved reads at the
4243 call: the replicator's path (JS awaits the proof BEFORE `tryFlush`) would then reject reads with no
4244 handler. Also `L2TreeStorage`, and `proveAndSettle` (core.js's checkConflict / `_repairTreeNodes`
4245 chain: proof, `tryFlush`, await, settle — one chain, so settle's reactions precede any checkpoint).
4246 - Reorg batches are `TreeBatchPtr` (Core::verifyReorg, the replicator's `f.batch`, `reorgUpdate`).
4247 - keetd's own ByteSeeker (core/byte_seeker.cpp) is deleted: `Session::seek` and the replicator's
4248 seeks use l3's port of merkle-tree.js's.
4249 - **JS shapes restored:** the replicator reads the block in the proof's own read batch and `destroy()`s
4250 the batch when generation throws (inventory sr:H15); `Session::proof` reads its block in the proof's
4251 batch (index.js `Hypercore#proof`); core-ops likewise.
4252 - The m3b / m5g1b vector tests drive the async API over the generators' kind of rx (settled at the call)
4253 on the virtual runtime: m3b serve 8742 / verify 14246, m5g1b 14969 cases, all pass. Harness rule:
4254 proof + settle in one coroutine.
4255 - **4c-4:** the synchronous readers are deleted (merkle.cpp 1021 → 387 lines); l3 keeps synchronous only
4256 what JS does (the batch's append / checkout / prune / clone / verifyUpgrade, maxMissingNodes,
4257 upgradeLength).
4258 - **Drills.** 44 anchors on changed code were re-anchored and re-drilled. Results: 40 red; 3 known
4259 survivors (m5g1b `_update`'s sibling-miss equivalent; m5g1d repair's check repeated by
4260 `checkConflict`; m5g1e's owed tree-cache test); and 1 new equivalent: 'range: offset lookups before
4261 size' — `Promise.all` settles with the longer chain (offset +1 hop), so creation order changes nothing,
4262 confirmed on the hop-trace gate. core's 'descends past an exact fit' (`>` → `>=`) is equivalent in l3's
4263 ByteSeeker (the `==` return precedes it) and is replaced by 'never descends into a larger left child'
4264 (red). ctest 90/90.
4265 - **Process lessons:**
4266 - Freezing a drill (SIGSTOP) that is a direct child of the tool's shell ends it: the shell reports it
4267 Stopped, moves on (a loop starts the next set beside it: two drills on one tree), and SIGHUPs it on
4268 exit. Drills run under a Python `subprocess.run` runner, and sets pause between runs via a pause file.
4269 - A `ps | grep "[d]rill.py"` inside a shell whose own command line contains "drill.py" self-matches.
42224270- **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack
42234271 is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful.
42244272