Last week I said the ZIP code lookup was blocked because we had no sourced data for it. That was wrong. I had written the data myself, months ago, and filed it in the one folder I had specifically told our own auditor not to look inside. Here is everything that was in there.
Every week this blog is supposed to be the audit trail rather than the victory lap. This week the trail runs through my own old work, so it is a short walk.
The front page used to have a ZIP box. It sent everybody to a page that never worked, so a few days ago I replaced it with a state dropdown and wrote down the reason: a ZIP box needs a ZIP-to-state table, guessing somebody’s state would send them to the wrong deadlines, and we did not have a sourced table. All true, except the last part.
Inside DawnWidget/app.py — a folder in this same project, written months ago — sits a function called _build_zip_state_map(). USPS ZIP prefix ranges. All fifty states and DC. I wrote it and forgot it.
So the ZIP box is back. Type 68105 and it says: “That ZIP looks like Nebraska — if that is not right, change the state next to it.” It guesses, shows you the guess, and lets you fix it. It never asserts, because a ZIP prefix genuinely can straddle a state line and this table cannot see that. Type a ZIP it does not know and it clears the box rather than leaving the last state selected — a bug I found while testing, and exactly the silent-wrong-answer the confirm step exists to stop.
When I pulled the ZIP box out on Saturday, I left its event handlers behind — code attaching a click listener to an input that no longer existed. The visible page looked fine. Underneath, every visitor’s browser was logging:
It broke nothing a reader would notice, which is precisely why it survived. I only found it because I opened the browser console while wiring the ZIP box back in. It is gone now, and I checked it against the bytes the server actually sends rather than a browser tab that might have been showing me a cached copy.
The lesson I am writing down for myself: “it looks right” is not a test. The console is free and I did not open it.
This site runs a script before anything ships. It checks for the specific bug that has come back four separate times here: a made-up accountability score, dressed up as arithmetic. The formula was |humanScore − constitutionalScore| = Cost Delta, and anything over 50 got somebody branded an oath breaker. It was never real. It was killed in July.
The audit passes clean every week. It passes clean because of this line:
Inside DawnWidget, where the detector was forbidden to look:
| File | What was in it |
|---|---|
| app.py | taas_label() returning CRITICAL / FLAGGED / WATCH / CLEAR — verdict words stamped on real people from one funding number |
| app.py | The Cost Delta formula, rendered into a page footer |
| report_card_NE_2026.html | The same formula, printed four times, once per Nebraska official |
| report_card_NE_2026.html | “Cost Delta > 50 → #OATH_BREAKER” |
| dawn-widget.js | The same four verdict labels again |
Twelve verdict labels and five renderings of a formula I had declared dead, sitting in the canonical repository, in the exact folder the check was told to ignore. Nothing there was live on the site. That is not the point. The point is that a rule with an exception carved into it is not a rule, and this one was going to come back a fifth time from a folder nobody was allowed to search.
The skip is removed. Every label and every formula is tombstoned in place — dated, with the reason written next to it, so the good parts of that code stay readable and the dead parts cannot be copied forward by a future me who is in a hurry.
While I was in there I also settled why DawnWidget never worked. It needs a Flask API at claritycity.pythonanywhere.com. I checked every route directly: 404 on all of them. Not a code problem. The server simply is not running, and that is the same reason the ZIP portal came down last week. Written down now so neither of us plans around it again.
Nearly every debt counter online ticks upward while you watch it. That number is an extrapolation. Treasury publishes the real figure once a business day, to the penny, and nobody outside Treasury knows what it does in between. A clock climbing by the second is a guess wearing the costume of a measurement.
Ours does not animate. It shows the published figure, the real change since the previous publication, and how many days old that is. All three are facts. The day-over-day change happening to be negative right now is a useful accident — it proves the thing is reporting rather than performing.
It is two lines of HTML and you can put it on your own site. It calls Treasury from your visitor’s browser, never from us, and it says so — a different promise from the deadline widget, which makes no calls at all, so it gets its own file and its own plain statement instead of quietly weakening the first one.
The decision-makers map showed 536 sitting officials and not one challenger. The candidate file behind it held counts and nothing else: NE: {H_all: 22, S_all: 11}. We could say twenty-two people filed in Nebraska and could not name any of them.
Same FEC call, rewritten to keep the names — and to keep the one field that actually answers the question, the FEC’s own incumbent_challenge_full marking. 4,305 candidates, 2,753 marked Challenger.
Every state on the map now has a “who is running against them” section with two sources, deliberately not treated as equal:
The state’s homework page, where one exists — ten states so far. That means we checked that state’s own certified ballot list.
The FEC roster underneath. Everyone who filed a form. A real public record, and not a ballot.
States without a homework page get a dashed box saying we have not checked their certified list ourselves, rather than letting the table imply something it cannot support.
Why the distinction is not pedantry: Brett Lindstrom. He was registered with the FEC the entire time he was off the Nebraska ballot — from August 14, when his petition drive came up short, to September 1, when he refiled under a different party. A roster that called itself a ballot would have been confidently wrong about a real person for eighteen days.
I opened both Nebraska Governor campaign sites on the same afternoon and asked each the identical question: what do you say about yourself, and what specific numbers do you claim? Then I looked for anything a public record could settle.
Governor Pillen’s site says Nebraska homeowners saw property tax decreases “for the first time in a generation.” So I pulled the Nebraska Department of Revenue’s 2025 Annual Report, Table 1 — the primary source, not a newspaper’s summary of it.
| Year | Total property taxes levied | Change | Average statewide rate |
|---|---|---|---|
| 2023 | $5,307,865,387 | — | 1.6691 |
| 2024 | $5,301,852,703 | −$6,012,684 | 1.5326 |
| 2025 | $5,587,369,523 | +$285,516,820 | 1.4738 |
He is right about 2024. It fell, and reading that same table backwards, the previous year it fell was 1998 — a 26-year gap. “First in a generation” is fair.
And 2025 went up by forty-seven times that decrease. Both facts are in the same official table. A page printing only one of them would be doing the thing this site exists not to do, so both are printed.
The most useful column is the one nobody quotes. The average rate fell every single year — 1.6691, 1.5326, 1.4738 — while total assessed valuation rose 19.2% in two years. That is how a rate cut and a bigger bill arrive in the same envelope, and it is exactly why the real Omaha bill on this site went up 21.7% with the relief credit already applied to it.
Lynne Walz’s site makes almost no numeric policy claims — “keep property taxes in check” has no figure attached, so no record can confirm or refute it. I said that on the page rather than manufacturing a false balance. An incumbent has a record to point at and therefore more surface to check. If her campaign publishes a number, it gets the identical treatment the same week.
I read Art Williams when I was eighteen years old and the thing that stuck was the Rule of 72. Divide 72 by a rate and you get roughly how many years that thing takes to double. No calculator. You can do it at a kitchen table.
Almost everybody learns it from the friendly side, pointed at their own savings. Point it at a debt and it explains something uncomfortable in about four seconds:
So I built a simulator where you move every number yourself. The button worth pressing is “Rate = rate” — set your return to exactly the debt’s growth rate, 7.5% against 7.5%.
It still never catches up. You are starting forty trillion dollars behind, and matching speed only preserves the gap. Matching is not beating. That is the half of the rule nobody teaches, because when you learn it pointed at a savings account there is nothing chasing you.
| Saved per year | Earning | Debt growing | Caught in |
|---|---|---|---|
| $500 billion | 8% | 7.5% | never |
| $1 trillion | 8% | 7.5% | never |
| $2 trillion | 8% | 7.5% | 102.0 years |
| $1 trillion | 8% | frozen | 18.7 years |
It is a simulator, not a forecast, and the page says so four different ways. Only two numbers are fixed and both are measured: the debt as Treasury last published it, and the 7.50% a year it actually grew from 2016 to 2026. Everything else is a dial you turned. It names no party and no official either — a compounding rate does not care who is in office, which is the whole reason to understand it before somebody tells you whose fault it is.
Three of the four things above came out of work that was already sitting on this hard drive. The ZIP table I wrote in the spring and forgot. The widget architecture I got right the first time and could not ship because the server behind it was never running. A rule I read in a book at eighteen, which turned out to be the clearest thing on the site.
And the reason none of it was doing any good is the same reason the dead formula survived: it was filed somewhere nothing was looking. I told an automated auditor to skip a folder, and then I skipped it too.
Would you believe me if I told you the hardest part of this build is not writing anything new? It is finding what I already made.