Radish alpha
r
rad:z371PVmDHdjJucejRoRYJcDEvD5pp
Radicle website including documentation and guides
Radicle
Git
Release 1.7.0 Daffodil
Fintan Halpenny committed 1 month ago
commit e0da77f27f1100cd2e8ec902bb98fb7491470db5
parent 1ac3fe3
2 files changed +405 -0
added _posts/2026-03-18-radicle-1.7.0.md
@@ -0,0 +1,404 @@
+
---
+
title: "Radicle 1.7.0 – Daffodil"
+
image: radicle-1.png
+
---
+

+
[748ddad]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5/commits/748ddade2feb6f00245c2ba878bd54842dc57506
+

+
Spring has sprung, where we're writing from, and Daffodils are in season!
+

+
The Radicle team are springing into action and announcing the release of Radicle 1.7.0 ([748ddad]), code name *Daffodil*.
+
The Daffodil is the national flower of Wales and starts to pop up in February/March – guiding us into the spring time.
+

+
This release consists of 226 commits from 11 contributors.
+
Thank you to all the amazing contributors who provided valuable work this release:
+
- Aaron Würth
+
- Defelo
+
- justarandomgeek
+
- Matthias Beyer
+
- Sebastian Martinez
+
- srestegosaurio
+
- Yorgos Saslis
+

+
## Installation
+

+
```
+
curl -sSLf {{ site.url }}/install | sh -s -- --no-modify-path --version=1.7.0
+
```
+

+
## ⚠️ Security Fix
+

+
This release contains a security fix, and so it is **highly recommended that you update all of your nodes**.
+
The information on the vulnerability will be disclosed on the 2026-03-23, with a full write-up at <https://radicle.xyz/2026/03/23/vulnerability-disclosure>.
+

+
We have taken the time to scan all existing repositories on our public seeds, and have not detected any active exploitation of the vulnerability with malicious intent as of today, 2026-03-18.
+

+
## New Features
+

+
### Improved `rad/sigrefs`
+

+
[`989edacd564fa658358f5ccfd08c243c5ebd8cda`]: https://app.radicle.xyz/nodes/seed.radicle.xyz/rad%3Az3gqcJUoA1n9HaHKufZs5FCSGazv5/commits/989edacd564fa658358f5ccfd08c243c5ebd8cda
+

+
The "Signed References" feature was reimplemented.
+
The commits in `refs/rad/sigrefs` will now only verify if they carry an appropriate value for `refs/rad/root` in the associated `refs` blob.
+
This reference was introduced in commit [`989edacd564fa658358f5ccfd08c243c5ebd8cda`], which was released via version 1.1.0.
+
A new reference, `refs/rad/sigrefs-parent`, is now recorded in the `refs` blob, when writing a new entry.
+
If present, its target must match the parent commit. This is to prevent a replay of a previous `refs/rad/sigrefs` commit.
+
It is optional to maintain backwards compatibility, and might become mandatory (like `refs/rad/root` does in this release) in the future.
+
Further, the new implementation detects replay of `refs` blobs.
+
In order to do so, it walks the history of `refs/rad/sigrefs` backwards to the root commit, if `refs/rad/sigrefs-parent` is not set.
+

+
### Blocking Policies
+

+
For those familiar with `rad block`, you may be aware that you can block a `NodeId`.
+
Previous to this release, the blocked node's references would be rejected during a fetch.
+
However, it would not be blocked on the connection management level.
+
With the changes included in this release, blocked nodes are now also blocked at the connection level.
+
Any attempts for inbound or outbound connections will be rejected.
+

+
### Include a Wider Set of References
+

+
The references of a remote were restricted to `heads`, `tags`, `notes`, `rad`, and `cobs`.
+
This is too restrictive, and does not allow the extensibility that Git affords us as users.
+
The restriction is now lifted, and the only references that are filtered out are `refs/tmp/heads`; used by `radicle-remote-helper` to create temporary patches.
+

+
### Better Errors for `rad id` Updates
+

+
Using `rad id` to update the identity document as a non-delegate would result in unclear errors.
+
Now, when a non-delegate user attempts to update the document, they will have a clearer error given to them.
+

+
```
+
$ rad id update \
+
    --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji \
+
    --title "Add myself!" \
+
    --delegate did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk \
+
    --no-confirm
+
✗ Error: did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk is not a delegate, and only delegates are allowed to create a revision
+
✗ Hint: bob (you) is attempting to modify the identity document but is not a delegate!
+
```
+

+
### Improved I/O Usage
+

+
Radicle uses `sqlite` for local state storage, and it was configured to use `journal_mode = WAL`, and the default value of `synchronous = FULL`.``
+
It was recently found that this combination would result in a high amount of I/O operations for a long running node.
+
The `journal_mode` and `synchronous` pragmas are now configurable from `rad config edit`.
+
The new default values for both are `WAL` and `NORMAL`, respectively. This results in less I/O operations.
+
On power loss, transactions might be rolled back, but SQLite still guarantees consistency in this mode.
+

+
## Fixed Bugs
+

+
### Windows
+

+
#### Use `winsplit` on Windows
+

+
When preparing commands to execute, the `shlex` crate was used on all platforms.
+
The semantics on Windows are different (e.g. '\\' is a path separator on Windows but marks an escape sequence on Unix-like systems).
+
This lead to issues when attempting to execute child processes, and was fixed by using `winsplit` on Windows instead.
+

+
#### Prevent `git-upload-pack` Zombies
+

+
[Job]: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects
+

+
One of our Windows users noticed that `git-upload-pack` processes would never be reaped, resulting in zombie processes.
+
These zombie processes are now prevented by using the "[Job]" API of the operating system to group child processes and their children.
+

+
#### Signal Handling Support
+

+
Signal handling is now supported, and so the `radicle-node` executable will now respect signals on Windows.
+

+
### Responsive CLI Commands
+

+
Users of the `rad` CLI would often encounter the following output:
+

+
```
+
✗ Error: timed out reading from control socket
+
```
+

+
The reason for this was that the request/response pattern that was implemented never accounted for errors.
+
When the `Service` would receive a request that resulted in a failure, it would log it, and move on.
+
The `Service` has now learned to respond with errors.
+
This will improve the above error scenarios by providing more information about the error that occurred.
+

+
### IPv6 Address Parsing
+

+
Parsing addresses involving an IPv6 host failed if they were enclosed in square brackets, e.g. in `rad node connect z6Mk...@[::1]:8776`.
+
Also, ambiguous addresses would parse, e.g. `::1:8776` would be indistinguishable from `[::1]:8776`.
+
Since a port number is always required along with a host when providing an address, IPv6 addresses now always require brackets to avoid confusion.
+
Existing IPv6 addresses that are stored in the `sqlite` database are migrated automatically on node startup.
+

+
## Deprecations
+

+
### `rad fork`
+

+
The `rad fork` command was confusing, and mislead users as to what its purpose was.
+
Many believed it to create a hard-fork of the repository.
+
Instead, it pushed the default branch to the local user's namespace.
+
The command is now deprecated, and you should use `git push` instead.
+

+
## Breaking Changes
+

+
### `Seeds` No Longer Contains Fetching Information
+

+
If you are using the `radicle-node` control socket, and request `Seeds` information, then expect a breaking change to the output.
+
The `Connected` state of a peer no longer contains fetching information, which was separated out.
+
This has resulted in the entire `fetching` value being removed.
+

+
### Changes to `rad node debug` Information
+

+
The `rad node debug` information for ongoing fetches contained the number of subscribers awaiting for results, this was removed.
+

+
### COB Type Names are More DNS Compliant
+

+
[RFC-1035]: https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
+

+
The `TypeName` strings defined in `radicle-cob` are restricted to reflect the size limits on domain names as specified in [RFC-1035].
+
These restrictions are:
+
- A total length of 255 bytes.
+
- A max component length of 63 bytes.
+

+
### Human-readable Timeout Durations
+

+
Several `rad` commands take a `--timeout` option, and each one would vary in units, e.g. seconds, milliseconds.
+
These options now take human-readable durations as values, e.g. "9s" for 9 seconds, "1min" for 1 minute, etc.
+
This is a breaking change since these options now require the unit to be specified.
+

+
## Changelog
+

+
This release contains 226 commit(s) by 11 contributor(s).
+

+
* `748ddade` **fetch: Make `RemoteRefs` an alias** *<lorenz.leutgeb@radicle.xyz>*
+
* `35d71f59` **fetch: Remove `DelegateStatus`** *<lorenz.leutgeb@radicle.xyz>*
+
* `363a7231` **fetch: Remove dead code from `DataRefs`** *<lorenz.leutgeb@radicle.xyz>*
+
* `725ced09` **fetch: Prune remotes with sigrefs failures** *<fintan.halpenny@gmail.com>*
+
* `6967bf8f` **radicle: Automatically upgrade sigrefs** *<lorenz.leutgeb@radicle.xyz>*
+
* `20598d39` **radicle: Remove unused `SyncedAt::load`** *<lorenz.leutgeb@radicle.xyz>*
+
* `0f9eace8` **crypto: Remove markers `Verified` and `Unverified`** *<lorenz.leutgeb@radicle.xyz>*
+
* `304a6631` **radicle: Remove generics for verification markers** *<lorenz.leutgeb@radicle.xyz>*
+
* `393eca39` **node/e2e: `rad/sigrefs-parent` is not fetched** *<fintan.halpenny@gmail.com>*
+
* `d40fa9a3` **radicle/sigrefs: Switch to new implementation** *<fintan.halpenny@gmail.com>*
+
* `d3bc868e` **radicle/sigrefs: Rewrite Signed References** *<fintan.halpenny@gmail.com>*
+
* `52a660fd` **node/test: Set `RAD_RNG_SEED`** *<lorenz.leutgeb@radicle.xyz>*
+
* `99d92421` **Use humantime to parse timeouts** *<mail@beyermatthias.de>*
+
* `52e55812` **cli: Don't override existing seeding scope in `rad seed`** *<mail@defelo.de>*
+
* `281f92e9` **cli/tests: Add test for `rad clone --scope`** *<mail@defelo.de>*
+
* `eea36177` **use `CONIN$` instead of `/dev/tty` on windows** *<justarandomgeek@gmail.com>*
+
* `a1fd9e04` **radicle: Update `sqlite` to 0.37** *<fintan.halpenny@gmail.com>*
+
* `07369771` **node: Migrate IPv6 addresses in database** *<lorenz.leutgeb@radicle.xyz>*
+
* `9e8f09a1` **Remove stray files** *<fintan.halpenny@gmail.com>*
+
* `0c47d06f` **radicle/storage/refs: Strengthen Encapsulation** *<fintan.halpenny@gmail.com>*
+
* `f4495e92` **radicle/device: `impl Keypair for BoxedSigner`** *<lorenz.leutgeb@radicle.xyz>*
+
* `74fa4425` **crypto: Require `Signer: signature::Signer`** *<lorenz.leutgeb@radicle.xyz>*
+
* `06fae85e` **crypto: `impl Signer` based on `Keypair`** *<lorenz.leutgeb@radicle.xyz>*
+
* `f2ad5454` **crypto: `impl signature::KeypairRef` for Signers** *<lorenz.leutgeb@radicle.xyz>*
+
* `768ecf56` **crypto: Add `impl Verifier for PublicKey`** *<fintan.halpenny@gmail.com>*
+
* `01c60388` **git-metadata: Add parsing of `CommitData`** *<fintan.halpenny@gmail.com>*
+
* `58624148` **git-metadata: Add `CommitData::strip_signatures`** *<fintan.halpenny@gmail.com>*
+
* `60871de8` **git-metadata: Add derivable traits** *<fintan.halpenny@gmail.com>*
+
* `0e45347b` **radicle/storage: Improve `Validation` error** *<lorenz.leutgeb@radicle.xyz>*
+
* `ba9c09fa` **radicle/refs: Better `SignedRefs` Encapsulation** *<fintan.halpenny@gmail.com>*
+
* `39a58ded` **node/test: Use `Arbitrary` for `SignedRefs`** *<fintan.halpenny@gmail.com>*
+
* `f7ff4d8f` **radicle/arbitrary: Move `impl Arbitrary` of refs** *<fintan.halpenny@gmail.com>*
+
* `b8502397` **protocol/wire: Remove SignedRefs encoding/decoding** *<fintan.halpenny@gmail.com>*
+
* `ba8d6b88` **radicle/storage: Remove unused Remote methods** *<fintan.halpenny@gmail.com>*
+
* `e78d477b` **radicle/git: Remove unused `fn remote_refs`** *<lorenz.leutgeb@radicle.xyz>*
+
* `759a6fb9` **radicle: Compile `rad::fork_remote` only for tests** *<fintan.halpenny@gmail.com>*
+
* `7bac1714` **CHANGELOG: fix typo** *<fintan.halpenny@gmail.com>*
+
* `cb3ca622` **radicle/CHANGELOG: remove variant typo** *<fintan.halpenny@gmail.com>*
+
* `9dbbb01d` **radicle: remove `TryFrom`** *<fintan.halpenny@gmail.com>*
+
* `57da7799` **radicle: Add a `load` method to `radicle::profile::Home`** *<me@sebastinez.dev>*
+
* `ff85c74e` **cli: Add blank line after issue reply header** *<mail@beyermatthias.de>*
+
* `1b986af0` **cli/tests: Refactor workflow test** *<fintan.halpenny@gmail.com>*
+
* `fa82bd5f` **cli/tests: Refactor watch command tests** *<adrian.duke@gmail.com>*
+
* `45e6afd0` **cli/tests: Refactor utility command tests** *<fintan.halpenny@gmail.com>*
+
* `d282e0d0` **cli/tests: Refactor sync command tests** *<fintan.halpenny@gmail.com>*
+
* `7d2842a4` **cli/tests: Refactor remote command tests** *<adrian.duke@gmail.com>*
+
* `c1ab7c38` **cli/tests: Refactor policy command tests** *<adrian.duke@gmail.com>*
+
* `18d7f99e` **cli/tests: Refactor patch command tests** *<adrian.duke@gmail.com>*
+
* `4ffabde6` **cli/tests: Refactor node command tests** *<adrian.duke@gmail.com>*
+
* `b2568f0b` **cli/tests: Refactor jj command tests** *<adrian.duke@gmail.com>*
+
* `4753b889` **cli/tests: Refactor issue command tests** *<adrian.duke@gmail.com>*
+
* `8bf655ef` **cli/tests: Refactor init command tests** *<adrian.duke@gmail.com>*
+
* `a1c1b03b` **cli/tests: Refactor inbox command tests** *<adrian.duke@gmail.com>*
+
* `cd4532ec` **cli/tests: Refactor id command tests** *<adrian.duke@gmail.com>*
+
* `dac099e4` **cli/tests: Refactor git command tests** *<adrian.duke@gmail.com>*
+
* `d39e485c` **cli/tests: Refactor cob command tests** *<adrian.duke@gmail.com>*
+
* `1f3dc6ae` **cli/tests: Refactor clone command tests** *<adrian.duke@gmail.com>*
+
* `7a1e6a24` **cli/tests: Refactor checkout command tests** *<fintan.halpenny@gmail.com>*
+
* `5aaf978f` **radicle: Configure database connections on open** *<lorenz.leutgeb@radicle.xyz>*
+
* `f3afe7b0` **radicle/config/sqlite: Use `synchronous = NORMAL`** *<lorenz.leutgeb@radicle.xyz>*
+
* `f4aee203` **radicle: Make SQLite pragmas configurable** *<yorgos.work@proton.me>*
+
* `6cc3da95` **radicle/node/db: Model SQLite `synchronous` pragma** *<yorgos.work@proton.me>*
+
* `d36bf41f` **radicle/node/db: Directly represent SQLite pragmas** *<yorgos.work@proton.me>*
+
* `9ff67562` **cli: Format IPv6 addresses in square brackets** *<mail@defelo.de>*
+
* `df8e4e6c` **node: Parse IPv6 addresses in square brackets** *<mail@defelo.de>*
+
* `7c923608` **radicle: fix to schemars of DefaultSeedingPolicy** *<fintan.halpenny@gmail.com>*
+
* `6291cae5` **cli: add `rad config schema` to the `rad-config` test** *<fintan.halpenny@gmail.com>*
+
* `f018b434` **node: control debug serialization of FetcherState** *<fintan.halpenny@gmail.com>*
+
* `9ea1ea24` **Revert "node/debug: Use derived serializers"** *<fintan.halpenny@gmail.com>*
+
* `e9245b63` **cli: don't override existing seeding scope in `rad clone`** *<mail@defelo.de>*
+
* `b04f487b` **term: Update to 0.17.0** *<fintan.halpenny@gmail.com>*
+
* `9a98cf7b` **keccak: Update to 0.1.6** *<fintan.halpenny@gmail.com>*
+
* `bab3f82a` **fetch: Update to 0.17.0** *<fintan.halpenny@gmail.com>*
+
* `a0b434c3` **localtime: add description in Cargo.toml** *<fintan.halpenny@gmail.com>*
+
* `9dba9130` **core: use "data-types" instead of "data types"** *<fintan.halpenny@gmail.com>*
+
* `f9a36ef7` **systemd: Update to 0.12.0** *<fintan.halpenny@gmail.com>*
+
* `18d6ce94` **protocol: Update 0.5.0** *<fintan.halpenny@gmail.com>*
+
* `c0ae5e32` **node: Update to 0.17.0** *<fintan.halpenny@gmail.com>*
+
* `963b4ded` **crypto: Update to 0.15.0** *<fintan.halpenny@gmail.com>*
+
* `84e9ffe4` **cob: Update to 0.18.0** *<fintan.halpenny@gmail.com>*
+
* `186d8d30` **cli: Update to 0.18.0** *<fintan.halpenny@gmail.com>*
+
* `3a110746` **radicle: Update to 0.21.0** *<fintan.halpenny@gmail.com>*
+
* `15666467` **radcile/cob/identity: mark ApplyError as non_exhaustive** *<fintan.halpenny@gmail.com>*
+
* `d596b14e` **build: Pin Zig to 0.13.0** *<fintan.halpenny@gmail.com>*
+
* `4c759a26` **build: Update macos-sdk to include IOKit, libconv, and libcharset** *<fintan.halpenny@gmail.com>*
+
* `57a44dae` **build: Update cargo-zigbuild to 0.22.1** *<fintan.halpenny@gmail.com>*
+
* `89478b16` **cargo/git2: Update to 0.20.4** *<fintan.halpenny@gmail.com>*
+
* `423cf604` **nix: update to 25.11** *<fintan.halpenny@gmail.com>*
+
* `30701cc6` **node/runtime: Make `Runtime::run` more readable** *<lorenz.leutgeb@radicle.xyz>*
+
* `057edf55` **node/reactor: Introduce `LAG_TIMEOUT`** *<lorenz.leutgeb@radicle.xyz>*
+
* `ae06111e` **node/reactor: Rewrite `Runtime::run`** *<lorenz.leutgeb@radicle.xyz>*
+
* `4d7b942b` **remote-helper: Rename `to_branch_name`** *<lorenz.leutgeb@radicle.xyz>*
+
* `6d2a99e1` **remote-helper: Remove Unused Error Variants** *<lorenz.leutgeb@radicle.xyz>*
+
* `a69420b9` **remote-helper: Rework Visibility Modifiers** *<lorenz.leutgeb@radicle.xyz>*
+
* `d36ed7c8` **remote-helper/protocol: Introduce Line and Command** *<adrian.duke@gmail.com>*
+
* `27493c22` **remote-helper/service: Introduce `NodeSession`** *<adrian.duke@gmail.com>*
+
* `56253b52` **remote-helper/service: Introduce `GitService`** *<adrian.duke@gmail.com>*
+
* `bd30e80b` **remote-helper/list: Remove printing to stdio** *<adrian.duke@gmail.com>*
+
* `119445ce` **cli-test: Move `let mut args` closer to its uses** *<lorenz.leutgeb@radicle.xyz>*
+
* `56ece480` **cli-test: Remove special handling for `rad`** *<lorenz.leutgeb@radicle.xyz>*
+
* `3cd1af1d` **cli-test: Configure `escargot` properly** *<lorenz.leutgeb@radicle.xyz>*
+
* `5aca9bf1` **cli-test: Refactor Path Handling** *<lorenz.leutgeb@radicle.xyz>*
+
* `d88ef3fa` **e2e: Introduce 3 tests for block command** *<adrian.duke@gmail.com>*
+
* `a4806f27` **node/test: check remote events for `Event::PeerDisconnected`** *<fintan.halpenny@gmail.com>*
+
* `1fa14ef5` **protocol/service: Use block list for connections** *<adrian.duke@gmail.com>*
+
* `94e0a512` **node: Add block command to control socket** *<adrian.duke@gmail.com>*
+
* `4286590f` **fetch: move `Component::from` outside of loop** *<fintan.halpenny@gmail.com>*
+
* `0e9d7607` **hooks: Enable typos, fix reported errors** *<lorenz.leutgeb@radicle.xyz>*
+
* `5fa68ed8` **node: Use `gix_packetline`** *<lorenz.leutgeb@radicle.xyz>*
+
* `c96aea06` **node/e2e: Fix test_non_fastforward_identity_doc** *<adrian.duke@gmail.com>*
+
* `832598ce` **cli: Warn user about implicit seeding policy** *<adrian.duke@gmail.com>*
+
* `cee3659e` **radicle: Introduce `radicle::node::config::Scope`** *<adrian.duke@gmail.com>*
+
* `306d0afb` **protocol: Note on peering and fetches** *<adrian.duke@gmail.com>*
+
* `0684d1cc` **cli: Changed the default scope from all to followed for clone and seed** *<adrian.duke@gmail.com>*
+
* `dd13eed1` **cli: Do not print scope in block table** *<adrian.duke@gmail.com>*
+
* `b5e8776e` **fetch: Improve `refs/rad/id` resolution** *<adrian.duke@gmail.com>*
+
* `84320919` **node/tests/e2e: use assert_eq! in test** *<fintan.halpenny@gmail.com>*
+
* `7862e108` **Update gix-* crates** *<fintan.halpenny@gmail.com>*
+
* `39157117` **fetch: introduce domain type RefPrefix** *<fintan.halpenny@gmail.com>*
+
* `8070f98a` **fetch/transport/ls_refs: Post-filter of references** *<fintan.halpenny@gmail.com>*
+
* `980ed561` **protocol/service: rename `Responder::new` to `Responder::oneshot`** *<fintan.halpenny@gmail.com>*
+
* `0d628a45` **protocol: refactor to use Responder** *<fintan.halpenny@gmail.com>*
+
* `b1eedd3b` **protocol/service: introduce Responder type** *<fintan.halpenny@gmail.com>*
+
* `61a9b214` **protocol/service: introduce Result synonym** *<fintan.halpenny@gmail.com>*
+
* `2c197215` **protocol: opaque command error** *<fintan.halpenny@gmail.com>*
+
* `38713a8e` **protocol/service: drop `chan` qualifier** *<fintan.halpenny@gmail.com>*
+
* `912a5ca4` **protocol/service: create command module** *<fintan.halpenny@gmail.com>*
+
* `fa94638a` **radicle/storage/init: Remove placeholder files** *<lorenz.leutgeb@radicle.xyz>*
+
* `7425ae4b` **ssh: Treat "connection refused" on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `5099c25d` **node/debug: Use derived serializers** *<lorenz.leutgeb@radicle.xyz>*
+
* `a1fa3801` **protocol: Depend on `cypheraddr` not `cyphernet`** *<lorenz.leutgeb@radicle.xyz>*
+
* `d530f126` **node/test: Remove unused file `environment.rs`** *<lorenz.leutgeb@radicle.xyz>*
+
* `730d696d` **node/test: Bind to loopback interface** *<lorenz.leutgeb@radicle.xyz>*
+
* `dfe3b501` **radicle/git/raw: `Config` not used on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `ed2b36cf` **cli-test: Log line of assertion being executed** *<lorenz.leutgeb@radicle.xyz>*
+
* `9055a204` **cli-test: Add placeholder for executable extension** *<lorenz.leutgeb@radicle.xyz>*
+
* `e831aeb5` **cli-test: Do not store `bins`** *<lorenz.leutgeb@radicle.xyz>*
+
* `8fbdd46c` **cli-test: Cheat to find coreutils on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `4894657b` **cli-test: Simplify cargo path handling** *<lorenz.leutgeb@radicle.xyz>*
+
* `25d1974c` **cli-test: Deduplicate populating `bins`** *<lorenz.leutgeb@radicle.xyz>*
+
* `44f52f4c` **cli-test: Fix uses of `PATH_SEPARATOR`** *<lorenz.leutgeb@radicle.xyz>*
+
* `dd122f10` **cli/test: Ignore `rad_diff` on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `5974fa32` **windows: Add installer build** *<lorenz@lap-21-0150.mpi-inf.mpg.de>*
+
* `c06b00e3` **CVE-2026-25727** *<fintan.halpenny@gmail.com>*
+
* `31607cf7` **CVE-2026-25541** *<fintan.halpenny@gmail.com>*
+
* `2d0db3c6` **CVE-2025-58160** *<fintan.halpenny@gmail.com>*
+
* `03bbe524` **signals: Add support for Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `865abd35` **protocol/fetcher: Intro `RefsToFetch`** *<lorenz.leutgeb@radicle.xyz>*
+
* `9081c11b` **protocol/fetcher: Remove `from` from `QueuedFetch`** *<lorenz.leutgeb@radicle.xyz>*
+
* `53a12869` **protocol/service: Remove unnecessary arg** *<lorenz.leutgeb@radicle.xyz>*
+
* `94d7799f` **protocol/fetcher/state: Typo** *<lorenz.leutgeb@radicle.xyz>*
+
* `56ee626a` **protocol/fetcher: Delete unused file** *<lorenz.leutgeb@radicle.xyz>*
+
* `41f77a49` **RELEASE: start at rc.1** *<fintan.halpenny@gmail.com>*
+
* `613c4e83` **protocol: separate subscribers by RefsAt** *<fintan.halpenny@gmail.com>*
+
* `993428df` **node: donwgrade log error to trace for disconnection** *<fintan.halpenny@gmail.com>*
+
* `aeba81f4` **core: add documentation to `RepoId::from_canonical`** *<fintan.halpenny@gmail.com>*
+
* `35a01898` **core: guard on expected multibase** *<fintan.halpenny@gmail.com>*
+
* `8ee32168` **radicle: remove file** *<fintan.halpenny@gmail.com>*
+
* `ebf7d876` **node: Control via `uds_windows` not `winpipe`** *<lorenz.leutgeb@radicle.xyz>*
+
* `90cf37c4` **node: On Windows, use job for upload-pack child** *<lorenz.leutgeb@radicle.xyz>*
+
* `990edbf0` **windows: Introduce new crate** *<lorenz.leutgeb@radicle.xyz>*
+
* `50fb228a` **term/editor: Implement `exists` for Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `450b664a` **term/editor: Use `cfg`-attribute instead of macro** *<lorenz.leutgeb@radicle.xyz>*
+
* `8fb2d96b` **radicle/profile: No pager from Git on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `930ec175` **term, cli: `winsplit` over `shlex` on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `537eaba8` **Use rust-analyzer from tool chain in devShell** *<aaron.wuerth@posteo.de>*
+
* `d7a4137e` **systemd: remove redundant lines from system unit** *<lcdt@disroot.org>*
+
* `27ee6e10` **ci: Enable debugging on Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `fefa2837` **cli/init: Canonicalize path before comparison** *<lorenz.leutgeb@radicle.xyz>*
+
* `ffbbb374` **cli-test: Path separation compatible with Windows** *<lorenz.leutgeb@radicle.xyz>*
+
* `faeee9f3` **crypto: Optionally provide JSON Schema** *<lorenz.leutgeb@radicle.xyz>*
+
* `82ad52b1` **cob: further restrict TypeName** *<fintan.halpenny@gmail.com>*
+
* `fe09cd4a` **cob: split up typename tests** *<fintan.halpenny@gmail.com>*
+
* `204db22b` **cob: enable sha1 feature** *<fintan.halpenny@gmail.com>*
+
* `1cab036c` **protocol/service: Wire up `FetcherService`** *<fintan.halpenny@gmail.com>*
+
* `9e208909` **protocol: Introduce `FetcherService`** *<fintan.halpenny@gmail.com>*
+
* `f0e3ca34` **protocol: Introduce `FetcherState`** *<fintan.halpenny@gmail.com>*
+
* `7cf73300` **radicle/storage/refs: Derive `Hash` for `RefsAt`** *<fintan.halpenny@gmail.com>*
+
* `eccfd6ba` **cli: optional message for issue comments** *<fintan.halpenny@gmail.com>*
+
* `c33c26fa` **cli: fix casing for warning of preferred_seeds** *<fintan.halpenny@gmail.com>*
+
* `15adb161` **protocol: missed formatting** *<fintan.halpenny@gmail.com>*
+
* `91eb6fc0` **protocol: ensure `connect` supports connecting address** *<fintan.halpenny@gmail.com>*
+
* `36d5a4c8` **protocol: use helper method** *<fintan.halpenny@gmail.com>*
+
* `73f9a350` **protocol: reuse session address for reconnect** *<fintan.halpenny@gmail.com>*
+
* `589925e3` **radicle/node: avoid unnecessary allocations in `Emitter::emit_all`** *<mail@defelo.de>*
+
* `8b1d4751` **protocol: batch inventory removals and events in `sync_routing`** *<mail@defelo.de>*
+
* `d2ab7b1b` **RELEASE: include patch releases** *<fintan.halpenny@gmail.com>*
+
* `1c9a1b4f` **RELEASE: Add file documenting the release process** *<fintan.halpenny@gmail.com>*
+
* `e63c3097` **cli/fork: Deprecate** *<lorenz.leutgeb@radicle.xyz>*
+
* `b937a938` **radicle-cli: more helpful error for non-delegate updates** *<adrian.duke@gmail.com>*
+
* `60959f7e` **cli: promote WithHint hint type to String** *<adrian.duke@gmail.com>*
+
* `67a4a712` **radicle: add new error type for unauthorized non-delegates** *<adrian.duke@gmail.com>*
+
* `bd5436d7` **core: Fix doctest** *<lorenz.leutgeb@radicle.xyz>*
+
* `b41ce2e6` **radicle/canonical: provide public Canonical JSON link** *<fintan.halpenny@gmail.com>*
+
* `f6d3dae4` **CHANGELOG: Release 1.6.1** *<fintan.halpenny@gmail.com>*
+
* `a4e66d14` **radicle: Allow all references to be included in sigrefs** *<mail@defelo.de>*
+
* `67dee655` **Release 1.6.0 CHANGELOG** *<fintan.halpenny@gmail.com>*
+
* `6d1abd28` **node: downgrade `error!` logs** *<fintan.halpenny@gmail.com>*
+
* `b020543c` **node: downgrade `warn!` logs** *<fintan.halpenny@gmail.com>*
+
* `ee1f5542` **protocol: downgrade `error!` logs** *<fintan.halpenny@gmail.com>*
+
* `eeadffa6` **node: update comment** *<fintan.halpenny@gmail.com>*
+
* `958422a7` **node/routing: remove error scenario from Database::prune** *<fintan.halpenny@gmail.com>*
+
* `95b3d109` **protocol: downgrade `warn!` logs** *<fintan.halpenny@gmail.com>*
+
* `9236277a` **fetch: remove `target: "fetch"`** *<fintan.halpenny@gmail.com>*
+
* `e3cb36d9` **fetch: clean up logging** *<fintan.halpenny@gmail.com>*
+
* `d860ec15` **cli: Remove dead `fn parse_remote`** *<adrian.duke@gmail.com>*
+
* `53cb8da8` **clippy: Deny and fix `must_use_candidate`** *<adrian.duke@gmail.com>*
+
* `2df32c00` **clippy: Deny `fn_params_excessive_bools`** *<adrian.duke@gmail.com>*
+
* `4c1b7fcd` **clippy: Deny and fix `index_slicing`** *<adrian.duke@gmail.com>*
+
* `0855af00` **clippy: Deny and fix `unneeded_field_pattern`** *<adrian.duke@gmail.com>*
+
* `9cc2c869` **clippy: Deny and fix `wildcard_enum_match_arm`** *<adrian.duke@gmail.com>*
+
* `001aba0d` **clippy: Deny and fix `fallible_impl_from`** *<adrian.duke@gmail.com>*
+
* `02318f19` **radicle: Re-export `radicle_core::RepoId`** *<fintan.halpenny@gmail.com>*
+
* `73827f53` **radicle: Re-export `radicle_core::NodeId`** *<fintan.halpenny@gmail.com>*
+
* `7c016f92` **core: Introduce NodeId** *<fintan.halpenny@gmail.com>*
+
* `d5fea632` **core: Introduce RepoId** *<fintan.halpenny@gmail.com>*
+
* `af3f0762` **chore: Update thiserror from 1 to 2** *<lorenz.leutgeb@radicle.xyz>*
+
* `d98033a1` **localtime: localise the localtime dependency** *<fintan.halpenny@gmail.com>*
+
* `3168107d` **fetch: surface underlying I/O error** *<fintan.halpenny@gmail.com>*
+
* `75b665ff` **node/wire: manage logs for error establishing connection** *<fintan.halpenny@gmail.com>*
+
* `47dc2c56` **protocol/service: defensive storage.contains check** *<fintan.halpenny@gmail.com>*
+
* `a46f8eb1` **node: use `outbound.get` over `outbound.get_mut`** *<fintan.halpenny@gmail.com>*
+
* `b8a6e1a5` **radicle/cob/stream: skip commits that do not have a manifest** *<fintan.halpenny@gmail.com>*
+
* `cf023f75` **cob: allow hyphens in `TypeName`** *<mail@defelo.de>*
+
* `352c29c2` **cargo(deny): allow Zlib** *<fintan.halpenny@gmail.com>*
+
* `a66d44eb` **workspace: update git-ref-format-core and radicle-surf** *<fintan.halpenny@gmail.com>*
+

+
## Checksums
+

+
```
+
e6de41ba2b2efd07b9ab008717d720184f8385c3bb93ad5c4a37f257179ecfed  radicle-1.7.0-x86_64-apple-darwin.tar.xz
+
0dd4d185bd6a1e5588ec879471678c482b0cc27d92cb2cc3b22982e63e920049  radicle-1.7.0-aarch64-unknown-linux-musl.tar.xz
+
dd9b734dc7b7b7132e7a27e5a53e268276870bbebd195ff6c0e1273ec2984dea  radicle-1.7.0-aarch64-apple-darwin.tar.xz
+
e23ad2f616d9730db5ae4eb730baad1373172e2dcaec1fef2c6b199dba514378  radicle-1.7.0-x86_64-unknown-linux-musl.tar.xz
+
```
+

modified index.md
@@ -113,6 +113,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>

+
- 18.03.2026 [Radicle 1.7.0]({% post_url 2026-03-18-radicle-1.7.0 %}) released. 🌤️
- 14.01.2026 [Radicle 1.6.0]({% post_url 2026-01-14-radicle-1.6.0 %}) released. ✨
- 30.09.2025 [Radicle 1.5.0]({% post_url 2025-09-30-radicle-1.5.0 %}) released.
- 04.09.2025 [Radicle 1.4.0]({% post_url 2025-09-04-radicle-1.4.0 %}) released.