The CLI gap
rad cob has no delete subcommand, but the plumbing exists:
cob::store::Store::remove—crates/radicle/src/cob/store.rs:306Issues::removeandPatches::remove(viaCache) are already used byrad issue deleteandrad patch delete.
Adding rad cob delete --repo <RID> --type <TYPENAME> --object <OID> is just CLI wiring. Identity COBs should be rejected, matching the behavior of Create/Update.
Existing code paths for patches
- Library entry point:
radicle::cob::patch::Cache::removeatcrates/radicle/src/cob/patch/cache.rs:172.- Calls
store::Store::removeatcrates/radicle/src/cob/store.rs:361, which drops the COB ref from storage and re-signsrad/sigrefs. - Then removes the cache entry via
Remove<Patch>.
- Calls
- CLI surface:
rad patch deleteincrates/radicle-cli/src/commands/patch/delete.rs:9, viaterm::cob::patches_mut(...).remove(patch_id). Patchesitself does not expose aremove; deletion must go through theCachewrapper. By contrast,Issues::removeis available directly atcrates/radicle/src/cob/issue.rs:842.
Why the git object survives deletion — it’s a soft delete
Storage::remove (crates/radicle/src/storage/git/cob.rs:169-180) only deletes the git reference:
refs/namespaces/<nid>/refs/cobs/<typename>/<oid>
fn remove(&self, ...) -> Result<(), ...> {
let mut reference = self.backend.find_reference(...)?;
reference.delete() // deletes the ref, not the objects
}Store::remove then calls self.repo.sign_refs(signer) to update the signed refs.
The underlying commits, trees, and blobs of the COB’s operation history remain in the object store as unreachable objects.
Consequences
rad cob listhides the COB (no ref to discover), but the data is recoverable if you know the OID.- Radicle storage is a bare repo, so unreachable objects persist until
git gcis run explicitly. Even then, if any other ref reaches them, they survive. - Deletion is local to your namespace only. Removal drops your namespaced ref (
refs/cobs/<type>/<id>under your NID) and re-signsrad/sigrefs. Other peers who replicated the COB still have their own refs under their own namespaces, so their copies are unaffected — and the COB may reappear on fetch.
Takeaway
“Delete” in a COB context means “drop my local signed ref,” not “destroy the data.” This is consistent with a gossip-replicated git model: you cannot unilaterally erase history that other peers may have replicated.