radicle-reticulum/README.md

4.3 KiB
Raw Blame History

radicle-reticulum

Bridges Radicle (decentralized Git) over Reticulum 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


Install

git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ
cd radicle-reticulum
uv sync

Optional — faster push detection (inotify, Linux/macOS):

uv sync --extra watch

Quick start

1. Tell radicle-node to listen on localhost

Edit ~/.radicle/config.json:

"node": {
    "listen": ["127.0.0.1:8776"]
}

Restart:

rad node start
rad node status   # should show "listening … 127.0.0.1:8776"

2. Start the bridge on both machines

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: <hash>  (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

# 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:

[[lora_interface]]
  type = RNodeInterface
  port = /dev/ttyUSB0
  frequency = 868000000
  bandwidth = 125000
  spreadingfactor = 7
  codingrate = 5

See the Reticulum manual for the full interface list.

Initial clones over LoRa are impractical (pack objects can be megabytes; LoRa is ~15 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 <hash> Connect to a specific bridge by RNS hash
--nid <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

uv run pytest        # 97 tests
uv run pytest -x -q  # stop on first failure
mypy src/