---
name: aide-implement
description: >-
  Implement the solution for a spec with Test-Driven
  Development (RED → GREEN → VERIFY). Reads the existing analysis and plan,
  writes tests first, implements, and runs the quality check.
  Use when: implementing a solution with TDD, having a completed analysis and
  implementation plan, coding based on 3-solution.md.
  Do NOT use for: creation (use aide-create),
  analysis (use aide-analyze).
argument-hint: "[PROJ-XXXX or task number]"
effort: high
---

Implement the solution for a spec with TDD.

**Input:** $ARGUMENTS (all arguments after the command)

## Smart detection

Parse `$ARGUMENTS`:

**The spec:** the first word is its number, its `TODO-<name>` folder, or an issue key its title began with
- Example: `/aide-implement 55` or `/aide-implement TODO-01`

**Error handling:** If the argument is missing or has an invalid format, show:

```text
Missing argument

Usage:
/aide-implement 55               # the spec's number
/aide-implement TODO-01           # or its folder
```

---

## Workflow

The steps below are this skill's own, inside the queue's `implement`
step. Mark each one in the log, so a reader can follow the run: when it
starts, write one line `--- Step N of 4: <title> — started`, and
when it ends, one line `--- Step N of 4: <title> — done`. A step
that ends the run early says `— stopped: <why>` in place of `— done`, and one that does not apply to this run `— skipped: <why>`.
Step 3 also marks each task it takes from the plan, as it finishes it:
`--- Step 3 of 4, task K of M: <task> — done`, where M counts the
task rows of `4-status.md`'s GREEN tables.

### Step 1 of 4: Preparation

First write `--- Step 1 of 4: Preparation — started`, and when this step ends, `--- Step 1 of 4: Preparation — done`.


1. Read `specs/XX-slug/2-analysis.md` (affected files)
2. Read `specs/XX-slug/3-solution.md` (implementation plan)
3. If the spec is MEDIUM/HIGH and `3-solution.md` has no "Plan review"
   section: suggest re-running `/aide-analyze` first (proceed if the
   user declines)
4. Read the relevant coding standard (frontend or backend)
5. Read `specs/XX-slug/4-status.md`'s task tables. A step
   stopped by its time limit commits what it wrote, and that work is
   landed rather than left on a branch — so an earlier run may already
   have finished some of the steps below. A step whose task rows are
   all ✅ is done: skip it. A step whose table is marked 🔄, with some
   rows ✅ and some ⬜: keep the ✅ ones and resume at the first ⬜.
   Start at Step 2 only when every row is still ⬜ Not started.

**Where a symbol is used or defined, ask the language server first.**
When an `LSP` tool is listed, it is usually deferred: load it once with
`ToolSearch` (`select:LSP`) before the first search, then make the FIRST
search for where a function, type or constant is used or defined a
`findReferences` or `goToDefinition` call — never `grep`. It answers with
the real references, not every line that happens to contain the name.
Fall back to `grep` only when the language server gives no answer (it
errors, or the file's language has none), and for text that is not a
symbol — a message, a config key, a CSS class.

### Step 2 of 4: RED — Write failing tests

First write `--- Step 2 of 4: RED — Write failing tests — started`, and when this step ends, `--- Step 2 of 4: RED — Write failing tests — done`.


Skip this step entirely if item 5 of Step 1 found it already done;
resume it at the first unticked task if it found it in progress.

1. Read "Task 0" (the tests the plan asks for) and the acceptance
   criteria from 3-solution.md
2. Run `aide-emit-run --phase red --spec <ID>` (see [Reporting RED, GREEN and VERIFY](#reporting-red-green-and-verify))
3. Create test files — at least one failing test per acceptance criterion.
   A criterion an existing test already proves gets no second test: add
   the AC-id to that test's name instead (step 4). What a test is for,
   and what it is not, is the testing rule's "What to test"
4. **Put the AC-id in the test's name.** A test written for a criterion
   that opens with an AC-id carries that id in its own name, as the
   name's last words: `test("the total keeps counting (AC-2)", ...)`.
   The runner reads these names after the step to show, on the row the
   user ticks, which test covers which requirement — a test without the
   id is a requirement shown as untested
5. **Write a browser test for a *(browser)* criterion,** where the
   project keeps its browser tests; a project with none names that
   criterion in `3-solution.md`'s Manual testing note instead
6. **Check the list before running anything:** every AC-id in
   `3-solution.md`'s Acceptance criteria appears in at least one test
   name from steps 3-5. An id with none gets its test now
7. Run the tests — verify that they FAIL
8. Tick this step's task rows in `4-status.md` — ✅ once a row's test is
   written and confirmed to fail, not merely planned. Write the result
   with `aide-write-spec --file 4-status.md` (never Write/Edit)
9. Report the RED result briefly and continue to GREEN

### Step 3 of 4: GREEN — Implement until tests pass

First write `--- Step 3 of 4: GREEN — Implement until tests pass — started`, and when this step ends, `--- Step 3 of 4: GREEN — Implement until tests pass — done`.


1. Run `aide-emit-run --phase green --spec <ID>`
2. Implement each task from 3-solution.md's plan — before writing to a file,
   check its current line count against any limit the project's coding
   standard states (e.g. dashboard/CLAUDE.md's "Code health" section),
   and split by responsibility instead of appending past it
3. Run the tests after each task, and log the task as done
4. Verify that the tests PASS
5. Tick this step's task rows in `4-status.md` as each one's tests turn
   green. Write the result with `aide-write-spec --file 4-status.md`
   (never Write/Edit)
6. Report the GREEN result briefly and continue to VERIFY

### Step 4 of 4: VERIFY — Full suite, types, lint, build

First write `--- Step 4 of 4: VERIFY — Full suite, types, lint, build — started`, and when this step ends, `--- Step 4 of 4: VERIFY — Full suite, types, lint, build — done`.


**The whole suite is the runner's, not yours.** `aide-run-spec` runs the
project's test command once on what you deliver, and that run is the one
that decides: a green one ticks the "Run the full test suite" row, and a
red one comes back to this session as a follow-up turn with the failing
lines. Never run the whole suite yourself — not through
`aide-record-test-run`, not directly. Under load it takes ten minutes and
decides nothing.

1. Run `aide-emit-run --phase verify --spec <ID>`
2. Run the tests that cover the change: every test file this step wrote
   or changed, and the existing test files for the source files it
   changed — each file once. Red is fixed back through Step 3. A test that
   fails and has nothing to do with the change is the machine's load, not
   a fault: name it in the step's summary and go on.

   A browser test this step wrote for a *(browser)* criterion is run
   too, each file on its own and once — never the project's whole
   browser suite. Red is fixed back through Step 3 like any red test. A
   file that could not start at all (no browser on the machine) is named
   in the step's summary, never passed over in silence.
3. TypeScript check
4. ESLint
5. Build
6. Tick this step's task rows in `4-status.md` as each check above
   passes. Leave "Run the full test suite" as it is: the runner ticks it.
   Write the result with `aide-write-spec --file 4-status.md` (never
   Write/Edit)
7. Before reporting anything: confirm every row in this step's own table
   reads ✅, the full-suite row apart. This is a separate, required
   write, the last one this step makes.
8. Show a summary — ready for commit

**Find a table in `4-status.md` by its HEADING TEXT, never by its
number.** This skill's RED, GREEN and VERIFY are its Steps 2-4;
`4-status.md` has four tables for them, because its GREEN work is split
into implementing and verifying. So RED is `## Phase 1: RED`
there, this skill's GREEN covers BOTH `## Phase 2: GREEN - Implement`
and `## Phase 3: GREEN - Verify tests`, and this skill's VERIFY phase is
`## Phase 4: VERIFY` — or, on a spec whose `4-status.md` was created
before this table was renamed, `## Phase 4: REFACTOR`, the same table
under its old heading. A tick placed by matching a number in this
skill to a number there lands in the wrong table.

In a Tasks table's Status cell, write the SYMBOL its Notation section
gives — `✅`, `⬜`, `🔄` — never the word beside it, and never both
together (`✅ Completed` is wrong the same way `Completed` alone is
wrong). The dashboard reads both forms, but a file that spells the
same state two ways is a file whose own legend has stopped describing
it.

None of Steps 2-4 above ever ticks a row under a `## Acceptance
criteria` heading, if `4-status.md` has one — never tick that section,
and never touch a TICKED row's Notes cell either. Implement never writes
`Not verified` to any Status cell: the mark counts as done, so writing
it would let a run past the archive gate that only the user may open. It
never writes `Failed` either: that mark says a check made after the
deploy did not hold, and only the person who made the check can say so. Those rows name the
spec's own AC-tagged acceptance criteria, and ticking one is a judgment
only the user the spec is for can make.

**One narrow carve-out.** On a held-back spec, or a reopened spec
(`aide-reopen-spec`, files kept), taking another round on its open checks
(`core/skills/aide-analyze/references/requirements-tracing.md`'s
"A held-back spec's second round"), the Notes cell of a row that is
still OPEN (`⬜`) may be written. The Status cell of that same row, and
every cell of a row that is already ticked, stays exactly as found
regardless. On any spec that is not in a held-back or reopened round, leave every
row exactly as you found it, Notes cell included — this carve-out does
not widen the rule above it.

**The cell is REWRITTEN, never added to, and it is one or two
sentences: what is missing for a user to tick this row, and nothing
else.** The cell is a table cell a user reads to decide one thing;
four rounds' worth of appended paragraphs in it is a cell nobody reads
at all. Whatever the earlier round left there is replaced, not kept —
what each round found, ran and measured belongs in `2-analysis.md` and
`3-solution.md`, which carry a `## Round N` section for exactly that.
Nothing is missing is a cell left empty, not a sentence saying so.
One sentence is kept as it is: a cell that starts `Failed:` (what did
not hold, written when a check after the deploy failed) keeps that
sentence first until the row is ticked, because the next round reads it
as the reason the round is needed.

`aide-run-spec` writes `Workflow steps completed:` from the spec's own
commits — leave that line exactly as you found it. The same script
writes this phase's `Repo`/`Model`/`Result`/`Time spent`/`Cost` block
into `3-solution.md`'s own Tracking info — leave those lines alone too.

The percentage above it is still yours: it says how far
RED, GREEN and VERIFY got, which is the field for partial work.

A headless run gets its commit for free — this session does not run
`git commit` or `git push` itself, headless or not. Working
interactively, ASK whether to commit the work, and suggest this message
so the step is recognised the same way:

```text
Run /aide-implement for <spec-folder> (model: <tool> <model>)
```

That subject belongs to the specs repository alone. When the step also
changed the project's own code, suggest a separate commit there whose
message describes the change as a developer on the project would, and
names no tool, spec or step — the project may have nothing to do with
Aide (the git rules, "No tool in a project's history").

Add the `(model: ...)` part only when you can name your own model with
certainty. A Claude Code session is told which model it is running in
its own context, so it can write `claude claude-opus-5`; an assistant
that cannot name itself offers the bare subject without the suffix and
never guesses.

Offer it only once the verification in Step 4 has passed. A red
suite, a failing build or a step of this skill you could not finish is not a step
that completed.

### Reporting RED, GREEN and VERIFY

One Bash call at the start of Steps 2, 3 and 4, with the spec's ID:

```bash
aide-emit-run --phase red --spec 81
```

It is a fire-and-forget report, not a gate: it prints nothing, never
asks anything, always exits 0, and does nothing at all unless
`AIDE_RUN_URL` is set. A run that reports them can be followed from
the dashboard while it works; the steps still run through without
stopping.

See `references/tdd-phases.md` for the detailed workflow with commands
and expected output per phase.

IMPORTANT:
- Run all four steps through WITHOUT stopping to ask for
  confirmation — report each step's result as you pass it. Stop only
  when genuinely blocked (a decision only the user can make, or a
  step that cannot be completed)
- NEVER skip tests
- Follow the coding standard strictly
- Code blocks ALWAYS end with just ` ``` `

---

## Quality check

Use the project's own test/lint/build commands — detect them, never assume
a toolchain (see the "Project commands" section of the tools-and-scripts
rules). Example for a pnpm/TypeScript project:

```bash
pnpm test -- --run    # All tests
npx tsc --noEmit      # TypeScript check
pnpm run eslint       # ESLint
pnpm run build        # Build
```

Example for a Maven/Gradle backend:

```bash
./gradlew test        # or: mvn test
./gradlew build       # or: mvn verify
```

**The project's test command is the runner's to run.** It is the
manifest's `AIDE_TEST_CMD` (the tools-and-scripts skill, "Project
commands"), and `aide-run-spec` runs it on the step's result. A change to
Markdown files alone runs the project's documentation check instead.

---

## After implementation

1. Optional: read the Manual testing note in 3-solution.md. It names what no
   test covers and why — a thing to look at when you get the chance, never a
   step that has to be completed before the spec is done
2. Commit the changes
