From 6a119055009b16360ac2ad19b8d8d87b9c0312b8 Mon Sep 17 00:00:00 2001 From: "Maciek \"mab122\" Bator" Date: Fri, 24 Apr 2026 11:01:15 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20simplify=20README=20=E2=80=94=20one=20m?= =?UTF-8?q?ode,=20remove=20seed=20section?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the "two modes" framing and always-on seed quickstart; seed setup is standard radicle-node configuration, not part of this codebase. Remove --lora references and dead commands. Keep quickstart, interface config, and architecture note. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 215 +++++++++++++++++++----------------------------------- 1 file changed, 77 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 17d778d..9f6e7f9 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,27 @@ # radicle-reticulum -Bridges [Radicle](https://radicle.xyz) (decentralized Git) over [Reticulum](https://reticulum.network) mesh networking — LoRa, packet radio, serial, I2P, and more. Enables offline-first code collaboration without internet infrastructure. +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`) +- [Radicle](https://radicle.xyz/install) — `rad` CLI + `radicle-node` - [uv](https://docs.astral.sh/uv/getting-started/installation/) -- Git --- ## Install ```sh -git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ # via radicle -# or: git clone https://github.com/youruser/radicle-reticulum +git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ cd radicle-reticulum uv sync ``` -Optional: faster push detection (inotify-based, Linux/macOS): +Optional — faster push detection (inotify, Linux/macOS): ```sh uv sync --extra watch @@ -29,21 +29,9 @@ uv sync --extra watch --- -## Two modes +## Quick start -### Bridge mode — peer-to-peer - -Each machine runs a bridge. They discover each other over RNS, then radicle-node syncs through the tunnel as if both nodes were on the same network. - -### Seed mode — always-on relay - -One machine runs a dedicated seed radicle-node plus a bridge. Other machines' bridges discover and register the seed automatically. The seed self-populates: it calls `rad seed ` for any repo announced by gossip peers. - ---- - -## Quick start: bridge mode - -### Step 1 — Configure radicle-node to listen on localhost +### 1. Tell radicle-node to listen on localhost Edit `~/.radicle/config.json`: @@ -53,34 +41,33 @@ Edit `~/.radicle/config.json`: } ``` -Restart radicle-node: +Restart: ```sh rad node start -rad node status # "listening for inbound connections on 127.0.0.1:8776" +rad node status # should show "listening … 127.0.0.1:8776" ``` -### Step 2 — Start the bridge on both machines +### 2. Start the bridge on both machines ```sh uv run radicle-rns bridge ``` -Within ~30 s the bridges discover each other via RNS announce, connect automatically, and register each other's NIDs with radicle-node: +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...) -[Status] Tunnels: 0, Remote bridges: 1, TX: 0, RX: 0 ``` -Once radicle-node syncs through the bridge: +Once radicle-node connects through the tunnel: ``` Tunnel 1 opened [Status] Tunnels: 1, Remote bridges: 1, TX: 1551, RX: 1831 ``` -### Step 3 — Use radicle normally +### 3. Use radicle normally ```sh # Machine A @@ -91,122 +78,13 @@ rad push # prints RID: rad:z3... rad clone rad:z3... ``` ---- - -## Quick start: seed mode - -Run this once to initialise the seed identity: - -```sh -uv run radicle-rns setup # checks prerequisites and prints instructions -RAD_HOME=~/.radicle-seed rad auth -``` - -Then start the seed (keeps running, restarts cleanly): - -```sh -uv run radicle-rns seed -``` - -Other machines running `radicle-rns bridge` (or `seed`) discover the seed automatically over RNS. The seed begins tracking any repo announced by gossip peers. - -Register the seed in your local radicle-node (one-time, per machine): - -```sh -rad node connect @127.0.0.1:8777 -``` - -The seed NID is printed by `radicle-rns seed` on startup. - ---- - -## Gossip relay - -The gossip relay watches local Radicle storage for ref changes and sends small notifications (~100–200 B) to peer relays over RNS. On receipt, the peer calls `rad sync --fetch` against the announcing node. Seed mode enables gossip automatically; for bridge mode run it separately: - -```sh -uv run radicle-rns gossip rad:z3... # auto-detected from CWD if omitted -``` - -Gossip broadcasts only the changed refs (delta mode), so a one-commit push sends ~120 B instead of the full ref list. - ---- - -## Commands - -``` -radicle-rns bridge # TCP↔RNS bridge -radicle-rns seed # dedicated seed node + bridge + gossip -radicle-rns gossip [RID ...] # standalone gossip relay -radicle-rns setup # check prerequisites, print fix instructions -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 (first discovered bridge gets this) | -| `--radicle-port` | 8776 | Port radicle-node listens on | -| `-c, --connect ` | — | Connect to a specific remote bridge by RNS hash | -| `--nid ` | auto-detect | Override local radicle NID | -| `--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) | - -### seed flags - -| Flag | Default | Description | -|------|---------|-------------| -| `--seed-home` | `~/.radicle-seed` | RAD_HOME for the seed radicle-node | -| `--seed-port` | 8776 | TCP port for the seed radicle-node | -| `--bridge-port` | 8778 | TCP listen port for the seed bridge | -| `--poll-interval` | 30 | Seconds between gossip ref polls | - -### 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 | - ---- - -## Architecture - -``` -radicle-node ─TCP─ RadicleBridge ──RNS Link── RadicleBridge ─TCP─ radicle-node - (Machine A) (Machine A) (Machine B) (Machine B) - │ │ - GossipRelay ──RNS Packet── GossipRelay -``` - -Each discovered remote bridge gets its own OS-assigned TCP listen port, so radicle-node connections always route to the correct peer. The tunnel uses `RNS.Buffer` over `RNS.Channel` for ordered, reliable delivery — Reticulum handles retransmission transparently across all interface types including LoRa. - -- **`identity.py`** — Ed25519 DID ↔ RNS identity; saved to `~/.radicle-rns/identity` -- **`bridge.py`** — TCP↔RNS tunnel via `RNS.Buffer`, per-bridge port allocation, path maintenance -- **`gossip.py`** — ref-change notifications, delta broadcasts, auto-seed for unknown repos -- **`seed.py`** — dedicated radicle-node process lifecycle (separate RAD_HOME) - ---- - -## Development - -```sh -uv run pytest # 97 tests -uv run pytest -x -q # stop on first failure -mypy src/ # type check -``` +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 the same LAN, Reticulum auto-discovers peers via UDP multicast — no config needed. For LoRa / serial / I2P, edit `~/.reticulum/config`: +On a LAN, Reticulum auto-discovers peers via UDP multicast — no config needed. For LoRa, serial, or I2P, edit `~/.reticulum/config`: ```ini [[lora_interface]] @@ -219,3 +97,64 @@ On the same LAN, Reticulum auto-discovers peers via UDP multicast — no config ``` 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/ +```