Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Rename `Id` to `RepoId`
cloudhead committed 2 years ago
commit f87dfba9cd9a91f4fd7a8eaa4d7847ec58f02fb9
parent 7208d89c31964abaee4faa6ec53f6602e0f1d534
78 files changed +472 -457
modified radicle-cli/src/commands/checkout.rs
@@ -32,7 +32,7 @@ Options
};

pub struct Options {
-
    pub id: Id,
+
    pub id: RepoId,
    pub remote: Option<Did>,
}

modified radicle-cli/src/commands/clean.rs
@@ -2,7 +2,7 @@ use std::ffi::OsString;

use anyhow::anyhow;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::storage;
use radicle::storage::WriteStorage;

@@ -32,7 +32,7 @@ Options
};

pub struct Options {
-
    rid: Id,
+
    rid: RepoId,
    confirm: bool,
}

@@ -41,7 +41,7 @@ impl Args for Options {
        use lexopt::prelude::*;

        let mut parser = lexopt::Parser::from_args(args);
-
        let mut id: Option<Id> = None;
+
        let mut id: Option<RepoId> = None;
        let mut confirm = true;

        while let Some(arg) = parser.next()? {
modified radicle-cli/src/commands/clone.rs
@@ -10,7 +10,7 @@ use thiserror::Error;
use radicle::cob;
use radicle::git::raw;
use radicle::identity::doc;
-
use radicle::identity::doc::{DocError, Id};
+
use radicle::identity::doc::{DocError, RepoId};
use radicle::node;
use radicle::node::policy::Scope;
use radicle::node::{Handle as _, Node};
@@ -55,7 +55,7 @@ Options
#[derive(Debug)]
pub struct Options {
    /// The RID of the repository.
-
    id: Id,
+
    id: RepoId,
    /// The target directory for the repository to be cloned into.
    directory: Option<PathBuf>,
    /// The seeding scope of the repository.
@@ -71,7 +71,7 @@ impl Args for Options {
        use lexopt::prelude::*;

        let mut parser = lexopt::Parser::from_args(args);
-
        let mut id: Option<Id> = None;
+
        let mut id: Option<RepoId> = None;
        let mut scope = Scope::All;
        let mut mode = sync::RepoSync::default();
        let mut timeout = time::Duration::from_secs(9);
@@ -110,7 +110,7 @@ impl Args for Options {
                Value(val) if id.is_none() => {
                    let val = val.to_string_lossy();
                    let val = val.strip_prefix("rad://").unwrap_or(&val);
-
                    let val = Id::from_str(val)?;
+
                    let val = RepoId::from_str(val)?;

                    id = Some(val);
                }
@@ -229,13 +229,13 @@ pub enum CloneError {
    #[error(transparent)]
    Repository(#[from] RepositoryError),
    #[error("repository {0} not found")]
-
    NotFound(Id),
+
    NotFound(RepoId),
    #[error("no seeds found for {0}")]
-
    NoSeeds(Id),
+
    NoSeeds(RepoId),
}

pub fn clone<G: Signer>(
-
    id: Id,
+
    id: RepoId,
    directory: Option<PathBuf>,
    scope: Scope,
    mode: sync::RepoSync,
modified radicle-cli/src/commands/cob.rs
@@ -5,7 +5,7 @@ use anyhow::anyhow;
use chrono::prelude::*;
use nonempty::NonEmpty;
use radicle::cob;
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::storage::ReadStorage;
use radicle_cob::object::collaboration::list;

@@ -46,7 +46,7 @@ enum Operation {
}

pub struct Options {
-
    rid: Id,
+
    rid: RepoId,
    op: Operation,
    type_name: cob::TypeName,
}
@@ -59,7 +59,7 @@ impl Args for Options {
        let mut op: Option<OperationName> = None;
        let mut type_name: Option<cob::TypeName> = None;
        let mut oid: Option<Rev> = None;
-
        let mut rid: Option<Id> = None;
+
        let mut rid: Option<RepoId> = None;

        while let Some(arg) = parser.next()? {
            match arg {
modified radicle-cli/src/commands/fork.rs
@@ -2,7 +2,7 @@ use std::ffi::OsString;

use anyhow::Context as _;

-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::rad;

use crate::terminal as term;
@@ -25,7 +25,7 @@ Options
};

pub struct Options {
-
    rid: Option<Id>,
+
    rid: Option<RepoId>,
}

impl Args for Options {
modified radicle-cli/src/commands/id.rs
@@ -5,7 +5,7 @@ use anyhow::{anyhow, Context};
use nonempty::NonEmpty;
use radicle::cob::identity::{self, IdentityMut, Revision, RevisionId};
use radicle::identity::{doc, Identity, Visibility};
-
use radicle::prelude::{Did, Doc, Id, Signer};
+
use radicle::prelude::{Did, Doc, RepoId, Signer};
use radicle::storage::refs;
use radicle::storage::{ReadRepository, ReadStorage as _, WriteRepository};
use radicle::{cob, Profile};
@@ -92,7 +92,7 @@ pub enum OperationName {

pub struct Options {
    pub op: Operation,
-
    pub rid: Option<Id>,
+
    pub rid: Option<RepoId>,
    pub interactive: Interactive,
    pub quiet: bool,
}
@@ -104,7 +104,7 @@ impl Args for Options {
        let mut parser = lexopt::Parser::from_args(args);
        let mut op: Option<OperationName> = None;
        let mut revision: Option<Rev> = None;
-
        let mut rid: Option<Id> = None;
+
        let mut rid: Option<RepoId> = None;
        let mut title: Option<String> = None;
        let mut description: Option<String> = None;
        let mut delegate: Vec<Did> = Vec::new();
modified radicle-cli/src/commands/init.rs
@@ -13,7 +13,7 @@ use serde_json as json;
use radicle::crypto::{ssh, Verified};
use radicle::explorer::ExplorerUrl;
use radicle::git::RefString;
-
use radicle::identity::{Id, Visibility};
+
use radicle::identity::{RepoId, Visibility};
use radicle::node::policy::Scope;
use radicle::node::{Event, Handle, NodeId};
use radicle::prelude::Doc;
@@ -354,7 +354,7 @@ enum SyncResult<T> {
}

fn sync(
-
    rid: Id,
+
    rid: RepoId,
    node: &mut Node,
    config: &profile::Config,
) -> Result<SyncResult<Option<ExplorerUrl>>, radicle::node::Error> {
@@ -438,7 +438,7 @@ fn sync(
}

pub fn announce(
-
    rid: Id,
+
    rid: RepoId,
    doc: Doc<Verified>,
    node: &mut Node,
    config: &profile::Config,
modified radicle-cli/src/commands/inspect.rs
@@ -7,8 +7,8 @@ use std::str::FromStr;
use anyhow::{anyhow, Context as _};
use chrono::prelude::*;

-
use radicle::identity::Id;
use radicle::identity::Identity;
+
use radicle::identity::RepoId;
use radicle::node::policy::Policy;
use radicle::node::AliasStore as _;
use radicle::storage::refs::RefsAt;
@@ -64,7 +64,7 @@ pub enum Target {

#[derive(Default, Debug, Eq, PartialEq)]
pub struct Options {
-
    pub rid: Option<Id>,
+
    pub rid: Option<RepoId>,
    pub target: Target,
}

@@ -73,7 +73,7 @@ impl Args for Options {
        use lexopt::prelude::*;

        let mut parser = lexopt::Parser::from_args(args);
-
        let mut rid: Option<Id> = None;
+
        let mut rid: Option<RepoId> = None;
        let mut target = Target::default();

        while let Some(arg) = parser.next()? {
@@ -111,7 +111,7 @@ impl Args for Options {
                Value(val) if rid.is_none() => {
                    let val = val.to_string_lossy();

-
                    if let Ok(val) = Id::from_str(&val) {
+
                    if let Ok(val) = RepoId::from_str(&val) {
                        rid = Some(val);
                    } else if let Ok(val) = PathBuf::from_str(&val) {
                        rid = radicle::rad::at(val)
modified radicle-cli/src/commands/node.rs
@@ -4,7 +4,7 @@ use std::time;
use anyhow::anyhow;

use radicle::node::{Address, Node, NodeId, PeerAddr};
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;

use crate::terminal as term;
use crate::terminal::args::{Args, Error, Help};
@@ -73,7 +73,7 @@ pub enum Operation {
    },
    Routing {
        json: bool,
-
        rid: Option<Id>,
+
        rid: Option<RepoId>,
        nid: Option<NodeId>,
    },
    Start {
@@ -112,7 +112,7 @@ impl Args for Options {
        let mut parser = lexopt::Parser::from_args(args);
        let mut op: Option<OperationName> = None;
        let mut nid: Option<NodeId> = None;
-
        let mut rid: Option<Id> = None;
+
        let mut rid: Option<RepoId> = None;
        let mut json: bool = false;
        let mut addr: Option<PeerAddr<NodeId, Address>> = None;
        let mut lines: usize = 60;
modified radicle-cli/src/commands/node/routing.rs
@@ -1,12 +1,12 @@
use radicle::node;
-
use radicle::prelude::{Id, NodeId};
+
use radicle::prelude::{NodeId, RepoId};

use crate::terminal as term;
use crate::terminal::Element;

pub fn run<S: node::routing::Store>(
    routing: &S,
-
    rid: Option<Id>,
+
    rid: Option<RepoId>,
    nid: Option<NodeId>,
    json: bool,
) -> anyhow::Result<()> {
@@ -25,7 +25,7 @@ pub fn run<S: node::routing::Store>(
    Ok(())
}

-
fn print_table(entries: impl IntoIterator<Item = (Id, NodeId)>) {
+
fn print_table(entries: impl IntoIterator<Item = (RepoId, NodeId)>) {
    let mut t = term::Table::new(term::table::TableOptions::bordered());
    t.push([
        term::format::default(String::from("RID")),
@@ -42,7 +42,7 @@ fn print_table(entries: impl IntoIterator<Item = (Id, NodeId)>) {
    t.print();
}

-
fn print_json(entries: impl IntoIterator<Item = (Id, NodeId)>) {
+
fn print_json(entries: impl IntoIterator<Item = (RepoId, NodeId)>) {
    for (rid, nid) in entries {
        println!("{}", serde_json::json!({ "rid": rid, "nid": nid }));
    }
modified radicle-cli/src/commands/publish.rs
@@ -4,7 +4,7 @@ use anyhow::{anyhow, Context as _};

use radicle::identity::{Identity, Visibility};
use radicle::node::Handle as _;
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::storage::{SignRepository, ValidateRepository, WriteRepository, WriteStorage};

use crate::terminal as term;
@@ -38,7 +38,7 @@ Options

#[derive(Default, Debug)]
pub struct Options {
-
    pub rid: Option<Id>,
+
    pub rid: Option<RepoId>,
}

impl Args for Options {
modified radicle-cli/src/commands/remote/add.rs
@@ -13,7 +13,7 @@ use crate::commands::rad_sync as sync;
use crate::project::SetupRemote;

pub fn run(
-
    rid: Id,
+
    rid: RepoId,
    nid: &PublicKey,
    name: Option<RefString>,
    tracking: Option<BranchName>,
modified radicle-cli/src/commands/remote/list.rs
@@ -1,7 +1,7 @@
use std::collections::HashSet;

use radicle::git::Url;
-
use radicle::identity::{Did, Id};
+
use radicle::identity::{Did, RepoId};
use radicle::node::{Alias, AliasStore as _, NodeId};
use radicle::storage::ReadStorage as _;
use radicle::Profile;
@@ -56,7 +56,7 @@ pub fn tracked(working: &git::Repository) -> anyhow::Result<Vec<Tracked>> {
}

pub fn untracked<'a>(
-
    rid: Id,
+
    rid: RepoId,
    profile: &Profile,
    tracked: impl Iterator<Item = &'a Tracked>,
) -> anyhow::Result<Vec<Untracked>> {
modified radicle-cli/src/commands/seed.rs
@@ -46,9 +46,15 @@ Options

#[derive(Debug)]
pub enum Operation {
-
    Seed { rid: Id, fetch: bool, scope: Scope },
+
    Seed {
+
        rid: RepoId,
+
        fetch: bool,
+
        scope: Scope,
+
    },
    List,
-
    Unseed { rid: Id },
+
    Unseed {
+
        rid: RepoId,
+
    },
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
@@ -69,7 +75,7 @@ impl Args for Options {
        use lexopt::prelude::*;

        let mut parser = lexopt::Parser::from_args(args);
-
        let mut rid: Option<Id> = None;
+
        let mut rid: Option<RepoId> = None;
        let mut scope: Option<Scope> = None;
        let mut fetch: Option<bool> = None;
        let mut op: Option<OperationName> = None;
@@ -144,7 +150,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
}

pub fn update(
-
    rid: Id,
+
    rid: RepoId,
    scope: Scope,
    node: &mut Node,
    profile: &Profile,
@@ -160,7 +166,7 @@ pub fn update(
    Ok(())
}

-
pub fn delete(rid: Id, node: &mut Node, profile: &Profile) -> anyhow::Result<()> {
+
pub fn delete(rid: RepoId, node: &mut Node, profile: &Profile) -> anyhow::Result<()> {
    if project::unseed(rid, node, profile)? {
        term::success!("Seeding policy for {} removed", term::format::tertiary(rid));
    }
modified radicle-cli/src/commands/sync.rs
@@ -10,7 +10,7 @@ use radicle::node;
use radicle::node::AliasStore;
use radicle::node::Seed;
use radicle::node::{FetchResult, FetchResults, Handle as _, Node, SyncStatus};
-
use radicle::prelude::{Id, NodeId, Profile};
+
use radicle::prelude::{NodeId, Profile, RepoId};
use radicle::storage::{ReadRepository, ReadStorage};
use radicle_term::Element;

@@ -138,7 +138,7 @@ pub enum SyncDirection {

#[derive(Default, Debug)]
pub struct Options {
-
    pub rid: Option<Id>,
+
    pub rid: Option<RepoId>,
    pub verbose: bool,
    pub timeout: time::Duration,
    pub sort_by: SortBy,
@@ -306,7 +306,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
}

fn sync_status(
-
    rid: Id,
+
    rid: RepoId,
    node: &mut Node,
    profile: &Profile,
    options: &Options,
@@ -375,7 +375,7 @@ fn sync_status(
}

fn announce_refs(
-
    rid: Id,
+
    rid: RepoId,
    mode: RepoSync,
    timeout: time::Duration,
    mut node: Node,
@@ -482,7 +482,7 @@ pub fn announce_inventory(mut node: Node) -> anyhow::Result<()> {
}

pub fn fetch(
-
    rid: Id,
+
    rid: RepoId,
    mode: RepoSync,
    timeout: time::Duration,
    node: &mut Node,
@@ -501,7 +501,7 @@ pub fn fetch(
}

fn fetch_all(
-
    rid: Id,
+
    rid: RepoId,
    count: usize,
    timeout: time::Duration,
    node: &mut Node,
@@ -562,7 +562,7 @@ fn fetch_all(
}

fn fetch_from(
-
    rid: Id,
+
    rid: RepoId,
    seed: &NodeId,
    timeout: time::Duration,
    node: &mut Node,
modified radicle-cli/src/commands/watch.rs
@@ -4,7 +4,7 @@ use std::{thread, time};
use anyhow::{anyhow, Context as _};

use radicle::git;
-
use radicle::prelude::{Id, NodeId};
+
use radicle::prelude::{NodeId, RepoId};
use radicle::storage::{ReadRepository, ReadStorage};

use crate::terminal as term;
@@ -39,7 +39,7 @@ Options
};

pub struct Options {
-
    rid: Option<Id>,
+
    rid: Option<RepoId>,
    refstr: git::RefString,
    target: Option<git::Oid>,
    nid: Option<NodeId>,
modified radicle-cli/src/git.rs
@@ -22,7 +22,7 @@ use radicle::crypto::ssh;
use radicle::git;
use radicle::git::raw as git2;
use radicle::git::{Version, VERSION_REQUIRED};
-
use radicle::prelude::{Id, NodeId};
+
use radicle::prelude::{NodeId, RepoId};
use radicle::storage::git::transport;

pub use radicle::git::raw::{
@@ -260,7 +260,7 @@ pub fn is_remote(repo: &git2::Repository, alias: &str) -> anyhow::Result<bool> {
}

/// Get the repository's "rad" remote.
-
pub fn rad_remote(repo: &Repository) -> anyhow::Result<(git2::Remote, Id)> {
+
pub fn rad_remote(repo: &Repository) -> anyhow::Result<(git2::Remote, RepoId)> {
    match radicle::rad::remote(repo) {
        Ok((remote, id)) => Ok((remote, id)),
        Err(radicle::rad::RemoteError::NotFound(_)) => Err(anyhow!(
@@ -270,7 +270,7 @@ pub fn rad_remote(repo: &Repository) -> anyhow::Result<(git2::Remote, Id)> {
    }
}

-
pub fn remove_remote(repo: &Repository, rid: &Id) -> anyhow::Result<()> {
+
pub fn remove_remote(repo: &Repository, rid: &RepoId) -> anyhow::Result<()> {
    // N.b. ensure that we are removing the remote for the correct RID
    match radicle::rad::remote(repo) {
        Ok((_, rid_)) => {
modified radicle-cli/src/node.rs
@@ -1,7 +1,7 @@
use std::ops::ControlFlow;
use std::time::Duration;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::node;
use radicle::node::Handle as _;
use radicle::Node;
@@ -9,7 +9,7 @@ use radicle::Node;
use crate::terminal as term;

/// Announce changes to the network.
-
pub fn announce(rid: Id, node: &mut Node) -> anyhow::Result<()> {
+
pub fn announce(rid: RepoId, node: &mut Node) -> anyhow::Result<()> {
    match announce_(rid, node) {
        Ok(()) => Ok(()),
        Err(e) if e.is_connection_err() => {
@@ -20,7 +20,7 @@ pub fn announce(rid: Id, node: &mut Node) -> anyhow::Result<()> {
    }
}

-
fn announce_(rid: Id, node: &mut Node) -> Result<(), radicle::node::Error> {
+
fn announce_(rid: RepoId, node: &mut Node) -> Result<(), radicle::node::Error> {
    let seeds = node.seeds(rid)?;
    let connected = seeds.connected().map(|s| s.nid).collect::<Vec<_>>();

modified radicle-cli/src/project.rs
@@ -6,10 +6,10 @@ use radicle::node::policy::Scope;
use radicle::node::{Handle, NodeId};
use radicle::Node;

-
/// Setup a project remote and tracking branch.
+
/// Setup a repository remote and tracking branch.
pub struct SetupRemote<'a> {
-
    /// The project id.
-
    pub rid: Id,
+
    /// The repository id.
+
    pub rid: RepoId,
    /// Whether or not to setup a remote tracking branch.
    pub tracking: Option<BranchName>,
    /// Whether or not to fetch the remote immediately.
@@ -55,7 +55,7 @@ impl<'a> SetupRemote<'a> {
/// Seed a repository by first trying to seed through the node, and if the node isn't running,
/// by updating the policy database directly.
pub fn seed(
-
    rid: Id,
+
    rid: RepoId,
    scope: Scope,
    node: &mut Node,
    profile: &Profile,
@@ -72,7 +72,7 @@ pub fn seed(

/// Unseed a repository by first trying to unseed through the node, and if the node isn't running,
/// by updating the policy database directly.
-
pub fn unseed(rid: Id, node: &mut Node, profile: &Profile) -> Result<bool, anyhow::Error> {
+
pub fn unseed(rid: RepoId, node: &mut Node, profile: &Profile) -> Result<bool, anyhow::Error> {
    match node.unseed(rid) {
        Ok(updated) => Ok(updated),
        Err(e) if e.is_connection_err() => {
modified radicle-cli/src/terminal/args.rs
@@ -9,7 +9,7 @@ use radicle::cob::{self, issue, patch};
use radicle::crypto;
use radicle::git::{Oid, RefString};
use radicle::node::{Address, Alias};
-
use radicle::prelude::{Did, Id, NodeId};
+
use radicle::prelude::{Did, NodeId, RepoId};

use crate::git::Rev;

@@ -116,9 +116,9 @@ pub fn nid(val: &OsString) -> anyhow::Result<NodeId> {
    NodeId::from_str(&val).map_err(|_| anyhow!("invalid Node ID '{}'", val))
}

-
pub fn rid(val: &OsString) -> anyhow::Result<Id> {
+
pub fn rid(val: &OsString) -> anyhow::Result<RepoId> {
    let val = val.to_string_lossy();
-
    Id::from_str(&val).map_err(|_| anyhow!("invalid Repository ID '{}'", val))
+
    RepoId::from_str(&val).map_err(|_| anyhow!("invalid Repository ID '{}'", val))
}

pub fn pubkey(val: &OsString) -> anyhow::Result<NodeId> {
modified radicle-cli/tests/commands.rs
@@ -8,7 +8,7 @@ use radicle::node::address::Store as _;
use radicle::node::routing::Store as _;
use radicle::node::Handle as _;
use radicle::node::{Alias, DEFAULT_TIMEOUT};
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::profile;
use radicle::profile::{Home, PreferredSeeds};
use radicle::storage::{ReadStorage, RemoteRepository};
@@ -301,7 +301,7 @@ fn rad_id() {
    let bob = environment.node(config::node("bob"));
    let working = tempfile::tempdir().unwrap();
    let working = working.path();
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    // Setup a test repository.
    fixtures::repository(working.join("alice"));
@@ -350,7 +350,7 @@ fn rad_id_multi_delegate() {
    let eve = environment.node(Config::test(Alias::new("eve")));
    let working = tempfile::tempdir().unwrap();
    let working = working.path();
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    // Setup a test repository.
    fixtures::repository(working.join("alice"));
@@ -409,7 +409,7 @@ fn rad_id_collaboration() {
    let distrustful = environment.node(config::seed("distrustful"));
    let working = tempfile::tempdir().unwrap();
    let working = working.path();
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    // Setup a test repository.
    fixtures::repository(working.join("alice"));
@@ -511,7 +511,7 @@ fn rad_id_conflict() {
    let bob = environment.node(Config::test(Alias::new("bob")));
    let working = tempfile::tempdir().unwrap();
    let working = working.path();
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    // Setup a test repository.
    fixtures::repository(working.join("alice"));
@@ -696,7 +696,7 @@ fn rad_patch_checkout_force() {
    let alice = environment.node(Config::test(Alias::new("alice")));
    let bob = environment.node(Config::test(Alias::new("bob")));
    let working = environment.tmp().join("working");
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    // Setup a test repository.
    fixtures::repository(working.join("alice"));
@@ -895,7 +895,7 @@ fn rad_clean() {
    let working = environment.tmp().join("working");

    // Setup a test project.
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
    fixtures::repository(working.join("acme"));
    test(
        "examples/rad-init.md",
@@ -1060,7 +1060,7 @@ fn rad_clone_connect() {
    let alice = environment.node(Config::test(Alias::new("alice")));
    let bob = environment.node(Config::test(Alias::new("bob")));
    let mut eve = environment.node(Config::test(Alias::new("eve")));
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
    let now = localtime::LocalTime::now().as_secs();

    fixtures::repository(working.join("acme"));
@@ -1134,7 +1134,7 @@ fn rad_sync_without_node() {
    let bob = environment.node(Config::test(Alias::new("bob")));
    let mut eve = environment.node(Config::test(Alias::new("eve")));

-
    let rid = Id::from_urn("rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5").unwrap();
+
    let rid = RepoId::from_urn("rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5").unwrap();
    eve.policies.seed(&rid, Scope::All).unwrap();

    formula(&environment.tmp(), "examples/rad-sync-without-node.md")
@@ -1527,7 +1527,7 @@ fn rad_sync() {
    let alice = environment.node(config::node("alice"));
    let bob = environment.node(config::node("bob"));
    let eve = environment.node(config::node("eve"));
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    fixtures::repository(working.join("acme"));

@@ -1576,7 +1576,7 @@ fn test_replication_via_seed() {
        ..Config::test(Alias::new("seed"))
    });
    let working = environment.tmp().join("working");
-
    let rid = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let rid = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    let mut alice = alice.spawn();
    let mut bob = bob.spawn();
@@ -1657,7 +1657,7 @@ fn rad_remote() {
    let eve = environment.node(Config::test(Alias::new("eve")));
    let working = environment.tmp().join("working");
    let home = alice.home.clone();
-
    let rid = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let rid = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
    // Setup a test repository.
    fixtures::repository(working.join("alice"));

@@ -1991,7 +1991,7 @@ fn git_push_diverge() {
    let alice = environment.node(Config::test(Alias::new("alice")));
    let bob = environment.node(Config::test(Alias::new("bob")));
    let working = environment.tmp().join("working");
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    fixtures::repository(working.join("alice"));

@@ -2032,7 +2032,7 @@ fn rad_push_and_pull_patches() {
    let alice = environment.node(Config::test(Alias::new("alice")));
    let bob = environment.node(Config::test(Alias::new("bob")));
    let working = environment.tmp().join("working");
-
    let acme = Id::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();
+
    let acme = RepoId::from_str("z42hL2jL4XNk6K8oHQaSWfMgCL7ji").unwrap();

    fixtures::repository(working.join("alice"));

modified radicle-fetch/src/handle.rs
@@ -87,7 +87,7 @@ pub mod error {
    use std::io;

    use radicle::node::policy;
-
    use radicle::prelude::Id;
+
    use radicle::prelude::RepoId;
    use radicle::{git, storage};
    use thiserror::Error;

@@ -103,15 +103,15 @@ pub mod error {
    pub enum Tracking {
        #[error("failed to find policy for {rid}")]
        FailedPolicy {
-
            rid: Id,
+
            rid: RepoId,
            #[source]
            err: policy::store::Error,
        },
        #[error("cannot fetch {rid} as it is not seeded")]
-
        BlockedPolicy { rid: Id },
+
        BlockedPolicy { rid: RepoId },
        #[error("failed to get tracking nodes for {rid}")]
        FailedNodes {
-
            rid: Id,
+
            rid: RepoId,
            #[source]
            err: policy::store::Error,
        },
modified radicle-fetch/src/policy.rs
@@ -3,7 +3,7 @@ use std::collections::HashSet;
use radicle::crypto::PublicKey;
use radicle::node::policy::config::Config;
use radicle::node::policy::store::Read;
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;

pub use radicle::node::policy::{Policy, Scope};

@@ -14,7 +14,7 @@ pub enum Allowed {
}

impl Allowed {
-
    pub fn from_config(rid: Id, config: &Config<Read>) -> Result<Self, error::Policy> {
+
    pub fn from_config(rid: RepoId, config: &Config<Read>) -> Result<Self, error::Policy> {
        let entry = config
            .repo_policy(&rid)
            .map_err(|err| error::Policy::FailedPolicy { rid, err })?;
@@ -71,7 +71,7 @@ impl BlockList {

pub mod error {
    use radicle::node::policy;
-
    use radicle::prelude::Id;
+
    use radicle::prelude::RepoId;
    use radicle::storage;
    use thiserror::Error;

@@ -83,15 +83,15 @@ pub mod error {
    pub enum Policy {
        #[error("failed to find policy for {rid}")]
        FailedPolicy {
-
            rid: Id,
+
            rid: RepoId,
            #[source]
            err: policy::store::Error,
        },
        #[error("cannot fetch {rid} as it is not seeded")]
-
        BlockedPolicy { rid: Id },
+
        BlockedPolicy { rid: RepoId },
        #[error("failed to get followed nodes for {rid}")]
        FailedNodes {
-
            rid: Id,
+
            rid: RepoId,
            #[source]
            err: policy::store::Error,
        },
modified radicle-httpd/src/api.rs
@@ -16,7 +16,7 @@ use tower_http::cors::{self, CorsLayer};

use radicle::cob::issue;
use radicle::cob::patch;
-
use radicle::identity::{DocAt, Id};
+
use radicle::identity::{DocAt, RepoId};
use radicle::node::policy::Scope;
use radicle::node::routing::Store;
use radicle::node::{Handle, NodeId};
@@ -52,7 +52,7 @@ impl Context {
        }
    }

-
    pub fn project_info(&self, id: Id) -> Result<project::Info, error::Error> {
+
    pub fn project_info(&self, id: RepoId) -> Result<project::Info, error::Error> {
        let storage = &self.profile.storage;
        let repo = storage.repository(id)?;
        let (_, head) = repo.head()?;
@@ -196,7 +196,7 @@ mod project {
    use radicle::cob;
    use radicle::git::Oid;
    use radicle::identity::project::Project;
-
    use radicle::identity::{Id, Visibility};
+
    use radicle::identity::{RepoId, Visibility};
    use radicle::prelude::Did;

    /// Project info.
@@ -211,13 +211,13 @@ mod project {
        pub head: Oid,
        pub patches: cob::patch::PatchCounts,
        pub issues: cob::issue::IssueCounts,
-
        pub id: Id,
+
        pub id: RepoId,
        pub seeding: usize,
    }
}

/// Announce refs to the network for the given RID.
-
pub fn announce_refs(mut node: Node, rid: Id) -> Result<(), Error> {
+
pub fn announce_refs(mut node: Node, rid: RepoId) -> Result<(), Error> {
    match node.announce_refs(rid) {
        Ok(_) => Ok(()),
        Err(e) if e.is_connection_err() => Ok(()),
modified radicle-httpd/src/api/v1/node.rs
@@ -6,7 +6,7 @@ use axum_auth::AuthBearer;
use hyper::StatusCode;
use serde_json::json;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::node::{policy, Handle, DEFAULT_TIMEOUT};
use radicle::Node;

@@ -74,7 +74,7 @@ async fn node_policies_repos_handler(State(ctx): State<Context>) -> impl IntoRes
async fn node_policies_seed_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Query(qs): Query<PoliciesQuery>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
@@ -96,7 +96,7 @@ async fn node_policies_seed_handler(
async fn node_policies_unseed_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
    let mut node = Node::new(ctx.profile.socket());
modified radicle-httpd/src/api/v1/projects.rs
@@ -15,7 +15,7 @@ use serde_json::json;
use tower_http::set_header::SetResponseHeaderLayer;

use radicle::cob::{issue, patch, resolve_embed, Embed, Label, Uri};
-
use radicle::identity::{Did, Id, Visibility};
+
use radicle::identity::{Did, RepoId, Visibility};
use radicle::node::routing::Store;
use radicle::node::{AliasStore, Node, NodeId};
use radicle::storage::git::paths;
@@ -141,7 +141,7 @@ async fn project_root_handler(

/// Get project metadata.
/// `GET /projects/:project`
-
async fn project_handler(State(ctx): State<Context>, Path(id): Path<Id>) -> impl IntoResponse {
+
async fn project_handler(State(ctx): State<Context>, Path(id): Path<RepoId>) -> impl IntoResponse {
    let info = ctx.project_info(id)?;

    Ok::<_, Error>(Json(info))
@@ -161,7 +161,7 @@ pub struct CommitsQueryString {
/// `GET /projects/:project/commits?since=<sha>`
async fn history_handler(
    State(ctx): State<Context>,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Query(qs): Query<CommitsQueryString>,
) -> impl IntoResponse {
    let CommitsQueryString {
@@ -242,7 +242,7 @@ async fn history_handler(
/// `GET /projects/:project/commits/:sha`
async fn commit_handler(
    State(ctx): State<Context>,
-
    Path((project, sha)): Path<(Id, Oid)>,
+
    Path((project, sha)): Path<(RepoId, Oid)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = Repository::open(paths::repository(storage, &project))?;
@@ -308,7 +308,7 @@ async fn commit_handler(
/// `GET /projects/:project/diff/:base/:oid`
async fn diff_handler(
    State(ctx): State<Context>,
-
    Path((project, base, oid)): Path<(Id, Oid, Oid)>,
+
    Path((project, base, oid)): Path<(RepoId, Oid, Oid)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = Repository::open(paths::repository(storage, &project))?;
@@ -375,7 +375,7 @@ async fn diff_handler(
/// `GET /projects/:project/activity`
async fn activity_handler(
    State(ctx): State<Context>,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
) -> impl IntoResponse {
    let current_date = chrono::Utc::now().timestamp();
    let one_year_ago = chrono::Duration::weeks(52);
@@ -402,7 +402,7 @@ async fn activity_handler(
/// `GET /projects/:project/tree/:sha/`
async fn tree_handler_root(
    State(ctx): State<Context>,
-
    Path((project, sha)): Path<(Id, Oid)>,
+
    Path((project, sha)): Path<(RepoId, Oid)>,
) -> impl IntoResponse {
    tree_handler(State(ctx), Path((project, sha, String::new()))).await
}
@@ -411,7 +411,7 @@ async fn tree_handler_root(
/// `GET /projects/:project/tree/:sha/*path`
async fn tree_handler(
    State(ctx): State<Context>,
-
    Path((project, sha, path)): Path<(Id, Oid, String)>,
+
    Path((project, sha, path)): Path<(RepoId, Oid, String)>,
) -> impl IntoResponse {
    if let Some(ref cache) = ctx.cache {
        let cache = &mut cache.tree.lock().await;
@@ -436,7 +436,10 @@ async fn tree_handler(

/// Get all project remotes.
/// `GET /projects/:project/remotes`
-
async fn remotes_handler(State(ctx): State<Context>, Path(project): Path<Id>) -> impl IntoResponse {
+
async fn remotes_handler(
+
    State(ctx): State<Context>,
+
    Path(project): Path<RepoId>,
+
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = storage.repository(project)?;
    let delegates = repo.delegates()?;
@@ -478,7 +481,7 @@ async fn remotes_handler(State(ctx): State<Context>, Path(project): Path<Id>) ->
/// `GET /projects/:project/remotes/:peer`
async fn remote_handler(
    State(ctx): State<Context>,
-
    Path((project, node_id)): Path<(Id, NodeId)>,
+
    Path((project, node_id)): Path<(RepoId, NodeId)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = storage.repository(project)?;
@@ -506,7 +509,7 @@ async fn remote_handler(
/// `GET /projects/:project/blob/:sha/*path`
async fn blob_handler(
    State(ctx): State<Context>,
-
    Path((project, sha, path)): Path<(Id, Oid, String)>,
+
    Path((project, sha, path)): Path<(RepoId, Oid, String)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = Repository::open(paths::repository(storage, &project))?;
@@ -520,7 +523,7 @@ async fn blob_handler(
/// `GET /projects/:project/readme/:sha`
async fn readme_handler(
    State(ctx): State<Context>,
-
    Path((project, sha)): Path<(Id, Oid)>,
+
    Path((project, sha)): Path<(RepoId, Oid)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = Repository::open(paths::repository(storage, &project))?;
@@ -551,7 +554,7 @@ async fn readme_handler(
/// `GET /projects/:project/issues`
async fn issues_handler(
    State(ctx): State<Context>,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Query(qs): Query<CobsQuery<api::IssueState>>,
) -> impl IntoResponse {
    let CobsQuery {
@@ -599,7 +602,7 @@ pub struct IssueCreate {
async fn issue_create_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Json(issue): Json<IssueCreate>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
@@ -641,7 +644,7 @@ async fn issue_create_handler(
async fn issue_update_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path((project, issue_id)): Path<(Id, Oid)>,
+
    Path((project, issue_id)): Path<(RepoId, Oid)>,
    Json(action): Json<issue::Action>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
@@ -696,7 +699,7 @@ async fn issue_update_handler(
/// `GET /projects/:project/issues/:id`
async fn issue_handler(
    State(ctx): State<Context>,
-
    Path((project, issue_id)): Path<(Id, Oid)>,
+
    Path((project, issue_id)): Path<(RepoId, Oid)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = storage.repository(project)?;
@@ -722,7 +725,7 @@ pub struct PatchCreate {
async fn patch_create_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Json(patch): Json<PatchCreate>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
@@ -761,7 +764,7 @@ async fn patch_create_handler(
async fn patch_update_handler(
    State(ctx): State<Context>,
    AuthBearer(token): AuthBearer,
-
    Path((project, patch_id)): Path<(Id, Oid)>,
+
    Path((project, patch_id)): Path<(RepoId, Oid)>,
    Json(action): Json<patch::Action>,
) -> impl IntoResponse {
    api::auth::validate(&ctx, &token).await?;
@@ -901,7 +904,7 @@ async fn patch_update_handler(
/// `GET /projects/:project/patches`
async fn patches_handler(
    State(ctx): State<Context>,
-
    Path(project): Path<Id>,
+
    Path(project): Path<RepoId>,
    Query(qs): Query<CobsQuery<api::PatchState>>,
) -> impl IntoResponse {
    let CobsQuery {
@@ -938,7 +941,7 @@ async fn patches_handler(
/// `GET /projects/:project/patches/:id`
async fn patch_handler(
    State(ctx): State<Context>,
-
    Path((project, patch_id)): Path<(Id, Oid)>,
+
    Path((project, patch_id)): Path<(RepoId, Oid)>,
) -> impl IntoResponse {
    let storage = &ctx.profile.storage;
    let repo = storage.repository(project)?;
modified radicle-httpd/src/cache.rs
@@ -4,12 +4,12 @@ use std::sync::Arc;
use lru::LruCache;
use tokio::sync::Mutex;

-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle_surf::Oid;

#[derive(Clone)]
pub struct Cache {
-
    pub tree: Arc<Mutex<LruCache<(Id, Oid, String), serde_json::Value>>>,
+
    pub tree: Arc<Mutex<LruCache<(RepoId, Oid, String), serde_json::Value>>>,
}

impl Cache {
modified radicle-httpd/src/git.rs
@@ -16,19 +16,19 @@ use axum::Router;
use flate2::write::GzDecoder;
use hyper::body::Buf as _;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::profile::Profile;

use crate::error::GitError as Error;

-
pub fn router(profile: Arc<Profile>, aliases: HashMap<String, Id>) -> Router {
+
pub fn router(profile: Arc<Profile>, aliases: HashMap<String, RepoId>) -> Router {
    Router::new()
        .route("/:project/*request", any(git_handler))
        .with_state((profile, aliases))
}

async fn git_handler(
-
    State((profile, aliases)): State<(Arc<Profile>, HashMap<String, Id>)>,
+
    State((profile, aliases)): State<(Arc<Profile>, HashMap<String, RepoId>)>,
    AxumPath((project, request)): AxumPath<(String, String)>,
    method: Method,
    headers: HeaderMap,
@@ -38,7 +38,7 @@ async fn git_handler(
) -> impl IntoResponse {
    let query = query.0.unwrap_or_default();
    let name = project.strip_suffix(".git").unwrap_or(&project);
-
    let rid: Id = match name.parse() {
+
    let rid: RepoId = match name.parse() {
        Ok(rid) => rid,
        Err(_) => {
            let Some(rid) = aliases.get(name) else {
@@ -70,7 +70,7 @@ async fn git_http_backend(
    headers: HeaderMap,
    mut body: Bytes,
    remote: net::SocketAddr,
-
    id: Id,
+
    id: RepoId,
    path: &str,
    query: String,
) -> Result<(StatusCode, HashMap<String, Vec<String>>, Vec<u8>), Error> {
@@ -210,7 +210,7 @@ mod routes {

    use axum::extract::connect_info::MockConnectInfo;
    use axum::http::StatusCode;
-
    use radicle::identity::Id;
+
    use radicle::identity::RepoId;

    use crate::test::{self, get, RID};

@@ -232,7 +232,7 @@ mod routes {
        let ctx = test::seed(tmp.path());
        let app = super::router(
            ctx.profile().to_owned(),
-
            HashMap::from_iter([(String::from("heartwood"), Id::from_str(RID).unwrap())]),
+
            HashMap::from_iter([(String::from("heartwood"), RepoId::from_str(RID).unwrap())]),
        )
        .layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 8080))));

modified radicle-httpd/src/lib.rs
@@ -21,7 +21,7 @@ use tokio::net::TcpListener;
use tower_http::trace::TraceLayer;
use tracing::Span;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::Profile;

use tracing_extra::{tracing_middleware, ColoredStatus, Paint, RequestId, TracingInfo};
@@ -40,7 +40,7 @@ pub const DEFAULT_CACHE_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecke

#[derive(Debug, Clone)]
pub struct Options {
-
    pub aliases: HashMap<String, Id>,
+
    pub aliases: HashMap<String, RepoId>,
    pub listen: SocketAddr,
    pub cache: Option<NonZeroUsize>,
}
modified radicle-httpd/src/main.rs
@@ -1,7 +1,7 @@
use std::num::NonZeroUsize;
use std::{collections::HashMap, process};

-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle_httpd as httpd;

#[tokio::main]
@@ -39,7 +39,7 @@ fn parse_options() -> Result<httpd::Options, lexopt::Error> {
            }
            Long("alias") | Short('a') => {
                let alias: String = parser.value()?.parse()?;
-
                let id: Id = parser.value()?.parse()?;
+
                let id: RepoId = parser.value()?.parse()?;

                aliases.insert(alias, id);
            }
modified radicle-httpd/src/raw.rs
@@ -9,7 +9,7 @@ use axum::Router;
use hyper::HeaderMap;
use tower_http::cors;

-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::profile::Profile;
use radicle::storage::{ReadRepository, ReadStorage};
use radicle_surf::{Oid, Repository};
@@ -107,7 +107,7 @@ pub fn router(profile: Arc<Profile>) -> Router {
}

async fn file_by_path_handler(
-
    Path((project, sha, path)): Path<(Id, Oid, String)>,
+
    Path((project, sha, path)): Path<(RepoId, Oid, String)>,
    State(profile): State<Arc<Profile>>,
) -> impl IntoResponse {
    let storage = &profile.storage;
@@ -134,7 +134,7 @@ async fn file_by_path_handler(
}

async fn file_by_oid_handler(
-
    Path((project, oid)): Path<(Id, Oid)>,
+
    Path((project, oid)): Path<(RepoId, Oid)>,
    State(profile): State<Arc<Profile>>,
    Query(qs): Query<RawQuery>,
) -> impl IntoResponse {
modified radicle-node/src/control.rs
@@ -10,7 +10,7 @@ use std::{io, net, time};
use radicle::node::Handle;
use serde_json as json;

-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node::NodeId;
use crate::node::{Command, CommandResult};
use crate::runtime;
@@ -201,7 +201,7 @@ where
}

fn fetch<W: Write, H: Handle<Error = runtime::HandleError>>(
-
    id: Id,
+
    id: RepoId,
    node: NodeId,
    timeout: time::Duration,
    mut writer: W,
@@ -225,7 +225,7 @@ mod tests {
    use std::thread;

    use super::*;
-
    use crate::identity::Id;
+
    use crate::identity::RepoId;
    use crate::node::Handle;
    use crate::node::{Alias, Node, NodeId};
    use crate::service::policy::Scope;
@@ -236,7 +236,7 @@ mod tests {
        let tmp = tempfile::tempdir().unwrap();
        let handle = test::handle::Handle::default();
        let socket = tmp.path().join("alice.sock");
-
        let rids = test::arbitrary::set::<Id>(1..3);
+
        let rids = test::arbitrary::set::<RepoId>(1..3);
        let listener = UnixListener::bind(&socket).unwrap();

        thread::spawn({
@@ -283,7 +283,7 @@ mod tests {
    fn test_seed_unseed() {
        let tmp = tempfile::tempdir().unwrap();
        let socket = tmp.path().join("node.sock");
-
        let proj = test::arbitrary::gen::<Id>(1);
+
        let proj = test::arbitrary::gen::<RepoId>(1);
        let peer = test::arbitrary::gen::<NodeId>(1);
        let listener = UnixListener::bind(&socket).unwrap();
        let mut handle = Node::new(&socket);
modified radicle-node/src/lib.rs
@@ -21,7 +21,7 @@ pub mod prelude {
    pub use crate::bounded::BoundedVec;
    pub use crate::crypto::{PublicKey, Signature, Signer};
    pub use crate::deserializer::Deserializer;
-
    pub use crate::identity::{Did, Id};
+
    pub use crate::identity::{Did, RepoId};
    pub use crate::node::Address;
    pub use crate::service::filter::Filter;
    pub use crate::service::{DisconnectReason, Event, Message, Network, NodeId};
modified radicle-node/src/runtime/handle.rs
@@ -9,7 +9,7 @@ use radicle::storage::refs::RefsAt;
use reactor::poller::popol::PopolWaker;
use thiserror::Error;

-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node::{Alias, Command, FetchResult};
use crate::profile::Home;
use crate::runtime::Emitter;
@@ -178,7 +178,7 @@ impl radicle::node::Handle for Handle {
            .map_err(Error::from)
    }

-
    fn seeds(&mut self, id: Id) -> Result<Seeds, Self::Error> {
+
    fn seeds(&mut self, id: RepoId) -> Result<Seeds, Self::Error> {
        let (sender, receiver) = chan::bounded(1);
        self.command(service::Command::Seeds(id, sender))?;
        receiver.recv().map_err(Error::from)
@@ -192,7 +192,7 @@ impl radicle::node::Handle for Handle {

    fn fetch(
        &mut self,
-
        id: Id,
+
        id: RepoId,
        from: NodeId,
        timeout: time::Duration,
    ) -> Result<FetchResult, Error> {
@@ -213,19 +213,19 @@ impl radicle::node::Handle for Handle {
        receiver.recv().map_err(Error::from)
    }

-
    fn seed(&mut self, id: Id, scope: policy::Scope) -> Result<bool, Error> {
+
    fn seed(&mut self, id: RepoId, scope: policy::Scope) -> Result<bool, Error> {
        let (sender, receiver) = chan::bounded(1);
        self.command(service::Command::Seed(id, scope, sender))?;
        receiver.recv().map_err(Error::from)
    }

-
    fn unseed(&mut self, id: Id) -> Result<bool, Error> {
+
    fn unseed(&mut self, id: RepoId) -> Result<bool, Error> {
        let (sender, receiver) = chan::bounded(1);
        self.command(service::Command::Unseed(id, sender))?;
        receiver.recv().map_err(Error::from)
    }

-
    fn announce_refs(&mut self, id: Id) -> Result<RefsAt, Error> {
+
    fn announce_refs(&mut self, id: RepoId) -> Result<RefsAt, Error> {
        let (sender, receiver) = chan::bounded(1);
        self.command(service::Command::AnnounceRefs(id, sender))?;
        receiver.recv().map_err(Error::from)
modified radicle-node/src/service.rs
@@ -34,7 +34,7 @@ use radicle::storage::RepositoryError;

use crate::crypto;
use crate::crypto::{Signer, Verified};
-
use crate::identity::{Doc, Id};
+
use crate::identity::{Doc, RepoId};
use crate::node::routing;
use crate::node::routing::InsertResult;
use crate::node::{
@@ -105,11 +105,11 @@ pub use message::REF_REMOTE_LIMIT;
#[derive(Default)]
struct SyncedRouting {
    /// Repo entries added.
-
    added: Vec<Id>,
+
    added: Vec<RepoId>,
    /// Repo entries removed.
-
    removed: Vec<Id>,
+
    removed: Vec<RepoId>,
    /// Repo entries updated (time).
-
    updated: Vec<Id>,
+
    updated: Vec<RepoId>,
}

impl SyncedRouting {
@@ -166,7 +166,7 @@ pub type QueryState = dyn Fn(&dyn ServiceState) -> Result<(), CommandError> + Se
/// Commands sent to the service by the operator.
pub enum Command {
    /// Announce repository references for given repository to peers.
-
    AnnounceRefs(Id, chan::Sender<RefsAt>),
+
    AnnounceRefs(RepoId, chan::Sender<RefsAt>),
    /// Announce local repositories to peers.
    AnnounceInventory,
    /// Announce local inventory to peers.
@@ -178,13 +178,13 @@ pub enum Command {
    /// Get the node configuration.
    Config(chan::Sender<Config>),
    /// Lookup seeds for the given repository in the routing table.
-
    Seeds(Id, chan::Sender<Seeds>),
+
    Seeds(RepoId, chan::Sender<Seeds>),
    /// Fetch the given repository from the network.
-
    Fetch(Id, NodeId, time::Duration, chan::Sender<FetchResult>),
+
    Fetch(RepoId, NodeId, time::Duration, chan::Sender<FetchResult>),
    /// Seed the given repository.
-
    Seed(Id, Scope, chan::Sender<bool>),
+
    Seed(RepoId, Scope, chan::Sender<bool>),
    /// Unseed the given repository.
-
    Unseed(Id, chan::Sender<bool>),
+
    Unseed(RepoId, chan::Sender<bool>),
    /// Follow the given node.
    Follow(NodeId, Option<Alias>, chan::Sender<bool>),
    /// Unfollow the given node.
@@ -261,7 +261,7 @@ impl FetchState {
#[derive(Debug)]
struct QueuedFetch {
    /// Repo being fetched.
-
    rid: Id,
+
    rid: RepoId,
    /// Peer being fetched from.
    from: NodeId,
    /// Result channel.
@@ -347,7 +347,7 @@ pub struct Service<D, S, G> {
    /// Source of entropy.
    rng: Rng,
    /// Ongoing fetches.
-
    fetching: HashMap<Id, FetchState>,
+
    fetching: HashMap<RepoId, FetchState>,
    /// Fetch queue.
    queue: VecDeque<QueuedFetch>,
    /// Request/connection rate limitter.
@@ -439,7 +439,7 @@ where

    /// Seed a repository.
    /// Returns whether or not the repo policy was updated.
-
    pub fn seed(&mut self, id: &Id, scope: Scope) -> Result<bool, policy::Error> {
+
    pub fn seed(&mut self, id: &RepoId, scope: Scope) -> Result<bool, policy::Error> {
        let updated = self.policies.seed(id, scope)?;
        self.filter.insert(id);

@@ -450,7 +450,7 @@ where
    /// Returns whether or not the repo policy was updated.
    /// Note that when unseeding, we don't announce anything to the network. This is because by
    /// simply not announcing it anymore, it will eventually be pruned by nodes.
-
    pub fn unseed(&mut self, id: &Id) -> Result<bool, policy::Error> {
+
    pub fn unseed(&mut self, id: &RepoId) -> Result<bool, policy::Error> {
        let updated = self.policies.unseed(id)?;
        // Nb. This is potentially slow if we have lots of repos. We should probably
        // only re-compute the filter when we've unseeded a certain amount of repos
@@ -514,7 +514,7 @@ where
    }

    /// Lookup a repository, both locally and in the routing table.
-
    pub fn lookup(&self, rid: Id) -> Result<Lookup, LookupError> {
+
    pub fn lookup(&self, rid: RepoId) -> Result<Lookup, LookupError> {
        let remote = self.db.routing().get(&rid)?.iter().cloned().collect();

        Ok(Lookup {
@@ -787,7 +787,7 @@ where
    /// another node's announcement.
    fn fetch_refs_at(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        from: NodeId,
        refs: NonEmpty<RefsAt>,
        timeout: time::Duration,
@@ -798,7 +798,7 @@ where
    /// Initiate an outgoing fetch for some repository.
    fn fetch(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        from: NodeId,
        timeout: time::Duration,
        channel: Option<chan::Sender<FetchResult>>,
@@ -808,7 +808,7 @@ where

    fn _fetch(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        from: NodeId,
        refs_at: Vec<RefsAt>,
        timeout: time::Duration,
@@ -852,7 +852,7 @@ where

    fn try_fetch(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        from: &NodeId,
        refs_at: Vec<RefsAt>,
        timeout: time::Duration,
@@ -897,7 +897,7 @@ where

    pub fn fetched(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        remote: NodeId,
        result: Result<fetch::FetchResult, FetchError>,
    ) {
@@ -1683,12 +1683,12 @@ where
    /// given inventory.
    fn sync_routing(
        &mut self,
-
        inventory: &[Id],
+
        inventory: &[RepoId],
        from: NodeId,
        timestamp: Timestamp,
    ) -> Result<SyncedRouting, Error> {
        let mut synced = SyncedRouting::default();
-
        let included: HashSet<&Id> = HashSet::from_iter(inventory);
+
        let included: HashSet<&RepoId> = HashSet::from_iter(inventory);

        for (rid, result) in self.db.routing_mut().insert(inventory, from, timestamp)? {
            match result {
@@ -1726,7 +1726,7 @@ where
    /// Return a refs announcement including the given remotes.
    fn refs_announcement_for(
        &self,
-
        rid: Id,
+
        rid: RepoId,
        remotes: impl IntoIterator<Item = NodeId>,
    ) -> Result<(Announcement, Vec<RefsAt>), Error> {
        let repo = self.storage.repository(rid)?;
@@ -1757,7 +1757,7 @@ where
    /// Announce local refs for given id.
    fn announce_refs(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        remotes: impl IntoIterator<Item = NodeId>,
    ) -> Result<Vec<RefsAt>, Error> {
        let repo = self.storage.repository(rid)?;
@@ -1850,7 +1850,7 @@ where
        true
    }

-
    fn seeds(&self, rid: &Id) -> Result<Seeds, Error> {
+
    fn seeds(&self, rid: &RepoId) -> Result<Seeds, Error> {
        let mut seeds = Seeds::new(self.rng.clone());

        // First build a list from peers that have synced our own refs, if any.
@@ -1915,7 +1915,7 @@ where
    ////////////////////////////////////////////////////////////////////////////

    /// Announce our inventory to all connected peers.
-
    fn announce_inventory(&mut self, inventory: Vec<Id>) -> Result<(), storage::Error> {
+
    fn announce_inventory(&mut self, inventory: Vec<RepoId>) -> Result<(), storage::Error> {
        let time = if self.clock > self.last_announce {
            self.clock.as_millis()
        } else if self.last_announce - self.clock < LocalDuration::from_secs(1) {
@@ -2140,7 +2140,7 @@ pub trait ServiceState {
    /// Get the existing sessions.
    fn sessions(&self) -> &Sessions;
    /// Get a repository from storage.
-
    fn get(&self, rid: Id) -> Result<Option<Doc<Verified>>, RepositoryError>;
+
    fn get(&self, rid: RepoId) -> Result<Option<Doc<Verified>>, RepositoryError>;
    /// Get the clock.
    fn clock(&self) -> &LocalTime;
    /// Get the clock mutably.
@@ -2163,7 +2163,7 @@ where
        &self.sessions
    }

-
    fn get(&self, rid: Id) -> Result<Option<Doc<Verified>>, RepositoryError> {
+
    fn get(&self, rid: RepoId) -> Result<Option<Doc<Verified>>, RepositoryError> {
        self.storage.get(rid)
    }

modified radicle-node/src/service/filter.rs
@@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};

pub use bloomy::BloomFilter;

-
use crate::identity::Id;
+
use crate::identity::RepoId;

/// Size in bytes of *large* bloom filter.
/// It can store about 13'675 items with a false positive rate of 1%.
@@ -28,7 +28,7 @@ pub const FILTER_HASHES: usize = 7;
/// The [`Default`] instance has all bits set to `1`, ie. it will match
/// everything.
#[derive(Clone, PartialEq, Eq, Debug)]
-
pub struct Filter(BloomFilter<Id>);
+
pub struct Filter(BloomFilter<RepoId>);

impl Default for Filter {
    fn default() -> Self {
@@ -40,7 +40,7 @@ impl Filter {
    /// Create a new filter with the given items.
    ///
    /// Uses the iterator's size hint to determine the size of the filter.
-
    pub fn new(ids: impl IntoIterator<Item = Id>) -> Self {
+
    pub fn new(ids: impl IntoIterator<Item = RepoId>) -> Self {
        let iterator = ids.into_iter();
        let (min, _) = iterator.size_hint();
        let size = bloomy::bloom::optimal_bits(min, FILTER_FP_RATE) / 8;
@@ -71,7 +71,7 @@ impl Filter {
}

impl Deref for Filter {
-
    type Target = BloomFilter<Id>;
+
    type Target = BloomFilter<RepoId>;

    fn deref(&self) -> &Self::Target {
        &self.0
@@ -84,8 +84,8 @@ impl DerefMut for Filter {
    }
}

-
impl From<BloomFilter<Id>> for Filter {
-
    fn from(bloom: BloomFilter<Id>) -> Self {
+
impl From<BloomFilter<RepoId>> for Filter {
+
    fn from(bloom: BloomFilter<RepoId>) -> Self {
        Self(bloom)
    }
}
@@ -136,7 +136,7 @@ mod test {

    #[test]
    fn test_sizes() {
-
        let ids = arbitrary::vec::<Id>(3420);
+
        let ids = arbitrary::vec::<RepoId>(3420);
        let f = Filter::new(ids.iter().cloned().take(10));
        assert_eq!(f.size(), FILTER_SIZE_S);

@@ -147,7 +147,7 @@ mod test {
        assert_eq!(f.size(), FILTER_SIZE_L);

        // Just checking that iterators over hash sets give correct size hints.
-
        let hs = arbitrary::set::<Id>(42..=42);
+
        let hs = arbitrary::set::<RepoId>(42..=42);
        assert_eq!(hs.iter().size_hint(), (42, Some(42)));
    }
}
modified radicle-node/src/service/gossip.rs
@@ -23,8 +23,8 @@ pub fn node(config: &Config, timestamp: Timestamp) -> NodeAnnouncement {
    }
}

-
pub fn inventory(timestamp: Timestamp, inventory: Vec<Id>) -> InventoryAnnouncement {
-
    type Inventory = BoundedVec<Id, INVENTORY_LIMIT>;
+
pub fn inventory(timestamp: Timestamp, inventory: Vec<RepoId>) -> InventoryAnnouncement {
+
    type Inventory = BoundedVec<RepoId, INVENTORY_LIMIT>;

    if inventory.len() > Inventory::max() {
        error!(
modified radicle-node/src/service/io.rs
@@ -24,7 +24,7 @@ pub enum Io {
    /// Fetch repository data from a peer.
    Fetch {
        /// Repo being fetched.
-
        rid: Id,
+
        rid: RepoId,
        /// Remote node being fetched from.
        remote: NodeId,
        /// Namespaces being fetched.
@@ -113,7 +113,7 @@ impl Outbox {
    pub fn fetch(
        &mut self,
        remote: &mut Session,
-
        rid: Id,
+
        rid: RepoId,
        namespaces: Namespaces,
        refs_at: Vec<RefsAt>,
        timeout: time::Duration,
modified radicle-node/src/service/message.rs
@@ -5,7 +5,7 @@ use radicle::storage::refs::RefsAt;
use radicle::storage::ReadRepository;

use crate::crypto;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node;
use crate::node::{Address, Alias};
use crate::prelude::BoundedVec;
@@ -158,7 +158,7 @@ impl wire::Decode for NodeAnnouncement {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RefsAnnouncement {
    /// Repository identifier.
-
    pub rid: Id,
+
    pub rid: RepoId,
    /// Updated `rad/sigrefs`.
    pub refs: BoundedVec<RefsAt, REF_REMOTE_LIMIT>,
    /// Time of announcement.
@@ -247,7 +247,7 @@ impl RefsAnnouncement {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InventoryAnnouncement {
    /// Node inventory.
-
    pub inventory: BoundedVec<Id, INVENTORY_LIMIT>,
+
    pub inventory: BoundedVec<RepoId, INVENTORY_LIMIT>,
    /// Time of announcement.
    pub timestamp: Timestamp,
}
@@ -260,7 +260,7 @@ pub struct InventoryAnnouncement {
pub enum Info {
    /// Tell a node that sent a refs announcement that it was already synced at the given `Oid`,
    /// for this particular `rid`.
-
    RefsAlreadySynced { rid: Id, at: git::Oid },
+
    RefsAlreadySynced { rid: RepoId, at: git::Oid },
}

/// Announcement messages are messages that are relayed between peers.
@@ -664,7 +664,7 @@ mod tests {
    }

    #[quickcheck]
-
    fn prop_refs_announcement_signing(rid: Id) {
+
    fn prop_refs_announcement_signing(rid: RepoId) {
        let signer = MockSigner::new(&mut fastrand::Rng::new());
        let timestamp = 0;
        let at = raw::Oid::zero().into();
modified radicle-node/src/service/session.rs
@@ -5,7 +5,7 @@ use crate::node::config::Limits;
use crate::node::Severity;
use crate::service::message;
use crate::service::message::Message;
-
use crate::service::{Address, Id, LocalTime, NodeId, Outbox, Rng};
+
use crate::service::{Address, LocalTime, NodeId, Outbox, RepoId, Rng};
use crate::Link;

pub use crate::node::{PingState, State};
@@ -155,7 +155,7 @@ impl Session {
        false
    }

-
    pub fn is_fetching(&self, rid: &Id) -> bool {
+
    pub fn is_fetching(&self, rid: &RepoId) -> bool {
        if let State::Connected { fetching, .. } = &self.state {
            return fetching.contains(rid);
        }
@@ -171,7 +171,7 @@ impl Session {
    /// # Panics
    ///
    /// If it is already fetching that RID, or the session is disconnected.
-
    pub fn fetching(&mut self, rid: Id) {
+
    pub fn fetching(&mut self, rid: RepoId) {
        if let State::Connected { fetching, .. } = &mut self.state {
            assert!(
                fetching.insert(rid),
@@ -185,7 +185,7 @@ impl Session {
        }
    }

-
    pub fn fetched(&mut self, rid: Id) {
+
    pub fn fetched(&mut self, rid: RepoId) {
        if let State::Connected { fetching, .. } = &mut self.state {
            if !fetching.remove(&rid) {
                log::warn!(target: "service", "Fetched unknown repository {rid}");
modified radicle-node/src/test/arbitrary.rs
@@ -3,7 +3,7 @@ use qcheck::Arbitrary;

use crate::crypto;
use crate::node::Alias;
-
use crate::prelude::{BoundedVec, Id, NodeId, Timestamp};
+
use crate::prelude::{BoundedVec, NodeId, RepoId, Timestamp};
use crate::service::filter::{Filter, FILTER_SIZE_L, FILTER_SIZE_M, FILTER_SIZE_S};
use crate::service::message::{
    Announcement, Info, InventoryAnnouncement, Message, NodeAnnouncement, Ping, RefsAnnouncement,
@@ -55,7 +55,7 @@ impl Arbitrary for Message {
            MessageType::RefsAnnouncement => Announcement {
                node: NodeId::arbitrary(g),
                message: RefsAnnouncement {
-
                    rid: Id::arbitrary(g),
+
                    rid: RepoId::arbitrary(g),
                    refs: BoundedVec::arbitrary(g),
                    timestamp: Timestamp::arbitrary(g),
                }
@@ -84,7 +84,7 @@ impl Arbitrary for Message {
            }
            MessageType::Info => {
                let message = Info::RefsAlreadySynced {
-
                    rid: Id::arbitrary(g),
+
                    rid: RepoId::arbitrary(g),
                    at: oid(),
                };
                Self::Info(message)
modified radicle-node/src/test/environment.rs
@@ -15,7 +15,7 @@ use radicle::crypto::test::signer::MockSigner;
use radicle::crypto::{KeyPair, Seed, Signer};
use radicle::git;
use radicle::git::refname;
-
use radicle::identity::{Id, Visibility};
+
use radicle::identity::{RepoId, Visibility};
use radicle::node::config::ConnectAddress;
use radicle::node::policy::store as policy;
use radicle::node::routing::Store;
@@ -233,7 +233,7 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
    }

    /// Get routing table entries.
-
    pub fn routing(&self) -> impl Iterator<Item = (Id, NodeId)> {
+
    pub fn routing(&self) -> impl Iterator<Item = (RepoId, NodeId)> {
        Database::reader(self.home.node().join(node::NODE_DB_FILE))
            .unwrap()
            .entries()
@@ -244,13 +244,13 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
    pub fn converge<'a>(
        &'a self,
        remotes: impl IntoIterator<Item = &'a NodeHandle<G>>,
-
    ) -> BTreeSet<(Id, NodeId)> {
+
    ) -> BTreeSet<(RepoId, NodeId)> {
        converge(iter::once(self).chain(remotes))
    }

    /// Wait until this node's routing table contains the given routes.
    #[track_caller]
-
    pub fn routes_to(&self, routes: &[(Id, NodeId)]) {
+
    pub fn routes_to(&self, routes: &[(RepoId, NodeId)]) {
        log::debug!(target: "test", "Waiting for {} to route to {:?}", self.id, routes);
        let events = self.handle.events();

@@ -276,7 +276,7 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {

    /// Wait until this node has the inventory of another node.
    #[track_caller]
-
    pub fn has_inventory_of(&self, rid: &Id, nid: &NodeId) {
+
    pub fn has_inventory_of(&self, rid: &RepoId, nid: &NodeId) {
        log::debug!(target: "test", "Waiting for {} to have {rid}/{nid}", self.id);
        let events = self.handle.events();

@@ -296,12 +296,12 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
    }

    /// Clone a repo into a directory.
-
    pub fn clone<P: AsRef<Path>>(&self, rid: Id, cwd: P) -> io::Result<()> {
+
    pub fn clone<P: AsRef<Path>>(&self, rid: RepoId, cwd: P) -> io::Result<()> {
        self.rad("clone", &[rid.to_string().as_str()], cwd)
    }

    /// Fork a repo.
-
    pub fn fork<P: AsRef<Path>>(&self, rid: Id, cwd: P) -> io::Result<()> {
+
    pub fn fork<P: AsRef<Path>>(&self, rid: RepoId, cwd: P) -> io::Result<()> {
        self.clone(rid, &cwd)?;
        self.rad("fork", &[rid.to_string().as_str()], &cwd)?;
        self.announce(rid, &cwd)?;
@@ -310,7 +310,7 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
    }

    /// Announce a repo.
-
    pub fn announce<P: AsRef<Path>>(&self, rid: Id, cwd: P) -> io::Result<()> {
+
    pub fn announce<P: AsRef<Path>>(&self, rid: RepoId, cwd: P) -> io::Result<()> {
        self.rad("sync", &[rid.to_string().as_str(), "--announce"], cwd)
    }

@@ -377,7 +377,7 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
    }

    /// Create an [`issue::Issue`] in the `NodeHandle`'s storage.
-
    pub fn issue(&self, rid: Id, title: &str, desc: &str) -> cob::ObjectId {
+
    pub fn issue(&self, rid: RepoId, title: &str, desc: &str) -> cob::ObjectId {
        let repo = self.storage.repository(rid).unwrap();
        let mut issues = issue::Issues::open(&repo).unwrap();
        *issues
@@ -459,7 +459,7 @@ impl<G: cyphernet::Ecdh<Pk = NodeId> + Signer + Clone> Node<G> {
        name: &str,
        description: &str,
        repo: &git::raw::Repository,
-
    ) -> Id {
+
    ) -> RepoId {
        transport::local::register(self.storage.clone());

        let branch = refname!("master");
@@ -516,7 +516,7 @@ impl<G: cyphernet::Ecdh<Pk = NodeId> + Signer + Clone> Node<G> {
    }

    /// Populate a storage instance with a project.
-
    pub fn project(&mut self, name: &str, description: &str) -> Id {
+
    pub fn project(&mut self, name: &str, description: &str) -> RepoId {
        let tmp = tempfile::tempdir().unwrap();
        let (repo, _) = fixtures::repository(tmp.path());

@@ -528,10 +528,10 @@ impl<G: cyphernet::Ecdh<Pk = NodeId> + Signer + Clone> Node<G> {
#[track_caller]
pub fn converge<'a, G: Signer + cyphernet::Ecdh + 'static>(
    nodes: impl IntoIterator<Item = &'a NodeHandle<G>>,
-
) -> BTreeSet<(Id, NodeId)> {
+
) -> BTreeSet<(RepoId, NodeId)> {
    let nodes = nodes.into_iter().collect::<Vec<_>>();

-
    let mut all_routes = BTreeSet::<(Id, NodeId)>::new();
+
    let mut all_routes = BTreeSet::<(RepoId, NodeId)>::new();
    let mut remaining = BTreeMap::from_iter(nodes.iter().map(|node| (node.id, node)));

    // First build the set of all routes.
modified radicle-node/src/test/handle.rs
@@ -6,7 +6,7 @@ use std::time;
use radicle::git;
use radicle::storage::refs::RefsAt;

-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node::{Alias, Config, ConnectOptions, ConnectResult, Event, FetchResult, Seeds};
use crate::runtime::HandleError;
use crate::service::policy;
@@ -14,8 +14,8 @@ use crate::service::NodeId;

#[derive(Default, Clone)]
pub struct Handle {
-
    pub updates: Arc<Mutex<Vec<Id>>>,
-
    pub seeding: Arc<Mutex<HashSet<Id>>>,
+
    pub updates: Arc<Mutex<Vec<RepoId>>>,
+
    pub seeding: Arc<Mutex<HashSet<RepoId>>>,
    pub following: Arc<Mutex<HashSet<NodeId>>>,
}

@@ -44,13 +44,13 @@ impl radicle::node::Handle for Handle {
        unimplemented!();
    }

-
    fn seeds(&mut self, _id: Id) -> Result<Seeds, Self::Error> {
+
    fn seeds(&mut self, _id: RepoId) -> Result<Seeds, Self::Error> {
        unimplemented!();
    }

    fn fetch(
        &mut self,
-
        _id: Id,
+
        _id: RepoId,
        _from: NodeId,
        _timeout: time::Duration,
    ) -> Result<FetchResult, Self::Error> {
@@ -60,11 +60,11 @@ impl radicle::node::Handle for Handle {
        })
    }

-
    fn seed(&mut self, id: Id, _scope: policy::Scope) -> Result<bool, Self::Error> {
+
    fn seed(&mut self, id: RepoId, _scope: policy::Scope) -> Result<bool, Self::Error> {
        Ok(self.seeding.lock().unwrap().insert(id))
    }

-
    fn unseed(&mut self, id: Id) -> Result<bool, Self::Error> {
+
    fn unseed(&mut self, id: RepoId) -> Result<bool, Self::Error> {
        Ok(self.seeding.lock().unwrap().remove(&id))
    }

@@ -83,7 +83,7 @@ impl radicle::node::Handle for Handle {
        Ok(self.following.lock().unwrap().remove(&id))
    }

-
    fn announce_refs(&mut self, id: Id) -> Result<RefsAt, Self::Error> {
+
    fn announce_refs(&mut self, id: RepoId) -> Result<RefsAt, Self::Error> {
        self.updates.lock().unwrap().push(id);

        Ok(RefsAt {
modified radicle-node/src/test/peer.rs
@@ -17,7 +17,7 @@ use radicle::Storage;

use crate::crypto::test::signer::MockSigner;
use crate::crypto::Signer;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node;
use crate::prelude::*;
use crate::runtime::Emitter;
@@ -132,7 +132,7 @@ impl Default for Config<MockSigner> {
}

impl<G: Signer> Peer<Storage, G> {
-
    pub fn project(&mut self, name: &str, description: &str) -> Id {
+
    pub fn project(&mut self, name: &str, description: &str) -> RepoId {
        radicle::storage::git::transport::local::register(self.storage().clone());

        let (repo, _) = fixtures::repository(self.tempdir.path().join(name));
@@ -256,7 +256,7 @@ where
        self.service.storage().inventory().unwrap()
    }

-
    pub fn git_url(&self, repo: Id, namespace: Option<RemoteId>) -> remote::Url {
+
    pub fn git_url(&self, repo: RepoId, namespace: Option<RemoteId>) -> remote::Url {
        remote::Url {
            node: self.node_id(),
            repo,
@@ -297,7 +297,7 @@ where
        )
    }

-
    pub fn refs_announcement(&self, rid: Id) -> Message {
+
    pub fn refs_announcement(&self, rid: RepoId) -> Message {
        let mut refs = BoundedVec::new();
        if let Ok(repo) = self.storage().repository(rid) {
            if let Ok(false) = repo.is_empty() {
@@ -468,7 +468,7 @@ where
    }

    /// Get a draining iterator over the peer's I/O outbox, which only returns fetches.
-
    pub fn fetches(&mut self) -> impl Iterator<Item = (Id, NodeId, Namespaces)> + '_ {
+
    pub fn fetches(&mut self) -> impl Iterator<Item = (RepoId, NodeId, Namespaces)> + '_ {
        iter::from_fn(|| self.service.outbox().next()).filter_map(|io| {
            if let Io::Fetch {
                rid,
modified radicle-node/src/test/simulator.rs
@@ -15,7 +15,7 @@ use localtime::{LocalDuration, LocalTime};
use log::*;

use crate::crypto::Signer;
-
use crate::prelude::{Address, Id};
+
use crate::prelude::{Address, RepoId};
use crate::service::io::Io;
use crate::service::{DisconnectReason, Event, Message, NodeId};
use crate::storage::Namespaces;
@@ -66,7 +66,7 @@ pub enum Input {
    /// Received a message from a remote peer.
    Received(NodeId, Vec<Message>),
    /// Fetch completed for a node.
-
    Fetched(Id, NodeId, Rc<Result<fetch::FetchResult, FetchError>>),
+
    Fetched(RepoId, NodeId, Rc<Result<fetch::FetchResult, FetchError>>),
    /// Used to advance the state machine after some wall time has passed.
    Wake,
}
modified radicle-node/src/tests.rs
@@ -16,7 +16,7 @@ use radicle::storage::refs::RefsAt;

use crate::collections::{RandomMap, RandomSet};
use crate::crypto::test::signer::MockSigner;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node;
use crate::node::config::*;
use crate::prelude::*;
@@ -57,7 +57,7 @@ use crate::{git, identity, rad, runtime, service, test};

#[test]
fn test_inventory_decode() {
-
    let inventory: Vec<Id> = arbitrary::gen(300);
+
    let inventory: Vec<RepoId> = arbitrary::gen(300);
    let timestamp = LocalTime::now().as_millis();

    let mut buf = Vec::new();
@@ -369,7 +369,9 @@ fn test_inventory_pruning() {
                bob.id(),
                Message::inventory(
                    InventoryAnnouncement {
-
                        inventory: test::arbitrary::vec::<Id>(num_projs).try_into().unwrap(),
+
                        inventory: test::arbitrary::vec::<RepoId>(num_projs)
+
                            .try_into()
+
                            .unwrap(),
                        timestamp: bob.local_time().as_millis(),
                    },
                    peer.signer(),
@@ -391,7 +393,7 @@ fn test_inventory_pruning() {
#[test]
fn test_seeding() {
    let mut alice = Peer::new("alice", [7, 7, 7, 7]);
-
    let proj_id: identity::Id = test::arbitrary::gen(1);
+
    let proj_id: identity::RepoId = test::arbitrary::gen(1);

    let (sender, receiver) = chan::bounded(1);
    alice.command(Command::Seed(proj_id, policy::Scope::default(), sender));
@@ -473,7 +475,7 @@ fn test_announcement_rebroadcast_duplicates() {
    let mut alice = Peer::new("alice", [7, 7, 7, 7]);
    let bob = Peer::new("bob", [8, 8, 8, 8]);
    let eve = Peer::new("eve", [9, 9, 9, 9]);
-
    let rids = arbitrary::set::<Id>(3..=3);
+
    let rids = arbitrary::set::<RepoId>(3..=3);

    alice.connect_to(&bob);
    alice.receive(bob.id, carol.node_announcement());
@@ -1249,7 +1251,7 @@ fn test_maintain_connections_failed_attempt() {
fn test_seed_repo_subscribe() {
    let mut alice = Peer::new("alice", [7, 7, 7, 7]);
    let bob = Peer::new("bob", [8, 8, 8, 8]);
-
    let rid = arbitrary::gen::<Id>(1);
+
    let rid = arbitrary::gen::<RepoId>(1);
    let (send, recv) = chan::bounded(1);

    alice.connect_to(&bob);
@@ -1268,7 +1270,7 @@ fn test_seed_repo_subscribe() {

#[test]
fn test_fetch_missing_inventory_on_gossip() {
-
    let rid = arbitrary::gen::<Id>(1);
+
    let rid = arbitrary::gen::<RepoId>(1);
    let mut alice = Peer::new("alice", [7, 7, 7, 7]);
    let bob = Peer::new("bob", [8, 8, 8, 8]);
    let now = LocalTime::now();
@@ -1293,7 +1295,7 @@ fn test_fetch_missing_inventory_on_gossip() {

#[test]
fn test_fetch_missing_inventory_on_schedule() {
-
    let rid = arbitrary::gen::<Id>(1);
+
    let rid = arbitrary::gen::<RepoId>(1);
    let mut alice = Peer::new("alice", [7, 7, 7, 7]);
    let bob = Peer::new("bob", [8, 8, 8, 8]);
    let now = LocalTime::now();
modified radicle-node/src/wire.rs
@@ -19,7 +19,7 @@ use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
use crate::crypto::{PublicKey, Signature, Unverified};
use crate::git;
use crate::git::fmt;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node;
use crate::node::Alias;
use crate::prelude::*;
@@ -215,7 +215,7 @@ impl Encode for git::Url {
    }
}

-
impl Encode for Id {
+
impl Encode for RepoId {
    fn encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
        self.deref().encode(writer)
    }
@@ -420,7 +420,7 @@ impl Decode for String {
    }
}

-
impl Decode for Id {
+
impl Decode for RepoId {
    fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
        let oid: git::Oid = Decode::decode(reader)?;

@@ -572,8 +572,8 @@ mod tests {
    }

    #[quickcheck]
-
    fn prop_id(input: Id) {
-
        assert_eq!(deserialize::<Id>(&serialize(&input)).unwrap(), input);
+
    fn prop_id(input: RepoId) {
+
        assert_eq!(deserialize::<RepoId>(&serialize(&input)).unwrap(), input);
    }

    #[quickcheck]
modified radicle-node/src/wire/message.rs
@@ -149,7 +149,7 @@ impl wire::Encode for RefsAnnouncement {

impl wire::Decode for RefsAnnouncement {
    fn decode<R: std::io::Read + ?Sized>(reader: &mut R) -> Result<Self, wire::Error> {
-
        let rid = Id::decode(reader)?;
+
        let rid = RepoId::decode(reader)?;
        let refs = BoundedVec::<_, REF_REMOTE_LIMIT>::decode(reader)?;
        let timestamp = Timestamp::decode(reader)?;

@@ -244,7 +244,7 @@ impl wire::Decode for Info {

        match InfoType::try_from(info_type) {
            Ok(InfoType::RefsAlreadySynced) => {
-
                let rid = Id::decode(reader)?;
+
                let rid = RepoId::decode(reader)?;
                let at = Oid::decode(reader)?;

                Ok(Self::RefsAlreadySynced { rid, at })
@@ -478,7 +478,7 @@ mod tests {
    #[test]
    fn test_inv_ann_max_size() {
        let signer = MockSigner::default();
-
        let inv: [Id; INVENTORY_LIMIT] = arbitrary::gen(1);
+
        let inv: [RepoId; INVENTORY_LIMIT] = arbitrary::gen(1);
        let ann = AnnouncementMessage::Inventory(InventoryAnnouncement {
            inventory: BoundedVec::collect_from(&mut inv.into_iter()),
            timestamp: arbitrary::gen(1),
modified radicle-node/src/worker.rs
@@ -10,7 +10,7 @@ use std::{io, time};

use crossbeam_channel as chan;

-
use radicle::identity::Id;
+
use radicle::identity::RepoId;
use radicle::prelude::NodeId;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadRepository, ReadStorage};
@@ -78,7 +78,7 @@ pub enum UploadError {
    #[error(transparent)]
    Io(#[from] io::Error),
    #[error("{0} is not authorized to fetch {1}")]
-
    Unauthorized(NodeId, Id),
+
    Unauthorized(NodeId, RepoId),
    #[error(transparent)]
    Storage(#[from] radicle::storage::Error),
    #[error(transparent)]
@@ -103,7 +103,7 @@ pub enum FetchRequest {
    /// `rid` from the peer identified by `remote`.
    Initiator {
        /// Repo to fetch.
-
        rid: Id,
+
        rid: RepoId,
        /// Remote peer we are interacting with.
        remote: NodeId,
        /// If this fetch is for a particular set of `rad/sigrefs`.
@@ -132,7 +132,7 @@ impl FetchRequest {
pub enum FetchResult {
    Initiator {
        /// Repo fetched.
-
        rid: Id,
+
        rid: RepoId,
        /// Fetch result, including remotes fetched.
        result: Result<fetch::FetchResult, FetchError>,
    },
@@ -261,7 +261,7 @@ impl Worker {
        }
    }

-
    fn is_authorized(&self, remote: NodeId, rid: Id) -> Result<(), UploadError> {
+
    fn is_authorized(&self, remote: NodeId, rid: RepoId) -> Result<(), UploadError> {
        let policy = self.policies.repo_policy(&rid)?.policy;
        let repo = self.storage.repository(rid)?;
        let doc = repo.canonical_identity_doc()?;
@@ -274,7 +274,7 @@ impl Worker {

    fn fetch(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        remote: NodeId,
        refs_at: Option<Vec<RefsAt>>,
        channels: channels::ChannelsFlush,
modified radicle-node/src/worker/fetch.rs
@@ -3,7 +3,7 @@ pub mod error;
use std::collections::HashSet;

use radicle::crypto::PublicKey;
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadStorage as _, RefUpdate, WriteRepository as _};
use radicle::Storage;
@@ -31,7 +31,7 @@ pub enum Handle {

impl Handle {
    pub fn new(
-
        rid: Id,
+
        rid: RepoId,
        local: PublicKey,
        storage: &Storage,
        follow: Allowed,
@@ -52,7 +52,7 @@ impl Handle {

    pub fn fetch(
        self,
-
        rid: Id,
+
        rid: RepoId,
        storage: &Storage,
        limit: FetchLimit,
        remote: PublicKey,
@@ -113,7 +113,7 @@ impl Handle {
///
/// # Errors
///   - Will fail if `storage` contains `rid` already.
-
fn mv(tmp: tempfile::TempDir, storage: &Storage, rid: &Id) -> Result<(), error::Fetch> {
+
fn mv(tmp: tempfile::TempDir, storage: &Storage, rid: &RepoId) -> Result<(), error::Fetch> {
    use std::io::{Error, ErrorKind};

    let from = tmp.path();
modified radicle-node/src/worker/garbage.rs
@@ -1,7 +1,7 @@
use std::process::{Command, ExitStatus, Stdio};
use std::{fmt, io};

-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::storage::ReadStorage;

/// Default expiry time for objects.
@@ -36,7 +36,7 @@ impl fmt::Display for Expiry {
}

/// Run Git garbage collector.
-
pub fn collect(storage: &impl ReadStorage, rid: Id, expiry: Expiry) -> io::Result<ExitStatus> {
+
pub fn collect(storage: &impl ReadStorage, rid: RepoId, expiry: Expiry) -> io::Result<ExitStatus> {
    let git_dir = storage.path_of(&rid);
    let mut gc = Command::new("git");
    gc.current_dir(git_dir)
modified radicle-node/src/worker/upload_pack.rs
@@ -132,7 +132,7 @@ pub(super) mod pktline {
    use std::io::Read;
    use std::str;

-
    use radicle::prelude::Id;
+
    use radicle::prelude::RepoId;

    pub const HEADER_LEN: usize = 4;

@@ -195,7 +195,7 @@ pub(super) mod pktline {
    /// Example: `0032git-upload-pack /rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5.git\0host=myserver.com\0`
    #[derive(Debug)]
    pub struct GitRequest {
-
        pub repo: Id,
+
        pub repo: RepoId,
        pub path: String,
        pub host: Option<(String, Option<u16>)>,
        pub extra: Vec<(String, Option<String>)>,
modified radicle-remote-helper/src/push.rs
@@ -15,7 +15,7 @@ use radicle::explorer::ExplorerResource;
use radicle::identity::Did;
use radicle::node;
use radicle::node::{Handle, NodeId};
-
use radicle::prelude::Id;
+
use radicle::prelude::RepoId;
use radicle::storage;
use radicle::storage::git::transport::local::Url;
use radicle::storage::{ReadRepository, SignRepository as _, WriteRepository};
@@ -631,7 +631,7 @@ fn push_ref(

/// Sync with the network.
fn sync(
-
    rid: Id,
+
    rid: RepoId,
    updated: impl Iterator<Item = ExplorerResource>,
    mut node: radicle::Node,
    profile: &Profile,
modified radicle/src/cob/identity.rs
@@ -18,7 +18,7 @@ use crate::{
        ActorId, Timestamp,
    },
    identity::{
-
        doc::{Doc, DocError, Id},
+
        doc::{Doc, DocError, RepoId},
        Did,
    },
    storage::{ReadRepository, RepositoryError, WriteRepository},
@@ -137,7 +137,7 @@ pub enum Error {
pub struct Identity {
    /// The canonical identifier for this identity.
    /// This is the object id of the initial document blob.
-
    pub id: Id,
+
    pub id: RepoId,
    /// The current revision of the document.
    /// Equal to the head of the identity branch.
    pub current: RevisionId,
@@ -241,7 +241,7 @@ impl Identity {

impl Identity {
    /// The repository identifier.
-
    pub fn id(&self) -> Id {
+
    pub fn id(&self) -> RepoId {
        self.id
    }

@@ -1004,7 +1004,7 @@ mod test {
    use crate::identity::doc::PayloadId;

    #[quickcheck]
-
    fn prop_json_eq_str(pk: PublicKey, proj: Id, did: Did) {
+
    fn prop_json_eq_str(pk: PublicKey, proj: RepoId, did: Did) {
        let json = serde_json::to_string(&pk).unwrap();
        assert_eq!(format!("\"{pk}\""), json);

modified radicle/src/cob/patch.rs
@@ -2557,7 +2557,7 @@ mod test {
        let base = git::Oid::from_str("cb18e95ada2bb38aadd8e6cef0963ce37a87add3").unwrap();
        let oid = git::Oid::from_str("518d5069f94c03427f694bb494ac1cd7d1339380").unwrap();
        let mut alice = Actor::new(MockSigner::default());
-
        let rid = gen::<Id>(1);
+
        let rid = gen::<RepoId>(1);
        let doc = Doc::new(
            gen::<Project>(1),
            nonempty::NonEmpty::new(alice.did()),
modified radicle/src/explorer.rs
@@ -2,7 +2,7 @@ use std::str::FromStr;

use thiserror::Error;

-
use crate::prelude::Id;
+
use crate::prelude::RepoId;
use crate::{cob, git};

#[derive(Debug, Error)]
@@ -47,7 +47,7 @@ pub struct ExplorerUrl {
    /// Host serving the repository.
    pub host: String,
    /// Repository.
-
    pub rid: Id,
+
    pub rid: RepoId,
    /// Resource under the repository.
    pub resource: Option<ExplorerResource>,
}
@@ -95,7 +95,7 @@ impl Default for Explorer {

impl Explorer {
    /// Get the explorer URL, filling in the host and RID.
-
    pub fn url(&self, host: impl ToString, rid: Id) -> ExplorerUrl {
+
    pub fn url(&self, host: impl ToString, rid: RepoId) -> ExplorerUrl {
        ExplorerUrl {
            template: self.clone(),
            host: host.to_string(),
modified radicle/src/identity.rs
@@ -5,7 +5,7 @@ pub mod project;

pub use crypto::PublicKey;
pub use did::Did;
-
pub use doc::{Doc, DocAt, DocError, Id, IdError, PayloadError, Visibility};
+
pub use doc::{Doc, DocAt, DocError, IdError, PayloadError, RepoId, Visibility};
pub use project::Project;

pub use crate::cob::identity::{Error, Identity, IdentityMut};
modified radicle/src/identity/doc.rs
@@ -482,7 +482,7 @@ mod test {
        let tempdir = tempfile::tempdir().unwrap();
        let storage = Storage::open(tempdir.path().join("storage"), fixtures::user()).unwrap();
        let remote = arbitrary::gen::<RemoteId>(1);
-
        let proj = arbitrary::gen::<Id>(1);
+
        let proj = arbitrary::gen::<RepoId>(1);
        let repo = storage.create(proj).unwrap();
        let oid = git2::Oid::from_str("2d52a53ce5e4f141148a5f770cfd3ead2d6a45b8").unwrap();

modified radicle/src/identity/doc/id.rs
@@ -18,23 +18,23 @@ pub enum IdError {
    Multibase(#[from] multibase::Error),
}

-
/// A radicle identifier. Commonly used to uniquely identify radicle projects.
+
/// A repository identifier.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-
pub struct Id(git::Oid);
+
pub struct RepoId(git::Oid);

-
impl fmt::Display for Id {
+
impl fmt::Display for RepoId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.urn().as_str())
    }
}

-
impl fmt::Debug for Id {
+
impl fmt::Debug for RepoId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-
        write!(f, "Id({self})")
+
        write!(f, "RepoId({self})")
    }
}

-
impl Id {
+
impl RepoId {
    /// Format the identifier as a human-readable URN.
    ///
    /// Eg. `rad:z3XncAdkZjeK9mQS5Sdc4qhw98BUX`.
@@ -69,7 +69,7 @@ impl Id {
    }
}

-
impl FromStr for Id {
+
impl FromStr for RepoId {
    type Err = IdError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -77,7 +77,7 @@ impl FromStr for Id {
    }
}

-
impl TryFrom<OsString> for Id {
+
impl TryFrom<OsString> for RepoId {
    type Error = IdError;

    fn try_from(value: OsString) -> Result<Self, Self::Error> {
@@ -86,19 +86,19 @@ impl TryFrom<OsString> for Id {
    }
}

-
impl From<git::Oid> for Id {
+
impl From<git::Oid> for RepoId {
    fn from(oid: git::Oid) -> Self {
        Self(oid)
    }
}

-
impl From<git2::Oid> for Id {
+
impl From<git2::Oid> for RepoId {
    fn from(oid: git2::Oid) -> Self {
        Self(oid.into())
    }
}

-
impl Deref for Id {
+
impl Deref for RepoId {
    type Target = git::Oid;

    fn deref(&self) -> &Self::Target {
@@ -106,7 +106,7 @@ impl Deref for Id {
    }
}

-
impl serde::Serialize for Id {
+
impl serde::Serialize for RepoId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
@@ -115,7 +115,7 @@ impl serde::Serialize for Id {
    }
}

-
impl<'de> serde::Deserialize<'de> for Id {
+
impl<'de> serde::Deserialize<'de> for RepoId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
@@ -124,11 +124,11 @@ impl<'de> serde::Deserialize<'de> for Id {
    }
}

-
impl From<&Id> for Component<'_> {
-
    fn from(id: &Id) -> Self {
+
impl From<&RepoId> for Component<'_> {
+
    fn from(id: &RepoId) -> Self {
        let refstr =
-
            RefString::try_from(id.0.to_string()).expect("project id's are valid ref strings");
-
        Component::from_refstr(refstr).expect("project id's are valid refname components")
+
            RefString::try_from(id.0.to_string()).expect("repository id's are valid ref strings");
+
        Component::from_refstr(refstr).expect("repository id's are valid refname components")
    }
}

@@ -139,9 +139,9 @@ mod test {
    use qcheck_macros::quickcheck;

    #[quickcheck]
-
    fn prop_from_str(input: Id) {
+
    fn prop_from_str(input: RepoId) {
        let encoded = input.to_string();
-
        let decoded = Id::from_str(&encoded).unwrap();
+
        let decoded = RepoId::from_str(&encoded).unwrap();

        assert_eq!(input, decoded);
    }
modified radicle/src/lib.rs
@@ -38,7 +38,7 @@ pub mod prelude {
    use super::*;

    pub use crypto::{PublicKey, Signer, Verified};
-
    pub use identity::{project::Project, Did, Doc, Id};
+
    pub use identity::{project::Project, Did, Doc, RepoId};
    pub use node::{Alias, NodeId, Timestamp};
    pub use profile::Profile;
    pub use storage::{
modified radicle/src/node.rs
@@ -26,7 +26,7 @@ use serde_json as json;

use crate::crypto::PublicKey;
use crate::git;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::profile;
use crate::storage::refs::RefsAt;
use crate::storage::RefUpdate;
@@ -92,7 +92,7 @@ pub enum State {
        #[serde(skip)]
        ping: PingState,
        /// Ongoing fetches.
-
        fetching: HashSet<Id>,
+
        fetching: HashSet<RepoId>,
    },
    /// When a peer is disconnected.
    #[serde(rename_all = "camelCase")]
@@ -411,7 +411,7 @@ impl From<Address> for HostName {
pub enum Command {
    /// Announce repository references for given repository to peers.
    #[serde(rename_all = "camelCase")]
-
    AnnounceRefs { rid: Id },
+
    AnnounceRefs { rid: RepoId },

    /// Announce local repositories to peers.
    #[serde(rename_all = "camelCase")]
@@ -432,7 +432,7 @@ pub enum Command {

    /// Lookup seeds for the given repository in the routing table.
    #[serde(rename_all = "camelCase")]
-
    Seeds { rid: Id },
+
    Seeds { rid: RepoId },

    /// Get the current peer sessions.
    Sessions,
@@ -440,18 +440,18 @@ pub enum Command {
    /// Fetch the given repository from the network.
    #[serde(rename_all = "camelCase")]
    Fetch {
-
        rid: Id,
+
        rid: RepoId,
        nid: NodeId,
        timeout: time::Duration,
    },

    /// Seed the given repository.
    #[serde(rename_all = "camelCase")]
-
    Seed { rid: Id, scope: policy::Scope },
+
    Seed { rid: RepoId, scope: policy::Scope },

    /// Unseed the given repository.
    #[serde(rename_all = "camelCase")]
-
    Unseed { rid: Id },
+
    Unseed { rid: RepoId },

    /// Follow the given node.
    #[serde(rename_all = "camelCase")]
@@ -803,25 +803,25 @@ pub trait Handle: Clone + Sync + Send {
        opts: ConnectOptions,
    ) -> Result<ConnectResult, Self::Error>;
    /// Lookup the seeds of a given repository in the routing table.
-
    fn seeds(&mut self, id: Id) -> Result<Seeds, Self::Error>;
+
    fn seeds(&mut self, id: RepoId) -> Result<Seeds, Self::Error>;
    /// Fetch a repository from the network.
    fn fetch(
        &mut self,
-
        id: Id,
+
        id: RepoId,
        from: NodeId,
        timeout: time::Duration,
    ) -> Result<FetchResult, Self::Error>;
    /// Start seeding the given repo. May update the scope. Does nothing if the
    /// repo is already seeded.
-
    fn seed(&mut self, id: Id, scope: policy::Scope) -> Result<bool, Self::Error>;
+
    fn seed(&mut self, id: RepoId, scope: policy::Scope) -> Result<bool, Self::Error>;
    /// Start following the given peer.
    fn follow(&mut self, id: NodeId, alias: Option<Alias>) -> Result<bool, Self::Error>;
    /// Un-seed the given repo and delete it from storage.
-
    fn unseed(&mut self, id: Id) -> Result<bool, Self::Error>;
+
    fn unseed(&mut self, id: RepoId) -> Result<bool, Self::Error>;
    /// Unfollow the given peer.
    fn unfollow(&mut self, id: NodeId) -> Result<bool, Self::Error>;
    /// Notify the service that a project has been updated, and announce local refs.
-
    fn announce_refs(&mut self, id: Id) -> Result<RefsAt, Self::Error>;
+
    fn announce_refs(&mut self, id: RepoId) -> Result<RefsAt, Self::Error>;
    /// Announce local inventory.
    fn announce_inventory(&mut self) -> Result<(), Self::Error>;
    /// Notify the service that our inventory was updated.
@@ -889,7 +889,7 @@ impl Node {
    /// within the given time.
    pub fn announce(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        seeds: impl IntoIterator<Item = NodeId>,
        timeout: time::Duration,
        mut callback: impl FnMut(AnnounceEvent, &[PublicKey]) -> ControlFlow<()>,
@@ -984,7 +984,7 @@ impl Handle for Node {
        Ok(result)
    }

-
    fn seeds(&mut self, rid: Id) -> Result<Seeds, Error> {
+
    fn seeds(&mut self, rid: RepoId) -> Result<Seeds, Error> {
        let seeds = self
            .call::<Seeds>(Command::Seeds { rid }, DEFAULT_TIMEOUT)?
            .next()
@@ -995,7 +995,7 @@ impl Handle for Node {

    fn fetch(
        &mut self,
-
        rid: Id,
+
        rid: RepoId,
        from: NodeId,
        timeout: time::Duration,
    ) -> Result<FetchResult, Error> {
@@ -1021,7 +1021,7 @@ impl Handle for Node {
        Ok(response.updated)
    }

-
    fn seed(&mut self, rid: Id, scope: policy::Scope) -> Result<bool, Error> {
+
    fn seed(&mut self, rid: RepoId, scope: policy::Scope) -> Result<bool, Error> {
        let mut line = self.call::<Success>(Command::Seed { rid, scope }, DEFAULT_TIMEOUT)?;
        let response = line.next().ok_or(Error::EmptyResponse)??;

@@ -1035,14 +1035,14 @@ impl Handle for Node {
        Ok(response.updated)
    }

-
    fn unseed(&mut self, rid: Id) -> Result<bool, Error> {
+
    fn unseed(&mut self, rid: RepoId) -> Result<bool, Error> {
        let mut line = self.call::<Success>(Command::Unseed { rid }, DEFAULT_TIMEOUT)?;
        let response = line.next().ok_or(Error::EmptyResponse {})??;

        Ok(response.updated)
    }

-
    fn announce_refs(&mut self, rid: Id) -> Result<RefsAt, Error> {
+
    fn announce_refs(&mut self, rid: RepoId) -> Result<RefsAt, Error> {
        let refs: RefsAt = self
            .call(Command::AnnounceRefs { rid }, DEFAULT_TIMEOUT)?
            .next()
modified radicle/src/node/events.rs
@@ -14,20 +14,20 @@ use crate::storage::{refs, RefUpdate};
pub enum Event {
    RefsFetched {
        remote: NodeId,
-
        rid: Id,
+
        rid: RepoId,
        updated: Vec<RefUpdate>,
    },
    RefsSynced {
        remote: NodeId,
-
        rid: Id,
+
        rid: RepoId,
        at: Oid,
    },
    SeedDiscovered {
-
        rid: Id,
+
        rid: RepoId,
        nid: NodeId,
    },
    SeedDropped {
-
        rid: Id,
+
        rid: RepoId,
        nid: NodeId,
    },
    PeerConnected {
@@ -39,12 +39,12 @@ pub enum Event {
    },
    InventoryAnnounced {
        nid: NodeId,
-
        inventory: Vec<Id>,
+
        inventory: Vec<RepoId>,
        timestamp: Timestamp,
    },
    RefsAnnounced {
        nid: NodeId,
-
        rid: Id,
+
        rid: RepoId,
        refs: Vec<refs::RefsAt>,
        timestamp: Timestamp,
    },
modified radicle/src/node/policy.rs
@@ -7,14 +7,14 @@ use std::str::FromStr;
use serde::{Deserialize, Serialize};
use thiserror::Error;

-
use crate::prelude::Id;
+
use crate::prelude::RepoId;

pub use super::{Alias, NodeId};

/// Repository seeding policy.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Repo {
-
    pub id: Id,
+
    pub id: RepoId,
    pub scope: Scope,
    pub policy: Policy,
}
modified radicle/src/node/policy/config.rs
@@ -6,7 +6,7 @@ use log::error;
use thiserror::Error;

use crate::crypto::PublicKey;
-
use crate::prelude::{Id, NodeId};
+
use crate::prelude::{NodeId, RepoId};
use crate::storage::{Namespaces, ReadRepository as _, ReadStorage, RepositoryError};

pub use crate::node::policy::store;
@@ -18,28 +18,28 @@ pub use crate::node::policy::{Alias, Node, Policy, Repo, Scope};
pub enum NamespacesError {
    #[error("failed to find policy for {rid}")]
    FailedPolicy {
-
        rid: Id,
+
        rid: RepoId,
        #[source]
        err: Error,
    },
    #[error("cannot fetch {rid} as it is not seeded")]
-
    BlockedPolicy { rid: Id },
+
    BlockedPolicy { rid: RepoId },
    #[error("failed to get node policies for {rid}")]
    FailedNodes {
-
        rid: Id,
+
        rid: RepoId,
        #[source]
        err: Error,
    },
    #[error("failed to get delegates for {rid}")]
    FailedDelegates {
-
        rid: Id,
+
        rid: RepoId,
        #[source]
        err: RepositoryError,
    },
    #[error(transparent)]
    Git(#[from] crate::git::raw::Error),
    #[error("could not find any followed nodes for {rid}")]
-
    NoFollowed { rid: Id },
+
    NoFollowed { rid: RepoId },
}

/// Policies configuration.
@@ -75,7 +75,7 @@ impl<T> Config<T> {
    }

    /// Check if a repository is seeded.
-
    pub fn is_seeding(&self, id: &Id) -> Result<bool, Error> {
+
    pub fn is_seeding(&self, id: &RepoId) -> Result<bool, Error> {
        self.repo_policy(id)
            .map(|entry| entry.policy == Policy::Allow)
    }
@@ -98,7 +98,7 @@ impl<T> Config<T> {

    /// Get a repository's seediing information.
    /// Returns the default policy if the repo isn't found.
-
    pub fn repo_policy(&self, id: &Id) -> Result<Repo, Error> {
+
    pub fn repo_policy(&self, id: &RepoId) -> Result<Repo, Error> {
        Ok(self.store.seed_policy(id)?.unwrap_or(Repo {
            id: *id,
            scope: self.scope,
@@ -106,7 +106,11 @@ impl<T> Config<T> {
        }))
    }

-
    pub fn namespaces_for<S>(&self, storage: &S, rid: &Id) -> Result<Namespaces, NamespacesError>
+
    pub fn namespaces_for<S>(
+
        &self,
+
        storage: &S,
+
        rid: &RepoId,
+
    ) -> Result<Namespaces, NamespacesError>
    where
        S: ReadStorage,
    {
modified radicle/src/node/policy/store.rs
@@ -7,7 +7,7 @@ use sqlite as sql;
use thiserror::Error;

use crate::node::{Alias, AliasStore};
-
use crate::prelude::{Id, NodeId};
+
use crate::prelude::{NodeId, RepoId};

use super::{Node, Policy, Repo, Scope};

@@ -132,7 +132,7 @@ impl Store<Write> {
    }

    /// Seed a repository.
-
    pub fn seed(&mut self, id: &Id, scope: Scope) -> Result<bool, Error> {
+
    pub fn seed(&mut self, id: &RepoId, scope: Scope) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
            "INSERT INTO `seeding` (id, scope)
             VALUES (?1, ?2)
@@ -164,7 +164,7 @@ impl Store<Write> {
    }

    /// Set a repository's seeding policy.
-
    pub fn set_seed_policy(&mut self, id: &Id, policy: Policy) -> Result<bool, Error> {
+
    pub fn set_seed_policy(&mut self, id: &RepoId, policy: Policy) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
            "INSERT INTO `seeding` (id, policy)
             VALUES (?1, ?2)
@@ -190,7 +190,7 @@ impl Store<Write> {
    }

    /// Unseed a repository.
-
    pub fn unseed(&mut self, id: &Id) -> Result<bool, Error> {
+
    pub fn unseed(&mut self, id: &RepoId) -> Result<bool, Error> {
        let mut stmt = self.db.prepare("DELETE FROM `seeding` WHERE id = ?")?;

        stmt.bind((1, id))?;
@@ -215,7 +215,7 @@ impl<T> Store<T> {
    }

    /// Check if a repository is seeded.
-
    pub fn is_seeded(&self, id: &Id) -> Result<bool, Error> {
+
    pub fn is_seeded(&self, id: &RepoId) -> Result<bool, Error> {
        Ok(matches!(
            self.seed_policy(id)?,
            Some(Repo {
@@ -252,7 +252,7 @@ impl<T> Store<T> {
    }

    /// Get a repository's seeding policy.
-
    pub fn seed_policy(&self, id: &Id) -> Result<Option<Repo>, Error> {
+
    pub fn seed_policy(&self, id: &RepoId) -> Result<Option<Repo>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT scope, policy FROM `seeding` WHERE id = ?")?;
@@ -343,7 +343,7 @@ mod test {

    #[test]
    fn test_seed_and_unseed_repo() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let mut db = Store::open(":memory:").unwrap();

        assert!(db.seed(&id, Scope::All).unwrap());
@@ -369,7 +369,7 @@ mod test {

    #[test]
    fn test_repo_policies() {
-
        let ids = arbitrary::vec::<Id>(3);
+
        let ids = arbitrary::vec::<RepoId>(3);
        let mut db = Store::open(":memory:").unwrap();

        for id in &ids {
@@ -403,7 +403,7 @@ mod test {

    #[test]
    fn test_update_scope() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let mut db = Store::open(":memory:").unwrap();

        assert!(db.seed(&id, Scope::All).unwrap());
@@ -414,7 +414,7 @@ mod test {

    #[test]
    fn test_repo_policy() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let mut db = Store::open(":memory:").unwrap();

        assert!(db.seed(&id, Scope::All).unwrap());
modified radicle/src/node/routing.rs
@@ -6,7 +6,7 @@ use thiserror::Error;
use crate::node::Database;
use crate::{
    prelude::Timestamp,
-
    prelude::{Id, NodeId},
+
    prelude::{NodeId, RepoId},
    sql::transaction,
};

@@ -35,11 +35,11 @@ pub enum Error {
/// Backing store for a routing table.
pub trait Store {
    /// Get the nodes seeding the given id.
-
    fn get(&self, id: &Id) -> Result<HashSet<NodeId>, Error>;
+
    fn get(&self, id: &RepoId) -> Result<HashSet<NodeId>, Error>;
    /// Get the resources seeded by the given node.
-
    fn get_resources(&self, node_id: &NodeId) -> Result<HashSet<Id>, Error>;
+
    fn get_resources(&self, node_id: &NodeId) -> Result<HashSet<RepoId>, Error>;
    /// Get a specific entry.
-
    fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error>;
+
    fn entry(&self, id: &RepoId, node: &NodeId) -> Result<Option<Timestamp>, Error>;
    /// Checks if any entries are available.
    fn is_empty(&self) -> Result<bool, Error> {
        Ok(self.len()? == 0)
@@ -47,24 +47,24 @@ pub trait Store {
    /// Add a new node seeding the given id.
    fn insert<'a>(
        &mut self,
-
        ids: impl IntoIterator<Item = &'a Id>,
+
        ids: impl IntoIterator<Item = &'a RepoId>,
        node: NodeId,
        time: Timestamp,
-
    ) -> Result<Vec<(Id, InsertResult)>, Error>;
+
    ) -> Result<Vec<(RepoId, InsertResult)>, Error>;
    /// Remove a node for the given id.
-
    fn remove(&mut self, id: &Id, node: &NodeId) -> Result<bool, Error>;
+
    fn remove(&mut self, id: &RepoId, node: &NodeId) -> Result<bool, Error>;
    /// Iterate over all entries in the routing table.
-
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (Id, NodeId)>>, Error>;
+
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (RepoId, NodeId)>>, Error>;
    /// Get the total number of routing entries.
    fn len(&self) -> Result<usize, Error>;
    /// Prune entries older than the given timestamp.
    fn prune(&mut self, oldest: Timestamp, limit: Option<usize>) -> Result<usize, Error>;
    /// Count the number of routes for a specific repo RID.
-
    fn count(&self, id: &Id) -> Result<usize, Error>;
+
    fn count(&self, id: &RepoId) -> Result<usize, Error>;
}

impl Store for Database {
-
    fn get(&self, id: &Id) -> Result<HashSet<NodeId>, Error> {
+
    fn get(&self, id: &RepoId) -> Result<HashSet<NodeId>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT (node) FROM routing WHERE repo = ?")?;
@@ -77,18 +77,18 @@ impl Store for Database {
        Ok(nodes)
    }

-
    fn get_resources(&self, node: &NodeId) -> Result<HashSet<Id>, Error> {
+
    fn get_resources(&self, node: &NodeId) -> Result<HashSet<RepoId>, Error> {
        let mut stmt = self.db.prepare("SELECT repo FROM routing WHERE node = ?")?;
        stmt.bind((1, node))?;

        let mut resources = HashSet::new();
        for row in stmt.into_iter() {
-
            resources.insert(row?.read::<Id, _>("repo"));
+
            resources.insert(row?.read::<RepoId, _>("repo"));
        }
        Ok(resources)
    }

-
    fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error> {
+
    fn entry(&self, id: &RepoId, node: &NodeId) -> Result<Option<Timestamp>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT (timestamp) FROM routing WHERE repo = ? AND node = ?")?;
@@ -104,10 +104,10 @@ impl Store for Database {

    fn insert<'a>(
        &mut self,
-
        ids: impl IntoIterator<Item = &'a Id>,
+
        ids: impl IntoIterator<Item = &'a RepoId>,
        node: NodeId,
        time: Timestamp,
-
    ) -> Result<Vec<(Id, InsertResult)>, Error> {
+
    ) -> Result<Vec<(RepoId, InsertResult)>, Error> {
        let time: i64 = time.try_into().map_err(|_| Error::UnitOverflow)?;
        let mut results = Vec::new();

@@ -144,7 +144,7 @@ impl Store for Database {
        })
    }

-
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (Id, NodeId)>>, Error> {
+
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (RepoId, NodeId)>>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT repo, node FROM routing ORDER BY repo")?
@@ -160,7 +160,7 @@ impl Store for Database {
        Ok(Box::new(entries.into_iter()))
    }

-
    fn remove(&mut self, id: &Id, node: &NodeId) -> Result<bool, Error> {
+
    fn remove(&mut self, id: &RepoId, node: &NodeId) -> Result<bool, Error> {
        let mut stmt = self
            .db
            .prepare("DELETE FROM routing WHERE repo = ? AND node = ?")?;
@@ -201,7 +201,7 @@ impl Store for Database {
        Ok(self.db.change_count())
    }

-
    fn count(&self, id: &Id) -> Result<usize, Error> {
+
    fn count(&self, id: &RepoId) -> Result<usize, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT COUNT(*) FROM routing WHERE repo = ?")?;
@@ -237,7 +237,7 @@ mod test {

    #[test]
    fn test_insert_and_get() {
-
        let ids = arbitrary::set::<Id>(5..10);
+
        let ids = arbitrary::set::<RepoId>(5..10);
        let nodes = arbitrary::set::<NodeId>(5..10);
        let mut db = database(":memory:");

@@ -260,7 +260,7 @@ mod test {

    #[test]
    fn test_insert_and_get_resources() {
-
        let ids = arbitrary::set::<Id>(5..10);
+
        let ids = arbitrary::set::<RepoId>(5..10);
        let nodes = arbitrary::set::<NodeId>(5..10);
        let mut db = database(":memory:");

@@ -278,7 +278,7 @@ mod test {

    #[test]
    fn test_entries() {
-
        let ids = arbitrary::set::<Id>(6..9);
+
        let ids = arbitrary::set::<RepoId>(6..9);
        let nodes = arbitrary::set::<NodeId>(6..9);
        let mut db = database(":memory:");

@@ -301,7 +301,7 @@ mod test {

    #[test]
    fn test_insert_and_remove() {
-
        let ids = arbitrary::set::<Id>(5..10);
+
        let ids = arbitrary::set::<RepoId>(5..10);
        let nodes = arbitrary::set::<NodeId>(5..10);
        let mut db = database(":memory:");

@@ -320,7 +320,7 @@ mod test {

    #[test]
    fn test_insert_duplicate() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let node = arbitrary::gen::<NodeId>(1);
        let mut db = database(":memory:");

@@ -340,7 +340,7 @@ mod test {

    #[test]
    fn test_insert_existing_updated_time() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let node = arbitrary::gen::<NodeId>(1);
        let mut db = database(":memory:");

@@ -357,8 +357,8 @@ mod test {

    #[test]
    fn test_update_existing_multi() {
-
        let id1 = arbitrary::gen::<Id>(1);
-
        let id2 = arbitrary::gen::<Id>(1);
+
        let id1 = arbitrary::gen::<RepoId>(1);
+
        let id2 = arbitrary::gen::<RepoId>(1);
        let node = arbitrary::gen::<NodeId>(1);
        let mut db = database(":memory:");

@@ -384,7 +384,7 @@ mod test {

    #[test]
    fn test_remove_redundant() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let node = arbitrary::gen::<NodeId>(1);
        let mut db = database(":memory:");

@@ -399,7 +399,7 @@ mod test {
    #[test]
    fn test_len() {
        let mut db = database(":memory:");
-
        let ids = arbitrary::vec::<Id>(10);
+
        let ids = arbitrary::vec::<RepoId>(10);
        let node = arbitrary::gen(1);

        db.insert(&ids, node, LocalTime::now().as_millis()).unwrap();
@@ -411,7 +411,7 @@ mod test {
    fn test_prune() {
        let mut rng = fastrand::Rng::new();
        let now = LocalTime::now();
-
        let ids = arbitrary::vec::<Id>(10);
+
        let ids = arbitrary::vec::<RepoId>(10);
        let nodes = arbitrary::vec::<NodeId>(10);
        let mut db = database(":memory:");

@@ -420,7 +420,7 @@ mod test {
            db.insert(&ids, *node, time).unwrap();
        }

-
        let ids = arbitrary::vec::<Id>(10);
+
        let ids = arbitrary::vec::<RepoId>(10);
        let nodes = arbitrary::vec::<NodeId>(10);

        for node in &nodes {
@@ -441,7 +441,7 @@ mod test {

    #[test]
    fn test_count() {
-
        let id = arbitrary::gen::<Id>(1);
+
        let id = arbitrary::gen::<RepoId>(1);
        let nodes = arbitrary::set::<NodeId>(5..10);
        let mut db = database(":memory:");

modified radicle/src/node/seed/store.rs
@@ -10,7 +10,7 @@ use crate::node::address;
use crate::node::address::Store as _;
use crate::node::NodeId;
use crate::node::{seed::SyncedSeed, Database, SyncedAt};
-
use crate::prelude::{Id, Timestamp};
+
use crate::prelude::{RepoId, Timestamp};

#[derive(Error, Debug)]
pub enum Error {
@@ -29,7 +29,7 @@ pub trait Store: address::Store {
    /// Mark a repo as synced on the given node.
    fn synced(
        &mut self,
-
        rid: &Id,
+
        rid: &RepoId,
        nid: &NodeId,
        at: Oid,
        timestamp: Timestamp,
@@ -38,18 +38,18 @@ pub trait Store: address::Store {
    fn seeded_by(
        &self,
        nid: &NodeId,
-
    ) -> Result<Box<dyn Iterator<Item = Result<(Id, SyncedAt), Error>> + '_>, Error>;
+
    ) -> Result<Box<dyn Iterator<Item = Result<(RepoId, SyncedAt), Error>> + '_>, Error>;
    /// Get nodes that have synced the given repo.
    fn seeds_for(
        &self,
-
        rid: &Id,
+
        rid: &RepoId,
    ) -> Result<Box<dyn Iterator<Item = Result<SyncedSeed, Error>> + '_>, Error>;
}

impl Store for Database {
    fn synced(
        &mut self,
-
        rid: &Id,
+
        rid: &RepoId,
        nid: &NodeId,
        at: Oid,
        timestamp: Timestamp,
@@ -72,7 +72,7 @@ impl Store for Database {

    fn seeds_for(
        &self,
-
        rid: &Id,
+
        rid: &RepoId,
    ) -> Result<Box<dyn Iterator<Item = Result<SyncedSeed, Error>> + '_>, Error> {
        let mut stmt = self.db.prepare(
            "SELECT node, head, timestamp
@@ -106,7 +106,7 @@ impl Store for Database {
    fn seeded_by(
        &self,
        nid: &NodeId,
-
    ) -> Result<Box<dyn Iterator<Item = Result<(Id, SyncedAt), Error>> + '_>, Error> {
+
    ) -> Result<Box<dyn Iterator<Item = Result<(RepoId, SyncedAt), Error>> + '_>, Error> {
        let mut stmt = self.db.prepare(
            "SELECT repo, head, timestamp
             FROM `repo-sync-status`
@@ -116,7 +116,7 @@ impl Store for Database {

        Ok(Box::new(stmt.into_iter().map(|row| {
            let row = row?;
-
            let rid = row.try_read::<Id, _>("repo")?;
+
            let rid = row.try_read::<RepoId, _>("repo")?;
            let oid = row.try_read::<&str, _>("head")?;
            let oid = Oid::from_str(oid).map_err(|e| {
                Error::Internal(sql::Error {
modified radicle/src/rad.rs
@@ -10,7 +10,7 @@ use crate::cob::ObjectId;
use crate::crypto::{Signer, Verified};
use crate::git;
use crate::identity::doc;
-
use crate::identity::doc::{DocError, Id, Visibility};
+
use crate::identity::doc::{DocError, RepoId, Visibility};
use crate::identity::project::Project;
use crate::storage::git::transport;
use crate::storage::git::Repository;
@@ -52,7 +52,7 @@ pub fn init<G: Signer, S: WriteStorage>(
    visibility: Visibility,
    signer: &G,
    storage: S,
-
) -> Result<(Id, identity::Doc<Verified>, SignedRefs<Verified>), InitError> {
+
) -> Result<(RepoId, identity::Doc<Verified>, SignedRefs<Verified>), InitError> {
    // TODO: Better error when project id already exists in storage, but remote doesn't.
    let pk = signer.public_key();
    let delegate = identity::Did::from(*pk);
@@ -127,14 +127,14 @@ pub enum ForkError {
    #[error("payload: {0}")]
    Payload(#[from] doc::PayloadError),
    #[error("project `{0}` was not found in storage")]
-
    NotFound(Id),
+
    NotFound(RepoId),
    #[error("repository: {0}")]
    Repository(#[from] RepositoryError),
}

/// Create a local tree for an existing project, from an existing remote.
pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
-
    proj: Id,
+
    proj: RepoId,
    remote: &RemoteId,
    signer: &G,
    storage: S,
@@ -169,7 +169,7 @@ pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
}

pub fn fork<G: Signer, S: storage::WriteStorage>(
-
    rid: Id,
+
    rid: RepoId,
    signer: &G,
    storage: &S,
) -> Result<(), ForkError> {
@@ -198,7 +198,7 @@ pub enum CheckoutError {
    #[error("payload: {0}")]
    Payload(#[from] doc::PayloadError),
    #[error("project `{0}` was not found in storage")]
-
    NotFound(Id),
+
    NotFound(RepoId),
    #[error("repository: {0}")]
    Repository(#[from] RepositoryError),
}
@@ -206,7 +206,7 @@ pub enum CheckoutError {
/// Checkout a project from storage as a working copy.
/// This effectively does a `git-clone` from storage.
pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
-
    proj: Id,
+
    proj: RepoId,
    remote: &RemoteId,
    path: P,
    storage: &S,
@@ -265,11 +265,11 @@ pub enum RemoteError {
    #[error("remote `{0}` not found")]
    NotFound(String),
    #[error("expected remote for {expected} but found {found}")]
-
    RidMismatch { found: Id, expected: Id },
+
    RidMismatch { found: RepoId, expected: RepoId },
}

/// Get the radicle ("rad") remote of a repository, and return the associated project id.
-
pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, Id), RemoteError> {
+
pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, RepoId), RemoteError> {
    let remote = repo.find_remote(&REMOTE_NAME).map_err(|e| {
        if e.code() == git2::ErrorCode::NotFound {
            RemoteError::NotFound(REMOTE_NAME.to_string())
@@ -305,7 +305,7 @@ pub fn remove_remote(repo: &git2::Repository) -> Result<(), RemoteError> {
/// This function should only perform read operations since we do not
/// want to modify the wrong repository in the case that it found a
/// Git repository that is not a Radicle repository.
-
pub fn cwd() -> Result<(git2::Repository, Id), RemoteError> {
+
pub fn cwd() -> Result<(git2::Repository, RepoId), RemoteError> {
    let repo = repo()?;
    let (_, id) = remote(&repo)?;

@@ -313,7 +313,7 @@ pub fn cwd() -> Result<(git2::Repository, Id), RemoteError> {
}

/// Get the repository of project in specified directory
-
pub fn at(path: impl AsRef<Path>) -> Result<(git2::Repository, Id), RemoteError> {
+
pub fn at(path: impl AsRef<Path>) -> Result<(git2::Repository, RepoId), RemoteError> {
    let repo = git2::Repository::open(path)?;
    let (_, id) = remote(&repo)?;

modified radicle/src/sql.rs
@@ -4,7 +4,7 @@ use std::str::FromStr;
use sqlite as sql;
use sqlite::Value;

-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node;
use crate::node::Address;

@@ -28,12 +28,12 @@ pub fn transaction<T, E: From<sql::Error>>(
    }
}

-
impl TryFrom<&Value> for Id {
+
impl TryFrom<&Value> for RepoId {
    type Error = sql::Error;

    fn try_from(value: &Value) -> Result<Self, Self::Error> {
        match value {
-
            Value::String(id) => Id::from_urn(id).map_err(|e| sql::Error {
+
            Value::String(id) => RepoId::from_urn(id).map_err(|e| sql::Error {
                code: None,
                message: Some(e.to_string()),
            }),
@@ -45,7 +45,7 @@ impl TryFrom<&Value> for Id {
    }
}

-
impl sqlite::BindableWithIndex for &Id {
+
impl sqlite::BindableWithIndex for &RepoId {
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        self.urn().as_str().bind(stmt, i)
    }
modified radicle/src/storage.rs
@@ -20,7 +20,7 @@ use crate::git::ext as git_ext;
use crate::git::{refspec::Refspec, PatternString, Qualified, RefError, RefString};
use crate::identity::{Did, PayloadError};
use crate::identity::{Doc, DocAt, DocError};
-
use crate::identity::{Id, Identity};
+
use crate::identity::{Identity, RepoId};
use crate::storage::git::NAMESPACES_GLOB;
use crate::storage::refs::Refs;

@@ -28,7 +28,7 @@ use self::git::UserInfo;
use self::refs::SignedRefs;

pub type BranchName = git::RefString;
-
pub type Inventory = Vec<Id>;
+
pub type Inventory = Vec<RepoId>;

/// Describes one or more namespaces.
#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -344,16 +344,16 @@ pub trait ReadStorage {
    /// Get the storage base path.
    fn path(&self) -> &Path;
    /// Get a repository's path.
-
    fn path_of(&self, rid: &Id) -> PathBuf;
+
    fn path_of(&self, rid: &RepoId) -> PathBuf;
    /// Check whether storage contains a repository.
-
    fn contains(&self, rid: &Id) -> Result<bool, RepositoryError>;
+
    fn contains(&self, rid: &RepoId) -> Result<bool, RepositoryError>;
    /// Get the inventory of repositories hosted under this storage.
    /// This function should typically only return public repositories.
    fn inventory(&self) -> Result<Inventory, Error>;
    /// Open or create a read-only repository.
-
    fn repository(&self, rid: Id) -> Result<Self::Repository, Error>;
+
    fn repository(&self, rid: RepoId) -> Result<Self::Repository, Error>;
    /// Get a repository's identity if it exists.
-
    fn get(&self, rid: Id) -> Result<Option<Doc<Verified>>, RepositoryError> {
+
    fn get(&self, rid: RepoId) -> Result<Option<Doc<Verified>>, RepositoryError> {
        match self.repository(rid) {
            Ok(repo) => Ok(Some(repo.identity_doc()?.into())),
            Err(e) if e.is_not_found() => Ok(None),
@@ -367,9 +367,9 @@ pub trait WriteStorage: ReadStorage {
    type RepositoryMut: WriteRepository;

    /// Open a read-write repository.
-
    fn repository_mut(&self, rid: Id) -> Result<Self::RepositoryMut, Error>;
+
    fn repository_mut(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error>;
    /// Create a read-write repository.
-
    fn create(&self, rid: Id) -> Result<Self::RepositoryMut, Error>;
+
    fn create(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error>;

    /// Clean the repository found at `rid`.
    ///
@@ -379,13 +379,13 @@ pub trait WriteStorage: ReadStorage {
    ///
    /// If the local peer has no initialised `rad/sigrefs`, then the
    /// repository will be entirely removed from storage.
-
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError>;
+
    fn clean(&self, rid: RepoId) -> Result<Vec<RemoteId>, RepositoryError>;
}

/// Allows read-only access to a repository.
pub trait ReadRepository: Sized + ValidateRepository {
    /// Return the repository id.
-
    fn id(&self) -> Id;
+
    fn id(&self) -> RepoId;

    /// Returns `true` if there are no references in the repository.
    fn is_empty(&self) -> Result<bool, git2::Error>;
@@ -585,11 +585,11 @@ where
        self.deref().path()
    }

-
    fn path_of(&self, rid: &Id) -> PathBuf {
+
    fn path_of(&self, rid: &RepoId) -> PathBuf {
        self.deref().path_of(rid)
    }

-
    fn contains(&self, rid: &Id) -> Result<bool, RepositoryError> {
+
    fn contains(&self, rid: &RepoId) -> Result<bool, RepositoryError> {
        self.deref().contains(rid)
    }

@@ -597,11 +597,11 @@ where
        self.deref().inventory()
    }

-
    fn get(&self, rid: Id) -> Result<Option<Doc<Verified>>, RepositoryError> {
+
    fn get(&self, rid: RepoId) -> Result<Option<Doc<Verified>>, RepositoryError> {
        self.deref().get(rid)
    }

-
    fn repository(&self, rid: Id) -> Result<Self::Repository, Error> {
+
    fn repository(&self, rid: RepoId) -> Result<Self::Repository, Error> {
        self.deref().repository(rid)
    }
}
@@ -613,15 +613,15 @@ where
{
    type RepositoryMut = S::RepositoryMut;

-
    fn repository_mut(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn repository_mut(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        self.deref().repository_mut(rid)
    }

-
    fn create(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn create(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        self.deref().create(rid)
    }

-
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
    fn clean(&self, rid: RepoId) -> Result<Vec<RemoteId>, RepositoryError> {
        self.deref().clean(rid)
    }
}
modified radicle/src/storage/git.rs
@@ -14,7 +14,7 @@ use tempfile::TempDir;
use crate::crypto::Unverified;
use crate::git;
use crate::identity::doc::DocError;
-
use crate::identity::{doc::DocAt, Doc, Id};
+
use crate::identity::{doc::DocAt, Doc, RepoId};
use crate::identity::{Identity, Project};
use crate::storage::refs;
use crate::storage::refs::{Refs, SignedRefs, SignedRefsAt};
@@ -46,7 +46,7 @@ pub static CANONICAL_IDENTITY: Lazy<git::Qualified> = Lazy::new(|| {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RepositoryInfo<V> {
    /// Repository identifier.
-
    pub rid: Id,
+
    pub rid: RepoId,
    /// Head of default branch.
    pub head: Oid,
    /// Identity document.
@@ -101,11 +101,11 @@ impl ReadStorage for Storage {
        self.path.as_path()
    }

-
    fn path_of(&self, rid: &Id) -> PathBuf {
+
    fn path_of(&self, rid: &RepoId) -> PathBuf {
        paths::repository(&self, rid)
    }

-
    fn contains(&self, rid: &Id) -> Result<bool, RepositoryError> {
+
    fn contains(&self, rid: &RepoId) -> Result<bool, RepositoryError> {
        if paths::repository(&self, rid).exists() {
            let _ = self.repository(*rid)?.head()?;
            return Ok(true);
@@ -123,7 +123,7 @@ impl ReadStorage for Storage {
            .collect())
    }

-
    fn repository(&self, rid: Id) -> Result<Self::Repository, Error> {
+
    fn repository(&self, rid: RepoId) -> Result<Self::Repository, Error> {
        Repository::open(paths::repository(self, &rid), rid)
    }
}
@@ -131,15 +131,15 @@ impl ReadStorage for Storage {
impl WriteStorage for Storage {
    type RepositoryMut = Repository;

-
    fn repository_mut(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn repository_mut(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        Repository::open(paths::repository(self, &rid), rid)
    }

-
    fn create(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn create(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        Repository::create(paths::repository(self, &rid), rid, &self.info)
    }

-
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
    fn clean(&self, rid: RepoId) -> Result<Vec<RemoteId>, RepositoryError> {
        let repo = self.repository(rid)?;
        // N.b. we remove the repository if the `local` peer has no
        // `rad/sigrefs`. There's no risk of them corrupting data.
@@ -173,7 +173,7 @@ impl Storage {
    /// N.b. it is important to keep the [`TempDir`] in scope while
    /// using the [`Repository`]. If it is dropped, any action on the
    /// `Repository` will fail.
-
    pub fn lock_repository(&self, rid: Id) -> Result<(Repository, TempDir), RepositoryError> {
+
    pub fn lock_repository(&self, rid: RepoId) -> Result<(Repository, TempDir), RepositoryError> {
        if self.contains(&rid)? {
            return Err(Error::Io(io::Error::new(
                io::ErrorKind::AlreadyExists,
@@ -213,8 +213,8 @@ impl Storage {
                    continue;
                }
            }
-
            let rid =
-
                Id::try_from(path.file_name()).map_err(|_| Error::InvalidId(path.file_name()))?;
+
            let rid = RepoId::try_from(path.file_name())
+
                .map_err(|_| Error::InvalidId(path.file_name()))?;

            let repo = match self.repository(rid) {
                Ok(repo) => repo,
@@ -272,7 +272,7 @@ impl Storage {
/// Git implementation of [`WriteRepository`] using the `git2` crate.
pub struct Repository {
    /// The repository identifier (RID).
-
    pub id: Id,
+
    pub id: RepoId,
    /// The backing Git repository.
    pub backend: git2::Repository,
}
@@ -335,14 +335,14 @@ pub enum Validation {

impl Repository {
    /// Open an existing repository.
-
    pub fn open<P: AsRef<Path>>(path: P, id: Id) -> Result<Self, Error> {
+
    pub fn open<P: AsRef<Path>>(path: P, id: RepoId) -> Result<Self, Error> {
        let backend = git2::Repository::open_bare(path.as_ref())?;

        Ok(Self { id, backend })
    }

    /// Create a new repository.
-
    pub fn create<P: AsRef<Path>>(path: P, id: Id, info: &UserInfo) -> Result<Self, Error> {
+
    pub fn create<P: AsRef<Path>>(path: P, id: RepoId, info: &UserInfo) -> Result<Self, Error> {
        let backend = git2::Repository::init_opts(
            &path,
            git2::RepositoryInitOptions::new()
@@ -426,7 +426,7 @@ impl Repository {
        signer: &G,
    ) -> Result<(Self, git::Oid), RepositoryError> {
        let (doc_oid, _) = doc.encode()?;
-
        let id = Id::from(doc_oid);
+
        let id = RepoId::from(doc_oid);
        let repo = Self::create(paths::repository(storage, &id), id, storage.info())?;
        let commit = doc.init(&repo, signer)?;

@@ -577,7 +577,7 @@ impl ValidateRepository for Repository {
}

impl ReadRepository for Repository {
-
    fn id(&self) -> Id {
+
    fn id(&self) -> RepoId {
        self.id
    }

@@ -988,10 +988,10 @@ pub mod trailers {
pub mod paths {
    use std::path::PathBuf;

-
    use super::Id;
    use super::ReadStorage;
+
    use super::RepoId;

-
    pub fn repository<S: ReadStorage>(storage: &S, proj: &Id) -> PathBuf {
+
    pub fn repository<S: ReadStorage>(storage: &S, proj: &RepoId) -> PathBuf {
        storage.path().join(proj.canonical())
    }
}
@@ -1285,7 +1285,7 @@ mod tests {
        let mut rng = fastrand::Rng::new();
        let signer = MockSigner::new(&mut rng);
        let storage = Storage::open(tmp.path(), fixtures::user()).unwrap();
-
        let proj_id = arbitrary::gen::<Id>(1);
+
        let proj_id = arbitrary::gen::<RepoId>(1);
        let alice = *signer.public_key();
        let project = storage.create(proj_id).unwrap();
        let backend = &project.backend;
modified radicle/src/storage/git/cob.rs
@@ -250,7 +250,7 @@ impl<'a, R: storage::ValidateRepository> ValidateRepository for DraftStore<'a, R
}

impl<'a, R: storage::ReadRepository> ReadRepository for DraftStore<'a, R> {
-
    fn id(&self) -> identity::Id {
+
    fn id(&self) -> identity::RepoId {
        self.repo.id()
    }

modified radicle/src/storage/git/transport/local/url.rs
@@ -6,7 +6,7 @@ use thiserror::Error;

use crate::{
    crypto,
-
    identity::{Id, IdError},
+
    identity::{IdError, RepoId},
};

/// Repository namespace.
@@ -38,7 +38,7 @@ pub enum UrlError {
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Url {
    /// Repository identifier.
-
    pub repo: Id,
+
    pub repo: RepoId,
    /// Repository sub-tree.
    pub namespace: Option<Namespace>,
}
@@ -54,8 +54,8 @@ impl Url {
    }
}

-
impl From<Id> for Url {
-
    fn from(repo: Id) -> Self {
+
impl From<RepoId> for Url {
+
    fn from(repo: RepoId) -> Self {
        Self {
            repo,
            namespace: None,
@@ -88,7 +88,7 @@ impl FromStr for Url {
            _ => return Err(UrlError::InvalidFormat),
        };

-
        let resource = Id::from_canonical(resource).map_err(UrlError::InvalidRepository)?;
+
        let resource = RepoId::from_canonical(resource).map_err(UrlError::InvalidRepository)?;
        let namespace = namespace
            .map(|pk| Namespace::from_str(pk).map_err(UrlError::InvalidNamespace))
            .transpose()?;
@@ -107,7 +107,7 @@ mod test {

    #[test]
    fn test_url_parse() {
-
        let repo = Id::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
+
        let repo = RepoId::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
        let namespace =
            Namespace::from_str("z6Mkifeb5NPS6j7JP72kEQEeuqMTpCAVcHsJi1C86jGTzHRi").unwrap();

@@ -137,7 +137,7 @@ mod test {

    #[test]
    fn test_url_to_string() {
-
        let repo = Id::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
+
        let repo = RepoId::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
        let namespace =
            Namespace::from_str("z6Mkifeb5NPS6j7JP72kEQEeuqMTpCAVcHsJi1C86jGTzHRi").unwrap();

modified radicle/src/storage/git/transport/remote/url.rs
@@ -6,7 +6,7 @@ use thiserror::Error;

use crate::{
    crypto,
-
    identity::{Id, IdError},
+
    identity::{IdError, RepoId},
};

type NodeId = crypto::PublicKey;
@@ -40,7 +40,7 @@ pub struct Url {
    /// Node identifier.
    pub node: NodeId,
    /// Repository identifier.
-
    pub repo: Id,
+
    pub repo: RepoId,
    /// Repository sub-tree.
    pub namespace: Option<Namespace>,
}
@@ -89,7 +89,7 @@ impl FromStr for Url {
        };

        let node = NodeId::from_str(node).map_err(UrlError::InvalidNode)?;
-
        let resource = Id::from_canonical(resource).map_err(UrlError::InvalidRepository)?;
+
        let resource = RepoId::from_canonical(resource).map_err(UrlError::InvalidRepository)?;
        let namespace = namespace
            .map(|pk| Namespace::from_str(pk).map_err(UrlError::InvalidNamespace))
            .transpose()?;
@@ -110,7 +110,7 @@ mod test {
    #[test]
    fn test_url_parse() {
        let node = NodeId::from_str("z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK").unwrap();
-
        let repo = Id::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
+
        let repo = RepoId::from_canonical("z2w8RArM3gaBXZxXhQUswE3hhLcss").unwrap();
        let namespace =
            Namespace::from_str("z6Mkifeb5NPS6j7JP72kEQEeuqMTpCAVcHsJi1C86jGTzHRi").unwrap();

modified radicle/src/test.rs
@@ -122,7 +122,7 @@ pub mod setup {
            }
        }

-
        pub fn clone(&mut self, rid: Id, other: &Self) {
+
        pub fn clone(&mut self, rid: RepoId, other: &Self) {
            let repo = self.storage.create(rid).unwrap();
            super::fetch(&repo, other.signer.public_key(), Namespaces::All).unwrap();

@@ -241,7 +241,7 @@ pub mod setup {
        pub alice: NodeWithRepo,
        pub bob: NodeWithRepo,
        pub eve: NodeWithRepo,
-
        pub rid: Id,
+
        pub rid: RepoId,

        #[allow(dead_code)]
        tmp: tempfile::TempDir,
modified radicle/src/test/arbitrary.rs
@@ -12,7 +12,7 @@ use qcheck::Arbitrary;
use crate::collections::RandomMap;
use crate::identity::doc::Visibility;
use crate::identity::{
-
    doc::{Doc, DocAt, Id},
+
    doc::{Doc, DocAt, RepoId},
    project::Project,
    Did,
};
@@ -68,7 +68,7 @@ pub fn vec<T: Eq + Arbitrary>(size: usize) -> Vec<T> {
pub fn nonempty_storage(size: usize) -> MockStorage {
    let mut storage = gen::<MockStorage>(size);
    for _ in 0..size {
-
        storage.inventory.insert(gen::<Id>(1), gen::<DocAt>(1));
+
        storage.inventory.insert(gen::<RepoId>(1), gen::<DocAt>(1));
    }
    storage
}
@@ -224,7 +224,7 @@ impl Arbitrary for MockStorage {

impl Arbitrary for MockRepository {
    fn arbitrary(g: &mut qcheck::Gen) -> Self {
-
        let rid = Id::arbitrary(g);
+
        let rid = RepoId::arbitrary(g);
        let doc = Doc::<Verified>::arbitrary(g);

        Self::new(rid, doc)
@@ -241,12 +241,12 @@ impl Arbitrary for storage::Remote<crypto::Verified> {
    }
}

-
impl Arbitrary for Id {
+
impl Arbitrary for RepoId {
    fn arbitrary(g: &mut qcheck::Gen) -> Self {
        let bytes = <[u8; 20]>::arbitrary(g);
        let oid = git::Oid::try_from(bytes.as_slice()).unwrap();

-
        Id::from(oid)
+
        RepoId::from(oid)
    }
}

modified radicle/src/test/fixtures.rs
@@ -4,7 +4,7 @@ use std::str::FromStr;
use crate::crypto::{PublicKey, Signer, Verified};
use crate::git;
use crate::identity::doc::Visibility;
-
use crate::identity::Id;
+
use crate::identity::RepoId;
use crate::node::Alias;
use crate::rad;
use crate::storage::git::transport;
@@ -55,7 +55,7 @@ pub fn project<P: AsRef<Path>, G: Signer>(
    path: P,
    storage: &Storage,
    signer: &G,
-
) -> Result<(Id, SignedRefs<Verified>, git2::Repository, git2::Oid), rad::InitError> {
+
) -> Result<(RepoId, SignedRefs<Verified>, git2::Repository, git2::Oid), rad::InitError> {
    transport::local::register(storage.clone());

    let (working, head) = repository(path);
modified radicle/src/test/storage.rs
@@ -6,7 +6,7 @@ use std::str::FromStr;
use git_ext::ref_format as fmt;

use crate::crypto::{Signer, Verified};
-
use crate::identity::doc::{Doc, DocAt, DocError, Id};
+
use crate::identity::doc::{Doc, DocAt, DocError, RepoId};
use crate::node::NodeId;

pub use crate::storage::*;
@@ -16,16 +16,16 @@ use super::fixtures;
#[derive(Clone, Debug)]
pub struct MockStorage {
    pub path: PathBuf,
-
    pub inventory: HashMap<Id, DocAt>,
+
    pub inventory: HashMap<RepoId, DocAt>,
    pub info: git::UserInfo,

    /// All refs keyed by RID.
    /// Each value is a map of refs keyed by node Id (public key).
-
    pub remotes: HashMap<Id, HashMap<NodeId, refs::SignedRefsAt>>,
+
    pub remotes: HashMap<RepoId, HashMap<NodeId, refs::SignedRefsAt>>,
}

impl MockStorage {
-
    pub fn new(inventory: Vec<(Id, DocAt)>) -> Self {
+
    pub fn new(inventory: Vec<(RepoId, DocAt)>) -> Self {
        Self {
            path: PathBuf::default(),
            info: fixtures::user(),
@@ -39,7 +39,7 @@ impl MockStorage {
    }

    /// Add a remote `node` with `signed_refs` for the repo `rid`.
-
    pub fn insert_remote(&mut self, rid: Id, node: NodeId, refs: refs::SignedRefsAt) {
+
    pub fn insert_remote(&mut self, rid: RepoId, node: NodeId, refs: refs::SignedRefsAt) {
        self.remotes.entry(rid).or_default().insert(node, refs);
    }
}
@@ -55,11 +55,11 @@ impl ReadStorage for MockStorage {
        self.path.as_path()
    }

-
    fn path_of(&self, rid: &Id) -> PathBuf {
+
    fn path_of(&self, rid: &RepoId) -> PathBuf {
        self.path().join(rid.canonical())
    }

-
    fn contains(&self, rid: &Id) -> Result<bool, RepositoryError> {
+
    fn contains(&self, rid: &RepoId) -> Result<bool, RepositoryError> {
        Ok(self.inventory.contains_key(rid))
    }

@@ -67,7 +67,7 @@ impl ReadStorage for MockStorage {
        Ok(self.inventory.keys().cloned().collect::<Vec<_>>())
    }

-
    fn repository(&self, rid: Id) -> Result<Self::Repository, Error> {
+
    fn repository(&self, rid: RepoId) -> Result<Self::Repository, Error> {
        let doc = self
            .inventory
            .get(&rid)
@@ -83,7 +83,7 @@ impl ReadStorage for MockStorage {
impl WriteStorage for MockStorage {
    type RepositoryMut = MockRepository;

-
    fn repository_mut(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn repository_mut(&self, rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        let doc = self.inventory.get(&rid).unwrap();
        Ok(MockRepository {
            id: rid,
@@ -92,24 +92,24 @@ impl WriteStorage for MockStorage {
        })
    }

-
    fn create(&self, _rid: Id) -> Result<Self::RepositoryMut, Error> {
+
    fn create(&self, _rid: RepoId) -> Result<Self::RepositoryMut, Error> {
        todo!()
    }

-
    fn clean(&self, _rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
    fn clean(&self, _rid: RepoId) -> Result<Vec<RemoteId>, RepositoryError> {
        todo!()
    }
}

#[derive(Clone, Debug)]
pub struct MockRepository {
-
    id: Id,
+
    id: RepoId,
    doc: DocAt,
    remotes: HashMap<NodeId, refs::SignedRefsAt>,
}

impl MockRepository {
-
    pub fn new(id: Id, doc: Doc<Verified>) -> Self {
+
    pub fn new(id: RepoId, doc: Doc<Verified>) -> Self {
        let (blob, _) = doc.encode().unwrap();

        Self {
@@ -157,7 +157,7 @@ impl ValidateRepository for MockRepository {
}

impl ReadRepository for MockRepository {
-
    fn id(&self) -> Id {
+
    fn id(&self) -> RepoId {
        self.id
    }