`recallBlocks` could make a candidate disappear in three downstream places, and
none of them incremented anything:
· MinScore gate it scored, but below the threshold
· structural gate neither a usable vector score nor a symbol hit
· caller topK survived everything, fell outside the requested count
Measured before this change, 6 blocks in one space, `minScore: 0.99`:
hits=0 skipped=0 skippedDim=0
That reading is indistinguishable from "the space holds one block". An operator
whose threshold is swallowing the whole corpus is told "nothing was excluded",
and goes looking at the wrong subsystem. Only the space filter and the width
filter were ever counted — the two that are decided before scoring.
## What this adds
Three non-enumerable counters, each named after its own remedy:
skippedScore lower the threshold
skippedNoEvidence re-embed: there was nothing to score
truncated not a defect — reported so the totals reconcile
Plus the invariant that makes the next silent path impossible:
**hits + skipped + skippedDim + skippedScore + skippedNoEvidence + truncated
=== the candidate pool.** A future `continue` that forgets a counter breaks it.
## Criterion
`test/recall-accounting.test.js`, one fixture per path, asserting each counter's
own value (not a merged total — "scored too low" and "nothing to score" have
opposite remedies). The fourth test is the reconciliation above.
Mutations, both in a scratch copy:
remove `gatedByScore += 1` -> criteria 1 and 4 red
remove `gatedNoEvidence += 1` -> criterion 2 red
## Collateral: two static mutation anchors moved
`test/phase-b-a.test.js` pins the V5 gate and the caller-topK truncation by
rewriting `lib/recall.js` text. Making the gate multi-line (to hold a counter)
and threading `drops` through `withSkipped` changed those exact strings, so the
anchors are updated to the new text — same mutations, same properties pinned.
Running the file confirms 38/38 afterwards; without the update three V5†
mutations failed on a stale anchor rather than on their subject.
Gates: npm test 298/298 (0 skipped), npm run check 12/12. Frozen faces untouched.