fix(dwn-sdk-js): carry mutable visibility facts onto tombstone indexes#1012
Merged
Conversation
RecordsDelete.constructIndexes copied only immutable initial-write facts,
so tombstones of tagged permission records never matched the permission
shadow filters ({ protocol: permissionsURI, tag.protocol: P }) and
published-record tombstones never matched published: true subscriptions.
Tombstone indexes now take mutable query-visibility facts — flattened
tag.* (same flattening as the write path) and published — from the newest
message that existed immediately before the delete, while immutable
descriptor/domain facts keep coming from the initial write. When the
pre-delete newest message is an existing tombstone (prune-of-deleted, or
a tombstone displaced under the delete-wins lattice), its visibility
facts carry forward via the initial write it derived them from. The
replication duplicate-repair path in dwn.ts derives the same pre-delete
newest message by excluding the already-stored delete itself.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Coverage ReportNode (bun test)
Coverage ReportNode coverage not available for this run. |
Contributor
Author
|
Rerunning the failed browser job: the Firefox dids/agent/api job failed before tests while downloading the workspace-build artifact with GitHub artifact API 403 (Failed to ListArtifacts). Chromium/WebKit variants and the rest of the matrix passed, so this is environmental rather than code-related. |
|
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.



Summary
Implements the tombstone visibility facts stream of the sync replication-log plan (SDK phase item 8).
RecordsDelete.constructIndexescopied only immutable initial-write facts onto tombstone indexes, dropping the mutable query-visibility facts. As a result, tombstones of tagged permission records never matched the permission shadow filters ({ protocol: permissionsURI, tag.protocol: P }) and published-record tombstones never matchedpublished: truequeries and subscriptions.constructIndexes(initialWrite, newestPreDeleteMessage): immutable descriptor/domain facts (protocol, protocolPath, recipient, contextId, schema, dateCreated, …) keep coming from the initial write; mutable facts — flattenedtag.*(sameRecords.buildTagIndexesflattening the write path uses) andpublished— come from the newest message that existed immediately before the delete.RecordsDelete(prune-of-deleted, or a tombstone displaced under the delete-wins lattice), the existing tombstone's visibility facts carry forward: a tombstone's descriptor carries neither tags norpublished, so they are reconstructed from the newest retainedRecordsWrite— the initial write — which is the same source the existing tombstone derived its own facts from.StorageController.performRecordsDeletepasses thenewestExistingMessageit already derives for its tombstone-lattice gate (covers both the handler path and resumable-task replay); the replication duplicate-repair path indwn.tsderives the pre-delete newest message by excluding the already-stored delete itself, falling back to the initial write.Changeset: patch on
@enbox/dwn-sdk-js.Test plan
{ protocol: permissionsURI, 'tag.protocol': P }and is the only match after deletion (handler spec)published: truemessage-store filters and is delivered to apublished: trueRecordsSubscribe; an unpublished record's tombstone matches neither (handler spec)bun run lintclean (15/15 packages)bun run --filter @enbox/dwn-sdk-js buildandbun run --filter @enbox/agent buildpassbun run test:nodeinpackages/dwn-sdk-js: 1466 pass, 0 fail (113 files)🤖 Generated with Claude Code