A Nil Result Is Not a Finding Until You Prove You Could Have Found Something

2026-09-08 · Philip Choo · AI9OS

Here are seven searches of a live government register, each for the same firm, each using a different guess at the parameter name. Every one returned the firm's name in the page body. Every one returned HTTP 200.

```

keyword=hitpay 40910 bytes name present

searchText=hitpay 40913 bytes name present

search=hitpay 40909 bytes name present

name=hitpay 40907 bytes name present

q=hitpay 40904 bytes name present

institutionName=hitpay 40918 bytes name present

entityName=hitpay 40913 bytes name present

```

Seven for seven, and all seven false. The register had not been searched. Not once.

What actually happened

Two things gave it away, and neither was the presence of the name.

The sizes. The page with no search applied at all is 40,891 bytes. Every "result" above is within thirty bytes of it, and the difference each time is the length of the query string itself. Seven different searches, seven near-identical pages, all of them the unfiltered index.

The single occurrence. Searching the body for where the name appeared found it exactly once:

```

href="/fid/institution/print?sector=payments&keyword=hitpay"

```

The name was in a print link the page had built out of the query. The register had echoed the question back and it had been read as an answer.

The parameter the application actually accepts is term. It took one request to the search page and one look at the form's <input name=...> to find it. That is thirty seconds of work, and it came after seven confident false positives.

Why this matters more than it looks

An evidenced negative is one of the most valuable things an investigation can produce, and it sits at the top of any honest confidence ladder. It converts he says he has no interest in that company into the audited public record does not show one. Directors' registers, judgment databases, bankruptcy indexes, licence registers: the negative finding is often what the whole instruction turns on.

That value is exactly what makes a false negative dangerous. In a report, a broken search and a genuine absence look identical. Both are a zero. Both get written up as a nil. And the false one is quoted downstream with all the confidence the real one has earned, because nothing on the page distinguishes them.

A broken search is silent, and silence reads as absence.

The first control, and why it is not enough

The long-standing discipline is a positive control: before recording any nil, run a term on the same interface, in the same session, that must return rows. For a Singapore company index, a very common surname. For a judgment database, an unfiltered corpus count. For a marketplace, a generic high-volume item.

If the control does not populate, every nil from that interface is discarded and the finding recorded is mechanism not proven. That failed control is itself worth recording, because it stops the next person banking the same false negative.

This works. In one asset trace, two register searches in a single session both returned zero for the subject. One was a real nil: the corpus populated in the thousands when queried without a filter, so the mechanism was proven. The other was a register where the control term, among the most common surnames in the country, also returned zero. The two zeroes were indistinguishable in the raw output. Only the control separated the evidenced negative from the broken interface.

But look again at the seven searches at the top of this page. A positive control would have passed all seven. The control term is somewhere in a 40,891-byte index, so a register that ignores your query and hands back its entire contents contains the control term too.

The positive control proves the interface answers. It cannot prove the interface is listening.

The second control

So run a negative control as well: a term no register on earth can hold, which must return zero.

Something long, ASCII, and composed of nothing that occurs in a company name or a statute. If that returns rows, the query is not filtering, and no result from that session means anything, including the ones that looked right.

The two controls fail in opposite directions, which is why you need both:

| Control | What it proves | The failure it catches |

|---|---|---|

| Positive, must return rows | The interface answers | A dead endpoint, a broken index, a query that silently errors |

| Negative, must return none | The interface filters | An ignored parameter, an echoed query, an unfiltered index handed back whole |

Neither catches the other's failure. A dead search fails the positive and passes the negative. An ignored parameter passes the positive and fails the negative. Running one and calling it a control is how the seven false positives above happened, on a project that already required a control.

Make it structural, not a habit

A habit is present when the person running it is unhurried, and absent when they are not, which is precisely when it is needed.

So the rule belongs in the tool rather than the training. In our register-search tool the control term is a required argument: a search with no control raises rather than returning rows. The negative control runs on every query, even after the positive one has passed. And the guarded call is not the search itself but the conclusion drawn from it. Rows are harmless. The register contains no such instrument is the sentence that reaches a client, so that is the call that refuses unless both controls behaved and every page was fetched.

It returns a sentence rather than a boolean, on purpose. A boolean loses its provenance somewhere between the script and the report. A sentence carries the control evidence with it:

The register returns no instrument for this term across four pages fetched. The control term returns 397 rows in the same session, so the interface answers, and a nonsense term returns none, so it filters. Note that this register's index does not read scanned documents, so this shows only that nothing is titled or inline-indexed for the term. It is not a register-wide textual absence.

That last sentence is the part most people leave out, and it is the part that decides what the nil is worth.

What to ask, if you are the one commissioning the work

You do not need to run any of this yourself. You need to know whether the person you instructed did. These sit alongside the questions in how to check the investigator you are about to instruct is licensed: one set establishes that they may lawfully do the work, this set establishes that the work was actually done.

  • "How do you know the search worked?" A good answer names a control term and what it returned. A weak answer describes the interface.
  • "Is this absence from the register, or absence from the register's index?" Rarely the same thing. Scanned documents, legacy fonts and partial digitisation all produce indexes that cannot read their own contents.
  • "How many pages did you fetch?" Many registers page at ten rows and report the total separately. Ten rows is a page, not a result set, and reading it as one is a distinct way to reach a confident wrong answer.
  • "What would have made you say you could not tell?" If nothing would have, you are not being told about a search. You are being told about a screenshot.

A nil result from an unproven interface is not a finding. It is a blank space with a citation attached, and the citation is what makes it dangerous.

And a control that survives collection can still die on the way into the report. That is the companion failure, and it has its own post: closed as "no links found", when the links were in the file.

AI9OS turns public information into verified, chain-of-custody findings for licensed investigation agencies, law firms and corporate risk teams.

Request a demo