How we did it
We used official data, our own software, which logs every step, and digital fingerprints (hashes) that make it possible to check that no file has changed. AI tools have helped us to read, organise, code, suggest wording and review. The figures for esPublico's contracts do not come from an AI model: they are calculated from the official files by a program with automated testssource 1. We copy the other figures from their source and cite it.
In detail
The official sources
- Plataforma de Contratación del Sector Público (Spain's official public procurement platform, contrataciondelestado.es)source 2. It is governed by Law 9/2017 on Public Sector Contracts: contracting authorities publish their buyer profile on it, and the autonomous communities may have a platform of their ownsource 3. The buyer profile exists to ensure transparency and public access to the activity of each contracting authoritysource 4.
- Open data from the Platform, on the Ministry of Finance website. It is generated by the Directorate-General for State Assets from what the contracting authorities themselves entersource 5. We use three datasets: tenders published on buyer profiles, tenders that arrive by aggregation from other platforms (since ) and minor contracts (since )source 6. The aggregated ones are those from the regional platformssource 7. The file format is set out in the official syndication specificationsource 8.
- Register of mayors and councillors of the Ministry of Territorial Policy and Democratic Memory, in its Local Information Systemsource 9, and the search service for local elected representatives on Red SARA, the Spanish administrations' communications networksource 10. We use them only to find out the party recorded for the mayor of each council on each date.
- Boletín Oficial del Estado, Spain's Official State Gazette, for the text of Law 9/2017source 11 and of the previous lawsource 12.
The tools
- Download robots, which fetch notices and tender specifications from the public platformssource 13,source 14.
- Our own Python programs, which turn the official files into tables, with one row per contract award resultsource 15.
- A version-controlled repository, in which every change is recorded with its author and datesource 16, as entered by whoever makes it.
- SHA-256 hash manifests (see below).
What the AI tools have done
We have let them read, organise, code, suggest wordingsource 17 and review, but not decide. This is what we told Antigravity: You are not a lawyer, you do not decide litigation strategy, you do not sign.
(our translation)source 18 Some of the ones we have used:
- Manus, since source 19: prepared the first analysis documentation for the repositorysource 20.
- The Clone, Miguel Ángel Domínguez's digital brain, since : received the investigation archive to organise what we knewsource 21,source 22.
- Antigravity, from Googlesource 23, since : received the case to integrate it into the digital brainsource 24,source 25.
- Claude Code, from Anthropicsource 26, since source 27: programmed the analysis of the open datasource 28 and checked that every tender and every person mentioned in the complaint is linked to a document in the investigation filesource 29.
The chain of custody
A SHA-256 hash is a string of letters and numbers calculated from the contents of a file. If a single bit of the file changes, the hash is differentsource 30. That is why it can be used to show that a file has not changed.
We have generated three manifests of the investigation file, each with the hash of every file it covers. Here we publish the hash of each manifest: if any of them is produced later, anyone can check whether it is the same one, because a single change would make the hash stop matching. We publish this page ourselves: a hash shows that a manifest has not changed, but not how long it has existed.
- source 31 ·
db2cb7498216d7d7994a465ca93ae50f77641b013e008d97f0ca8fb9544f660asource 32 - source 33 ·
d8159666f9845f2d4569fe0f7fd1f7edc5ba304395bd3be2bfb20f5d35a2238dsource 34 - source 35 ·
e3e071e13c41cfe262226bdb3d9939625712c6c2ef50adf19e9fd1a15ff96c5esource 36
Before filing the criminal complaint, we will regenerate the manifest from the final version of the investigation filesource 37.
How to check the hash of a filesource 38:
- macOS or Linux:
shasum -a 256 filename(on Linux alsosha256sum filenamesource 39) - Windows:
certutil -hashfile filename SHA256
The result must match the one in the manifest, character for character.
What we are not explaining yet
Part of the work is an analysis of the published tender specificationssource 40. We will set out the full method when the Public Prosecutor's Office allows us to publish the criminal complaint.
Sources for this page
‘Investigation archive’ refers to our own documents, which are not yet public; ‘Source code of this website’ refers to this portal’s source code, which is not public either. For both we give a reference so that they can be located.
- Source code of this website, reference datos-pruebas · checked on
- contrataciondelestado.es, reference placsp-portal · checked on
- boe.es, Ley 9/2017, art. 347.1, 347.3, reference lcsp-art-347 · checked on
- boe.es, Ley 9/2017, art. 63.1, reference lcsp-art-63 · checked on
- hacienda.gob.es, reference placsp-datos-abiertos · checked on
- hacienda.gob.es, reference placsp-conjuntos · checked on
- Investigation archive, reference placsp-agregadas · checked on
- contrataciondelsectorpublico.gob.es, reference placsp-especificacion · checked on
- mptmd.gob.es, reference alcaldes-mptmd · checked on
- concejales.redsara.es, reference alcaldes-redsara · checked on
- boe.es, reference lcsp-boe · checked on
- boe.es, RDL 3/2011 (TRLCSP), art. 138.3, reference trlcsp-art-138 · checked on
- Investigation archive, reference robot-descarga-anuncios · checked on
- Investigation archive, reference robot-pliegos · checked on
- Investigation archive, reference herramientas-scripts · checked on
- Investigation archive, reference git-registra-autor-fecha · checked on
- Investigation archive, reference antigravity-misiones · checked on
- Investigation archive, reference antigravity-no-decide · checked on
- Investigation archive, reference manus-20260101 · checked on
- Investigation archive, reference manus-uso · checked on
- Investigation archive, reference clon-ordena-archivo · checked on
- Investigation archive, reference clon-20260417 · checked on
- Investigation archive, reference antigravity-google · checked on
- Investigation archive, reference antigravity-encargo · checked on
- Investigation archive, reference antigravity-20260521 · checked on
- claude.com, reference claude-code-anthropic · checked on
- Investigation archive, reference claude-code-20260702 · checked on
- Investigation archive, reference claude-code-analisis · checked on
- Investigation archive, reference claude-code-cobertura · checked on
- Investigation archive, reference sha256-un-bit · checked on
- Investigation archive, reference manifiesto-20260702 · checked on
- Investigation archive, reference huella-manifiesto-20260702 · checked on
- Investigation archive, reference manifiesto-20260704 · checked on
- Investigation archive, reference huella-manifiesto-20260704 · checked on
- Investigation archive, reference manifiesto-20260722 · checked on
- Investigation archive, reference huella-manifiesto-20260722 · checked on
- Investigation archive, reference manifiesto-final-previsto · checked on
- Investigation archive, reference como-comprobar-huella · checked on
- man7.org, reference sha256sum-coreutils · checked on
- Investigation archive, reference analisis-pliegos · checked on