Thicket.
← Back to Journal

Measurement

We Declared Our Data Source Exhausted. We Had Measured Our Own Query.

A re-run returned 83% the same domains and twelve new ones. That looks exactly like a source running dry. It was a keyword list running dry, and the two are indistinguishable until you deliberately change the question.

We re-ran a sourcing sweep and got 83% the same domains back, with twelve genuinely new ones. We wrote the source up as saturated. One day later, widening the keyword list from 20 terms to 65 — same registry, same script, nothing else changed — returned 5,063 domains at 44% overlap and 2,859 genuinely new. The source was never exhausted. Our query was.

Two horizontal bars comparing sweeps. The 20-seed sweep returns 2,285 domains of which 83% were already collected. The 65-seed sweep returns 5,063 domains of which only 44% were already collected.
The teal portion is what we already had. Nothing about the registry changed between these two bars.

What we were doing

We collect company domains from a public package registry, keep the ones that publish regularly, and check whether an AI assistant names them when asked their category's buying question. The collection step queries by keyword — twenty of them, deliberately paginated deep into the long tail rather than the popular head.

It had worked. Then we re-ran it, and the yield collapsed: 2,285 domains, of which 2,204 we already had. Twelve genuinely new candidates survived filtering. Three had a contact address that a mail server would confirm exists. Three is under one day of work.

The wrong conclusion, and why it was easy

We wrote it up as source exhaustion. The reasoning felt solid, and one part of it still is: a queryable registry is a set, not a stream. Running the same query again mostly re-enumerates what it matched the first time. Yield collapses on the second pass and keeps collapsing. Re-running an unchanged sweep on a schedule is close to worthless, and knowing that is worth something.

The error was attaching that fact to the wrong noun. We had measured the reach of one query design and drawn a conclusion about a registry containing millions of packages. A high overlap number cannot distinguish those two situations — it looks identical either way — and we had run exactly one sweep design.

What the widened sweep returned

stage20 seeds65 seeds
domains returned2,2855,063
overlap with prior sweep83%44%
genuinely new domains122,859
candidates (active publisher + contact)12136
usable contact address11123
verifiably live mailbox357

Three verifiably live contacts became fifty-seven. One widened sweep produced more genuinely new domains than the entire previous sweep contained.

Adjacent, not synonymous

The widening only works if the new terms reach a different population. Adding synonyms matches the same items and re-proves the saturation you were trying to test — if your seeds are analytics and metrics, you have one slice, not two.

We added observability and delivery, data infrastructure, AI-native tooling, money and trust, identity and security, product surface. The test for an added seed is simple: do you expect it to match things the old seeds could not? If not, it is decoration.

The habit that caught it

The write-up declaring the source exhausted also contained this, in the same document, on the same day:

If widening the seed list to ~60 keywords returns a similar 80%+ overlap, the registry itself is exhausted rather than these seeds being narrow. Read it on overlap percentage, not on raw domain count — raw count is what made this morning's number look healthy.

Both halves earned their keep. The condition made the test worth running instead of leaving a plausible conclusion to harden into a fact. And naming the metric in advance mattered more than we expected: the second sweep returned 5,063 domains against 2,285, and a raw count that much larger is easy to read as an ordinary better day. Overlap is the number that actually distinguishes the two explanations, and we had committed to it before we knew which way it would fall.

We had spent the previous day designing a replacement source. None of that was needed. The fix was forty-five extra words in a list.

Method: npm registry search API, queried by keyword, paginated from result 200 to 1,000 to avoid the popularity head. Sweeps on 25 and 26 August 2026 with 20 and 65 seeds respectively. Overlap is computed on distinct non-repository company domains. "Verifiably live mailbox" means the receiving mail server accepted the address at RCPT while rejecting a random control address at the same domain.

Frequently asked

How do you tell a saturated data source from a saturated query?

Change the query and measure overlap, before you conclude anything about the source. Re-running our sweep with an unchanged keyword list returned 83% the same domains, which looks exactly like a dead source. Widening the keyword list from 20 terms to 65 — same registry, same script, one day later — returned 5,063 domains at 44% overlap. A saturated source returns high overlap no matter how you ask. A saturated query returns high overlap only for that query, and you cannot tell the two apart without varying the query deliberately.

Why is repeated collection from the same source so misleading?

Because a queryable registry is a set, not a stream. Running the same query again mostly re-enumerates what it matched the first time, so the yield collapses on the second pass and keeps collapsing. That collapse is real and worth knowing — it means re-running an unchanged sweep on a schedule is close to worthless — but it is a fact about your query's reach, not about how much the source contains. We measured the collapse correctly and then attached it to the wrong noun.

What did the numbers actually look like?

First sweep, 20 keyword seeds: 2,285 domains, 83% overlap with the previous run, 12 genuinely new candidates, of which 3 had a verifiably live contact address. That is under one day of outbound. Second sweep, 65 seeds, one day later: 5,063 domains, 44% overlap, 2,859 genuinely new domains, 136 candidates, 123 with a usable contact, 57 with a verifiably live mailbox. One widened sweep produced more genuinely new domains than the entire previous sweep contained.

How should you widen a keyword list without just re-running the same thing?

Add adjacent categories, not synonyms. A synonym matches the same items and re-proves the saturation you are trying to test — if your seeds are 'analytics' and 'metrics' you have one slice, not two. We added observability, delivery, data infrastructure, AI-native tooling, money and trust, identity and security, and product surface. Each is a different population of publishers rather than a different way of naming the first one. The test of a good added seed is whether you expect it to match things the old seeds could not.

What stopped this from becoming a permanent wrong belief?

Writing the falsifier down in the same document as the conclusion, and naming in advance the metric it would be read on. The write-up said: if widening to around 60 keywords returns a similar 80%-plus overlap, the source really is exhausted. It also said to read it on overlap percentage rather than raw domain count, because raw count was exactly what had made the original number look healthy. Without the named metric the second sweep's 5,063 domains would have been easy to read as an ordinary better day.

What are the limits of this result?

It is one source — the npm registry — queried by keyword, and one team's seed list. The specific numbers will not transfer. What we think does transfer is the failure mode: a collapse in yield on re-collection is evidence about your query's coverage, and becomes evidence about the source only after you have varied the query and watched overlap stay high. We had run one sweep design and drawn a conclusion about a registry containing millions of packages.

More from the Journal