computedriven computedriven/docs/history-anchor-model.md
R6.3 closed history B: after an acknowledged success and the ACTIVE holder's death, the exact successor is recovered from the durable Locus history through the placement path. I…

R6.4 durable history anchor model — written before the mechanism

R6.3 closed history B: after an acknowledged success and the ACTIVE holder's death, the exact successor is recovered from the durable Locus history through the placement path. Its H3x exhibit then showed the one thing that history cannot see about itself. Replace the whole history file with an older, internally consistent copy and everything the store checks passes — the chain re-hashes, the head matches its newest row, the bound writer agrees with the old file — and recovery installs a stale state. GPT's ruling on R6.3 makes that the round:

A self-consistent Locus history is not sufficient evidence that it is the current Locus history. Recovery may use a history head only when a deployment-controlled anchor establishes that exact head and writer binding as current.

This is the R0.8 distinction one layer up — self-consistent store ≠ current store — and R0.8 already paid for the answer: a trust anchor outside the copyable store, committing to the canonical head, with an exact pending-successor authorization and a reconciliation that never lets the store teach the anchor a successor it did not authorize. This document reuses that trust shape, not R0.8's lifecycle domain, and states before anything is built what the anchor commits to, how two objects advance without an atomic write across them, what every crash window recovers to, which rollbacks must become refusals, and what falsifies it.

0. Standing rulings adopted from R6.3 (permanent)

  • the Locus State Revision and the successor row; realization A (snapshot

rows) is the architecture, journal/replay is experimental only, and no privileged replay executor is built;

  • the writer binding is load-bearing: *a durable successor is admissible

only from the incarnation currently bound as writer for that Locus history*; the chain answers where, the binding answers who;

  • the crash-window vocabulary `NOT_APPLIED / SUCCESS / NOT_DURABLE /

INDETERMINATE / DURABLE_LAG(1), with NOT_APPLIED meaning *absent from the authoritative recoverable history* (not "nothing happened anywhere") and DURABLE_LAG(1)` valid only under the single-outstanding-successor discipline;

  • the recovery composition: positive finality → verified head → successor

snapshot → new claim → dormant install → install gate → durable activation → floor ACTIVATE; the transfer capsule stays consumed;

  • everything R6.2 and R6.1 ruled; R0.8 unmodified; the 309-byte hot Locus

state unchanged.

1. Two objects, one truth

   DEPLOYMENT-CONTROLLED HISTORY ANCHOR               HISTORY STORE (copyable)
   one file per Locus, its own directory              one file per Locus (R6.3)
   ┌────────────────────────────────────┐             ┌──────────────────────────┐
   │ current  (L, n,   Hn,   writer)    │ commits to  │ row 0 … row n            │
   │ pending  (L, n+1, Hn+1, writer)?   │ ──────────► │ head = (n, Hn)           │
   │ log      every authorize/finalize/ │             │ bound = writer (a cache) │
   │          cancel/rebind, stamped    │             └──────────────────────────┘
   └────────────────────────────────────┘

The anchor commits to the canonical semantic head — Locus, LSR, successor-row digest, bound writer — never to the database file's bytes. SQLite's physical bytes change under WAL checkpoints and VACUUM while the logical history is the same; an anchor on bytes would couple authority to storage layout and refuse an honest file (F130 tests exactly that).

What each object answers:

questionanchorhistory
which head is currentauthoritativesays what it holds
who may advance the historyauthoritative (current.writer)bound is a cache, checked as defense in depth, never trusted alone
what the successor state IS—the row's 317 bytes, verified by digest against the anchor
may this history be recovered fromonly if its head equals the anchor's current, or is the anchor's exact pending successor—

The anchor holds no Locus state and no successor bytes: 8 + 32 + 16 bytes per Locus, plus at most one pending tuple. Nothing is added to the floor or to the 309-byte hot state.

Trust boundary, as R0.8's. The anchor's directory is deployment- controlled: the adversary who can replace, roll back or edit the history file cannot write the anchor. An adversary who can rewrite the anchor has the trust root and has won; that is what a trust root means. The anchor authenticates no caller: any process that can open the anchor file can rebind, cancel, or finalize as the supervisor. What keeps a late writer out is the protocol discipline of the parties that can open it (an agent calls only authorize and finalize for its own tuple), not access control; in the harness the directory is one more directory under the same user. Not claimed: coordinated rollback of history and anchor, hostile root or kernel, storage-device rollback, power loss, lying or reordering fsync, a caller that lies about being the supervisor.

2. The three-phase advance — and why the anchor moves first and last

R0.8's handshake, transposed:

  anchor current (n, Hn, w)
      │
   1. AUTHORIZE  anchor.pending := (n+1, Hn+1, w)      fsync   -- the exact successor, before it exists anywhere durable
      │
   2. COMMIT     history row n+1 = S', head := (n+1, Hn+1)   fsync   -- R6.3's one-transaction commit, unchanged
      │
   3. FINALIZE   anchor.current := (n+1, Hn+1, w); pending := none   fsync
      │
   4. ACK        SUCCESS

The agent computes Hn+1 from the exported successor before step 1 (d(L, n+1) = sha256("cd-lsr/1" ‖ L ‖ n+1 ‖ Hn ‖ "S" ‖ S')), so the anchor authorizes a specific successor — not "whatever the history commits next". That is what makes reconciliation a comparison and never a guess.

Refusals at AUTHORIZE, by name: wrong-writer (the caller is not current.writer), not-successor (LSR ≠ current + 1), pending-outstanding (another exact tuple is authorized and not yet finalized or cancelled), already-authorized (this exact tuple is the pending one — the idempotent retry). At FINALIZE: not-authorized (no pending, or a different tuple), already-finalized (current already is this tuple), wrong-writer.

The fence and the binding go through the anchor. rebind(writer) sets current.writer in one anchor transaction. It does not cancel a pending authorization: it makes it un-finalizable by the fenced writer (wrong-writer), and leaves it for reconciliation (§3), which cancels it if the history is still at n and finalizes it as the supervisor if the history committed exactly that successor. The first cut cancelled at the fence; the battery's X3+F window (agent dead after the history COMMIT, floor dead too) then refused a successor the history already held — the fence had erased the authorization that made it recoverable. The supervisor's finalize(supervisor=True) moves current to the exact pending tuple and leaves current.writer as it is (still NOBODY until the new holder binds). The supervisor fences (rebind(NOBODY)) before reading the head, and checks that the fence was taken (NOT_FENCED otherwise); the new holder binds itself after its durable activation. The history's own bound is set alongside. The fence is two writes and is complete only when both have committed: the anchor's binding is the fence for AUTHORIZE and FINALIZE, the history's binding is the fence for COMMIT. Between them, a COMMIT of an already-authorized successor may land; reconciliation then finalizes it and recovery installs S' — legal, because the tuple was authorized before the fence, and the caller's op is INDETERMINATE. A late AUTHORIZE is refused at the anchor; a late COMMIT of an unauthorized row is refused at the store, and if the store's cache were stale enough to admit it, the anchor refuses the history that results (history-ahead-unauthorized) — at reconciliation and at the install gate.

Three fsync'd transactions per mutation (authorize, the history commit with its ack, finalize), where R6.3 had two. Named as a cost; not optimized here.

3. Reconciliation — the store never teaches the anchor

Read three things, compare, never guess. A = anchor.current (n, Hn, w), P = anchor.pending, M = history head (m, Hm):

pending Phistory head Mverdictrecovery does
nonem = n, Hm = Hncleannothing
(n+1, H', w)m = n, Hm = Hnunused-authorization-cancelledcancel — the successor never became durable; the truth is S
(n+1, H', w)m = n+1, Hm = H'pending-successor-finalizedfinalize — the anchor had authorized exactly this; surface the unacknowledged row
(n+1, H', w)m = n+1, Hm ≠ H'REFUSE `history-diverged`a successor the anchor did not authorize
nonem = n+1REFUSE `history-ahead-unauthorized`the store presents a newer self-consistent state; the anchor does not learn it
anym > n+1REFUSE `history-ahead`
anym < nREFUSE `history-behind-anchor`this is H3x: a whole-file rollback to an older copy
anym = n, Hm ≠ HnREFUSE `history-diverged`same LSR, different digest: a substituted history
(n+1, H', w)m = n+1, Hm = H', row.writer ≠ wREFUSE `writer-mismatch`the authorized bytes committed by another writer: the binding is re-verified, not only the digest
(n+1, H', w)the supervisor's finalize is refusedREFUSE `finalize-refused`a transient (busy) or a pending that vanished between the read and the write; retry
genesis: no currentpending (0, H0), history emptyunused-authorization-cancelledcancel
genesis: no currentpending (0, H0), history head (0, H0)pending-successor-finalizedfinalize as the supervisor: the anchor's current becomes LSR 0
genesis: no currenthistory has rows, no pendingREFUSE `history-ahead-unauthorized`a history with no anchor
—history refuses its own open (chain-broken, head-behind, wrong-locus)REFUSE as R6.3

A refusal is a verdict, not a repair: this round does not roll a history back to the anchor or forward to it. Repair is a supervisor act with its own receipt and is a hand-on (§8).

4. Every crash window, named

The protocol is A-only (§0). Parties: the floor, the agent, the history service, the anchor service. w is the bound writer.

#dieswhenanchorhistoryrecovery reconstructscaller
X0floorbefore the agent holds S'(n)nSNOT_APPLIED (R6.3 W1/W2, unchanged)
X1agentafter S', before AUTHORIZE(n)n; floor holds S'—INDETERMINATE; the successor agent reconciles the lag: authorize → commit → finalize the floor's own export (DURABLE_LAG(1), R6.3 A1)
X2agentafter AUTHORIZE, before history COMMIT(n) + pending (n+1, H')nS; unused-authorization-cancelledINDETERMINATE; a living floor still holds S' and the successor agent re-authorizes the same tuple after the cancel
X3agentafter history COMMIT, before FINALIZE(n) + pending (n+1, H')n+1, H'S'; pending-successor-finalizedINDETERMINATE
X4agentafter FINALIZE, before ACK(n+1)n+1S' (clean)INDETERMINATE
X2+Fagent and floorafter AUTHORIZE, before COMMIT(n) + pendingnS; the fence leaves the pending, reconciliation cancels itINDETERMINATE, and the truth is S
X3+Fagent and floorafter COMMIT, before FINALIZE(n) + pendingn+1S'; the fence leaves the pending, reconciliation finalizes it as the supervisorINDETERMINATE, and the truth is S'
N1anchor serviceduring AUTHORIZE (after the write, before the reply)pending writtenn—the agent re-opens; authorize answers already-authorized; continues; SUCCESS
N2anchor serviceduring FINALIZE, before the writependingn+1—re-open; finalize → ok; SUCCESS
N3anchor serviceduring FINALIZE, after the write, before the reply(n+1)n+1—re-open; finalize → already-finalized; SUCCESS
S1–S5history serviceR6.3's five pointspendingas R6.3as R6.3 (a crash before its COMMIT leaves nothing; after, committed-unacknowledged)the retry answers ok / already-applied, then FINALIZE; SUCCESS
W3/W4floorafter the agent holds S'advances normallyn+1S'SUCCESS — the holder's death cannot retract a state the agent holds (R6.3)
W3b-Afloor, then a concurrent recovery fences before the agent's AUTHORIZE—(n)nSNOT_DURABLE (wrong-writer at AUTHORIZE): nothing of this op is durable; the truth is S
W3b-Ffloor, then a concurrent recovery fences between the agent's COMMIT and its FINALIZE—(n) + pending, then finalized by reconciliationn+1S'INDETERMINATE (committed-unfinalized): the row is durable and the anchor authorized exactly it; reconciliation finalizes; the caller may not be told NOT_DURABLE for a state that is the recovered truth
G1agentgenesis: after AUTHORIZE(0), before COMMITpending (0)emptycancelledINDETERMINATE
G2agentgenesis: after COMMIT(0), before FINALIZEpending (0)0finalized as the supervisorINDETERMINATE

No window may establish two current heads for one Locus: the anchor has one current row; authorize refuses a second pending tuple; finalize moves current only to the exact pending tuple; a history that disagrees with both is refused, never adopted.

5. The rollbacks that must become refusals (the H3x family)

Each is a control the battery performs on the history file with the anchor untouched, followed by a recovery attempt and then a restore that must open and recover normally:

controlexpected
the whole history file replaced by an older, internally consistent copy (H3x)history-behind-anchor — REFUSE
an older copy reached through a symlink at the canonical pathnamethe same: the anchor names the head, not the file
head and rows rolled back together (rows > k deleted, head := k)history-behind-anchor
rows rolled back, the internal head left at nthe store's own head-behind at open
the head row's bytes replaced by another row's (same LSR, different digest)the store's chain-broken, or history-diverged if the chain is re-hashed to match
the writer binding rolled back with the file (old bound)the anchor's current.writer wins: the old incarnation's AUTHORIZE is wrong-writer; the file is also history-behind-anchor
a foreign Locus's history presented as L'sthe store's wrong-locus
the same Locus's history from another deployment's anchor namespace (a second anchor directory with its own genesis for L), at the same LSR with different byteshistory-diverged against this anchor
the same, one LSR aheadhistory-ahead-unauthorized

Two deployments that perform byte-identical operation sequences on the same Locus produce identical chains and are indistinguishable to the anchor — by construction, since the anchor commits to the semantic head. Not a defect; said.

Writer controls (F127), each against the anchor: old history + old binding restored together; current history + stale bound; current bound + stale history. Each must recover to the exact anchored tuple or refuse.

The unanchored mechanism is retained as the negative control: R6.3's Domain.recover on the same rolled-back file still accepts it (F131).

6. Recovery, anchored

ACTIVE(F1, I17), floor dead, positive finality
   │  anchor.rebind(NOBODY)            -- the fence, first; a pending is left for reconciliation; NOT_FENCED if not taken
   │  history.bind(NOBODY)             -- the cache follows
   │  reconcile(anchor, history)       -- §3: clean | finalized | REFUSE
   │  (n, Hn) := anchor.current; row := history.get(n); require d(row) = Hn and row.locus = L
   ▼
S' = row.bytes
   │  finalize F1‖I17 <gen> supervisor req=take:<m'>   payload S'   (R6.2/R6.3, unchanged)
   ▼
IN_TRANSFER(m') → CLAIM → MOVE_IN dormant → INSTALL GATE: EXPORT == history.get(anchor.current.lsr).bytes, digest == anchor.current.digest
   → durable ACTIVATE → floor ACTIVATE → anchor.rebind(F2‖I') and history.bind(F2‖I')

The install gate is now install-is-anchored-head: the new holder's bytes must equal the row the anchor names, not merely the row the store calls head.

7. Falsifiers

  • F123 a whole-file rollback of the history to an older consistent copy

is recovered from (H3x must be a refusal).

  • F124 the store moves the anchor: a self-consistent newer history is

accepted without an exact prior authorization.

  • F125 after any crash window, two current heads exist for one Locus

(two finalized tuples, or a finalized tuple and an adopted unauthorized head).

  • F126 a pending authorization is finalized for a history head with a

different digest.

  • F127 the writer binding rolls back with the history: a fenced

incarnation authorizes or finalizes again.

  • F128 a crash window at an anchor boundary (§4) has no named recovery,

or its recovery differs from the table.

  • F129 the anchored path loses R6.3's parity: history B through the

anchored gate does not reproduce the acknowledged successor, or the capsule replays.

  • F130 the anchor is coupled to file bytes: a WAL checkpoint or VACUUM

of an honest history changes the verdict. (By construction the anchor never reads the history's bytes, so the control measures that the store survives a layout change under the anchor; the anchor's byte-independence is structural, and the control asserts the bytes did change.)

  • F131 the unanchored control stops accepting the rollback (the round's

non-vacuity).

  • F132 a fenced incarnation finalizes its pending authorization, or a

pending authorization the history never committed survives reconciliation, or one the history did commit is lost to it.

  • F86 kept; the R6, R6.2 and R6.3 images byte-identical to their

receipts.

8. Hand-ons (named, not built)

  • Repair: rolling a refused history back to the anchor's head, or

forward to a finalized one, as a supervisor act with a receipt.

  • Three fsyncs per mutation: the authorize could be batched or the

anchor co-located with a trusted service; not optimized here.

  • A transient busy (a lock held past the 5 s timeout) is treated as a

refusal and poisons the agent; it is not retried. Fail-safe, not tuned.

  • Everything R6.3 handed on: the INDETERMINATE dedup table, structural

backpressure, compaction, sealed rows, inter-host transport, power loss.

9. Predictions, before the battery

  1. H3x becomes history-behind-anchor; every control in §5 refuses by the

name in its row; the restored history opens clean and recovers with parity; the unanchored control still accepts the rollback.

  1. Every window in §4 lands as the table says; X3 finalizes, X2 cancels;

the anchor service's three crash points answer already-authorized, ok, already-finalized on retry.

  1. The writer controls refuse at the anchor (wrong-writer) whatever the

history's bound says; after rebind(NOBODY) the fenced agent's finalize is wrong-writer, and reconciliation cancels the unused authorization.

  1. History B through the anchored path keeps R6.3's parity; the transfer

capsule stays ALREADY_CONSUMED; the install gate refuses a payload that is not the anchored head.

  1. A WAL checkpoint and a VACUUM of the history leave the verdict clean.

  2. Two agents of one bound incarnation racing AUTHORIZE for the same

successor: one ok, the other pending-outstanding; never two current heads. (A second incarnation is wrong-writer deterministically — no race to run.)

  1. F86 and the three image identities hold; R6, R6.1 (repaired rule),

R6.2 and R6.3 retained batteries hold.

10. Adjudicated (2026-09-05) — accepted, and R6 frozen

R6.4 was accepted as executed, and with it R6 is frozen under its declared trust profile (receipts/R6-FROZEN.md). Standing after the ruling:

  • H3x is closed for the declared R6 trust profile. The deciding

evidence is the negative control: R6.3's unanchored recovery still accepts the rolled-back, internally consistent history, while the anchored path refuses the same family by name (history-behind-anchor, history-diverged, history-ahead-unauthorized, …) and the restored file recovers with parity.

  • **AUTHORIZE → history COMMIT → FINALIZE → ACK and its reconciliation

rule are the standing durable-history currentness protocol.** The anchor commits to the semantic head, never to file bytes; recovery fences through the anchor before trusting the history; the store may confirm what the anchor authorized and may not teach it.

  • Cost and hand-ons accepted as named: three fsync'd transactions per

durable mutation; repair of a refused history is an explicit supervisor act with its own receipt, never the anchor silently learning from the store.

  • No R6.5. The regression "what makes the anchor current — another

anchor?" terminates where a system declares its trust root: copyable semantic state → durable Locus history → deployment-controlled history anchor → TRUST ASSUMPTION. Continuing upward would not discover further Locus currentness semantics; it would only choose how strongly the trust root is instantiated. Remote quorum anchoring, secure-hardware anchoring, hostile-host protection, caller authentication, power-loss semantics and replicated anchors strengthen the deployment profile later without changing the Locus model.

  • Editorial, folded into the freeze, no protocol change: the standing

wording is the reconciliation verdict table (§3), never a row count — the records' "nine-row" / "nine verdicts" predate the genesis, writer and finalize-refused rows (ERRATA E3); and the R6.4 EXECUTED unclaim list's out-of-sequence numbering is a formatting accident whose canonical enumeration is receipts/R6-FROZEN.md §6.

  • What R6 hands to the next round is not another currentness layer but

multiplexing as multiplexing: ready-Locus progress, density, fairness and starvation controls, and semantic work per physical cost — under the rule that a semantic transition is never split to imitate thread suspension (receipts/R7-OPEN.md, docs/progress-model.md).

Open in the interactive atlas