docs(rooms): the root memory is keyed by room, which buys a fourth comparison - #1379
Merged
Conversation
…mparison The one question `data-rooms-read-through.md` §5 left open. Working it out turned it from a storage question into a design one, which is why it is written down rather than settled in an implementation. **Key it by room, not by host.** A room's tree at version V is a fact about the room; who served it is not part of that fact. Keying by `(room, host)` files two hosts of one room in two drawers and never compares them — and a room may deliberately have several, a mirror serving reads while its primary takes writes. Keyed by room, a member who reads the same room from two of its hosts gets the comparison for free: two hosts reporting different roots at one `headVersion` is exactly as damning as one host disagreeing with itself. A mirror that merely lags reports a lower `headVersion` and is correctly not compared at all. That is a **fourth comparison**, and it is not among the three `rooms/records/list` lists. Another member's root needs a gossip channel rooms deliberately lack; the witnessed anchor is unbuilt. *Another host of the same room* needs neither — only a caller who names a different `host`, which `rooms/keys/read` already lets them do. **Hold a small map from `headVersion` to root**, most-recent-N plus the highest version ever seen. One slot is weaker than it looks in a specific way: it does catch a host that alternates at one version, but it misses a head that advances and then goes backwards — `(V, A)`, `(V+1, X)`, `(V, B)` — which is precisely the mirror and rollback case this exists for. 16 versions is more than a member reads across in a session and costs a few hundred bytes. The highest-ever value is separate because it answers a question no single pair can: has this room gone backwards? **Bounded by membership, not by time.** Dropped when the member leaves. It carries no record content, but it is a record of when this member read this room, and an agent keeping that after the membership ends is keeping a diary of a room its principal can no longer open.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The one question
data-rooms-read-through.md§5 left open, and the one I said was worth deciding before the implementation rather than during it. Working it out turned a storage question into a design one.Key it by room, not by host
This is the part worth not getting wrong. A room's tree at version
Vis a fact about the room; who served it is not part of that fact. Keying by(room, host)files two hosts of one room in two drawers and never compares them — and a room may deliberately have several, a mirror serving reads while its primary takes writes.Keyed by room, a member who reads the same room from two of its hosts gets the comparison for free. Two hosts reporting different roots at one
headVersionis exactly as damning as one host disagreeing with itself: one of them is wrong. A mirror that merely lags reports a lowerheadVersionand is correctly not compared at all.That is a fourth comparison
rooms/records/listlists three ways a root becomes evidence: another member's root, the same member's earlier root, the witnessed anchor. The first needs a gossip channel rooms deliberately lack — on aprivateroom a member list is the thing being withheld — and the third is unbuilt.Another host of the same room needs neither. No gossip, no anchor, no second member — only a caller who names a different
host, whichrooms/keys/readalready lets them do, because nothing maps a room to its host and the caller always names one.It falls out of keying by room. It would have been invisible if the memory had been keyed the other way, which is the reason to write this down rather than leave it to whoever types the storage key.
How much
A small map from
headVersionto root, most-recent-N by version, plus the highestheadVersionever seen.One slot is weaker than it looks in a specific way, and stronger than it looks in another. It does catch a host that alternates:
(V, A)then(V, B)is same version, different root, caught — and caught again on the way back toA. What it misses is a head that advances and then goes backwards:With one slot the agent holds
V+1and has nothing to compareVagainst. That is the mirror case and the rollback case — the two this exists for — so one slot is not enough.N = 16 versions is more history than a member reads across in a session and costs a few hundred bytes. The highest-ever value is separate because it answers a question no single pair can: has this room gone backwards?
Bounded by membership, not by time
Dropped when the member leaves the room. It carries no record content, but it is a record of when this member read this room, and an agent that keeps that after the membership ends is keeping a diary of a room its principal can no longer open.
Documentation only. Closes the last open question in the read-through note, so §5's two questions are both answered.