Back to list
Jul 30 2026

Development Update — July 30

The throughline today is the browser dmsg edge. A reachability campaign run down over the last stretch culminates in a fix to the deepest issue: a wss-only browser client was silently falling back to raw TCP it can’t dial, dead-ending connections that should have rendezvoused over WebSocket to the next server. That fix comes with a two-tier headless test harness so the browser edge — which the compile lane can’t cover — is finally regression-gated, plus an operator-run health probe that would have auto-caught the day’s real wss outage. The wallet also stopped shipping an 11MB copied tree and now serves straight from the vendored skycoin module, and the manager UI’s dependabot backlog was cleared in one batch.

Skywire: The Browser Never Falls Back to TCP

3632 fix(wasm/dmsg): robust on-demand rendezvous — browser never falls back to TCP (+ live server discovery) fixes the core reachability bug. dmsg is a rendezvous network: a visor holds a few sessions and reaches a peer by opening an on-demand session to one of that peer’s delegated servers, DialStream trying the next on failure. But a browser/wss-only client fell back to raw TCP in two places a tab can never satisfy — the per-carrier dial-failure fallbacks (gated on Address=="" under the false assumption that js entries carry no TCP address, when discovery-resolved entries do), and pickCarrier’s final fallback — so a failed wss dial became a futile dial tcp …:30082: connection refused that dead-ended the attempt as dmsg error 202. The fix gates every TCP/QUIC fallback on hasCarrier(), so a wss-only client that can’t reach a server fails cleanly and the rendezvous moves on to the peer’s next server over wss; native clients keep the historic QUIC→TCP default. It also makes the seeded discovery client answer AllServers from the live discovery rather than the seed-only client, so a browser edge learns the whole deployment. 3634 fix(dmsg): browser client never falls back to TCP — robust on-demand rendezvous re-applies the rendezvous half of that work, which was orphaned when #3632 auto-merged its first commit before this one caught up — verified as the real fix, with live futile dial tcp attempts dropping 3→0. As a side effect, the honest wss errors it now surfaces (instead of masking them as TCP refusals) exposed the actual server-side breakage: two stale DNS records pointing at a dead shared proxy and one failed cert issuance.

Skywire: A Headless Test Harness for the Browser Edge

3637 test(dmsg,wasmhv): Tier A headless browser-edge regression gate + mdisc check wss health probe locks the reachability fixes in place with the browser profile — a wss-only dmsg client — exercised headlessly against real in-process dmsg servers as ordinary CI-gating go test: four e2e regressions on the on-demand rendezvous model, including the explicit “never fall back to a live, dialable tcp-only server” case that was the capability violation. It also adds skywire cli mdisc check, the operator-requested probe that would have auto-caught the day’s wss breakage — for every discovery server’s advertised AddressWS it DNS-cross-checks and does a plain HTTP/1.1 GET expecting 426 Upgrade Required, exiting nonzero when an advertised front doesn’t serve — wired into a 6-hourly scheduled workflow. 3638 test(wasm): Tier B headless smoke — run the REAL wasm-visor blob under Node (no browser) adds the runtime tier: a self-contained loopback dmsg server plus a Node harness that runs the actual compiled js/wasm binary via wasm_exec.js and asserts boot → ws dmsg session → in-wasm hypervisor /api answering — catching boot-glue, carrier-selection, and dispatch regressions the compile lane can’t. 3639 fix(wasm): populate SelfSummary mirror fields, flag host-stats N/A, serve empty app-logs cleans up three mirror-struct leftovers where a healthy browser visor rendered as broken: a long-running tab showing “0s uptime” (now stamps a real uptime and states its honest edge values), host-stats reporting fake 0% gauges (now flags available:false so the resources page shows N/A), and app-logs 404ing into an error dialog (now serves a valid empty result so the panel renders “no logs”). 3633 fix(wasm): mirror the subsystem log firehose into the node Logs page (/runtime-logs) closes a dual-surface divergence where the desktop log window read the full subsystem firehose while the Angular Logs page read only sparse step markers all hard-coded to “info”; a logrus hook now mirrors every subsystem line into the ring at its real level, taking /runtime-logs from a handful of markers to 78 mixed-level entries.

Skywire: The Wallet Serves From Vendor

3635 feat(wallet): serve skycoin-web straight from the vendored module (drop the copied tree) + vendor skycoin@1bb47440 does two things best landed together. It vendors skycoin at develop head, carrying two freshly-merged wallet PRs — a known-servers dropdown in Settings → Nodes, and new wallets defaulting to bip44 (HD, multicoin). And it stops keeping an 11MB copy of the built wallet at pkg/visor/static/wallet, synced by make embed-wallet: skycoin already exports its built wallet as an embedded FS, so visor.WalletUIFS() now serves it directly from the vendored module, the copy is deleted, and the embed-wallet target is removed — from now on a skycoin vendor bump is the wallet update, eliminating the “forgot to re-embed” staleness class and the build-ui wipe-and-restore dance. 3636 chore(deps): batch the open dependabot npm bumps for the manager UI clears all seven open dependabot PRs in one lockfile update — all transitive build-time deps of the manager UI, with the built bundle verified byte-identical — avoiding seven sequential rebase cycles.