---
name: implement
description: Stage 4 of the SDD pipeline — execute a ZettelFlow task checklist (in a GitHub issue comment) test-first (red → green → refactor), one commit per advance, keeping npm run verify green and CI green on every commit on a single feature branch. Use after a tasks comment exists and the user says "implement", "build issue #N", "work the tasks", or "start coding". Drives the tdd skill.
---

# /implement — build the tasks test-first

Stage 4 of the [SDD pipeline](../sdd/SKILL.md). Work the task checklist (in the GitHub issue
comment) top to bottom using the **`tdd`** discipline. This stage is done by the main assistant
(not a subagent) because it commits to the branch and must keep CI green at every step.

## Before starting

Run `gh issue view <N>` — read the spec (body) and the plan + tasks comments. The tasks comment
has the checklist; the plan comment has the files, guardrails, and risks.

## The loop (per task)

1. **Red** — write/extend the test named in the task; run `npm test` and watch it fail for the
   right reason. Import from `@jest/globals`; resolve source via the bare aliases; extend
   `test/__mocks__/obsidian.ts` when the unit pulls in more Obsidian API (see the `tdd` skill).
2. **Green** — make the minimal change to pass.
3. **Refactor** — clean up with the suite green.
4. **Verify** — `npm run verify` (typecheck + oxlint + jest) must be green. For score tasks also
   run `npm run lint:obsidian` and confirm **no new** violations. For i18n tasks confirm
   `en.ts`/`es.ts` key parity.
5. **Commit** — one Conventional Commit per completed task/advance (constitution §IX):
   `git add -A && git commit -m "<type>(<scope>): <subject>"`.
6. **Check off the task** — mark `[x]` directly in the GitHub issue comment (edit the comment with
   `gh issue comment <comment-id> --edit-last` or find the comment id and patch it).
7. **Keep CI green** — push the branch; the CI workflow re-runs the blocking guardrails. Because
   `verify` is green locally, CI stays green. Fix forward if a push ever goes red — don't stack
   more commits on a red branch.

## Rules

- **Single branch** — one `feature/*` branch for the whole issue; never commit to `main`.
- **Never** introduce `innerHTML`, inline `el.style.*`, Title-case UI strings, bare `console.*`,
  or global `app` — they cost score (constitution §III–IV). Build DOM with `createEl`; style with
  `c()` + SCSS; log with `log`.
- **The user's theme wins** (§XV). No hex or named colour in a stylesheet, no pixel the
  `--size-4-*` grid can express, Obsidian's own classes (`mod-cta`, `clickable-icon`,
  `setting-item`, `is-active`) before inventing one, and a shape that exists twice goes in
  `src/styles/utils/mixins.scss`. The guide, with Obsidian's own wording, is
  [`docs/development/obsidian-styling.md`](../../../docs/development/obsidian-styling.md).
- Touching the **Canvas patcher**? Keep every patched access guarded and uninstalled on unload
  (§VI) — see issue #91 / the reviewer agent.
- Update the matching `docs/` page + `mkdocs.yml` nav in the **same** commit that changes behavior
  (§VIII).

## Exit → stage 5

When all tasks are checked off, do **four things before declaring done**:

### 1. Docs audit (mandatory)

For every user-facing change — new feature, changed behaviour, new config option, new action,
changed UI text — ask: *does the existing docs page cover this?*

- **New feature / behaviour change** → update the matching page under `docs/` AND check the
  `mkdocs.yml` nav (add an entry if the feature deserves its own page).
- **New action** → add or update `docs/actions/<ActionName>.md`.
- **New config option** → update the settings section of the relevant architecture page.
- **API / public surface change** → update `docs/api/ZettelFlowAPI.md`.
- **No user-facing change** (pure refactor, test, chore) → docs audit is still required; confirm
  explicitly that no doc update is needed and state why.

This audit is a **blocking exit criterion** — do not commit the implementation without it.
Docs and code travel in the same commit (or a `docs:` follow-up commit immediately after).

### 2. README placement audit — by door rank (mandatory for user-facing features)

Adoption is a first-class goal and the README is the front door. For every change that ships
something a *user* would care about, do not ask *"where do I add a row?"* — ask **what is this
capability's door rank** ([capability doors](../../../docs/development/capability-doors.md)), and
place it accordingly:

- **Rank 1–3, and it asks something of the reader** (a practice loop) → the README's **first
  screen**: one sentence, its door, a link to its page. The first screen is bounded — something else
  has to leave.
- **Rank 1–3, ordinary capability** → a **headline entry** in the README, a few lines, linked.
- **Rank 4–5 or configuration** → **one line in the generated capability reference**
  (`docs/reference/capabilities.md`; regenerate with `UPDATE_DOCS=1 npx jest capabilityIndex`) plus
  its own docs page. The README does not grow.
- **New action** → the actions page and the action count; no README row.
- **No user-facing surface** (pure refactor, internal fix) → say so explicitly.

Never *"add a row to the Features table"* — that table was removed in #588 precisely because one row
per epic produced a 69-row changelog in which nothing could be ranked. `npm test` enforces the
ceiling (`test/docs/readmeCeiling.test.ts`), that nothing shipped disappeared
(`test/docs/readmeNamesKept.test.ts`) and that this rule still reads this way
(`test/docs/placementRule.test.ts`).

Blocking exit criterion, like the docs audit.

### 3. Walk the verification script (mandatory)

Open the issue's `## How to verify` and **do it** — run every command in the automated table, then
walk the manual steps in a real vault (`npm run dev:vault`). Two outcomes are failures, not
paperwork:

- **A step does not describe reality** → fix the spec section in the same change. A verification
  script nobody has walked is worth less than none, because it will be trusted.
- **A manual step turned out to be automatable** → automate it and move it up into the table.

This is a **blocking exit criterion** (constitution §XIV): the change is not done until someone has
seen it work by following the written script.

### 4. Quality check

Run the **`obsidian-plugin-quality`** skill and the **`obsidian-plugin-reviewer`** agent on the
diff, and verify every acceptance criterion in the issue spec (body).

### 5. Close the issue via PR

**Closing the issue (constitution §X).** Commits only *reference* the issue (`(#N)`) — they never
close it. The issue is closed by the **pull request** that merges the branch to `main`: put
`Closes #N` (one line per addressed issue) in the **PR body**. Do not `gh issue close` from the
feature branch and do not put closing keywords in commit messages. "Issue closed" is realised when
the PR merges.
