Rework rate: the missing fifth key
Every one of the four keys treats a change that undoes a previous change as progress. Under the ADLC that is the single most expensive blind spot in the set.
Here is a hypothetical week, and I want you to hold it in mind for the rest of this piece.
A team merges thirty pull requests. Eleven of them implement new behaviour. Six of them fix problems introduced by the other five earlier the same week. Four of them modify code merged in the previous nine days, not to extend it but because it was not what the requester meant. Three are reverts. The remaining six are dependency bumps and test additions.
Every DORA metric this team has is excellent. Thirty merges is a strong deployment frequency. Cycle time is short, because small changes review quickly. Change failure rate is three over thirty, which is ten percent, and if you count only user-visible incidents it is lower still. Time to restore is fine.
The team delivered eleven changes worth of forward motion for thirty changes worth of effort and cost. That ratio is the most important fact about their week and not one of the four keys can see it.
Why this is new
Rework is not a new phenomenon. Software teams have always built the wrong thing and rebuilt it. What is new is the ratio at which it can happen without anyone feeling it.
Under the old model, rework was self-limiting because it hurt. If a developer spent three days building something and then had to rebuild it, they knew. Their manager knew, because the ticket did not move. The pain was proportional to the waste and it arrived immediately, which meant the organisation had a natural feedback loop pushing it toward getting requirements right the first time. Nobody had to measure rework, because everybody could feel it.
Agentic development severs the link between waste and pain. Rebuilding something costs an agent twenty minutes and costs a human one review cycle. It does not hurt. So the feedback loop that used to cap rework is gone, and the natural equilibrium moves to a much higher level of it.
Rework used to be self-limiting
- Three days spent, then rebuilt
- The developer knew
- The manager knew, the ticket sat there
- It hurt, so it corrected itself
Now it looks like productivity
- Twenty minutes and one review cycle
- Nobody feels it
- Each rebuild is a merge
- Each merge improves the numbers
Worse, rework now looks like productivity. Each rebuild is a merge. Each merge improves your metrics. A team thrashing around an unclear requirement will post better numbers than a team that stopped, thought hard, wrote precise criteria and built it once.
That is the definition of a metric set pointing the wrong way, and it is why I think some measure of rework belongs alongside the original four rather than in a footnote.
30 merges in the week11 new behaviour 6 fixing problems from earlier the same week 4 modifying code merged in the last ten days because the requirement was misread 9 ordinary maintenance
DORA reading: deployment frequency strong cycle time short, failure rate 3/30 Actual: 11 changes of forward motion for 30 changes of cost
What counts as rework
The definitional work here matters, because the concept is easy to state and hard to operationalise without either capturing everything or capturing nothing.
I would separate four categories.
Reverts. A change is undone. Unambiguous, visible in the repository, easy to count. It is also the narrowest category and the one teams increasingly avoid in favour of patching forward, which means a revert-only measure will systematically undercount and will get worse over time as teams get better at rolling forward.
Corrective follow-ups. A change lands, and within a short window another change modifies substantially the same lines for the purpose of fixing rather than extending. This is where most rework actually lives. It is detectable from the change record by looking at the interval between successive changes to the same region, and it requires a judgement about intent that the raw data does not contain.
Specification rework. A change lands, is reviewed by whoever asked for it, and is rejected or substantially amended because it does not match what they meant. This is the most expensive category and the least visible in source control, because it often shows up as a perfectly ordinary follow-up pull request with no marker distinguishing it from planned iteration. Catching it means capturing something at acceptance time.
Churn without outcome. Code written and then deleted before anything ever reached users. Common with agents, because exploring three approaches is cheap. Frequently this is good, it is thinking made visible, and counting it as waste would punish exactly the exploratory behaviour that agents make affordable for the first time.
Any usable rework metric has to take a position on which of these it counts. The fourth category should probably be excluded outright. The first is easy and insufficient. The second is where the value is. The third is where the money is and requires a human to record something.
The measurement I would actually build
Given all that, here is the shape I think holds up.
Take a window, say two weeks. For each merge, ask whether it substantially modifies code that was itself merged within a recent recency window, say ten days, and whether the modification reads as corrective rather than additive. Sum those, divide by total merges. That is your rework rate.
The recency window is the crucial parameter and it does most of the work. Modifying code from a year ago is maintenance, which is the job. Modifying code from last Tuesday is usually either rework or genuinely iterative delivery, and separating those two is where judgement enters. The recency window is what makes the metric about the current cycle rather than about the codebase’s whole history.
Two properties matter about the result.
First, it should be reported as a trend rather than a level. The absolute value of rework rate is close to meaningless, because it depends entirely on how you drew the categories above and on the nature of the codebase. What matters is whether it is rising as throughput rises. A team whose merges doubled and whose rework rate held steady genuinely doubled its output. A team whose merges doubled and whose rework rate also doubled did not increase output at all, it just spent more.
Second, it should be decomposed by cause where possible. Rework tracing to unclear acceptance criteria is a specification problem and the fix is upstream. Rework tracing to changes that broke something is a quality problem and the fix is in review and testing. Rework tracing to changed priorities is not a defect at all, it is the business changing its mind, which is allowed. A single undifferentiated rework number will get read as “engineering is sloppy” when the cause is frequently upstream of engineering entirely.
Why it belongs beside the four, not inside them
There is an argument that rework should just be folded into change failure rate, since both are about changes that did not work out. I do not think that holds.
Change failure rate is about harm reaching users. Rework is about effort not reaching users. They are different failures with different fixes: change failure rate is improved by testing, staged rollout and review; rework is improved by specification, prioritisation and acceptance discipline. A team can have an excellent change failure rate and a terrible rework rate, and that combination has a specific meaning: you are very good at not breaking things and very bad at knowing what to build. That is an extremely common state and it deserves its own number.
There is also a structural argument. The four keys measure the delivery system. Rework measures the coupling between the delivery system and the intent that drives it. Under the ADLC that coupling is precisely what got weaker, so a metric that sits across it is measuring the thing that changed.
What a rising rework rate is telling you
Almost always, one of three things.
Acceptance criteria are too loose. The most common cause by a distance. An agent builds the literal text. Loose text produces plausible-but-wrong output, which produces a correction cycle, which produces rework. The fix is upstream and it is unglamorous: writing criteria precise enough that a literal reader gets it right. Teams resist this because it feels like waterfall. It is not waterfall, it is the interface contract for a builder that has no context and no taste.
Review is rubber-stamping. If problems that should be caught in review are being caught in production or at acceptance, you will see it as corrective follow-ups. This usually means review capacity has been overwhelmed by volume, which is a squeeze I described in the previous piece and which nothing except reducing volume or adding reviewers actually fixes.
Priorities are unstable. Work is being started before it is decided. This produces rework that is not engineering’s fault at all, and it is worth separating out explicitly, because otherwise engineering gets blamed for the cost of decisions made elsewhere.
The reason to measure is not to know the number. It is that a rising trend forces the question of which of those three you are in, and all three are fixable once named.
Where this breaks down
More than usual, so let me be thorough.
The gaming is easy and obvious. If rework rate becomes a target, teams will stop reverting and start patching forward, will bundle corrections into larger changes so they read as new work, and will avoid touching recently merged code until the recency window expires. Every one of those behaviours is worse than the behaviour it replaces. This is the strongest argument against ever putting rework rate on a performance dashboard, and I would rather it be a diagnostic a team runs for itself than a number reported upward.
The corrective-versus-additive judgement is genuinely hard. Distinguishing “fixing what I got wrong” from “building the next increment” is a semantic call about intent, and the change record does not contain intent. Any automated classification will be wrong a meaningful fraction of the time. That is survivable for a trend and fatal for a level, which is another reason to report only the trend.
Iterative delivery looks identical to rework. A team practising genuine incremental delivery, shipping a thin slice and improving it based on feedback, will produce exactly the pattern I described as rework: repeated modification of recently merged code. That is not waste, it is the healthiest way to build software, and a naive rework metric will condemn it. This is the deepest problem with the whole concept, and I do not have a clean solution. The only real separator is whether the successive changes were planned or corrective, and that distinction lives in someone’s head unless the team writes it down.
Exploratory work gets punished. Agents make it cheap to try three approaches and keep one. Counting the two discarded approaches as rework discourages precisely the exploration that has become affordable, and exploration is often the highest-value thing a team can do. I excluded the churn-without-outcome category for this reason, but the boundary is fuzzy and any implementation will catch some exploration in its net.
The whole idea assumes rework is bad. Mostly it is. But a team with zero rework is probably building only what it is completely certain about, which usually means building only what is safe and obvious. Some rework is the price of ambition, and a target of zero would select for timidity. The interesting question is never “is there rework” but “is rework growing faster than output.”
The takeaway
The four keys treat every merge as progress, which was harmless when a merge was expensive and is actively misleading when it is cheap. A team can double its throughput, improve every DORA number and deliver no more than it did before, and rework is the term that explains the difference.
Measure it as corrective modification of recently merged code, report the trend rather than the level, decompose it by cause, and keep it well away from anything that looks like a performance target. Then read it as a question rather than a verdict: are criteria too loose, is review overwhelmed, or are priorities unstable.
The next piece goes after the first of those causes directly, and makes the case for definition-of-done adherence as a metric you can actually compute per change.