Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Consolidate policy/scope variants
cloudhead committed 2 years ago
commit f453090e27a6be99aaefee4e5eac6cdd4cd7ff7f
parent 4605348d68d5ebc27cf578cbec759b56b0fc1ba7
25 files changed +128 -132
modified rad.1.adoc
@@ -153,8 +153,8 @@ You can see all replicated and locally-available repositories using:
    $ rad ls

By default, your node will subscribe to updates from _all_ peers. This
-
behavior can be changed by passing *--scope trusted* when cloning. It can
-
also be changed later via the *rad track* command.
+
behavior can be changed by passing *--scope followed* when cloning. It can
+
also be changed later via the *rad seed* command.

=== Publishing a repository on Radicle

modified radicle-cli/examples/rad-clone-unknown.md
@@ -1,7 +1,7 @@
Trying to clone a repository that is not in our routing table returns an error:

``` (fail)
-
$ rad clone rad:zVNuptPuk5XauitpCWSNVCXGGfXW --scope trusted
-
✓ Tracking relationship established for rad:zVNuptPuk5XauitpCWSNVCXGGfXW with scope 'trusted'
+
$ rad clone rad:zVNuptPuk5XauitpCWSNVCXGGfXW --scope followed
+
✓ Tracking relationship established for rad:zVNuptPuk5XauitpCWSNVCXGGfXW with scope 'followed'
✗ Error: no seeds found for rad:zVNuptPuk5XauitpCWSNVCXGGfXW
```
modified radicle-cli/examples/rad-clone.md
@@ -2,8 +2,8 @@ To create a local copy of a repository on the radicle network, we use the
`clone` command, followed by the identifier or *RID* of the repository:

```
-
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope trusted
-
✓ Tracking relationship established for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'trusted'
+
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope followed
+
✓ Tracking relationship established for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'followed'
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
✓ Forking under z6Mkt67…v4N1tRk..
✓ Creating checkout in ./heartwood..
modified radicle-cli/examples/rad-config.md
@@ -37,7 +37,7 @@ $ rad config
      }
    },
    "policy": "block",
-
    "scope": "trusted"
+
    "scope": "followed"
  }
}
```
modified radicle-cli/examples/rad-init-private-clone.md
@@ -2,8 +2,8 @@ Given a private repo `rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu` belonging to Alice,
Bob tries to fetch it, and even though he's connected to Alice, it fails.

``` ~bob
-
$ rad seed rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --scope trusted
-
✓ Seeding policy updated for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu with scope 'trusted'
+
$ rad seed rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --scope followed
+
✓ Seeding policy updated for rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu with scope 'followed'
$ rad ls
```
``` ~bob (fail)
modified radicle-cli/examples/rad-init-sync.md
@@ -3,7 +3,7 @@ To create your first radicle project, navigate to a git repository, and run
the `init` command:

```
-
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm --public --scope trusted
+
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm --public --scope followed

Initializing public radicle 👾 project in .

modified radicle-cli/examples/rad-node.md
@@ -34,11 +34,11 @@ repository that was already created:

```
$ rad node seeding
-
╭──────────────────────────────────────────────────────╮
-
│ RID                                 Scope     Policy │
-
├──────────────────────────────────────────────────────┤
-
│ rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji   trusted   track  │
-
╰──────────────────────────────────────────────────────╯
+
╭───────────────────────────────────────────────────────╮
+
│ RID                                 Scope      Policy │
+
├───────────────────────────────────────────────────────┤
+
│ rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji   followed   allow  │
+
╰───────────────────────────────────────────────────────╯
```

If we wish to see which nodes we are following:
@@ -48,7 +48,7 @@ $ rad node following
╭───────────────────────────────────────────────────────────────────────────╮
│ DID                                                        Alias   Policy │
├───────────────────────────────────────────────────────────────────────────┤
-
│ did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk   Bob     track  │
+
│ did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk   Bob     allow  │
╰───────────────────────────────────────────────────────────────────────────╯
```

modified radicle-cli/examples/rad-track.md
@@ -9,6 +9,6 @@ $ rad follow did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk --alias ev
Now let's track one of Eve's repositories:

```
-
$ rad seed rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope trusted --no-fetch
-
✓ Seeding policy updated for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'trusted'
+
$ rad seed rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --scope followed --no-fetch
+
✓ Seeding policy updated for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji with scope 'followed'
```
modified radicle-cli/src/commands/inspect.rs
@@ -176,7 +176,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            let tracking = profile.tracking()?;
            if let Some(repo) = tracking.repo_policy(&rid)? {
                let tracking = match repo.policy {
-
                    Policy::Track => term::format::positive("tracked"),
+
                    Policy::Allow => term::format::positive("tracked"),
                    Policy::Block => term::format::negative("blocked"),
                };
                println!(
modified radicle-cli/src/commands/seed.rs
@@ -25,15 +25,15 @@ Usage
    To delete a policy, use the `--delete` flag.

    When seeding a repository, a scope can be specified: this can be either `all` or
-
    `trusted`. When using `all`, all remote nodes will be followed for that repository.
-
    On the other hand, with `trusted`, only the repository delegates will be followed,
+
    `followed`. When using `all`, all remote nodes will be followed for that repository.
+
    On the other hand, with `followed`, only the repository delegates will be followed,
    plus any remote that is explicitly followed via `rad follow <nid>`.

Options

    --delete, -d           Delete the seeding policy
    --[no-]fetch           Fetch repository after updating seeding policy
-
    --scope <scope>        Peer follow scope for a repository
+
    --scope <scope>        Peer follow scope for this repository
    --verbose, -v          Verbose output
    --help                 Print help
"#,
modified radicle-cli/tests/commands.rs
@@ -700,7 +700,7 @@ fn rad_clean() {
    let mut bob = bob.spawn();
    let mut eve = eve.spawn();
    alice.handle.track_repo(acme, Scope::All).unwrap();
-
    eve.handle.track_repo(acme, Scope::Trusted).unwrap();
+
    eve.handle.track_repo(acme, Scope::Followed).unwrap();

    bob.connect(&alice).converge([&alice]);
    eve.connect(&alice).converge([&alice]);
@@ -769,7 +769,7 @@ fn rad_clone() {
    let mut alice = alice.spawn();
    let mut bob = bob.spawn();
    // Prevent Alice from fetching Bob's fork, as we're not testing that and it may cause errors.
-
    alice.handle.track_repo(acme, Scope::Trusted).unwrap();
+
    alice.handle.track_repo(acme, Scope::Followed).unwrap();

    bob.connect(&alice).converge([&alice]);

@@ -873,8 +873,8 @@ fn rad_clone_connect() {

    let eve = eve.spawn();

-
    alice.handle.track_repo(acme, Scope::Trusted).unwrap();
-
    bob.handle.track_repo(acme, Scope::Trusted).unwrap();
+
    alice.handle.track_repo(acme, Scope::Followed).unwrap();
+
    bob.handle.track_repo(acme, Scope::Followed).unwrap();
    alice.connect(&bob);
    bob.routes_to(&[(acme, alice.id)]);
    eve.routes_to(&[(acme, alice.id), (acme, bob.id)]);
@@ -1257,7 +1257,7 @@ fn test_replication_via_seed() {
    let alice = environment.node(Config::test(Alias::new("alice")));
    let bob = environment.node(Config::test(Alias::new("bob")));
    let seed = environment.node(Config {
-
        policy: Policy::Track,
+
        policy: Policy::Allow,
        scope: Scope::All,
        ..Config::test(Alias::new("seed"))
    });
modified radicle-fetch/src/stage.rs
@@ -13,7 +13,7 @@
//!      delegate data for the repository.
//!   2. [`SpecialRefs`]: fetches the special references, `rad/id` and
//!      `rad/sigrefs`, for each configured namespace, i.e. tracked
-
//!      and delegate peers if the scope is trusted and all peers is the
+
//!      and delegate peers if the scope is "followed" and all peers is the
//!      scope is all.
//!   3. [`DataRefs`]: fetches the `Oid`s for each reference listed in
//!      the `rad/sigrefs` for each fetched peer in the
@@ -241,7 +241,7 @@ impl ProtocolStage for SpecialRefs {
    fn ls_refs(&self) -> Option<NonEmpty<BString>> {
        match &self.tracked {
            tracking::Tracked::All => Some(NonEmpty::new("refs/namespaces".into())),
-
            tracking::Tracked::Trusted { remotes } => NonEmpty::collect(
+
            tracking::Tracked::Followed { remotes } => NonEmpty::collect(
                remotes
                    .iter()
                    .chain(self.delegates.iter())
modified radicle-fetch/src/tracking.rs
@@ -10,7 +10,7 @@ pub use radicle::node::tracking::{Policy, Scope};
#[derive(Clone, Debug)]
pub enum Tracked {
    All,
-
    Trusted { remotes: HashSet<PublicKey> },
+
    Followed { remotes: HashSet<PublicKey> },
}

impl Tracked {
@@ -23,17 +23,17 @@ impl Tracked {
                log::error!(target: "fetch", "Attempted to fetch untracked repo {rid}");
                Err(error::Tracking::BlockedPolicy { rid })
            }
-
            Policy::Track => match entry.scope {
+
            Policy::Allow => match entry.scope {
                Scope::All => Ok(Self::All),
-
                Scope::Trusted => {
+
                Scope::Followed => {
                    let nodes = config
                        .node_policies()
                        .map_err(|err| error::Tracking::FailedNodes { rid, err })?;
-
                    let trusted: HashSet<_> = nodes
-
                        .filter_map(|node| (node.policy == Policy::Track).then_some(node.id))
+
                    let followed: HashSet<_> = nodes
+
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.id))
                        .collect();

-
                    Ok(Tracked::Trusted { remotes: trusted })
+
                    Ok(Tracked::Followed { remotes: followed })
                }
            },
        }
modified radicle-node/src/service.rs
@@ -425,7 +425,7 @@ where
        self.filter = Filter::new(
            self.tracking
                .repo_policies()?
-
                .filter_map(|t| (t.policy == tracking::Policy::Track).then_some(t.id)),
+
                .filter_map(|t| (t.policy == tracking::Policy::Allow).then_some(t.id)),
        );
        Ok(updated)
    }
@@ -570,7 +570,7 @@ where
        self.filter = Filter::new(
            self.tracking
                .repo_policies()?
-
                .filter_map(|t| (t.policy == tracking::Policy::Track).then_some(t.id)),
+
                .filter_map(|t| (t.policy == tracking::Policy::Allow).then_some(t.id)),
        );
        // Try to establish some connections.
        self.maintain_connections();
@@ -1266,7 +1266,7 @@ where
                    "Service::handle_announcement: error accessing repo tracking configuration",
                );

-
                if repo_entry.policy == tracking::Policy::Track {
+
                if repo_entry.policy == tracking::Policy::Allow {
                    let (fresh, stale) = match self.refs_status_of(message, &repo_entry.scope) {
                        Ok(RefsStatus { fresh, stale }) => (fresh, stale),
                        Err(e) => {
@@ -1424,13 +1424,13 @@ where
        // Second, check the scope.
        match scope {
            tracking::Scope::All => Ok(refs),
-
            tracking::Scope::Trusted => {
+
            tracking::Scope::Followed => {
                match self.tracking.namespaces_for(&self.storage, &message.rid) {
                    Ok(Namespaces::All) => Ok(refs),
-
                    Ok(Namespaces::Trusted(mut trusted)) => {
-
                        // Get the set of trusted nodes except self.
-
                        trusted.remove(self.nid());
-
                        refs.fresh.retain(|r| trusted.contains(&r.remote));
+
                    Ok(Namespaces::Followed(mut followed)) => {
+
                        // Get the set of followed nodes except self.
+
                        followed.remove(self.nid());
+
                        refs.fresh.retain(|r| followed.contains(&r.remote));

                        Ok(refs)
                    }
@@ -1817,7 +1817,7 @@ where

    /// Return a new filter object, based on our tracking policy.
    fn filter(&self) -> Filter {
-
        if self.config.policy == tracking::Policy::Track {
+
        if self.config.policy == tracking::Policy::Allow {
            // TODO: Remove bits for blocked repos.
            Filter::default()
        } else {
@@ -1920,7 +1920,7 @@ where
        let missing = self
            .tracking
            .repo_policies()?
-
            .filter_map(|t| (t.policy == tracking::Policy::Track).then_some(t.id))
+
            .filter_map(|t| (t.policy == tracking::Policy::Allow).then_some(t.id))
            .filter(|rid| !inventory.contains(rid));

        for rid in missing {
modified radicle-node/src/test/environment.rs
@@ -420,7 +420,7 @@ impl<G: cyphernet::Ecdh<Pk = NodeId> + Signer + Clone> Node<G> {

        assert!(self
            .tracking
-
            .track_repo(&id, node::tracking::Scope::Trusted)
+
            .track_repo(&id, node::tracking::Scope::Followed)
            .unwrap());

        log::debug!(
modified radicle-node/src/test/peer.rs
@@ -172,7 +172,7 @@ where
        config.config.external_addresses.push(local_addr.into());

        for rid in storage.inventory().unwrap() {
-
            tracking.track_repo(&rid, Scope::Trusted).unwrap();
+
            tracking.track_repo(&rid, Scope::Followed).unwrap();
        }
        let announcement = service::gossip::node(&config.config, config.local_time.as_secs());
        let emitter: Emitter<Event> = Default::default();
modified radicle-node/src/test/simulator.rs
@@ -422,7 +422,7 @@ impl<S: WriteStorage + 'static, G: Signer> Simulation<S, G> {
                                radicle::test::fetch(
                                    &repo,
                                    &nid,
-
                                    Namespaces::Trusted(namespaces.clone()),
+
                                    Namespaces::Followed(namespaces.clone()),
                                )
                                .unwrap();
                            }
@@ -655,7 +655,7 @@ impl<S: WriteStorage + 'static, G: Signer> Simulation<S, G> {
                                Rc::new(Ok(fetch::FetchResult {
                                    updated: vec![],
                                    namespaces: match namespaces {
-
                                        Namespaces::Trusted(hs) => hs,
+
                                        Namespaces::Followed(hs) => hs,
                                        Namespaces::All => HashSet::new(),
                                    },
                                })),
modified radicle-node/src/tests.rs
@@ -742,7 +742,7 @@ fn test_refs_announcement_fetch_trusted_no_inventory() {
    let bob_inv = bob.storage().inventory().unwrap();
    let rid = bob_inv[0];

-
    alice.track_repo(&rid, tracking::Scope::Trusted).unwrap();
+
    alice.track_repo(&rid, tracking::Scope::Followed).unwrap();
    alice.connect_to(&bob);

    // Alice receives Bob's refs.
@@ -755,11 +755,11 @@ fn test_refs_announcement_fetch_trusted_no_inventory() {
/// Alice and Bob both have the same repo.
///
/// First, Alice will not fetch from Bob's `RefsAnnouncement` as Alice does not
-
/// track Bob as `Trusted`.
+
/// track Bob as `Followed`.
///
-
/// Later Alice tracks Bob, and will be able to fetch Bob's refs.
+
/// Later Alice follows Bob, and will be able to fetch Bob's refs.
#[test]
-
fn test_refs_announcement_trusted() {
+
fn test_refs_announcement_followed() {
    logger::init(log::Level::Debug);

    // Create MockStorage for Alice and Bob. Both will have repo with `rid`.
@@ -796,9 +796,9 @@ fn test_refs_announcement_trusted() {
        },
    );

-
    // Alice uses Scope::Trusted, and did not track Bob yet.
+
    // Alice uses Scope::Followed, and did not track Bob yet.
    alice.connect_to(&bob);
-
    alice.track_repo(&rid, tracking::Scope::Trusted).unwrap();
+
    alice.track_repo(&rid, tracking::Scope::Followed).unwrap();

    // Alice receives Bob's refs
    alice.receive(bob.id(), bob.refs_announcement(rid));
@@ -1538,14 +1538,14 @@ fn test_push_and_pull() {
    assert!(eve.get(proj_id).unwrap().is_none());
    assert!(bob.get(proj_id).unwrap().is_none());

-
    // Bob tracks Alice's project.
+
    // Bob seeds Alice's project.
    let (sender, _) = chan::bounded(1);
    bob.command(service::Command::TrackRepo(
        proj_id,
        tracking::Scope::default(),
        sender,
    ));
-
    // Eve tracks Alice's project.
+
    // Eve seeds Alice's project.
    let (sender, _) = chan::bounded(1);
    eve.command(service::Command::TrackRepo(
        proj_id,
modified radicle-node/src/tests/e2e.rs
@@ -284,7 +284,7 @@ fn test_replication_invalid() {
    converge([&alice, &bob]);

    alice.handle.track_node(*carol.public_key(), None).unwrap();
-
    alice.handle.track_repo(acme, Scope::Trusted).unwrap();
+
    alice.handle.track_repo(acme, Scope::Followed).unwrap();
    let result = alice.handle.fetch(acme, bob.id, DEFAULT_TIMEOUT).unwrap();

    // Fetch is successful despite not fetching Carol's refs, since she isn't a delegate.
@@ -367,7 +367,7 @@ fn test_dont_fetch_owned_refs() {
    alice.connect(&bob);
    converge([&alice, &bob]);

-
    assert!(bob.handle.track_repo(acme, Scope::Trusted).unwrap());
+
    assert!(bob.handle.track_repo(acme, Scope::Followed).unwrap());

    let result = bob.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
    assert!(result.is_success());
@@ -380,7 +380,7 @@ fn test_dont_fetch_owned_refs() {
}

#[test]
-
fn test_fetch_trusted_remotes() {
+
fn test_fetch_followed_remotes() {
    logger::init(log::Level::Debug);

    let tmp = tempfile::tempdir().unwrap();
@@ -402,18 +402,18 @@ fn test_fetch_trusted_remotes() {
    alice.connect(&bob);
    converge([&alice, &bob]);

-
    let trusted = signers
+
    let followed = signers
        .iter()
        .map(|s| *s.public_key())
        .take(2)
        .collect::<HashSet<_>>();

    assert!(
-
        trusted.len() < signers.len(),
+
        followed.len() < signers.len(),
        "Bob is only trusting a subset of peers"
    );
-
    assert!(bob.handle.track_repo(acme, Scope::Trusted).unwrap());
-
    for nid in &trusted {
+
    assert!(bob.handle.track_repo(acme, Scope::Followed).unwrap());
+
    for nid in &followed {
        assert!(bob.handle.track_node(*nid, None).unwrap());
    }

@@ -429,8 +429,8 @@ fn test_fetch_trusted_remotes() {
        .collect::<Result<HashSet<_>, _>>()
        .unwrap();

-
    assert!(bob_remotes.len() == trusted.len() + 1);
-
    assert!(bob_remotes.is_superset(&trusted));
+
    assert!(bob_remotes.len() == followed.len() + 1);
+
    assert!(bob_remotes.is_superset(&followed));
    assert!(bob_remotes.contains(&alice.id));
}

@@ -450,7 +450,7 @@ fn test_missing_remote() {
    alice.connect(&bob);
    converge([&alice, &bob]);

-
    assert!(bob.handle.track_repo(acme, Scope::Trusted).unwrap());
+
    assert!(bob.handle.track_repo(acme, Scope::Followed).unwrap());
    assert!(bob.handle.track_node(*carol.public_key(), None).unwrap());
    let result = bob.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
    assert!(result.is_success());
@@ -477,7 +477,7 @@ fn test_fetch_preserve_owned_refs() {
    alice.connect(&bob);
    converge([&alice, &bob]);

-
    assert!(bob.handle.track_repo(acme, Scope::Trusted).unwrap());
+
    assert!(bob.handle.track_repo(acme, Scope::Followed).unwrap());
    assert!(bob.handle.track_node(alice.id, None).unwrap());

    let result = bob.handle.fetch(acme, alice.id, DEFAULT_TIMEOUT).unwrap();
modified radicle/src/node/tracking.rs
@@ -25,12 +25,12 @@ pub struct Node {
    pub policy: Policy,
}

-
/// Tracking policy.
+
/// Resource policy.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Policy {
-
    /// The resource is tracked.
-
    Track,
+
    /// The resource is allowed.
+
    Allow,
    /// The resource is blocked.
    #[default]
    Block,
@@ -39,7 +39,7 @@ pub enum Policy {
impl fmt::Display for Policy {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
-
            Self::Track => write!(f, "track"),
+
            Self::Allow => write!(f, "allow"),
            Self::Block => write!(f, "block"),
        }
    }
@@ -50,7 +50,7 @@ impl FromStr for Policy {

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
-
            "track" => Ok(Self::Track),
+
            "allow" => Ok(Self::Allow),
            "block" => Ok(Self::Block),
            _ => Err(s.to_owned()),
        }
@@ -64,7 +64,7 @@ impl sqlite::BindableWithIndex for Policy {
        i: I,
    ) -> sqlite::Result<()> {
        match self {
-
            Self::Track => "track",
+
            Self::Allow => "allow",
            Self::Block => "block",
        }
        .bind(stmt, i)
@@ -78,7 +78,7 @@ impl TryFrom<&sqlite::Value> for Policy {
        let message = Some("sql: invalid policy".to_owned());

        match value {
-
            sqlite::Value::String(s) if s == "track" => Ok(Policy::Track),
+
            sqlite::Value::String(s) if s == "allow" => Ok(Policy::Allow),
            sqlite::Value::String(s) if s == "block" => Ok(Policy::Block),
            _ => Err(sqlite::Error {
                code: None,
@@ -88,21 +88,21 @@ impl TryFrom<&sqlite::Value> for Policy {
    }
}

-
/// Tracking scope of a repository tracking policy.
+
/// Follow scope of a seeded repository.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum Scope {
-
    /// Track remotes of nodes that are already tracked.
+
    /// Seed remotes that are explicitly followed.
    #[default]
-
    Trusted,
-
    /// Track all remotes.
+
    Followed,
+
    /// Seed all remotes.
    All,
}

impl fmt::Display for Scope {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
-
            Scope::Trusted => f.write_str("trusted"),
+
            Scope::Followed => f.write_str("followed"),
            Scope::All => f.write_str("all"),
        }
    }
@@ -117,7 +117,7 @@ impl FromStr for Scope {

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
-
            "trusted" => Ok(Self::Trusted),
+
            "followed" => Ok(Self::Followed),
            "all" => Ok(Self::All),
            _ => Err(ParseScopeError(s.to_string())),
        }
@@ -131,7 +131,7 @@ impl sqlite::BindableWithIndex for Scope {
        i: I,
    ) -> sqlite::Result<()> {
        let s = match self {
-
            Self::Trusted => "trusted",
+
            Self::Followed => "followed",
            Self::All => "all",
        };
        s.bind(stmt, i)
modified radicle/src/node/tracking/config.rs
@@ -16,21 +16,21 @@ pub use crate::node::tracking::{Alias, Node, Policy, Repo, Scope};

#[derive(Debug, Error)]
pub enum NamespacesError {
-
    #[error("Failed to find tracking policy for {rid}")]
+
    #[error("failed to find tracking policy for {rid}")]
    FailedPolicy {
        rid: Id,
        #[source]
        err: Error,
    },
-
    #[error("Cannot fetch {rid} as it is not tracked")]
+
    #[error("cannot fetch {rid} as it is not tracked")]
    BlockedPolicy { rid: Id },
-
    #[error("Failed to get tracking nodes for {rid}")]
+
    #[error("failed to get tracking nodes for {rid}")]
    FailedNodes {
        rid: Id,
        #[source]
        err: Error,
    },
-
    #[error("Failed to get delegates for {rid}")]
+
    #[error("failed to get delegates for {rid}")]
    FailedDelegates {
        rid: Id,
        #[source]
@@ -38,8 +38,8 @@ pub enum NamespacesError {
    },
    #[error(transparent)]
    Git(#[from] crate::git::raw::Error),
-
    #[error("Could not find any trusted nodes for {rid}")]
-
    NoTrusted { rid: Id },
+
    #[error("could not find any followed nodes for {rid}")]
+
    NoFollowed { rid: Id },
}

/// Tracking configuration.
@@ -77,13 +77,13 @@ impl<T> Config<T> {
    /// Check if a repository is tracked.
    pub fn is_repo_tracked(&self, id: &Id) -> Result<bool, Error> {
        self.repo_policy(id)
-
            .map(|entry| entry.policy == Policy::Track)
+
            .map(|entry| entry.policy == Policy::Allow)
    }

    /// Check if a node is tracked.
    pub fn is_node_tracked(&self, id: &NodeId) -> Result<bool, Error> {
        self.node_policy(id)
-
            .map(|entry| entry.policy == Policy::Track)
+
            .map(|entry| entry.policy == Policy::Allow)
    }

    /// Get a node's tracking information.
@@ -120,14 +120,14 @@ impl<T> Config<T> {
                error!(target: "service", "Attempted to fetch untracked repo {rid}");
                Err(NamespacesError::BlockedPolicy { rid: *rid })
            }
-
            Policy::Track => match entry.scope {
+
            Policy::Allow => match entry.scope {
                Scope::All => Ok(Namespaces::All),
-
                Scope::Trusted => {
+
                Scope::Followed => {
                    let nodes = self
                        .node_policies()
                        .map_err(|err| FailedNodes { rid: *rid, err })?;
-
                    let mut trusted: HashSet<_> = nodes
-
                        .filter_map(|node| (node.policy == Policy::Track).then_some(node.id))
+
                    let mut followed: HashSet<_> = nodes
+
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.id))
                        .collect();

                    if let Ok(repo) = storage.repository(*rid) {
@@ -135,15 +135,15 @@ impl<T> Config<T> {
                            .delegates()
                            .map_err(|err| FailedDelegates { rid: *rid, err })?
                            .map(PublicKey::from);
-
                        trusted.extend(delegates);
+
                        followed.extend(delegates);
                    };
-
                    if trusted.is_empty() {
+
                    if followed.is_empty() {
                        // Nb. returning All here because the
                        // fetching logic will correctly determine
-
                        // trusted and delegate remotes.
+
                        // followed and delegate remotes.
                        Ok(Namespaces::All)
                    } else {
-
                        Ok(Namespaces::Trusted(trusted))
+
                        Ok(Namespaces::Followed(followed))
                    }
                }
            },
modified radicle/src/node/tracking/schema.sql
@@ -2,30 +2,30 @@
-- Service configuration schema.
--

-
-- Node tracking policy.
-
create table if not exists "node-policies" (
+
-- Node follow policies.
+
create table if not exists "following" (
  -- Node ID.
  "id"                 text      primary key not null,
  -- Node alias. May override the alias announced by the node.
  "alias"              text      default '',
  -- Tracking policy for this node.
-
  "policy"             text      default 'track'
+
  "policy"             text      default 'allow'
  --
) strict;

-
-- Repository tracking policy.
-
create table if not exists "repo-policies" (
+
-- Repository seeding policies.
+
create table if not exists "seeding" (
  -- Repository ID.
  "id"                 text      primary key not null,
  -- Tracking scope for this repository.
  --
  -- Valid values are:
  --
-
  -- "trusted"         track repository delegates and remotes in the `node-policies` table.
-
  -- "all"             track all remotes.
+
  -- "followed"        seed repository delegates and remotes in the `following` table.
+
  -- "all"             seed all remotes.
  --
-
  "scope"              text      default 'trusted',
+
  "scope"              text      default 'followed',
  -- Tracking policy for this repository.
-
  "policy"             text      default 'track'
+
  "policy"             text      default 'allow'
  --
) strict;
modified radicle/src/node/tracking/store.rs
@@ -118,7 +118,7 @@ impl Config<Write> {
    /// Track a node.
    pub fn track_node(&mut self, id: &NodeId, alias: Option<&str>) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
-
            "INSERT INTO `node-policies` (id, alias)
+
            "INSERT INTO `following` (id, alias)
             VALUES (?1, ?2)
             ON CONFLICT DO UPDATE
             SET alias = ?2 WHERE alias != ?2",
@@ -134,7 +134,7 @@ impl Config<Write> {
    /// Track a repository.
    pub fn track_repo(&mut self, id: &Id, scope: Scope) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
-
            "INSERT INTO `repo-policies` (id, scope)
+
            "INSERT INTO `seeding` (id, scope)
             VALUES (?1, ?2)
             ON CONFLICT DO UPDATE
             SET scope = ?2 WHERE scope != ?2",
@@ -150,7 +150,7 @@ impl Config<Write> {
    /// Set a node's tracking policy.
    pub fn set_node_policy(&mut self, id: &NodeId, policy: Policy) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
-
            "INSERT INTO `node-policies` (id, policy)
+
            "INSERT INTO `following` (id, policy)
             VALUES (?1, ?2)
             ON CONFLICT DO UPDATE
             SET policy = ?2 WHERE policy != ?2",
@@ -166,7 +166,7 @@ impl Config<Write> {
    /// Set a repository's tracking policy.
    pub fn set_repo_policy(&mut self, id: &Id, policy: Policy) -> Result<bool, Error> {
        let mut stmt = self.db.prepare(
-
            "INSERT INTO `repo-policies` (id, policy)
+
            "INSERT INTO `seeding` (id, policy)
             VALUES (?1, ?2)
             ON CONFLICT DO UPDATE
             SET policy = ?2 WHERE policy != ?2",
@@ -181,9 +181,7 @@ impl Config<Write> {

    /// Untrack a node.
    pub fn untrack_node(&mut self, id: &NodeId) -> Result<bool, Error> {
-
        let mut stmt = self
-
            .db
-
            .prepare("DELETE FROM `node-policies` WHERE id = ?")?;
+
        let mut stmt = self.db.prepare("DELETE FROM `following` WHERE id = ?")?;

        stmt.bind((1, id))?;
        stmt.next()?;
@@ -193,9 +191,7 @@ impl Config<Write> {

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

        stmt.bind((1, id))?;
        stmt.next()?;
@@ -212,7 +208,7 @@ impl<T> Config<T> {
        Ok(matches!(
            self.node_policy(id)?,
            Some(Node {
-
                policy: Policy::Track,
+
                policy: Policy::Allow,
                ..
            })
        ))
@@ -223,7 +219,7 @@ impl<T> Config<T> {
        Ok(matches!(
            self.repo_policy(id)?,
            Some(Repo {
-
                policy: Policy::Track,
+
                policy: Policy::Allow,
                ..
            })
        ))
@@ -233,7 +229,7 @@ impl<T> Config<T> {
    pub fn node_policy(&self, id: &NodeId) -> Result<Option<Node>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT alias, policy FROM `node-policies` WHERE id = ?")?;
+
            .prepare("SELECT alias, policy FROM `following` WHERE id = ?")?;

        stmt.bind((1, id))?;

@@ -259,7 +255,7 @@ impl<T> Config<T> {
    pub fn repo_policy(&self, id: &Id) -> Result<Option<Repo>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT scope, policy FROM `repo-policies` WHERE id = ?")?;
+
            .prepare("SELECT scope, policy FROM `seeding` WHERE id = ?")?;

        stmt.bind((1, id))?;

@@ -277,7 +273,7 @@ impl<T> Config<T> {
    pub fn node_policies(&self) -> Result<Box<dyn Iterator<Item = Node>>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT id, alias, policy FROM `node-policies`")?
+
            .prepare("SELECT id, alias, policy FROM `following`")?
            .into_iter();
        let mut entries = Vec::new();

@@ -301,7 +297,7 @@ impl<T> Config<T> {
    pub fn repo_policies(&self) -> Result<Box<dyn Iterator<Item = Repo>>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT id, scope, policy FROM `repo-policies`")?
+
            .prepare("SELECT id, scope, policy FROM `seeding`")?
            .into_iter();
        let mut entries = Vec::new();

@@ -412,8 +408,8 @@ mod test {

        assert!(db.track_repo(&id, Scope::All).unwrap());
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().scope, Scope::All);
-
        assert!(db.track_repo(&id, Scope::Trusted).unwrap());
-
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().scope, Scope::Trusted);
+
        assert!(db.track_repo(&id, Scope::Followed).unwrap());
+
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().scope, Scope::Followed);
    }

    #[test]
@@ -422,7 +418,7 @@ mod test {
        let mut db = Config::open(":memory:").unwrap();

        assert!(db.track_repo(&id, Scope::All).unwrap());
-
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().policy, Policy::Track);
+
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().policy, Policy::Allow);
        assert!(db.set_repo_policy(&id, Policy::Block).unwrap());
        assert_eq!(db.repo_policy(&id).unwrap().unwrap().policy, Policy::Block);
    }
@@ -433,7 +429,7 @@ mod test {
        let mut db = Config::open(":memory:").unwrap();

        assert!(db.track_node(&id, None).unwrap());
-
        assert_eq!(db.node_policy(&id).unwrap().unwrap().policy, Policy::Track);
+
        assert_eq!(db.node_policy(&id).unwrap().unwrap().policy, Policy::Allow);
        assert!(db.set_node_policy(&id, Policy::Block).unwrap());
        assert_eq!(db.node_policy(&id).unwrap().unwrap().policy, Policy::Block);
    }
modified radicle/src/storage.rs
@@ -36,8 +36,8 @@ pub enum Namespaces {
    /// All namespaces.
    #[default]
    All,
-
    /// The trusted set of namespaces.
-
    Trusted(HashSet<PublicKey>),
+
    /// The followed set of namespaces.
+
    Followed(HashSet<PublicKey>),
}

impl Namespaces {
@@ -48,7 +48,7 @@ impl Namespaces {
                dst: (*NAMESPACES_GLOB).clone(),
                force: true,
            }],
-
            Namespaces::Trusted(pks) => pks
+
            Namespaces::Followed(pks) => pks
                .iter()
                .map(|pk| {
                    let ns = pk.to_namespace().with_pattern(git::refspec::STAR);
@@ -65,7 +65,7 @@ impl Namespaces {

impl FromIterator<PublicKey> for Namespaces {
    fn from_iter<T: IntoIterator<Item = PublicKey>>(iter: T) -> Self {
-
        Self::Trusted(iter.into_iter().collect())
+
        Self::Followed(iter.into_iter().collect())
    }
}

modified radicle/src/test.rs
@@ -19,7 +19,7 @@ pub fn fetch<W: WriteRepository>(
) -> Result<Vec<RefUpdate>, crate::storage::FetchError> {
    let namespace = match namespaces.into() {
        Namespaces::All => None,
-
        Namespaces::Trusted(trusted) => trusted.into_iter().next(),
+
        Namespaces::Followed(followed) => followed.into_iter().next(),
    };
    let mut updates = Vec::new();
    let mut callbacks = git2::RemoteCallbacks::new();