docs: simplify README — one mode, remove seed section

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 <noreply@anthropic.com>
This commit is contained in:
Maciek "mab122" Bator 2026-04-24 11:01:15 +02:00
parent 63267e5789
commit 6a11905500
1 changed files with 77 additions and 138 deletions

215
README.md
View File

@ -1,27 +1,27 @@
# radicle-reticulum # 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 ## 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/) - [uv](https://docs.astral.sh/uv/getting-started/installation/)
- Git
--- ---
## Install ## Install
```sh ```sh
git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ # via radicle git clone rad:z4NMdcKbw2TETQ56fbQfbibFHtZqZ
# or: git clone https://github.com/youruser/radicle-reticulum
cd radicle-reticulum cd radicle-reticulum
uv sync uv sync
``` ```
Optional: faster push detection (inotify-based, Linux/macOS): Optional — faster push detection (inotify, Linux/macOS):
```sh ```sh
uv sync --extra watch uv sync --extra watch
@ -29,21 +29,9 @@ uv sync --extra watch
--- ---
## Two modes ## Quick start
### Bridge mode — peer-to-peer ### 1. Tell radicle-node to listen on localhost
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 <RID>` for any repo announced by gossip peers.
---
## Quick start: bridge mode
### Step 1 — Configure radicle-node to listen on localhost
Edit `~/.radicle/config.json`: Edit `~/.radicle/config.json`:
@ -53,34 +41,33 @@ Edit `~/.radicle/config.json`:
} }
``` ```
Restart radicle-node: Restart:
```sh ```sh
rad node start 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 ```sh
uv run radicle-rns bridge 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: <hash> (NID: z6Mk...) [+] Discovered bridge: <hash> (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 Tunnel 1 opened
[Status] Tunnels: 1, Remote bridges: 1, TX: 1551, RX: 1831 [Status] Tunnels: 1, Remote bridges: 1, TX: 1551, RX: 1831
``` ```
### Step 3 — Use radicle normally ### 3. Use radicle normally
```sh ```sh
# Machine A # Machine A
@ -91,122 +78,13 @@ rad push # prints RID: rad:z3...
rad clone rad:z3... 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.
## 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 <SEED_NID>@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 (~100200 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 <hash>` | — | Connect to a specific remote bridge by RNS hash |
| `--nid <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
```
--- ---
## Reticulum interfaces ## 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 ```ini
[[lora_interface]] [[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. 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 ~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
```sh
uv run pytest # 97 tests
uv run pytest -x -q # stop on first failure
mypy src/
```