Back to list
Skywire Development Update — October 1, 2026
October opened with the native hypervisor’s own desk finally getting the same real-origin browser the wasm desk already had, after which a run of navigation and caching fixes made browsing inside either one feel like an ordinary browser rather than a proof of concept. A folded dmsg server picked up QUIC and WebTransport on the same shared socket its visor already uses, closing a gap that had kept folded servers unreachable from a browser. WebTransport’s own certificate now rotates itself before browsers would otherwise refuse a connection outright, and the browser visor got WebRTC transports back after they’d quietly stopped working when the visor moved into its own worker thread. Reward pool 2 moved onto a real per-visor bandwidth feed published by transport discovery itself, after a cold cache had let an empty day get paid as if it were real data a week earlier.
Skywire: The Native Desk Gets a Real Browser Too
5310 found the native hypervisor’s own desk never actually loading the page component that claims a real browsing origin in the first place, so every single site opened there, mesh and clearnet alike, fell through to the sandboxed transcoder regardless; a mesh site now opens through the visor’s own reverse proxy instead, letting the browser load it natively with working subresources, cookies and WebSockets, while clearnet sites keep using the transcoder there for now. 5311 finished the job by giving the native desk’s browser the same real-origin architecture the wasm desk already runs, including clearnet sites this time — isolated per-origin bootstrapping, a streamed transport through the visor’s own resolving proxy, and a loopback-only fallback address for browsing over plain HTTP without TLS, verified end to end against a public test site with cookies, WebSockets and a twenty-megabyte stream all working correctly.
5325 found a real-origin page navigating away from its own site — a plain link, a form, a script setting the location — going straight to the network instead of through the visor, since a service worker simply never sees a top-level navigation at all; the bootstrap now intercepts exactly that case and hands the real destination to netscrape to load properly, which is also what makes the Back button and the address bar actually track where the frame went.
5327 followed with a run of smaller navigation fixes found by using the browser as a browser: Back and Forward now show a page’s own cached copy instead of re-fetching it over the mesh every time, a form that posts to its own site actually reaches the destination instead of being silently dropped by the shell server in between, and a background tab takes on the page’s own title rather than a generic placeholder. 5330 fixed outbound clearnet requests going out with Go’s own generic HTTP client signature rather than a real browser’s headers, which was enough for Wikipedia to refuse the connection outright with a 403; the desk now fills in the browser’s own User-Agent and Accept headers whenever the page itself hasn’t already set them.
Skywire: A Certificate That Rotates Itself Before Being Refused
5318 found every WebTransport server generating one certificate at startup and keeping it indefinitely, while a browser will only accept a hash-pinned certificate for up to fourteen days from issuance — so any server running longer than its own certificate’s lifetime simply became unreachable to every browser client until it was restarted. Each server now replaces its own certificate on a six-and-a-half-day cycle well inside that window, with existing connections left untouched and the new certificate’s hash advertised the moment it takes effect. 5319 closed the gap that rotation alone would have left open: a client that cached the old certificate’s hash before a rotation had no way to reconnect without first looking the server up again; every server now advertises both its current and its next certificate’s hash in advance, so a client holding either one can still connect through a rotation with no fresh lookup required.
Skywire: A Folded dmsg Server Learns Every Protocol Its Standalone Self Had
5313 found a dmsg server folded into a visor sharing only the TCP half of the visor’s transport port, leaving its UDP side — the visor’s own shared QUIC socket — refusing the dmsg protocol’s handshake outright and forcing every QUIC dial back down to a TCP fallback; the dmsg protocol identifier is now registered on that shared socket alongside the visor’s own, with the resulting endpoint advertised in discovery exactly as a standalone server’s would be.
5315 closed the matching gap for WebTransport, which a standalone dmsg server advertises as how a browser specifically reaches it, but which a folded server had never been able to offer since the transport port’s own WebTransport identifier already belonged entirely to the visor’s own transport; one shared HTTP/3 server on that socket now dispatches to either the visor’s own endpoint or the folded dmsg server’s by path, so a browser can reach a folded dmsg server the same way it reaches a standalone one. 5322 and 5323 fixed the js/wasm build of the full binary, which the WebTransport fold had broken outright by calling into functions that exist only in native builds, having quietly stopped publishing any browser binary at all until the actual build failure was found and the offending calls moved behind the correct build tag.
Skywire: WebRTC Comes Back to the Browser Visor
5314 found every WebRTC transport failing outright with an “unknown network type” error ever since the visor’s own code had moved into a dedicated Web Worker, because a worker has no RTCPeerConnection object of its own and can’t reach the one that lives on the page; a small proxy object now carries every call and event between the worker and a real peer connection the page holds on its behalf.
5328 found the browser visor freezing for ten to thirty seconds at a time once WebRTC was back, tracing it to an ICE-candidate callback writing to the signaling connection inline — a blocking call inside that specific kind of callback stalls Go’s entire js/wasm scheduler, not just the one goroutine — fixed by moving the send onto its own goroutine, which took one tab’s measured transport latency from roughly twenty seconds down to 187 milliseconds. 5324 found the router ranking WebTransport and the browser’s WebSocket carrier behind ordinary WebRTC in its first-hop preference order, when both are actually just as direct a link as the TCP and QUIC carriers a browser visor can’t open at all; both now rank alongside the genuinely direct carriers instead of behind WebRTC.
5333 found autoconnect capping a browser visor’s WebSocket-carried transports at the same low number a native visor keeps alongside its own direct TCP transports, even though that carrier is the closest thing to a direct transport a browser visor actually has; the cap is now twenty, filled over thirty-second cycles instead of five-minute ones, measured carrying roughly four times the bytes of a WebRTC leg at comparable latency. 5331 found the standby pool’s own sizing logic only ever refreshed on a fresh dial, so once a pool had settled early on a small set of WebRTC-only first hops it never grew to use the WebSocket transports that came up a minute or two later, stuck that way until the proxy was manually restarted; the bound is now refreshed on its own two-minute cycle so a settling pool keeps rechecking what’s actually available to it.
Skywire: Reward Pool 2 Gets a Real Data Source
5316 found that a missing or empty bandwidth file for a given day had been silently falling back to an older reward model that splits visors into pools by architecture, which is exactly the behavior the newer model exists to replace; rewards no longer split by architecture under any circumstance, and a day with no bandwidth data simply pays pool 2 the same way pool 1 is paid, with the reason recorded plainly in the day’s own stats. 5317 found the actual reason a day’s bandwidth file had come back empty in the first place: the reward host’s own visor had answered a metrics query from a CXO feed whose very first sync hadn’t finished yet, which reads as a legitimate empty answer rather than a feed that simply isn’t ready; that feed is now read only after its first sync completes, and an empty answer is never written over a day’s existing real data.
5320 moved pool 2’s entire data source off a roughly nine-megabyte-a-day raw metrics dump fetched through the reward host’s own visor, replacing it with a proper per-visor bandwidth summary that transport discovery itself computes and publishes once each day settles, at roughly fifty kilobytes instead of nine megabytes; the same-IP exclusion pool 2 needs now happens inside transport discovery directly, fed by a keyed hash of each visor’s own surveyed IP rather than transport discovery ever seeing a raw address. 5321 fixed that exclusion’s actual coverage: it had only ever worked from survey data that exists solely for visors seeking rewards in the first place, so a transport to an unsurveyed visor on the identical IP was still being paid in full; each visor now marks its own transports to a peer it reaches at a private, its own public, or an interface address directly, which closes the gap without needing survey data from the peer at all.
Skywire: Smaller Fixes
5312 put a tunnel’s actual round-trip time on its own line in the route tree, since packet-level multiplexing delivers everything in order and is therefore only ever as fast as its single slowest live leg, and removed a trailing column describing where each leg’s chain came from that had been making the whole tree too wide to read comfortably. 5329 stopped a dmsg web bridge from logging two routine lines as errors every time an ordinary bridged connection simply ended normally. 5332 and 5334 fixed a test that had been failing the Windows CI lane eight times out of twelve recent runs, because it pasted a raw filesystem path straight into a JSON string without escaping it, which reads as an invalid escape sequence the moment that path contains a Windows-style backslash; the path is now properly JSON-encoded, and the test’s own temporary file name was adjusted so the fix could be verified on Linux too without tripping over Windows’s own use of backslashes as path separators.