The corpus was not thin. It was shattered.
- Symptom
Recent bids returned the wrong references. Two hypotheses were on the table: too few relevant references, or broken matching.
- Diagnosis
Neither. I measured against the running database rather than reasoning about the code, and the numbers settled it: 108 reference-shaped answers existed, behind 108 distinct question wordings, with at most one reference reachable under any single wording.
That last figure is the whole story. The importer deduplicates on the pair of source and question hash, deliberately discarding which file a row came from, and the last occurrence wins. The corpus stores one reference per row against a repeating question, which is exactly the shape question-hash dedup cannot survive: it treats “three references” as “one answer, imported three times”.
I replayed the real import file through that logic to see the size of it: 283 of 3,141 answers discarded, eight of them reference-shaped. Three references answering one repeating question collapse to whichever row happened to be last.
So “give me three references” was unanswerable by construction. There was no question you could ask that had three. And to reach one particular reference you had to ask the past bid’s question near-verbatim.
- Decision
Stop trying to serve references from the question-keyed store, and stop trying to guard it. The mismatch was not a prediction about caching to be mitigated. It was already deleting the corpus at import time, silently, with the survivor chosen by row order.
The corpus check also sized the solution, which is why it was worth doing before designing anything: on the order of twenty distinct customers, tens of references rather than hundreds. That answers “curation or machinery” in favour of curation. And thirteen of the reference rows in the export had been hand-added directly rather than extracted from any bid, so somebody was already curating references by hand. The habit existed; it had no home in the system.
three references → three rows, one question hash
dedup key (source, question hash)
source file deliberately dropped from the key
winner the last row. by row order.
replayed 283 of 3,141 answers discarded
8 of them reference-shaped
retrievable 1 reference per question wording
so “three refs” unanswerable by constructionone engagement → one structured record
three refs → three records. nothing to
collapse them onto.
selection once per bid, over the register
ranked by product overlap → sector → recency
pins/exclusions outrank every ranking axis
the test three DISTINCT customers across
the three blocks ← fails if
selection goes per-cell again