Projects Burnout Tracker
Burnout Tracker
A burnout model built only from git commit timestamps: speed, revs, coolant, fuel. It's calibrated against one real burnout, in-sample, and the write-up is honest about that.
- Stack
- Python · GitHub API · Stream Deck

The short version
The tracker reads my own commit history to see whether the spring 2026 burnout showed up in it before it happened. It pulls commit timestamps from GitHub and turns them into four dials, on the model of a car dashboard. Speed is work per hour of work, rather than raw output. Revs is how hard the week ran, measured as engine-hours. Coolant is how well the week was paced. Fuel is what’s left, a reserve that drains when the other three run hot and refills when they don’t.
Backtested over 23 weeks, the fuel gauge dropped to 12 out of 100 in the week of 13 April. The crash weeks are 27 April to 10 May, so that reading came two to three weeks ahead of it. The dials render live onto Stream Deck keys on my desk.
The code is not published yet, so there is no code link on this page.
The caveat, up front. The constants were tuned on the same 23 weeks and the same single burnout they describe. This is a fit, not a forecast. One person, one event, no held-out data. I’d need a second period, ideally someone else’s, before saying it predicts anything.
How it works
The model has four dials, on the metaphor of a car dashboard, and each is a plain formula over commit data.
Speed is work per hour of work. Work is the sum of additions and deletions per commit, capped at 500 lines so one bulk or generated commit cannot dominate, divided by engine-hours. It measures how fast I was actually moving, not how much I produced. 600 work per hour maps to 0, and 1450 maps to 100.
Revs is engine-hours per week, mapped as engine-hours divided by 72, times 100. Engine-hours come from clustering commit timestamps into sessions with a 90-minute gap and summing the session spans. That is the entire computation. The redline mark is 60 hours in a week; 72 hours was my highest week.
Coolant is pacing. It is 0.45 times the days since my last breather, plus 0.30 times a sleep proxy, plus 0.25 times an early-finish test. A breather is a day at or below my 25th-percentile output. The sleep proxy is the median overnight gap between the last commit of one day and the first of the next. Coolant’s only job is to knock up to 40 per cent off the overwork burn.
Fuel is the accumulator, and the dial in the chart. Each week, Fuel gains its recharge and loses its overwork and molasses drain, clamped to 0–100 and carried across the whole history. The overwork term is convex above 54 Revs, so a week of pushing barely costs anything while a redline week bites hard. Recharge is rest-only, and gated by how light the week actually was.
Two sources feed all of it. The GitHub contribution calendar gives daily counts, and the commit history gives timestamps with additions and deletions per repository. Both are account-wide, pulled through the API rather than from local clones. There is no manual logging, no self-report and no health device.
The first version got recovery wrong, and its constants are still in the repository, in gauge.py. That version recharged the tank with 100 × (1 − 0.55^days_off), which returned about 45 points for a single calendar day off. Almost every week slammed back towards full, and the tank read 96 through weeks that were plainly not fine. Three changes fixed it: an engine-hours rest factor, so easing off is not counted as resting; a finish-scaled first day off worth 20 to 33 points, plus a small concave bonus for further days, capping how much any single week can refill; and the convex overwork term, so redline weeks actually bite.
Fuel enters the empty zone at W16, the week of 13 April, reading 12 out of 100. The crash weeks are W18 and W19, 27 April to 10 May. That is two to three weeks of warning, depending on which week you call the crash.
The caveat holds. This is 23 weeks, one person and one event, with the constants tuned on the same data they describe and nothing held out.
The long version
This section is being written.