Take the sequenced keys and make in force mean what it says

The pin moves to Epiphany `d5a36c2a`, where a resolution's key ends in its
per-subject sequence and a stewardship's in its per-(instance, repo) one. Two
fields arrive with it, so `stewardship` and `resolution` in the fixtures set
`sequence: 1` and `stewardship_n`/`resolution_n` say otherwise when a test
needs a second record. Every literal key that gained `.n1` moved with it,
`id_of` included.

The rules the sequence was for:

- `in_force` is recursive. A document is in force when no resolution that is
  itself in force names it, so a withdrawn resolution stops closing its
  subject. The old one-level version counted a withdrawal as if it still
  stood, which is half of why a reopened subject could not be resolved again.
- The other half was A10. `refuse_collisions` no longer has a `Resolution`
  arm: a resolution key is not one-per-subject any more, so a collision on it
  means what it means for every other kind, and whether a subject is closed
  is A8's question.
- A8 asks it, for both sequenced kinds, in the same two steps. The sequence
  is the writer's and must be the previous plus one over image and batch,
  counting every record of that scope but this document --
  `ResolutionOutOfSequence`, `StewardshipOutOfSequence`. Then no record of
  that scope may still be in force -- `AlreadyResolved`, `AlreadyStewarded`.
  With both, at most one stewardship of a repo stands on a mind, which is
  what `stewardship_of` has been assuming.
- Q19 A is enforced rather than described: a resolution whose subject is a
  resolution of a resolution is `IncompatibleResolution`. A withdrawal cannot
  be withdrawn; a closure is reinstated by resolving the subject again.
- `derive` sets a sequence on each write it makes, from the same image the
  rule reads.

Two existing tests move with the rules. `subject_resolves_at_most_once` is
now `a_subject_with_a_resolution_in_force_refuses_another` and separates the
two refusals. The hand-off test's last case used to be an A4 collision
between a batch's own stewardship and the derived one; the derived write now
takes the sequence after the batch's, so there is nothing left to collide and
the batch is refused as out of sequence instead.

31 tests, 0 warnings; `cargo check --workspace` clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-16 19:28:17 +02:00
commit 3efc0dc82d
5 changed files with 181 additions and 63 deletions

2
Cargo.lock generated
View file

@ -146,7 +146,7 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "epiphany-pipeline"
version = "0.1.0"
source = "git+https://github.com/GameCult/Epiphany.git?rev=a65c6420f681d6641b842f94b319f0fa14166c96#a65c6420f681d6641b842f94b319f0fa14166c96"
source = "git+https://github.com/GameCult/Epiphany.git?rev=d5a36c2a291b910539072717d42d61a9aa7485d1#d5a36c2a291b910539072717d42d61a9aa7485d1"
dependencies = [
"anyhow",
"chrono",