May 5, 20265 min

Building TN Election in Numbers with Claude Code

What worked, what needed a human, what almost shipped wrong


Building TN Election in Numbers with Claude Code

What worked, what needed a human, what almost shipped wrong

A short field report on building Tamil Nadu’s 2026 election dashboard with Claude Code — and on what an AI partner can and can’t do.

Some context. I spent a month building TN Election in Numbers — a Next.js dashboard tracking Tamil Nadu’s 2026 assembly election from February’s Special Intensive Revision (SIR) of the rolls, when 74 lakh names were struck, through to live counting-day results on May 4. The build partner was Claude Code (Opus 4.7). The repo is public.

The dashboard’s editorial spine, set five months before the result was known: the cleansed roll matters, and the cleansing will read in the ballot data. That thesis closed cleanly. In ACs where the SIR struck the most names, TVK won 77% of the time. In the least-cleansed ACs, 26%.

This article is about how the work is split between the model and me.

What the model was load-bearing for

The model was good at the parts of the work I’d describe as building the pipeline. Once a few sections existed in a consistent visual and editorial voice, it could spin up new sections in 5–10 minutes that snapped to the same rhythm without instruction. It wrote reproducible Python scrapers — knowing, for example, to shell out to curl instead of fighting urllib's TLS fingerprint when Akamai was blocking direct Python requests on ECI's endpoint. It cross-tabbed six data files into a flip matrix, turnout-shift quintiles, and per-bloc profiles in 25 minutes — work that would have taken me half a day in a notebook.

The single biggest moment was a stray path { stroke: none } in the inline <style> block of an Adobe Illustrator export of a Tamil Nadu state map. It had been silently breaking SVGs. The model walked the diagnostic chain methodically — reproduce in headless Chrome, isolate the SVG, grep the inline styles — and found it in 30 minutes. Solo, that was a multi-hour guessing game.

And on counting day itself, the model managed live ops for 16 hours: tailing the cron’s log, adjusting cadence when ECI started rate-limiting, retrying transient failures, and narrating the count: “10:51 IST · TVK 99 (+2) · NDA 75 (=) · SPA 37 (=). Pushed.” That kind of patient operational presence without losing the bigger picture is exactly what a junior reporter cycling between the wire and the editor’s desk would do.

Where I had to stay, load-bearing

Four moments. Each of these would have shipped wrong without me, and each points at something the model can’t be trusted to do alone.

Sanity-checking outputs against the world. The off-by-one is the headline example. The model can verify that the data is internally consistent. It cannot verify that a politician is the age I know him to be.

AI is good at building the pipeline, terrible at sanity-checking specific outputs against real-world facts.

Vetoing data that’s technically present but broken. MyNeta’s gender field looked usable. The model dutifully aggregated it and produced “24 women MLAs.” Spot-checks revealed all-male names tagged female across 23 ACs, with 210 ACs marked entirely male — binary-but-clustered, almost certainly a scraping artifact upstream. The fix wasn’t technical, it was editorial: don’t ship that number. We replaced it with a name-heuristic estimate of 21 women MLAs, carrying an explicit methodology disclaimer.

That should have been the end. It wasn’t. Weeks later I pasted a single URL — MyNeta’s separately-curated women-candidate listing, 442 contestants paginated across 23 pages. Cross-referencing every AC winner against that list gave the authoritative answer: 23 women MLAs, not 21. The heuristic had been wrong in both directions — men with feminine first names tagged female, women with unfamiliar first names tagged male. Even the cached file we’d named myneta_women.json turned out to be the full alphabetical candidate roll, misnamed months earlier under a wrong assumption.

AI defaults to “use the data we have”; humans have to enforce “no, that data is wrong” — and then keep looking until the right data turns up.

Setting boundaries. The model didn’t know which ECI URL pattern to use, or which seats were “marquee.” It didn’t know that NTK’s 2021 vote share (6.46%) lived in the ECI Statistical Report, not in any local data file. Once told, it built. But it doesn’t know to seek what it doesn’t know.

AI explores within boundaries; humans set the boundaries.

Optimising for reversibility. When the home page’s information architecture got messy, the model proposed a 4-act narrative restructure. I countered: first park the to-be-moved sections on a _/others_ route so we can rearrange later without losing them. Strictly the better move — lower-risk, reversible. The model would have gone straight to restructure.

AI optimises for completion; humans optimise for optionality and reversibility.

So, what’s the shape of the work now

The project shipped because both were necessary. The model was load-bearing on building the pipeline, on diagnosis, and on operational patience across a 16-hour day. I was load-bearing on sanity-checking specific outputs against the world, on vetoing data that was technically present but fundamentally broken, on setting boundaries within which the model could explore, and on protecting reversibility.

When people ask whether AI replaces the engineer or the journalist, the answer from this project is: it replaces neither, but it changes what the work is. My month of evenings became one person’s month instead of three people’s month. The off-by-one was caught not because I’m a careful programmer but because I knew who V. Senthilbalaji was.

The pipeline is cheap now. The judgment is what’s left.

Source: github.com/s1dd4rth/tamilnadu-elections-2026 ·

Live:

85.1% - Tamil Nadu's 2026 turnout, mapped constituency by constituencyTamil Nadu polled 85.1% on 23 April 2026 - the highest assembly-election turnout in modern memory. An editorial data…tn-dashboard-app.vercel.app

Originally published on Medium