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
Lifecycle deadlock: stale alive record loops recover_not_listening (reaped 0, never respawns); duplicate-collapse path resets state but reap-0 path does not
Bridge lifecycle deadlock: stale "alive" record makes recover_not_listening loop forever, reaping 0 and never respawning
Root-caused live on AdomLapper tonight against the puppeteer bridge, but the bug is ab-core lifecycle state, not pup. Two multi-hour outages with the same signature; full forensics on adom/pup-bridge#40.
The signature
The adLifecycle audit repeats this every ~20 s, for hours:
process was alive but never bound port Some(64230), reaped 0 pid(s) so the next verb respawns a clean instance (issue #31)
While it repeats, all three of these are simultaneously true:
netstat -anoshows nothing on the assigned porttasklistshows NO pup node process at all, andbridge-pids.jsonhas no puppeteer entry- the bridge's log gains zero new lines, so no respawn ever reached first output
So "alive" is a stale record for a process that no longer exists. The reap then kills 0 pids because there is nothing to kill, the stale record survives, and the "next verb respawns" promise never executes, presumably because the tracked instance still reads as alive. Believes alive, so will not spawn. Reap kills nothing, so the belief never clears. Deadlock, indefinitely, while every verb against the bridge returns the startup-hang hint.
The tell: what accidentally breaks the deadlock
Both recoveries happened moments after a REAL pup-shaped process appeared (I ran node server.js manually from the bridge cache while diagnosing; it binds pup's default 8851):
[ab 2026-08-09 05:15:40] spawned process pid 5348 (node.exe)
[ab 2026-08-09 05:22:19] REAPED 1 instance(s) [(29788, 8851)] as duplicates; kept pid 5348 on the assigned port 64230.
The duplicate-collapse path saw the foreign instance, collapsed, spawned a genuinely fresh instance on the assigned port, and pup has been healthy since (pid 5348, hours now). So the collapse path RESETS the tracked-instance state correctly; the reaped-0 path does not. That asymmetry is the bug.
Suggested fix
In recover_not_listening (the "issue #31" path):
- When a reap matches 0 pids, CLEAR the tracked-instance record before returning. A record that matches no live process is stale and safe to discard.
- Treat "record says alive, but no process matches it" as dead on every probe, not only at reap time.
- Consider updating the audit line: it currently states a respawn will happen, but in this state it never does, which sends the reader down the wrong path. If the state machine declines to spawn because it believes an instance is alive, log THAT, so the next person's first clue is the actual condition.
Repro
Hard to force on demand (we never caught what orphaned the record; candidates are a crash between spawn and pid-record, or a kill that bypassed record cleanup), but detection is trivial: any bridge whose audit shows 3+ consecutive "reaped 0 pid(s)" lines with no interleaved "spawned process" line is in this state. AdomLapper showed hundreds in a row across two windows totalling ~4 hours, and a KiCad-thread bridge_kill during the first window returned killedPids=[] against the same stale record.
Happy to run any instrumented build; the box that reproduced it is mine and I have a full timeline.