Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: rad id example
Fintan Halpenny committed 3 years ago
commit 6b674a38c163d5de1982e87406e920f01fc3e96d
parent b257f482cbad5e0382c182fdb01bb129377672f3
3 files changed +845 -0
added radicle-cli/examples/rad-id-rebase.md
@@ -0,0 +1,430 @@
+
In this example, we're going to see what happens when a proposal
+
drifts away from the latest Radicle identity.
+

+
First off, we will create two proposals -- we can imagine two
+
delegates creating proposals concurrently.
+

+
```
+
$ rad id edit --title "Add Alice" --description "Add Alice as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
+
ok Identity proposal '57332790a2eabc0b2fd8c7ff48c3579d5812d405' created 🌱
+
title: Add Alice
+
description: Add Alice as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
```
+
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG --no-confirm
+
ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' created 🌱
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
Now, if the first proposal was accepted and committed before the
+
second proposal, then the identity would be out of date. So let's run
+
through that and see what happens.
+

+
```
+
$ rad id accept 57332790a2eabc0b2fd8c7ff48c3579d5812d405 --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Accepted proposal ✓
+
title: Add Alice
+
description: Add Alice as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
```
+
$ rad id commit 57332790a2eabc0b2fd8c7ff48c3579d5812d405 --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Committed new identity 🌱
+
title: Add Alice
+
description: Add Alice as a delegate
+
status:  committed 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
Now, when we go to accept the second proposal:
+

+
```
+
$ rad id accept c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
** Warning: Revision is out of date
+
** Warning: d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f
+
=> Consider using 'rad id rebase' to update the proposal to the latest identity
+
ok Accepted proposal ✓
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
-    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
Note that a warning was emitted:
+

+
    ** Warning: Revision is out of date
+
    ** Warning: d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f
+
    => Consider using 'rad id rebase' to update the proposal to the latest identity
+

+
If we attempt to commit this revision, the command will fail:
+

+
```
+
$ rad id commit c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
** Warning: Revision is out of date
+
** Warning: d96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f
+
=> Consider using 'rad id rebase' to update the proposal to the latest identity
+
== Id failed
+
the identity hashes do match 'd96f425412c9f8ad5d9a9a05c9831d0728e2338d =/= 475cdfbc8662853dd132ec564e4f5eb0f152dd7f' for the revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1'
+
```
+

+
So, let's fix this by running a rebase on the proposal's revision:
+

+
```
+
$ rad id rebase c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' rebased 🌱
+
ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4'
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
-    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
We can now update the proposal to have both keys in the delegates set:
+

+
```
+
$ rad id update c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/4 --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
+
ok Identity proposal 'c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e' updated 🌱
+
ok Revision 'z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6'
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
Finally, we can accept and commit this proposal, creating the final
+
state of our new Radicle identity:
+

+
$ rad id show c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --revisions
+

+
```
+
$ rad id accept c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6 --no-confirm
+
ok Accepted proposal ✓
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
```
+
$ rad id commit c3698d4e85f9d4c0ee536b34d6122fc7c81f7e2e --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/6 --no-confirm
+
ok Committed new identity 🌱
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  committed 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
added radicle-cli/examples/rad-id.md
@@ -0,0 +1,401 @@
+
At some point in the lifetime of a Radicle project you may want to
+
collaborate with someone else allowing them to become a project
+
maintainer. This requires adding them as a `delegate` and possibly
+
editing the `threshold` for passing new changes to the identity of the
+
project.
+

+
For cases where `threshold = 1`, it is enough to use the `rad
+
delegate` command. For cases where `threshold > 1`, it is necessary to
+
gather a quorum of signatures to update the Radicle identity. To do
+
this, we use the `rad id` command.
+

+
Let's add Bob as a delegate using their key
+
`z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn`.
+

+
```
+
$ rad id edit --title "Add Bob" --description "Add Bob as a delegate" --delegates z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn --no-confirm
+
ok Identity proposal '06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39' created 🌱
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
Before moving on, let's take a few notes on this output. The first
+
thing we'll notice is that the difference between the current identity
+
document and the proposed changes are shown. Specifically, we changed
+
the delegates:
+

+
    "delegates": [
+
    -    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
    +    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
    +    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
    ],
+

+
Next we have the number of `Accepted` reviews from delegates, starting
+
off with none:
+

+
    Accepted
+
    
+
    total: 0
+
    keys: []
+

+
The same with `Rejected` reviews:
+

+
    Rejected
+
    
+
    total: 0
+
    keys: []
+

+
Finally, we can see whether the `Quorum` was reached:
+

+
    Quorum Reached
+
    
+
    ✗ no
+

+
Let's see what happens when we reject the change:
+

+
```
+
$ rad id reject 06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39 --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Rejected proposal ✗
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
Our key was added to the `Rejected` set of `keys` and the `total`
+
increased to `1`.
+

+
    Rejected
+
    
+
    total: 1
+
    keys: [
+
      "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
    ]
+

+
Instead, let's accept the proposal:
+

+
```
+
$ rad id accept 06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39 --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Accepted proposal ✓
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
Our key has changed from the `Rejected` set to the `Accepted` set
+
instead:
+

+
    Accepted
+
    
+
    total: 1
+
    keys: [
+
      "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
    ]
+

+
As well as that, the `Quorum` has now been reached:
+

+
    Quorum Reached
+
    
+
    ✓ yes
+

+
At this point, we can commit the proposal and update the identity:
+

+
```
+
$ rad id commit 06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39 --rev z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/1 --no-confirm
+
ok Committed new identity 🌱
+
title: Add Bob
+
description: Add Bob as a delegate
+
status:  committed 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
-    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
+    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
+    "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
   "threshold": 1
+
 }
+

+

+
Accepted
+

+
total: 1
+
keys: [
+
  "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
]
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✓ yes
+
```
+

+
Let's say we decide to also change the `threshold`, we can do so using
+
the `--threshold` option:
+

+
```
+
$ rad id edit --title "Update threshold" --description "Update to safer threshold" --threshold 2 --no-confirm
+
ok Identity proposal 'dc00640d3152ea5f1df59f39f2f5983d2ad21810' created 🌱
+
title: Update threshold
+
description: Update to safer threshold
+
status:  open 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
-  "threshold": 1
+
+  "threshold": 2
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
But we change our minds and decide to close the proposal instead:
+

+
```
+
$ rad id close dc00640d3152ea5f1df59f39f2f5983d2ad21810 --no-confirm
+
ok Closed identity proposal 'dc00640d3152ea5f1df59f39f2f5983d2ad21810'
+
title: Update threshold
+
description: Update to safer threshold
+
status:  closed 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
-  "threshold": 1
+
+  "threshold": 2
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
The proposal is now closed and cannot be committed. If at a later date
+
we want to update the document with the same change we have to open a
+
new proposal.
+

+
If at any time we want to see what proposals have been made to this
+
Radicle identity, then we can use the list command:
+

+
```
+
$ rad id list
+
06d9efa2a9aad06bfdf25a25690e1ec7db2c3c39 "Add Bob"           committed
+
dc00640d3152ea5f1df59f39f2f5983d2ad21810 "Update threshold"  closed
+
```
+

+
And if we want to view the latest state of any proposal we can use the
+
show command:
+

+
```
+
$ rad id show dc00640d3152ea5f1df59f39f2f5983d2ad21810
+
title: Update threshold
+
description: Update to safer threshold
+
status:  closed 
+
author: z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+

+
Document Diff
+

+
 {
+
   "payload": {
+
     "xyz.radicle.project": {
+
       "defaultBranch": "master",
+
       "description": "Radicle Heartwood Protocol & Stack",
+
       "name": "heartwood"
+
     }
+
   },
+
   "delegates": [
+
     "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
+
     "did:key:z6MkedTZGJGqgQ2py2b8kGecfxdt2yRdHWF6JpaZC47fovFn"
+
   ],
+
-  "threshold": 1
+
+  "threshold": 2
+
 }
+

+

+
Accepted
+

+
total: 0
+
keys: []
+

+
Rejected
+

+
total: 0
+
keys: []
+

+
Quorum Reached
+

+
✗ no
+
```
+

+
On a final note, these examples used `--no-confirm`. The default mode
+
for making proposals is to select and confirm any actions being
+
performed on the proposal.
modified radicle-cli/tests/commands.rs
@@ -176,6 +176,20 @@ fn rad_id() {
}

#[test]
+
fn rad_id_rebase() {
+
    let mut environment = Environment::new();
+
    let profile = environment.profile("alice");
+
    let working = tempfile::tempdir().unwrap();
+
    let home = &profile.home;
+

+
    // Setup a test repository.
+
    fixtures::repository(working.path());
+

+
    test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
+
    test("examples/rad-id-rebase.md", working.path(), Some(home), []).unwrap();
+
}
+

+
#[test]
#[ignore]
fn rad_patch() {
    let mut environment = Environment::new();