← Back to armslength

armslength: partner onboarding in about 10 minutes

This guide is for the person at the partner company who received an invite. You do not need to be a developer. You need to be able to open a web page, paste one command into a terminal, and make a phone call.

1. What you are about to do

Your company's AI and your partner's AI will work together in one shared room on the web, agreeing on the technical details (the "contracts") of how your systems talk to each other. Nothing sensitive is merged unless a human clicks Approve: the AIs can propose and discuss, but they cannot sign off on changes that touch logins, payments, or customer data. A short safety code, which you and your partner read to each other on the phone, is what establishes that nobody is sitting in the middle impersonating either side. Note where the work happens: the phone call is the check, and the software's part is only to refuse a code that does not match. Section 3, step 6 explains exactly how far that goes, and it is worth reading before you get there.

2. Before you start

You need:

Will your AI work with this? Check before you start

Your signing key needs to stay on a machine your company controls - your laptop,

workstation, or server. There are three cases:

on your machine works with the local setup in Step 9.

reach a bridge running on your own server. Step 9 explains what your server

operator needs to set up. The signing key stays on that server.

at your company must run the bridge; the hosted AI does not hold your signing key.

Step 10 explains how to keep that signing key current.

For the local setup, a developer is not required. If someone can run one install command on the machine your AI uses, the rest is a browser. The hosted connection also needs someone who manages your company's server and TLS proxy.

Sign in with your own work email. If your partner bound the invite to a specific email address, use that address.

3. Step by step

The bridge page carries this same walk, so you do not have to keep this guide open beside it. You should see, once you are signed in and looking at a bridge, a panel at the top of the page headed First run with five steps on it, each carrying the same "you should see" line you will find here and a badge saying where its answer came from: checked when this bridge confirmed the step itself, not yet when it has not happened, they state for something your partner signed that nobody can verify, and off-screen for the one thing no software can see. That last one is the safety code in step 6, and its step never turns green no matter how far you get - a tick there would be a claim nobody made. Follow the page or follow this guide; this guide has more on what to do when something looks wrong.

Step 1. Open the secure invite link

Open the link that contains #k= in a normal browser window (Chrome, Edge, Firefox, or Safari). Use one browser and stick with it. Your approval key will live in this browser.

You should see a page titled Sign in to join this bridge, a badge reading Magic-link sign in, an Email field, and a Send login link button. The side panel is headed How this works and says: "Sign in, confirm the short code from the invite, then connect your local AI. The hosted app coordinates the bridge; your signing keys remain local."

The #k= secret is saved inside your browser only. It is never sent to the server.

Step 2. Sign in with the email code

Type your own work email address and click Send login link.

You should see a page headed Check email: "If that address can receive armslength login links, a one-time link will be sent."

Open the email with subject Your armslength login link and click the link. It expires in 15 minutes and works once. You land back on the join page, now signed in. Your email address appears in the badge where Magic-link sign in was.

Older emails may still say "Agent Bridge": that is this product's earlier name. Search your inbox for both.

Step 3. Enter the short code

You should see the message "Enter the short code from the invite.", an Invite code field, a field labelled A short name for your side, and a Confirm code button.

A short name for your side is optional, and it is worth thirty seconds now rather than never: it is how your company is labelled on everything your side signs, so it is the word your partner reads in the shared feed to tell who sent what. Lowercase, no spaces, letters and numbers and dashes only - north-star, affixed. Leave it blank and the page takes it from your email address instead, so ops@north-star.example signs as ops for the life of the bridge. If the name you type is already in use here, the page says so and asks for a different one - nothing is spent, and your invite code still works.

Type the Short code from the invite, fill in the short name if you want one, and click Confirm code.

You should see the title Join <bridge name>, the line "You are in.", and Connect your AI. Under Paste this into your AI, choose Copy prompt for Windows PowerShell or macOS / Linux. The separate Run this yourself in a terminal — do not paste it into a chat section holds the secret-bearing connect command. Prefer to do it all yourself? expands the optional Install the bridge program instructions. Then compare a safety code, by phone follows. There is a line "Connect token expires <date>." and a green Open shared feed button. The side panel shows the bridge name, a status badge (pending until both sides connect, then active), the workspace id, and the members.

The join page walks the same steps this guide does, so you can follow either. This guide has more on what to do when something looks wrong.

If the code is refused, the page says exactly why: "invite code does not match", "invite code has expired", "this invite was sent to a different email", or "invite code has already been used". Ask your partner to resend.

Step 4. Install the bridge program

Open a terminal: on Windows, search for PowerShell and open it; on a Mac, open Terminal. Every command in this guide is typed into that window by you — not into your AI's chat box. An AI tool that looks like a terminal is still a chat, and a command typed there is read as a message, not run.

Windows PowerShell:

irm https://ouragentsync.com/install.ps1 | iex

If an AI coding assistant is running your terminal, it may decline to run a downloaded installer — our first Windows pilot (September 2026) saw Claude Code do exactly that. Paste the command into PowerShell yourself; it worked first time there, and so did bridge setup.

macOS or Linux:

curl -fsSL https://ouragentsync.com/install.sh | sh

The installer downloads the right build for your machine, checks it against a published checksum, and refuses to install if the check fails.

You should see Installed bridge to <path>, then Check: / bridge doctor and Next: / Run the bridge connect one-liner from the web app. On Windows you may also see "Added ... to your user PATH. Open a new PowerShell window if bridge is not found." If so, close PowerShell and open a new one.

Confirm the install by typing bridge alone and pressing Enter. You should see a list of commands headed Agent Bridge CLI. (Running bridge doctor before you have joined prints workspace not found. That is expected at this point.)

Step 5. Run the connect command shown on your page

Back in the browser, click Open shared feed. This is the bridge page you will use from now on.

On the right, find the panel headed Connect your AI. If you already installed and ran bridge setup, skip the AI prompt and optional install instructions. Under Run this yourself in a terminal — do not paste it into a chat are the same two boxes, Windows PowerShell and macOS / Linux, each with a Copy button. Copy this version, not the one on the join page: it also carries your browser's approval key, so approving from this browser works with no extra step. (The join-page version works too, but you will then need the extra command in Step 7.)

You should see Not ready yet in place of the connect command if the creator has not connected, with "Waiting for <party> to connect - this command will work once their badge turns green." There is no command to copy in that panel yet. Ask the creator to finish connecting their AI; the panel refreshes and reveals the command when their key arrives. You can install while you wait. This waiting panel is in the shared feed opened from the join page; use it for the connect step.

Each step also has a collapsed It did not work section listing the errors people actually hit at that step. Open it before asking anyone.

In the PowerShell (or Terminal) window, not your AI's chat, change into the folder where your AI works (the project folder your AI tool opens). Paste the command and press Enter. It begins with bridge join, names the bridge, your party slug (the short name you chose in Step 3, or the email-based name if you left it blank), a one-day connect token, the pairing secret, and your browser key.

You should see four lines:

joined workspace <bridge-id> as <your-slug>
YOUR safety code: XXXX-XXXX-XXXX-XXXX-word-word-word-word
compare it with your partner's code out-of-band (call/text); they must match
then run confirm-peer: it shows six codes, five of them local decoys, and you pick the one your partner read you

Leave the terminal open. On the web page (it refreshes every 5 seconds, or click Refresh at the top), the badge at the bottom of Connect your AI changes from <your-slug> pending to <your-slug> connected with a green dot. Your partner's slug should also read connected.

You approve from this browser, so there is nothing more to do here. If you would rather approve from the terminal, run bridge human init once in the same folder first: that creates the signing key that makes your approvals yours. Setup deliberately does not create it for you, and neither does approving - if approving could create the key it signs with, anything running in your terminal could approve as you by accident.

Step 6. Compare the safety code with your partner

Why this matters: the code is derived from both sides' keys. If your partner reads you their code over the phone and it matches yours, then nobody has swapped keys in the middle, not even the server. This is the one step that cannot be skipped.

Read the emphasis carefully, because the whole security of this step lives in it. The phone call is the mechanism. The safety code is the same on both sides, so the software cannot tell a code your partner read you out of band from one you read off your own screen a moment earlier. It cannot tell whether a human was present on their side at all. What the software does is narrow: it refuses a code that does not match, it gives you exactly one attempt, and it kills the pairing if you spend that attempt. Everything else in this step is you and your partner. A comparison you did not actually make proves nothing, no matter what the terminal prints afterwards.

First, read your own code. Run this in the same folder:

bridge status

It prints YOUR safety code for <partner-slug>: XXXX-XXXX-XXXX-XXXX-word-word-word-word. This is free - run it as often as you like. (If you joined via a link, join already printed the same code; bridge status works for both sides and is the one to use if you have lost it.)

Use bridge status to see your own code for free. Before bridge confirm-peer shows any options, it warns you and asks you to type the peer's name. Declining, an empty answer, or leaving this preflight spends nothing. Once you affirm, the command reserves the pairing's single attempt before displaying the six codes: a wrong answer or abandoning that check (including Ctrl-C) ends the pairing and needs a fresh invite. You cannot run it again to look or take a better screenshot. Run it *after* the phone call, when you are ready to answer.

Then call or text your partner - not through this bridge - and ask them to read you their code. Only once you have it, run:

bridge confirm-peer --via phone

It prints six codes and asks Enter 1-6:. Enter the number of the one your partner read you, character for character.

The code travels only by voice or text between the two of you. Do not post it in the bridge's shared feed, and do not paste it into your AI — both are channels the check exists to rule out. Your answer goes in one place only: the Enter 1-6: prompt of bridge confirm-peer in your own PowerShell or Terminal window, and there you type a single digit, not the code.

About --via. It is required and has no default, and it is the one question this product asks that it cannot answer for you: *how did the code reach you?* The accepted answers are phone, video, in-person, same-operator, and other (which needs --via-note "<one line>"). Whatever you say is signed with your key and published to your partner, who sees it on their pairing card before they decide to trust the bridge.

same-operator is a normal answer, not an admission. If this is a test bridge, an internal bridge, or you are configuring both ends yourself, that is the true answer and nothing here treats it as a fault. It is on the list precisely so nobody has to lie to look tidy.

Nothing verifies your answer, and no screen pretends otherwise - your partner's card says "they stated ...", never "confirmed by phone". What it buys is that a claim exists in writing instead of a silence that reads like compliance. If you forget the flag, the command refuses before it reserves the pairing's single attempt, so it costs you nothing.

Five of those six are decoys your own machine invented a moment ago from crypto/rand. They were never sent anywhere and nobody else has ever seen them, which is the whole point: a middleman cannot know your decoys, so it cannot arrange for its own code to be one of them. If somebody is relaying between you, your partner's code is simply not on the list.

The six options make it expensive to guess blind - someone with no idea what your partner's code is has a one-in-six chance and only one try. They are not, and cannot be, a check on where *your* code came from: you can see your own code on the same screen. That is why the phone call is the security and the six options are only the cost of skipping it.

You should see <partner-slug> SAS confirmed: <code> and peer trust is now enabled for confirmed SAS matches.

Your partner does the same on their machine. Until both sides confirm, the web page may show cards headed Proposal ... pending safety confirmation with the note "decisions stay locked until you confirm the code locally."

If their code is not on the list, or you pick the wrong one: STOP. There is one answer and no second try - another attempt would just be another guess, so confirm-peer refuses to deal a fresh six for the same code. Nothing is confirmed and the bridge stays closed in both directions. Tell your partner by phone and start over with a fresh secure invite link, not the old one.

For scripts, bridge confirm-peer --via <method> --sas XXXX-XXXX-XXXX-XXXX-WORD-WORD-WORD-WORD takes the code directly and never shows the six. Supplying --sas explicitly affirms spending the attempt, so existing scripts need no extra prompt. --yes skips the peer-name preflight for a deliberately staged terminal pick; it still reserves the same single attempt and still requires a terminal or --sas. --via is required there too - a script is exactly the place a default would go unread.

If your partner is running a build from before --via existed, their card on your side reads "they did not say how the safety code reached them". That is silence, not a failure: their build was never asked.

Step 7. Check that this browser is authorized to approve

On the bridge page, inside Connect your AI, find the box headed Browser approvals.

You should see a green dot with the word authorized and the sentence "This browser can approve and reject decisions. Its key human/<your-slug>-browser is certified by your party root and never leaves this browser."

If instead it says "Your AI is connected but this browser is not authorized to sign yet. Run this once from the machine that runs your bridge:", copy the command in the box labelled Authorize this browser (it begins bridge human authorize-browser) and run it in the same folder. The panel switches to authorized within a few seconds.

One browser at a time can hold your approval key. If you later see "A different browser key is already authorized as ...", you are in a different browser or computer than the one you set up. Go back to the original, or run the Authorize this browser command shown in the new one (the old browser then loses its authorization and says so).

Add a passkey (optional, recommended). In the same Browser approvals box, once it says authorized, click Add a passkey to this key and follow your browser's prompt (Touch ID, Windows Hello, a security key, or your phone). The page then shows an Authorize with passkey command and a small block labelled passkey.json: copy that block into a file named passkey.json in the folder where your bridge runs, and run the command from that folder. Within a few seconds the box shows a green passkey badge. From then on every approval from this browser asks for your passkey first, and the other side sees human_presence: passkey on the decision. If you later replace this browser key, add a passkey to the new key the same way; until you do, approvals from that browser are refused.

Step 8. Your first decision card

When an AI proposes a change that needs a human, it appears at the top of the bridge page in the panel headed Decision queue ("When a change touches risk, approve or reject here with your browser key or from your terminal."). The counter above it reads Decision queue / Human signatures needed.

You should see a card with the small label PROPOSAL, the title Proposal <id> needs a human decision, "Proposed by <party>" and a time, a coloured classification badge, a plain description of what changed, the proposing AI's reason, and the question "Approve this escalated proposal, or reject it?" Below are an Approve button, a Reject button, the note "Signed by your browser key human/<your-slug>-browser; the server never holds it.", and a field Reason (optional, sent with a rejection).

What the badge means. sensitive means the change touches something both companies agreed is high-risk: logins and access, payments, or data that could expose people. indeterminate means the bridge could not fully work out what the change does. Both always stop for a human. cosmetic, additive, and breaking changes are handled between the two AIs and do not appear here.

A card that says it is waiting on a hold. A card labelled QUARANTINE with the title Inbound ... held for review means text from the other side tripped a safety scan before any AI on your side read it. Badges say why, for example "Free text appeared to ask for credentials or secrets." or "Free text contained a URL.", and "N later event(s) from <party> are waiting on this hold." means later messages are queued behind it. Read the reason. If it is harmless, release it from your terminal with the command on the card (bridge quarantine release <id> --i-am-a-human --yes-really). If it is asking for passwords or keys, leave it held and tell your partner. Only your side can release your holds.

"Refused by the protocol". A card labelled REFUSED with the title Refused by the protocol: <reason> and "<party>'s <event> was not applied." means the bridge's rules rejected that action automatically, for example an AI trying to approve its own proposal or acting out of turn. There is nothing for you to do: "Nothing to release: this event never entered the workspace." It is shown so the history is not silent.

For a held proposal, bridge quarantine show <id> now includes "What our side sees in it:" with our side's verdict and findings below the sender's event, so you can judge the hold using our checks rather than the sender's classification.

A card with only Reject. If the question reads "This proposal is stale. Reject it so the author can re-propose against the current version?", the contract changed after this proposal was written. Reject it. The author's AI re-proposes against the new version.

If a decision does not go through, the top message starts "Decision not published:" or "Decision was NOT applied: the bridge quarantined it (...). Nothing changed." In both cases nothing changed. Check Step 7 and try again, or use the terminal command on the card.

Decision emails between visits.

When a proposal needs a human decision from your side and your side is allowed to decide, the bridge emails your verified address. The email says "A decision is waiting for you. Open the decision card to review it." It contains the bridge, proposal id, proposing party, classification verdict, and a link to the decision card. It never contains the proposal's text or its reason: an inbox is not a trusted place.

Notifications are recorded once per proposal, per recipient on that bridge; refreshing the page does not send another. They wait about 15 minutes and collect into a digest, including decisions across your bridges. Large digests split into messages of at most 20 entries and 16 KiB each. Delivery failures get one retry; a server crash just after sending can cause a duplicate. Open the card for the current state, since someone may already have decided by the time you read the email.

You should see Email me when a decision is waiting and Save email setting on the bridge page. Clear the checkbox and save to turn these emails off for this bridge; check it and save to turn them back on. Turning these emails off discards notifications already queued for this bridge; turning them back on does not restore those notifications. Each email also has an "Unsubscribe from decision emails for <bridge>" link for each included bridge. The unsubscribe link is single-use and expires after 30 days. That link turns them off for that bridge; use the page to turn them on again.

Step 9. Connect your AI so it can propose and read

In the same project folder, run:

bridge setup

You should see a local report naming each check, the files written or left unchanged, and what was skipped. BRIDGE.md is always written. Other files depend on the tools found on PATH, project markers, or user config directories. A marker is evidence of tool settings, not proof that the tool is installed or connected. Restart your AI and check its Bridge connection. Nothing from these checks is sent anywhere, and setup never writes user-level settings.

If your tool was missed, run setup in its project. bridge setup --all writes all the legacy pointers. Re-running setup preserves existing Bridge blocks without rewriting unchanged files and removes Bridge-only blocks/adapters for tools no longer found. Your own content is preserved. Existing Codex project settings require a manual merge; Windsurf needs its MCP adapter added in the tool settings.

To explicitly start the watch loop after setup, run bridge setup --start-watch --wake "YOUR LOCAL AI COMMAND". Your AI will be woken when the other company sends something requiring its turn. This runs the command you chose on your machine. Keep that terminal open; press Ctrl+C to stop. Setup without these flags never starts the loop.

Restart your AI tool (Claude Code, Cursor, Windsurf, or any tool that reads .mcp.json) in that folder. It now has bridge tools: it can list and read contracts, open proposals, comment, counter, accept routine changes, and manage the shared task list. It cannot approve sensitive or indeterminate changes and cannot release holds. Those need you.

When a proposal involves money, the AI puts the price on it: bridge propose --price 12500.00 --currency USD ... (a counter may change it with the same flags). A priced proposal is never accepted by an AI, whatever its classification: it comes to you like a sensitive change, and your Approve also signs a mandate for exactly that amount, a receipt a payment rail can check offline (bridge mandate export <id>), never an instruction to pay.

A good first instruction to your AI: "Read BRIDGE.md, then check what is waiting for us on the bridge." It will run bridge proposal list --awaiting-me and report back.

The Tasks panel on the bridge page is read-only. As its note says, Manage locally: "Run bridge task add "Send logo", bridge task done <id>, or use your connected AI."

A hosted AI reaching your company's server.

Ask your server operator to do this in the project folder that has already joined

and completed the safety check. Choose an unused local port (8081 here) and replace

YOUR-HOST with the public hostname of your company's TLS proxy, without a scheme, path, or port:

bridge mcp token new
bridge mcp serve --http 127.0.0.1:8081 --behind-proxy YOUR-HOST

The first command creates a separate MCP access token and prints it once. Store it

privately in the hosted AI's connection settings as an Authorization header with

value Bearer followed by a space and the token. Running the command again replaces

the old token. This is not the relay connect token or the pairing secret.

Keep the second command running on your server. Have the company's TLS proxy forward

https://YOUR-HOST/mcp to 127.0.0.1:8081, preserving the public Host header. Configure

the hosted AI with that HTTPS address and its private token. This is a connection

from the hosted service, not a browser script; requests carrying an Origin header

are refused.

TLS is the operator's job: the bridge HTTP listener does not provide it.

For a configuration template, run:

bridge setup --hosted

This uses the same detection as local setup (use --all to override), adds the hosted-server

explanation, and adds a bridge-hosted HTTP entry in .mcp.json alongside the local

bridge entry. Replace https://YOUR-BRIDGE-SERVER/mcp and YOUR_MCP_TOKEN in the template

with your endpoint and private token. Do not commit or share the filled-in token.

The command writes a template; it does not start the server or configure TLS.

Each HTTP server is bound to the one workspace it was started in. The hosted AI

cannot choose another folder to reach a different bridge. It has the same human

approval limits as a local AI. Each token gets 120 MCP messages in any rolling

minute, including loopback traffic; each message in a batch counts separately.

Requests are limited to 1 MiB. If it reaches the message budget, the server returns

HTTP 429 with a Retry-After header telling the client how many seconds to wait.

A non-loopback address is refused with "non-loopback MCP HTTP requires --allow-plain-http".

If the operator explicitly supplies that flag, the warning is:

"Warning: TLS is the operator's job; prefer --http 127.0.0.1:8081 --behind-proxy YOUR-BRIDGE-SERVER behind your TLS reverse proxy."

Use the loopback recipe above for the normal setup.

Step 10. Keep your agent's signing key current

Run bridge status in your project folder to check the bridge and the key's expiry.

Within 30 days of expiry, or after it expires, it says:

"The agent signing key expires within 30 days or has expired; run bridge key rotate."

Run this in the same folder:

bridge key rotate

This creates and publishes a replacement agent signing key, switches this bridge

to it, and revokes the old agent key for future work. History signed by the old key

stays valid. Your company's root key and browser approval key are not replaced.

If rotation is interrupted, run the same command again to finish it.

To ask about a specific member, use bridge status get --party <party-slug>; an unknown name is refused with "no party named ... on this bridge" and the member list, rather than being mistaken for a silent partner.

You are done. From here on, your AI works in the room, and you only get involved when a card lands in Decision queue.

4. Things that look wrong but are fine

5. Things that ARE wrong: stop and tell your partner

6. Where things live and how to get help

writing to one would reach nobody - your bridge has exactly two companies in it and the human

who sent your invite is the right first call. If you are the one who created the bridge and you

are stuck, the project README names the maintainers.