fix: add resetRadiusThreshold() mitigation for radius threshold leak (closes #200) - #209
Merged
Merged
Conversation
added 2 commits
August 30, 2026 19:41
…loses #200) A radius-filtered Flat/IVF query poisons the thread-local search context: subsequent radius-less queries on the same thread return only the radius-filtered subset (upstream: no-op Flat/IVF context reset, radius>0 gate in _prepare_for_search). Add ZVecCollection::resetRadiusThreshold() plus ZVec::RADIUS_THRESHOLD_RESET (FLT_MAX) purge query and regression test test_radius_threshold_leak.phpt.
- IP metrics: radius DOES filter docs with similarity < -radius (e.g. opposite vectors) — the leak can occur for IP too, and the purge restores the missing negative-similarity docs (empirically verified). Replaces the false 'radius never filters / leak cannot occur / no-op' claims in CHANGELOG, method docblock, faq and decisions. - ZVec:: not ZVecCollection:: (no such class). - RADIUS_THRESHOLD_RESET rationale: PHP_FLOAT_MAX overflows to inf in float32 (not 'rejected by the FFI'); FLT_MAX mirrors upstream reset_threshold(). Fix MipsL2 '-1' misattribution (denormalize is a sign flip via its InnerProduct query metric; the -= 1 shift is cosine). - Docblock: purge query is always dense fp32 — sparse fields cannot be purged through this method.
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.
Description
Closes #200
A radius-filtered Flat/IVF query poisons the thread-local search context in upstream zvec (threshold cached on a
thread_localcontext shared per index type; Flat/IVFreset()is a no-op; radius gated byif (radius > 0.0f)): every later radius-less query on that thread — refiner, plain, any field of the same index type, even other collections — silently returns only the radius-filtered subset.Changes
ZVec::RADIUS_THRESHOLD_RESET(FLT_MAX) — purge value mirroring upstreamreset_threshold()ZVec::resetRadiusThreshold(string $fieldName, array $vector)— throwaway topk-1 purge query that overwrites the leaked thresholdtest_radius_threshold_leak.phpt(documents the leak + recovery)Empirical verification (built dylib, zvec v0.6.0)
-radius(opposite vectors) — the leak occurs for IP too, and the purge restores the missing docsTesting