apm-issue-autopilot - intake-to-merge issue orchestrator
This SKILL.md is the natural-language module derived from a genesis design packet; refactors re-run the genesis skill from that packet.
This skill is an A11 RECONCILIATION LOOP, MANUALLY INVOKED, over a queue of issues each driven to a terminal state under non-determinism. It generalizes batch-bug-shepherd from bugs-only to ANY issue type, and promotes the full apm-triage-panel rubric to the central front gate. It does NOT re-implement triage, panel review, or the per-PR convergence loop -- it COMPOSES existing skills.
What it composes (do not re-implement)
- apm-triage-panel -- the triage rubric, run per issue in DIRECT (orchestrator-return) mode.
- shepherd-driver -- the per-PR drive- to-merge convergence loop and cross-PR mergeability gate (which in turn composes apm-review-panel).
- pr-description-skill -- authors
the anchored, mermaid-validated body of the ONE issue PR opened at
Phase 4 acceptance-close (see
assets/acceptance-observer.md). The PR body is never hand-rolled.
All three are same-repo LOCAL SIBLINGS. This skill DECLARES each
dependency here AND in apm.yml, and PROBES for each at its use-site
(Phase 1 triage, Phase 4 PR-open, Phase 5 shepherd) with a tool call --
never an assertion from recall (A9 SUPERVISED EXECUTION).
Hard boundaries
- MANUAL invocation only. No event triggers, no label triggers, no
gh-aw. Labels (
status/accepted,status/shepherding) are WRITTEN for bookkeeping but are NEVER the trigger. - Triage is paramount. The autopilot ESCALATES to the maintainer by default; auto-implementation is the narrow exception, reached only for a clear, bounded, high-confidence accept the maintainer approved.
- ONE consolidated triage review for the whole batch, not drop-by- drop. Exactly one human checkpoint (Phase 2).
- Never auto-merge. Mergeability is the terminal state; the human approves the protected merge.
- Escalation NEVER auto-closes or auto-declines an issue. It surfaces the issue to the maintainer running the session and leaves it for human action (inherits batch-bug-shepherd terminal-handling).
Architecture invariants
- Fan-out, not serial. Triage, solution-pipeline (and its Plan
lenses + per-wave task children), and shepherd-driver all run as
parallel child threads via the runtime
taskaffordance. A single-loop variant is an anti-pattern. Subagent capacity is UNLIMITED and is NEVER a deferral reason. - Worktree isolation, with one-writer integration. Every solution-
pipeline and shepherd-driver child runs in its OWN git worktree (one
per issue/PR). Within Phase 4, a pipeline child further spawns ONE
task child per task PER WAVE, each in its OWN worktree branched off
the issue branch at the wave base; the pipeline child is the SOLE
WRITER of the issue branch and integrates task branches via
git merge --no-ffat the wave gate. Tasks in a wave are mutually independent and touch disjoint files by construction (planner- enforced), so integration is conflict-free -- a real conflict is a planning error and triggers a re-plan, never a hand-resolve. Do NOT fan out against one shared working tree. Triage and verifier/lens children are read-only and may share a read-only REPO_ROOT. - One persisted state table. A single
plan.mdground-truth table plus a machine-readableproceed_manifestis the canonical session state (B4 PLAN MEMENTO). Reload it at every phase boundary; never keep parallel state in memory. The orchestrator is the SOLE writer (one-writer rule); children return JSON, the parent writes rows. - Escalate by default. The confidence gate (assets/confidence-gate-rubric.md) routes anything doubtful to the human. Auto-proceed is the exception.
- Triage children are advisory-only. A triage child runs the apm-triage-panel rubric and returns structured JSON. It MUST NOT post a comment, apply a label, touch the working tree, or use any GitHub safe-output channel. A child that emits a comment is a hard retry/fail.
- Fold by default at the PR layer. Inherited from shepherd-driver: every follow-up inside a PR's stated scope is folded; only scope- crossing items defer with a one-line boundary note.
- Deterministic tool bridge. Every consequential write (label,
assign, PR open, push, comment, merge probe) and every present-state
fact (CI status, mergeable, head sha, duplicate existence, PR-in-
flight) goes through a deterministic CLI (
gh,git,uv run ruff) wrapped in plan + execute + verify. Never assert these from recall. - ASCII only. All artifacts (tables, comments, commits, the
digest) stay within printable ASCII; status symbols
[+] [!] [x] [i] [*] [>].
Dependency probes (run before composing)
Phase 1 (before triage fan-out):
test -f ../apm-triage-panel/SKILL.md \
&& echo "apm-triage-panel present" \
|| echo "MISSING apm-triage-panel - stop and ask the operator"
Phase 5 (before shepherd-driver fan-out):
test -f ../shepherd-driver/assets/shepherd-driver-prompt.md \
&& test -f ../shepherd-driver/assets/completion-schema.json \
&& echo "shepherd-driver present" \
|| echo "MISSING shepherd-driver - stop and ask the operator"
Phase 4 (before a pipeline child opens the issue PR -- the child
re-probes this in its own worktree before gh pr create):
test -f ../pr-description-skill/SKILL.md \
&& test -f ../pr-description-skill/assets/pr-body-template.md \
&& echo "pr-description-skill present" \
|| echo "MISSING pr-description-skill - stop and ask the operator"
On a probe MISS, STOP and ask the operator to restore the sibling; do NOT re-implement the composed logic inline.
Phases
Work through the phases in order. Reload the ground-truth table and
proceed_manifest at each phase boundary (B8 ATTENTION ANCHOR). Do
not skip the consolidated-review gate (Phase 2).
Phase 0 - scope and seed
Take the issue list or queue from the maintainer (explicit issue
numbers, a search query, or "the open backlog"). Resolve it to a
concrete set via gh issue list. Seed the ground-truth table
(assets/ground-truth-table.md) with
one row per issue at status: pending-triage. Record the seed source
and HEAD sha in plan.md. No labels are written in this phase.
Phase 1 - triage fan-out (read-only)
PROBE for apm-triage-panel (above). Then, for EACH issue, spawn ONE
triage child using
assets/triage-prompt.md, at PLANNER class
(claude-opus-4.8) per model-routing.md (Phase 1 triage binding -- the
paramount front gate is front-loaded heavy: a wrong accept burns a whole
downstream pipeline). Each child runs
the apm-triage-panel rubric in DIRECT mode and returns ONE
autopilot-triage-decision JSON matching
assets/autopilot-triage-schema.json.
Children are read-only and post nothing.
This is "A11 per-item child thread running an existing triage module", not a nested panel-of-panels: each child invokes apm-triage-panel (which itself spawns no sub-agents) once and returns its decision.
On each return: schema-validate, write the row (decision, type,
confidence, red_flags), set status: triaged. On a child that posted
a comment or mutated the tree, discard and re-spawn ONCE; on a second
violation, mark the row blocked and escalate it in Phase 2.
Phase 2 - consolidated triage review + the ONE human checkpoint
This is the heart of the skill and the single human gate. Do it ONCE for the whole batch, not per issue.
- For every triaged row, apply
assets/confidence-gate-rubric.md
to compute a
gate:auto-proceed|escalate|terminal. Escalate by default; auto-proceed only for a clear, bounded, high- confidence accept whose implementation brief is complete. - Write the machine-readable
proceed_manifestinto plan.md (one row per issue:issue, gate, maintainer_decision, override_reason, implementation_brief_ref, status).maintainer_decisionstartspending. - Render ONE consolidated digest from assets/triage-digest-template.md: every issue with its decision, type, confidence, gate, red flags, and (for auto-proceed rows) the implementation brief. Present it to the maintainer in-session.
- Capture the maintainer's decision per row:
approved|rejected|overridden(withoverride_reason). The maintainer may approve an escalated row (override to proceed) or reject an auto-proceed row. Write the result into theproceed_manifest.
All later phases select rows ONLY where gate resolves to proceed AND
maintainer_decision in (approved, overridden-to-proceed). Rows the
maintainer left escalated/terminal are handled in Phase 7.
Phase 3 - ownership signaling + PR-in-flight xref
For each proceed row: cross-reference open PRs that already address
the issue (gh pr list --search). Record pr and pr_in_flight.
Apply status/accepted to the issue and, on the issue (and the PR if
one exists), assign @me and add status/shepherding. Record every
label THIS run adds in the row's labels_added column so Phase 7 (and
Phase 5 teardown) strip ONLY those and never touch pre-existing
labels.
Phase 4 - solution pipeline (Ideate -> Plan -> Implement waves)
For each proceed row WITHOUT an in-flight PR, spawn ONE solution-
pipeline child in its OWN git worktree on the issue branch (provision
with git worktree add at HEAD; record its slug in the row's
worktree column so Phase 7 tears down only worktrees this run
created). Spawn it at IMPLEMENTER class (claude-sonnet-4.6); it and
every child it spawns route models per
assets/model-routing.md (B12 MODEL ROUTER).
The child runs
assets/solution-pipeline-prompt.md,
a four-stage per-issue pipeline (A2 PIPELINE), and returns the opened
PR. It is the SOLE WRITER of the issue branch:
- Ideate (assets/ideate-prompt.md,
devx-ux-expert) -- frame the brief and derive a testable
acceptance_shape(the B5 contract). Spawn at PLANNER class (claude-opus-4.8) per model-routing.md -- front-loaded heavy because this contract is the verification spine for every wave. - Plan (assets/plan-panel-prompt.md, python-architect lead + conditional performance / test-coverage / supply-chain / auth lenses) -- emit a persisted task DAG matching assets/plan-schema.json: per-task staffing, interdependencies, ordering, and WAVES with checkpoints (B4 PLAN MEMENTO). Trivial issue -> ONE task in ONE wave; skip the full gate ceremony (scale-down).
- Implement (A5 WAVE EXECUTION) -- per wave, spawn ONE task child (assets/task-implement-prompt.md) per task, each in its OWN worktree off the issue branch at the wave base; the pipeline integrates the task branches into the issue branch, then runs the inter-wave checkpoint (assets/wave-gate-rubric.md, plan- guardian + ideator verifiers). PASS advances; FAIL re-plans from the failed wave (cap 2 re-plans).
- Acceptance close
(assets/acceptance-observer.md, B5)
-- verify every
acceptance_shapecondition deterministically, then open ONE PR (Closes #N) and return its number.
Each task child writes the TYPED coverage gate first (bug: failing
regression trap + mutation-break; feature: failing acceptance test;
docs: docs build/link check; refactor/perf: behavior-preserving test +
benchmark) for its task type, never opens a PR, and never spawns
children. The orchestrator then applies the Phase 3 ownership signaling
to the new PR. Rows WITH an in-flight PR skip Phase 4 and go straight
to Phase 5. On a status: escalate|blocked return, write the reason to
the row and surface it in Phase 7 (no PR opened). On a pr-opened
return, also record the child's routing_receipts array in the row's
notes (B12 cost audit) so the Ideate=opus / architect=opus front-load
is auditable from plan.md alone, never from a child transcript.
Phase 5 - shepherd-driver fan-out (drive to merge)
PROBE for shepherd-driver (above). For each PR (own-implemented or in-
flight), spawn ONE shepherd-driver subagent using
../shepherd-driver/assets/shepherd-driver-prompt.md. It owns the
convergence loop (Copilot classification, apm-review-panel, fold-vs-
defer, push, CI watch) and returns a completion_return matching
../shepherd-driver/assets/completion-schema.json. Caps: 4 outer
iterations, 2 Copilot rounds, 3 CI recovery iterations.
On each terminal return: schema-validate, then write head_sha and
the mergeable/merge_state_status/ci_status projection into the row's
head_sha and merge_state columns (the crash-survivable A11 stop
evidence), and remove ONLY the status/shepherding labels listed in
the row's labels_added column (assignment stays). Also record the
return's panel_execution (skill-tool|inline), panel_personas,
and routing_receipt in the row's notes -- the inline panel path is
EXPECTED in subagent context, so panel_execution: inline is a normal
healthy value, not a degradation.
Phase 6 - conflict-resolution
For every PR that returned ready-to-merge, probe mergeability (gh pr view --json mergeable,mergeStateStatus). On DIRTY / BEHIND /
CONFLICTING, spawn one conflict-resolution subagent per
../shepherd-driver/assets/conflict-resolution-prompt.md (step-by-
step in ../shepherd-driver/references/mergeability-gate.md).
Phase 7 - final report
Read the table and proceed_manifest one last time. Render
assets/final-report-template.md to
the maintainer: per-issue decision, gate, maintainer decision, PR
link, terminal status, ready-to-merge PRs, advisory-with-deferred
PRs, blockers (with the responsible child's session ref), and every
ESCALATED / terminal row still awaiting human action. Tear down only
the solution-pipeline/shepherd worktrees recorded in the worktree
column (git worktree remove); leave branches on origin for open PRs.
Never auto-close an escalated issue.
Bundled assets
- assets/triage-prompt.md -- any-type triage child spawn body (runs apm-triage-panel in DIRECT mode).
- assets/autopilot-triage-schema.json
-- JSON schema for the
autopilot-triage-decisionreturn. - assets/confidence-gate-rubric.md -- escalate-by-default gate policy (Phase 2).
- assets/triage-digest-template.md -- the ONE consolidated review presented to the maintainer.
- assets/solution-pipeline-prompt.md -- A2 PIPELINE: per-issue Ideate -> Plan -> Implement(waves) -> Acceptance close (Phase 4 child; sole writer of the issue branch).
- assets/ideate-prompt.md -- devx-ux-expert Ideate child: design_brief + testable acceptance_shape (read-only).
- assets/plan-panel-prompt.md -- Plan stage: lens-selection rubric + python-architect synthesis emitting the task DAG.
- assets/plan-schema.json -- JSON schema for
the persisted
issue-solution-plan(tasks, deps, waves, checkpoints). - assets/model-routing.md -- B12 MODEL ROUTER: authoritative role-class -> concrete-model table + per-spawn bindings + verifier escalation; the pipeline resolves every Phase 4 spawn's model here. Also records the B14b CAVEMAN BRIEF layer (lens advisors + wave-gate verifiers ship compressed, fixed-schema briefs), the B14c audience-boundary PER-SPAWN DECLARATION TABLE, the B13 cache-aware- prefix discipline, and the B15/B16 status for this harness.
- assets/task-implement-prompt.md -- ONE task per child in its own worktree; loads the typed coverage gate by task type; no PR, no further fan-out.
- assets/implement-bug.md, assets/implement-feature.md, assets/implement-docs.md, assets/implement-refactor.md -- per-type coverage-gate references loaded per task by task-implement-prompt.md.
- assets/wave-gate-rubric.md -- inter-wave checkpoint: integrate + plan-guardian/ideator verify + re-plan policy.
- assets/acceptance-observer.md -- B5 close: verify acceptance_shape, open the ONE issue PR.
- assets/ground-truth-table.md -- canonical table template with A11 columns + proceed_manifest.
- assets/final-report-template.md -- end-of-session report to the maintainer.
Composed siblings (declared dependencies)
- apm-triage-panel -- triage rubric (Phase 1; probed before use).
- shepherd-driver -- per-PR drive-to- merge loop + mergeability gate (Phases 5-6; probed before use). Transitively composes apm-review-panel.
- pr-description-skill -- authors the Phase 4 issue-PR body (probed before the PR-open; never hand-rolled). Transitively also used by shepherd-driver for any superseding PR.
Operating contract for the orchestrator thread
- Before each phase: re-read
plan.md(table + proceed_manifest). Do NOT rely on recall. - The orchestrator is the SOLE writer of the ground-truth table and of the GitHub state it explicitly owns (issue labels, assignment, tracking issues). PR-side writes -- pushes and PR comments during the drive and mergeability phases -- are owned by shepherd-driver, never by the orchestrator.
- Every consequential write is plan + execute + verify through a CLI.
- One consolidated review, one human checkpoint, escalate by default.