fix(knowledge): stop document ACL changes from rewriting unfilled projection chunks - #8175
Merged
Merged
Conversation
…jection chunks The document trigger copied a changed ACL onto every enabled chunk whose projected ACL differed, and a chunk the projection backfill has not filled yet (acl IS NULL) always differs. Each such write re-inserts the row into the vector index, so one document ACL change inside a sync or member rewrite could rewrite every unfilled chunk of that document in the writer's own statement. Unfilled chunks now keep a NULL ACL: search already decides them on their document, and the backfill copies the document's current values under a share lock. A document that moves to another source still carries the source onto them, since source filters read it from the row. The new body ships as script migration 0023, which replaces the function in place; 0022 installs the same body on a fresh database.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
Collaborator
Author
Collaborator
Author
|
@cubic-dev-ai review this PR |
Contributor
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
This was referenced Sep 22, 2026
This branch was successfully deployed
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
sync_projection_source_acl()updated every enabled chunk whose projected ACL differed from the document's; a chunk the projection backfill hasn't filled (acl IS NULL) always differs, so any real document ACL change rewrote all its unfilled chunks (each a vector index insert) inside the writer's statement — admin ACL writes, the permissions-only revoke, andrewriteConnectorAclsall paid itacl = NULL; filled chunks still get the new ACL and source; unfilled chunks get the new source only when the document actually moves (OLD.connector_id IS DISTINCT FROM NEW.connector_id), since source filters readconnector_idoff the row0023_projection_acl_skip_unfilled(runs in the migrate job after SQL migrations), which onlyCREATE OR REPLACEs the function;0022/db:pushinstall the same body via the sharedreplaceProjectionSourceAclSyncWhy it's safe
projectionCandidateAccessConditionunfilled branch), so leaving it NULL can't leak or hide anything; the "projection filled" probe only ever sees fewer NULLs, never new onesconnector_id/aclfrom the documentFOR SHAREand only write rows still NULL. Change committed first → the page reads the new values. Page holds the share lock first → the change waits, then its trigger sees a filled row and overwrites it. Change uncommitted when the page arrives → the page waits and rechecks the updated document. All three are covered by tests with real lock waitsType of Change
Testing
bun run lint,bun run check:audits,type-check(packages/db, apps/sim),check:migrations origin/stagingpassChecklist