Radish alpha
r
rad:z371PVmDHdjJucejRoRYJcDEvD5pp
Radicle website including documentation and guides
Radicle
Git
End of Year Roadmap – 2025
Archived fintohaps opened 7 months ago
2 files changed +612 -0 0a489a76 c076434a
added _posts/2025-09-16-roadmap.md
@@ -0,0 +1,611 @@
+
---
+
title: "End of Year Roadmap – 2025"
+
image: radicle-1.png
+
layout: blog
+
---
+

+
## The Road Ahead
+

+
After the initial 1.0 release, the team was busy polishing certain aspects of
+
the Radicle tooling and stack. This work resulted in 1.1, 1.2, 1.3, and most
+
recently 1.4. We can really feel the momentum, and we could not have done it
+
without the help from contributors also weighing in on the discussion and
+
submitting patches.
+

+
We are close approaching the anniversary of that first release, and as the
+
project matures, we wanted to take this opportunity to share a roadmap with you.
+
The aim is to provide some transparency towards what we want to work on, and to
+
also help contributors focus their attention on ongoing topics.
+

+
This is not necessarily a commitment to getting this work done within a certain
+
time frame. We will always try to aim to work on features and fixes that will
+
provide the best experience for you and ourselves.
+

+
Without further ado, let's put on our cartographer hats on and map out the
+
direct of the Radicle protocol over the coming months!
+

+
## Project Management
+

+
First things first, we'll discuss some general management of the project itself.
+
We want to touch on our release management process and how we will practice
+
cutting new releases and maintaining patch versions going forward.
+

+
### Release Management
+

+
The Radicle Protocol team are aiming to improve their release process going
+
forward. The previous process has got us this far, but we feel like it's time to
+
take the next step towards more mature workflows.
+

+
First, we will quickly discuss the current release process. As a maintainer,
+
@fintohaps has been using the scripts that are available in `heartwood`:
+
`build/tag`, `build/build`, `build/upload`, and `build/release`. In order, these
+
scripts achieve tagging a commit for release, building the binaries – via
+
`cargo-zigbuild` for cross-compilation, uploading the binaries to our file
+
server, and finally, marking a binary as the latest. This uses @fintohaps' key
+
material for signing and verification, and unfortunately, ties the whole process
+
to them. Before the advent of canonical references, it also meant that it was
+
tied their particular namespace. The final note here is that we would only
+
release under minor versions and never attempt to create patch or hotfix
+
releases.
+

+
Proceeding forward, we want to tackle each of these problems to grow towards a
+
healthier release process. The goal is to have a rotating release maintainer.
+
For this to happen, the team will share a release signing key. This will be used
+
to sign the tags for the releases, and can be used by others to verify our
+
releases. For historical releases, we will ensure to list the older keys that
+
were used to build them – which will also pave the way for rotating the release
+
signing key.
+

+
We will also begin to release patch and hotfix versions. The process will be
+
based on a contributors suggestion, and blog post ([How to Do Releases]) –
+
thanks Matthias. When a Radicle patch provides a fix or improvement that is
+
considered a hotfix or patch, then the release maintainer will apply to a branch
+
`releases/1.x`, where `x` is the minor version they are patching. They can then
+
tag a new patch release, while also creating a `CHANGELOG` entry that is patched
+
to the `master` branch – describing the changes in the patch release.
+

+
Note that these versions only apply to the versions of the binary releases. For
+
the crates in `heartwood`, we will use `cargo-semverchecks` to detect version
+
changes and release the crates every 2 weeks. We will start to explore tools
+
like `cargo-release` and/or `cargo-smart-release` for making the process of
+
releasing the crates more easier for the team.
+

+
If you have any further suggestions, please reach out to us on [Zulip]!
+

+
### Yanking `iris` and `rosa`
+

+
The Radicle run seed nodes, `rosa.radicle.xyz` and `iris.radicle.xyz`, are set
+
up to be permissive nodes in the network. This has been a great experience for
+
users coming to Radicle for the first time. They immediately have nodes that
+
replicate their projects. Another benefit of this is that we are able to see how
+
permissive nodes behave and can inspect their logs more easily.
+

+
That being said, they are nonetheless a maintenance burden that we, as a team,
+
do not want to maintain forever.
+

+
Going forward, we will be working on reducing how permissive these nodes. Part
+
of this work relates to [bootstrapping] as well as [policy improvements]. We
+
will use these nodes to test these features and slowly, but surely, remove them
+
from the network. Do not worry, we will give ample time and plenty of
+
announcements on more concrete timelines for when this will be underway.
+

+
## Protocol & Node
+

+
Now for the juicy parts. Over the past few months, the team has been chipping
+
away at a few larger topics regarding the protocol and the `radicle-node`. On
+
top of this, we also met in Helsinki recently and discussed a few potential
+
topics for the roadmap. Below are the bigger topics that generally touch the
+
protocol and the node.
+

+
### Identity and Multi-Device
+

+
These topics are on the mind of every maintainer, contributor, and user of
+
Radicle. These topics are closely related but can be thought of as two different
+
beasts. On the one hand, multi-device would mean that any user of Radicle could
+
work across multiple devices without any issues. This includes using the same
+
key on two different devices (looking at you YubiKey holders), or associating
+
different keys to the same person. The latter begins to sound a lot more like
+
identity, where one person is not identified by a single key, and should be able
+
to move that identity around with them.
+

+
Currently, when someone comes to the Radicle protocol and runs `rad auth` this
+
generates their signing key. This is used in a myriad of ways:
+

+
- The public portion of the key is used as the Node ID
+

+
- Which, in turn, is used as part of protocol handshakes
+

+
- It also identifies your namespace within a Radicle repository, e.g.
+
  `refs/namespaces/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/refs/heads/main`
+

+
- The current DID being used is `did:key` which is derived from the signing key
+

+
- The signing key is, naturally, also used for signing data including:
+
  - `rad/sigrefs` – to tell the network that these are the state of your
+
    references
+
  - Changes to collaborative objects
+
  - Announcements, which can be verified by other nodes to ensure that the message
+
    came from you
+

+
You may notice that this closely ties a node's identity to a user while also
+
mixing the responsibility of the user signing data and the node signing data.
+

+
As you can see, while these decisions got us up and running quicker, it has come
+
with consequences. On top of this, we declared a 1.0 for the protocol, and so we
+
have a duty to attempt to transition towards identity in a backwards-compatible
+
way.
+

+
One of our main tasks will be to slowly provide a separation from the node's key
+
and the user's key. Some of this work is already underway and is happening with
+
backwards-compatibility. This may help us towards a story of multi-device, but
+
we still have some constraints around signing references that blocks us on that
+
front.
+

+
Our other task will be exploring key management systems (KMS) for allowing us to
+
revoke and rotate keys of a user. The astute reader will notice that `did:key`
+
does not provide a way to this – its a self describing DID method, and so it
+
*cannot* provide these functionalities. Currently, we are interested in two key
+
management systems and exploring their functionality: [Keyhive] and
+
[BetterSign]. However, the introduction of one of these systems is not as simple
+
as plugging it in and getting key revocation and rotation. We also need to plan
+
how those operations play with the current data that we are signing. Some harder
+
questions need to be answered:
+

+
- How do we continue to verify historical data?
+
- How do we handle revoked data that has been signed by a compromised key?
+
- How do we evolve the Git namespaces when a new key is introduced?
+
- Can we do this in a backwards-compatible fashion?
+

+
Finally, we want to provide a consistent identity for a person (or more
+
generally an agent – no, not AI) that acts within the Radicle network. For this,
+
we have started to draft a [RIP][Agent Repository RIP] that describes a way for
+
us to represent an identity that could be communicated using the Radicle
+
protocol. This draft needs to be further developed and tested with an
+
implementation in the `heartwood` repository.
+

+
Admittedly, due to the size of these problems, the consequences of making these
+
changes, and its lasting implications on the protocol we have moved a bit slower
+
on this front. It has, however, never been forgotten and we will continue to
+
push towards an implementation for identity and multi-device.
+

+
### Migration of network I/O in `radicle-node` to `mio`
+

+
[Migration to mio]: #Migration-of-network-IO-in-radicle-node-to-mio
+

+
The crates [`netservices`], [`io-reactor`], and [`popol`] have served us well to
+
implement `radicle-node`. However, they are not ideal dependencies for ensuring
+
long-term health of our network I/O layer:
+
- [`popol`] is only intended to support Unix-like platforms, and we are looking
+
  to support other platforms, like [Windows].
+

+
- Even though `io-reactor` defines the trait [`reactor::poller:Poll`] to
+
  potentially support multiple I/O polling mechanisms, there only is one single
+
  implementation for wrapping `popol`. Issues for other polling crates are open
+
  since 2023 without tangible progress: [#10 for `mio`], [#9 for `polling`], [#8
+
  for `epoll`]. This suggests that it is not a high priority for the maintainers
+
  to integrate with other polling abstractions (which might offer better
+
  cross-platform compatibility).
+

+
- The trait [`reactor::poller:Poll`] can only be implemented for file
+
  descriptors which also implement [`std::os::fd::raw::AsRawFd`] and this trait
+
  is only implemented on Unix-like platforms and WASI. We believe that this is
+
  leaked from `popol` as the only known implementation of the trait wraps it.
+

+
- We would like to benefit from network effects, i.e. from other people
+
  maintaining crates that depend on `io-reactor` to implement support for other
+
  pollers. However, [according to crates.io, the only dependent is
+
  `radicle-node`][io-reactor-dependents] (via `netservices`). Contrary to that,
+
  at the time of writing, [`mio` has 494 dependents according to
+
  crates.io][mio-dependents], and, notably, [`tokio`, which has 30628 dependents
+
  on crates.io, is dependent on `mio`][tokio-dependents]. We therefore think
+
  that even if `mio` is obsoleted, e.g. by [`a10`] (which is based on
+
  [`io_uring`] on Linux and could potentially build on top of [I/O rings on
+
  Windows]) the people behind a large network of dependent projects will come up
+
  with new ideas and solutions, that we would then benefit from.
+

+
- One downside of `mio` is that it forces the use of [`mio::Token`] to identify
+
  sources (while a type that is `Eq + Clone` might be enough), and that it
+
  forces the use of the types in [`mio::net`] for sockets, which need to be
+
  converted to/from [`std::net`] if required. These distinctions are also [noted
+
  by cloudhead]. We are willing to buy in that far to `mio` to leverage the
+
  benefits of a well-tested and cross-platform network I/O layer.
+

+
A proof-of-concept is submitted as [patch `5ea90b97`].
+

+
### Windows Compatibility
+

+
[Windows]: Windows Compatibility
+

+
If we truly want Radicle to succeed, it is necessary that we attempt to provide
+
the technology to as many people as we can. This should include Windows users.
+

+
A pure Windows build of the `heartwood` repository has not been a number one
+
priority for the team since we started. The fact is that none of the team used
+
Windows, with the majority of us on a flavour of Linux and a few MacOS users.
+
That did not stop some interested users on Windows coming along and asking
+
questions!
+

+
More recently, a team member who has access to a Windows machine has started to
+
slowly get some parts of the system working on Windows[^1][^2][^3]. This has
+
allowed some interaction with Radicle via the `rad` CLI, and started paving the
+
way to getting the `radicle-node` to also build. To get to that, we need to make
+
some changes to not rely on Unix specific utilities and take control of the
+
underlying networking libraries and house changes to them within `heartwood` –
+
with a draft patch already in place (See [Migration to mio]).
+

+
We also want to ensure that once we have Windows compatibility in place, that we
+
do not easily lose it. We will move towards testing more strictly in CI and have
+
a target that checks the builds on Windows. This will place Windows as a "second
+
tier" platform within our ecosystem – meaning we will try support it, but it
+
will not always be our first priority.
+

+
### Road to a Sans-I/O Protocol
+

+
While diving deeper into the `radicle-node` protocol, we realised that we were
+
finding it hard to understand and modify the innards of the protocol code. The
+
logic of what happens in the protocol was tied to the I/O of calling to the
+
network, modifying sqlite databases, etc. At that point, we decided that it was
+
time to explore [Sans-I/O].
+

+
This effort has already begun. The first step was moving the majority of the
+
code from `radicle-node` into a new `radicle-protocol` crate. This kept the
+
majority of the code as-is, but removed any dependencies on any crates that were
+
required to perform I/O. These were plugged in via `radicle-node`. This was only
+
the beginning.
+

+
To better understand these techniques, we have also made efforts to separate
+
"business logic" away from I/O in smaller components of our code base. This has
+
been a great process and has resulted in code that is easier to reason about
+
*and* easier to test. This may be obvious to most people, but sometimes as
+
programmers, we cut corners to get to a result faster – and one of those corners
+
is mixing our business logic with I/O.
+

+
We have already started working towards a sans-I/O [implementation of the
+
protocol][Sans-I/O Patch]. We have been dissecting the code that is in
+
`radicle-protocol`, and finding components that have a single responsibility.
+
These components are being defined using an event and command architecture.
+
These components will then be composed to have an architecture that can be
+
driven by commands and will output events – which can then be logged, made into
+
metrics, notify the user, etc.
+

+
Once this has been sketched and tested, we plan on having a version of
+
`radicle-node` that uses this version of the protocol and ensure that it has
+
compatibility with the previous version.
+

+
From this point on, we will aim to explore how this helps us improve the
+
protocol. We will explore the possibility of new protocol messages, and better
+
error handling for Git fetches. As well as this, we want to explore different
+
networking libraries such as [`iroh`] and [`libp2p`].
+

+
### Policy Improvements
+

+
[policy improvements]: #policy-improvements
+

+
The team was thinking about ways to improve node storage management and
+
moderation. One of the team noted a mode of behaviour that could be implemented
+
that was dubbed quarantining, at the time. The basic idea is that a node could
+
say it wants to fetch a repository but not advertise it as part of its own
+
inventory. Put another way, the repository is in storage, but it is not being
+
announced to the network.
+

+
So, what is the value of this mode of operation? Once this repository has been
+
fetched, it means that it can be inspected to evaluate whether the node operator
+
wishes to announce it as part of the node's inventory. If the repository is
+
deemed worthy, then it can be promoted to be seeding, and if not, then it can be
+
blocked.
+

+
Node operators can begin to ask questions like:
+
- How big is this repository?
+
- Can I detect illicit content in this repository?
+
- Are the delegates part of my follow list?
+
- Is this a Rust project?
+
- etc.
+

+
Essentially, this provides enough power to the operator, and the general
+
ecosystem as a whole, to begin experimenting with their own kinds of moderation
+
and node management.
+

+
The idea did not stop there. As we tugged on this concept more, we started to
+
compare it more to the existing behaviour. The existing modes are "seed" and
+
"block". The former says that the node will fetch and announce the repository,
+
while the latter says it will ignore it completely. We were now proposing a mode
+
that is only fetching, and we began to wonder about a mode that would only be
+
announce. After considering these different modes, potential use cases, and
+
playing around with wording, we came to the conclusion that this concept seems
+
to lie close to a [publish-subscribe] method. The repository is a topic,
+
fetching is subscribing, announcing is publishing, and we have the option to
+
block the topic.
+

+
After this brief foray into thought, we have decided to formalise a RIP for
+
improving policies and explore the implementation in `heartwood`. The change to
+
the node behaviour seems to be straight-forward, however, the CLI tooling and
+
terminology seems to be the more challenging portion of this set of changes.
+

+
### Reaping Repositories
+

+
It has been a common occurrence that someone decides to try out Radicle, and
+
they test it out on a repository – with an apt name, such as
+
`radicle-test`[^4][^5][^6]. The next question on their mind is, "How do I
+
delete this repository?" They don't see an immediate answer in the set of `rad`
+
commands, and they ask the same question in our [Zulip]. Unfortunately, up
+
until this point, there has been no mechanism for deleting a repository.
+

+
Initially, we punted on it because in a decentralized network, you cannot go
+
around to each machine and delete content – that would be censorship
+
susceptible[^7]. After some thought, we decided that we could implement a
+
mechanism where one could *ask* for their repository to be deleted.
+

+
The basis of this feature is to define a payload extension for the identity
+
document, that could be added to set an expiry date for the repository. Other
+
nodes and node operators can then decide, based on the expiry, to reap the
+
repository from their storage, and block it so that they would not replicate it
+
again. Essentially, if you wanted to delete the repository, then you would set
+
the expiry to the current date-time and announce that to the network.
+

+
The aim for this feature is to provide this basic mechanism and supplement it
+
with tooling through the `rad` CLI so that a node operator can easily detect
+
expired repositories, and a user can ensure that their repository continues to
+
live or die in the Radicle network.
+

+
### Bootstrapping
+

+
[bootstrapping]: #bootstrapping
+

+
To get things up and running, the Radicle team put together seed nodes – now
+
called `rosa.radicle.xyz` and `iris.radicle.xyz` – that act as bootstrap nodes
+
to the network. This means that these nodes will relay gossip for new nodes that
+
join the network. When someone sets up a new node in the Radicle network, their
+
Node ID and some other useful information well be gossiped to other nodes via
+
the seeds.
+

+
We and other contributors feel that these nodes should not be necessarily
+
defined as part of the `heartwood` repository. The bootstrap process should be
+
configured by the user, where the Radicle team can provide help and resources
+
for picking nodes. This can be a similar process to how Arch Linux users pick
+
their mirrors for retrieving packages from. This kind of work has already been
+
[kicked off][Remove Bootstrap Nodes], but needs some more input to progress it
+
further.
+

+
The aim of this is to encourage more decentralization of the network, allowing
+
operators to act as bootstrap nodes in the future. The team would slowly wind
+
down the use of `rosa` and `iris` to reduce the maintenance burden of operating
+
seeds as well as developing the protocol. The road map for this process would be
+
to remove them as predefined nodes in `heartwood`, and then slowly decommission
+
them.
+

+
### Compatibility with Git Worktrees
+

+
The current setup of Radicle defines a directory where it stores repositories.
+
These repositories essentially contain the usual references that you interact
+
with, each under [namespaces][Git Namespaces] of each node, as well as special
+
references such as `rad/sigrefs` and collaborative objects, e.g.
+
`xyz.radicle.patch`, `xyz.radicle.issue`. This acts as the user's forge, where
+
they can push and pull updates – using `git push` and `git fetch`, and interact
+
with collaborative objects through the the `rad` CLI. It's important to note,
+
however, that they do this through a working copy of the repository – a non-bare
+
repository which is a copy of the repository in storage.
+

+
There is a slight issue with this – it means you are duplicating the repository
+
on your disk, and for very large repositories this could mean taking up to the
+
range of 10's of gigabytes of disk space. So, we asked ourselves, is there a way
+
to unify these two repositories?
+

+
The answer, we believe, is [Git Worktrees]. The idea is that the Radicle storage
+
would also be your working copy. When you want to make changes to your
+
namespace, then you would create a new worktree based on a reference that you
+
want to work on top of, for example, the default branch of the repository.
+

+
To get to this point, we will need to improve certain aspects around reference
+
handling, primarily with canonical references, and also teach our tooling to
+
work better with bare Git repositories.
+

+
This will not only improve the storage space situation but may also feel more
+
natural to some developers who prefer working with worktrees.
+

+
## Developer Experience
+

+
### Migrating Radicle CLI to `clap`
+

+
If you have been looking up `rad` options all the time, `clap` your hands! We
+
will start migrating our `rad` CLI command-line parsing over to the [`clap`]
+
crate.
+

+
Up until this point, we have been using [`lexopt`] to parse command-line
+
arguments. The choice here was to have a small dependency that was flexible for
+
defining our own help messages. At the time, `clap` was going through its major
+
rewrite and was moving towards the `v3.0.0` release.
+

+
While minimising dependency footprint is a useful endeavour, the team and
+
contributors were feeling the pain of maintaining and hand writing out parsing
+
logic for any and all of the CLI commands, using `lexopt`. Last year, we did a
+
spike on exploring `clap` to see if it could be useful for adding completions
+
and providing dynamic hints, such as patch and issue identifier completions.
+
This gave us an idea of how using `clap` would work, but there was still some
+
need for additional upstream changes back then, and ultimately the experiment
+
was dropped for more pressing matters.
+

+
A while later, this was revisited again, and the main part of the exploration
+
was checking if we could keep somewhat compatible help messages for the
+
commands. It was found that with some boilerplate, we likely could. However, yet
+
again, our attentions were diverted elsewhere.
+

+
Now, with enough interest in the change, we have picked the effort back up to
+
bring this change over the finish line. We hope to leverage all that `clap`
+
brings with it: automatic argument parsing, completion tooling, a rich library
+
experience, and an ever evolving ecosystem of tools around `clap` itself.
+

+
### Code Review Research
+

+
[Code Review Research][#code-review-research]
+

+
If you have been using Radicle for any amount of time, you will have likely used
+
patches that are defined as part of the `rad` CLI, and the `git-remote-rad` [Git
+
remote helper]. This is and has been the primary way of exchanging code changes
+
via Radicle. This has bought us a lot, allowing us to propose new changes and
+
track the work that is going on through these patch contributions.
+

+
If you have been part of the Radicle [Zulip], you will have also noticed that
+
maintainers of the `heartwood` repository tend to have discussions in the
+
[#Patches] channel. This is where we do the majority of our review. We combine
+
these discussions with creating `REVIEW` commits and pushing these as a new
+
patch revision, for the original author to accept, modify, or drop.
+

+
On top of this, those who have dug around in the `rad patch` command will have
+
noticed that `rad patch review --patch` and `rad patch review --hunk` seemingly
+
have a flow for reviewing code. These operations, unfortunately, were never
+
wired up fully and are built on pieces of code that do not pan out with our
+
underlying libraries. Going forward, we intend to remove these options. You may
+
ask if this breaks backwards-compatibility, but we are of the opinion that if it
+
didn't work in the first place, then there is nothing to be compatible with!
+
However, there are still ways to submit patch reviews, through [Radicle
+
Desktop], a future release of [Radicle TUI], and `rad cob action` (this requires
+
a bit more documentation for proper use).
+

+
Where does that leave us for code review? We believe that this is a more complex
+
and multifaceted problem, that requires a lot more thought and design. Whole
+
teams have gone into building tools that perform code review, e.g. Jane Street's
+
Iron and Google's Gerrit. Now take these problems and also add people who want
+
use their own diff tools, crafted diff settings (e.g. diff algorithm), and still
+
make sure it works in an environment of decentralized collaboration. The
+
landscape of tooling is also changing, where we see more and more users flocking
+
towards [Jujutsu-VCS], where even some of our team are finding it useful for
+
[their day-to-day][Jujutsu with Radicle]. The usage of `jj` seems to have even
+
had a ripple effect of introducing change IDs into [Git itself][change-id commit
+
footer]!
+

+
We are happy to start this research and start dropping down our ideas – but
+
we're a small team. This is somewhere where the whole community could really
+
benefit by getting involved, researching these tools, and helping us build
+
something that could be great. Let's collaborate to improve collaboration! 🌱
+

+
### COB API Documentation
+

+
In the Radicle protocol, Collaborative Objects (COBs) play an important role in
+
supplementing Git with social artifacts such as issues, patches and discussions,
+
which are not inherently supported by Git. It includes three predefined
+
collaborative object types to support code collaboration: *Issues*, *Patches*,
+
and *Identities*.
+

+
These COBs are primarily interacted with through their `rad` sub-commands,
+
`issue`, `patch`, and `id` respectively. However, the full set of interactions
+
is not covered by these commands yet. For example, there is no way to add a
+
review comment using the `rad patch` command (see [Code Review Research]). That
+
does not mean that there is *no way* of doing this using the `rad` CLI. There is
+
a set of low-level, plumbing commands under `rad cob` that allow you to add COB
+
actions for updating an object – note that for the `Identity` COB, these updates
+
are not permitted, since we want strict validation of what can happen here. With
+
this in mind, we want to better document these commands and show how these
+
actions can be used for modifying the objects, which means outside tooling can
+
programmatically modify the objects by making CLI calls.
+

+
On top of this, we want to encourage more experimentation with COBs that can be
+
defined by other contributors outside of the team, outside of the `heartwood`
+
repository. We will supplement the above documentation with further tutorials on
+
how to define your own COBs and create your own workflows.
+

+
We plan to have all this information presented in a COB Guide on
+
[radicle.xyz/guides][Guides], and we look forward to hearing about all the
+
amazing COBs people will dream up!
+

+
### `rad` URI
+

+
A feature that we are missing in the Radicle ecosystem is being able to link to
+
resources easily. For example, there is no way to cross-link a patch to an issue
+
saying that, when merged, the issue is solved – something that GitHub users have
+
grown fond of.
+

+
Lorenz made an effort to kick-off discussion around this topic in a [RIP][Early
+
URI Proposal] that linked to a notepad of rough notes on the topic. Now, thanks
+
to the effort of Richard Levitte (`levitte`), the topic has been revived in
+
[another RIP proposal][`rad URI RIP`].
+

+
The goal here is to have a full specification of what the URI grammar looks like
+
for identifying resources in Radicle, such as repositories, Git objects, and
+
collaborative objects. Applications can then use these URIs for linking to these
+
resources within their application, users can have registered handlers for
+
taking them to their preferred Radicle application, and we can begin to support
+
automated workflows such as the one mentioned above with patches and issues.
+
With a mature scheme, we can also register it with [IANA][RFC 4395 – URI Scheme
+
Registration].
+

+
<!-- Zulip -->
+
[Zulip]: https://radicle.zulipchat.com
+

+
<!-- Release Management -->
+
[How To Do Releases]: https://beyermatthias.de/how-to-do-releases
+

+
<!-- Identity and Multi-Device -->
+
[Keyhive]: https://www.inkandswitch.com/keyhive/notebook/
+
[BetterSign]: https://github.com/cryptidtech/bs
+
[Agent Repository RIP]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3trNYnLWS11cJWC6BbxDs5niGo82/patches/27fea5d31ad98a49b2b5b7520d196620c3ed2b92
+

+
<!-- Migration of network I/O in `radicle-node` to `mio` -->
+
[`netservices`]: https://crates.io/crates/netservices
+
[`io-reactor`]: https://crates.io/crates/io-reactor
+
[`popol`]: https://crates.io/crates/popol
+
[`reactor::poller:Poll`]: https://docs.rs/io-reactor/0.5.2/reactor/poller/trait.Poll.html
+
[#10 for `mio`]: https://github.com/rust-amplify/io-reactor/issues/10
+
[#9 for `polling`]: https://github.com/rust-amplify/io-reactor/issues/9
+
[#8 for `epoll`]: https://github.com/rust-amplify/io-reactor/issues/8
+
[`reactor::poller:Poll`]: https://docs.rs/io-reactor/0.5.2/reactor/poller/trait.Poll.html
+
[`std::os::fd::raw::AsRawFd`]: https://doc.rust-lang.org/nightly/std/os/fd/raw/trait.AsRawFd.html
+
[io-reactor-dependents]: https://crates.io/crates/io-reactor/reverse_dependencies
+
[mio-dependents]: https://crates.io/crates/mio/reverse_dependencies
+
[tokio-dependents]: https://crates.io/crates/tokio/reverse_dependencies
+
[`a10`]: https://crates.io/crates/a10
+
[`io_uring`]: https://en.wikipedia.org/wiki/Io_uring
+
[I/O rings on Windows]: https://learn.microsoft.com/en-us/windows/win32/api/ioringapi/
+
[`mio::Token`]: https://docs.rs/mio/1.0.4/mio/struct.Token.html
+
[`mio::net`]: https://docs.rs/mio/1.0.4/mio/net/index.html
+
[`std::net`]: https://doc.rust-lang.org/stable/std/net/index.html
+
[noted by cloudhead]: https://cloudhead.io/popol/
+
[patch `5ea90b97`]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/5ea90b9757059522e80301bbd9b1458a39a71f7e
+

+
<!-- Windows Compatibility -->
+
[^1]: [radicle-cli: Build on Windows](https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/af3292c47ec93d906ccda8d9382f711c2201e678)
+
[^2]: [node: Use winpipe for control socket on Windows](https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/5109cda98885b00c1d4f7165013e4d66f9b7512f)
+
[^3]: [radicle/profile: Control socket path for Windows](https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/c7498dcdee66fbca673c7d6b85dfc18555fbd988)
+

+
<!-- Road to Sans-I/O Protocol -->
+
[Sans-I/O]: https://sans-io.readthedocs.io/
+
[Sans-I/O
+
Patch](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/511ad5ad569fea9124a9ad4738431e42b5075675)
+
[iroh]: https://www.iroh.computer/
+
[libp2p]: https://libp2p.io/
+

+
<!-- Policy Improvements -->
+
[publish-subscribe]: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
+

+
<!-- Reaping Repositories -->
+
[^4]: https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az23FUbgvSZMtshnoYuxmvaHfgMsCe
+
[^5]: https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az2H5Cae9kLahf57MbYoipimZzF2VU
+
[^6]: https://app.radicle.xyz/nodes/seed.radicle.garden/rad%3Az2KGZouSGAtbVcK4wkpWJP3MXSK3h
+
[^7]: One of the tenets of the Radicle protocol is to offer censorship resistance.
+

+
<!-- Bootstrapping -->
+
[Remove Bootstrap Nodes]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5/patches/3219ef871dd44c7ef51693f4aeba4c2c5c0c5c7b
+

+
<!-- Compatibility with Git Worktrees -->
+
[Git Namespaces]: https://git-scm.com/docs/gitnamespaces
+
[Git Worktrees]: https://git-scm.com/docs/git-worktree
+

+
<!-- Migrating Radicle CLI to clap -->
+
[clap]: https://crates.io/crates/clap
+
[lexopt]: https://crates.io/crates/lexopt
+

+
<!-- Code Review Research -->
+
[Git remote helper]: TODO
+
[#Patches]: https://radicle.zulipchat.com/#narrow/channel/383670-Patches
+
[Radicle Desktop]: https://desktop.radicle.xyz/
+
[Radicle TUI]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z39mP9rQAaGmERfUMPULfPUi473tY
+
[Jujutsu-VCS]: https://jj-vcs.github.io/jj/latest/
+
[Jujutsu with Radicle]: https://radicle.xyz/2025/08/14/jujutsu-with-radicle
+
[change-id commit footer](https://lore.kernel.org/git/CAESOdVAspxUJKGAA58i0tvks4ZOfoGf1Aa5gPr0FXzdcywqUUw@mail.gmail.com/)
+

+
<!-- COB API Documentation -->
+
[Guides]: https://radicle.xyz/guides
+

+
<!-- rad URI -->
+
[Early URI Proposal]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3trNYnLWS11cJWC6BbxDs5niGo82/patches/19ba16634fbde97156255ed97069d0aa3ab2bf12
+
[`rad` URI RIP]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3trNYnLWS11cJWC6BbxDs5niGo82/patches/2e2061857d703b8467648ff2b77efd61c72ca583
+
[RFC 4395 – URI Scheme Registration]: https://www.rfc-editor.org/rfc/rfc4395.html#section-5
modified index.md
@@ -115,6 +115,7 @@ updated, join our community on 💬 [Zulip][zulip], or <a href="{{ site.feed.pat
  Subscribe <img src="/assets/images/rss.svg" alt="RSS logo" style="width:15px;"/>
</a>

+
- 16.09.2025 [End of Year Roadmap]({% post_url 2025-09-16-roadmap %})
- 12.08.2025 [Radicle 1.4.0]({% post_url 2025-09-04-radicle-1.4.0 %}) released. ✨
- 12.08.2025 [Radicle 1.3.0]({% post_url 2025-08-12-radicle-1.3.0 %}) released. ✨
- 17.07.2025 [Radicle 1.2.1]({% post_url 2025-07-17-radicle-1.2.1 %}) released.