* fix(search): stop boosting compiled_truth at default detail (#3430)
COMPILED_TRUTH_BOOST = 2.0 is applied AFTER RRF normalization, and RRF's whole
dynamic range over a 100-deep pool is 1/60 -> 1/160 (a factor of 2.67). So a
2.0x multiplier consumes roughly three quarters of the range: break-even is
`2/(60+r) >= 1/60`, i.e. r <= 60, which means ANY boosted chunk inside the
first 60 ranks outranks an unboosted rank-1 chunk. That is a categorical
filter, not a tilt.
Measured against master's own rrfFusion, with the correct answer in a
fenced_code chunk at vector rank 0:
compiled_truth chunks in pool | final rank | in top-20
10 | 10 | yes
20 | 20 | NO
40 | 40 | NO
80 | 59 | NO
With the boost off the answer stays at rank 0 in every case.
The gate was spelled `detail !== 'high'` -- written as though `high` were the
special case. The documented contract in src/core/operations.ts is
"low (compiled truth only), medium (default, all with dedup), high (all
chunks)", which makes LOW the special one: `low` already restricts to
compiled_truth, so a boost there is a no-op among equals, while `medium` and
`high` are both meant to see everything. So the default detail was silently
compiled-truth-only, contradicting the op's own description.
Three changes:
1. The three fusion call sites now route through a named predicate,
`shouldBoostCompiledTruth(detail)`, returning true only for 'low'.
Extracted rather than left inline precisely because an inline expression is
only reachable through a full hybridSearch round trip -- which is why the
inversion went unnoticed. The predicate is directly unit-testable.
2. KNOBS_HASH_VERSION 13 -> 14. Results are cached AFTER fusion, so rows
ranked under the old semantics would otherwise be served under the new ones
for the whole TTL (3600s default). One-time miss spike on upgrade.
3. test/search-compiled-truth-boost-scope.test.ts pins both the mapping and
the arithmetic, and documents the displacement it prevents.
Verified the tests discriminate: stubbing the OLD predicate body into master
(so the failure is behavioral rather than a missing export) gives 4 fail /
3 pass; with the fix, 7 pass. typecheck clean, verify 32/32, and 144 pass /
0 fail across the search + fusion + cache suites.
* fix(test): update the three remaining KNOBS_HASH_VERSION pins to 14 (#3430)
Missed in the first pass because I ran a targeted set of test files instead of
the full suite. CI shards 3, 8 and 10 caught them:
test/search/knobs-hash-reranker.test.ts:67
test/cross-modal-phase1.test.ts:139,149
test/search-alias-resolved-boost.test.ts:93
Each carries the running history of why the version moved, so each gets the
13→14 rationale appended rather than just the number swapped. No pins at 13
remain anywhere in test/.
---------
Co-authored-by: Garry Tan <garrytan@gmail.com>