| name | linear-epic |
| description | Orchestrate an epic — assess readiness, sequence sub-issues, implement all on a single branch, open one PR, and deliver a completion summary. Handles fresh epics, partially-completed epics, and crash recovery. |
| scopes | ["linear","slack"] |
Linear Epic
Orchestrate an epic end-to-end: assess its children, build an execution plan, implement all sub-tickets on a single feature branch, open one PR, and wrap up with a summary.
Use the linear plugin tools (linear_issue_view, linear_issue_update, linear_issue_create, linear_comment_add, etc.) for all API operations.
Phase 1: Assess the Epic
- Fetch the epic with
linear_issue (action: view). Read everything — title, description, comments, labels, child issues.
- Fetch all child issues and read each one (title, description, state, assignee, labels).
Decision tree
| Situation | Action |
|---|
| No children exist AND epic is too small to split | This isn't really an epic — delegate the entire ticket to linear-execute and stop. |
| No children exist AND epic is splittable | Run linear-prep Phase 1 (sizing/splitting) to create sub-issues. After splitting, re-fetch children and continue to Phase 2. |
| Children exist but some lack descriptions or DoD | Run linear-prep Phase 3 (context enrichment) on each under-specified child before continuing. |
| Children exist and are well-prepped | Proceed directly to Phase 2. |
All children are already Done | Skip to Phase 4 (Wrap Up). |
A child is well-prepped if it has a meaningful description (not just a title), clear scope, and enough context for the coding agent to start without guessing. Use judgment — a detailed human-written description counts as much as formal linear-prep output.
Phase 2: Build Execution Plan
Ordering
Sort sub-tickets for execution using these criteria in priority order:
[N/M] prefix — if titles use [1/5], [2/5], etc., respect that ordering.
- Dependency chain — if a child's description contains "Depends on: ENG-XX", schedule the dependency first.
- Foundation first — schema changes, config, shared utilities, type definitions before feature code.
- Backend before frontend — API/data layer before UI.
- Risk/unknowns first — external integrations or uncertain scope earlier, so blockers surface fast.
- Smallest unblocking unit — when two tickets are independent, prefer the smaller one to build momentum.
Filtering
- Skip sub-tickets in
In Review or Done state — they're already handled (committed or merged).
- Skip sub-tickets assigned to someone else — note them in the plan as "owned by [assignee]".
- The remaining tickets form the execution queue.
Post the plan
Post the execution plan as a comment on the epic using linear_comment (action: add):
## Execution Plan
**Total sub-tickets:** N | **Already complete:** X | **Skipped (assigned):** Y | **To execute:** Z
| # | Ticket | Title | Status | Notes |
|---|--------|-------|--------|-------|
| 1 | ENG-XX | [1/5] First task | 🔜 Queued | — |
| 2 | ENG-YY | [2/5] Second task | 🔜 Queued | Depends on ENG-XX |
| 3 | ENG-ZZ | [3/5] Third task | ✅ Done | Already complete |
| 4 | ENG-AA | [4/5] Fourth task | ⏭️ Skipped | Assigned to @someone |
| 5 | ENG-BB | [5/5] Fifth task | 🔜 Queued | — |
Starting execution from **ENG-XX**.
If the execution queue is empty (all done/skipped), skip to Phase 4.
Phase 3: Execute Loop
The entire epic is implemented on a single feature branch with one PR at the end. Do NOT delegate to linear-execute — that would create separate branches and PRs per sub-ticket.
3.0. Check In-Flight Work
Before setting up the branch, scan for concurrent work that might overlap with the epic's scope.
- Query Linear for in-progress and in-review tickets on the same team:
linear_issue list --team <TEAM> --state "In Progress"
linear_issue list --team <TEAM> --state "In Review"
- Query GitHub for open PRs on the target repo:
gh pr list --state open --json number,title,headRefName,changedFiles,additions,deletions
- Identify overlaps — tickets or PRs that touch the same files, same feature area, or are explicitly related (linked issues, dependency chains) to any of the epic's sub-tickets.
- Decide how to proceed:
- No overlap → proceed normally (branch off
main).
- Prerequisite PR exists (the epic depends on changes in an open PR) → branch off that PR's branch instead of
main in the next step.
- Parallel but overlapping PR (touches the same files but isn't a dependency) → read its diff to understand what's changing and avoid conflicts during execution.
- Note any overlaps in the execution plan comment so reviewers have context.
3.1. Set up the branch
- Fetch and reset to
origin/main (or a prerequisite PR's branch if Step 3.0 identified one).
- Create one feature branch named after the epic:
{epic-identifier}-short-description (e.g. eng-50-user-onboarding).
- Work in a git worktree to isolate from other concurrent agents.
All sub-tickets are implemented as commits on this branch.
For each sub-ticket:
3a. Check for interrupts
Before starting each sub-ticket, re-fetch the epic's comments (not the sub-ticket's) and scan for human interrupt signals. Look for comments containing:
pause or hold — Stop processing. Post a comment on the epic confirming the pause and which sub-ticket you stopped before. Do NOT move the epic state. Wait for a resume comment.
stop or abort — Stop processing permanently. Post a comment on the epic confirming the stop. Skip to Phase 4 to write the completion summary with current progress. Note the stop was human-initiated.
skip ENG-XX — Skip the named sub-ticket. Remove it from the queue and continue with the next one. Post a comment confirming the skip.
3b. Execute the sub-ticket
- Move the sub-ticket to
In Progress using linear_issue (action: update, state: "In Progress").
- Understand the sub-ticket — read its description, comments, and any prep artifacts. Follow the implementation prompt if one exists.
- Implement the changes on the shared feature branch. Follow existing codebase patterns and conventions.
- Verify — run the build and tests. Fix any failures your changes caused.
- Commit with a clear message that references the sub-ticket identifier (e.g.
ENG-51: add user profile schema).
- Move the sub-ticket to
In Review using linear_issue (action: update, state: "In Review"). The sub-ticket will transition to Done when the epic PR is merged and the parent epic moves to Done — Linear's parent-cascade automation handles it.
Do NOT open a PR per sub-ticket. Sub-tickets sit in In Review alongside the parent epic until the epic's PR merges; Linear cascades them to Done automatically when the parent transitions.
3c. Handle failures
If a sub-ticket fails during execution (build errors, test failures, missing access, unclear requirements):
- Post an error comment on the sub-ticket describing what went wrong, what was attempted, and what's needed to unblock.
- Move the sub-ticket back to its previous state (or
Todo).
- Skip it and continue to the next sub-ticket in the queue.
- Flag it for the epic summary — note it as failed with a brief reason.
Do NOT let one failed sub-ticket block the entire epic.
3d. Post progress
After completing (or skipping) each sub-ticket, post a progress comment on the epic:
### Progress Update
✅ **ENG-XX** — [Title] → Done
⏭️ **ENG-YY** — [Title] → Skipped (build failure — see comment on ENG-YY)
**Completed:** 3/5 | **Remaining:** 2
3e. Save checkpoint
After each sub-ticket completes, write a checkpoint file to enable crash recovery:
Checkpoint path: .vera/sessions/epic-{epic-identifier}.checkpoint.json
{
"epicId": "ENG-XX",
"lastCompleted": "ENG-YY",
"completedTickets": ["ENG-AA", "ENG-BB", "ENG-YY"],
"skippedTickets": ["ENG-CC"],
"failedTickets": ["ENG-DD"],
"remainingQueue": ["ENG-EE", "ENG-FF"],
"branchName": "eng-xx-short-description",
"timestamp": "2026-03-30T23:00:00Z"
}
3.2. Open one PR
After all sub-tickets in the queue have been processed:
- Push the branch and open a single PR covering the entire epic.
- Title: Short, descriptive (include the epic identifier)
- Description: Summary of all sub-tickets implemented, with links to each. List any skipped/failed sub-tickets.
- Link the PR to the epic's Linear session using
linear_issue (action: connect_pr).
Crash Recovery
On startup (Phase 1), before assessing the epic, check for an existing checkpoint file at .vera/sessions/epic-{epic-identifier}.checkpoint.json.
If a checkpoint exists:
- Read it and validate the epic identifier matches.
- Check out the existing branch (
branchName from checkpoint).
- Skip all sub-tickets listed in
completedTickets and skippedTickets.
- Resume execution from the first ticket in
remainingQueue.
- Post a comment on the epic: "Resuming from checkpoint — last completed: ENG-YY".
- Continue with Phase 3 from that point.
If no checkpoint exists, proceed normally from Phase 1.
Phase 4: Wrap Up
Completion Summary
Append a completion summary to the epic's description using linear_issue (action: update, appendDescription: true):
---
## Completion Summary
**PR:** [#42](link)
| Ticket | Title | Status |
|--------|-------|--------|
| ENG-AA | [1/5] First task | ✅ In Review |
| ENG-BB | [2/5] Second task | ✅ In Review |
| ENG-CC | [3/5] Third task | ❌ Failed (build error, see ENG-CC) |
| ENG-DD | [4/5] Fourth task | ⏭️ Skipped (assigned to @someone) |
| ENG-EE | [5/5] Fifth task | ✅ In Review |
**Result:** 3/5 completed, 1 failed, 1 skipped
**Stopped:** No (completed normally) | Yes (human-initiated stop) | Yes (crash, resumed from checkpoint)
Update epic state
- All sub-tickets in
In Review → Move the epic to In Review (the PR is open for review). When the PR merges and a human moves the epic to Done, Linear's parent-cascade transitions the sub-tickets to Done automatically.
- Some sub-tickets failed or were skipped → Move the epic to
In Review but note incomplete items in the summary. The human reviewer decides whether to re-attempt or descope.
- Human-initiated stop → Do NOT move the epic state. Leave it as-is for the human to decide.
Clean up
- Delete the checkpoint file (
.vera/sessions/epic-{epic-identifier}.checkpoint.json) after a successful completion.
- Clean up any git worktrees created during the session.
Edge Cases
| Scenario | Behavior |
|---|
| Epic has 0 children and is too small to split | Treat as a regular ticket — delegate to linear-execute and stop. |
| Sub-ticket is assigned to someone else | Skip it. Note in execution plan and completion summary as "owned by [assignee]". |
| Sub-ticket fails build/test | Post error on sub-ticket, skip it, continue to next. Flag in epic summary. |
All sub-tickets are already In Review or Done | Skip directly to Phase 4 — post completion summary and move epic to In Review. |
| Sub-ticket has no description | Run linear-prep Phase 3 (context enrichment) on it before executing. |
| Epic has a mix of prepped and unprepped children | Prep only the ones that need it — don't re-prep already well-scoped tickets. |
| Network/tool error mid-execution | Save checkpoint before retrying. If retry fails, skip the sub-ticket and continue. |
Notes
- One sub-ticket at a time. Do not parallelize — each sub-ticket may depend on the prior one's merged code.
- Always post progress on the epic, not just on sub-tickets. The epic is the coordination hub.
- Respect human ownership. Never take over a sub-ticket assigned to someone else.
- Checkpoint after every sub-ticket. This is the crash safety net — without it, a restart means re-doing completed work.
- The epic description is the source of truth for final status. Comments track progress; the description tracks outcomes.
- Single branch, single PR. All sub-tickets are commits on one feature branch. The PR is opened once at the end covering the entire epic.
- Follow existing codebase patterns and conventions for all code changes.