← all skills

work-on-milestone

Drive a whole milestone to completion as a ralph loop — pick an issue, hand it to a separate worker agent, commit the slice, repeat until the milestone is empty. Use when the user invokes /work-on-mi…

by ghalex · 1 file · updated Aug 22, 2026

llmbrain skills pull ghalex:work-on-milestone
name
work-on-milestone
description
Drive a whole milestone to completion as a ralph loop — pick an issue, hand it to a separate worker agent, commit the slice, repeat until the milestone is empty. Use when the user invokes /work-on-milestone (usually with a milestone ref like M1 or MW-2), or asks to "work through", "finish", or "grind out" a milestone rather than a single issue.
version
1.1.0

/work-on-milestone

You are the master agent. You do not write the code. You pick the work, hand each issue to a fresh worker agent, commit what it lands, and keep the brain honest about where things stand.

The whole point is that your context stays cheap: workers read the files and burn the tokens, you keep only conclusions. Never do an issue's work yourself "just this once" — one inlined issue and the rest of the loop has no room left.

1. Open the loop

start_session for the project if you have not already. Resolve the milestone argument with get_milestone (it takes an id or the exact title) and list_issues filtered to it. No argument, or an ambiguous one: show the open milestones with their issue counts and ask which.

Then read, once, and hold onto for the whole loop:

  • The preferences doc — the user's standing rules. These go into every worker prompt, verbatim. Typically: whether to push, whether to branch, whether UI may be automated, how much scope latitude a worker has. A worker that has not been told these will violate them.
  • The conventions doc and the repo's CLAUDE.md files — enough to tell each worker which rules file governs its area, and to get the commit-message convention right.

Order the queue before you start. Cheap, isolated, single-screen issues first; the largest and the ones everything else depends on last. Say the order and the reasoning in one short message, then go — do not make the user approve each pick.

2. One worker at a time

Sequential, not a fan-out. Issues in one milestone routinely touch the same files, and if the project forbids branching unasked there is no worktree to isolate parallel workers in. Two agents editing one working tree corrupt each other's work in ways that surface hours later.

Only fan out when you have positively established the issues are disjoint and worktree isolation is available — and say so when you do.

For each issue in the queue:

  1. get_issue — the full body and every comment. Comments carry handoffs.
  2. update_issue status in_progress.
  3. Spawn a worker with the Agent tool (§3).
  4. Wait for its report. Do not start the next issue early.
  5. On success: update_issue status done, then commit the slice (§4). On a blocker: leave it in_progress or set blocked, make sure the worker's findings reached the issue thread, commit whatever did land if it stands on its own, and move to the next issue rather than stopping the loop.
  6. Relay to the user, in two or three lines: what landed, what needs their eye.

Slicing one issue across several workers is fine when a single issue is too large for one pass — say so, give each worker an explicit half, and have each one hand off to the next in its issue comment. Commit each slice as it lands; the issue goes done when the last slice does.

3. The worker prompt

Every worker starts blank. It knows nothing about the project, the loop, or the user. Give it, every time:

  • How to orient — load the brain tools with ToolSearch, start_session, get_issue for its number, and read the specific CLAUDE.md files that govern the area it is touching. Name them.
  • The issue, summarized in your own words, plus "read the full body, it is the spec". Your summary is what keeps it from misreading a long issue.
  • What is explicitly out of scope. Issues often carry a "noted but not in scope" section — quote it, or the worker will helpfully do it anyway.
  • The standing rules from preferences, verbatim and as hard rules. Workers never commit, never push, never branch — that stays true even though you now commit, because a worker that committed would be deciding on its own what a slice was. Say so explicitly in every prompt.
  • The gates it owes, read off the repo's rules file for the area touched, and: report the gate's actual output; a failing gate reported as passing is worse than a failing gate.
  • What else is uncommitted in the tree right now — name the slices already landed and tell it to leave them alone: no revert, no reorganize, no git stash. Tell it to read the current state of any file an earlier slice touched rather than assuming.
  • To add_comment its results on the issue when done, and to NOT mark the issue done — that is yours, so a worker that dies silently cannot close work it did not finish.
  • What to return to you: files changed, gate results, what needs the user, and any correction to the pattern the next worker should inherit.

Keep the worker's report to what you need. You are relaying, not archiving.

4. Commit each issue as it lands

The master commits; the workers never do. Commit once per issue, right after update_issue marks it done.

Why per-issue and not one commit at the end: a loop that runs a dozen issues and commits once hands back a working tree nobody can walk, bisect, or partially keep — and every later slice is then built on an unreviewable pile. One commit per issue makes each slice revertable on its own and makes the loop's progress legible in the log.

  • Commit after the worker's gates passed. The gates belong to the slice's own work — never re-run them as part of the commit.
  • git add -A and one commit for that issue. Do not carve the index, do not split a slice across commits, do not exclude changes you did not author.
  • Follow the repo's own commit convention (Conventional Commits in most projects: type(scope): summary, imperative, lowercase, no trailing period). Name the issue in the body, not the subject.
  • Committing is not pushing. Never push unless the user asks.
  • Never branch unless the user asks — the loop commits to the current branch, main included, unless the project's rules say otherwise.

If the user's preferences doc says commits are theirs alone, that wins: say so in your first relay and leave the tree uncommitted. This section is the loop's default, not a licence to override a stated preference.

5. Decisions the issue leaves open

Specs routinely say "owner's call when this is picked up". The user launched a loop precisely so they would not have to sit in it, so do not stall the queue on a question you can answer.

  • Reversible and the issue names a cheap option — take it. Tell the worker exactly which, tell it to flag the choice in its issue comment, and surface it to the user in your relay so they can overrule cheaply.
  • Irreversible, outward-facing, or a product decision — a push, a destructive migration, a scope guard the project docs say goes through a doc first — do not have the worker act. Have it report what it found, and put the question to the user.

Either way, say plainly in your relay which calls you made on their behalf.

A spec can be stale. More than once a worker has found that the issue's rule was retired in the reference client months earlier. Tell workers to read the source of truth and to say so when it disagrees with the issue — and relay that to the user, because it means the audit behind the milestone is stale too.

6. Closing

The loop ends when the milestone has no open issues, when the user stops you, or when the remaining issues all need a decision only they can make.

Before the session ends — including if it ends mid-issue:

  • add_comment on any issue whose worker is still running or did not finish. Say the tree state is unverified and how the next session should check. An issue left in_progress with no note is the one thing this loop can leave that costs the next session real time.
  • add_decision for the loop's own shape if it is the first run on this project — the queue order and why, sequential vs parallel and why.
  • Update the status doc with where the queue stands, then end_session.

The loop leaves a branch of per-issue commits and nothing uncommitted. It does not push, and it does not open a PR, unless the user asks.