WritingCohereCoherepublished Jun 25, 2026seen Jun 26

Automating Fork Maintenance With Ai Agents

Open original ↗

Captured source

source ↗
published Jun 25, 2026seen Jun 26captured Jun 28http 200method plain

Automating fork maintenance with AI agents | Cohere North Mini Code. Cohere's first model for developers. Learn more

Jun 25, 2026

10 minute read

Automating fork maintenance with AI agents

You maintain a fork. Upstream moves. You sync, things break, you fix them, you verify, you ship. A few weeks later, upstream moves again. The cycle repeats.

This post describes a general method for automating that cycle using AI coding agents. We apply it to our fork of vLLM, walking through a concrete case where a routine upstream release silently broke Cohere's cohere-transcribe-03-2026 ASR model on our fork, with the fix flowing back upstream as a vLLM PR.

In practice, this approach has compressed the time to absorb a new upstream release from weeks to days , with humans only reviewing the outcome. The skills powering this workflow are open-sourced at cohere-ai/vllm-skills . The problem Maintaining a long-lived fork of an actively developed project is a recurring cost. But upstream releases also carry features, performance improvements, and bug fixes that you want. Staying in sync is not just maintenance, it's how the fork keeps getting better. The problem is that every upstream release also introduces a disturbance : merge conflicts, changed APIs, removed functions, new dependencies, or broken tests. The fork maintainer's job is to absorb that disturbance and restore a working state.

The structure of this work is always the same:

Sync the new upstream version into the fork. Measure by running tests, benchmarks, evals to see what broke. Fix conflicts, adapt to API changes, update tests. Repeat steps 2 to 3 until everything passes. Ship the updated fork.

This is a feedback loop. It already exists in every team that maintains a fork; it's just slow and manual. For our vLLM fork, absorbing a typical upstream release used to take weeks of intermittent developer attention, and the goal of the work described below is to bring that down to days of mostly unattended agent time. Feedback systems In control theory, a closed-loop system continuously compares its output to a reference and adjusts to close the gap. But real systems also face disturbances : external inputs that push the system away from its desired state. r(t) is the reference, the desired value that the system should produce. y(t) is the output, the actual value that the system produces. e(t) is the error, the gap between reference and measurement, computed as r(t) − measured_output. d(t) is a disturbance, an external force acting on the system that pushes the output away from the reference.

The controller uses the error to adjust the system; the feedback brings output closer to the target. A well-designed feedback loop doesn't just track the reference; it rejects disturbances by detecting their effect on the output and driving the error back toward zero without manual intervention.

Cruise control is the textbook example. You set a desired speed (reference), the car maintains it (system), but a hill or headwind appears (disturbance). A good controller notices the speed drop and adjusts throttle automatically. Fork maintenance has exactly the same structure. Control theory Fork maintenance

r(t), reference Custom changes working correctly on the latest upstream

d(t), disturbance New upstream release: conflicts, API changes, breaking changes

Controller Resolve conflicts, update patches, fix tests

System The fork itself (code, tests, CI)

y(t), output Runtime behavior of the fork after syncing

Measurement Test suite, benchmarks, evals

e(t), error Delta between expected behavior and actual post-sync behavior

The goal is to automate the entire loop — sync, measure, fix, repeat — so we can absorb upstream improvements with minimal human intervention. Our pre-agent process There are several ways to sync a fork with upstream: merge , cherry-pick , and rebase are the most common. Merge preserves both histories, but produces a tangled commit graph that makes it hard to tell custom changes from upstream. Cherry-pick gives precise control, but doesn't scale when upstream moves hundreds of commits per release; you end up maintaining a growing list of picks that drifts out of sync. Rebase replays your custom commits on top of the new upstream tag, producing a clean, linear history where your patches sit clearly on top. The tradeoff is that rebase rewrites history and forces a force-push, but for a fork with a small number of custom commits on top of a fast-moving upstream, the clarity is worth it.

At Cohere, we settled on rebase early on. Before the agent-based workflow described below, our pipeline already mixed scripted automation with manual work.

Rebase: A GitHub Actions workflow attempts the rebase onto a target upstream tag, replaying previously-seen conflict resolutions from a shared git rerere cache. Resolve conflicts: When the workflow's automated rebase fails, a developer picks up locally, resolves the remaining conflicts by hand (often with an LLM assistant), verifies CI, and uploads the updated rerere cache. Verify and ship: Once CI is green on the rebased branch, it becomes the new base for the fork.

This process already combines several kinds of automation: git rerere replays known resolutions, GitHub Actions runs the rebase attempt and CI, and LLMs assist with individual coding and debugging tasks. But the human is still part of the controller, stitching the pieces together, choosing which fixes to apply, and deciding when to re-run. The feedback loop works; it just turns slowly. The agent-based workflow described below keeps the same structure, but lets an agent play the controller role, so iterations happen at machine speed and humans only intervene at the edges. Automating each component This method decomposes the loop into three, agent-automatable components. Each maps to a piece of the control diagram. 1. Disturbance injection An agent skill detects and applies new upstream releases. It rebases the fork onto the new tag and resolves merge conflicts automatically. This is the disturbance entering the system: a deliberate, automated action that we know will temporarily break things, but that we want to absorb as quickly as possible.

The skill needs to: Detect which upstream tag the fork is currently based on Check whether a newer tag exists Perform git rebase --onto with the fork's custom commits Resolve conflicts (using upstream diff context to make informed...

Excerpt shown — open the source for the full document.

Notability

notability 6.0/10

Substantive research post on AI for code maintenance.