Repository navigation
fix(embeddings): reject background vectors for superseded content - #204
Merged
Merged
Conversation
johnny4young
marked this pull request as ready for review
October 7, 2026 21:59
- Accept a guarded vector write for any row the store still shows, using the shared unexpired predicate, so an expired pinned, boarded or snippet row stays indexable as it was before - Share the ineligible-kind list between the guarded write and the stale refresh queue, so rows the write always rejects cannot fill a batch and stop the refresh for every row behind them - Bound the write-race tests with a time limit so a regression fails instead of hanging, and cover both rules
12 tasks
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.
Finding
Capture enrichment keeps the captured body across asynchronous title work; model-version refresh reads a body before computing its vector. Both later used an unconditional ID-only upsert. A concurrent text edit could delete its old vector, then an older background producer could put that stale vector back.
Correction
Identity and risk
Title/keyword-only edits do not invalidate a body vector. A content-equal ABA change, including deletion/recreation under the same ID with the same eligible body, may accept it: the vector describes the current body. Different replacement text or changed privacy eligibility is rejected. The content hash is deliberately not used because curation preserves it for deduplication. Full-body comparison is stricter than the model's 1,000-character input truncation.
This does not introduce a reindexing scheduler, retroactively repair all existing vectors, or change title/OCR behavior. Review the optional-capability behavior for custom stores and transaction predicate.
Regression evidence
Exact source and limits
Head: 919acb3
Tree: 4f974d5947577ac0fb326de9370e58609438ea46
Base: main at ccc4403
make format, make lint and make test were attempted, but this Linux executor lacks Swift/Xcode. Initial CI 37661464708 failed strict swift-format on one trailing comma in ContentBoundEmbeddingTests.swift before package tests executed. The forward-only follow-up removes that comma, with no behavior, assertion or gate change. Exact-head CI 37690654827 passed: strict swift-format, SwiftLint, build-warning checks, 1,507 package tests in 234 suites, 83.8% production-source coverage above the unchanged 80% floor, StoreKit entitlement tests and both macOS/iOS app builds. All seven new embedding regressions passed natively. GitGuardian passed; the non-blocking beta canary was skipped as expected. Scoped gates are complete and this PR is ready for review. No UI flow was changed; the separate full UI workflow was not dispatched.
All earlier open repairs were inventoried before editing. No open PR addresses these producer/persistence paths. #203 fixes legacy snippet-edit invalidation; this PR has no overlapping files, is independently main-based, and also protects current draft/text-edit paths. No stack dependency or combined-native qualification is claimed.
No public API removal, schema migration, new dependency, log content, license removal, threshold/workflow change, manual CI dispatch, merge, release or deployment.