Commit Graph
4 Commits
Author SHA1 Message Date
Chris CoutinhoandClaude Opus 4.8 8deb48e6fa fix: address PR #813 review round 4 (log leak, cross-user chunk ctx, algo, overlap)
1. Don't log unverified result titles: both search algorithms logged top-5
   titles at DEBUG before verify-on-read; with owner-level share expansion the
   unverified set can contain other users' docs. Algorithms now log a count
   only; the verifying callers (server/semantic, viz_routes, api/visualization)
   log verified titles after verify-on-read.

2. Cross-user FILE chunk context: get_chunk_with_context + the Qdrant chunk
   helpers now take accessible_owners and use build_ownership_filter. For files
   the expanded scope is honoured only after a per-file file_accessible_by_id
   check (accessible_owners is owner-level, so the gate prevents a one-file
   share recipient from reading any of the owner's cached chunks). note/deck/
   news stay self-only (per-user APIs) — a documented gap. Both chunk endpoints
   pass accessible_owners.

3. Algorithm usage: SemanticSearchAlgorithm is not dead (it backs the dense-only
   option on the viz/API surfaces); added a clarifying comment in server/
   semantic.py. Additionally wired accessible_owners + verify-on-read into the
   /api/v1 search routes (unified_search, vector_search) so the astrolabe
   surface is ACL-aware too — degrading gracefully to self-only/unverified for
   non-provisioned callers instead of 401.

4. Overlapping conditions: build_ownership_filter no longer lists self in the
   owner_id MatchAny branch (self is already covered by the user_id branch);
   the owner_id branch carries only the OTHER owners.

Tests: build_ownership_filter dedup + chunk-bbox filter-shape updates; new
ACL-aware get_indexed_doc_types, cached-chunk lookup, and end-to-end cross-user
file chunk-context (recipient gets the chunk, non-recipient denied) tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 16:55:00 +02:00
Chris CoutinhoandClaude Opus 4.8 423d0a1758 fix: address PR #813 latest review (ACL-aware doc-type discovery, robustness)
- get_indexed_doc_types: add optional accessible_owners param and reuse
  build_ownership_filter so cross-user doc-type discovery matches the real
  search scope (was self-only / ACL-blind); docstring documents the self-only
  default. Covered by test_get_indexed_doc_types_is_acl_aware.
- access_filter: build_ownership_filter now omits the owner_id branch entirely
  for an empty owner set instead of relying on undocumented MatchAny(any=[])
  semantics; updated the empty-list unit test accordingly.
- access_filter: make the uid_owner/owner share-owner extraction explicit
  ("absent, not empty") to avoid skipping on a falsy-but-present field.
- access_filter: add an operator note that pre-owner_id points need a re-index
  to surface to share recipients (ACL search is a no-op for legacy data).
- verification/webdav: lock the file_accessible_by_id(scope="") contract with a
  targeted multi-user test (owner + recipient True, non-recipient False).
- viz_routes: comment that verify-on-read eviction runs inline by design (no
  lifespan task group available on the Starlette route).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 14:57:34 +02:00
Chris CoutinhoandClaude Opus 4.8 b1fac2d7a8 fix(search): address PR #813 review (viz verify-on-read, owners cache, docs)
- viz_routes: run verify_search_results before returning results. After the
  accessible_owners expansion the viz can surface OTHER users' shared docs, so
  it must drop ones the caller can no longer access (revoked share) — same as
  the nc_semantic_search tool path. (Blocking review item.)
- access_filter: cache list_accessible_owners per user for 30s to keep the OCS
  shares round-trip off the search hot path (failures aren't cached); document
  the single-page OCS limitation; add a clear_accessible_owners_cache() test
  helper. Comment the empty-accessible_owners MatchAny([]) edge case.
- verification: comment why cross-user eviction is a deliberate no-op (eviction
  is scoped to the querying user's id, so a recipient's revoked access never
  deletes the owner's points; the recipient self-heals via accessible_owners).
- algorithms: declare SearchResult.original_score (set by the viz route) so the
  now-precisely-typed result list type-checks.
- tests: cross-user eviction-no-op safety test; autouse owners-cache reset in
  the access_filter + shared-search tests; replace async-no-await qdrant fakes
  with AsyncMock (clears SonarCloud S7503).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 02:15:44 +02:00
Chris CoutinhoandClaude Opus 4.8 bf35200bab fix(search): verify shared files by global file id (ACL-aware)
The ACL-aware vector filter (PR #813) expands a user's search to documents
whose owner shared them, but verify-on-read still re-checked each file by
PATH under the *searching* user's WebDAV root. Nextcloud mounts received
shares at the recipient's root by basename, so a nested shared file (e.g.
owner's /docs/report.pdf) 404s for the recipient and was silently dropped —
defeating the filter for everything but root-level files.

Verify files by their global Nextcloud file id instead (the file doc_id IS
that id): WebDAVClient.get_file_info_by_id was insufficient (the dav/meta
endpoint only resolves the user's own storage, not shares), so add
WebDAVClient.file_accessible_by_id which runs a WebDAV SEARCH over the user's
whole tree (incl. mounted shares) filtered on oc:fileid. Empirically this
resolves owned, directly-shared, and folder-shared files; an empty result is
a definitive drop, transport errors are kept as transient.

- search/verification.py: _verify_files now checks file_accessible_by_id.
- client/webdav.py: add file_accessible_by_id (SEARCH by fileid).
- tests/integration/test_acl_owner_filter.py: filter matrix vs real Qdrant.
- tests/integration/test_acl_shared_search.py: real-Nextcloud share -> search.
- tests/integration/test_verify_on_read.py: nested shared file kept for the
  recipient; unshared file dropped.
- tests/unit/search/test_verification.py: id-based verifier semantics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 23:05:40 +02:00