On `Action::RevisionAccept` use `has_active_sibling_accept` to check for a sibling accept.
If one is found, the `RevisionAccept` is logged and skipped.
This preserves the invariant of a single accept per delegate on active, sibling
revisions without throwing an error on existing histories.
The evaluation of the reposioty identity is rewritten to better handle cases
where there are child and sibling revisions that are active at the same time.
In particular, `fn Identity::action` is now free of any references to
`self.current`.
This is achieved through two main improvements. The first is that the `State`
of revisions changes to improve clarity:
1. `Active` and `Accepted` remain, and their meanings also remain the same.
2. `Stale` is removed entirely.
3. `Rejected` is improved to also contain `RejectedBy`, to keep track of the
reason for rejection.
4. `Redacted` is promoted to a state. Similarly, the reason for
redaction is tracked by `RedactedBy`.
The transition of a revision from `Active` to one of the other states now
influences siblings and children.
If a revision transitions to `Accepted`, then the sibling revisions can no
longer transition to `Accepted`. They are considered `Rejected` where the reason
is `Sibling`. This cascades: Children of siblings are `Rejected`
recursively, tracking `RejectedBy::Parent`.
Any children of the `Accepted` revision are also evaluated to see if they can be
similarly transitioned to the `Accepted` state; since they may have already been
voted on.
If a revision was rejected by a majority, then the it transitions to `Rejected`
with `RejectedBy::Vote`. Dually to acceptance, the children of this revision
are also rejected with the reason of `Ancestor`.
Finally, when the author of a revision redacts a revision, it transitions
to `Redacted`, tracking `RedactedBy::Author`, and its children are redacted
tracking `RedactedBy::Parent`.
The test is adjusted to `remove_delegate_concurrent` reflect that concurrently
proposed revisions are retained in the timeline and explicitly marked as rejected,
rather than being dropped entirely (as before).
When delegates collaborate on the repository identity, their voting
narrows the tree of active proposals to the chain of accepted
proposals. Thus, they crucially must understand which proposals are
siblings, i.e., which proposals share the same parent, because no
two sibling proposals should ever be accepted at the same time, as
this would mean a fork.
To ease collaboration of delegates and improve their overview, also
print the parent revision, if present. Note that the initial revision
is the only revision that has no parent.
Pay more attention to when a Node ID is displayed in compact form. As
this was sometimes used to save space, e.g. in `rad node status` in
combination with long node addresses (like .onion names), also implement
a compact format for node addresses and use that instead in some cases.
Progress notifications in spinners keep the short form.