Repository navigation
Port durable batched search metadata sync to React v2 - #1674
Merged
Paul Lizer (paullizer) merged 1 commit intoOct 6, 2026
Merged
Paul Lizer (paullizer) merged 1 commit into
Paul Lizer (paullizer) merged 1 commit into
Conversation
Port #1658 (merged into Development as 900a3e4, including hardening commit 9c156a4) and its follow-up #1673 (df3879c) to the React V2 branch. Re-implemented against V2's strict update_document(), group projection fence, content screening and native group/public document APIs rather than cherry-picked. - Mirrored metadata (title, authors, file name, classification, tags) is projected by a durable background sync. The request is recorded in the settings container before the save, the save carries its token, and a worker merges only the changed fields in key-paged batches of 500. The worker never writes to the document. - Access-control lists are projected synchronously and fail closed. Group revocations go through the projection fence before the save, grants after it. Re-approving an approved share repairs its search access. - Native group/public receipts add search_sync. Metadata projection failures no longer produce document_propagation_incomplete; strict group edits on multi-chunk documents no longer fail on the fence etag. - Legacy routes save every field in one update_document() call and drop propagate_tags_to_chunks(), which is removed. Errors are fixed messages. - Blob tag refresh moves to the worker, best effort and conditioned on the blob ETag. After a pass that changed chunks, the worker clears cached search results for the workspace and every approved share recipient. - React and classic workspace UIs show a notice while the index updates. - Harnesses that exercised the per-chunk loop now drive the sync worker. Refs #1657 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment on lines
+84
to
+88
| from utils_cache import ( | ||
| invalidate_group_search_cache, | ||
| invalidate_personal_search_cache, | ||
| invalidate_public_workspace_search_cache, | ||
| ) |
| return 'user_id', user_id | ||
|
|
||
|
|
||
| def get_document_search_acl_fields(group_id=None, public_workspace_id=None): |
Paul Lizer (paullizer)
merged commit Oct 6, 2026
7bc21b6
into
paullizer-react-v2-ui
11 checks passed
6 tasks
Paul Lizer (paullizer)
added a commit
that referenced
this pull request
Oct 6, 2026
, #1671, #1674) and renumber the Operations settings parity to 0.261.269 Conflict resolutions: - admin_settings_fields.py: keep the full Operations block. The Application Insights and Health Check declarations #1670 added beside Appearance are superseded by it, and its mixed-source telemetry switch moves into the Operations Application Insights section, after the global logging readouts. Keep #1668's on_enable documentation and both sides' V2_ONLY_FIELDS entries. - route_backend_v2.py: fold content_understanding_supported into _build_runtime_flags. - SettingsSection.tsx, AdminSettingsPage.tsx, adminFields.ts: keep both the section guide and runtimeFlags props, and on_enable beside the Operations field properties. - operations.md, release_notes.md and tests: keep both sides. Both enable_dai_debug and enable_mixed_source_development_telemetry are documented rather than exempted, and Workspaces and Operations are both fully described. - Renumber this branch's 0.261.260 references to 0.261.269; the base's own 0.261.260 Web Search fix references are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
15 of 24 tasks
Paul Lizer (paullizer)
added a commit
that referenced
this pull request
Oct 7, 2026
…ditors to 0.261.269 Brings in the durable batched search metadata sync port (#1674), which took 0.261.268, the version this pull request used. - config.py: VERSION 0.261.269 (both sides had bumped 0.261.267 to 0.261.268). - release_notes.md: this pull request's section moves to v0.261.269 above the base's v0.261.268 section, which is kept unchanged. - Renumbered this pull request's 30 other 0.261.268 references (feature, fix, admin and guide docs, functional and UI test headers, version assertions). The fix doc's version transition now reads 0.261.268 -> 0.261.269. The base's own 0.261.268 references are untouched. - docs/_data/app_surface.yml regenerated; unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.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.
Summary
Ports the durable, batched document search metadata sync from #1658 (merged into
Developmentas900a3e431, including hardening commit9c156a429) and its follow-up #1673 (df3879c07) to the React V2 branch. It is re-implemented against V2'supdate_document()(strict mode, etag and operation guards, content screening), the group projection fence, and the native group and public document APIs; it is not a cherry-pick.document_propagation_incomplete. Strict mode compared the document etag before every chunk, and the projection fence's claim changes that etag.V2-specific adaptations (beyond #1658)
_upsert_document_and_sync_access_index(..., strict=True)save.search_sync: not_required, and the worker treats them as nothing to sync, because publication rebuilds their chunks.status: 'updated',updated_fields,document_id, and the scope id, plussuccess/errors/documents_updated/vocabulary_retained. They addsearch_sync.document_propagation_incomplete, because they retry durably. Access-index failures, and group grants that don't reach Search, still do.DocumentMutationPropagationError: native APIs reportdocument_propagation_incomplete, and legacy routes answer 503 withRetry-Afterwhen frozen, otherwise 500.document_tags. An inline failure could only fail a request after the document had already saved.DevelopmentClear cached search results after a background metadata sync #1673,df3879c07): after a pass that changed chunks, the worker clears cached search results for the document's workspace and for every user or group with an approved share. Without that, a search during the sync window could keep serving pre-sync values for the cache TTL (5 minutes by default).editMetadatanow returns{ searchSyncPending }, and only anupdated200 confirms an edit.searchSyncPending. The explorer and tag manager show an info toast withSEARCH_SYNC_PENDING_NOTICE.Follow-ups (not in this PR)
_search_acl(collaboration) andset_document_chunk_visibility()(publication) still write a document's chunks as a single batch, which AI Search caps at 1,000 documents. Moving them ontoproject_fields_to_document_chunks()removes that limit.Linked issue
Refs #1657. Port of #1658 (merged as
900a3e431) and #1673 (df3879c07, search cache refresh after a sync).Release Notes & Latest Features
Is this visible to end users?
Is this admin-facing (Admin Settings, governance, deployment, config)?
Should this become a Latest Feature card?
Screenshot needed for the card?
Version bump
application/single_app/config.pyVERSIONthird segment bumped:0.261.267→0.261.268. Rebased on the latest V2 (10fbad92e, Add collapsible category rail to V2 Admin Settings #1671) and renumbered.deployers/version.txtbumped, or not needed becausedeployers/was not changedTesting / validation
Python runs use a Python 3.12 venv with Flask 3.1.3 and Werkzeug 3.1.6 (this machine's global Flask 2.2.5 does not work with its Werkzeug). Each pytest file runs in its own process, because combined runs cross-talk through module stubs. "Base" means the same command on V2 without this change.
Final tree (
10fbad92e+ this PR)python -m pytest functional_tests/test_document_search_metadata_sync.py: 35 passed (new suite, including Clear cached search results after a background metadata sync #1673's owner/approved-recipient cache test)python -m pytest functional_tests/test_group_document_management.py -k "receipt_preserves or search_failure_after or access_index_failure or blob_tag_refresh or screened_tag_edit or storage_cas_rejection or tag_finalization_conflict or successful_operations_use_the_path": 22 passedpython -m pytest "functional_tests/test_content_screening_upload_only_intake.py::test_model_generated_metadata_applies_without_a_hold": passedpython -m pytest functional_tests/test_image_description_indexing_without_ocr_text.py: 9 passed (the offline real-import probe, which covers the newutils_cacheimport)python functional_tests/route_tests/test_route_blueprint_policy_inventory.py: 12/12test_route_unauthenticated_policy_contract.py: 7/7test_route_policy_test_coverage.py: 2/2python scripts/check_swagger_routes.py <39 changed files>: 5 route filespython scripts/check_xss_sinks.py --base-sha 10fbad92e --head-sha HEAD <changed files>: 35 filespython scripts/check_broken_access_control.py --base-sha 10fbad92e --head-sha HEAD <changed files>: 27 filesgit diff --check 10fbad92e HEAD: cleanpython functional_tests/test_docs_app_surface_coverage.py7/7;python functional_tests/test_docs_site_quality.py6/6application/v2_ui:npm run typecheckpassed;npm run buildpassed, with the existing chunk-size warning.package.jsonhas no test script; the V2 UI logic tests are the node.mjssuites.node functional_tests/test_v2_group_document_operations.mjs: 20 checks passed. It failed on base because of a stalequeuedmetadata case, which this PR updates.Full per-file suites
These ran on
e66f8f475+ this change. The later V2 merges (#1669, #1670, #1671) touch only admin settings, settings derivation, and workflow code.test_group_document_management.pytest_group_document_fixture_parity.pytest_public_document_management.pytest_public_document_fixture_parity.pytest_public_context_fixture_parity.pytest_public_document_read_apis.pytest_group_document_read_apis.pytest_group_document_collaboration.pytest_group_document_publication.pytest_public_document_publication.pytest_group_document_projection_fence.pytest_data_management_search_write_fence_authorization.pytest_group_tag_definition_writers.pytest_public_workspace_tag_writer_safety.pytest_content_screening_upload_only_intake.pytest_content_screening_jobs.pytest_content_screening_upload_routes.pytest_document_provenance_versions_and_guards.pytest_xsd_ingestion_generation_integration.pytest_group_document_blob_upload_etag.pytest_public_document_call_boundary.pyThese failures predate this PR and are unchanged by it:
test_document_auto_metadata_extraction_consistency.py: 1 failed, 3 passedtest_content_screening_pipeline.py: 6 failed, 26 passedtest_workspace_upload_conversation_fix.py: 4 failed*_swagger_integration.pysuite: 3 failed, 3 passedtest_multiselect_metadata_extraction.py: 1 failed (an exact-version check)test_logging_tag_standardization.py: nonstandardWorkflow*tags in files this PR does not touch. The new[DOCUMENT_METADATA],[DOCUMENT_SEARCH_SYNC], and[DOCUMENT_SHARING]tags are used and documented.Regression sweep
The 108 other functional test files that reference the changed routes, JS, templates, or
background_tasks.pywere run per file onc968d5875with and without this change: 0 new failures. 54 files fail identically on both, for environment-dependent or pre-existing reasons..mjssuitesOf the 75
functional_tests/*.mjsfiles, 73 pass. The 2 failures are unrelated and pre-existing:test_v2_admin_nested_setting_reads.mjsis a companion script that needs its Python driver.test_v2_workspace_action_authoring_logic.mjsfinds no V2 action-registry entry form365_calendar_plugin.py.Not run
ui_tests/test_workspace_metadata_search_sync_toast.py(new, env-gated Playwright): needsSIMPLECHAT_UI_BASE_URLand a storage state.Documentation
### **(v0.261.268)**indocs/explanation/release_notes.mddocs/explanation/fixes/DOCUMENT_SEARCH_METADATA_SYNC_FIX.mddocs/reference/logging-tags.md([DOCUMENT_METADATA],[DOCUMENT_SEARCH_SYNC],[DOCUMENT_SHARING]) anddocs/guides/use-tags-in-chat.md(troubleshooting row)Security checklist
@swagger_route(security=get_auth_security()): no new routes;check_swagger_routes.pypasses on the changed route filessanitize_settings_for_user(): no settings are sent