
Epic Executor
- 13 installs
- 2 repo stars
- Updated July 17, 2026
- ontoledgy/ol_ai_context_library
Helps with ai & agent building tasks.
About
epic-executor is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- epic-executor
- AI & Agent Building
- AI-coding skill
Epic Executor by the numbers
- 13 all-time installs (skills.sh)
- Ranked #11,389 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/ontoledgy/ol_ai_context_library --skill epic-executorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 2 |
| Last updated | July 17, 2026 |
| Repository | ontoledgy/ol_ai_context_library ↗ |
What it does
Helps with ai & agent building tasks.
Files
Epic Executor
Role
You are the epic lead. Given a single epic id, you:
1. Discover every child ticket under the epic (stories + their subtasks) 2. Graph their dependencies from tracker links (blocks / blocked-by) plus subtask→parent edges 3. Schedule the graph into waves via topological sort 4. Execute each wave — tickets within a wave run in parallel (isolated in worktrees), waves run sequentially 5. Delegate each individual ticket to task-executor, which handles Codex delegation, review, commit, state transition, and impl log 6. Roll up the results into an epic-level summary on the epic ticket
You do NOT write code. You do NOT directly transition individual story / subtask states — that's task-executor's job. You orchestrate.
You are a strict superset of task-executor in scope, but a subset in responsibility per ticket: the per-ticket loop is delegated.
Tracker Adapter
This skill is tracker-agnostic and shares task-executor's adapter:
tracker: jira→../task-executor/references/tracker-jira.mdtracker: linear→../task-executor/references/tracker-linear.mdtracker: ado→../task-executor/references/tracker-ado.md(Azure DevOps Boards)tracker: local→../task-executor/references/tracker-local.md(filesystem; no MCP)
It uses two adapter operations directly — discoverChildren(epicId) and getDependencies(id) — and delegates everything else per-ticket to task-executor. If tracker is not passed, infer it from the epic id format / documentation/workflow-config.md; with no tracker MCP available, default to local.
| Concern | JIRA | Linear | Azure DevOps | Local |
|---|---|---|---|---|
| Epic id | Epic issue key (TI-100) | Feature-issue labelled type:feature (ONT-27) | Feature work item (AB#100) | epic file type: epic (LOC-100) |
| Discover children | searchJiraIssuesUsingJql("\"Epic Link\" = X OR parent = X"), then subtasks | list_issues({parentId}) recursively, or list_issues({project, label:"feature:X"}) | wit_query_by_wiql recursive WorkItemLinks tree under the Feature (Hierarchy-Forward), or wit_get_work_item(expand:'relations') | Grep -l "parent: X" documentation/tracker/*.md, then per story |
| Dependencies | issuelinks (Blocks / Is blocked by) | get_issue relations (blocks / blockedBy) | relations Predecessor/Successor (System.LinkTypes.Dependency) | blocks / blockedBy frontmatter arrays |
Inputs
Required:
- Epic id (e.g.
TI-100,ONT-27, orLOC-100) or epic URL
Optional:
- Tracker —
jira,linear,ado, orlocal(inferred if absent; defaults tolocalwhen no tracker MCP is available) - Parallelism —
auto(default),sequential, orparallel.autoparallelises within a wave only when the wave has > 1 ticket AND no ticket touches files claimed by another in the same wave. - Max concurrency — integer, default
3. Caps how manytask-executoragents run simultaneously within a wave. - Working directory — defaults to current
cwd. Each parallel agent gets its own worktree under this repo. - Resume —
trueif the epic was started before; skips tickets already in Done or In Review.
Outputs
- One commit per ticket (created by
task-executor), merged back to the base branch when worktrees are used - State transitions on every child ticket
- Impl log comment on every shipped child ticket
- Epic summary comment on the epic itself: tickets shipped, tickets deferred / blocked, total +/- line stats, list of impl-log URLs
- Final return to caller: wave-by-wave execution table
---
Workflow
Step 1 — Discover Children
1. getWorkItem(epic-id) via the adapter — confirm it is an epic/feature (JIRA: Epic type; Linear: type:feature label — Linear has no separate epic level; ADO: a Feature work item; local: type: epic frontmatter). 2. discoverChildren(epic-id) via the adapter:
- JIRA: JQL
"Epic Link" = {EPIC} OR parent = {EPIC}; for each story, JQLparent = {STORY}for subtasks. - Linear:
list_issues({parentId: EPIC})for stories;list_issues({parentId: STORY})for tasks. (Or the flatlist_issues({project, label:"feature:X"}).) - Azure DevOps: a
wit_query_by_wiqlrecursiveWorkItemLinkstree under the Feature (System.LinkTypes.Hierarchy-Forward,mode=Recursive), or recursewit_get_work_item(expand:'relations')over child relations. - Local:
Grep -l "parent: {EPIC}" documentation/tracker/*.mdfor stories; per storyGrep -l "parent: {STORY}"for tasks.
3. Collect all leaf-level issues (stories with no subtasks + every subtask/task). Leaves are the units of work; a parent story closes only when all its children are done. 4. For each leaf, getDependencies(id) — capture blocks / blocked-by edges.
If the epic has zero children: stop and report "Epic is empty — nothing to execute. Populate via backlog-manager / linear-backlog-manager / ado-backlog-manager / local-backlog-manager / feature-spec-author first."
Step 2 — Build Dependency Graph
Nodes = leaf-level tickets discovered in Step 1.
Edges (directed, "must finish before"):
- Explicit tracker links:
A blocks B→ edgeA → B - Subtask→parent is not an edge between leaves (parent stories are not leaves in our model).
- Two children of the same story are not implicitly ordered unless an explicit
blockslink exists.
Detect cycles. If a cycle is found, stop and report it — cycles must be resolved in the tracker before execution.
Step 3 — Schedule Into Waves
Topological sort with leveling:
- Wave 0: nodes with no incoming edges
- Wave N: nodes whose only incoming edges come from waves
0..N-1
This gives the minimum-depth schedule. Tickets within the same wave have no inter-dependencies and are eligible to run in parallel.
Post a planning comment on the epic before execution begins:
## Epic Execution Plan — {epic-id}
Discovered {N} leaf tickets across {M} waves.
### Wave 0 ({n0} tickets, parallelism: {auto/sequential/parallel})
- {id} — {summary}
- {id} — {summary}
### Wave 1 ({n1} tickets)
- {id} — {summary} (blocked by {id})
...
Starting Wave 0 now.If resume=true: drop tickets already in Done / In Review, and recompute waves over the remainder.
Step 4 — Execute Waves
For each wave in order:
4a. Decide parallelism for this wave
sequential→ run one ticket at a time, in any order within the wave.parallel→ run all wave tickets concurrently, capped atmaxConcurrency.auto(default) → parallel if all of:- wave has > 1 ticket
- no two tickets in the wave list the same file in their description / spec's "Files to modify"
- the repo is a git repo (worktrees require it)
Otherwise sequential.
If a file-overlap conflict prevents auto parallelism, log the overlap on the epic comment and fall back to sequential for that wave only.
4b. Spawn ticket runs
Sequential mode: invoke task-executor once per ticket in turn. Wait for each to return before starting the next.
Parallel mode: spawn one Agent per ticket in a single tool message (multiple Agent tool uses in parallel), each:
subagent_type: "general-purpose"(orclaudeif your harness exposes the default)isolation: "worktree"— each agent gets a fresh git worktree off the current branch- Prompt instructs the agent to invoke the
task-executorskill on its assigned ticket
Cap the number of in-flight agents at maxConcurrency. If the wave has more tickets than the cap, dispatch in batches.
Agent prompt template (for a parallel ticket run):
Invoke the task-executor skill to ship ticket {ticket-id} (tracker: {tracker}).
You are working in an isolated git worktree off branch {base-branch}. Your
worktree has been freshly created for this ticket — assume a clean tree.
Follow the task-executor workflow exactly:
- Load context, triage complexity, move to In Progress
- Delegate implementation to Codex via mcp__codex__codex
- Review (clean-code-reviewer for complex tickets), iterate up to 3 times
- Commit with conventional-commits, move state forward, invoke the impl-logger
- Return: {commit hash, files +/-, complexity, review verdict, impl log URL, final status}
Do not touch any ticket other than {ticket-id}. Do not advance to other tickets
even if you finish early — return immediately.4c. Reconcile parallel returns
Once all agents in a wave return:
1. Each agent's worktree contains its commit(s). Merge them back into the base branch. Strategy:
- Default: fast-forward / rebase each worktree's commits onto base, one at a time, in the order the tickets completed.
- If a rebase produces a real conflict (not a trivial merge), the wave's
autoparallelism heuristic was wrong. Surface the conflict, halt that wave, and re-run the remaining conflicting tickets sequentially after resolving.
2. Clean up the worktrees (ExitWorktree if available, or git worktree remove). 3. Verify HEAD on base branch passes the language's quick check (syntax / build) — catches accidental cross-ticket interactions even when files don't overlap.
4d. Wave summary
Post a wave summary comment on the epic:
**Wave {N} complete.** {n_done}/{n_wave} tickets done, {n_blocked} blocked, {n_failed} failed.
- {id} ✅ Done — commit abc1234
- {id} ✅ In Review — commit def5678
- {id} ⛔ Blocked — see ticket comment
Starting Wave {N+1}.If any ticket in the wave is blocked or failed:
- Compute the set of downstream tickets that depend on the failed ticket (transitive closure).
- These downstream tickets are still in To Do / Backlog — leave them there. They will be skipped from future waves.
- Continue with the remainder of the graph that is not downstream of the failure.
- Record the skip in the epic summary at the end.
Do not halt the whole epic on a single ticket failure unless the user passed --fail-fast. A partial epic delivery is usually more valuable than nothing.
Step 5 — Epic Summary
After the last wave (or after fail-fast halt):
1. Compute totals: shipped / blocked / skipped, files touched, line stats, total duration. 2. Post the epic summary comment:
## Epic Execution Complete — {epic-id}
**Shipped:** {n_shipped} of {n_total}
**Blocked / failed:** {n_blocked}
**Skipped (downstream of blockers):** {n_skipped}
**Total churn:** +{lines_added} / -{lines_removed} across {n_files} files
**Duration:** {wall-clock}
### Shipped tickets
| Ticket | Summary | Commit | Impl log |
|---|---|---|---|
| {id} | ... | abc1234 | {url} |
### Blocked / failed
| Ticket | Reason |
|---|---|
| {id} | Codex iteration cap exceeded — see ticket comments |
### Skipped (will need re-run after blockers resolved)
- {id} (was downstream of {id})3. Consider whether the epic itself can move to Done:
- All children Done →
setState(epic, "Done") - Any children still open → leave the epic in In Progress and surface the open set to the user
Step 6 — Hand Back
Return a wave-by-wave table to the caller plus the epic summary URL. Stop.
---
Parallelism Safety Rules
Parallel ticket execution in the same repo is only safe when:
- Each agent runs in its own git worktree (
isolation: "worktree") — never the same working directory. - The base branch is a clean commit (or rebased to one) before each wave starts.
- Tickets in a wave do not modify the same files. The
autoheuristic checks the spec's file list; if a spec is missing or vague, default to sequential rather than guessing. - The CI / test suite is idempotent — running the same suite in two worktrees must not collide on shared resources (databases, ports). If your project's tests require a unique DB or port, force
sequentialmode and document it on the epic's planning comment.
When in doubt, fall back to sequential. The cost of sequential execution is wall-clock time; the cost of a botched parallel merge is hours of debugging.
---
Blocker Handling
A ticket-level blocker (single ticket cannot be shipped) is handled by task-executor — it moves the ticket to Blocked and posts a ticket comment.
The epic executor reacts by:
- Marking that ticket and its transitive downstream set as
skippedfor this run. - Continuing with the rest of the graph.
- Surfacing the blocker in the final epic summary.
An epic-level blocker (graph cycle, empty epic, tracker permission failure) halts execution before any wave runs. Surface the reason to the user and stop.
---
What This Skill Does NOT Do
- Does not write code —
task-executordoes (which itself delegates to Codex). - Does not design or spec the epic — that was settled in Phase 1 (
feature-spec-author). - Does not change ticket scope or estimates — replanning goes via
sprint-planner/backlog-manager/linear-backlog-manager/ado-backlog-manager/local-backlog-manager. - Does not handle multi-epic releases — one epic per invocation. For multi-epic releases see
sprint-executororol-sdd-workflow. - Does not auto-resolve merge conflicts — surfaces them and falls back to sequential.
---
References
skills/task-executor/SKILL.md— the per-ticket loop this skill orchestrates.skills/task-executor/references/tracker-jira.md·tracker-linear.md·tracker-ado.md·tracker-local.md— the tracker adapter (used for discovery + dependencies).skills/sprint-executor/SKILL.md— same wave pattern, scoped to a sprint instead of an epic.skills/jira-impl-logger/SKILL.md·skills/linear-impl-logger/SKILL.md·skills/ado-impl-logger/SKILL.md·skills/local-impl-logger/SKILL.md— invoked bytask-executorafter each ticket ships.skills/clean-code-reviewer/SKILL.md— invoked bytask-executorfor complex tickets.- Codex MCP:
mcp__codex__codex(viatask-executor).
---
Feedback
If the user corrects this skill's output due to a misinterpretation or missing rule in the skill itself (not a one-off preference), invoke skill-feedback to capture structured feedback and optionally post a GitHub issue.
If skill-feedback is not installed, ask the user: "This looks like a skill defect. Would you like to install the `skill-feedback` skill to report it?" If the user declines, continue without feedback capture.