Design 55: follow ADR 0592's tenth version: submit commits when its version is stored, and the tests for the rollback's double write and the Approve bound to its sections

This commit is contained in:
2026-11-02 19:55:40 +01:00
parent b9a42eaf90
commit eaa98758b9
+12 -6
View File
@@ -89,11 +89,14 @@ The module is written in Go against the SDK. It holds no checkout of this reposi
the records module, as the issue tracker's import does. Until the move of § 8.1, its records are in a database in
the store; from the move on, it requires no database (ADR 0592 §1, changing ADR 0290 §7).
**A write is whole or refused** (ADR 0592 §10). Every change to `heads`, `drafts`, `asked`, `names` and `findings` is a
compare-and-set on the key's revision, retried at most three times and then refused with the reason. `submit`
writes the message on `versions` first, then the head against its revision, then the event; a failed step refuses
the call. At start the module rebuilds any head behind its last version. A reservation is a head created only if
the key is absent, so two sessions reserving at once get two numbers or one refusal.
**A write is whole or refused, and `submit` commits when its version is stored** (ADR 0592 §10). Every change to
`heads`, `drafts`, `asked`, `names` and `findings` is a compare-and-set on the key's revision, retried at most three
times and then refused with the reason. The commit point of `submit` is the version message stored on `versions`: a
failure before it is stored refuses the call, and nothing is taken. Once it is stored, the call answers that the
version is taken; the head's update against its revision and the event are then completed at once, retried, and at
the next start for any head behind its last stored version. So nothing an author was told was refused takes effect
later. A reservation is a head created only if the key is absent, so two sessions reserving at once get two numbers
or one refusal.
**The search index** is a full-text index in the module's own memory, written with the pure Go library bleve. At
start the module reads every head and the bodies of every current version into it, then keeps it current by watching
@@ -601,7 +604,10 @@ table-driven; one integration test starts the module whole against the real bus
| two writes race on one draft | unit: the second compare-and-set loses, is retried, and is refused with the reason past its tries |
| `submit` races `take-over` | unit: one wins; the other is refused naming the new author or the new version |
| two reservations race | unit: two numbers, or one refused; never one number twice |
| a write cut between the stream and the head | unit: a start rebuilds the head from its last version |
| a write cut between the stream and the head | unit: the call answered that the version is taken; a start completes the head from the stored version and sends the event once |
| a failure before the version is stored | unit: the call is refused, and no head, event or version follows later |
| a change through the bus during the move | unit: read back from the database, so a rollback of the delivery reads a current database (ADR 0592 §14) |
| a section changed after the operator's Approve | unit: the record is asked again; a version with every section unchanged is not (ADR 0592 §21) |
| a named digest has no object | unit: health unhealthy, naming it; the integrity tool restores it from given text |
| a body does not hash to its name | unit: the read refuses it, naming the digest |
| a full object bucket | integration: a write refused naming the cap; health unhealthy |