Files
awesome-copilot/skills/copilot-pr-autopilot/references/orchestration.md
T
Gordon Lam d47a6c93b7 Add copilot-pr-autopilot skill (#1944)
* Add copilot-pr-autopilot skill

Skill that drives any GitHub pull request through repeated rounds of
Copilot Code Review until the agent has either resolved every thread
or explicitly escalated it to the human. Triggered via GraphQL (no
@copilot mention needed), triages every open thread with a fix /
decline / escalate rubric, replies and resolves each thread citing
the pushed SHA, then re-triggers until HEAD is reviewed with zero
threads awaiting the agent's reply.

Includes step scripts (01 request-review, 02 check-review-status,
03 list-open-threads, 08 reply-and-resolve, 10 cleanup-outdated),
shared library (_lib.ps1) with gh-CLI wrappers (Invoke-Gh,
Invoke-GhGraphQL, ConvertFrom-GhJson, Assert-GhReady), reply
templates, and reference docs for each step.

Repo-agnostic. Requires gh CLI on PATH and repo Triage/Write for
full autopilot; external PR authors get single-iteration mode with
manual re-trigger via the UI re-request button or a substantive
push.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review: split per-step references + add recap-gate circuit breaker

- Fix #1: give steps 1/7/10 their own reference files
  (01-request-review.md, 07-commit-push.md, 10-cleanup.md); trim the
  inline bodies out of orchestration.md so it stays cross-cutting only.
- Fix #3: add a recurring round-cap & recap gate to 09-convergence.md —
  default STOP every 10th round, recap all prior rounds, detect drift
  (out-of-scope / over-engineering / wrong-direction / belongs-in-separate-PR)
  with CONTINUE / REVERT-AND-SHIP / HAND-OFF verdicts. Agent reasoning,
  no new script.
- Surface the gate from SKILL.md and orchestration.md; regenerate
  docs/README.skills.md. Markdown-only change; scripts unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(copilot-pr-autopilot): surface recap gate in decision pseudo-code; clarify Copilot+human convergence and round definition

- Inject the round-cap recap gate into the '## Decision: loop back or exit'
  pseudo-code else-branch so an agent following the code block (not just the
  prose) runs the STOP-every-10th-round check before looping.
- Broaden the 'never terminal' paragraph: non-convergence is driven by a
  Copilot finding OR a human review comment (this skill handles both); the
  loop ends only when there are no new comments from either source AND every
  open thread (Copilot or human) has an agent reply/escalation.
- Define a 'round' explicitly as one execution of step 1 (01-request-review),
  i.e. one Copilot-review trigger — the cap counts review rounds, not tool
  calls or fix edits.

Markdown-only; no script changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* copilot-pr-autopilot: make recap-gate round count deterministic

Add 09-review-round.ps1: counts Copilot Code Review submissions straight
from the PR's API history (full GraphQL pagination), so the recap-gate
trigger is a derived number, not a fallible agent mental tally. This
removes the exact failure mode the skill exists to survive — a count
drifting across a long run (the real 156-round case).

The script reports Round + RecapDue (Round % RecapInterval == 0) only;
it never stops the loop or picks the verdict. CONTINUE / REVERT-AND-SHIP
/ HAND-OFF stays agent reasoning. 09-convergence.md updated to reference
the deterministic count while preserving 'no script stops the loop' and
'non-convergence = Copilot finding OR human comment'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Regenerate docs/README.skills.md for copilot-pr-autopilot (add 09-review-round.ps1)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-01 11:09:58 +10:00

107 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Orchestration — Parent-Owned Loop Control
Cross-cutting protocol for the Copilot PR review loop: time-boxing,
the sub-agent delegation map, the single-iteration fallback, and the
loop-wide notes. Every step — including the parent-owned steps 1, 7,
and 10 — has its own `NN-*.md` contract file alongside this one; this
file holds only what spans the whole loop.
Build, test, and lint commands are NOT prescribed here. Every step
that needs them defers to the target repo's own conventions
(`CONTRIBUTING.md`, `AGENTS.md`, `README`, `package.json` /
`Makefile` / language tooling, etc.). Discover and follow the repo's
existing practice — never invent build commands.
## Time-boxing & extension protocol
| Concept | Rule |
|---------|------|
| Default budget | 5 minutes per sub-agent invocation |
| Sub-agent must return | `status` ∈ {`complete`, `partial`, `blocked`} + `next_action` + `needs_extension_minutes` (0 if none). Always summarize progress before the budget expires — never silently overrun. |
| Extension | parent only extends when `status: partial` AND `next_action` is concrete; sends `write_agent "continue for N min"` with `N = min(needs_extension_minutes, 10)` |
| Extension cap (default) | 2 extensions per step; step 6 (build/test) up to 2× for slow suites. Step 2 (wait) is a single bounded sub-agent — see [02-wait.md](02-wait.md) — not extension-driven. |
| Parent never blocks | step 1 (request), step 7 (commit + push), step 8 reply/resolve mutations, and the `task_complete` decision stay in the parent |
When the cap is reached and the work is still `partial`, the parent
narrows the input (batch smaller in step 4 / split fix scope in step 5)
or takes the step over itself.
## Sub-agent delegation map
> **The loop:** one **round** = steps 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9. After step 9, if `Converged: false`, **go back to step 1** for another round. Repeat until step 9 returns `Converged: true`; then run step 10 once and exit. **At every 10th round, the parent runs the [round-cap recap gate](09-convergence.md#round-cap--recap-gate-circuit-breaker) before looping back** — the circuit breaker that recaps all prior rounds and stops the loop if it has drifted out of the PR's original scope. See [09-convergence.md](09-convergence.md) for the convergence definition, the loop-exit / loop-back decision, and the recap gate.
Canonical order per round: **request → wait → list → triage → fix →
build → commit + push → reply + resolve (citing pushed SHA) →
convergence check**. Reply/resolve runs AFTER push so replies can cite
the pushed commit SHA.
| Step | Owner | Contract |
|------|-------|----------|
| 1 — Request review | parent | [01-request-review.md](01-request-review.md) |
| 2 — Wait for review | sub-agent (`general-purpose`, 20 min) | [02-wait.md](02-wait.md) |
| 3 — List + categorize open threads | sub-agent (`explore`, 5 min) | [03-list-threads.md](03-list-threads.md) |
| 4 — Triage | sub-agent (`general-purpose`, 5 min/≤5 threads) | [04-triage.md](04-triage.md) |
| 5 — Apply fixes | sub-agents (`general-purpose`, parallel max 5, 5 min each) | [05-fix.md](05-fix.md) |
| 6 — Build + test per repo conventions | sub-agent (`task` + `explore`, 10 min) | [06-build-test.md](06-build-test.md) |
| 7 — Commit + push | parent | [07-commit-push.md](07-commit-push.md) |
| 8 — Reply (always) + resolve (conditional) | sub-agent drafts → parent posts | [08-reply-resolve.md](08-reply-resolve.md) |
| 9 — Convergence verify | sub-agent (`explore`, 3 min) | [09-convergence.md](09-convergence.md) |
| 10 — Cleanup outdated (post-convergence, once) | parent | [10-cleanup.md](10-cleanup.md) |
## Single-iteration fallback
When `01-request-review.ps1` throws because Copilot Code Review isn't
enabled on the repo / account (the GraphQL mutation reports the bot
isn't a valid reviewer), the agent falls back to **single-iteration
mode**:
- Skip step 2 (no Copilot review to wait for).
- Run steps 3 8 once against whatever review threads already exist
(human, advanced-security, other bots).
- At step 9, pass `-SingleIteration` to `02-check-review-status.ps1` so
the convergence check ignores the stale-review checks that can never
advance without a new Copilot review. `Converged: true` collapses to
`OpenThreadsAwaitingReply == 0`.
- Re-iteration happens only when a human posts new comments later —
re-run the skill at that point.
Single-iteration mode is **the agent's decision after the trigger
fails**, not an auto-detected state — the script can't reliably tell
"Copilot disabled" from "Copilot enabled but not yet triggered" from
API state alone.
## Convergence proof
Print the proof of convergence in the `task_complete` message — proof,
not assertion:
- `HeadOid`
- `LatestCopilotReview.commitOid`
- `submittedAt`
- `OpenThreadsAwaitingReply: 0`
- The list of any open `escalate-to-user` threads if
`OpenThreadCount > 0`.
## Notes
- **Re-request is first-class.** `01-request-review.ps1` does not
silently skip when Copilot has already reviewed; it issues the
same mutation and verifies via a new `copilot_work_started` event
(the script enforces this — see [api-quirks.md](api-quirks.md) for
the GraphQL surface and the silent-drop trap).
- **Outdated threads still need reply + resolve.** They show up in
the PR UI as unresolved until you explicitly close them; step 10
is a safety net, not the primary mechanism.
- **Reopened / revisit requests reset the thread to step 4.** If a
declined finding is reopened by the user (or by a follow-up
Copilot review), pull it back into triage with the prior rationale
as input rather than re-running the whole loop.
- **Resumability after interruption.** On restart, snapshot HEAD,
the latest Copilot review's `commit.oid` + `submittedAt`, the
open-threads list, and any uncommitted local changes. Discard
cached triage / drafts if HEAD or the open-threads set changed.
- **Local-build patches.** For projects with uncommitted local-build
patches held out of the PR: `git stash push -m "local-build" --
<paths>` before committing, `git stash pop` after. Note `-m` must
come BEFORE `--` (see [api-quirks.md](api-quirks.md)).