Skip to content

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 also sha256sum 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.

  1. Source code of this website, reference datos-pruebas · checked on
  2. contrataciondelestado.es, reference placsp-portal · checked on
  3. boe.es, Ley 9/2017, art. 347.1, 347.3, reference lcsp-art-347 · checked on
  4. boe.es, Ley 9/2017, art. 63.1, reference lcsp-art-63 · checked on
  5. hacienda.gob.es, reference placsp-datos-abiertos · checked on
  6. hacienda.gob.es, reference placsp-conjuntos · checked on
  7. Investigation archive, reference placsp-agregadas · checked on
  8. contrataciondelsectorpublico.gob.es, reference placsp-especificacion · checked on
  9. mptmd.gob.es, reference alcaldes-mptmd · checked on
  10. concejales.redsara.es, reference alcaldes-redsara · checked on
  11. boe.es, reference lcsp-boe · checked on
  12. boe.es, RDL 3/2011 (TRLCSP), art. 138.3, reference trlcsp-art-138 · checked on
  13. Investigation archive, reference robot-descarga-anuncios · checked on
  14. Investigation archive, reference robot-pliegos · checked on
  15. Investigation archive, reference herramientas-scripts · checked on
  16. Investigation archive, reference git-registra-autor-fecha · checked on
  17. Investigation archive, reference antigravity-misiones · checked on
  18. Investigation archive, reference antigravity-no-decide · checked on
  19. Investigation archive, reference manus-20260101 · checked on
  20. Investigation archive, reference manus-uso · checked on
  21. Investigation archive, reference clon-ordena-archivo · checked on
  22. Investigation archive, reference clon-20260417 · checked on
  23. Investigation archive, reference antigravity-google · checked on
  24. Investigation archive, reference antigravity-encargo · checked on
  25. Investigation archive, reference antigravity-20260521 · checked on
  26. claude.com, reference claude-code-anthropic · checked on
  27. Investigation archive, reference claude-code-20260702 · checked on
  28. Investigation archive, reference claude-code-analisis · checked on
  29. Investigation archive, reference claude-code-cobertura · checked on
  30. Investigation archive, reference sha256-un-bit · checked on
  31. Investigation archive, reference manifiesto-20260702 · checked on
  32. Investigation archive, reference huella-manifiesto-20260702 · checked on
  33. Investigation archive, reference manifiesto-20260704 · checked on
  34. Investigation archive, reference huella-manifiesto-20260704 · checked on
  35. Investigation archive, reference manifiesto-20260722 · checked on
  36. Investigation archive, reference huella-manifiesto-20260722 · checked on
  37. Investigation archive, reference manifiesto-final-previsto · checked on
  38. Investigation archive, reference como-comprobar-huella · checked on
  39. man7.org, reference sha256sum-coreutils · checked on
  40. Investigation archive, reference analisis-pliegos · checked on