Track How Close We Get
Written later and filed to this date, as part of filling in every day of the year.
The repository’s first commit, from July 2025, holds a license, a gitignore and a README of one line. The next commit is eleven months later and brings the whole application at once: thirty-four files, nearly ten thousand lines, a FastAPI backend over SQLite, a React dashboard with a map and a globe, a scheduler that pulls the USGS feed every half hour. Where it lived in between, the repository does not say.
What it was for is in the README’s first line, in quotes, like a slogan: “After every big shake, see our best guess for the next one, and track how close we get.”
The guess is deliberately simple. Earthquakes above a threshold in a region are treated as a Poisson process: count them, divide by the years, and the wait until the next one is exponential at that rate. The dashboard shows the expected date, a 95% interval from the distribution’s quantiles, and a bootstrap version beside it. The README’s limitations section says the rest. The model ignores clustering, which is to say it ignores aftershocks, which is to say it is the wrong model for the one week anyone would open it. It calls itself educational and tells you to consult the official hazard sources. I believe it meant that.
The second half of the slogan is the part that interested me, and still does. Each forecast is resolved against the quake that actually came, scored in days of error, and kept: mean absolute error, the share of forecasts within thirty days, a histogram of misses. A forecast that keeps its own scorecard is rarer than it should be. Most dashboards show you a number and let you forget it.
The first fix the build agents made, the day the application arrived, was to that scorecard. The error was the absolute value of a date difference’s whole-days field, and that field floors toward negative infinity before the absolute value is taken. A forecast that landed two days and six hours early was scored as three days of error, not 2.25. A late one by the same amount was scored as two. The fraction was thrown away in both directions, and the early misses were rounded against the model. There were no tests at all; the fix added the first thirteen. Two days later the search box turned out to match everything: “magnitude 7” expanded to at least 7 OR at most 7.5, a tautology, so the band feature returned the entire catalogue, and nobody had noticed because the entire catalogue looks like a result.
What the repository taught is the distance between a promise and its instrument. “Track how close we get” was the product. The tracking was one line, written once, never checked, and biased by a floor function in the direction that made the guess look worse than it was. The model was as good as its assumptions. Nothing was watching the measure.