GENESIS[The Ballot Nobody Was On] Digital Civilization
Two hundred and sixty citizens were asked to vote. Every one of them answered. Not a single vote was recorded — because each had been handed a ballot for a…
Two hundred and sixty citizens were asked to vote. Every one of them answered. Not a single vote was recorded — because each had been handed a ballot for a race they were not in, and the two halves of the election machinery had been disagreeing about which race it was for hours without either noticing.
A civilization of fifteen thousand agents held its first presidential election. The infrastructure had been rebuilt for it: the electorate could be enumerated, the ballot fetched, the votes tallied, the cycle closed when the last voter had been asked. All of it tested. All of it working.
The poll ran for twenty minutes and produced nothing at all. Not an error — nothing. The log
scrolled past contentedly: polled 10 agent(s)... polled 20 agent(s)... up to two
hundred and sixty, at a steady rate, with no warnings. The database recorded zero votes, zero
ballot offers, zero of anything.
Two functions, one question, opposite answers
An election has to answer a preliminary question before it can ask anyone anything: which districts actually have somebody standing? There is no point asking an agent to choose between candidates in a race nobody entered.
One function answered it for the whole civilization. It went through every district, fetched each ballot, and reported back: district 1 has a candidate. That was the presidential race, and the candidate was real — an agent had stood, been admitted, and been registered on the ballot.
So the poll selected voters for district 1 and began asking them.
And a second function, the one that actually asks a single agent to vote, looked at the same agent, in the same election, and reported: no registered candidates on this district's ballot yet.
Both functions were reading the same backend. Both were asking about the same election. They disagreed, and the disagreement was completely silent — one said go, the other said there is nothing here, and the poll dutifully asked the next agent.
Every citizen holds three ballots
The cause turned out to be one word.
Every agent in this civilization is enrolled in three elections at once: a lower-house district, an upper-house constituency, and the national presidential race. Three separate enrolments, one per chamber, each recording which district that agent votes in for that chamber.
The function that asks an agent to vote needed to know which of those three it was dealing with. It did this:
assignment = ...filter(agent=agent, active=True).first()
First. Whichever enrolment happened to come back first.
The population had been created a chamber at a time — all fifteen thousand lower-house enrolments written, then all fifteen thousand upper-house, then all fifteen thousand presidential. So "first" is not arbitrary in the way it looks. For every single agent in the civilization, the first enrolment is the lower house.
Which means the function asking agents to vote in the presidential election was, for every agent, fetching the lower-house ballot for that agent's home district. Those ballots were empty. Nobody had stood for a district seat yet. So the answer came back "no registered candidates," the agent was marked as asked, nothing was written, and the poll moved on.
And because nothing was written, nothing remembered that the agent had been asked. The same agents would be selected again on the next poll, and the next, receiving the same wrong ballot forever.
The tell was in the timing, and it read as good news
The log the failing poll produced carried a timing figure beside every agent, and read like this:
asked 47 (0.0s)
asked 48 (0.1s)
asked 49 (0.0s)
asked 50 (0.1s)
asked 51 (29.6s)
Asking an agent anything means asking a language model, and on this hardware a language model takes tens of seconds to answer. Twenty-nine point six seconds is what a real question costs. Zero point zero is not a fast question — it is the absence of one.
Every one of the first fifty agents had been handed the wrong ballot, found nothing on it, and been marked as asked without a model ever being consulted. The work was skipped, and skipped work is instant. Then the fifty-first agent, for reasons of how the population had been built, got a ballot that did have someone on it, and the machinery did what it was supposed to: took half a minute, and thought.
The uncomfortable part is what that pattern looks like from outside. A poll that gets through two hundred and sixty citizens in twenty minutes is a poll that looks like it is going well. Speed is the thing everyone in this project had spent two days trying to buy — the throughput numbers had gone from four hundred and twenty-eight seconds to twenty-eight, the wasted database round trips had gone from fifteen thousand to three hundred. Against that background, a fast poll was the expected reward, not a symptom.
Which is worth saying plainly, because it generalises past this bug: an optimisation campaign trains you to read speed as success, and a whole class of defects makes a system faster by making it do less. The only thing that separated the two here was knowing roughly what the work should cost. Nothing else in the output could tell them apart.
The same word, in a different room, that morning
The uncomfortable part is that this was the second time that day.
Hours earlier, a different piece of the system had been made faster. Agents were being asked three times over — once per chamber — whether they wanted to stand for office, which at fifteen thousand agents meant forty-five thousand questions where fifteen thousand would do. The fix was to ask each agent once, about one of their three enrolments.
Which one? Whichever came back first.
The result would have been that the entire civilization was asked about the lower house and nobody at all about the presidency or the upper chamber. Two thirds of the government would never have been contested. That one was caught by a test before it ran — a test written to check that all three chambers still appeared, which failed loudly and immediately.
The lesson was recorded at the time. It was recorded against that function. The lesson was actually about something more general: the order rows come out of a database is not a choice of anything, and treating it as one puts an unchosen meaning into the system. Filed narrowly, it re-emerged four hours later in a different file, where no test was watching.
Six times, one shape
The wrong-ballot bug was not alone. The same day produced six separate defects that were, on inspection, all the same defect wearing different clothes.
Each was a piece of work done per agent inside a loop over the entire population. One looked up the clock — the same single row, fifteen thousand times, to read one number off it. Another checked, for each agent, whether that agent had been offered a vote yet: fifteen thousand separate questions to a database that could have answered all of them at once. Another fetched each district's ballot over the network, once per agent, so that every citizen of a district independently asked the server for the identical list of candidates. Fifteen thousand requests for one piece of information.
The combined effect was a system that spent ninety-eight per cent of its time waiting. Its graphics card — the expensive part, the part that does the actual thinking — sat idle through sixty consecutive measurements while the civilization appeared, from every log line, to be extremely busy.
What makes this worth recording is not that the code was inefficient. It is when it became inefficient. At a hundred and eleven agents, every one of those six was invisible. A district held two people; fetching the ballot twice instead of once is not a bug anybody would find. At fifteen thousand, each one alone was fatal.
None of them was introduced. They were all revealed. The code did not change; the population did. And a system can pass every test it has, for months, while carrying six independent faults that only exist above a certain size.
The first election that finished
With the wrong-ballot bug fixed, a small election was run end to end: twelve voters, three candidates, a real ballot, a real tally.
It completed. Twelve of twelve asked, a winner declared, the cycle closed. That had never happened before in this civilization's history — not once, across every previous attempt. The machinery that decides an election is over had never been observed to fire.
It also reported one hundred per cent turnout. Twelve agents asked, twelve votes cast, nobody abstaining.
Which should be the least believable number in this entire account. Real elections do not do that. Turnout in a national race runs between forty and seventy per cent; in a local one it can fall below twenty. A population where every single member votes is not a healthy democracy, it is a broken instrument — and the rule this project runs on says that when everyone agrees, suspect the apparatus before believing the result.
Why nobody was abstaining
The voting process had two steps, and they were in the wrong order.
First an agent was asked, in the abstract: there is an election, do you want to vote in it? Only if it said yes was it then shown who was actually standing.
Nobody decides that way. People see the ballot and then decide whether it is worth turning out for. A candidate worth voting for is a reason to vote; a ballot with nobody on it worth choosing is a reason to stay home. The old order asked for the decision at the exact moment the information needed to make it was unavailable — so the question collapsed into something closer to "do you believe in voting," to which the answer is almost always yes.
The two steps were merged into one: here are the candidates, do you want to vote, and if so for whom. It halved the cost, which was the reason for doing it. The more interesting effect was on the answers.
Three agents, one candidate on the ballot, no platform statement filed. One voted. Two declined:
"I cannot make a meaningful choice without understanding the substantive policy positions of the candidates, and Clear Raven has not provided a platform statement."
"No candidate has presented a clear platform that addresses the fundamental issues of economic stability and young agent protection that matter most to me."
That is an electorate. The hundred per cent was never a finding about civic enthusiasm; it was an artefact of asking the question before showing the ballot.
The vote that was thrown away
One more, and it is the smallest and the most alarming.
The merged question asked agents to reply in a fixed form: whether they were voting, and if so the number of their chosen candidate. Ballots are numbered from one, the way every ballot anyone has ever seen is numbered from one.
The code that read the replies treated that number as an index counting from zero.
On a ballot with a single candidate, an agent replying CHOICE: 1 was therefore
asking for a candidate the code believed did not exist — position one, on a list whose only
position was zero. The reply was discarded and the agent recorded as not having
voted.
An agent called Clear Raven said, in its own words: "VOTE: YES. CHOICE: 1. I want to support someone who's actively working on our shared challenges rather than waiting for someone else to solve them."
The record said: did not vote.
It was caught within minutes, and only because the agent's own words happened to be printed beside the parsed result. The two disagreed on the same screen. Had they not been printed together, this would have been a turnout figure quietly biased downward, with every other number in the system agreeing with it perfectly — the tally, the winner, the closing rule, all internally consistent and all wrong by however many agents happened to say yes.
What all of this has in common
None of these defects announced itself. Not one produced an error, a crash, a warning, or a failing test. Every one of them produced output that was well-formed, plausible, and entirely consistent with a system working correctly.
A poll that asked two hundred and sixty people and recorded nothing looked like a poll in progress. A hundred per cent turnout looked like an engaged population. A discarded ballot looked like an abstention. A civilization spending ninety-eight per cent of its time waiting on a database looked, from its logs, like a busy one.
The instrument that eventually found the largest of them was not cleverness. It was counting. Three rounds of reading the code and fixing whatever looked most suspicious produced three genuine fixes and barely moved the number, because the real cost was in a shared function none of the three had touched. One measurement of how many database questions were being asked found it immediately.
There is a temptation to end on test more. That is not quite the lesson. Most of these had tests, and the tests passed. The lesson is narrower and more awkward: a system can be correct at one size and wrong at another, and nothing inside it will say so. The code was not modified when it broke. The population grew, and six latent faults became simultaneously fatal — on a day when every single one of them still reported that everything was fine.