refactor(search): address PR #750 round 8 review feedback

- Rename `verified_count` → `verified_chunk_count` to make the count
  granularity explicit at the field name (chunks vs unique docs).
- News verifier now fails open *per-item* on non-numeric stored doc_ids
  (matches notes/files/deck shape); a single bad id no longer rescues
  definitively-missing siblings from eviction.
- Update note-verifier integration test to use string doc_ids end-to-end
  to match production storage (scanner.py:241 stringifies note ids).
- Add regression test for the closed-task-group race guard in
  `verify_search_results` so the RuntimeError swallow is locked in.
- Convert remaining f-string logger calls in `server/semantic.py` to
  lazy %-style formatting (per repo convention).
- Document `evict_on_missing` as a developer/test flag (no env var) and
  flag the `get_file_info` 404→raise contract change in its docstring.
- Add a TODO(ADR-019) breadcrumb for the hardcoded 2× over-fetch so
  future tuning has a clear hook.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-01 21:40:30 +02:00
co-authored by Claude Opus 4.7
parent 3e981e647a
commit 8a2626da6c
6 changed files with 252 additions and 76 deletions
+17 -11
View File
@@ -323,28 +323,34 @@ async def _verify_news_items(
)
return set(doc_ids)
# Cast safely: a non-numeric id from the API or in our doc_ids would
# otherwise raise ValueError after the semaphore block exits and surface
# as a verifier crash. Treat as transient (fail open) instead.
# Build present_ids from the API response. If the API itself returns
# malformed (non-numeric) ids, the whole batch becomes unverifiable —
# fail open for every requested doc_id (transient).
try:
present_ids = {
int(item.get("id")) for item in items if item.get("id") is not None
}
# Map back to the original doc_id types (caller may pass ints or strs).
accessible: set[int | str] = set()
for d in doc_ids:
if int(d) in present_ids:
accessible.add(d)
return accessible
except (TypeError, ValueError) as e:
logger.warning(
"Non-numeric id while verifying news items (sample=%r, doc_ids=%r): %s; keeping all results",
"Non-numeric id in news API response (sample=%r): %s; keeping all results",
items[:3] if items else items,
doc_ids,
e,
)
return set(doc_ids)
# Per-item check: a single non-numeric *stored* doc_id is fail-open
# for THAT item only — not the whole batch. Mirrors the per-item
# shape of the notes/files/deck verifiers.
accessible: set[int | str] = set()
for d in doc_ids:
try:
if int(d) in present_ids:
accessible.add(d)
except (TypeError, ValueError):
logger.debug("Non-numeric news doc_id %r; keeping (cannot verify)", d)
accessible.add(d)
return accessible
_VERIFIERS: dict[str, BatchVerifier] = {
"note": _verify_notes,