F Forge Project Guide

Companion Transport

Forge uses its own Iroh and QUIC path for iPhone pairing.

The quickstart stays one command. This page is the deeper view: what starts on the desktop, what the QR contains, how the phone finds the machine, where relays fit, how Forge frames API requests, and why the protocol is called forge-companion/1.

npx forge-memory
npx forge-memory pair-ios

Quick Path

The base install does not ask users to understand transport internals.

Default user flow

Users run npx forge-memory. Forge installs the local runtime, discovers host adapters, keeps one data folder explicit, and offers iPhone pairing from the same guided flow.

npx forge-memory

Later pairing

If Forge is already installed, pairing can be reopened without repeating setup. This prints the default Iroh QR and transport diagnostics.

npx forge-memory pair-ios

Network Model

The phone dials a desktop identity, not a changing IP address.

What starts on the desktop

Forge starts the repo-owned Rust host forge-companion-iroh. The host creates or reloads an Iroh secret key under the Forge data root, derives a stable node id, registers ALPN forge-companion/1, and proxies authenticated stream requests into the local Fastify runtime.

What the iPhone dials

The QR gives the iPhone a node id, token, optional relay hint, and forge-iroh:// URLs. The Swift app links the same Rust transport core as a native static library, dials that node id through Iroh, and sends Forge request envelopes over QUIC streams.

Relay reality

Iroh still uses public rendezvous and relay infrastructure. That replaces the need for the user to install Tailscale, open a router port, or maintain a public Forge URL. It does not remove the need for a public meeting point.

Direct path when possible

Iroh can use relay-assisted NAT traversal to attempt direct encrypted QUIC. If the network blocks that path, encrypted QUIC traffic can stay relayed. The relay is not the Forge app server and does not need Forge's database.

Pairing Payload

The QR is a connection recipe, not just a URL.

{
  "apiBaseUrl": "forge-iroh://<node-id>/api/v1",
  "uiBaseUrl": "forge-iroh://<node-id>/forge/",
  "transportMode": "iroh",
  "transport": {
    "protocol": "iroh",
    "provider": "forge-companion-iroh",
    "status": "ready",
    "nodeId": "<node-id>",
    "relay": "https://relay.example",
    "alpn": "forge-companion/1",
    "agent": "forge",
    "pairPayload": {
      "v": 1,
      "node_id": "<node-id>",
      "token": "<pairing-token>",
      "host_name": "desktop-name",
      "relay": "https://relay.example"
    }
  }
}

Node id

The stable public-key identity of the desktop Iroh endpoint. It remains the durable target even when the current IP changes.

Pairing token

The app-level secret. The first stream frame must prove the phone scanned the current QR before Forge accepts requests.

ALPN

The QUIC protocol selector. Forge uses forge-companion/1 so this is clearly Forge's protocol, not KittyLitter or Alleycat.

Wire Protocol

Forge carries existing API requests over authenticated QUIC streams.

Step Message Responsibility
1 connect frame First JSON frame includes version, pairing token, and agent forge.
2 ok frame Desktop host validates the token and accepts or rejects the stream.
3 HTTP request envelope iPhone sends method, path, headers, and base64 body for a Forge API route.
4 HTTP response envelope Rust host proxies to Fastify and returns status, headers, and base64 body.

Fallbacks

Manual HTTP remains available, but it is no longer the default.

Use Iroh first

The default QR path should be Iroh. It avoids forcing users to install a VPN app, configure port forwarding, or copy a LAN address that breaks when the network changes.

Use HTTP deliberately

Direct HTTP/TCP is still useful for known LAN hosts, Tailscale operator setups, and debugging. It is an explicit mode.

npx forge-memory pair-ios --manual-http

License Boundary

Forge owns this protocol and keeps the code permissive.

Forge license

Forge-owned public code is Apache-2.0. That keeps the open source project permissive, patent-explicit, and compatible with future closed-source commercial Forge forks.

Upstream boundary

Alleycat and KittyLitter were studied for the Iroh pairing pattern. Forge does not vendor, link, copy, or name its protocol after Alleycat. The protocol label is forge-companion/1.

Verification

Transport changes should be checked at Rust, TypeScript, server, and iOS layers.

cargo fmt --manifest-path companion-iroh/Cargo.toml --check
cargo test --manifest-path companion-iroh/Cargo.toml
cargo build --release --manifest-path companion-iroh/Cargo.toml --bin forge-companion-iroh
npx tsc --noEmit
npm run check:server
npm run test:forge-memory

iOS bridge changes should also build and test ios-companion/ForgeCompanion.xcodeproj. Dependency installs should stay deliberate; most local checks can use the already installed toolchains and packages.