5.5 KiB
5.5 KiB
Analysis — Radicle: Decentralized Git Network & Forge
Part of radicle-decentralized-git/index
How the protocol works (deep dive)
1. Nodes and identities
- Every participant runs a node — a background daemon (
radicle-node) that is both client and server. - Identity = Ed25519 public key, encoded as a W3C DID (
did:key:z6Mk...). Generated offline; no email, no registry, no permission. - A node seeds repositories it is interested in; the seeding policy defines which repos it keeps and offers to the network.
- Always-on seed nodes (public or community) increase availability. Bootstrap via two well-known nodes (
iris.radicle.network,rosa.radicle.network) when the address book is empty.
2. Gossip protocol (discovery metadata)
Three signed, timestamped message types relayed between peers:
- Node announcements — broadcast Node ID + reachable addresses (peer discovery)
- Inventory announcements — broadcast which repositories a node hosts (routing table: repo → hosts)
- Refs announcements — broadcast repository updates, relayed only to interested nodes (
rid+ updated signed refs) - Dedup (drop seen messages) prevents infinite propagation; messages are replayed to newly-joined nodes.
- Every announcement carries the originating Node ID, a cryptographic signature, and a timestamp → peers verify before relaying.
3. Transport
- Noise XK handshake (same pattern as Lightning Network): nodes must know the peer's static key (their Node ID) before connecting — learned via gossip.
- Full forward secrecy after handshake. Tor addresses supported for IP anonymity.
4. Replication via Git
- Actual repository data transfers over the standard Git pack protocol (fetch/negotiation).
- Framing/multiplexing lets gossip + git fetch coexist over one physical connection — efficient, avoids NAT issues.
5. Self-certifying repositories
- Repo identity document (canonical JSON) under
refs/rad/id: delegates (DIDs), signature threshold, name/description/defaultBranch. - RID =
rad:+ base58btc(SHA-1 of the initial identity document) — stable even as the doc evolves. - Every ref change is signed into
refs/rad/sigrefs(a Git blob listing refs + OIDs). Anyone can verify the full history from the RID + clone — no trusted third party (TUF-inspired). - Canonical branch: the default branch's authoritative state = the commit that N-of-M delegates have pushed (threshold from identity doc). Not a server rule — a cryptographic quorum.
- Private repos:
visibility: private+allowlist of DIDs → selective replication (not encryption at rest).
6. Collaborative Objects (COBs)
- Social artifacts (issues, patches, reviews) are Git commit DAGs under
refs/cobs/<type>/<id>. - Convergent like CRDTs: union of histories + topological (causal) reduction + deterministic merge. Concurrent edits converge without a server.
- Three built-in types: issues (
xyz.radicle.issue), patches (xyz.radicle.patch), identities (xyz.radicle.id). New types = new namespaces — fully programmable.
7. Storage layout
- All repos are bare Git repos under
<storage>/<rid>/, with per-peer Git namespaces (refs/namespaces/<nid>/...) sharing one object database. - Users interact with a working copy + the node's stored copy via
git-remote-radoverrad://<rid>/<nid>URLs. - Offline work is first-class: pushes/fetches happen whenever the node is connected.
Forgejo vs Radicle — should we run both?
Complementary roles (not replacements)
- Forgejo (current): mature forge experience — web UI, issues/PRs, CI (Forgejo Actions), mirroring, private repos, admin control, Forgejo API for our agents.
- Radicle: decentralized network presence — no server to maintain, censorship-resistant, cross-instance collaboration, COB programmability, jj-friendly.
What we gain from a Radicle node
- Sovereignty redundancy: public repos remain reachable even if greencloud-vps is down (other seeds)
- No fragmentation: external collaborators without a Forgejo account can still clone/contribute over Radicle
- Agent-native collaboration: COBs as programmable, signed objects — matches our durable-agent-runtime direction (agents as first-class participants)
- Low maintenance: a seed node is a lightweight daemon; no web UI/CI/backup surface of a forge
What we give up / risks
- Discovery: no GitHub-scale search; network effects still small
- Social layer maturity: issues/patches UX younger than Forgejo's
- Availability: our own repos are only reachable while some seed is online — so we'd want our seed always-on (hermes-vm or greencloud-vps)
- Another protocol surface: new key material, new daemon, new storage dir to back up
Verdict
Worth a trial, not a migration. Run a Radicle seed node on hermes-vm (or greencloud-vps) beside Forgejo, mirror public repos for presence, keep Forgejo as the primary forge. Decision to invest deeper (dedicated seed service in clan-private, COB-based workflows, moving a project's issue tracking) only after an external collaborator actually uses Radicle.
Notes for our stack
- Radicle CLI + daemon installable via Nix; seed node needs a stable identity key (back it up!)
- jj interop works via
rad://remotes - Keep private repos on Forgejo (Radicle private = selective replication, not encryption; Forgejo private + access control is simpler for our use)
- Radicle Garden is the hosted option if we don't want to run our own seed — but self-hosting matches our sovereignty principle