CHANGELOG: Describe the changes to repository identity evaluation

This commit is contained in:
Fintan Halpenny 2026-07-03 19:10:46 +01:00 committed by Lorenz Leutgeb
parent 2f1aaa45b2
commit fb80d58af7
1 changed files with 61 additions and 0 deletions

View File

@ -7,6 +7,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## Repository Identity Evaluation
The limitations of evaluating repository identities were found on multiple
repositories, including the `heartwood` repository. This prompted a review of
the evaluation logic, which resulted in several improvements.
The bulk of the improvements come from two aspects in the evaluation. The first
is keeping track of the parent and children relationship of revisions. The
second is having a richer model of a revision's state.
Every revision (except the initial revision which is created during `rad init`)
explicitly refers to a parent revision. This is similar to Git commits, which
usually refer to one parent. Similarly, root commits do not refer to any parent,
and merge commits refer to multiple parents. For repository identity, merges
are not possible. This gives the first relation of interest: We say that two
revisions `A` and `B` are in relation "parent" if `A` refers to `B` explicitly
as its parent. The inverse relation is called "child". The transitive closure
of "parent" is called "ancestor" and the transitive closure of "child" is called
"descendant". Further, we say that two revisions `A` and `B` are in relation
"sibling" if they are both in relation "parent" with the same revision `C`.
With these relationships in mind, a revision can now be in one of four states:
1. *Active*: this is the initial state of any revision when it is proposed. The
proposal is waiting for delegates to accept or reject it. Or alternatively,
the revision can be redacted.
A revision will remain active, even if it has a majority of accepted votes,
if its parent is still active.
2. *Accepted*: the revision was accepted by a majority of delegates. The
revision can no longer be rejected nor redacted.
When a revision is accepted, its children are also evaluated, recursively, to
see if they also have reached a majority.
3. *Rejected*: there are now three variants of rejection for a revision:
a. The revision was directly rejected by a majority of the delegates, by them
casting their rejection votes.
b. The parent of the revision was rejected, and thus this revision was
transitively rejected.
c. A sibling of the revision was accepted, and thus this revision (and all
other siblings) are rejected.
4. *Redacted*: there are two variants of redaction for a revision:
a. The author explicitly redacted (withdrew) the revision.
b. The parent of the revision was redacted, and thus this revision was
transitively redacted.
This modeling of revisions ensures that the evaluation of the state remains
consistent, and accounts for the previous cases we had come across in the wild.
The final ingredient that was added ensures that the evaluation remains
consistent when it involves delegates accepting a revision. A delegate can only
accept a revision if they have not accepted any other active revision that is a
sibling of the revision they are voting on.
This prevents scenarios such as Alice creating and accepting two revisions `A`
and `B`, and Bob and Eve accepting each respectively. Both revisions would then
reach majority, but the evaluation would pick one arbitrarily based on the
topological sort of the COB graph. However, with the above condition in place,
this cannot happen.
We will note that we found an inconsistency where the concurrent operations
"redact" and "accept" will produce a different identity document depending on
which is ordered first. Further analysis of the ordering of pairs of actions is
required, but is left to future work.
## Improvements
- `rad patch list` includes a `Labels` column, showing any assigned labels to