Skip to content
All projects

AI-built product2026Live

TempoParking: a live parking directory built with AI agents

A Spanish directory of over 15,000 car parks where Claude Code writes most of the code and versioned agents rewrite the listings. My part is the contract: the rules, the checks that must prove they can fail, the spending vetoes and the calls only a person makes.

Built and operated with AI agents, under human review

Role
Built and run it; AI agents write most of the code
Timeline
2026, live and in active development
Stack
Next.js 15, React 19, TypeScript, SQLite, Python, Leaflet
AI tooling
Claude Code (Opus 4.8, then Opus 5), Opus sub-agents; Cursor and Codex for bounded jobs
Scale
15,381 car parks, 1,836 landmark pages, 1,622 town pages
  • Claude Code
  • AI agents
  • LLM evaluation
  • Prompt versioning
  • Data quality
  • Data pipelines
  • Next.js
  • SQLite
  • +2
tempoparkings.com
The tempoparkings.com home page: the headline "Aparca sin dar vueltas" (park without circling the block) above live counters for 15,381 active car parks, 11,599 free options and 52 provinces.
Problem
Car-park data is scattered across operator sites, OpenStreetMap and Google, and often contradicts itself. Search only rewards pages that are specific and true.
Approach
Claude Code as the engineer under a written contract, versioned agents behind a deterministic lint, self-testing checks on every deploy.
Outcome
15,381 car parks live in 52 provinces. Google clicks grew from 1,755 in June to 44,520 in the first 26 days of August.
Car parks on the live site
15,381
Home-page counter, 18 Sep 2026
Google clicks, June to August
×25
1,755 → 44,520 (August: 26 days)
Commits co-authored by Claude Code
803 / 830
Working branch, to 18 Sep 2026
Listings rewritten by versioned agents
3,940
By 1 Sep 2026

Clicks: Google Search Console daily totals, read 30 Aug 2026. Commits: Co-Authored-By trailers in the git history.

Where to park near anything in Spain

TempoParking is a Spanish directory of car parks, focused on free parking and on where to park near a landmark, a beach or a venue. No bookings, no payments: it lives on search. Every car park, town and landmark is a page, and a data-quality score decides which ones get indexed.

On 31 August the site had 1,836 landmark pages, 1,622 town pages and 4,840 indexable car-park pages. In twelve days of August, AI crawlers made 162,086 requests against 41,124 human page views.

tempoparkings.com/parkings-gratuitos/cantabria/comillas
Town page for Comillas: the headline "Dónde aparcar gratis en Comillas", counters for 5 free options, 7 car parks in town and 4 nearby alternatives, and a map with parking pins and 500 m, 1 km and 2 km distance rings.
A town page built from the data, and the site’s fourth page by clicks from 1 July to 13 September. Live site, 18 September 2026.

Search clicks grew 25× in two months

Clicks per month

Search clicks grew 25× in two months
020K40K60K192May1.8KJun17.6KJul44.5KAug*
Search clicks grew 25× in two months
CategoryGoogle search clicks
May192 clicks
Jun1,755 clicks
Jul17,616 clicks
Aug*44,520 clicks

*1–26 August only. Average position improved from 12.1 in May to 8.6 in August.

Source: Google Search Console daily totals, read 30 August 2026.

Claude Code writes the code. I write the contract

Claude Code co-authored 803 of the 830 commits on the working branch: the app, the pipeline, the audits and most of the documentation. It can reach the production server, so the rules live in files it must read before acting:

  • CLAUDE.md: the hard rules, including Rule 0 below.
  • A decisions log, D-001 to D-081, each with an evidence level.
  • One task queue: 494 items on 18 September, 317 owned by Claude, 23 waiting for me.
  • A changelog: 233 dated entries with revert steps.
  • 20 workflow sheets; the deploy fails if a script appears outside them.

Cursor and Codex got bounded jobs. When Codex restyled the admin panel, Claude caught its quality badges showing green for bad scores.

Agents propose and write; irreversible calls stay with me

Task
Code
What the AI did
Features, fixes, audits, docs.
What I decided
Priorities and trade-offs.
Guardrail
“Done” includes a green type check, no new failing guardians and the data shipped.
Task
Listing rewrites
What the AI did
Opus sub-agents rewrite text from reviews and our own fields, and flag contradictions.
What I decided
Sets the editorial rules; signs off before published titles change.
Guardrail
Deterministic lint, dry-run apply, version stamps. Owner-confirmed fields are locked.
Task
Paid API calls
What the AI did
Builds the batch, estimates the calls.
What I decided
Approves spending per session, cost and volume separately.
Guardrail
One function makes and logs every call. The live site never calls Google.
Task
Bulk data changes
What the AI did
Writes the script, runs it dry, shows ten samples.
What I decided
Reviews the sample; production waits for my go-ahead.
Guardrail
Dated backup, disk ceiling, archive instead of delete.
Task
Questions to me
What the AI did
Checks the decisions log first.
What I decided
Answers what the log does not cover.
Guardrail
Only my literal words carry my name; inferred rules stay “candidate”.

On 18 September, Claude Code’s own permission classifier also stopped a production write and left it for me.

What the agents may not do

  • Spend on a paid API without my approval. Over 10 calls needs a second approval even when free: the monthly quota only resets on the 1st.
  • Delete data. It gets archived.
  • Publish copied text, or call a car park free without evidence.
  • Lower the indexing threshold, or rewrite content at scale with an LLM.
  • Silence a failing guardian. Skipping them is my call, with a written reason.
  • Follow a rule that is not in its versioned prompt.

From scattered sources to a gated deploy

  1. 01

    Sources

    • Operator websites
    • OpenStreetMap
    • Openly licensed photos
    • Google Places, enrichment only
  2. 02

    Master and bridge DBs

    • One record per car park
    • One place ID, one listing
  3. 03

    Listing agents

    • Opus, batches of 5
    • Prompt v6.15
    • Typed flags
  4. 04

    Deterministic lint

    • auto · review · blocked
  5. 05

    Apply and rescore

    • Dry run by default
    • Version stamp
    • Score of 60+ gets indexed
  6. 06

    Deploy gate

    • 58 guardians
    • 50 break-on-purpose runs
    • Canary first

As of 18 September 2026. The score decides indexing, never what users see.

Each prompt version has to earn its number

Every change to an agent’s rules bumps its version, stamped on each listing it writes: 3,940 listings and 5,997 revisions by 1 September. Each version states in advance how it will be judged, and the judge changed as I learned.

The quality score rewarded invention: “hours and price not confirmed” scored 93, an invented “200 m from the cathedral, open 24 h, free” scored 96. Versions are now judged by errors corrected minus true facts dropped. Since v4.0, a feature taken from reviews needs a word-for-word quote; 21 of the first 84 were paraphrases and were rejected.

I picked the model by measuring it: Opus looked harder

Same prompt, same saved inputs, three models, 30 listings across three agents. Nothing was written to any database.

MeasureHaiku 4.5Sonnet 5Opus 5
Prepared findings caught6 / 99 / 99 / 9
Contradictions flagged unprompted141127
Published errors corrected01221
Descriptions too short (of 10)600
Titles changed (of 10)721
Published a wrong cityYesNoNo

24 July 2026. No model hallucinated; the hallucination detector raised four false alarms. Opus needed fewer turns and about half the output, so it cost no more per listing than Sonnet. All listing agents moved to Opus.

Every check has to prove it can fail

A guardian blocks a deploy when an invariant breaks. Each one ships with a perturbation mode that breaks the protected thing on purpose and confirms the guardian turns red: mutation testing, aimed at the detectors.

Running them was the hard part. On 30 August, 50 of 75 guardians ran nowhere and none ran in CI. Deploys took over two hours, although only 3 of 18 failures in 30 days were real defects. Now CI runs 15 guardians on every branch, deploys gate on 58 plus 50 perturbation runs, all of them run each morning (301 on 13 September), and new failures reach the first message of each Claude session.

Feature chips and description from an early listing page: chips for easy access, surveillance, outstanding cleanliness, covered and 24 hours, above a description about free Wi-Fi, a buffet breakfast and a cosy bar.
An early listing page (1 June 2026): the description is about a hotel, not the car park. In September the “Limpieza destacada” (outstanding cleanliness) label turned out to be printed on 3,016 listings by a template bug.

Rule 0: fix a defect where it is born, not where it is seen

Written on 9 September, after 2,339 listings had been reviewed on more than one day because nobody closed the flag. A wrong listing is a sample of a mechanism.

  1. 01

    Measure the mechanism, not the example

    What else passes through this function, column or table?

    3,016 listings shared one wrong chip.

  2. 02

    Fix what is already published

    Chips regenerate; written prose must be rewritten.

  3. 03

    Find the origin, with file and line

    Ingestion, template, agent, script or brief.

    460 duplicate reviews came from two ingestion paths.

  4. 04

    Close the door

    Constraints and validation, so bad data cannot return.

    One database trigger instead of eight patches.

  5. 05

    Leave a guardian that can fail

    And ask why an existing one stayed green.

    One passed for a week reading empty folders.

  6. 06

    Close the flag and check production

    Then write the lesson next to the failing line, with its number.

I tested my own knowledge base. It changed nothing

The project keeps about 7,400 short lessons and a search tool over them. I built a test bench to see whether the tool helped debugging agents: the same tasks with and without it, graded against written answers, over four rounds and 16 tasks with Sonnet 5 and Opus 5.

It changed zero answers and saved no more tokens than the control group; 96% of the lessons came from files the agents could already grep. Only a researched expert brief changed results, at 21–40% more tokens. Agents asked once, in two to six words, so the tool now splits each question into seven searches itself.

Most rules have an incident behind them

  1. 26 Jun

    An uncapped Google sync

    Paid batches are now estimated, approved and logged.

  2. 8 Jul

    A host-side rebuild overwrote production

    Deploys now stop if the host rebuilt on its own.

  3. 30 Jul

    A paid area listed as free for 25 days

    Its owner caught it. Five of six failures were in the code around the agent, not the prompt.

  4. 3–15 Aug

    Six dev servers, then eight agents at once

    The first crashed the Claude app at 97% RAM. Both now have a cap of three, written in CLAUDE.md.

  5. 12 Aug

    A batch applied straight to production

    216 listings of work lost. Workflows now write to the bridge first.

  6. 30 Aug

    Five self-audits

    Among the findings: a Next.js advisory (CVSS 9.5) missed for five days, since patched.

What holds, and what is still open

Holding up

  • Model choice by measurement.
  • Paid calls behind approval and a per-call log.
  • Deploys gated by self-testing guardians.

Still open

  • No proof that newer agent versions rank better: three analyses disagreed on the sign because the queue was ordered by traffic. The next campaign needs a control group reserved up front.
  • Flagging is not fixing: on 2 September, 96.5% of 9,020 agent flags were pending; on 15 September, 15,384 of 22,044 were open.
  • Accuracy debt: 183 listings showed an airport price from Faro, Portugal (fixed in the bridge on 18 September, not yet live); 397 place IDs were shared by 879 listings (31 August).
  • Thin data: the median listing has one of nine own data fields (30 August).
  • Seasonality: demand for “dónde aparcar” fell 39% from mid-August to early September.

Next case study

Moduly Homes: an AI-built catalog that has to prove its numbers

Get in touch

Working on something similar? I am happy to compare notes.