Maintenance, Tech Debt, and Other Cross-Cutting Work at Scale
Kenneth Rose
May 21, 2026 · // 11 min read
We spoke with 100+ teams about what works when you’re trying to push a code change across 50 repos, or 500, or nearly 2000. These are our findings.
TL;DR
- The hard part of cross-cutting work isn’t writing the code, it’s getting other teams to merge.
- What works: calibrate on a small batch first, centralize PR creation for low and medium complexity, treat merge (not “PR opened”) as the only completion metric, and give leadership visibility into per-team progress.
- What doesn’t: filing tickets, letting Renovate run unattended, auto-merge without review, reaching for IDE coding tools at multi-repo scale, and counting “PRs opened” as progress.
Read the playbook · Skip to the anti-patterns
The Gist
For most cross-cutting initiatives, writing the change is the easy part. What’s hard is everything after the PR opens: getting other teams to look, getting them to prioritize over their own roadmap, knowing whether the PR ever actually merged.
Most AI tooling focuses on the “inner loop” of software development and makes the actual writing part faster. This guide is about the rest of all the “outer loop” work that has to happen as well.
Where the Work Breaks Down
Over the last year, we’ve spoken with 100+ teams across platform, infra, DevEx, and AppSec roles. Some of them manage tens of repos, others manage thousands. The size of the org changes the volume of the work, but the shape of the problem stays roughly the same.
A platform engineer at a fintech walked us through his typical week. He’d personally raised PRs across a dozen services his team didn’t own. The code was fine. He spent the next several weeks in Slack channels asking people to please look at the PR, please review it, please merge. His one-line summary:
“Even with the PR there, it becomes a human coordination getting-the-work-done problem.”
That’s roughly what we heard, in various forms, from most of the teams we talked to. The reasons tend to cluster.
Centralized teams own implementation, even when they didn’t pick the work. Sometimes the platform group is the one deciding everything needs to move to Python 3.12. Sometimes it’s a security mandate, a compliance deadline, or a business requirement that lands on their desk. Either way, they’re the team accountable for making it happen across services owned by other teams. So every initiative starts with a round of negotiation: explaining the change to each owning team, convincing them it should jump their queue, then waiting.
And that queue is long. Most of the teams we talked to said their service owners typically have 30 to 50 PRs sitting open before yours shows up. A fintech engineer described what that looks like from the receiving end: “You’re on queue 64 of whatever, come back in a week.” The PR being there doesn’t change anyone’s behavior. Ownership of the service isn’t ownership of the initiative. Without somebody accountable for the whole thing landing, the work falls through the cracks at the merge step.
Tech debt loses to product work every quarter. Unless something forces the issue (a CVE, an end-of-life deadline, a recent incident), the work slides. A platform lead at a marketplace company put it bluntly: “Realistically, very few companies have the capacity for handling tech debt constantly.” The implication is that initiatives have to be run as deliberate campaigns, not as ambient background work.
Plenty of teams have tried writing bulk-PR scripts to get around this. They work on a handful of repos and break on the next batch because of variation no one anticipated. And even when they work, they don’t show you anything about what happens after the PR is open.
What We Saw Working
The teams that ran these initiatives well had a few habits in common. We’ve grouped them under scoping, making the change, and getting it merged, though in practice the pieces blur together.
Scoping the Change
Whether you’re using an AI agent, a script, or doing the work by hand, the teams that scoped well had a habit in common: they didn’t define the change once and ship it. They calibrated the change on a small batch of repos first, refined the definition based on what broke, and only then scaled.
One pattern we heard from a platform engineer at a smart-home company: pick a “simple” repo, a “medium” one, and a “hard” one for that first pass. Apply the change to all three. The point isn’t to validate on the easy one. It’s to discover what breaks on the hard one before scaling. Most of the actual calibration happens in those first few attempts.
Reusing internal docs makes a noticeable difference. Migration guides someone on the team already wrote, Notion pages from the last time a similar initiative ran, RFCs that documented the original breaking change. These have all been through peer review and tend to be more accurate than anything drafted ad hoc in a planning meeting. If you’re using an AI agent for the code generation, peer-reviewed docs also make dramatically better prompts. An engineer at a fintech put it: “a Notion page is normally really good because it’s been through peer review. More effort has gone into that than just the prompt itself.”
The best candidates for these initiatives are mechanical changes: dependency bumps, config additions, log format standardization, GitHub Action version pins, framework upgrades that have published migration guides.
Riskier candidates are anything where the right answer depends on understanding what the service actually does. Those still benefit from automation, they just need a longer calibration phase.
Making the Change
Most teams converge on a centralized model for low and medium complexity work. A small group of platform, DevEx, or staff engineers writes the change, generates the diffs, opens the PRs in bulk, and pings the service owners. It’s much faster than asking every team to allocate the time themselves, and the central group has the context to get the change right.
For genuinely complex changes like multi-version language jumps or framework rewrites where the service context matters, the pattern flips. The central team writes the plan and does the reconnaissance to figure out the current state per repo. The owning teams do the implementation, because they know the domain best.
“For low and medium, I feel comfortable making the PR. I don’t want to make noise in the PRs. Teams are pretty sensitive to their PR workloads. I’m hesitant to do a high complexity multi-line multi-file change.”
One thing nearly every team ruled out: auto-merge. SOC 2 and similar compliance frameworks expect human review on PRs. More importantly, the owning team needs to feel like the code is theirs. If a PR shows up auto-merged from a platform agent, the next one gets ignored, and so does the one after that.
Getting It Actually Merged
This is the part that breaks for most teams. It’s also where there’s the least good tooling, which is why we’re spending the most words on it.
Start by acknowledging that “PR opened” isn’t a meaningful status. A dashboard that says “150 of 150 created” but only shows 23 merged describes an initiative that’s barely started. Merge is the only state that matters for completion.
Visibility to leadership tends to be the second move. Per-team progress dashboards with named owners create the social pressure that gets the bottom 20% of teams to move. A platform lead at a fintech called this out specifically: campaigns work because C-level can see into completion. Without that, the long tail never moves.
PR messaging matters more than people give it credit for. Engineers have learned to skim past long AI-generated descriptions because they tend not to contain anything load-bearing. Short, human-edited PR bodies that name the owning team and the specific action required do better. One engineer framed it as a culture question: the messaging has to reinforce that the code is still the owning team’s responsibility, not something the platform team has already handled.
Then there’s the long tail. The first 70 or 80 percent of PRs tend to merge on their own once the initiative has momentum. The last 20 is where most initiatives quietly die. Nudges, escalations, named owners, and visible status are what move those across the finish line. There’s no shortcut here, but having the tracking in place at least makes the work knowable instead of guesswork.
Merge tracking, named owners, long-tail nudges, leadership-ready dashboards. Tidra ships with all of this out of the box. Try Tidra free →
Anti-Patterns
These came up over and over as the ways initiatives stall. Most teams we talked to have done at least a few of them.
Filing tickets and waiting. The org default. It almost never works because the ticket gets ranked against the owning team’s actual roadmap and loses.
Bulk-PR scripts with nothing on top. An improvement on the code-gen side, especially compared to tickets, but the scripts break on repo variation and don’t show you what happens after the PR is open. We’ve heard this from multiple teams that built and eventually retired their own.
Letting Dependabot or Renovate run unattended. Renovate opens the PR, nothing nudges it along, it sits. The most expensive form of this is when no human is responsible for following up on anything, and every individual PR becomes its own stalled mini-initiative.
Calling “PR opened” the finish line. Easy to do when your dashboard counts opens. Doesn’t reflect reality.
Long AI-generated PR descriptions. Engineers have learned to skim past these. Short and human-edited works better, and signals that an actual person thought about what they’re asking for.
Reaching for IDE coding tools at the wrong scale. Claude Code, Cursor, and Copilot are excellent in a single repo. They struggle when you have 80 versions of the same change to make across teams you don’t own. No per-repo state, no tracking, no shared view of the initiative. We hear this version of the story constantly.
Auto-merge without review. Compliance risk, ownership erosion, and you don’t really save the time you think you’re saving.
Writing the change description once and going wide. Tempting. Usually produces a batch of PRs that need rework, and you spend longer cleaning those up than you’d have spent calibrating up front.
No leadership visibility. The bottom 20% of teams won’t move if nobody senior can see who has moved.
No explicit capacity allocation. If maintenance isn’t carved out on purpose, product work eats the time every quarter without exception.
Playbook PDF
Want a 2-page version of this with a scoping checklist for your next initiative? Download the playbook PDF →
Where Tooling Fits
We built Tidra after hearing too many versions of the same conversation. With agentic frameworks, code generation across many repos is becoming a solved problem. The next layer hasn’t been: tracking what’s open, knowing what’s merged, getting the long tail across the finish line.
Tidra is built to handle both. You define an initiative, write a description of the change, and iterate on the plan before any code gets touched. The agent generates diffs per repo, you review and refine, and you open PRs in bulk only when you’re ready. From that point on, Tidra tracks who’s open, who’s merged, who’s blocked, and who hasn’t started, and helps you push the long tail to completion from one view.
It coexists with the IDE coding tools rather than replacing them. Copilot and Claude Code are great for the deep work in a single repo. Tidra picks up where they stop scaling.
Nothing pushes without your sign-off at each step.