Implement a whole spec by orchestrating subagents over its ticket graph; auto-detects the most recent task folder when no argument is given.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add lttr/claude-marketplace --skill implement-spec --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Implement Spec?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lttr-implement-spec)More formats (shields.io, HTML) on the badges page.
---
name: implement-spec
description: Implement a whole spec by orchestrating subagents over its ticket graph; auto-detects the most recent task folder when no argument is given.
disable-model-invocation: true
argument-hint: [spec-or-task-folder-path]
---
## Flow at a glance
1. **Resolve input**: find the task folder and its tickets. Nothing there → stop
2. **[GATE]** spec concrete enough? Last chance to ask the user. Past this, unattended
3. **Task worktree**: own branch, the whole run happens there. User's checkout stays untouched
4. **[LOOP]** repeat until every ticket is done:
- pick the ready tickets: those whose blockers are all done
- run one implementer subagent per ready ticket, in parallel, each in its own worktree
- inside each: implement with tests → run the checks → simplify → verify criteria → done → commit
- as each returns, land its work onto the task branch one at a time (linear history), keep its notes, drop its worktree
- landed work may unblock more tickets → next round. A ticket that cannot be finished stops the whole run
5. **Wrap-up** (once): full project verification on the merged branch
6. **Fresh-context review** of the whole diff, fixes applied, outcome saved as the review record
7. **Clean up and report**: remove leftover worktrees and branches, tell the user what's done and where the branch is
Follows the `aiwork-protocol` skill. Don't enter plan mode: the spec and tickets are the plan.
## 1. Resolve input
`$ARGUMENTS` is a spec/PRD or task folder path. With no args, find the most recently modified task folder (per `aiwork-protocol` conventions). Resolve it to an **absolute path** and use that everywhere, including in subagent prompts. Locate the `tickets/` subfolder:
- **No tickets** → suggest `/to-tickets`, or `/implement <spec>` if the spec is small enough for one pass. Stop.
- **All tickets `done` but no `review.md`** → go straight to Wrap-up (§5).
- Nothing found → tell the user and stop.
## 2. Clarity gate
Before touching code, check the spec is concrete enough for an unattended run. **Warn and stop for confirmation** if any hold:
- Open questions, TBDs, or unresolved decisions
- Key technical choices (data model, API shape, file targets) unspecified
- Success criteria too vague to tell when "done"
- Content is contradictory, out of order, or otherwise corrupted
- An external service or credential the tickets depend on is unreachable or unset
Measure that last one, do not read it off the spec: ping each service the spec names and assert the config keys the tickets need. A prerequisite that only fails mid-chain costs the whole run.
The gate runs **once**, against the spec, not per ticket. A badly specified ticket discovered mid-chain doesn't stop for confirmation: resolve it with best judgment and record the gap and resolution in `implementation-notes.md`.
This gate is the **last stop**. Past it, run unattended to the end.
## 3. Task worktree
Run the whole task in its own worktree so the user's checkout stays free. Skip this only when the session is already in a worktree or the user asked to stay in the checkout. If the task already has a worktree (`git worktree list`), enter that one instead of creating a second.
1. Commit the task folder, or at least the spec and tickets. A worktree only sees committed work.
2. Run `git worktree add ../<repo>-<task-slug> -b <task-branch> HEAD`. Branch from `HEAD`, not `origin/main`, so the task folder's commit is in it. Name the branch after the task slug, and keep the worktree a sibling of the repo unless the project has its own convention.
3. Enter it with the `EnterWorktree` tool, passing `path` (not `name`, which creates its own worktree off `origin/<default>`). This skill is the instruction that authorizes the tool.
4. Bootstrap the worktree. A manually created worktree gets none of Claude Code's built-in setup. If the repo has a `.worktreeinclude`, copy each listed gitignored file from the main checkout into the same relative path (`cp --parents`). Then run the project's session-bootstrap script (e.g. `.claude/hooks/session-bootstrap.sh`) if one exists: `SessionStart` hooks don't fire for a worktree entered mid-session, so invoke it directly.
5. Re-resolve the task folder to its absolute path **inside the worktree** and use that path everywhere from here on, including in subagent prompts.
This worktree is the base for the whole run. Per-ticket worktrees in §4 branch off it and merge back, and `implementation-notes.md` is written only here.
## 4. Execution
This session acts as **orchestrator** and spawns one subagent per ticket, always, even for a lone ticket. Subagents keep the orchestrator's context clean. Parallelism is a bonus when the frontier allows it. Invoking this skill is itself the user's explicit request to spawn subagents. The `blocked_by` graph defines a **frontier** of ready tickets (`status: ready`, all blockers `done`), often several at once.
1. _(optional)_ If tickets call for codebase or documentation exploration, spawn one **exploration subagent** up front. It saves markdown notes into the task folder. Implementer subagents get a pointer to them so they can focus on implementing.
2. Spawn an **implementer subagent** for every frontier ticket, in parallel, each with its ticket path and the `<ticket-loop>` below as its instructions. Tickets that touch dependencies or the lockfile never run in parallel with other tickets: hold them until they can run alone.
A **lone frontier ticket works directly in the task worktree**. Only when the frontier holds more than one ticket does each subagent get its own worktree. Branch it off the **task branch's current tip** (not `origin/main`, not another ticket's branch) so it starts from everything merged so far:
```bash
git worktree add ../<repo>-<task-slug>-<NN-ticket-slug> -b <task-slug>-<NN-ticket-slug> <task-branch>
```
Bootstrap each ticket worktree the same way as the task worktree (§3.4): copy `.worktreeinclude` files from the task worktree, then run the project's session-bootstrap script if one exists.
Never spawn an implementer with the Agent tool's `isolation: worktree`: it creates its own `.claude/worktrees/agent-*` worktree and branch outside this lifecycle, and they leak. Create the worktree yourself as above and pass its path. The orchestrator owns every worktree's lifecycle, so subagents never create or remove one. Pass each subagent its worktree's absolute path as its working root and tell it to stay inside it, using absolute paths or `git -C` rather than assuming a working directory.
3. When a subagent returns, confirm the ticket says `status: done` and a commit landed. Then integrate it **linearly**, without merge commits: rebase the ticket branch onto the task branch's tip (`git -C <ticket-worktree> rebase <task-branch>`), resolving conflicts against the spec. Then fast-forward the task branch onto it (`git merge --ff-only <ticket-branch>` in the task worktree). Append the returned notes that clear the bar below and drop the rest. Then delete the ticket worktree and branch. Integrate one ticket at a time so a conflict is attributable. A lone ticket that worked directly in the task worktree has no branch to merge and no worktree to remove, so only its notes apply.
4. Recompute the frontier (merged work may have unblocked tickets) and spawn implementers for the newly ready ones. Repeat until no ticket remains.
5. If a ticket cannot be completed (tests won't pass, blocker discovered), let in-flight subagents finish, then stop the chain and report the state. Never mark it done. Stop every background task the run started (`TaskStop`) before reporting: pollers left running keep waking the orchestrator with news it already has.
<ticket-loop>
1. Set ticket `status: in-progress`.
2. Implement. Use `/tdd` where possible, at the seams recorded in the spec's Testing Decisions section.
3. Run the project's check command (see its scripts). Green before anything below.
4. Run `/simplify`. Skip only when the change was a small mechanical edit. Its reviewers only read a diff, so spawn them as fresh subagents: a fork inherits your full context and costs about three times as much for the same findings.
5. Run `/verify <ticket-path>` so it verifies the ticket's acceptance criteria, not just the diff. Check off `- [ ]` → `- [x]` for each criterion it passed.
6. Set ticket `status: done` and `verified:` to the passes that ran (`checks`, `behaviour`, `review`), re-running the checks first if `/simplify` changed code. Commit. Do not ask.
Returning is hooked: `verified-gate` holds the turn when a ticket goes to `done` without that evidence (see below). Set the frontmatter because the passes ran, never to get past the hook.
When a check fails because an external service is unreachable, do not poll for it. Retry once, wait at most 60 seconds, then commit what works, leave the ticket `in-progress` with the unverified criteria listed, and return. Whether to wait for infrastructure is the orchestrator's call, not yours.
Throughout: keep `implementation-notes.md` in the task folder (an `aiwork-protocol` artifact) as a short log for the maintainer. One test decides what goes in: the reader has to act on it, or would be misled without it. Write each entry when it happens.
- Work only a human can finish: a service that is down, a credential the user must set, a console change agents cannot reach. Say what to do and where.
- Anything left unverified, and what would close it.
- A decision you took where the spec was silent, and why.
- A deliberate deviation from the spec or ticket.
- A fact that contradicts the spec, a ticket, or an earlier note.
- An accepted limit, open question, or a stopped chain.
Leave out what you built, files touched, tests run, and checks that passed. Cite a file, commit, or test name instead of pasting output. Notes for later tickets belong in those tickets.
A few bullets per ticket is the budget. A ticket that went to plan and left nothing to do reports nothing at all.
Never edit `implementation-notes.md` directly: the orchestrator owns it and appends the entries you return in your final report. Likewise, never create, merge, or remove a worktree or branch. Work only in the root you were given, commit there, and let the orchestrator merge.
If a blocker forces work beyond the ticket's stated scope, make the smallest deviation that unblocks it and flag it in your returned notes. If the deviation would touch another ticket's territory, stop and return the decision to the orchestrator instead.
</ticket-loop>
## 5. Wrap-up
Runs **once**, after the last ticket, never per ticket. Skip it if `review.md` exists in the task folder and no ticket finished since. If tickets did finish after a review, run wrap-up again and save the new review as the next number (`review_2.md`).
1. Run the project's full verification gate (tests, lint, build, whatever the project defines). This is the first check of the merged branch as a whole, because per-ticket checks saw only one ticket's branch and merges ran nothing.
2. Review the whole branch diff with `/code-review xhigh --fix`. It reviews and applies fixes in its own subagent, so the verdict comes from a fresh context. Never review the diff by hand instead. Fix any findings it reported but left unapplied, then re-run the affected tests. A finding deliberately left unfixed goes into `implementation-notes.md` with the reason.
3. Save the review outcome as `review.md` per `aiwork-protocol`, with `reviewed_sha:` set to the commit the review read. Its presence marks wrap-up complete.
4. Remove any leftover ticket worktrees (`git worktree list`) **and their branches** (`git branch --merged` catches them), then commit remaining changes. Also sweep any stray `.claude/worktrees/agent-*` worktrees and `worktree-agent-*` branches whose commits are merged. Leave the task worktree on disk. Don't merge it into the user's branch or delete it.
5. Report tickets completed, commits made, review outcome, and anything left open, plus the worktree path and branch name so the user can review, merge, or open a PR.
## The verified-gate hook
Driving the app and judging the code are agent work; code cannot enforce that they happened well, but it can enforce that the **evidence** exists. The plugin's `hooks/verified-gate.mjs` runs on `Stop` and `SubagentStop`, over tickets and review reports touched recently in any worktree. It holds the turn open when:
- a ticket is `status: done` and `verified:` has no on-app pass (`behaviour`, `ux` or `human`)
- a ticket is `status: done` with acceptance criteria still `- [ ]`
- a `review*.md` has no `reviewed_sha:`, or names a commit unreachable from `HEAD`
It is active whether or not this skill ran and reaches the implementer subagents. It fails open and has no bypass.
When the hook holds you, run the missing pass. Do not edit frontmatter or tick criteria to satisfy it. If a pass genuinely cannot run, the ticket is not done: set it back to `in-progress`, record why in `implementation-notes.md`, and commit that.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!