app
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
← Commit history
docs/mesh.md: the Adom Mesh, per-machine trust, and permission prompts that follow you across your boxes and into Hydrogen (2.1.74)
1 file changed
+153
docs/mesh.mdadded+153@@ -0,0 +1,153 @@+# The Adom Mesh: your machines find each other, and your permission prompts follow you++One person, several computers, one Adom account. The Adom Mesh is how every Adom Bridge you run+knows about the others, reaches them, and shows you a permission prompt raised on any of them,+wherever you happen to be sitting. This page is the user's view: what is on, what it costs you,+what a prompt from another box looks like (in Adom Bridge and in Hydrogen), and what a human+still has to decide.++## What the mesh is++Every Adom Bridge (2.1.40 and later) carries a durable node identity: an ed25519 key that lives+only on that machine (`~/.adom/mesh/node.key`, DPAPI-protected since 2.1.66). Machines signed into+the same Adom account learn about each other through the account directory in the Adom cloud+(each box publishes a small `bridge.runtime.<machine>` record: its name, node id, version, and the+relay it is homed on) and, on the same network, through mDNS. Nothing secret is in the directory;+the transport verifies the key, so a stale or forged record cannot impersonate a box.++The mesh has three modes (Settings, Mesh; or `settings_set {"mesh_mode": ...}`):++| Mode | What is open on your PC | How your boxes talk | When Windows asks anything |+|---|---|---|---|+| `off` | nothing | only through the cloud command relay, as always | never |+| `relay` (the default) | nothing: no port, no listener | each box holds one outbound connection to the Adom-hosted mesh relay; traffic goes box, relay, box, still end-to-end encrypted on the two node keys (the relay forwards ciphertext) | never |+| `direct` | one UDP endpoint | same as relay, plus direct QUIC between boxes on the same network or where a direct path exists | once, the ordinary per-app firewall question, with an on-screen caption explaining it |++Relay mode is the one networked feature that ships on, because it is outbound-only TCP, the same+class as the connection every Adom Bridge already makes to its command relay. Nothing on your+machine listens. Direct mode is opt-in; the first bind draws a caption next to the Windows+firewall dialog saying exactly what is being allowed (only machines signed into your own account+can connect; everything else stays on 127.0.0.1) and the same notice is mirrored to your other+boxes so nobody wonders what that dialog was.++## What it changes for the AI that drives you++- `--target <name>` (or `target` on the loopback API) tries the mesh first and falls back to the+ cloud command relay. A mesh answer carries `route: {via: "mesh", peer, nodeId, rttMs}`; the+ `via` is `direct` or `relay` depending on the path iroh selected.+- `targets` lists every box the relay knows and every box the mesh directory knows, in one list.+- `desktop_mesh_status` says what this box is (node id, mode, relay, endpoints, counters);+ `desktop_mesh_peers` lists the others with their reach, link, version, and trust state.+- Screenshots and `pull_file --target <peer>` stream over the mesh path with a sha256 check, so a+ file from another of your boxes lands on this one without a relay host holding it.++## Who is allowed in: a human trusts each new machine++The directory says which node ids belong to your account. Each box keeps its own answer to a+different question: which of those has a human let into this box's mesh (`~/.adom/mesh/trust.json`).++- **First start:** the fleet as it stands is trusted as a snapshot, so an upgrade or a fresh+ install joins an existing set of boxes without asking anything.+- **A new machine afterwards:** every box raises one card, "A machine wants to join your Adom+ Mesh", naming the machine, its Adom Bridge version and node id, with Trust this machine / Deny.+ Until someone clicks Trust, the new box is refused in both directions.+- **One click settles the fleet:** the decision is carried to your other boxes over the mesh+ (node-authenticated, never over the plain command relay), and their copies of the card go away.+- **Approval is human-only.** `desktop_mesh_trust` can `list`, `revoke`, `deny`, and (2.1.74)+ `raise`; it cannot approve. No verb, no AI, no remote caller can trust a machine into your mesh.++Since 2.1.74 an unanswered join card does not get lost. Hydrogen's copy of a card expires after+330 seconds; before 2.1.74 the node then sat "pending" forever while the status text claimed a+card was on your boxes. Now Adom Bridge re-raises a pending card every 10 minutes and whenever+`desktop_mesh_status` is read, an AI with eyes on the screen can bring it back on demand with+`desktop_mesh_trust {"nodeId": "...", "action": "raise"}` (or `{"all": true}`), and the pending+summary says when the card was last raised and whether it is still likely visible.++## Permission prompts follow you across your boxes++When one of your machines raises a human prompt, a shell approval, a grant request, a+web-control consent, a credential import, an input approval, or a toast with buttons, the same+card appears on every other machine signed into your account. Each mirrored card carries a bold+chip naming the box it belongs to ("ON CONFROOMROG"; local cards say THIS MACHINE), the AI thread+that asked, the command, and the reason the AI gave.++This does not need the mesh: since 2.1.59 the mirror also travels over the cloud command relay,+which every Adom Bridge is already connected to outbound, so a machine with the mesh `off` still+sees the other boxes' prompts. The mesh is the faster direct path and the fallback when the relay+is down; a card that arrives over both shows once.++Deciding a mirrored card is exactly as strong as deciding it on the box itself:++- A decision travels back to the origin and lands in the same place a local click does. Once,+ 1 hour, 24 hours, Auto (persistent), or Deny mean the same thing there.+- Only a box that received the mirror can answer it: the origin stamps a one-shot nonce into the+ mirrored card and refuses a decision without it. A cloud AI is also a relay caller, and this is+ what keeps it from approving its own prompt by echoing an id.+- Every decision is attributed: the origin's Activity Log and the card's record say which machine+ the human decided on.++A native Windows toast announces every mirrored card once ("Permission request on winvm ..."),+so a box with Adom Bridge in the tray still hears about it. The `cross_box_toasts` setting+(`prompts`, `decisions` by default, `all`) says how much plain toast traffic crosses between your+boxes beyond the cards themselves.++## In Hydrogen: the cards show up where you are looking++When Adom Bridge runs embedded under Hydrogen, the human is looking at Hydrogen, not at Adom+Bridge's window and, if toasts are hidden or Do Not Disturb is on, not at a toast either. So every+card is forwarded to Hydrogen's permission dialog:++- **A local prompt** (an AI asking to run something on this machine) has always been forwarded.+- **A prompt from another of your boxes** is forwarded too since 2.1.74. Before that, a cross-box+ card stopped at Adom Bridge's own window and a Windows toast, and Hydrogen never showed it: you+ could see "Permission request on winvm, open Adom Bridge to decide it here" and find nothing in+ Hydrogen. Now the same card, with the machine chip, renders in Hydrogen on every box you have it+ open on, and deciding it there routes the decision back to the origin with the nonce, the same+ path a click in Adom Bridge takes.+- **Dismissals are forwarded as well.** When the origin decides, expires, or drops a prompt,+ Hydrogen's copy on every other box goes down with it. A mirrored card nobody answers is dropped+ from the receiving box after 330 seconds (the same cap Hydrogen applies), so a stack never+ fills with prompts that can no longer be answered.+- **The join card for a new mesh machine** is forwarded the same way, and re-raised as described+ above until a human decides.++The reliable surface is the dialog, in Hydrogen or in Adom Bridge's window. A Windows toast is a+courtesy: on a fresh Windows 11 install Do Not Disturb stays on until the one-time "Allow important+notifications from Adom Bridge" prompt is answered, and until then a toast folds into the+notification center unseen. `GET /status` on the loopback API reports this as+`notifications.mayBeSuppressed` (2.1.73), so an AI that raised a prompt can tell you to look at+the dialog instead of waiting for a toast, and `notification_settings_open` opens the Windows page+where the permission is granted. Adom Bridge never grants that permission for itself.++## The Mesh view++The Mesh button in Adom Bridge's header (or `desktop_ui_panel {"panel": "mesh", "action": "show"}`)+opens "Your mesh": this machine in the centre, the Adom mesh relay above it as its satellite, your+other machines fanning into that relay, the cloud command relay beside it, and each box's attached+Hydrogen container beneath its parent. Every line says what carries it (direct, via the Adom+relay, cloud command relay); hovering a line or a box shows the transport, the encryption in plain+words, both endpoints, round-trip time, bytes each way, and how long the link has been up.+Hovering a box also shows its trust record: who approved it, on which machine, when.++## What it cannot do yet++- **Direct paths across different networks.** Two boxes behind different NATs talk through the+ Adom mesh relay (still end-to-end encrypted). Hole punching needs a UDP-reachable relay host+ and is not on yet; a box on the same network as you connects directly in `direct` mode.+- **Other accounts.** The mesh is one account. Pairing a work account with a personal one is+ planned, not shipped.+- **Containers as full nodes.** Your Hydrogen containers are drawn under their parent box and are+ reachable through it; they do not yet hold their own node keys.++## Verbs and settings on this page++| Surface | What |+|---|---|+| `desktop_mesh_status` | this box: node id, mode, relay, endpoints, counters; also re-raises any pending join card older than 330 s |+| `desktop_mesh_peers` | every same-account box: reach, link (transport, encryption, RTT, bytes), version, trust |+| `desktop_mesh_trust` | `list`, `raise` (2.1.74), `revoke`, `deny`; never approve |+| `desktop_ui_panel {"panel": "mesh"}` | open the Mesh view |+| `settings_set {"mesh_mode": "off" \| "relay" \| "direct"}` | the mode; `mesh_enabled: true` means `direct` |+| `settings_set {"cross_box_toasts": "prompts" \| "decisions" \| "all"}` | how much plain toast traffic crosses boxes |+| `GET /status` -> `notifications.mayBeSuppressed` | whether a toast on this box may go unseen |+| `POST /permission/resolve {id, decision}` | how Hydrogen decides a card; a `remote:<peer>:<id>` id is routed back to the origin (2.1.74) |