skills/do-epic/SKILL.md
Work on a multi-story GitHub epic end-to-end. Builds a DAG from the child stories, groups them into waves, runs waves in parallel via per-story worktrees, ejects PRs that fail agent-code-review for human handling, and propagates blocks to downstream stories. Requires git worktrees.
npx skillsauth add thermiteau/maverick do-epicInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Depends on: mav-scope-boundaries, mav-multi-instance-coordination, mav-durability-on-gh, mav-block-propagation, mav-git-workflow, mav-stacked-prs, mav-github-issue-workflow, mav-create-solution-design, mav-create-tasks, mav-plan-execution, mav-local-verification, mav-bp-cicd, mav-bp-remote-code-review, mav-claude-code-recovery, do-issue-solo
Work on epic issue `` end-to-end. Builds a dependency DAG from the epic's child stories, schedules them into waves, runs each wave in parallel via per-story worktrees, and drives every story through agent code review with binary PASS/FAIL verdicts.
Run this first. If it exits non-zero, halt and report the stderr output to the user verbatim. Do not claim, do not branch, do not start any worktree.
uv run maverick preflight do-epic
The check verifies: the project is initialised, the Maverick GitHub
App is configured (maverick gh-app status reports configured: true),
git worktrees are usable, and required tools (gh, git, uv) are on
PATH. PR code review runs locally inside each story's worktree as the
agent-code-reviewer subagent (delegated from
do-issue-solo Phase 9). For epics that fan out across
many parallel workers, consider opting into the CI-side re-run
described in mav-bp-remote-code-review so the merge is
gated by an independent check even if a worker's local review fails to
fire — that workflow is optional and not enforced by preflight.
`` must be the GitHub issue number of a Maverick epic
— an issue whose body contains a task table of child stories. If it is
a single story, dispatch do-issue-solo instead.
gh repo view --json nameWithOwner.mav-durability-on-gh:
maverick-dag marker on the epic.maverick-state marker.maverick-bprop marker — if present, resume block
propagation first before continuing.uv run maverick coord claim <repo> --scope <csv-of-issues>.
On ClaimRejected, abort and report per
mav-multi-instance-coordination.coord release runs at session end, so there is no
manual kill step:
for issue in <epic> <story1> <story2> …; do
uv run maverick coord heartbeat-loop <repo> $issue >/dev/null 2>&1 &
done
coord release for every claimed issue; the matching heartbeat-loop
detects the cleared label on its next iteration and exits.If the epic does not yet have a solution design:
agent-issue-analyst with the epic issue.agent-github-issue-planner — the planner will
create child stories as sub-issues (per the ≥ 5-tasks threshold in
mav-create-tasks).uv run maverick coord claim <repo> <child-issue> for each.If the epic already has stories, skip to Phase 2.
Build a machine-readable DAG of child stories.
docs/conventions/github-markers.md:
{
"epic": ,
"stories": {
"140": {"deps": [], "files": ["app/src/boot.ts"]},
"142": {"deps": ["140"], "files": ["app/src/admin/guard.ts"]}
}
}
# Write the DAG to a tmp file, then post via the GitHub App for a consistent audit trail.
uv run maverick gh-app gh -- issue comment --body-file /tmp/dag-marker.md
Alternatively, the CLI helper composes the marker for you — preferred:
construct the payload JSON and post via the App's gh with a fenced
maverick-dag block.uv run maverick dag waves <repo>
The output is a list of lists — each inner list is a set of stories with no un-satisfied deps on later waves. Record the waves in the epic's human-readable task-table comment as well, so a human skimming the epic can see execution order.
maverick-state with initial status:
pending if not yet startedmerged if already merged (detected by reading PR state)in_flight only if another instance's heartbeat is live for ituv run maverick state set <repo> <story> <status>
Each call mirrors the local cache to the maverick-state marker on
the epic.Repeat until every story is terminal (merged or ejected) or every remaining wave is fully blocked.
uv run maverick dag waves <repo> .uv run maverick state show <repo> .blocked-by:#N — re-read the labels at
selection time so human-resolved ejections automatically unblock.maverick-state.Resolve the story base branch from config:
STORY_BASE=$(uv run maverick git-workflow story-base)
For each unblocked story in the wave, decide its base branch:
mav-stacked-prs.$STORY_BASE.Create the worktree:
uv run maverick worktree create <branch> [--base <sibling-branch>]
Decide based on:
MAX_CONCURRENT_WORKTREES=4 active at once.If parallel: dispatch one subagent per worktree, running
do-issue-solo for that story inside that worktree. Track
the subagents and aggregate results.
If serial: iterate worktrees one at a time, running
do-issue-solo in each.
For each story being worked on (whether as subagent or serially):
uv run maverick coord heartbeat <repo> <story>
— if the story now carries blocked-by:#N, abort without pushing.do-issue-solo's per-story phases
(Phase 4 onward — branch is already created).ejected in epic state:
uv run maverick state set <repo> <story> ejected.mav-block-propagation:
maverick-bprop marker on the epic.blocked-by:#<story> to each.maverick-bprop marker when the walk completes.merged in epic state.When every story in the wave is terminal (merged or ejected):
maverick-state one last time.uv run maverick coord release <repo> --reason complete.heartbeat-loop background processes self-terminate within one
--interval window once their claims are released — wait for them
if you backgrounded them with PIDs, or just let the parent shell exit.do-issue-solo Phase 10, but the epic
itself spans multiple branches/PRs, so the simple close-on-merge
CLI doesn't fit — query the policy and decide:
policy=$(uv run maverick issue policy)
if [ "$policy" != "manual" ] && [ "$ejected_count" -eq 0 ]; then
gh issue close \
--comment "Epic complete: $merged_count stories merged."
fi
If any stories were ejected, leave the epic open for the human to
resolve them and close manually. If the policy is manual, leave
the epic open regardless — the team's promotion workflow handles
final close.At any entry, if another instance was mid-flight:
maverick-bprop marker means a block walk was in progress — resume it
per mav-block-propagation.maverick-claim on some stories with a stale lease means an instance
died — decide takeover per mav-multi-instance-coordination.maverick-state with stories marked in_flight but no live claim
means those stories are orphaned — reclaim and resume, or mark back to
pending if the worktree was destroyed.The workflow is idempotent on every entry — you can re-run do-epic on
the same epic any number of times and it will converge to the same final
state.
maverick gh-app status does not report configured: true.agent-code-reviewer. No fix loop.development
--- name: do-test description: Write or update tests for a code change. Operates in two modes: `unit` (module-scoped, fast, deterministic) and `integration` (crosses module / service / database boundaries). Intended to be invoked once per testable change from inside a do-issue-* or do-epic phase. Mode is required. argument-hint: mode: unit or integration user-invocable: true disable-model-invocation: false --- **Depends on:** mav-bp-unit-testing, mav-bp-integration-testing, mav-local-verificati
development
Implement a focused code change. Use this skill as the wrapper for any implementation work so the Maverick workflow report captures what was done and so the agent applies the project's coding standards before editing. Intended to be invoked once per task from inside a do-issue-* or do-epic phase, not standalone.
testing
How to stack a PR on top of an unmerged sibling branch, and how to retarget it to the repo's default branch once the sibling merges. Prevents orphan-merge incidents when a dependent story is ready before its parent.
development
Claim, lease, heartbeat, and release protocols for when multiple Claude Code instances may act on the same issue or epic concurrently. GitHub labels and marker comments are the coordination surface; local state is a cache.