Durable Owner Contract (#lzdurablespec)
The durable-owner contract is the backend-neutral boundary for a host whose accepted transitions survive process loss. It is distinct from the live durable effect-sink pattern: an effect sink projects a live graph outward, while a durable owner commits the accepted transition first and reconstructs a fresh graph from that durable image after restart.
No core type names SQL tables, broker subjects, or cache keys. A database adapter implements the boundary; transport acknowledgement and publication run after it.
Identity and version types
Every owner, inbox item, outbox effect, and receipt has a non-empty stable identity. Reusing an identity with byte-identical content is idempotent. Reusing it with different content, schema version, codec version, or terminal outcome is an identity conflict and MUST NOT overwrite the first record.
Every durable payload carries independent, positive schema_version and
codec_version values. A binding MUST preserve both. Unsupported versions fail
before decode or mutation; neither field may default, normalize, or stand in for
the other.
Position and fence
Each owner starts at position zero. A new commit names the exact current position and current fence token. The store assigns the next event position or snapshot position with checked arithmetic. A stale or future position is a compare-and-swap conflict. A fence mismatch is stale authority—even a greater token cannot promote itself through a state write. Fence advancement is a separate lease/authority operation.
Completed inbox deduplication runs before position and fence checks. Therefore, a redelivery of a committed message returns the original committed position even after later transitions or a fence handoff. It performs no new mutation.
Atomic unit of work
One accepted commit makes all of these records visible together:
- the completed inbox identity and immutable input fingerprint;
- appended domain events or the replacement snapshot;
- outbox effect intents with stable effect identities;
- transaction-local terminal effect receipts.
A crash before the commit exposes none of them. A crash after the commit exposes
all of them. Only Committed or an exact completed Duplicate makes ingress
acknowledgement safe. External effect publication occurs after commit; a crash
after publication reuses the same effect identity, and its terminal receipt is
recorded idempotently as another durable fact.
State modes
EventHistory and Snapshot are immutable per-owner modes:
- Event history preserves every accepted event in exact position order. Its complete-history fingerprint binds the owner, every positioned/versioned source record, the durable frontier, and the projected observation.
- Snapshot state replaces older state bytes while advancing the durable position. It proves recoverable current state, not complete history.
LatestDurableProjection is a third and deliberately separate egress protocol.
It may supersede pending intermediate values and therefore advertises only
latest_state_only. It MUST NOT implement, be accepted as, or be relabeled as a
complete-history source.
Two different valid histories may settle to the same projected state. Their projection-content fingerprints may compare equal, while their history/source fingerprints MUST differ. This is why a final-value comparison alone cannot certify replay completeness.
Complete-history projection and reconciliation
A complete-history projection consumes create, amend, and retract facts
in exact durable-position order. Its checkpoint binds the last consumed source
position, a monotonically increasing projection version, and the full projected
state. Restart resumes only from that checkpoint plus the contiguous suffix;
replaying the entire history and resuming from any valid checkpoint MUST produce
the same state and frontier. Partial retraction removes only its named entity;
retracting the final entity projects an empty state rather than a missing or
stale value.
A reconciliation pass is a dry-run comparison between a transaction-consistent
durable-owner/projection snapshot and a deterministic history rebuild. It reports
projection lag, content drift, and healthy, lagging, or drifted health. It
MUST NOT mutate authority directly. A repair is scheduled with a stable identity
such as reconcile/<owner>/<source-position> and joins the owner’s existing
transactional outbox in the same atomic commit, making repeated scheduling
idempotent.
Only the durable owner row loaded from the authority transaction may authorize a transition. A replica, projection, cache, health report, or reconciliation result is advisory even when fresh; a stale or cache-only read MUST NOT supply a position, fence, or state value used to accept a transition.
Canonical evidence
The conformance/durable-owner/ corpus fixes four independent proof surfaces:
atomic_crash_boundary.json— all-or-none commit visibility, commit-before-ACK, fresh reconstruction, and redelivery;ordered_replay.json— monotone positions, exact CAS, exact fences, history order, snapshot replacement, and independent schema/codec versions;inbox_outbox_deduplication.json— exact-repeat idempotency and identity conflict behavior for inboxes, effects, and receipts;projection_fingerprint.json— equal projections from unequal histories, thecomplete_historyversuslatest_state_onlycapability boundary, ordered create/amend/retract replay, checkpoint restart, partial and final retraction, drift/lag health, stable reconciliation identity, and durable-only transition authority.
The JSON Schema is schemas/durable-owner.json. Every assertion compares a
complete durable image or an explicit fingerprint relation, so an implementation
cannot pass by checking only a final value or a row count.