Skip to content
Back to skills

Implement

ASecurity

Orchestrates the full agent-pack pipeline for a task: git-engineer → [tech-lead] → engineer(s) → code-reviewer → [security-reviewer] → [performance-reviewer] → smell-reviewer → test-engineer → merge-reviewer → git-engineer (push/PR). Use when implementing a feature, fix, or change end-to-end. Trigger this when someone says: implement this, build this feature, make this change, add this functionality, code this up, I need this feature built, ship this. Do NOT use for targeted bug fixes with a ...

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 13, 2026
developmenttypescriptrustgoc#shellbashsqlvuenodeazure

Works with

  • api
  • mcp

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 13, 2026

npx -y skills add chuckplayer/claude-agent-pack --skill implement --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Implement?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Implement
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chuckplayer-implement/badge)](https://www.skillsdirectory.com/skills/chuckplayer-implement)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: implement
description: "Orchestrates the full agent-pack pipeline for a task: git-engineer → [tech-lead] → engineer(s) → code-reviewer → [security-reviewer] → [performance-reviewer] → smell-reviewer → test-engineer → merge-reviewer → git-engineer (push/PR). Use when implementing a feature, fix, or change end-to-end. Trigger this when someone says: implement this, build this feature, make this change, add this functionality, code this up, I need this feature built, ship this. Do NOT use for targeted bug fixes with a known root cause — use /hotfix or /debug instead. Do NOT use for pure restructuring with no behavior change — use /refactor instead."
---

# Implement Task

Run the full agent pipeline for the task the user described:

0. **Work-item mode — resolve and read an Azure DevOps item. Opt-in, and it performs no writes.**
   **This step runs only when a work item id is available**, from one of two channels:
   - a **work item id** passed with the invocation, or
   - a `work_item:` key in the frontmatter of an adopted plan (step 2).

   **An explicitly passed work item id wins over the key**, and if the two disagree, **say so out loud** — name both values and which one this run uses. Never resolve that silently.

   **No work item id in either channel → work-item mode does not run.** Steps 0, 1a, 10c and 11a are skipped, the run says so **once**, and everything else proceeds normally. **This is the default and the common case**, and it is what keeps `/implement` working against a repository with no tracker at all. Do not treat the absence of a work item id as a problem to report repeatedly.

   When a work item id is available, do all of this **without writing anything**:

   **Validate the work item id before it touches any command.** It must match **`^[0-9]+$`** — an Azure DevOps work item id is a positive integer and nothing else. **Apply this to both channels**, the explicit argument and the `work_item:` key, and **stop on a failing value; never sanitise it.** This is not defensive decoration: the key is read from a **hand-editable plan file**, so it is attacker-influenceable in exactly the sense a backlog tree is, and everything else this mode interpolates is already shape-checked — the commit SHA against `^[0-9a-f]{7,40}$`, `<N>` as digits, titles by the stop-list in `skills/devops-azure/batch.md` 8f, area and iteration by identity against an enumerated set. **The id was the one value with the most direct editable channel and no check at all.**

   **Then read `{{AGENT_PACK_REFS}}/implement-work-item-mode.md` and follow its "Step 0 (continued)" section** (if that path is relative, prefix it with the project root). It holds the read command, reading the item as task input, resolving the project and the state names, the previews, `preview only`, and the stop on an id that will not resolve. **If it cannot be read, stop work-item mode loudly:** name the path that failed, make **no** ADO write, and ask the user whether to continue code-only. Do not run steps 1a, 10c or 11a from memory. "Code-only" means steps 1a, 10c and 11a are skipped and no work item id is handed to merge-reviewer, so its gate 4b reports `not applicable`. **Whether or not you have read the reference, every `az` call in this mode goes through the interpreter beside the shim, never bare `az`, and every write is previewed and confirmed by the operator before it runs.**

1. **git-engineer** — always first. Confirm the working branch is correct before any code changes.

   **After git-engineer returns:** check the current branch with `git branch --show-current`. If the branch is still `main` or `master`, **stop immediately** and output:

   > **Cannot proceed:** Engineer agents use worktree isolation, and worktrees must not be created from `main` or `master`. Please switch to a feature branch first, then re-run `/implement`.

   Do not invoke any further agents until the user is on a non-main/master branch.

1a. **Set the work item in progress and assign it. Runs only in work-item mode, and only after step 1's branch check has cleared.**

   **The procedure — one preview, one confirmation, one invocation — is in `{{AGENT_PACK_REFS}}/implement-work-item-mode.md` ("Step 1a")** (if that path is relative, prefix it with the project root). **If it cannot be read, make no ADO write**, say so, name the path, and ask whether to continue code-only.

2. **tech-lead** — invoke if the task is ambiguous, spans multiple concerns, or touches more than three files. Skip for well-scoped, single-file tasks.

   **Adoption rule — check this before invoking tech-lead.** If the caller passed a `plan_id` and path (typically from `/plan` step 5), **adopt that plan instead of re-planning**: read it, take its `## Acceptance bars` and any `## Model Overrides` from the file, and skip tech-lead entirely. Re-planning would write a second plan file for the same work and discard the bars devils-advocate already pressure-tested.

   Adoption is **opt-in and explicit**. Never glob the plan directory looking for a plan — a file in `docs/plans/` may govern a different branch's in-flight work, and adopting it would run this pipeline against the wrong acceptance criteria. Three cases:

   - **A `plan_id` was passed and the file exists** → adopt it. Confirm its `plan_id` and `branch` frontmatter match this run; if either disagrees, stop and ask the user rather than guessing which is right. Read its `## Model Overrides` section into the same notes step 5 would have taken from tech-lead's chat output — see the adoption note in step 5.
   - **A `plan_id` was passed but no file exists at that path** → stop and tell the user. The caller asserted a plan; its absence is a real problem, not a reason to quietly re-plan.
   - **No `plan_id` was passed** → no plan governs this run. Invoke or skip tech-lead on the normal criteria above, and merge-reviewer's gate 4a will report "not applicable". This is the common case.

   When you adopt a plan, carry its `plan_id` and path through to steps 9 and 10. (Creating a plan is `/plan`'s job — it owns the directory resolution and the write instruction. `/implement` adopts; it does not create.)

   **On adoption, validate the plan's structure before invoking anything else.** Blocking gate, same footing as 5c:

   ```bash
   bash scripts/lint-plans.sh <the path you were handed>
   ```

   Pass the path as a **discrete argument** — never interpolated into a longer shell string, for the command-substitution reason `{{AGENT_PACK_REFS}}/plan-gate.md` sets out in full (if that path is relative, prefix it with the project root). Pass only the plan handed to this run; the script never globs the directory. If `bash` is not on the shell's PATH, use the Bash tool rather than skipping.

   **A non-zero exit stops the run** — report the failure and ask the user to fix the plan. This is worth one command at the start: `/implement` adopts plans it did not write, and a plan handed in by a caller other than `/plan` may have been through neither tech-lead's writer nor devils-advocate's audit. Without this, a plan missing `## Deviations` or carrying an untyped `Evidence:` line fails at merge-reviewer's gate 4a instead — after every engineer, reviewer, and test stage has already run. `[--] ## Deviations still holds its sentinel` is **not** a failure here; step 10 is where that section gets filled in.

3. **devils-advocate** — invoke before implementation if the task introduces a new pattern, a new dependency, or an irreversible architectural change. Skip for small bug fixes and established patterns.

   **If a plan governs this run, pass it the plan path and ask it to pressure-test the plan file in place** — both the acceptance bars and the entries in `## Calls made for you`. It holds `Write`, and it is the only check on either. Ask it to flag any bar whose `Evidence:` line names something that cannot be produced, and any stated call that names no concrete artifact (a quality or a pattern name rather than a dependency, file, type, or value) — those have no lookup target, so merge-reviewer's Tier 3 skips them by construction and they enforce nothing. Sharpen them or mark them as documentation for the human. This is the same duty `/plan` step 3 carries; on the adoption path `/plan` already ran it, so skip it rather than repeating it.

   **If devils-advocate edited a plan file in this run, re-run `scripts/lint-plans.sh` on it** — same command and same blocking rule as the step 2 adoption run. It edits bars in place, so it can introduce a `Gated:` field with no `Cost:` line, a row-6 failure that did not exist when the plan was adopted. This applies only when devils-advocate actually edited a plan *here*; on the adoption path it did not run at all and `/plan` already covered both the challenge and the lint.

   **Expect a `## Challenge` section appended to the plan** — devils-advocate persists its narrative findings there before composing its reply, so a stall cannot take the judgement with it. That is expected output, not drift, and it is **not** a substitute for the report: a plan with a fresh `## Challenge` section and no report means the stage did not complete. Re-request once; if that is silent too, record "challenge findings written to the plan; narrative verdict never received" rather than treating the edits as a pass.

3a. **Obsidian sync requests** — tech-lead (step 2) and devils-advocate (step 3) write memory files to `./memory/` but cannot reach the vault themselves; neither grants `Bash` or `Agent`. If either one's output ends with an `## Obsidian sync request` section, you own the dispatch:

   - Check `$env:OBSIDIAN_VAULT_PATH`. If empty, skip silently.
   - For each memory file listed, dispatch **obsidian-writer** with the same field set as step 10b (`write_mode: "capture"`, plus the vault and project values; obsidian-writer reads REST config from the environment itself), using the description on that file's line as `title` and the file's full content (frontmatter + body) as `body`.

   Do this before invoking any engineer — the point is that the decision is searchable at write time, not at session end. If obsidian-writer errors, continue; the `memory/` file is the authoritative record.

4. **api-designer** — invoke before engineer agents if the task creates or significantly modifies API endpoints. Skip for internal refactors that do not change the API surface.

5. **Engineer agents** — before invoking each engineer, check for model overrides from earlier planning stages:
   - If tech-lead (step 2) output includes a `## Model Overrides` section naming this agent, note the specified model.
   - **If step 2 adopted a plan instead of invoking tech-lead**, read `## Model Overrides` from the adopted plan file — there is no tech-lead chat output to read on that path. Without this, an escalation devils-advocate pressure-tested during `/plan` silently fails to apply to engineer dispatch.

   **If a plan governs this run, carry its stated calls into each engineer's prompt.** Engineers run under `isolation: "worktree"` and **cannot see the plan** — it sits uncommitted in the primary working tree, so it does not exist in their checkout. Read `## Calls made for you`, select the entries that bear on that engineer's slice, and paste them **verbatim** into the dispatch prompt. Do not paraphrase: a summarised call is one the engineer cannot recognise itself departing from, which is where the signal dies.

   Then require the departure report in the handoff:

   > The plan for this work states the following calls. Follow them unless you have a concrete
   > reason not to. Either way, end your handoff with a line reading
   > `Departures from stated calls:` — list any call you did not follow and what you did instead,
   > or write `none`. An absent line is not a "no", so do not omit it.

   An explicit "none" matters: it distinguishes *the engineer followed the plan* from *the engineer was never asked*.
   - If devils-advocate (step 3) output includes a `## Model Escalations` section naming this agent, use that model instead (it takes precedence over tech-lead).
   - Pass the `model` parameter to the Agent call only when an override or escalation is present. Otherwise, let the agent use its frontmatter default.

   Invoke based on file types, always with `isolation: "worktree"`:
   - C# / .NET changes: **csharp-engineer**
   - TypeScript / Vue 3 changes: **frontend-engineer**
   - MCP server changes: **mcp-engineer**
   - Schema, migrations, SQL: **database-engineer**
   - Run csharp-engineer and frontend-engineer in parallel if both are needed and there are no shared files between them.

   **Worktree base:** The `isolation: "worktree"` parameter only creates each worktree from the current feature branch's HEAD if `worktree.baseRef` is set to `"head"` in settings.json. If that setting is unset or `"fresh"`, the harness bases the worktree on local/origin `main` instead — silently, regardless of what branch you're actually on. Do not assume the setting is correct; verify with step 5b below.

   When each agent completes, the worktree path and branch name are both returned. Collect both — pass the **branch names** to merge-reviewer in step 10 and retain the **worktree paths** in case the pipeline fails or is abandoned before merge-reviewer runs (step 10a).

5b. **Verify worktree base** — immediately after each engineer agent returns from an `isolation: "worktree"` call, before ts-linter or code-reviewer sees the code, confirm the worktree actually branched from the feature branch:

   ```bash
   git merge-base --is-ancestor <feature-branch> <worktree-branch>   # correct base?
   git log --oneline <feature-branch>..<worktree-branch>             # any commits at all?
   git -C <worktree-path> status --short                             # uncommitted work?
   ```

   **Both questions matter, and the second is the one that has actually bitten.** Ancestry being correct does not mean there is anything to merge: engineers are told not to commit (merge-reviewer owns commits), so a worktree branch routinely has **zero commits** while the work sits uncommitted in the worktree. `git merge-base --is-ancestor` is trivially satisfied in that state, so step 5b passes, and merge-reviewer's Step 0 then runs `git merge --no-ff` on a branch with nothing on it — merging nothing, reporting success, and **silently stranding the engineer's work**. That is the failure in `memory/known-issues/2026-07-15-worktree-isolation-bases-off-main.md` arriving through the *green* path.

   - **Exit 0 and the commit list is non-empty:** safe — the worktree contains every commit on `<feature-branch>` and has work of its own. Proceed.
   - **Exit 0 but the commit list is EMPTY while `status --short` shows modifications:** the work exists but is uncommitted, so a plain merge would transfer nothing. Do **not** rely on `git merge --no-ff`. Tell merge-reviewer this branch needs the transplant path, or resolve it here: diff the worktree, confirm parity, and apply the change in the primary tree.

     ```bash
     diff <(git diff -- <file>) <(git -C <worktree-path> diff -- <file>)   # prove parity FIRST
     ```

     Proving parity before discarding the worktree is what makes "re-apply it yourself" safe rather than a silent re-implementation that might differ.
   - **Exit 0, empty commit list, and a clean worktree:** the engineer changed nothing. Treat that as a finding and ask why before proceeding — a no-op handoff reported as success is its own bug.
   - **Non-zero exit:** stale base — the engineer edited files starting from `main`, not `<feature-branch>`, so its diff may be missing feature-branch-only changes to the same files. Stop before continuing the pipeline and repair in place:

     ```bash
     git -C <worktree-path> diff "$(git -C <worktree-path> merge-base main HEAD)" > /tmp/<worktree-branch>.patch
     git -C <worktree-path> reset --hard <feature-branch>
     git -C <worktree-path> apply --3way /tmp/<worktree-branch>.patch
     ```

     This captures the engineer's full delta (committed and uncommitted) relative to its true starting point, then replays it on the correct base — sidestepping the bad ancestry instead of trying to merge two unrelated histories. If `git apply` reports conflicts, stop and route back to the originating engineer with the conflicting file list; do not resolve conflicts yourself.

   This check exists because `isolation: "worktree"` defaults to basing new worktrees on `main` (see step 5's Worktree base note) — a harness behavior the pack cannot override, only detect and repair after the fact.

   > **Test requirement:** Per CLAUDE.md, every engineer must verify existing tests pass and flag coverage gaps before handing off. Do not proceed to code-reviewer if an engineer reports failing tests.

5a. **ts-linter** — invoke immediately after **frontend-engineer** or **mcp-engineer** completes, before code-reviewer. Pass the list of modified `.ts` and `.vue` files. If ts-linter returns FAIL, route back to the originating engineer for fixes before continuing. Do not proceed to code-reviewer until ts-linter returns PASS or SKIP.

   If both frontend-engineer and mcp-engineer ran in parallel, invoke ts-linter **once** after both complete, passing all modified `.ts` and `.vue` files from both engineers combined.

5c. **lint-agents** — run whenever the changeset touches **`agents/`**, **`skills/`**, **`references/`**, **`CLAUDE.md`**, or **`docs/CLAUDE.template.md`**, after the files are written and **before code-reviewer**. The last three are on the list because the linter also checks every on-demand reference pointer, and a changeset that only renames or deletes a reference would otherwise skip the one check that finds the dangling pointer. This is a **blocking gate**, on the same footing as ts-linter:

   ```bash
   bash scripts/lint-agents.sh
   ```

   Run the script directly rather than invoking the `/lint-agents` skill — that skill exists for manual, user-invoked runs, and this is orchestration. On a machine where `bash` is not on the shell's PATH, use the Bash tool rather than skipping the step.

   A **non-zero exit fails the pipeline** — exit 1 is a finding, exit 2 means the linter's own self-test failed and its result cannot be trusted. Route the specific failure back to whoever wrote the file, fix it, and re-run until it exits 0. Do not proceed to code-reviewer on a FAIL: a malformed `description` is the routing contract itself, so an agent or skill that fails this check may be undispatchable or mis-routed no matter how good its body is, and a code-reviewer PASS on it means nothing.

   **Skip only when none of `agents/`, `skills/`, `references/`, `CLAUDE.md` or `docs/CLAUDE.template.md` appears in the changeset**, and say so explicitly rather than silently.

   > **Why this is a step rather than a suggestion.** The batch-write cut shipped `skills/devops-azure/SKILL.md` with a description of 1346 characters against a 1024 limit, through code-reviewer, security-reviewer, test-engineer, and merge-reviewer's gate, into two pushed commits. The check that catches it existed the whole time and took one command; nothing in the pipeline ran it. A mechanical check catches a class of defect that careful prose review demonstrably does not.

5d. **Obsidian hook tests** — run whenever the changeset touches **`scripts/obsidian-stop-hook.js`** or **`scripts/obsidian-context-hook.js`**, after the files are written and **before code-reviewer**. **Blocking gate**, same footing as 5c:

   ```bash
   node scripts/obsidian-stop-hook.test.js
   ```

   No npm install, no dependencies — Node stdlib only, so there is no setup step to skip. A **non-zero exit fails the pipeline**; route the failure back to whoever changed the hook and re-run until it exits 0.

   **The trigger is those two files by name, not `scripts/` as a directory.** The suite imports `obsidian-stop-hook.js` and exercises `obsidian-context-hook.js` as a subprocess; it covers **neither** the three other `obsidian-*.js` hooks **nor** any `.sh` script in that directory. Running it after a change to `check-updates.sh` produces a PASS that checked nothing relevant, which is the same false assurance 5c warns about. Say the skip out loud rather than leaving it ambiguous.

   > **Why this is a step.** 131 tests, exit 0, and until 2026-08-03 **no pipeline invoked them** — found by auditing `scripts/` for other unrun checks after 5c was added. Several are named as regressions (`"regression: it never closed"`), meaning they encode bugs already fixed once; nothing was stopping a hook edit from reintroducing one silently. This is the same class as 5c, found by asking the question 5c raised.

5e. **Identifier lint** — run on **every** changeset, after the files are written and **before code-reviewer**. **Blocking gate**, same footing as 5c and 5d:

   ```bash
   bash scripts/lint-identifiers.sh
   ```

   **This repository is public.** The script fails when a real organisation, project, host, user path, or email address appears where the placeholder convention requires a placeholder. On a failure it prints `file:line` for each hit — fix the file, do not add a suppression marker unless the line is genuinely showing an example.

   **The trigger is every changeset, and that is deliberate — there is no path-based narrowing and therefore no legitimate skip.** 5c triggers on two directories and 5d on two filenames, because each check only covers those. An identifier can be introduced by *any* file in *any* commit, so a path trigger here would be a hole rather than a scope. If it did not run, say so plainly; never let its absence read as a pass.

   **Two exit codes, and they mean different things.** Exit **1** is a finding: an identifier is present, fix it. Exit **2** means the checker's own self-test failed — it could not prove its rules fire on violating fixtures — so its verdict on the repo is worthless and must not be reported as clean. Treat exit 2 as "fix the checker first", not as a finding.

   > **Why this is a step.** The rule pre-existed and nothing enforced it: `docs/azure-devops-github-skills-brief.md` forbade hardcoded org/project names **four lines above a list of them**. Enforcing it late cost a scrub of 115 references across 20 files plus a rewrite of all 172 commits — and a force push provably does **not** remove them from a public host, so the exposure could not be fully undone. Unlike 5c and 5d, this gate cannot be justified by "a check existed and nothing ran it"; it exists because prevention is the only control that works at all.

6. **code-reviewer** — always after any engineer agent output.

7. **security-reviewer** — invoke if changes touch authentication, authorization, data access, PII, external endpoints, or secrets.

8. **performance-reviewer** — invoke if changes include database queries, API endpoints, loops over collections, or caching logic.

8a. **smell-reviewer** — always invoke after code-reviewer for any code change that introduces or modifies classes, methods, or files. Skip only for documentation-only, config-only, or SQL-migration-only changes with no application logic.

   Run security-reviewer, performance-reviewer, and smell-reviewer in parallel — they are all independent and have no dependency on each other. Omit security-reviewer and performance-reviewer when their conditions are not met; smell-reviewer always runs on code changes.

9. **test-engineer** — always last among reviewers, after code-reviewer completes. Never invoke before code-reviewer has finished.

   **If a plan governs this run, pass test-engineer the plan path** and ask it to return the bars-to-evidence mapping described in its own instructions: for every `BAR-nnn` id in the plan, what evidence actually satisfies it (`tests`, `manual`, or `files`), or `NONE` where it found none. This is the only point where a bar is connected to something real, so a gate can fail against it. Carry the mapping into step 10 — merge-reviewer cross-checks it against the plan.

   `manual` and `files` are complete answers. Work with no test surface — prompt files, docs, shell scripts — is fully satisfied by a concrete file reference or a repeatable command, and test-engineer should not be pushed to invent tests that cannot exist.

10. **merge-reviewer** — always last. Pass a summary of: the task description, which pipeline stages ran, all findings from code-reviewer / security-reviewer / performance-reviewer / smell-reviewer, whether test-engineer produced tests, and **the list of worktree branch names** collected in step 5. merge-reviewer will verify all required stages passed and commit the changes to the feature branch.

    **If a plan governs this run, also pass the `plan_id`, the plan's path, and test-engineer's bars-to-evidence mapping.** merge-reviewer's gate 4a acts on a plan only when handed one — it never searches the plan directory. Omitting these makes the gate report "not applicable" and the plan's bars go unenforced, which looks like a pass. If no plan governs this run, pass nothing and say so explicitly, so the "not applicable" verdict is a stated fact rather than an accident.

    **Before dispatching, fill in the plan's `## Deviations` section.** tech-lead wrote it as a sentinel — an italic line beginning `Deviations not yet reviewed` — and gate 4a greps for exactly that string and fails while it is present. This is deliberate: an untouched section cannot be told apart from one nobody looked at. Replace **that line only**; leave the `## Deviations` heading in place.

    Replace the sentinel with one of two things:

    - **Nothing diverged:** `None.` followed by a one-clause affirmation of what you checked, e.g. `None. Every stated call was followed as written.`
    - **Something diverged:** one bullet per departure, each naming **the stated call**, **what shipped instead**, and **who decided** — an engineer or this session:

      ```markdown
      - **Test runner: Vitest** -> shipped plain `node` + `assert` with no devDependency.
        Decided by: coordinating session, to keep the scratch project dependency-free.
      ```

    Both sources count. Collect departures from every engineer's `Departures from stated calls:` line, **and record your own** — a call you overrode while coordinating is a deviation exactly as much as one an engineer made, and in practice it is the more common case. No ids and no numbering: nothing downstream maps onto a deviation, so an id would be ceremony.

    **If a deviation makes an acceptance bar unsatisfiable, you may amend that bar — under all four of these conditions, never otherwise:**

    1. The amendment is a **named consequence of a recorded deviation**, not an independent editorial call. Record the deviation first.
    2. The deviation entry **quotes the bar id and the original wording verbatim**, so the edit leaves a trace instead of erasing one.
    3. The change is **narrowly scoped to the clause the deviation invalidated**. Do not touch other bars, and do not loosen a substantive constraint while you are in there.
    4. **Only this session amends bar text.** Engineers never edit the plan; tech-lead wrote the bar and is no longer in the loop.

    A bar whose premise a recorded deviation has falsified is testing an abandoned design — leaving it unamended fails the run on a criterion nobody intends to meet. But the licence is narrow on purpose: **if any inconvenient bar could be edited back into satisfiability, acceptance bars lose their teeth entirely**, because "unsatisfiable" would always be cheaper to fix by rewriting the bar than by fixing the code or admitting a real miss. When in doubt, leave the bar alone and let it fail — an honest FAIL is recoverable, a quietly rewritten record is not.

    Then hand merge-reviewer each engineer's departure claims alongside the plan, so its Tier 2 check can confirm every claimed departure actually reached the section.

    **If merge-reviewer returns PASS:** the changes are committed to the feature branch. Proceed to step 10a.

10a. **Worktree cleanup verification** — merge-reviewer owns worktree cleanup on the PASS path (its Step 0a removes each worktree, deletes its branch, and prunes). After a PASS, just verify nothing was left behind:
    ```bash
    git worktree list
    git worktree prune
    ```

    **Only if the pipeline failed or was abandoned before merge-reviewer ran** (or merge-reviewer stopped early on a merge conflict), clean up manually using the worktree paths and branch names collected in step 5:
    ```bash
    git worktree remove <worktree-path> --force
    git branch -D <worktree-branch>
    git worktree prune
    ```

    If a worktree path no longer exists, skip the `git worktree remove` for that path and proceed to branch deletion. Do not skip this step on failure — stale worktrees and branches accumulate in the repository and confuse future pipelines.

10b. **Obsidian capture** — after worktrees are cleaned up, record what was shipped.
     Check if `OBSIDIAN_VAULT_PATH` is set (PowerShell: `$env:OBSIDIAN_VAULT_PATH`).
     If empty, skip this step silently.

     Dispatch the **obsidian-writer** agent with:
     - `write_mode`: `"capture"`
     - `vault_path`: value of `OBSIDIAN_VAULT_PATH`
     - `projects_folder`: value of `OBSIDIAN_PROJECTS_FOLDER` (empty string if unset)
     - `project`: basename of the project directory
     - `title`: one-line description of what was shipped (e.g. "feat: add model tag to obsidian logs")
     - `body`: build from pipeline results collected during this run:
       ```
       **Shipped:** <commit SHA from merge-reviewer>
       **Branch:** <feature branch name>

       **What was built:**
       - <2–4 bullet points summarising the change>

       **Pipeline:** <comma-separated list of agents that ran, in order>
       **Key files:** <list of files changed, from merge-reviewer or engineers>
       ```

     Keep the body concise — this is a searchable index entry, not a design doc.

10c. **Close the work item and record elapsed time. Runs only in work-item mode, and only on a merge-reviewer PASS carrying an explicit advancement authorization.**

   **Do not write without an `AUTHORIZED` line from gate 4b.** merge-reviewer emits one of `AUTHORIZED for <work-item-id>`, `WITHHELD (<reason>)`, or `not applicable (no work item id passed)`. Anything other than `AUTHORIZED` means this step does not run.

   **A report carrying no advancement line at all is treated as `WITHHELD`, and that case is named here because it is the one a reader would otherwise have to infer.** Silence is not `AUTHORIZED`. It happens for a reason worth knowing: `memory/known-issues/2026-08-03-subagent-goes-idle-before-reporting.md` records agents completing correct work and never reporting, so **an absent line is a likely state, not an exotic one.** Report which of the four cases applied — one of the three defined lines, or **no line emitted** — and never describe an absent line as though a line were read. **Be clear-eyed about what that line is:** merge-reviewer makes no ADO call, so gate 4b is an **input to the confirmation below**, not the thing preventing a bad write. The control is the operator reading the command.

   **The procedure — one preview, one confirmation, one invocation — is in `{{AGENT_PACK_REFS}}/implement-work-item-mode.md` ("Step 10c")** (if that path is relative, prefix it with the project root): the command, the comment text and its validation, why no hours are set, and what a merge-reviewer FAIL means for the tracker. **If it cannot be read, make no ADO write**, say so, name the path, and give the operator the close-out to do by hand.

11. **git-engineer (push/PR mode)** — invoke after merge-reviewer returns PASS. Ask the user whether to push the feature branch and optionally open a pull request. Pass the feature branch name and the commit SHA from merge-reviewer.

    **If merge-reviewer's PASS report flagged mergeability conflicts against the base** (its step 3c advisory), surface them to the user *before* they open the PR — resolving conflicts locally now is cheaper than after GitHub/Azure's automatic review flags them. This is advisory: it does not block the push, but the user should decide whether to rebase/merge the base branch and resolve conflicts first.

    **If merge-reviewer returns FAIL:** begin a retry cycle:
    - Route each failed item back to the agent responsible (e.g., Critical code finding → engineer agent, missing tests → test-engineer).
    - Engineer agents on retry also use `isolation: "worktree"`. Re-run step 5b's ancestor check against each new worktree before trusting it — retries are exactly as susceptible to the stale-base problem as the first pass.
    - Add any new worktree paths and branch names to the collected lists.
    - After fixes, re-run steps 6–10 (code-reviewer through merge-reviewer). **A retry rewrites `## Deviations`** — step 10 runs again, so a fix that changes what shipped updates the section for free. This is why the section is written at step 10 rather than step 9: written earlier, a retry would leave it stale and the gate would then enforce a stale record, which is worse than no record at all.
    - Allow up to **2 retry cycles** total. If merge-reviewer still returns FAIL after 2 retries, stop and surface the unresolved FAIL report to the user for manual resolution.
    - On final failure, still run step 10a cleanup — do not leave retry worktrees behind.

11a. **Link the work item to an Azure Repos PR. Conditional, and usually skipped.**

   Runs **only** when an **Azure Repos pull request id** is actually available — either a `dev.azure.com` PR URL returned by git-engineer, or a **PR id** the operator supplies. **Otherwise report skipped and name the reason.**

   **The mechanics are in `{{AGENT_PACK_REFS}}/implement-work-item-mode.md` ("Step 11a")** (if that path is relative, prefix it with the project root): why a PR id is not a work item id, and why this step is usually skipped. If it cannot be read, skip this step, say so, and name the path.

Do not skip steps without stating a reason. State which agents you are skipping and why before beginning.

## Gotchas

- **An in-progress work item is not evidence that a run is alive.** Step 1a sets the item in progress; nothing sets it back. If a run dies after that, the item keeps asserting work is underway, and **no component is in a position to correct it** — a dead process cannot undo its own write, and the next run cannot tell *a previous run died* from *a human set this deliberately* from *another session is working it right now*. Rolling back on that guess is worse than a stale in-progress, so **resume is offered and rollback is not**: step 0 on a still-in-progress item writes nothing and proceeds. The operator's real recovery is knowing this, which is why it is written down rather than inferred.
- **Starting on main/master:** The worktree check in step 1 is critical. Engineer agents create worktrees from the current branch only when `worktree.baseRef` is `"head"` — if that branch is main, the worktree is based on main and the merge-reviewer cannot safely commit without polluting the main history. Stop hard if the branch is main.
- **`worktree.baseRef` unset or `"fresh"`:** This is the harness default and it silently bases every engineer worktree on local/origin `main` instead of the feature branch — even when step 1's check passed and the developer is correctly on a feature branch. This is exactly how engineer work has ended up stranded as uncommitted diffs after a "successful" run: the worktree never had the feature branch's commits to begin with. Step 5b's ancestor check exists specifically to catch this; do not skip it, and do not trust the "Worktree base" note in step 5 without it.
- **Worktrees left behind after failure:** If the pipeline fails or is abandoned mid-run, still execute step 10a cleanup. Stale worktrees are invisible to the user but accumulate in `.git/worktrees` and cause confusing failures on future runs.
- **Retry cycle confusion:** A retry cycle means routing a specific finding back to the responsible engineer, fixing it, and re-running from code-reviewer (step 6) through merge-reviewer (step 10). Do not re-run the full pipeline from step 1 — git-engineer, tech-lead, and api-designer do not need to re-run.
- **Parallel engineer agents writing to the same file:** If csharp-engineer and frontend-engineer both need to touch a shared file (e.g., a config file), run them sequentially, not in parallel. Parallel writes to the same file cause merge conflicts in the worktree branches.
- **Skipping ts-linter before code-reviewer:** Type errors caught by ts-linter are blocking — they invalidate the code-reviewer's analysis. Always run ts-linter immediately after any frontend-engineer or mcp-engineer output, before code-reviewer sees the code.
- **An agent that goes idle without reporting has NOT completed its stage.** This happens: on 2026-08-03 seven agents in one session finished their work correctly and went idle before sending a report. Because the work was right every time and only the report was lost, it looks indistinguishable from success — you watched the agent launch and finish, so believing it completed is the natural inference and it is wrong. **Treat a silent agent as a failed run of that stage and re-dispatch it.** Do not reconstruct its verdict, do not summarise what it "would have" found, and above all do not tell merge-reviewer the stage ran: that gate verifies stages from context, so an unreported stage passed off as complete produces a confident merge verdict about a review nobody read. Re-dispatching a read-only reviewer costs one call. Where the stage is mechanically reproducible — a test suite, `scripts/lint-agents.sh`, `node scripts/obsidian-stop-hook.test.js` — just run the command yourself instead. See `memory/known-issues/2026-08-03-subagent-goes-idle-before-reporting.md`; the stall is in the harness, so the only available defence is refusing to read silence as assent.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.