Repository navigation
Report a resident's full-write head in GET_RECORD answers, so readers keep replicas only of it - #1177
Merged
Merged
Conversation
… keep replicas only of it The answer carries fullWriteHead, the responder's head log key when its row is flagged FULL_WRITE_HEAD (core), and only then. Core keeps a replica only when that key is the stub's head, so a body whose head is a patch is served but never kept. An older reader ignores the field; an older responder omits it, so its answers are never kept. A copy frame, or a relayed entry carrying core's COPIED_RECORD audit flag, applies with copyFrame, so no node certifies a copied body (part of harper#3703). Relays forward the flag unchanged in the entry's bytes. The copy walk masks the record-only bit from the audit flags it mirrors, and builds a replica's projection in core's demotion order (primary key first, since core #3610), so it encodes as the demoted stub does. Bumps core to the companion change. Dispatch-Task: harper-replica-row-version-consistency Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F7groUxcrz6wPPXNzUKCnx
There was a problem hiding this comment.
Code Review
This pull request ensures that replicas are only kept when the resident head is a full write, and that copied puts maintain their provenance through relays without being certified. It updates the replication protocol to include fullWriteHead in GET_RECORD_RESPONSE when applicable, filters out FULL_WRITE_HEAD from audit flags, and marks copy frames appropriately. New integration and unit tests are also added to verify these behaviors. The review feedback suggests adding explicit parentheses around a bitwise operation in replicationConnection.ts to improve readability and prevent potential linter warnings.
Dispatch-Task: pr-maint-harper-pro-1177-repin Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xoBABrkJLf8fw26t48sNb
kriszyp
marked this pull request as ready for review
October 28, 2026 11:23
kriszyp
added a commit
that referenced
this pull request
Oct 28, 2026
Keeps #1177's fullWriteHead in GET_RECORD answers alongside this branch's residencySlot; the copy walk keeps this branch's copyExtendedType, which already masks FULL_WRITE_HEAD, so main's copiedFlags is dropped. Core moves from harper#3527's head to its squash merge b29241296 (adds only #3706, #3708). Dispatch-Task: pr-maint-harper-pro-1116-rebase Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xoBA8UtKfgJoZfMDdzpyv
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.
⊙ Problem
Core now keeps a resident's GET_RECORD answer as a replica only when the resident certifies that its newest write replaced the whole record (Keep a replica only of a resident's full-write head, and skip writes older than such a head without reading the audit log). Only the resident knows that: a non-resident receives every put and patch as an
invalidate. Without this PR, core keeps no replicas at all.🤔 Should the answer carry the resident's head kind, rather than the stub?
Yes. Tagging each converted put on the
invalidateinstead changes the audit entry format and must survive relays and copies. The answer field is additive, and readers that don't know it ignore it.💡 Solution
fullWriteHead, the resident's head log key, only when its row is flaggedFULL_WRITE_HEAD. Readers keep a replica only of their stub's own head.🤔 Should a copied put an older build logged be treated as a copy?
It has no
COPIED_RECORD, so a relay of it during a rolling upgrade can still be certified. Marking it needs the copy-read position tracked in harper#3704, awaiting a decision there.🔧 Changes
replication/replicationConnection.ts: the answer field;copyFrameon every copy frame and on a relayed entry carrying core'sCOPIED_RECORD; the copy walk masks the record-only bit from the audit flags it mirrors, and builds a replica's projection in core's order (primary key first, since core #3610; without it anycorebump past #3610 fails 9 copy tests).replication/DESIGN.md: the field, why it needs no gate, and the older-build gap.core: pinned to the merge commit of the core PR (harper maine7558e82).✅ Verification
residencyReplicas.test.mjs, new case: a patch head is not kept; a put head is kept and renews while hot. It fails onmain(patch head kept) and without the field (nothing kept). Suite 9/9.residencyReplicaWire.test.mjs: the field appears only for a put head, and copies carry noFULL_WRITE_HEAD. 49 passing withresidencyWire; copy suites 125 passing.copyProvenanceRelay.test.mjs, with its fixture (resources, config, schema): a relayed copied put is not certified on the next hop and still supersedes a late increment. It fails without the receive mapping.🤖 Generated with Claude Code
https://claude.ai/code/session_01F7groUxcrz6wPPXNzUKCnx
🤖 Generated by Claude Code (Claude Opus 5.5); posted via @kriszyp.
Release target: v5.4 — the companion core change (replica tier) is only on main/v5.4
Related PRs: #1092 overlaps (same send and receive paths: keep the copy-walk mask and the copyFrame mapping), #1116 overlaps (copy walk and GET_RECORD responder: shard paths must add fullWriteHead), #1133 overlaps (core pointer: this pin is newer and contains the companion commit), 1 others independent
Complexity: medium
Deferred findings
937b04141c08bb45major data-integrity —replication/replicationConnection.ts— below-audit-floor fold changes body at unchanged version; certified replica renews stale — filed A replica stays stale while hot after a below-floor commutative op folds into its resident's full-put head harper#3684e74a3450cc5d3b65minor data-integrity —replication/replicationConnection.ts— unmarked legacy copied put relayed by older build is certified FULL_WRITE_HEAD on upgraded receiver — filed Fold a late write a copied put's body lacks, using the source's log position at the copy read harper#370462aa91a96ddd5f83nit maintainability —replication/replicationConnection.ts— replica copy projection double-allocates and duplicates core residencyStub order — filed Tidy the replica copy-walk projection and the full-write-head wire tests #11766a9b5e9464e0a54cnit test-coverage —unitTests/replication/residencyReplicaWire.test.mjs— receiver fixture fabricates fullWriteHead; head-key test never hits additionalAuditRefs branch — filed Tidy the replica copy-walk projection and the full-write-head wire tests #1176f1770b6a4cc3cfd2nit test-coverage —replication/replicationConnection.ts— direct messageIsCopyFrame arm of the copyFrame mapping has no Pro test; deleting only that arm stays green — filed Tidy the replica copy-walk projection and the full-write-head wire tests #1176🤔 defer this PR's major data-integrity finding
937b04141c08bb45(below-audit-floor fold changes body at unchanged version; certified replica renews stale) to HarperFast/harper#3684 instead of fixing it here?Late Grok findings
1 surviving (highest major) — Grok reviewed ffc986c
replication/replicationConnection.ts:655— the live invalidation stub built byresidencyStubOfholds only index fields and leaves out the created-time value. Core'sresidencyStub(standaloneharper/resources/Table.ts:11117-11128) adds the created time. The copy walk adds it as well, by hand (`replication/replicationConnection.ts:7320-7Not standing: none. Grok ran 13m (13m from launch to report); the fold adjudication (
cursor-grok@ffc986c3867e-040b3c86, claude) took 2m.Late Grok findings
3 surviving (highest nit) — Grok reviewed c70c064
unitTests/replication/residencyReplicaWire.test.mjs:155— Mostly fixed. The answer-field comment atreplication/replicationConnection.ts:6121and the cited test comments at old lines 117 and 268 are gone. The comment "a resident whose head is the stub's own full write" is still in the unit test. It is probably the cited old :157 comment and it repeats thunitTests/replication/residencyReplicaWire.test.mjs:156— The kept-replica test writes the reader's own stub version intofullWriteHeadinstead of taking it from the responder. That test therefore can't catch a wrong head computed on the responder side. Other tests cover that::200-202checks the head the responder sends for a full write and for a patcreplication/replicationConnection.ts:6121— No Pro test sets a delete head and checks the head key it produces. The author says a delete reaches a non-resident node as a tombstone, not a stub, so that head is never used; this was not verified because core isn't checked outNot standing: none. Grok ran 12m (13m from launch to report); the fold adjudication (
cursor-grok@c70c06488b1b-29e0fef8, claude) took 1m.Review-Coverage: authored=claude; ran=cursor-composer,gemini,codex,cursor-grok; late=cursor-grok:adjudicated; adjudicated=domain; declined=muse; rounds=11; full=9 @ 23690ed
Review-Attention: deep ~25m (critical: replicationConnection.ts; decisions: ungated-wire-field, accept-rolling-upgrade-certification-gap, repin-as-separate-branch, deferred-937b0414; raised: degraded review) @ 23690ed