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

9/13/20267 min read
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.

AIBehind the scenesLegal Tech

Scritto da Giulio Garofalo