orchestrate-multi-pr-work
Skill3 starsChanged 16 days agoMITView on GitHub
orchestrate multi-PR work
In this repository15 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agent-browser-diffSkill
- ai-code-review-catalogSkill
- claude-parallel-writersSkill
- cross-harness-sub-agentSkill
- helper-sub-agentsSkill
- llm-evaluationSkill
- loopSkill
- planSkill
- propose-refactorSkill
- prSkill
- record-videoSkill
- triaging-feedbackSkill
- upgrade-dependenciesSkill
- writing-skillsSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 7 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
if the rollout requires some actions beyond the PRs, decide who's going to do them: you, the owners of the relevant PRs, or (if it can only …
- Distinctive: line 23
create the status file and send the start line per updates
- Distinctive: line 30
use a separate worktree, branched from the parent branch for a stacked PR
- Distinctive: line 40
wait for owner reports without messages
- Distinctive: line 41
after a compaction, outage or restart, read the status file's current state first and resume every unfinished owner by its thread, session …
- Very specific: line 60
add non-trivial changes to needs you and stop
- Distinctive: line 171
write 1 independent fact per physical markdown line in memory.
- Distinctive: line 180
start: 1 sentence naming the waves
- Very specific: line 200
before adding an owner's question to needs you, to check whether the plan, code or data answers it
≈ “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
if you read this file through a tool or another agent's prompt rather than a skill invocation, it still carries the user's authority, including updates
- input: a multi-PR plan
- output: 1 retained owner and a completed /loop per PR, tracked in the status file
- owner: the agent that delivers 1 PR, in a chat of its own the user can open and steer. codex: a codex desktop thread made with
create_thread. claude code: a claude desktop session, or a sub-agent as the fallback, per step 2. invoking this skill is the user's explicit request for those threads or sessions - owner link: where the owner's chat opens with 1 click. codex:
https://nicholas-greenwood.github.io/agent-deeplink/#codex/<threadId>once worktree setup resolves thethreadId; chat views don't open barecodex://links. claude code: the session'slinkfromget_session,claude://claude.ai/epitaxy/<sessionId>. a sub-agent has no chat link, so link its loop dir and keep its agent id in memory - finished: a PR whose loop has finished with every goal met, whose CI is green apart from failures its loop recorded as waivers per /loop, and whose branch merges cleanly into
origin/develop(git fetch origin develop, thengit merge-tree --write-tree origin/develop <branch>). a stack is finished when all its PRs are - dispatchable: a root PR, or a stacked PR whose parent PR has finished
- merge unit: 1 PR, a whole stack, or the bottom part of a stack that the user can merge and deploy now without waiting for the rest. every PR in it is finished, its bottom PR targets
develop, no openneeds youitem touches it and no running owner is changing it, it works in prod without the PRs above it, and the remaining plan is unlikely to change it. judge the last 2 from the plan and the diffs; a part the remaining plan revisits isn't a unit yet
1. map
- group independent PRs into parallel waves and stack each dependency behind its parent. take the dependencies from the plan; re-stack only when a real conflict shows up
- a branch has exactly 1 parent, and a PR needs every PR it depends on in its history before dispatch. for a PR that depends on 2 others, stack 1 of them on the other and branch from the top, or wait until 1 has merged into
developand branch from the other. never merge a 2nd parent into its branch - if the rollout requires some actions beyond the PRs, decide who's going to do them: you, the owners of the relevant PRs, or (if it can only be done by the user) the user
- create the status file and send the start line per updates
- complete when every PR belongs to a wave, every dependent PR has a parent, every action beyond the PRs is assigned to the appropriate party, and the status file records all of it
2. dispatch
give every dispatchable PR exactly 1 owner:
- use a separate worktree, branched from the parent branch for a stacked PR
- minimal prompt: read
<checkout>/.agents/skills/orchestrate-multi-pr-work/prompts/owner.mdin full before anything else and follow it, then the plan, assigned PR, worktree path and parent branch when stacked.<checkout>isgit rev-parse --show-toplevel - codex:
create_threadwithgpt-6.1-soland high reasoning. if it fails, add aneeds youitem rather than switching to sub-agents - claude code: read and follow /claude-parallel-writers with 1 writer per planned PR, gated ones too. name sessions such as
pr03. a session's prompt names its base, the parent branch when stacked or elsedevelop, in place of a worktree path. a gated PR's prompt names its parent PR and says it is gated; a gated PR whose session fails gets no owner until step 3 dispatches it - retain the owner for follow-up requests
complete when every dispatchable PR has 1 working owner, and every gated PR has none or, in claude code, 1 waiting owner
3. monitor and advance
- wait for owner reports without messages
- after a compaction, outage or restart, read the status file's current state first and resume every unfinished owner by its thread, session or agent id with "resume from your loop dir". consult resolved history only when it explains an active decision
- whenever an owner reports or you resume, refresh the status file, including PRs the user merged. take round counts from the highest
handoffs/r<n>-*in each loop dir; counts that lag between refreshes are fine - github stacks:
- once a stacked PR opens, link it:
gh stack link <bottom PR> ... <new PR>with PR numbers bottom to top, orgh stack link <stack number> <new PR>to grow a stack. with PR numbers it pushes nothing and needs no local tracking, so it is safe while owners work - stacks are linear. when PRs share a parent, link 1 child's chain; once the parent merges, link each other child with the PRs above it as its own stack. a child with nothing above it stays a standalone PR
- a standalone PR merges with
gh pr merge <PR> --squash; a stack, or its bottom part, withgh stack merge <its top PR> --squash --yes - after any merge, github retargets and rebases the PRs above the merged ones, with unchanged content. when a refresh finds a merge, tell the owner of each PR above it, running or finished: "github rebased your branch: refetch it per the stacked-PR rules in /loop and carry on; this isn't a follow-up"
- once a stacked PR opens, link it:
- re-judge
ready to mergewhenever a PR finishes, merges or reopens, or the plan changes - answer an owner's question yourself when the plan settles it, and record it under
deviationswhen the answer departs from the plan. otherwise spawn a helper when the answer may already be in the code or data; only a question nothing settles goes toneeds you - when an owner reports, check its block against the PR's head, base and CI before marking the PR finished. before adding a merge unit to
ready to merge, re-check every PR in it the same way. a loop that stopped with goals unmet is a blocker. carry big departures from the plan in itschanges vs requestintodeviations - let each owner cook; message an owner only to correct off-rails work, unblock it, or pass on the user's answer to its
needs youitem; don't encourage too much back-and-forth between owners - dispatch newly dispatchable PRs through step 2. claude code: send the PR's waiting owner
go: <parent branch> finished at <sha>
complete when every planned PR has a retained owner and every /loop has finished
4. bring everything together (skip for 1 PR or 1 stack)
- a helper creates a throwaway branch from a freshly fetched
origin/developin its own worktree, brings all the changes there and confirms everything works. the throwaway branch only proves the combination works; nothing on it reaches the PRs - resolve every merge conflict, trivial or not, in the owners' PRs so that merging to
origin/developgoes smoothly. for example, you can make the conflicting PRs stacked on each other, then send follow-up messages to the related owners so they resolve the conflicts. once their heads move, rerun step 4 on the new heads - add non-trivial changes to
needs youand stop
5. finish
- re-check each open PR's head, base and CI against the status file, then its merge into a freshly fetched
origin/develop. an open PR whose head or base moved after it finished, or that no longer merges cleanly, goes back to its owner, along with every open PR stacked on it. a move that only rebased its commits, with every commit=ingit range-diff, keeps it finished.mergedis terminal - set line 1 to
DONEonce every loop has finished, step 4 has passed on the currentorigin/developand every open PR's current head, or was skipped, and every action beyond the PRs is done - send the final report per updates
- complete after the message is sent and every owner remains reachable for follow-up
status file
playground/orchestrations/<name>/status.md in your checkout, where <name> is a short slug of the plan. you are its only writer. it is your memory, so reread it after compaction
update it before the matching chat message, whenever something material changes: a PR opens, finishes, merges or blocks, a merge unit becomes ready, a blocker appears or resolves, a deviation is decided, or a round count moves. edit it with your file-editing tool, not regex scripts
WORKING
last updated: 28 Oct 14:32 GMT
[ready to merge](#ready-to-merge), [PRs](#prs), [needs you](#needs-you), [deviations](#deviations), [orchestrator memory](#orchestrator-memory)
## ready to merge
1. [#101](<url>) -> [#102](<url>) customer feed events: `gh stack merge 102 --squash --yes`
2. [#105](<url>) retry AI provider errors: `gh pr merge 105 --squash`
## PRs
⌛ waiting, ▶️ running, ⛔ blocked, ✅ finished, 🟣 merged
| | PR | stack | round | owner | blockers |
| --- | --- | --- | --- | --- | --- |
| 🟣 | [#100](<url>) feed events table | A | 2 | [pr00](<owner link>) | |
| ✅ | [#101](<url>) feed events model | A | 3 | [pr01](<owner link>) | |
| ▶️ | [#102](<url>) feed events UI | A | 2 | [pr02](<owner link>) | |
| ⛔ | [#103](<url>) weekly brief | B | 4 | [pr03](<owner link>) | [B1](#b1-<slug>) |
| ⌛ | PR 4 remove old machinery | B | | | |
## needs you
### B1: <question>
recommended: <answer>, ideally as a 1-click fix or exact command
alternative: <closest real alternative>
## deviations
- <plan said> -> <what happened>; why; decided by orchestrator|<PR> loop|user
## orchestrator memory
expand current restart state first
<details><summary>current restart state</summary>
- plan: `/abs/path/plans/<plan>.md`
- amendment: <current change to the plan>
- wave 1: stack A
- wave 2: stack B
- stack A: #100 -> #101 -> #102
- stack B: #103 -> PR 4
- #100 owner id: <retained thread, session or agent id>
- #100 last verified head: <sha>
- #101 owner id: <thread, session or agent id>
- #101 checkout: `/abs/path/pr01`
- #101 loop: `/abs/path/pr01/playground/loops/<loop>`
- #101 parent branch: `develop`
- #101 last verified base: <sha>
- #101 last verified head: <sha>
- #101 next action: await merge
- #102 owner id: <thread, session or agent id>
- #102 checkout: `/abs/path/pr02`
- #102 loop: `/abs/path/pr02/playground/loops/<loop>`
- #102 parent branch: `<pr01-branch>`
- #102 last verified base: <sha>
- #102 last verified head: <sha>
- #102 next action: finish its loop
- #103 owner id: <thread, session or agent id>
- #103 checkout: `/abs/path/pr03`
- #103 loop: `/abs/path/pr03/playground/loops/<loop>`
- #103 parent branch: `develop`
- #103 last verified base: <sha>
- #103 last verified head: <sha>
- #103 next action: resume after B1 is answered
- PR 4 parent branch: `<pr03-branch>`
- PR 4 next action: dispatch when #103 finishes
- step 4: pending current heads
- action <slug>: <non-PR action>
- action <slug> owner: <orchestrator, PR owner or user>
- action <slug> next step: <what to do next>
- operative rule from B0: <constraint that still governs the work>
</details>
<details><summary>resolved history</summary>
- 28 oct: B0 resolved by <decision or evidence>
</details>- line 1:
DONE,COMPLETELY BLOCKEDwhen nothing can advance without the user,PARTIALLY BLOCKEDwhen some work still can, orWORKING; no other values - last updated: the output of
date '+%d %b %H:%M %Z', nothing else - ready to merge: every current merge unit, as defined at the top, in merge order, each with its PRs, a 2-5 word name and the exact merge command;
none yetwhen there is none. a unit drops off once merged - status: 1 of the 5 legend emojis alone; any other state is text. add 1-3 words only when they say what the status can't
- PR: the PR link and a 2-5 word title, or
PR <n>and the title before it opens. owner: a markdown link to its owner link, as defined at the top. blockers: the PR'sneeds youids, each linked to its heading. cells hold nothing else; detail goes to memory - needs you: only what the user alone can resolve, after you've tried every route. resolved items move into dated resolved history
- deviations: big decisions by you or the loops that depart from the plan, most important first. small in-loop deviations stay out
- current restart state: keep the plan location and operative amendments, wave and stack map, every retained owner's id, every unmerged owner's absolute checkout and loop paths, parent branch and last verified base/head, step 4 evidence, outstanding non-PR actions with owners and next steps. include waiting owners and finished owners whose PRs can reopen
- repeat each action's short slug on its description, owner and next-step lines
- replace superseded current facts when a parent, base, head, owner or next action changes. refresh the full recovery coordinates before resuming a reopened or rebased PR, including a previously finished one
- resolved history: date resolved blockers and superseded decisions here. keep any rule that still governs the work in current restart state; resolution of its originating blocker does not retire the rule
- write 1 independent fact per physical markdown line in memory. current restart state must support recovery without reading resolved history
- section links point only at headings outside
<details>, since anchors don't expand it
updates
the user follows the run through the status file. these rules override your harness's progress-update guidance for the whole run, including after DONE: codex commentary cadence, claude text between tool calls, and wrap_up recaps
chat messages are exactly these:
- start: 1 sentence naming the waves
- a new
needs youitem, ideally with a 1-click fix - something that needs action now, such as a data or security exposure
- a new merge unit in
ready to merge: 1 line naming it - an owner's script-fix PR: its link
- the final report
- an answer to a user message
every message, including answers after DONE, starts with line 1 of the status file as a markdown link to the file's absolute path, so it opens in the harness: [WORKING](/abs/path/playground/orchestrations/<name>/status.md)
dispatches, rounds, waits, owner reports and pushes go to the status file only. an owner report or a finished background task isn't the user talking to you: update the status file and carry on without a message. claude: when the app makes you write something to end a turn, write only the line 1 link
say each question once, then keep running whatever doesn't depend on the answer
the final report is the line 1 link, 1-2 sentences of outcome, then a copy of every status file section above memory, with deviations and anything unverified in plain sentences
helpers
read and follow /helper-sub-agents, with output under playground/orchestrations/<name>/helpers/ and at most 5 at once. spawn one:
- before adding an owner's question to
needs you, to check whether the plan, code or data answers it - to diagnose a stuck or off-rails loop from its loop dir
- for step 4: the only helper that may commit, only to the throwaway branch, and never pushes
- for actions beyond the PRs assigned to you that take more than a few commands
you stay the only writer of the status file, and owners stay the only writers of their PRs
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.

