refactor-pipeline
Skill279 starsChanged 17 days agoMITView on GitHub
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").
In this repository15 other files it gives its agents.
- automate-itSkill
- autonomous-deliverySkill
- autonomy-dialSkill
- briefSkill
- cross-model-reviewSkill
- experiment-armsSkill
- find-the-loopSkill
- keep-the-pool-fullSkill
- landing-planSkill
- leverSkill
- progress-contractSkill
- prompt-mirrorSkill
- pr-shepherdSkill
- run-health-reviewSkill
- steer-onceSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 4 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 36
Run each lane in its own session, such as its own Copilot CLI process, app session or cloud session.
- Distinctive: line 53
The baseline never moves: After each daily rebase, report against the *original* baseline.
- Distinctive: line 54
Never manufacture progress: Don't delete, weaken or reclassify tests.
- Very specific: line 83
Corrections go into the standing order: When you correct a lane ("push immediately, *then* verify"), the lane rewrites its own recurring …
- Distinctive: line 112
Every correction you have to type twice is a missing rule.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
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.
When to use
- The target is measurable and mechanical, for example "cut non-test LoC of
coreby 50%", "no file insrc/legacyimportsold_client", or "zero callers ofv1::fetch". - The change splits naturally into many small, independently correct units.
- The result has to land as reviewable PRs, not one giant diff.
Don't use it for:
- A refactor that needs design decisions at every step. Use
briefandautonomous-delivery. - Making something measurably better, such as faster or less flaky. Use
find-the-loopandexperiment-arms. - A single PR that needs babysitting. Use
pr-shepherddirectly.
The three lanes
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.
1. Producer: does the work
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:
- Push after every commit. This one rule is what lets the packager consume work while the producer keeps going.
- The baseline never moves. After each daily rebase, report against the original baseline. No shifting the goalposts.
- Never manufacture progress. Don't delete, weaken or reclassify tests. Don't change what's counted. Don't leave backward-compatibility wrappers behind just to keep callers compiling.
- Move tests with the code. Move whole test modules and their fixtures to the new owner, not only the code under test.
- Daily rebase: rebase onto the latest landed state, drop commits that have already merged, and re-measure.
2. Packager: makes it reviewable
A scheduled lane that turns raw commits into a reviewable stack.
- Checkpoint, don't remember. Save the last source commit you processed, plus a stable identity for every commit you've packaged: its
git patch-id --stable, or aChange-Id:trailer if the producer writes one. Every run starts with a diff: "Processed 8 new commits through5bf1e1f", or "No new commits sinced3137f5. Nothing to do." The second answer is silent. - Reconcile after the producer's rebase. If the source branch moved non-fast-forward, the old checkpoint may not be an ancestor anymore, and packaged commits have new SHAs. Don't diff from the checkpoint. Match source commits to packaged ones by patch-id or Change-Id, skip what's already packaged, and package only the rest. A commit whose patch changed in the rebase gets flagged, not packaged twice.
- Rebase new commits onto the top of the stack, run the tests, and fold fixups into commits that aren't in a PR yet. The packager only appends PRs on top. It never rewrites a PR that's already in the stack.
- Size each PR for a human reviewer, for example under 2,000 changed lines, excluding pure moves. Add PRs to the stack with the repo's stacking tool (for example
gh stack). - Cadence follows batch size. Start at every few hours. If runs keep finding only a commit or two, slow it down.
3. Shepherd: keeps the stack mergeable
A frequent lane that runs pr-shepherd across every PR in the stack.
- Rediscover stack membership on every run. Another lane is adding PRs, and merges restack it.
- The shepherd is the only lane that rewrites the stack. Restacks, conflict rebases and fixups to PRs already in the stack all go through it. The packager sends it a note instead of pushing.
- Check mergeability against the real target. A stacked PR can say "no conflicts" against its stacked base and still conflict with
mainonce the PRs below it merge. Verify withgit merge-treeagainst the branch it will actually land on. - On conflict, push the rebase immediately, then verify. A stale PR that's waiting on local validation blocks everyone above it. CI on the pushed head is the real check.
- Stay armed, within budget. A green stack is a checkpoint, not a finish line. Keep going until the stack is merged, a human says stop, the budget runs out, or 6 ticks in a row did nothing. Then post one line saying which, and stop the schedule.
- Rerun a red check only after showing that the stack didn't cause it.
Shared rules
- One API budget. All three lanes poll the same GitHub quota. Gate each PR to at most one status poll per ~10 minutes, combine queries (one GraphQL call per stack, not one per check), and back off until
resetAton 403 or 429. In one run, this cut a shepherd cycle from 11 GraphQL requests to 3. - Merging is the human's call by default. The shepherd keeps PRs green and the human merges whenever they like. Raise the autonomy dial if you want the shepherd to land green PRs itself.
- Corrections go into the standing order. When you correct a lane ("push immediately, then verify"), the lane rewrites its own recurring prompt to include the rule, so you say it once. See
steer-once. - The human routes context. You're the only one who sees all three lanes. Tell a lane things like "rebase onto
extract-projections, it has most of your work adapted to a later main" or "another job is adding PRs to this stack".
Running it
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.
Dials
| 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 |
What good looks like
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?"
This skill's own feedback loop
- The producer's heartbeat is the loop. If the metric hasn't moved in three reports, stop and ask the human whether the target or the unit of work is wrong.
- Every correction you have to type twice is a missing rule. Add it to the lane's standing order and, if it's general, to this file.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

