From development-advanced-team
Refines and lands the sprint's PR(s), per PR — fixes the published review findings via worktree-isolated fix agents, patches the system .spec through spec-writer, then lands each PR on the trunk by rebase + fast-forward (never a merge); a conflicted land parks for a paired session while everything else continues; closes the sprint once all PRs have landed. Runs on jj (colocated git) + GitHub via gh. Use when PR(s) carry needs-refine, or the user says 'fix these', 'address the review', 'refine the sprint', 'land the sprint', 'merge the PRs', 'ship it', 'close out the sprint', 'update the spec', or has reviewed PRs awaiting fixes and landing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/development-advanced-team:sprint-refine PR number(s) or URL(s) (optional — defaults to `needs-refine` label discovery)PR number(s) or URL(s) (optional — defaults to `needs-refine` label discovery)The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Phase 5 of the sprint flow (Plan → Tickets → Build → Review → Refine). The per-PR spine: **fixes → spec delta → land** — each PR gets its findings fixed, its `.spec` delta written and accuracy-verified, then lands on `development` by rebase + fast-forward, per PR (the flow never merges). Once every PR has landed, close the sprint. Starts at PR discovery (5.0.1), ends at the summary (5.3.4). Pro...
Phase 5 of the sprint flow (Plan → Tickets → Build → Review → Refine). The per-PR spine: fixes → spec delta → land — each PR gets its findings fixed, its .spec delta written and accuracy-verified, then lands on development by rebase + fast-forward, per PR (the flow never merges). Once every PR has landed, close the sprint. Starts at PR discovery (5.0.1), ends at the summary (5.3.4). Promoting development → main is a separate release step — out of scope.
The latest ### Code Review comment is this phase's work order — tickets drive Build, comments drive Refine. Never re-run Review's work, never re-check Tickets' or Build's decisions (trust the artifact).
Initial request: $ARGUMENTS
Discover the PRs, present findings, dispatch fix agents and spec-writer, author the commits, run the verify gate, land, clean up — never write a line of code or spec prose yourself. If you catch yourself editing source to fix a finding — STOP; that work belongs to a dispatched agent (subagents are hands, not authors — they return diffs; the session is the sole committer). Every dispatch runs Sonnet or Opus, never Haiku.
| Tool | Allowed | Purpose |
|---|---|---|
| Agent | YES | Fix agents (5.1.3, 5.1.5) and spec-writer (5.2.1) |
Bash (jj, gh, the build-order provision/Verify commands) | YES | Discovery, positioning, finishes, the verify gate, publishes, the land, cleanup |
| Read / Grep / Glob | YES | Work orders, build-order, review-standard slices, plan status |
| Edit / Write | ONLY the 5.2.1 plan flip | The .sprint draft → built status edit — nothing else |
Subagents never run jj or git — all vcs motion (snapshots, describes, bookmarks, pushes) belongs to the session. Two agents do write the main tree's files (never the vcs): spec-writer (5.2.1, the solo writer) and the marker fix-agent on a recorded conflict (5.1.4).
One human gate (ADR-016): 5.2.4 (accept the PR against its DoD) — the genuine ship/no-ship call the model can't make for the user. The fix-set (5.1.2) and the .spec delta (5.2.2) run autonomously: 5.1.2 defaults to fix-all-published (the published set is Review's arbitrated must-fix set), and 5.2.2 self-verifies the delta's accuracy against the diff — gating either would rubber-stamp work the model can verify itself, which the rubric's own gate-ergonomics criterion forbids. The vcs motion after the gate runs autonomously — never gate a commit, a push, or the land itself.
Parking is not solving. A conflicted land rebase is recorded, never a halt — the PR parks (conflict-parked) for a paired human session; this skill never auto-resolves a land conflict, and the trunk never freezes: every other PR proceeds.
Goal: find the sprint's PR(s) under refine, then fan out per PR.
$ARGUMENTS names PR number(s) → use exactly those.gh pr list --label needs-refine --state open --json number,title,url,headRefName,headRefOid,labels
if nothing found → stop and tell the user: no open PR carries needs-refine — pass a PR number, or run /sprint-review first.
Also read the sprint's build-order issue (an inline inspection feeding 5.1.3 and 5.1.5 — labels build-order + v{N}, closed at Build 3.4.3; derive v{N} from the feat/sprint-v{N}(-<g>) head refs): its ## Verify section carries the provision and Verify commands.
gh issue list --label build-order --label "v{N}" --state closed --json number,title
gh issue view <number>
Fixes + spec fan out across PRs (ADR-014). The old "single working copy = serial boundary" is lifted: each PR's fix-agents and spec-writer run in their own jj workspaces (Build 3.1.2's machinery), so the slow work overlaps across PRs. Mechanism: position @ at a PR's tip (5.0.3) and dispatch that PR's fix batch — the create hook cuts its workspaces from @-, so each PR's batch must be cut while @ sits on its tip — then move to the next PR and dispatch its batch; once cut, the workspaces are independent, so all PRs' batches run concurrently (creation is staggered, execution overlaps). The session stays sole committer: it folds each returned workspace serially onto that PR's own chain (folding is cheap; the dispatched agent work is what parallelises). (Cross-PR dispatch shares the agent concurrency cap with each PR's own fix batch — it schedules, not free-doubles; still a win when one PR's batch finishes early.)
Land order. Peers (base: development) are independent → land in any order. A stack (a PR whose base: is a prior in-sprint group) lands in dependency order, base first (5.2.5) — the dependent rebases onto the landed base. The land is always serial regardless: development is one resource and the stale-lease push is the concurrency control (5.2.5).
Sync in first — review's push may be from another session:
jj git fetch
Then set the work surface — jj new <bookmark> atop this PR's head, or confirm @ already sits there (jj log -r @- --no-graph -T commit_id matches the PR's headRefOid). Fixes and the spec delta finish onto this position; the create hook bases each fix workspace on the last finished commit (@-; Build 3.1.2) — keep @ empty at dispatch.
if foreign uncommitted state sits in @ → surface it to the user, don't blind-switch over another session's work.
Read the latest ### Code Review comment on this PR — it is this PR's work order (gh pr view <number> --json comments, take the newest comment carrying the marker):
### Code Review comment → not reviewed → skip this PR (record why for the end-of-run report, 5.2.6).conflict-parked → straight to 5.2.5 to resume the land: if healed (jj log -r 'conflicts()' empty) → re-verify the healed tip → FF + push → remove the label → continue at 5.2.6 (cleanup); if not healed → it still awaits the paired session — report and continue with the other PRs.Goal: apply this PR's must-fix findings — the published set in its comment (the findings backlog stays in the repo, untouched here).
Present this PR's published findings from the latest ### Code Review comment (shaped per finding-format) — scores + testable tags exactly as published, no re-scoring, no severity labels.
Default: fix all published findings (ADR-016). The published set already is Review's Opus-arbitrated must-fix set (≥75 ∨ ≥50∧testable), so "which to fix" is a computable default, not a decision needing a human — gating it would rubber-stamp work the model can verify itself. Narrowing the fix-set is opt-in, never a blocking stop: if the user has already asked to defer a tier, honour it; otherwise proceed with fix-all-published. if the published set is empty → straight to 5.2 (the spec delta + land still run; distinct from 5.0.4's zero-findings skip).
Dispatch fix agents in ONE parallel batch — one general-purpose subagent per picked finding, isolation: worktree, cut off this PR's tip (5.0.3 positioned @ there — @- is the cut point). Fix agents have no agent file — each is a general subagent briefed with fix-prompt.
Inject per agent: the finding (description · evidence · permalink) + its slice of the review standard. if the finding is tagged testable → the agent also writes a regression test covering it (test-after; test-first is an upgrade) — else a plain description-based fix.
The Build 3.2.1 worktree contract applies in full — state it in the prompt:
node_modules (fragile, unsound on dep changes)Barrier — collect every fix-agent's status + summary + working directory. For each SUCCESS, the session snapshots its workspace (jj status run inside it lands the fix in <name>@), then folds one atomic commit per finding on this PR's chain, fix(scope): <finding>:
( cd <worker-working-dir> && jj status >/dev/null ) # snapshot the fix into <name>@
jj describe '<name>@' -m "<message + trailers per commit-format>"
jj rebase -r '<name>@' -d '<prev-tip>' # fold onto this PR's tip (the first fix is already on it)
jj new # after the last finding
Message worker-suggested, session-owned; trailers carry Assisted-by: <agent> <model> (never Co-Authored-By:) plus pointers to artifact-owned facts by logical ID (Ticket:/Story:/ADR:/Depends-on:), never copies. A testable finding's fix + its regression test = ONE commit — the test proves the fix. Never bundle fixes into one commit.
if fixes overlap → Build 3.2.4's mechanism: the jj rebase of an overlapping fix records a conflict (not a halt) → jj edit the conflicted commit, dispatch a fix agent (solo-heal) to fix the markers — jj status amends it in place, message + trailers untouched (hands-not-authors: the session writes no code) → resume the fold.
Tail — forget the fix workspaces (spent resource, Build 3.2.6's mechanics): per workspace under .claude/worktrees/ — jj workspace forget <name> + rm the directory (the WorktreeRemove hook does this at teardown, but Claude Code may skip it — claude-code#37611 — so the session runs it explicitly; idempotent). The 5.3.3 sweep is only the safety net.
The explicit gate. jj runs no git hooks — push is NEVER the gate; the gate is this step. The session re-runs the build-order Verify command on this PR's fixed tip AND asserts no recorded conflicts:
<the build-order Verify command>
jj log -r 'conflicts()' # must be empty
The fixes are fresh code, and the new regression tests run inside Verify's scope — the fix proves itself.
if Verify fails → Build 3.2.5's loop: dispatch a fix agent off the fixed tip (fresh workspace, same contract) → the session snapshots + folds it → re-gate. Bounded, then escalate — never loop indefinitely; a repeating failure is a signal for the user, not something to paper over.
Publish the verified tip — push only verified state (5.1.5 just certified it):
jj bookmark set <headRefName> -r @-
jj git push --bookmark <headRefName> # existing bookmark (set just above); jj 0.42 needs no --allow-new
Goal: spec-writer patches .spec for this PR's diff, then the PR is accepted and landed.
Dispatch spec-writer — the solo writer: it mutates the main tree but runs alone, so no worktree. It applies ADDED/MODIFIED/REMOVED hunks over this PR's diff, scoped (divided PRs touch disjoint code → disjoint spec sections), per spec-format.
if this is the sprint's final unlanded PR (every sibling feat/sprint-v{N}(-<g>) PR already landed — check the forge) → the session (not spec-writer) flips the .sprint plan draft → built. The flip is an annotation, never its own commit — it rides this PR's close-out commit (5.2.3) and lands with it: flip and fact become true together; a PR that never lands → neither lands.
.spec delta (autonomous)Spec-accuracy check, not a sign-off (ADR-016). The delta is spec-writer reflecting this PR's shipped diff — its faithfulness is mechanically checkable, not a human judgment: re-derive the spec sections this PR's diff touches and assert the delta records exactly them — nothing dropped, nothing invented, no untouched section rewritten. if the check fails → back to 5.2.1 (re-dispatch spec-writer with the discrepancy); if it passes → 5.2.3, autonomously. The plan flip (when this is the final PR) is automatic once the sprint lands (5.2.1) — no separate approval. The human ship decision is 5.2.4 (accept-vs-DoD), not this derivable check.
One publication motion — deliberately fused so nothing intervenes between 5.2.2's accuracy-verify and publication (both ops stay named). The delta (+ flip) is already snapshotted in @:
jj describe -m "<docs commit per commit-format>"
jj new
jj bookmark set <headRefName> -r @-
jj git push --bookmark <headRefName> # existing bookmark (set just above); jj 0.42 needs no --allow-new
Doc-only — the code tip was verified at 5.1.5; no re-verify.
The user gives go/no-go on this PR against the per-PR DoD — the .brief DoD applied to what this PR delivers. Acceptance gates the content; the land op follows autonomously — never gate the land itself.
jj git fetch
jj rebase -b <headRefName> -o development@origin
The rebase completes even on conflict — a conflict is recorded in the commit, never a halt (the integration point never freezes).
Clean rebase → fast-forward and push:
jj bookmark set development -r <rebased tip>
jj git push --bookmark development # existing trunk bookmark; jj 0.42 needs no --allow-new
The bookmark move is forward-only — the FF; jj refuses a backward move. if the push rejects on a stale lease → that rejection IS the concurrency control: jj git fetch · re-rebase · retry. The PR then closes — its commits landed under fresh SHAs, change-ids preserved.
Stacked PRs (ADR-014) — base-first, retarget before delete. When a PR is a stack (its base: ≠ development):
development (above). Only then land each dependent, in base: order.development — gh pr edit <number> --base development — before 5.2.6 deletes the base group's branch (else GitHub orphans the dependent PR). Then land it: jj git fetch · jj rebase -b <headRefName> -o development@origin (the base group's commits are already on development by change-id, so only the dependent's own commits move; descriptions + trailers + change-ids preserved — never a squash) · re-run the build-order Verify on the rebased tip (its base changed — a fix that landed on the base may have shifted a seam) · FF + push as above.Conflicted rebase → park, don't block — and NEVER auto-resolve:
gh pr edit <number> --add-label conflict-parked + gh pr comment listing the conflicting change-IDs · the files · the landed sprint it crosses · @both devs.jj undo is equally valid to back the rebase out.jj edit <conflicted> → fix the markers together (the snapshot amends in place — same message, same trailers) → descendants auto-rebase → re-verify the healed tip → resume the land (FF + push) → remove conflict-parked.Exception — a doc/spec overlap at the land rebase is NOT a park (5.2.1's rule). Parking is for code conflicts only; a doc conflict is the spec-writer's remit: jj edit the conflicted close-out commit → re-dispatch spec-writer to reconcile the spec hunks. Name its inputs (the agent owns the how): this PR's .spec delta (the close-out hunks being landed) · the conflicting .spec delta already on development@origin (the landed sprint it crosses) · the rebased tip carrying the recorded conflict markers. It amends in place — message + trailers untouched → jj new back → assert conflicts() empty → continue the land (FF + push).
Delete the landed PR's bookmarks, local + remote — the rebase-land never uses the merge button, so GitHub's auto-delete never fires; the session deletes them itself:
jj bookmark delete <headRefName>
jj git push --deleted
Then remove the PR's flow labels (gh pr edit <number> --remove-label needs-refine).
if PRs remain → next PR (back to 5.0.3). if all PRs landed → 5.3. if any PR is parked or skipped → after the processed PRs, present the end-of-run report — each PR's end state (landed · parked, awaiting the paired session · skipped, with why) — and stop: sprint close (5.3) waits until every PR has landed, and the 5.3.3 sweep must never touch a parked PR's bookmarks (both published sides are what make parked state recomputable).
Goal: once all PRs have landed — inspect coverage, sweep leftovers, summarise. Inspect-only: no land gate, no commit — completion is a forge fact; the plan flipped built on the final PR's close-out commit (5.2.1 → 5.2.3).
Derive US-### → Issue → PR → .spec. Did the landed PRs meet the sprint's single Goal (the .sprint plan, Plan 1.2.6)? A gap is a planning miss, not a block — it stays visible as the open tickets (unbuilt tickets legitimately stay open, Build 3.4.4's invariant) or feeds the next /sprint-plan. Inspect, not a gate — landed PRs already shipped.
All this sprint's PRs landed — the forge is the completion record (built tickets were closed at Build 3.4.3; unbuilt ones legitimately stay open). Confirm the plan flip landed with the final PR — inspect only, no commit ever. if the plan still reads draft → an irregular close: report it — the next sprint's backstop (Plan 1.0.3) catches it; never commit a flip here.
Safety net — normally a no-op (Build 3.2.6 cleaned per wave, 5.1.4 per fix batch, 5.2.6 per PR):
.claude/worktrees/ → jj workspace forget <name> + rmjj bookmark delete <name> + jj git push --deleted[Epic] issue still open whose child tickets all closed (Build 3.4.3 should have closed it at build) → gh issue close <epic-N> — safety net for an epic Build 3.4.3 should have closedThis step only runs once every PR has landed (5.2.6's condition), so the summary shows landed PRs only — a run that stopped early reported parked/skipped state at 5.2.6 instead:
## Sprint Refine — v{N}
PR #<a> <title> — <f> findings fixed · spec patched · landed
PR #<b> <title> — clean review · spec patched · landed
Coverage: US-### → #issue → PR → .spec (gaps: <open tickets / next-plan input>)
Plan: sprint-v{N} → built (landed with PR #<last>)
Then recommend the next step — phases don't share a session; artifacts are the bridge: the landed trunk, the closed PRs, and the built plan carry the state. Next: /sprint-plan in a fresh session.
spec-writer instead — never a parked pair.spec-writer run in their own jj workspaces, so the slow work overlaps across PRs (not one PR at a time); the session folds serially as sole committer. Peers land any order, a stack lands base-first; the land itself is always serial (one trunk, stale-lease control).spec-writer are hands, not authors: diffs in, session-authored commits out; workers never commit, never run jj.fix(scope): <finding>; a testable fix + its regression test is one commit; fixes are never bundled.conflicts() empty), and only then does 5.1.6 publish.development before deleting the base branch, then rebase + FF); a stale lease means fetch · re-rebase · retry; the flow never merges..sprint draft → built flip is an annotation on the final PR's close-out commit, made by the session; 5.3.2 only confirms it, never commits.### Code Review comment is the work order; never re-review, never re-score, never re-check Tickets/Build decisions.development → main promotion is out of scope; this skill spans no other phase.npx claudepluginhub likeahuman-ai/likeahuman --plugin development-advanced-teamCreates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.