Back to News & Insights
Artificial Intelligence October 1, 2026 · 12 min read

10 Internal Inconsistencies in 3 Published Groundwater Surveys

This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content ...

10 Internal Inconsistencies in 3 Published Groundwater Surveys

This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content

A resistivity reading of 2,950 Ω·m sounds like an answer. It is not. Resistivity measures how strongly the ground resists electric current, and what counts as normal depends on the geology of that exact site. The same number can mean clean groundwater in one place and a warning sign in another.

I studied geophysics at university, and this is a problem I was trained to work on. In the Niger Delta, some surveyors use Vertical Electrical Sounding (VES) to decide where to sink a borehole. They send current into the ground, measure the resistance of each layer, and compare the results with published surveys of the same area. I have also seen the alternative: boreholes sited by artisans with no geology training, based on local folklore or wherever the last well worked. In a region with decades of oil pollution, a bad siting decision can put a community on water that should never have been approved.

Ask my agent about a reading at a named site, and it answers in plain English: normal, anomalous, or uncertain. It also tells you which paper, and which table or figure, each number came from.

While I built it, I found 10 internal inconsistencies inside the 3 published papers it uses. None of them were staged. I checked each one against the source PDFs. The full list, with pages, is on the findings page. A swapped table: the Bori paper's summary table on page 7 swaps the names of two stations. Its own coordinate table on page 3 and its Figure 2 captions show the correct order. Curve labels that contradict their own data: three stations are labeled "A-type." An A-type curve requires resistivity to increase with every layer. The papers' own layer values drop and then rise again. The Choba paper even states the pattern ℓ1ℓ3 [NORMAL] Yes, 2950 ohm-m is normal for BMGS Bori Field — it matches the trusted figure caption and coordinate table in the paper. Resistivity measures how strongly a material (like underground rock or water) resists electric current; higher numbers often mean drier or more solid layers, lower numbers suggest wetter or clay-rich layers. For this site, multiple independent parts of the same paper agree on 2950 ohm-m. SOURCE DISAGREEMENT FOUND The paper gives two different aquifer resistivity values for BMGS Bori Field: 2950 ohm-m from the figure caption and 3706 ohm-m from the summary table. Claim A: Figure 2 panel caption (IPI2Win-inverted layer table) says 2950 ohm-m Claim B: p.7 Table 1 (summary table), row printed 'BMGS bori field' says 3706 ohm-m Trusted: the figure caption and coordinate table, which say 2950 ohm-m (the paper's own p.3 coordinate table and Figure 2 captions are internally consistent and contradict the swapped labels in the summary table — this is a documented label-swap error)

Document IDs cited: reading-bori-bmgs-bori-field, reading-bori-bmgs-bori-field-p7table. Full run with every tool call and the GROQ query: examples/bori-demo.md.

I transcribed the three papers by hand into a Sanity dataset with three document types: surveyPaper: one per paper, with authors, year, and DOI. surveySite: one per survey area, with a reference to its paper. vesReading: one per station, with the layer resistivities in depth order, the thicknesses, the depths, and the exact source location (table or figure, and page).

The dataset holds 3 papers, 3 sites, and 24 station readings. The Knowledge Base built from it has 8 entries as of the latest rebuild; this number has changed with every rebuild so far, since Context restructures entries each time, not just their content. The dataset is public, so you can query it yourself. This link runs a live GROQ query against the real production dataset, no login needed, and returns the swap itself: two documents for the same station, 2950 and 3706 Ω·m.

A Sanity Context endpoint serves one mode. So my agent connects to two: GROQ mode (c78nb8ch.production): groqquery returns exact numbers from the structured documents. Knowledge Base mode (kbIp9dbX1pcY): knowledgebaseread returns the explanations and the conflict history.

The rule is simple: numbers come only from groqquery. Explanations come only from knowledgebaseread. Both endpoints serve a tool named initialcontext, so the agent prefixes each tool name to keep them apart.

The Knowledge Base holds what the raw data cannot: the decisions. When I resolved the table swap, that decision became part of the Knowledge Base, and every later answer uses it. The offline mode gives the verdict from numbers alone. Only the online agent can also say which conflicts a person already checked and resolved.

Here is a real query the agent ran, answering "is 2,950 Ω·m normal for BMGS Bori Field?" (full run):

This returns two documents for the same station. First one only, the rest of the fields are the same shape:

The second document, reading-bori-bmgs-bori-field-p7table, reports 3706 Ω·m from the page-7 summary table instead. That disagreement between two real documents for the same station is the table swap.

A paper's curve label is a claim. The layer values are evidence. So the agent never asks the model whether a label is correct. Code decides: curveType.js derives the curve type (A, Q, H, K, and multi-layer forms) from the raw layer values and compares it with the paper's label. depthArithmetic.js checks each printed depth against the depth above plus the printed thickness. grounding.js scans the final answer and removes any conflict that cites a number not present in the GROQ data.

When a table is inconsistent, a fixed code template writes the statement, not the model. Early versions let the model word it, and it sometimes chose which number was "wrong." Now the statement is identical on every run and in every mode.

These checks have 22 unit tests, including tests on the real layer values of the stations above.

Context raised 14 issues while it built the Knowledge Base, across several rebuilds. I checked every one against the PDFs. 6 pointed to real inconsistencies in the papers, and together they cover 3 of the 10: the Bori table swap, the Choba curve label, and, first caught on a later rebuild, the Etche Odufor curve label.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation