Filtered recall@10
# grade this stage (from your course directory)
npx theinference test --stage filtered-recall --watchMeasure filtered search the way you measured plain search. Run it over all queries for a high-cardinality filter and a low-cardinality one, compute filtered recall@10 against the filtered ground truth, and confirm the low-cardinality filter took the full-scan path (recall 1.0).
What to build
Print filtered recall per filter
Wire the filtered-recall subcommand. For each named filter, compute the filtered brute-force top-10 (ground truth among matching ids) and the filtered-search top-10, average recall@10, and report the match count + whether it took the full-scan path. Print:
{ "high": { "matchCount": ..., "recall": ..., "fullScan": 0 },
"low": { "matchCount": ..., "recall": 1, "fullScan": 1 } }
./your_program.sh filtered-recall <fixture>/chapters/06-payload-filtering/steps/04-filtered-recall/fixtures/data.json
The low-cardinality filter matches fewer points than fullScanThreshold, so it must take the filtered full scan — which returns the exact answer, recall 1.0. That fullScan: 1 field, plus recall exactly 1, is the proof the planner fired.
Process mode: stdout_json_match against the frozen reference (atol 1e-6 on recall). The "recall ≥ 0.90" framing is prose; the grade is an exact match to the reference filtered recall.