Adom Bridge
Public Made by Adomby adom
Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-onl
Startup network burst multiplied by restarts: about 2 requests/s per crash-looping install (4x carbon /user per launch, installer re-download, no saved backoff)
Colby caught Hydrogen Desktop hitting carbon.adom.inc/user about 4 times a second per installing machine (fixed in ah 1.0.571). We then audited every Adom client for the same class of bug. Bridge is quiet in steady state (about 15 to 30 requests an hour per install). The danger is startup cost multiplied by restarts. One launch from Hydrogen makes about 25 to 30 remote requests, and nothing about that rate is remembered on disk. Hydrogen respawns a crash-looping Bridge about every 15 s (about 240 launches an hour), so one crash-looping install sends roughly 6,000 to 7,500 requests an hour (about 2 a second):
| Destination | Per launch | Per hour in a crash loop |
|---|---|---|
| carbon.adom.inc | 4 x GET /user + 1 PATCH |
about 1,200 |
| wiki.adom.inc | about 15 to 20 | about 3,600 to 4,800 |
| fleet pings (insiders) | 5 | about 1,200 |
| adom.cloud | 1 relay WS upgrade per cloud server, plus the mesh relay | about 240 each |
If a Bridge update is pending, every launch also re-downloads the whole ~22 MB installer, up to about 5 GB an hour per install.
Audited origin/main at c0fde4ed (2.1.170), code reading only. Paths are under src-tauri/src/ unless they start with src/main.js. (Hydrogen's side of this, the 15 s respawn with no backoff, is ours to fix in ah; we'll do it there.)
1. Every Hydrogen spawn runs an update check at once, and can re-download the installer
- Trigger: Hydrogen passes
--session-tokenon every spawn, soauth.rs:202sees a handoff.lib.rs:5903callsaccept_handoff(auth.rs:265), which callsupdater::spawn_check_now("handoff")(auth.rs:286), skipping the updater's 20 s delay. - Requests: the wiki
version.json(insiders plus public,updater.rs:567,:600). With an update pending: a HEAD and Range GET (updater.rs:723), then the full installer (updater.rs:532,download_and_stage). For insiders: fleetPOST /pingfor Bridge and for each bridge (updater.rs:832,:919). With the bridge cache always empty at launch, each bridge's manifest is re-checked too (updater.rs:928). - Why it multiplies: "already staged" lives only in memory (
updater.rs:1855, status created fresh atlib.rs:6113).spawn_check_nowignoresupdate_mode=offand embedded mode.POST /embedded/enterwith a token (direct_api.rs:2985-3015) runsspawn_check_nowandkick_check_after_sessionback to back, and onlykick_checkhas an in-flight guard. - Fix: save the last check time and the staged installer's version and hash to disk. Skip the handoff check inside about 30 minutes of the last one, never re-download an installer already staged with a matching hash, and make
spawn_check_nowrespectupdate_mode=off.
2. Carbon /user is read 4 times per launch, plus a PATCH
accept_handoff(carbon.rs:157), cloud server pull (lib.rs:5926tocloud_config.rs:91), mesh relay token (mesh.rs:363to:1962) and the mesh peer directory (mesh.rs:481to:534) eachGET /userfor the same document. ThenPATCH /user/hydrogen/settings(carbon_runtime.rs:156, started atlib.rs:5722).- Fix: fetch
/useronce per launch and share it. Skip the PATCH when the record is unchanged and was published under 4 h ago (keep a copy on disk).
3. The UI re-checks every bridge on the wiki 4 s after each page load
src/main.js:4511-4515callscheck_bridge_updates(lib.rs:2620tobridge_cache.rs:1699) 4 s after load, then hourly. The page loads on every launch (including hidden and embedded ones), after each ~10 minute memory-saving unload, and on webview crash recovery. This skips the background sweep's jitter. About 2 GETs per bridge per load.- Fix: read the cached status on load, and keep the live check for the "Check for updates" button.
4. Relay WebSocket reconnect: no jitter, and fast reconnects after longer connections
- Backoff is 1 s to 30 s for quick failures and 5 minutes on auth failures (
ws_client.rs:232-325), which is good. But a clean close after more than 10 s reconnects immediately (:276-281), and an error after more than 10 s waits 1 s (:300-305). A relay or proxy that drops connections at 10 to 15 s therefore gets a reconnect every ~11 s forever (300 to 360 an hour per server). There's no jitter, so after a relaykick_allevery Bridge reconnects in the same instant. - Fix: add ±20 to 50% jitter, treat connections under about 60 s as short, and keep escalating across repeated short connections.
5. Relay peer list polled every 12 s while the window is showing
src/main.js:2390callsrelay_peers(lib.rs:1811), which POSTsget_clientsto the relay's 8766 through the adom.cloud proxy, once per relay every 12 s (about 300 an hour each).- Fix: poll every 60 s or more, or push peer changes over the existing WebSocket.
Lower
- 6.
web_demo.rs:185to:67fetchesweb-control-demo.htmlfrom the wiki on every launch. - 7.
POST /update/check(direct_api.rs:3248, verb atcommands.rs:2903) has no throttle. Each call runs a full check plus fleet pings. - 8. The runtime record publish retries every 60 s forever on a 429 or 5xx (
carbon_runtime.rs:149-168), so the whole fleet hits Carbon in sync during an outage. It needs exponential backoff with jitter. - 9. Per-verb bridge auto-update (
bridge_autoupdate.rs:23,45): the 30-minute throttle is in memory, so every new process repeats it. - 10. Bridge hero image and wiki metadata (
lib.rs:2932-3060,lib.rs:3270+) have no negative cache. A bridge with no hero is re-fetched (2 to 6 GETs) on every page load. - 11. After a failure, the runtime download (
runtime_cache.rs:283,:569-574), missing-bridge reconcile (bridge_cache.rs:493) and first-run prewarm repeat on every launch with no saved backoff. - 12. Hourly cloud sync (
lib.rs:7007to:4150-4160) sends an unconditionalPATCHplusGET /user, even when nothing changed.
Suggested crash guard
Record launches on disk. If Bridge has started more than N times in M minutes, skip all optional startup network work (demo page, fleet, bridge checks, reconcile, prewarm) until it stays up.
Already fine
- The background bridge sweep (jittered, 20 to 28 h).
- The 4 h updater.
- Daily skill sync.
- Mesh peer reads (throttled to one per 20 s).
- Sign-in polling (2 s, capped at 14.5 minutes).
- The container-side relay supervisor (backs off).
- One open question: iroh's mesh relay reconnect backoff on a 401 could not be verified locally.