Imported from williamthorsen/codeassembly (
packages/agents/content/skills/implement-plan/SKILL.md). Install upstream withnpx skills add williamthorsen/codeassembly --skill implement-plan. Copyright stays with the author.
Implement plan
Implement the work a feature plan describes. This skill is the canonical path for implementing a plan: It governs the phase the same way whether the plan was produced moments ago in this conversation or handed to a fresh session on another harness, because it re-resolves everything it needs from the environment rather than relying on conversation history.
Arguments
| Flag | Effect | Default |
|---|---|---|
--plan=<path> |
The plan artifact to implement. | Auto-resolved (see below) |
--ticket=<source> |
The ticket the plan serves. Resolved per ticket source resolution. | Auto-resolved (see below) |
Scope
This skill implements a feature plan, the ## Tasks / ## Verification shape the plan template defines. A spike plan has ## Investigation steps and a ## Deliverable instead (see spike conventions): It is carried out to produce findings rather than implemented to produce a diff, and none of the steps below read its shape. Step 4 turns one away.
The contract
The ticket's acceptance criteria are the contract; the plan is the mechanism by which they are met. When the plan and the facts on the ground disagree, the acceptance criteria decide: A plan step that no longer serves them is the one to abandon.
The plan artifact is read-only. It is a record of what was decided at plan time, and a later reader compares it against the diff to see how implementation departed from it. Never edit it to match what was built: Lifecycle events and the commits themselves record progress.
Process
-
Get context: Invoke
node {harness_home_dir}/skills/derive-session-context/derive-session-context.mjsvia Bash. The bundle emits the session-context manifest JSON to stdout; extractdefault_branch,ticket_id,ticket_ref,ticket_url,scm,project_slug, andartifact_base_dirfrom it. Then emitskill.started(payload{"skill":"implement-plan"}) per Lifecycle events. -
Resolve the plan: Stop at the first source that yields one:
- Explicit
--plan=<path>: Read it. - Already in context: This session produced or read the plan. Use it as-is; do not re-read the file.
- Newest plan for the ticket: The newest of
*_plan.mdand*_plan-v*.mdunder{artifact_base_dir}/projects/{project_slug}/tickets/{ticket_id}/(run subdirectories included), by the greatestYYYYMMDD-HHMMSSZfilename prefix. Both forms have that prefix, so they sort chronologically together and the lexicographically greatest is the newest across the two.refine-planwrites its revision as_plan-v2.mdunder a later prefix than the plan it revises, so matching both forms is what lets a refined plan take precedence over the original it supersedes. Do not widen to*_plan*.md, which also matches the_plan-review.mdartifact written beside the revision. - Ask: No plan is resolvable. Ask the user for a path rather than implementing from the ticket alone: A caller who invoked this skill has a plan in mind.
Announce the resolved path and its timestamp before executing anything. Several plans can exist for one ticket, and the newest is not always the intended one: This announcement is how the user catches a superseded plan while the choice is still free. It is not ceremony, and it is not skippable when the resolution was unambiguous.
- Explicit
-
Resolve the ticket: Stop at the first source that yields one:
- Explicit
--ticket=<source>: Resolve per ticket source resolution. - Already in context: This session already resolved the ticket. Use it as-is.
- Stored URL:
ticket_urlfrom step 1, fetched per Stored ticket URL. - Plan provenance: The plan's frontmatter
ticket_ref/ticket_id, resolved per auto-resolve. - No ticket: Every source failed; the plan was produced from a free-form description, or the ticket is unreachable. Announce that no ticket governs the run and execute against the plan as the sole contract. Do not stall on a missing ticket; do not silently substitute the plan for one without saying so.
- Explicit
-
Read the plan and the ticket in full before touching code, including the plan's
## Riskssection: It names where the author expected the work to need adaptation.Check the shape as you read: A plan with
## Investigation stepsrather than## Tasksis a spike, which this skill does not implement (see Scope). Emitskill.completed(payload{"outcome":"stopped: spike plan"}) per Lifecycle events, then stop and tell the user the plan is a spike, to be carried out directly rather than implemented here. -
Execute the tasks in plan order. Each task is done when its own acceptance criteria are met, not when its files have been touched. Task order encodes dependencies; do not reorder for convenience. Audit the comments you write along the way per Comment discipline.
Raise material divergence to the user before proceeding, rather than rerouting silently. Material means the plan's approach no longer fits what the code turns out to be: A named file or symbol does not exist, a task's premise is false, or meeting the acceptance criteria requires an approach the plan did not consider. Adapting details within the plan's approach (a different helper name, an extra test case, a step that turns out unnecessary because the code already does it) is ordinary implementation; carry on and note it in the closing summary.
Commit each task's work as its own commit with the
{skill:create-commit}skill. Everything the closing menu offers reads committed history, so work left uncommitted is work the next step cannot see. -
Audit the diff per Diff audit. The audit runs over the work of every task, ahead of the gates, so a repair it forces is itself covered by them. A repair made once the tasks are committed, whether the audit forces it or a gate does, is committed the same way: amended into the commit it corrects, or made as a commit of its own, composed with the
{skill:create-commit}skill. -
Run the plan's verification gates. Execute the
## Verificationsection's checks and report the actual results. A gate that fails is not done: Fix the cause, or report the failure. Never claim a gate passed without having seen it pass. -
Report completion. Route each fact surfaced by the run per Fact routing, then summarize what was built against the ticket's acceptance criteria, naming any criterion left unmet and any divergence from the plan. Every sentence of that summary is read back from the diff per Diff audit, a criterion reported unmet as much as one reported met. Then emit
skill.completed(payload{"outcome":"plan-implemented"}) per Lifecycle events. -
Present next steps following next-steps options. As you present the menu, emit
input.requested(payload{"prompt":"next-steps"}) per Lifecycle events.
Fact routing
The audience decides where a fact goes. A fact that the user acts on, such as a decision that is theirs or a divergence that they must weigh, belongs in the response. A fact that a reviewer acts on belongs in the commit body, the pull-request description, or a comment in the source. A fact needed by both goes in the artifact and may be summarized in the response; the artifact is never skipped.
The failure that this prevents is phrasing-shaped, so it has a tell: Any wording that casts the reader as an intermediary, such as "worth a reviewer's attention", "flag this in review", or "mention that...", marks a fact that belongs in an artifact. Where one surfaces after the artifact is written, amend the artifact rather than narrate the gap.
None of this suppresses the closing report. Reporting what was built, which acceptance criteria are met, and what diverged from the plan is owed to the user, whose call it is what happens next.
Next-steps options
Options
| # | Emoji | Option | Description |
|---|---|---|---|
| 1 | 🔍 | Review branch | Run a single end-of-work review pass over the branch |
| 2 | 🎶 | Orchestrated review | Run the full orchestrated review cycle over the branch |
| 3 | 🚢 | Create PR without review | Open the PR straight from the implementation |
Output format
Present all three options as a numbered list per option format. Each option has a strength marker (■■■/■■□/■□□/□□□); the recommendation rules below determine which option takes the strongest marker. Pros and cons are omitted by default; add a ➕ or ➖ line only when the realized diff presents a tradeoff that survives the option-format tests bearing on which option fits (e.g., "the shared schema changed, so consumers outside this package are affected"). Generic option properties ("structured review pass," "longer wall time") are noise and must be omitted. Include the ticket path in each skill-invoking option line; omit it when no ticket governed the run.
Options that invoke a review include context-clearing guidance:
- Review branch and Orchestrated review: Prepend "Clear context and use..."; a reviewer that watched the code being written inherits the author's blind spots, and orchestration dispatches fresh subagents regardless.
- Create PR without review: No "Clear context" prefix; the PR description is composed from this session's work.
create-prrequires the branch to be in sync with its remote and stops when it is not, so note on the option that it needs the branch pushed first.
Example (rendered for the default case, where the recommendation rules below select Review branch):
Next steps:
1. 🔍 ■■□ Review branch:
- Clear context and use the `review-branch` skill with ticket: {ticket_source}
2. 🎶 ■□□ Orchestrated review:
- Clear context and use the `orchestrate-review` skill with ticket: {ticket_source}
3. 🚢 ■□□ Create PR without review:
- Use the `create-pr` skill
Skill names for each option:
- 🔍 Review branch ->
review-branch - 🎶 Orchestrated review ->
orchestrate-review - 🚢 Create PR without review ->
create-pr
Recommendation rules
Select the recommended option by checking these rules in order and stopping at the first match. Judge the diff you actually produced, not the work the plan's author predicted: A plan-time estimate of how much review the work would need was made before anyone knew what the code would look like, and this menu is where that estimate is corrected.
- Create PR without review: The realized diff is trivial enough that a review pass would catch nothing meaningful (complexity levels 1–2): a mechanical rename, a typo fix, a single-file change with no behavioral surface.
- Orchestrated review: The realized diff turned out cross-cutting (complexity level 4): It spans packages or module boundaries, changes a shared contract, or has consequences that ripple past the change sites. Parallel aspect reviewers reach a surface that a single pass would cover only thinly.
- Review branch: All other cases (default).
Marker strengths
The selected option's marker follows how cleanly its rule matched: ■■■ where the rule's test is met squarely and the alternatives are worse on the criteria that decided it, ■■□ where the fit is good but an alternative stays defensible, ■□□ where little separates the options. Rule 3 is the cascade's fallthrough rather than a positive match, so an option selected there rarely earns more than ■■□. The other two options take ■□□ by default, and □□□ where one carries a clear drawback in the current context.