It knew 22,000 rulings, but not one bill number

Direct answer: the more sophisticated a system is along one dimension, the likelier it is that the trivial case next to it was never tested. My legal engine indexed over 22,000 Constitutional Court rulings going back to 1956, European judgments, Court of Cassation decisions and thousands of links between norms — and could not find a bill searched by number, because search only worked on the words in the title. Nobody had tried it: it seemed too obvious to be broken.
TL;DR
- Question: «Senate Act no. 1627». Answer: «I could not retrieve verified information».
- The same system answered far harder questions on constitutional case law without trouble.
- Cause: bill search did text matching on the title only. The numeric identifier was not a search criterion.
- No test covered it, because searching by number seems the most elementary function there is — so it is assumed done.
- General pattern: you test what you built with effort, not what you took for granted.
- Recursive footnote: I built that feature with a small team of AI agents in parallel. The end product is an agent, built by agents.
The moment you notice
The system is an assistant answering questions about Italian laws and public data. It holds, indexed and queryable, Constitutional Court case law since 1956: over twenty-two thousand rulings. Plus European judgments, Cassation decisions, and thousands of explicit links between norms and decisions.
I asked it something simple: information about Senate Act no. 1627.
«I could not retrieve verified information.»
Not an error, not a timeout: a polite failure, the kind the system produces when it genuinely finds nothing. On an exact identifier. For an act that exists.
The cause, suitably embarrassing
Parliamentary act search was implemented as text search over the title. You searched «antisemitism» and found bills with that word in the title. It worked perfectly for that.
The numeric identifier — which is how anyone who actually works with parliamentary acts refers to them — was not supported as a search criterion. Searching «1627» made the engine look for acts with «1627» in the title. There are none.
It was not an implementation bug. It was a feature never written, which appeared to exist because it was too obvious to be missing.
Why nobody had tested it
This is the part worth generalising, because it is not about my code.
When you build the hard part of a system — ingesting twenty-two thousand rulings, building the graph, disambiguating entities — all your attention is there. That is where you expect problems, and that is where you write tests, because that is where you have seen things break.
The trivial case next door never enters your field of view, for three reasons:
- It does not look like a feature. «Search by number» is not an item on a work plan: it is what the system obviously does.
- It was never declared. If nobody wrote it into a requirement, no test covers it.
- Whoever builds it never tries it. In months of work I never needed to search for an act by number: I searched by topic, because I was building the topic.
The result is a specific asymmetry: the system is rock solid where you sweated and fragile where you assumed. And the assumed part is, almost always, the first thing a user tries.
The test you never write
After this case I added a fixed item to my checklist, and I call it the layperson test:
Before release, ask the system the three stupidest questions a new user would ask in their first two minutes.
Not the hard questions — you have covered those. The ones you take for granted:
| System type | The stupid question you did not test |
|---|---|
| Document search engine | Searching a document by its identifier code |
| CRM | Searching a customer by tax ID rather than name |
| Catalogue assistant | Asking for an item by product code |
| Booking system | Searching a booking by confirmation number |
All of these have the same shape: the exact identifier instead of the description. It is the case developers use least and users use most, because the user has that code in front of them, printed on a document.
It is the same reason a bug that breaks the view survives for months: the person who could notice never walks that path.
Footnote: a team of agents to build an agent
One recursive thing worth telling, because it says something about how work happens now.
To restart after this problem I split the work into three independent strands — data-source retrieval, fixing the search bug, a reference legal dossier — and handed them to three AI agents in parallel, rather than doing them myself in sequence.
The end product is an agent that answers questions about laws. Built, in large part, by a small team of agents.
I am not telling this for the neat symmetry, but for a practical consequence: splitting work into strands with sharp ownership boundaries — this one touches only these files, that one only those — is what makes parallelism possible without the result being a mess to stitch back together. It is the same discipline needed between people, just made mandatory: an agent does not negotiate boundaries, it either respects them or breaks through them. And if it breaks through you find out immediately, which is more than can be said for many human processes. I wrote about it in detail thinking through what changes when you build at AI speed.
FAQ
Why can a complex system fail on an elementary search?
Because attention — and therefore testing — concentrates where the work was hard. Elementary functions are not declared as requirements, do not enter the test suite, and are never tried by whoever builds the system, who queries it with their own working questions rather than a new user's.
What is the «layperson test»?
It is a release check where you ask the system the most obvious questions a user would ask in the first two minutes — typically searches by exact identifier rather than description. These are the questions developers use least and users use most.
How do you avoid this class of problem systematically?
By writing requirements for the obvious too, and including in the test suite at least one case for every way a real user can name an entity: by name, by identifier, by code, by external reference. If an identifier appears on a document the user is holding, it must be a search criterion.
Is splitting work between multiple AI agents actually worth it?
It is worth it when the strands have sharp ownership boundaries over files and responsibilities. Without those boundaries, parallelism produces conflicts that cost more than the time saved; with them, it is the most effective way to stop doing things in sequence.
If you have a system that handles the hard questions beautifully and surprises you on the easy ones, the problem is usually coverage of implicit requirements, not the code. Let's talk.
Related articles
- PNRR contracts: five public systems that do not talkFinding out who won an Italian PNRR contract takes at least five different public databases, none of which is designed to be queried alongside the others. The technical record, source by source, from someone who actually tried.
- The worst bug does not break the feature. It breaks the view26 tools connected and working in production, the dashboard showed zero. The bug had been there for months for another product too, and nobody had seen it because whoever could notice had admin permissions.
- What ingesting 46,844 documents with an LLM actually costsThe prototype runs on the free tier, then you try to ingest 46,844 documents and find the real bill is not the one you had in mind. The calculation nobody does before launching the job, with real numbers.