HarperFast / HarperFast/harper-pro
Replication applies the origin's log key as the record version for source fills (cross-replica fill-version divergence)
- Dominant language
- JavaScript
- Stars
- 3
- Forks
- 0
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 80
Description
## Problem
Since core #2065 separated a source fill's stored record version from its fill transaction's commit timestamp (the transaction-log key), replication has applied the origin's LOG KEY as the record version on peers for every replicated source fill: `replication/replicationConnection.ts` puts `auditRecord.version` (the log key on RocksDB today) on the apply event as `timestamp` (~:5759), core adopts it as the apply transaction's timestamp (`Table.ts` ~1046 → `transaction.ts` ~52), and that timestamp becomes the record version.
Result: the origin stores the fill at its source-derived record version while every peer stores it at the origin's commit key. Cross-replica fill-version divergence, exactly the class of inconsistency #2065 set out to fix. Silent: nothing alarms; it surfaces later as spurious conflict-resolution outcomes.
## Fix direction (stage 0b of [harper#2412](https://github.com/HarperFast/harper/issues/2412), rewritten 2026-09-02)
Under the settled model, the receiver adopts two things from the origin separately:
- **First word / log key**: set the apply transaction's timestamp from `AuditRecord.localTime` (the origin's first word, which is also the origin's log key). This is the one legitimate `setTimestamp` caller besides crash replay. The destination's per-origin log keeps the origin clock, so the "version === audit-log key" resume-cursor invariant (~:4085 in the old numbering) is preserved. Do NOT reuse the applied record version as the destination's per-origin log key: that would fix leaf state while breaking relayed/proxied resume ordering.
- **Record version**: apply `AuditRecord.version` (normalized to the record version in stage 0b; `recordVersion ?? version` until then) per write. In stage 2 this lands in the second word when it differs from the first word; until then it is the record's stored version.
Cursor sites move to `localTime`. Wire format carries both words (it already carries the record version in-band per #2409).
## Scope
Main-line (unreleased) only: #2065 is on core main (v5.3), not on a cut release branch. Needs the two-node replication leg for verification: a fill replicates with its version preserved and its first word equal to the origin's log key; disconnect; resume from the origin cursor; receiver restart.
Contributor guide
Assessment
This issue has not been assessed yet.