# radicle-reticulum Bridges [Radicle](https://radicle.xyz) (decentralized Git) over [Reticulum](https://reticulum.network) mesh networking — LoRa, packet radio, serial, I2P, and more. `rad push` and `rad fetch` work normally. The bridge is transparent: radicle-node sees ordinary TCP peers, unaware it is talking over a mesh. --- ## Prerequisites - [Radicle](https://radicle.xyz/install) — `rad` CLI + `radicle-node` - [uv](https://docs.astral.sh/uv/getting-started/installation/) --- ## Install ```sh git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ cd radicle-reticulum uv sync ``` Optional — faster push detection (inotify, Linux/macOS): ```sh uv sync --extra watch ``` --- ## Quick start ### 1. Tell radicle-node to listen on localhost Edit `~/.radicle/config.json`: ```json "node": { "listen": ["127.0.0.1:8776"] } ``` Restart: ```sh rad node start rad node status # should show "listening … 127.0.0.1:8776" ``` ### 2. Start the bridge on both machines ```sh uv run radicle-rns bridge ``` The bridges announce themselves over RNS and discover each other within about a minute. When a peer is found its radicle NID is registered automatically: ``` [+] Discovered bridge: (NID: z6Mk...) ``` Once radicle-node connects through the tunnel: ``` Tunnel 1 opened [Status] Tunnels: 1, Remote bridges: 1, TX: 1551, RX: 1831 ``` ### 3. Use radicle normally ```sh # Machine A rad init --name myproject --description "" --default-branch main rad push # prints RID: rad:z3... # Machine B rad clone rad:z3... ``` That's it. `rad push`, `rad fetch`, and `rad sync` all work as usual — they talk to the local daemon, which syncs through the bridge. --- ## Reticulum interfaces On a LAN, Reticulum auto-discovers peers via UDP multicast — no config needed. For LoRa, serial, or I2P, edit `~/.reticulum/config`: ```ini [[lora_interface]] type = RNodeInterface port = /dev/ttyUSB0 frequency = 868000000 bandwidth = 125000 spreadingfactor = 7 codingrate = 5 ``` See the [Reticulum manual](https://reticulum.network/manual/) for the full interface list. Initial clones over LoRa are impractical (pack objects can be megabytes; LoRa is ~1–5 kbps). Clone over a fast link first, then sync incrementally over the mesh. --- ## Commands ``` radicle-rns bridge # TCP↔RNS bridge radicle-rns gossip [RID ...] # ref-change relay (auto-detected from CWD) radicle-rns setup # check prerequisites radicle-rns identity generate # create identity radicle-rns identity info # show DID and RNS hash ``` Global flags: `-v` verbose logging, `--identity PATH` (default `~/.radicle-rns/identity`). ### bridge flags | Flag | Default | Description | |------|---------|-------------| | `-l, --listen-port` | 8777 | Base TCP port for incoming radicle-node connections | | `--radicle-port` | 8776 | Port radicle-node listens on | | `-c, --connect ` | — | Connect to a specific bridge by RNS hash | | `--nid ` | auto-detect | Local radicle NID to announce | | `--no-auto-connect` | — | Disable auto-connect on discovery | | `--no-auto-seed` | — | Disable auto-registering remote NIDs | | `--announce-retry-delays` | 5,15,30 | Startup re-announce delays (seconds, comma-separated) | ### gossip flags | Flag | Default | Description | |------|---------|-------------| | `--nid` | auto-detect | Local radicle NID to advertise | | `--bridge-port` | 8777 | TCP port of the local bridge | | `--poll-interval` | 30 | Seconds between ref polls | --- ## How it works ``` radicle-node ─TCP─ RadicleBridge ──RNS Link── RadicleBridge ─TCP─ radicle-node (Machine A) (Machine A) (Machine B) (Machine B) │ │ GossipRelay ──RNS Packet── GossipRelay ``` The bridge tunnels radicle-node's TCP stream over an `RNS.Buffer` — an ordered, reliable channel that works across all Reticulum interfaces including LoRa. Reticulum handles peer discovery, routing, encryption, and retransmission transparently. The gossip relay is a lightweight side-channel (~300 bytes per event) that wakes peers when refs change, useful when the bridge TCP session is not yet live. --- ## Development ```sh uv run pytest # 97 tests uv run pytest -x -q # stop on first failure mypy src/ ```