Two hours and seventeen minutes, filed under maintenance, turned up two bugs that were about to ship broken. The job was supposed to be routine: 30 repos, fast-forward the stale base branches, delete dead leftover branches, close out the tickets sitting open against branches that no longer matched them.
Why 30 clones exist at all
The platform runs as one codebase cloned per deployment, 30 of them, each tracking its own base branch and its own set of open tickets. That model works until the clones drift. A branch gets created against the vmta-routing ticket, the ticket gets reassigned or closed elsewhere, and the branch just sits there, still open, still technically mergeable, no longer pointing at anything real. Multiply that by 30 repos and you get a pile of branches that look active in git branch -a but aren’t tied to anything a human is tracking.
The audit’s job was mechanical: walk all 30 clones, diff each base branch against its ticket’s current status, fast-forward the ones that were just behind, delete the ones that were dead, and flag the ones where the branch and the ticket disagreed about what was supposed to happen.
The first sweep deleted the wrong signal
The first pass at the cleanup script treated “branch behind base and ticket closed or reassigned” as the signal for delete. We ran the first sweep on that logic, and it flagged both the vmta-routing ticket and the push-guard ticket for deletion.
We caught it before the delete step ran, only because we diffed the flagged branches against develop by hand before letting the script execute. A dead branch’s diff comes back empty. These weren’t empty.
The vmta-routing ticket was sitting on a branch that looked stale by the ticket-tracking logic but was the only place the fix existed. The ticket metadata said “stale,” the code said “unmerged and needed.” Routing was picking the wrong vmta for a subset of outbound mail, silently, because nothing in the pipeline had exercised that path since whoever branched it. Had the script trusted the flag list, the fix would have vanished, and we wouldn’t have found out until the vmta routing bug resurfaced in a support ticket weeks later with no branch left to bisect from.
The push-guard ticket had the same shape: a fix that had stalled mid-flight, on a branch the naive drift check would have called dead, carrying a change nothing else had picked up. Both got merged and shipped live in the same pass instead of getting deleted as noise.
Most of the other flagged mismatches were what you’d expect: a branch for a ticket that had already merged somewhere else, safe to delete.
The second check
A branch can be stale by commit distance and still be the only copy of a real fix, if the ticket system and the branch went out of sync for reasons that have nothing to do with whether the code is needed. So the script got a second check before any delete: does this branch’s diff against its base contain anything not already present in develop. Stale-by-ticket-status and stale-by-content-diff turned out to be two different conditions, and only the second one is safe to act on.
What came out of it
Two live fixes (the vmta-routing ticket and the push-guard ticket), a follow-up ticket to revive the KB redirect-follow UI, and a tooling-gap ticket against the clone-cleanup scripts themselves. The diff-check wasn’t there when the audit started, and it needs to be permanent instead of something we remember to do by hand next time.
“Audit and clean up 30 clones” reads like busywork right up until the busywork surfaces a routing bug already live in production mail. The maintenance pass and the bug hunt were the same task, and the bugs surfaced only because the cleanup forced us to look at every branch instead of trusting what the ticket tracker said about it.
A closed or reassigned ticket does not show that its branch is safe to delete. In this audit, two branches that looked dead by ticket status were the only copies of live fixes. Before any branch cleanup, check whether the tooling diffs the branch against its base for content not already merged, and make that check permanent.