| … | … | @@ -3164,6 +3164,39 @@ injected per layer: |
| 3164 | 3164 | when convenient. |
| 3165 | 3165 | - **R2:** ss onto `rt` (`ss::Loop` and `ss::Timers` removed). The secret-stream trace and |
| 3166 | 3166 | interop gates are unchanged. |
| 3167 | - **R2 DONE 2026-10-04** (keetd 0aa694a). |
| 3168 | - timeout-refresh 2.0.1 is ported as `ss::TimeoutRefresh` on rt timers. Its `once` / `on` |
| 3169 | are overridable, the seam the JS trace patches (`Timer.once` / `Timer.on`). |
| 3170 | - rt gains the I/O hook: `uvLoop()` and `callback(fn)` (a libuv callback enters "JS": |
| 3171 | microtasks drain, then its throw is delivered). |
| 3172 | - Traces run on rt virtual: duplex plus 27/27 secret-stream scripts are identical to JS. |
| 3173 | - Interop runs on rt REAL with a `uv_pipe_t` raw stream: bare-pipe's core plus bare-stream |
| 3174 | 2.13's `_read` adapter, which calls `cb(null)` right after `_read()`. Without that |
| 3175 | adapter, streamx never re-reads after a pause. |
| 3176 | - New i6 (JS keepalive refreshes keetd's real timeout): 15/15. |
| 3177 | - Drills: m5g4e3b 20/20, m5g4e3c 19/19, r2 3/4 plus 1 equivalent. |
| 3178 | - **FINDING 2026-10-04 — Bare BATCHES timers and immediates; rt does not. DECISION PENDING |
| 3179 | (user).** |
| 3180 | - **Source (bare-timers 3.2.0, bundled in Bare 1.28):** all JS timers share ONE uv timer |
| 3181 | over a JS heap, and all immediates share ONE check callback. |
| 3182 | - `_ontimeout` runs every due timeout in one native callback, re-reading `Date.now()` on |
| 3183 | each pass. `_onimmediate` runs the queued batch (immediates added meanwhile go next |
| 3184 | iteration). |
| 3185 | - The microtask checkpoint follows the native callback, so it comes per BATCH. |
| 3186 | - A delay < 1 is clamped to 1 ms. |
| 3187 | - A throw aborts the batch: the rest is re-armed, then it rethrows. |
| 3188 | - **Measured, 20/20:** |
| 3189 | - two immediates, the first queuing a microtask: Bare gives `i1, i2, m1`; rt gives |
| 3190 | `i1, m1, i2`; |
| 3191 | - two 15 ms timers: Bare gives `a, b, ma`; rt gives `a, ma, b`; |
| 3192 | - a 1 ms timer queued in a timer that then spins 5 ms: Bare runs it in the same batch, 40/40. |
| 3193 | - **Why R1 missed it:** R1's scripts kept timers ≥ 15 ms apart and never batched |
| 3194 | immediates. The 0 ms-in-timer script raced the batch boundary (5/60 runs) and was replaced. |
| 3195 | - **Faithful fix:** port bare-timers' Scheduler into rt Real/Virtual (heap, one uv timer, |
| 3196 | batch dispatch, clamp, abort-on-throw), then gate batch orders. |
| 3197 | - **Alternative:** keep per-callback checkpoints and document the divergence; no ported |
| 3198 | library is known to depend on it (the timer audit). |
| 3199 | - The r1 drill's ONCE-first-iteration mutant survives until then (11/13). |
| 3167 | 3200 | - **R3:** mux / replicator / Core onto `rt` (Clock, `onsettimeout`, `Host::defer`, |
| 3168 | 3201 | `resumeVia_` removed). All repl / store / core gates and every drill re-run. |
| 3169 | 3202 | - **R4:** storage, per the decision above. |