How we think
The Quality Drawdown
Measure code quality like a portfolio: burn and replenish cycles, moving windows, and the golden/death cross - the data is already in your git log.

Every engineering organization has a repo that everyone hates working on, and nobody can say exactly why. Velocity feels fine on paper. Tickets close. But every change resists a little more than the last one, estimates drift upward, and the team's appetite for touching certain modules quietly disappears.
That repo is in a drawdown. It has been losing quality for months, and nobody measured it because nobody had a unit to measure it in.
Trading solved this problem decades ago. A trader doesn't ask "is my portfolio good?" - that question has no operational answer. A trader asks "how far am I below my last peak?" That number is the drawdown, and an entire discipline of risk management hangs off it: how deep you let it get, how expensive recovery becomes, and which signals tell you the regime has changed.
Code quality behaves the same way. You can measure it with data already sitting in your git history, and you can manage it with tools borrowed directly from trading.
Quality is a drawdown, not a score
Treat quality as a resource. It starts at a high water mark - the state of the codebase right after a stabilization or refactoring pass - and it draws down during feature development. Every feature lands a little debt: the shortcut taken to hit the date, the abstraction that almost fits, the third copy of a pattern that should have been extracted at the second.
None of this is visible in a single diff. It is entirely visible in aggregate, the same way no single losing trade defines a drawdown but the curve from peak to trough does.
The measurement question is not "how good is our code?" It is "how far are we below our last peak, and which direction are we moving?"
And here is the part that makes this practical rather than philosophical: the raw data already exists. Every commit and every PR in your history carries three numbers - lines added, lines removed, timestamp. That is enough to build the entire chart.
The add/remove ratio is the telemetry
The signal hiding in those numbers is the ratio of adds to removes.
- High-ratio PRs (3:1 and above) are burn events. Mostly new lines, few deletions. This is feature velocity - building, not reshaping. Each one pushes the drawdown deeper.
- Low-ratio PRs (under 2:1, with high absolute volume) are replenish events. High adds and high removes means code is being rewritten, consolidated, tightened. The drawdown recovers.
Burn magnitude is ratio times absolute volume. A 4:1 PR moving 8,000 absolute lines burns far more quality than a 4:1 PR moving 800. Both signal the same direction; one of them moves the needle twenty times harder.
Here is what this looks like in real data, from a client engineering team we advised, over roughly two and a half weeks of work:
| Period | Adds | Removes | Absolute | Ratio | Phase |
|---|---|---|---|---|---|
| Days 1–8 | +2,635 | -1,038 | 3,673 | 2.5:1 | Feature build |
| Days 1–8 | +4,271 | -1,328 | 5,599 | 3.2:1 | Feature build |
| Days 1–8 | +4,868 | -1,295 | 6,163 | 3.8:1 | Feature build |
| Days 1–8 | +6,858 | -1,420 | 8,278 | 4.8:1 | Feature build |
| Days 9–11 | +3,895 | -2,197 | 6,092 | 1.8:1 | Consolidation |
| Days 12–13 | +4,757 | -3,144 | 7,901 | 1.5:1 | Consolidation |
| Days 11–15 | +6,513 | -3,944 | 10,457 | 1.7:1 | Rework |
| Days 15–16 | +3,157 | -894 | 4,051 | 3.5:1 | New burn cycle |
Read the ratio column top to bottom and you are reading the drawdown chart: a burn phase climbing from 2.5:1 to 4.8:1, then the team felt the debt and the ratio dropped to 1.5–1.8:1 for a week of consolidation, then a fresh burn cycle started on the cleaned foundation at 3.5:1.
Notice what stayed constant: absolute volume. The consolidation PRs moved as many or more total lines than the feature PRs. The team did not slow down during cleanup - they worked just as hard in a different direction. This is the claim most worth arguing with: a low ratio with high absolute volume is not a productivity dip. It is the same engine in a different gear, and if your dashboards only track net lines or ticket throughput, you are misreading your best maintenance work as a slump.
You do not need a separate quality metric, a survey, or a static-analysis score. The ratio is the telemetry.
Recovery is asymmetric
Trading's most useful contribution to this model is the recovery math. Percentage losses and percentage gains are not symmetric - the deeper the drawdown, the disproportionately more it costs to get back to peak:
| Drawdown | Recovery needed |
|---|---|
| -10% | +11% to recover |
| -20% | +25% to recover |
| -40% | +67% to recover |
| -60% | +150% to recover |
The code translation is direct. At -10%, cleanup is a day or two - names, duplication, a couple of extractions. At -40%, you spend a week stabilizing what took two weeks to build, because the debt has compounded: features were built on top of the shortcuts, and unwinding them means touching everything above them. At -60%, you are seriously discussing a rewrite - and that is not weakness, that is the math. The recovery cost has exceeded the cost of a new position, which is exactly when a trader closes out rather than averaging down.
This asymmetry produces the single most actionable rule in the framework: five 10% recoveries are dramatically cheaper than one 50% recovery. Same total drawdown managed, completely different total cost. Frequent small stabilization passes are not overhead that interrupts roadmap work - they are the cheap end of a cost curve that gets exponentially worse the longer you defer.
Use moving windows, not cumulative scores
The instinct is to compute a quality score across the whole history of the repo. Resist it. A cumulative number over a three-year-old, 500,000-line repository tells you nothing - the codebase, the team, and the product were all different things six months ago, let alone three years ago.
Borrow the trader's answer: moving averages. Compute the add/remove ratio over rolling 30-day and 90-day windows. The window does not tell you a historical score; it tells you the current cadence:
- This sprint, this quarter - are we burning or replenishing?
- Is the pattern a sawtooth (regular burn and recovery) or monotonic (all burn, no recovery)?
- How far are we from our last replenish peak?
The window is also a planning instrument. If the last quarter was a heavy burn quarter, the next one needs replenishment budget - not as a nice-to-have, but because the asymmetric recovery table guarantees that stacking burn quarters escalates the eventual bill. You can defer the stabilization; you cannot defer the cost. The cost compounds while you wait.
The golden cross and the death cross
Traders compare a short moving average against a long one to detect regime changes. The same construction works on the ratio: plot the 30-day moving average against the 90-day.
The reading rules:
- 30-day below 90-day - the death cross. The team is burning quality faster than its own baseline. Debt is accumulating right now. Schedule stabilization.
- 30-day above 90-day - the golden cross. Replenishment relative to baseline. Recovery is underway.
- The gap between the lines is magnitude. A wide gap below means a deep, fast burn. A wide gap above means aggressive recovery.
As a leadership dashboard this is hard to beat: two lines. Short below long means trouble. Gap widening means act now. No interpretation meeting required.
What healthy looks like
- A sawtooth: regular, rhythmic burn/replenish cycles.
- Drawdowns stay shallow - in the -10% to -20% band, where recovery costs are still near-linear.
- Recoveries are quick: the golden cross follows the death cross within a sprint or two.
- The 30-day and 90-day lines stay close together, because the cadence never drifts far from baseline.
A healthy chart does not mean no burning. Burning is what shipping looks like. Healthy means the burns are deliberate, shallow, and paid back on a schedule.
What unhealthy looks like
- Monotonic decline: all burn, no recovery, sprint after sprint.
- Deep drawdowns - -40% and beyond - that demand multi-week stabilization efforts nobody budgeted for.
- A permanent death cross: the 30-day line lives below the 90-day line, which means the "baseline" itself is just a slower rate of decay.
This is the chart of that repo from the opening paragraph - the one everyone hates and nobody can explain. The explanation was in the git log the whole time. The team has been in an unmanaged drawdown for so long that working in the codebase means working at the bottom of a -50% hole, where the recovery table says the honest options are an expensive climb or a rewrite.
Run it on your own repo
Everything described here comes from git log --numstat: adds, removes, and timestamps per commit. An afternoon of scripting gets you the drawdown curve, the rolling ratios, and the crossover chart for any repository you can clone. Run it on your oldest repo and your newest one. The shape of the difference will tell you more about your engineering health than most of what is on your current dashboard - and you will be able to point at the exact week things turned.
One closing observation. Everything above applies to any engineering team and always has - burn and replenish cycles predate every tool in your stack. But AI-assisted development changes the timescale. A team whose developers moved 150 lines a day could run months between stabilization passes; the team in the data above was AI-augmented and sustained 3,000–4,000 absolute lines per developer per day, a burn rate of 10–20x. Same model, same math, compressed calendar. The chart makes the death cross visible: when AI tooling increases throughput without a shorter stabilization cadence to match, the curves cross. The ratio between the two is the thing worth tracking.
Don't take our word for it - ask ChatGPT what it thinks of this piece.


