Resolve reply parents referencing add-to batch hashes - #39
Open
markmnl wants to merge 3 commits into
Open
Conversation
A reply to an add-to batch message carries the batch hash as pid. Per SPEC SS11 the batch message is reconstructible from what the host already holds - the stored shared message plus the batch's sender, recipients and wire time - even though the batch's data was never downloaded again. Reply validation now falls back to reconstructing the batch wire form when pid matches msg_add_to_batch.sha256, and the relational parent link and challenge-participation thread walk resolve batch hashes to the shared message row. For that reconstruction to be faithful the receive path now records the batch's wire time in time_added, matching the outbound path where time_added already serves as the batch header's timestamp. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The receive path stores a batch's hash when recording it, but batches this host originates never had theirs stored - so a remote reply referencing our own batch could not resolve here (SPEC SS11: a host verifies messages it sent, not only ones it received). Mirror ensureSharedHash: compute once at first delivery (the challenge response reuses the cached value) and persist when null. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The populate-psha256 trigger required psha256 to equal the relational parent's canonical sha256, rejecting stored replies that reference one of the parent's add-to batch messages by batch hash (SPEC SS12). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Stacked on #35 (needs
msg_add_to_batch.sha256) — review/merge #35 first; this PR's base isfix/add-to-batch-hash-identity.Implements the acceptance side of the sibling-branch ruling: a reply to an add-to batch references the batch message's hash via
pid, and per SPEC §11 the receiving host can verify it because the batch message is reconstructible from what it already holds — the stored shared message plus the batch's sender, recipients and wire time — even though it never downloaded the message data again.Changes
msg_add_to_batch.time_added(previously the local record time). This matches the outbound path, wheretime_addedalready serves as the batch header's timestamp (addToHeader), and is required for the batch hash to be recomputable from stored fields.getMsgByBatchHash: resolves a batch hash to the reconstructed batch wire header via the existingloadMsgFields/loadAddToBatches/addToHeadermachinery.validatePidReplyPathfalls back to it whenpidmatches no canonicalmsg.sha256; time-travel and participant checks then run against the batch header (whose participants are the original's plus that batch'sadd to— exactly the batch message's participant set).txParentLinkStore.lookupParentIDalso resolves batch hashes to the shared message row, so a stored batch-reply'spidlinks into the thread.ensureBatchHash, mirroringensureSharedHash; the challenge response reuses the cached computation). Without this, a remote reply referencing our own batch could not resolve here — SPEC §11's "sent by the host" clause applies to batches too.threadHasFromDomain's root lookup also matches batch hashes, so HAS_NOT_PARTICIPATED mode doesn't wrongly challenge batch replies.handleAddToPathkeeps the canonical-only lookup deliberately (now commented): batches do not chain, so an add-to whosepidis another batch's hash must not resolve.Not in this PR (needs coordinated fmsg-webapi change)
loadMsgmerges all batch recipients into the parent's participant set) — deliberately left, because fmsg-webapi today sends replies with the shared hash aspidfor all participants. Once webapi replies with the batch hash for added recipients, the merged participant set inloadMsgcan be narrowed.🤖 Generated with Claude Code
dd.sql trigger fix (
647c36e)Integration testing caught that the
populate_msg_psha256_from_pidtrigger rejected stored batch replies: once the relationalpidlinks to the shared row, it requiredpsha256to equal the parent's canonicalsha256. It now also accepts apsha256matching one of the parent's recorded add-to batch hashes.Verification (fmsg-docker integration suite)
New test
009-reply-to-add-to-batch.sh(pushed to fmsg-docker main) covers the full scenario: receiver records the batch hash reconstructed without re-downloading data, originator persists the identical hash, and a reply carrying the batch hash aspidis delivered cross-instance and relationally linked.main: tests 001–008 pass, 009 fails ("did not record the add-to batch hash").After merge: run
scripts/update-dd.shin fmsg-docker and commit the dd sync (merging the dd sync before this branch would break fmsgd main's add-to path — the old code'sON CONFLICT (msg_id, addr)needs the constraint the new schema drops).