| … | … | @@ -2699,6 +2699,21 @@ SessionState's truncate / reorg / named-session machinery. |
| 2699 | 2699 | noise-curve-ed Ed25519); HKDF-expand's double `info`; the 65535 cap; "Insufficient |
| 2700 | 2700 | bytes" / decrypt failures. Gate: vectors from JS with fixed statics and preset |
| 2701 | 2701 | ephemerals, every pattern both ways, mutated messages. |
| 2702 | - **4e-3a DONE 2026-10-04** (keetd b6f6d72 + the vector commit). |
| 2703 | - Vectors: 44 handshakes + 8 misuse; red 0/42 on a stub, then 52/52. |
| 2704 | - **Drill `m5g4e3a`: 16/18 red, 2 equivalent:** |
| 2705 | - HKDF-expand's `prev = info`: noise's `info` is always empty; |
| 2706 | - the unkeyed S-token length: no pattern sends S before a DH. |
| 2707 | |
| 2708 | The first run's Reader-bound survivor became the case "an s token one byte short". |
| 2709 | - **Measured (never guessed):** |
| 2710 | - a keyed ciphertext under its tag is Bare's RangeError "Array buffer allocation |
| 2711 | failed"; |
| 2712 | - nanoassert's AssertionError has NO code; |
| 2713 | - after completion V8 says "this.handshake.shift is not a function or its return |
| 2714 | value is not iterable". |
| 2715 | - **NOT gated here:** the RANDOM key paths (`generateKeyPair()` with no private key). |
| 2716 | JS draws them inside sodium-native; 4e-3c's interop covers them. |
| 2702 | 2717 | - **4e-3b `ss/duplex`:** the streamx Duplex core. Gate: an event-trace harness. One op |
| 2703 | 2718 | script drives a JS Duplex subclass and keetd's: write / end / push / destroy / pause / |
| 2704 | 2719 | resume / listeners, plus when `_open` / `_write` / `_read` / `_final` / `_destroy` |