Revision Agreement
A system that answers from a copy should be able to tell you which copy.
- Specification
- Draft 0.1.0, 2026-09-29 · CC BY 4.0
revcheck- Released v0.2.1 on 2026-09-29 · Apache-2.0 or MIT
- Read it
- SPEC.md · repository
1 The problem
Most systems that answer questions from a body of content keep the real content in one place and build a search index on top of it. The index is a copy, and copies lag. When they do, a healthy-looking system returns a well-formed, confident, out-of-date answer, and nothing in the answer says so.
2 Three questions
Ask them of anything that serves content through a derived copy: a search index, a projection, a cache, a replica.
- Does a result carry its revision?
- Can the copy be checked against the original?
- Does disagreement stop it?
A system that does all three can be checked by its callers. A system that does none has to be taken on trust.
3 Requirements and levels
- R1
- A read reports its revision, in the same structure as its results.
- R2
- There is an operation that compares every derived consumer’s revision with the source and names any that disagree.
- R3
- When a consumer disagrees, the read is refused, or served with a machine-readable label naming the stale consumer and both revisions.
- R4
- Writes advance one revision at a time, and no read sees a half-applied write.
| Level | Requires | What it buys |
|---|---|---|
| 0 Unverified | none | Nothing. Staleness cannot be seen from outside. |
| 1 Attributed | R1 | A caller can tell two answers apart. |
| 2 Checked | R1, R2 | An operator can show, on demand, that the whole system is current. |
| 3 Fail-closed | R1–R3 | The system cannot silently serve stale content. |
| 4 Serialized | R1–R4 | Revisions name unambiguous states, and level 3 holds under concurrent writes. |
4 revcheck
revcheck reads a JSON response and decides whether it satisfies R1. It can also compare two payloads taken before and after a write and confirm that the revision moved. Static binaries for x86_64 and aarch64 Linux are on the release page.
$ curl -sD - https://example.test/search?q=x | revcheck
level 0 (Unverified)
near-misses:
- header:Last-Modified: rejected by name (wall-clock field)
- $.results[0].updated_at: rejected by name (wall-clock field)
- $.results[0].hash: per-item scope
It is deliberately narrow. It tests R1 and revision advance only. R2 and R3 need the system’s own write and comparison operations and cannot be judged from a payload, so a pass establishes level 1 and nothing above it. A pass is also weaker than a failure: revcheck sees the shape of a value, not its meaning, and an API version looks the same as a content revision. Confirm a pass with revcheck advance around a real write.
5 Status
The specification is a draft, stable enough to test against and expected to change in response to implementations and counterexamples. Counterexamples are the most useful contribution: if you know a system that already returns its revision with its results, open an issue so the specification can cite it.