US election data · a standing, dated exercise
Our predictions as of 2026-09-21, using Hypercane and Backdoor, are that the following will occur in the 11 2026 Senate races with real polling right now.
Not a poll average and not a risk score on its own — an actual call on each race, dated, so it can be scored later against what happens. This is not the pre-registered call: that one freezes its spec on October 20 and its call on November 2. This is separate, and it is meant to be wrong sometimes.
Phase 3 of this project’s upset research found a real weakness in Hypercane, the model that scores how likely the polls have named the wrong winner: it shrinks a poll margin toward the state’s lean, and that shrinkage actively misleads on ground that votes against a large lean. The open question then was whether to change the registered model over it. This does not change Hypercane — instead a second, separately named model, Backdoor, runs Hypercane’s exact method with that one shrinkage step switched off once a state’s lean clears 10 points. Backtested walk-forward, on the same discipline as Hypercane itself, before a single live number was trusted:
| Ground | Hypercane AUC | Backdoor AUC | Backdoor − Hypercane | 95% CI |
|---|---|---|---|---|
| Ground that votes against a 10+ point leann=163, 23 poll misses among them | 0.488 | 0.791 | +0.303 | [+0.247, +0.365] |
| Ground that votes with its leann=1,238, 140 poll misses among them | 0.919 | 0.879 | -0.040 | [-0.052, -0.030] |
Both intervals clear zero. Backdoor is a real, large improvement exactly where it was built to help, and a real, small cost everywhere else — which is why the table below uses each model only where the backtest validates it, never picks whichever number is smaller.
It is tempting to read Hypercane’s lean-shrinkage as correcting for polls that failed to account for a state’s partisan history — a state votes against its lean, the reasoning goes, because the polls missed something the lean would have caught. The data says close to the opposite.
On the 443 races in that census where the state’s result actually matched its lean, shrinkage earns its keep: Hypercane scores 0.968 AUC there, because a surprising poll number in that setting usually is noise, and pulling it back toward the lean is the right call. That is most of why Hypercane works.
But on the 77 races where the result genuinely broke against the lean — including the narrower “hostile” slice, a lean of 10+ points, that Backdoor specifically targets — the polls had usually already got it right, not wrong. On hostile ground alone, the poll average named the eventual winner in 52 of the 65 polled cases, even though that winner was bucking the state’s history. Of the 13 misses there, 10 still had the poll average within 3 points. In the cited cases with a documented cause — Begich–Stevens 2008, a conviction 8 days before the vote; Tester–Burns 2006; and others — most already showed the eventual winner ahead in polling before the vote, because a favorite damaged in public gets damaged before pollsters ever call. Hypercane’s AUC falls to 0.642 on the full lean-breaking group precisely because shrinkage discounts that already-correct signal in favor of a strong historical prior. Backdoor turns shrinkage off past a 10-point lean for this reason: not to fix a polling failure, but to stop the model from overruling polls that were right.
Every Senate race with real general-election polling today. The call is simply the poll average’s sign — nothing here claims to know a direction the polls do not already show. The risk column is the useful part: how much to trust that call, from whichever model this project’s own backtesting says is right for that race’s ground.
| Race | Poll average | State lean | On hostile ground? | Risk the polls are wrong |
|---|---|---|---|---|
| OH D20 polls all-time — fewer than 3 in the last 30 days | +1.25 | R+11.25 | Yes | 0.289Backdoor |
| IA D6 polls in the last 30 days | +1.33 | R+12.54 | Yes | 0.276Backdoor |
| NH D19 polls all-time — fewer than 3 in the last 30 days | +2.68 | D+3.65 | — | 0.154Hypercane |
| TX D5 polls in the last 30 days | +2.84 | R+11.28 | Yes | 0.139Backdoor |
| MI D5 polls in the last 30 days | +3.60 | R+0.82 | — | 0.137Hypercane |
| AK D21 polls all-time — fewer than 3 in the last 30 days | +3.05 | R+13.62 | Yes | 0.129Backdoor |
| ME D8 polls all-time — fewer than 3 in the last 30 days | +3.25 | D+6.25 | — | 0.117Hypercane |
| KS R5 polls all-time — fewer than 3 in the last 30 days | -2.00 | R+17.21 | — | 0.113Hypercane |
| GA D11 polls all-time — fewer than 3 in the last 30 days | +5.82 | R+2.49 | — | 0.080Hypercane |
| NC D32 polls all-time — fewer than 3 in the last 30 days | +8.88 | R+3.83 | — | 0.045Hypercane |
| KY R1 poll all-time — fewer than 3 in the last 30 days | -11.00 | R+30.23 | — | 0.020Hypercane |
Ohio carries the highest risk on the board: Sherrod Brown polls ahead in a state that voted for Trump by 11 points, and that gap is exactly the shape of ground where this project’s own model has a documented, tested weak spot. On all four hostile-ground races, raw Hypercane and the validated Backdoor score disagree by more than double — Hypercane alone would have overstated the risk in every one of them.
The recency window is a choice, not a law — a race can move materially between two snapshots a month apart, and that is what a dated call is for, not a flaw in it. A settled matchup can become unsettled (Georgia goes to a December 1 runoff without a majority). Backdoor’s backtest, however real, rests on 23 upsets on the hostile-ground side; the direction is solid, the exact size of the gain is not pinned to the decimal. And this is 11 of 35 Senate seats — the rest have no general-election polling yet, and nothing here says anything about them.
Polling from Wikipedia’s per-race articles, with an explicit,
dated, cited nominee list per state rather than automatic detection — a data
error found building this snapshot (two states carried a candidate no longer in the
race) is written up in full in docs/CALLS_2026.md. Every run of
src/calls_2026.py writes its own dated file under
data/calls/ and never overwrites an earlier one.
Built 2026-09-25 from data/calls/2026-09-21.json by
src/calls_2026.py. Not the pre-registered call.