diff --git a/radicle-decentralized-git/analysis.md b/radicle-decentralized-git/analysis.md new file mode 100644 index 0000000..1596377 --- /dev/null +++ b/radicle-decentralized-git/analysis.md @@ -0,0 +1,71 @@ +# Analysis — Radicle: Decentralized Git Network & Forge + +> Part of [[radicle-decentralized-git/index|Radicle — Decentralized Git Network & Forge]] + +## 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` + `allow` list of DIDs → selective replication (not encryption at rest). + +### 6. Collaborative Objects (COBs) +- Social artifacts (issues, patches, reviews) are Git commit **DAGs** under `refs/cobs//`. +- 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 `//`, with per-peer **Git namespaces** (`refs/namespaces//...`) sharing one object database. +- Users interact with a **working copy** + the node's **stored copy** via `git-remote-rad` over `rad:///` 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 +1. **Sovereignty redundancy**: public repos remain reachable even if greencloud-vps is down (other seeds) +2. **No fragmentation**: external collaborators without a Forgejo account can still clone/contribute over Radicle +3. **Agent-native collaboration**: COBs as programmable, signed objects — matches our durable-agent-runtime direction (agents as first-class participants) +4. **Low maintenance**: a seed node is a lightweight daemon; no web UI/CI/backup surface of a forge + +### What we give up / risks +1. **Discovery**: no GitHub-scale search; network effects still small +2. **Social layer maturity**: issues/patches UX younger than Forgejo's +3. **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) +4. **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 diff --git a/radicle-decentralized-git/index.md b/radicle-decentralized-git/index.md new file mode 100644 index 0000000..638fb6e --- /dev/null +++ b/radicle-decentralized-git/index.md @@ -0,0 +1,66 @@ +--- +title: Radicle — Decentralized Git Network & Forge +description: Research into Radicle (Heartwood), the peer-to-peer code collaboration network built on Git — nodes, gossip protocol, self-certifying repositories, Collaborative Objects (COBs), and whether a seed node is worth running beside our self-hosted Forgejo. +status: active +category: technical +tags: [radicle, p2p, decentralized, git, gossip, cofs, sovereign-forge, self-hosting, crdt, forgejo] +draft: true +created: 2026-08-09 +updated: 2026-08-09 +origin: buzz://d8a718be-031f-4a6e-9f5c-a55466641654/1491eaeeaf4e63b7e30e074b662309f78adcdd4a5420c74506af38dafbb61d39 +--- + +# Radicle — Decentralized Git Network & Forge + +## Summary + +Radicle is an open-source (MIT/Apache-2.0), peer-to-peer code collaboration stack built directly on Git. There is no central server or controlling entity: repositories replicate across peers, identities are Ed25519 keys (W3C DIDs), and every action is cryptographically signed. The current protocol generation is Heartwood (Rust, 1.10.0 as of 2026-08-05). Research goal: understand how it works and decide whether a Radicle seed node is worth running beside our existing self-hosted Forgejo. + +## Research Question + +How does Radicle's peer-to-peer protocol work under the hood, and is it worth serving a Radicle node alongside our Forgejo instance? + +## Scope + +- Protocol: nodes, gossip, transport, replication, identity, self-certification, COBs +- Comparison: GitHub/GitLab, self-hosted forges (Forgejo/Gitea), federated systems +- Deployment consideration: running a seed node on our NixOS infra beside Forgejo +- Excluded: the abandoned Radicle alpha (Haskell/IPFS), other decentralized git attempts in depth + +## Key Findings + +- **Every user runs a node.** Nodes are Ed25519 public keys (`did:key:...`), both client and server, seeding the repos they care about. No permission, email, or registry needed to join — the key is created offline. +- **Gossip for discovery, Git for data.** Three gossip message types (node announcements, inventory announcements, refs announcements) build routing tables; actual repo content transfers over the standard Git pack protocol, multiplexed over the same Noise XK-encrypted connection. Tor supported for IP anonymity. Bootstrap via two well-known nodes (iris, rosa). +- **Self-certifying repositories.** Each repo has an identity document (delegates, signature threshold) stored in Git; the RID (`rad:z3gqc...`) is the SHA-1 of that document. Every ref update is signed (`refs/rad/sigrefs`, TUF-inspired), so the whole history verifies without a trusted third party. The canonical branch is established dynamically: N-of-M delegates pushing the same commit defines the authoritative state. +- **Collaborative Objects (COBs)** — issues, patches, reviews are Git commit DAGs, not a database. They merge like CRDTs (causal order + deterministic reduce), so concurrent edits converge without a central server. New COB types are new namespaces under `refs/cobs/` — programmable collaboration, relevant for agent workflows. +- **Local-first and private**: everything works offline; private repos use an allow-list of peer DIDs (selective replication, not encryption at rest). `git-remote-rad` remote helper means plain `git push`/`fetch` over `rad://` URLs; jj works too. +- **vs alternatives**: solves the fragmentation problem of self-hosted forges (one network, no per-instance accounts), no admin can block you, seed nodes are interchangeable. Trade-offs: weaker discoverability/network effects than GitHub, social layer younger than a forge, availability depends on seeding peers. + +## Sources + +For the full reference list see [[radicle-decentralized-git/sources|Sources]]. + +## Detail Files + +- [[radicle-decentralized-git/sources|Sources]] — all references +- [[radicle-decentralized-git/analysis|Analysis]] — protocol deep-dive + Forgejo-vs-Radicle deployment verdict +- [[radicle-decentralized-git/next-steps|Next Steps]] — open questions, trial plan + +## Related Research + +- [[durable-agent-runtime/index|Durable Agent Runtimes & Harness Engineering]] — COB/agent-namespace angle; agents as signed first-class participants +- Workspace note: `RESEARCH/AMP_ORBS_REMOTE_DEV.md` (self-hosted infra philosophy) + +## Discussion + +User asked to research Radicle (radicle.network) after the durable-agent-runtime topic. Initial research delivered 2026-08-07; on 2026-08-09 user asked to separate Radicle into its own dedicated vault topic and to evaluate running it beside the existing Forgejo. + +## Next Steps + +- [ ] Trial a Radicle seed node on our infra (see next-steps.md) +- [ ] Mirror a public repo (e.g. research) to Radicle for network presence +- [ ] Revisit COB model for agent-driven collaboration if adoption grows + +## Conclusion + +Radicle is the "forge without the server": a sovereign, peer-to-peer git network where self-certifying repos and CRDT-like COBs give users full ownership of code and social artifacts. Verdict for our stack: worth a low-cost trial beside Forgejo (complementary roles), not a migration — Forgejo stays the primary forge (UI, CI, issues, private repos); Radicle adds decentralized presence, censorship resistance, and cross-instance collaboration. diff --git a/radicle-decentralized-git/next-steps.md b/radicle-decentralized-git/next-steps.md new file mode 100644 index 0000000..c55f1cd --- /dev/null +++ b/radicle-decentralized-git/next-steps.md @@ -0,0 +1,24 @@ +# Next Steps — Radicle: Decentralized Git Network & Forge + +> Part of [[radicle-decentralized-git/index|Radicle — Decentralized Git Network & Forge]] + +## Trial plan (seed node beside Forgejo) + +- [ ] Install Radicle (rad 1.10.0) on hermes-vm or greencloud-vps via Nix +- [ ] Initialize node identity key; back up the private key securely +- [ ] Publish one public repo (candidate: `research` vault or `idx-cli`) to the Radicle network +- [ ] Verify clone from a second machine / peer over `rad://` +- [ ] Evaluate: does anyone external find/use it? Is the seed node stable? + +## Decision triggers + +- [ ] External collaborator actually wants to contribute over Radicle → invest in dedicated clan-private seed service +- [ ] Agent-native collaboration via COBs becomes attractive → design a custom COB type for our workflows +- [ ] greencloud-vps outage showed Forgejo is a single point of failure → make Radicle mirror part of the resilience story + +## Open questions + +- [ ] Where should the seed run: hermes-vm (agent box, always-on) vs greencloud-vps (public services box)? +- [ ] Should public repos be dual-published (Forgejo + Radicle) or migrated? +- [ ] How does Radicle interact with our Forgejo mirroring automation (github-release, forgejo-repo-mirroring skills)? +- [ ] Nix packaging: is `radicle` in nixpkgs, or do we package the release binary? diff --git a/radicle-decentralized-git/sources.md b/radicle-decentralized-git/sources.md new file mode 100644 index 0000000..84665e1 --- /dev/null +++ b/radicle-decentralized-git/sources.md @@ -0,0 +1,43 @@ +# Sources — Radicle: Decentralized Git Network & Forge + +> Part of [[radicle-decentralized-git/index|Radicle — Decentralized Git Network & Forge]] + +Full reference list for the Radicle research topic. + +## Official + +- [radicle.network](https://radicle.network/) — the distributed code network landing page ("For humans and machines alike") +- [radicle.dev](https://radicle.dev/) — the sovereign forge: docs, install, guides, FAQ +- [Radicle Protocol Guide](https://radicle.dev/guides/protocol) — the definitive "how it works under the hood" document (nodes, gossip, replication, identity, COBs) +- [Radicle User Guide](https://radicle.dev/guides/user) — getting started, CLI usage +- [Radicle Heartwood repo (GitHub mirror)](https://github.com/radicle-dev/radicle-heartwood) — reference implementation, Rust, MIT/Apache-2.0 +- [Heartwood on Codeberg](https://codeberg.org/Radicle/Heartwood) — official mirror (codeberg.org/radicle/heartwood) +- [Radicle RIPs (Improvement Proposals)](https://radicle.network/nodes/seed.radicle.dev/rad:z3trNYnLWS11cJWC6BbxDs5niGo82) — protocol specification: RIP-1 (networking), RIP-2 (identity), RIP-3 (storage layout) +- [Radicle Garden](https://radicle.garden) — hosted always-on nodes ("Radicle Garden 🌱") +- [Radicle Desktop](https://radicle.dev/desktop) — graphical client (launched 2025-06) +- [Radicle Seeder's Guide](https://radicle.dev/guides/seeder) — how to run a seed node + +## Protocol / technical deep-dives + +- [LWN: Radicle — peer-to-peer collaboration with Git](https://lwn.net/Articles/966869) — independent technical overview of the protocol (motivation, gossip + git replication split) +- [Radicle Protocol Overview (Heartwood) — HackMD](https://hackmd.io/@radicle/rJ2UH54P6) — community protocol overview +- [gen.xyz: Peer-to-peer collaboration protocol Radicle.xyz](https://gen.xyz/blog/radicle-xyz) — background and history writeup +- [Secure Scuttlebutt (SSB)](https://en.wikipedia.org/wiki/Secure_Scuttlebutt) — inspiration for the gossip model +- [Noise protocol / XK pattern](https://noiseexplorer.com/patterns/XK/) — the transport encryption used between nodes (same pattern as Lightning) +- [W3C Decentralized Identifiers (DID) Core](https://www.w3.org/TR/did-core/) — node identity standard +- [The Update Framework (TUF)](https://theupdateframework.github.io/specification/latest/) — verification model inspiration for signed refs +- [Ink & Switch: Local-first software](https://www.inkandswitch.com/local-first/) — the local-first architecture principle Radicle follows + +## Related blog posts + +- [Jujutsu + Radicle = ❤️ (2025-08-14)](https://radicle.dev/blog/jujutsu) — jj integration angle +- [Canonical References (2025-08-12)](https://radicle.dev/blog/canonical-refs) — how canonical repo state works +- [Using Radicle CI for Development (2025-07-23)](https://radicle.dev/blog/radicle-ci) — CI usage on Radicle +- [How we used Radicle with GitHub Actions (2025-05-30)](https://radicle.dev/blog/radicle-github-actions) + +## Our context + +- Workspace note: `RESEARCH/AMP_ORBS_REMOTE_DEV.md` +- Vault topic: `durable-agent-runtime` (sibling research topic) +- Forgejo self-hosted at `git.rasyidanaf.com` (greencloud-vps) +- jj used across repos (jj + radicle compatibility relevant)