Runs a huge, mechanical refactor (crate or package splits, module extraction, API migrations, dead-code removal) as three independent lanes, producer, packager and shepherd, that coordinate only through git and a PR stack. It pushes branches and opens PRs, so it runs only on `/lever refactor` or an explicit ask ("split this crate", "break up this monolith", "this module is huge, cut it down", "migrate every caller").
npx skills add https://github.com/github/lever --skill refactor-pipeline
Some refactors matter a lot and nobody wants to do them: splitting a crate that has grown to half a million lines, extracting modules, migrating every caller of an API. The work is mechanical but long. It's too big to review as one PR, and too tedious to babysit for a week.
This skill runs it as three lanes that never talk to each other. Each lane has one job and its own cadence. Git is the message bus, and the PR stack is the shared state.
PRODUCER ──push every commit──▶ source branch ──▶ PACKAGER ──adds PRs──▶ PR stack ◀── SHEPHERD
(one split per commit, (rebase, test, (conflicts, CI,
reports vs a fixed baseline) reviewable PRs) review threads)
▲ │
└──────── daily: rebase onto what landed, drop merged commits ◀─────────────┘
You set the target, merge what's green, and route context between lanes when one of them needs to know something the others learned. The lanes do the rest.
core by 50%", "no file in src/legacy imports old_client", or "zero callers of v1::fetch".Don't use it for:
brief and autonomous-delivery.find-the-loop and experiment-arms.pr-shepherd directly.Run each lane in its own session, such as its own Copilot CLI process, app session or cloud session. Separate processes keep their context small and let one lane die without taking the others down.
A long-running goal with a measurable target and a heartbeat. The whole kickoff fits in one paragraph. It needs one sentence each for:
| Part | Example |
|---|---|
| Target | "bring the non-test LoC of this crate down by 50%" |
| Unit of work | "one logical split per commit" |
| Baseline | "measure the baseline now" |
| Heartbeat | "report every 30 min against the goal, in absolute LoC and %" |
| Validation | "run the tests for the affected crates before each commit" |
| Constraint | "don't make other crates significantly bigger" |
Rules the producer must follow:
A scheduled lane that turns raw commits into a reviewable stack.
git patch-id --stable, or a Change-Id: trailer if the producer writes one. Every run starts with a diff: "Processed 8 new commits through 5bf1e1f", or "No new commits since d3137f5. Nothing to do." The second answer is silent.gh stack).A frequent lane that runs pr-shepherd across every PR in the stack.
main once the PRs below it merge. Verify with git merge-tree against the branch it will actually land on.resetAt on 403 or 429. In one run, this cut a shepherd cycle from 11 GraphQL requests to 3.steer-once.extract-projections, it has most of your work adapted to a later main" or "another job is adding PRs to this stack".Copilot CLI: one terminal per lane. Use /goal for the producer's target and /every for each lane's cadence, for example producer report /every 30m, packager /every 3h and shepherd /every 20m. Put the terminals on a machine that stays awake (a dev box or VM), not a laptop that sleeps.
Copilot app: one session per lane. /goal works the same way. There's no /every; give each lane a session automation with the same cadence and prompt instead. It wakes the same session, so the lane keeps its context and checkpoint between runs.
In the cloud: the packager and shepherd are good automate-it candidates. They are scheduled, bounded and repeatable. Keep the producer as a long-running session that you check in on.
| Dial | Default | Notes |
|---|---|---|
| target | required | metric + direction + amount, measured against a fixed baseline |
| pr_size | < 2,000 changed lines excluding moves | what your reviewers can actually read |
| cadence | producer report 30 m · packager 3 h · shepherd 20 m · producer rebase 24 h | each lane runs at the speed of what it watches |
| autonomy | shepherd L2 (keeps green, human merges) | see docs/autonomy.md |
| api_budget | ≤ 1 poll per PR per 10 min | shared across all lanes |
| spend | your tier and budget, from /lever | a multi-day run makes thousands of model calls; prompt caching matters a lot |
In one real five-day run on a ~564k-line Rust crate, three lanes made 135 splits and cut non-test LoC by about a third. 19 of 20 stacked PRs merged, and one of the slowest CI jobs got about 28% faster as a side effect. The human typed 38 messages, and scheduled runs fired 373 times. Most of those 38 messages were one-line corrections that the lanes wrote into their own standing orders, plus "why did you stop the schedule?"
Take github/refactor-pipeline from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.