Route TS follows through the shared Rust WASM session
Browser, Node and Bun follows use the merged Rust Streams session engine through WASM. JavaScript supplies physical connect/read/write/close callbacks. ALL/LATEST validation, checked anchors, credit, cancellation, fencing and recovery no longer have a separate TypeScript implementation. Ordinary follows, canonical followData and live children share the Rust pool.
The shrinking stateful property drives the production Rust client against an independent append ledger with distinct commits. It fills credit, preserves unread deliveries and injects reconnect and moved at every action boundary. The last-received-anchor mutant fails the same oracle; thin TS tests verify the WASM sequence, cuts, attention and watermarks.
Decisions
- Reconciled with origin/main
05c5e29e2c555beae71c1d70955a38b10cd68585, which contains merged #710 and #740. Repository rules prohibit rebasing/force-pushing published branches, so this uses a signed normal main merge. All inherited gc-client snapshot files were resolved to main; the PR diff contains only stream-push changes under the Rust/TS Streams packages. No open dependent implementation PR needs a restack; #714, #724 and #740 are already merged. - Session gRPC callback failures now use the existing Rust
wire_codec::statusdecoder exported asgrpcErrorCode. The transport emits only canonical Rust codes; the existing public TS aliases stay outside the session engine. No inverse alias table is introduced. The complete inventory comes fromStreamError::ALLthrough WASM, rather than another JS list. Native shrinking properties and a shared TLS fixture verify every code, exact retry counts and one physical connection; a mutant routing through the former public alias projection fails the canonical-code assertion on NotFound. - Uses #710's final
Client::with_transport,transport::{Transport, Endpoint, Connect, Requests, Responses}andruntime::{Executor, PlatformExecutor}unchanged, plus existingfollow_data_with_ack,children,WasmFollowandFollowState. The callback export addsWasmSessionand a default no-opTransport::cancel_channelhook for asynchronous pre-admission writes. It extends the shared engine rather than replacing its native/direct-browser transports. - A blocked platform write is cancelled per logical channel without closing siblings' shared connection. Rejected subscription writes enter the existing terminal-channel path; physical control-write failures enter Rust recovery. The I/O response owns both directions and all cancellation state; no detached writer or second route/credit/recovery engine exists in JavaScript.
- Repeated Welcome/EOF before registration yields through the existing reconnect backoff so deadlines can execute; its final interest cancels the owned attempt. Healthy delivery has no coalescing timer. A real-path Loom model and negative control exercise retry release versus withdrawal, without exploration/preemption bounds.
- JS external-event models retain platform I/O, deadline, selection and admission coverage with negative controls. Cursor, credit, reservations and movement are verified against the Rust engine. Rust's existing batched aggregate credit policy remains; fixtures assert bounded grants and exact zero at shutdown.
- Eight browser seeds now run through the shared Rust session fuzz target. Exact intended cursor, watermark, item-length and confirmation outcomes are asserted independently, preventing mistagged seeds from bypassing their cases. The fuzz lock includes main's shared proto-build dependency.
- Rust malformed-follow failures retain their exact canonical Unavailable code; unary/read decoding retains invalid_response. Successful synchronous WASM initialization is preserved. Timer cancellation preserves both browser numeric and Node/Bun object handles.
- No wire fields, server endpoints, harness service, application store or polling were added. Application state remains files plus live queries; callbacks are platform transport I/O, which cannot be represented as application files.
Validation
All focused runtime suites below are under 10 seconds; builds and slot waits are excluded. Linux ran on bb1 through bs.ps1; Windows checks ran through lb.ps1. Models use the real synchronization shim and have no exploration caps.
| Check | Result | Runtime |
|---|---|---|
| Native session client, including 10k, allocation controls and stateful recovery mutant | 62 passed | 3.08 s |
| gRPC, including canonical status shrinking property / HTTP session tests | 22 / 2 passed | 0.31 / 0.05 s |
| Portable tracing / wire and exact seed properties | 2 / 5 passed | <0.01 s each |
| Pool Loom/property suite and negative controls | 29 passed | 0.67 s |
| JS I/O/deadline models and negative controls | 28 passed | 2.81 s |
| Runtime namespace shrinking properties and negative control | 2 passed | 0.24 s |
| WASM session and request capture | 15 passed | 5.08 s |
| WASM children and ALL/LATEST | 11 passed | 0.075 s |
| Canonical error round trips and mutant, TLS gRPC/browser transports and call-option declarations | 6 passed | 1.77 s |
| Node and Bun provider conformance | Both passed in one fixture | 2.17 s |
| ASan shared session fuzz, nightly-2026-07-01, GNU target | 2,000 runs, 18 seeds | 0.62 s |
| WASM build and TS typecheck/declarations | Passed | TS 0.21 s |
| Windows stream check, local,http, lib/tests | Passed after canonical-error fix | 2.69 s + 480 s slot wait |
| Windows standalone TS model crate check, tests | Passed | 0.19 s + 45 s slot wait |
Error-fix delta validation: WASM build and TS declarations passed; 22 native gRPC tests (0.31 s), six TLS/error/declaration checks (1.77 s), 11 ALL/LATEST/children checks (0.092 s), 28 existing JS I/O models using their built binary (0.80 s), Node+Bun conformance (0.77 s). Delta log: /home/var/log/buildbox/2026-10-16T211751766Z-806417.log.
The 38 standalone cursor/credit/wakeup models are unchanged from merged #740 (0.11 s); reused rather than rebuilt. Logs: /home/var/log/buildbox/2026-10-16T210001344Z-782941.log and 2026-10-16T210213935Z-785045.log. An additional redundant Bun-host launcher invocation selected Bun twice against one fixture and the second client correctly failed its initial absent-stream assertion. The Node-host invocation already passed both Node and Bun clients; the redundant launcher was removed from the external validation script, and only unfinished checks were resumed.
Local latency measurements
Previously recorded at the pre-restack adapter, 128 append-to-follower samples per case, microseconds; diagnostics only, with no wall-clock pass/fail threshold. Before is the existing server-streaming Follow RPC; after is the multiplexed Rust/WASM session. These shared-host measurements do not demonstrate a latency improvement.
| Runtime | Memory p50/p99 | gRPC before p50/p99 | gRPC after p50/p99 |
|---|---|---|---|
| Node | 111.32 / 592.16 | 3068.29 / 6689.76 | 3518.95 / 7125.28 |
| Bun | 111.20 / 1268.12 | 3235.83 / 8241.08 | 3173.89 / 11023.63 |
The native 10k, eight-node transaction/follow qualification passed with eight total sessions/connections and zero actor channels; delta p50/p99 was 1.220 / 1.677 ms. The paired 10k registration allocation probe still rejects the discarded path copy and redundant internal boxes: 110,001 to 80,001 allocations in the portable executor closure (including its registration deadline allocation), saving 380,000 bytes. Encoded traffic remains inside the linear per-follow budget.
Live steps
Hosted-service measurements require a deployed endpoint implementing ALL/LATEST, children and checked confirmation plus credentials; no hosted numbers are claimed. The previous read-only cloud audit at 686b37f66b0b804b3dbf63d2cb9e117205fdde4d found svc/streams/src/session/transport.rs:114-124 rejected these features; current deployed behavior remains unverified. The merged native 10k ALL qualification passes here; the combined tiered 10k status/view/prefetch workload and swarm interest-diff adapter remain subsequent work.