implement

Implement focused changes inline using spec + rules state, with strict Open Questions gate.

SKILL.md

GitHub

Implement

Implement the next focused change from the spec using bounded context and minimal diffs.


Central Rules

  1. Never silently guess business behavior.
  2. Unresolved Open Questions block implementation.
  3. Missing spec.md blocks implementation completely.
  4. A stale plan (spec.md mtime newer than plan.md mtime) blocks implementation — re-run /sdd:plan to regenerate, or delete the plan file to fall back to discovery.
  5. Read rules.json when available and apply it.
  6. Read implementation-cache.json when available and reuse it before discovery.
  7. Avoid broad repository scans.
  8. Load only spec + rules + cache + targeted files.
  9. Use bounded retries when fixing implementation or test failures.
  10. Escalate persistent failures instead of retrying indefinitely.
  11. If SDD_NON_INTERACTIVE=1, do not ask for conversational confirmations; continue automatically between steps.

Execution Modes

Only lightweight modes are supported:

  • focused: localized change, usually <= 3 files
  • batch: several sequential focused steps with shared context reuse

No full mode.


Step 0 — Pipeline Precondition Gate (STRICT)

Before anything else, confirm a pipeline exists here:

python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py precheck

Then rehydrate non-interactive mode from pipeline state:

if [ "${SDD_NON_INTERACTIVE:-0}" != "1" ]; then
  SLUG="$(python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py resolve-slug)"
  SDD_MODE="$(python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py non-interactive "$SLUG" 2>/dev/null || echo 0)"
  [ "$SDD_MODE" = "1" ] && export SDD_NON_INTERACTIVE=1
fi

If the exit code is non-zero, abort with no writes:

✗ Cannot implement.
No active pipeline (.specwork/ missing or uninitialized). Run /sdd:start first.

Outside strict gates/failures, /sdd:implement must not pause in non-interactive mode. Allowed pauses are only:

  • unresolved Open Questions gate
  • stale plan gate
  • command/runtime failure that prevents safe continuation

Step 1 — Detect Branch

git rev-parse --abbrev-ref HEAD

Extract slug from branch name.

Expected examples:

feature/IR-45        -> ir-45
feature/ir-45-fix    -> ir-45-fix
hotfix/foo           -> foo

Normalize the slug to match files under .specwork/.


Step 2 — Load Spec, Rules, and Implementation Cache

Read:

cat .specwork/_spec/<slug>-spec.md
cat .specwork/_state/<slug>-rules.json
cat .specwork/_state/<slug>-implementation-cache.json

If the canonical spec.md generated by /sdd:start is missing, abort:

✗ Cannot implement.

Missing spec:
.specwork/_spec/<slug>-spec.md

The spec has not been drafted yet. /sdd:start bootstraps state; /sdd:spec writes
the spec. Run /sdd:spec on this pipeline branch to draft it, then rerun /sdd:implement.

Rules for this failure:

  • Do not continue using only rules.json or implementation-cache.json
  • Do not reconstruct the spec silently from prior conversation or code
  • Do not proceed based on remembered context from an earlier run
  • Require the canonical .specwork/_spec/<slug>-spec.md generated by /sdd:start

If rules.json is missing, continue with spec-only behavior and ask for clarification on ambiguous business rules.

If implementation-cache.json is missing, continue and create it at the end of this run.

Extract from spec:

  • summary
  • scope
  • behavior
  • implementation context
  • constraints
  • testing requirements
  • acceptance criteria

Apply rules from rules.json as hard constraints — it is the compact, feature-scoped checklist for this run.

rules.json is a distilled checklist, not the full rule text: it omits tables, lifecycles, and other context. The project rule files under .claude/rules/ (and any .claude/service-rules.md) are already loaded in session context — consult them for detail the checklist cannot carry. Do not go hunting other docs beyond these.

When cache exists, treat it as a fast index for this feature:

  • repositories: already identified repositories
  • patterns: validated local implementation patterns
  • related_tests: tests likely to cover behavior
  • similar_classes: classes with similar behavior to reuse
  • notes: small implementation breadcrumbs

The cache is supplemental only. It never replaces .specwork/_spec/<slug>-spec.md as the canonical implementation contract.

The cache is only supplemental. It never replaces the spec as the canonical implementation contract.


Step 3 — Validate Open Questions (STRICT GATE)

Check both files when present — the spec (always) and the plan (if /sdd:plan was run). The canonical gate scans only the body of the ## Open Questions section in each; checkboxes elsewhere are ignored. Do not re-implement this check inline — call the shared gate:

python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py check-oqs "$SLUG"

It prints each blocking file (--- <path>) with its unresolved - [ ] items and exits non-zero when any remain (spec and plan are both checked; the plan is skipped if absent).

If the exit code is non-zero, abort with no writes. Distinguish which file blocks:

✗ Cannot implement.

Unresolved Open Questions:
  - .specwork/_spec/<slug>-spec.md  (N items)
  - .specwork/_plan/<slug>-plan.md  (M items)

Resolve them in the respective file, then re-run /sdd:implement.

Rules:

  • Spec Open Questions = business behavior ambiguity. Resolve in the spec.
  • Plan Open Questions = discovery/implementation-path ambiguity surfaced by /sdd:plan. Resolve in the plan.
  • Both gates are strict and additive — a single unresolved item in either file blocks implementation.
  • If the plan file does not exist, only the spec is checked (backward compatible with no-plan workflow).

Rules:

  • Do not implement while Open Questions are unresolved.
  • Do not infer answers.
  • Do not “pick the most reasonable option.”
  • Do not partially implement around unresolved business behavior.

Step 3.4 — Plan Required Gate (STRICT, high-risk only)

High-risk / architectural work must go through /sdd:plan before any code is written — the one place the otherwise-optional plan step becomes mandatory. Triage stamps plan_required: true into .specwork/_state/<slug>-path.json for the high-risk tier; trivial, focused, and standard tiers keep the optional plan step (the vibe-coding path is preserved).

Skip this gate silently when there is no path.json (a pipeline triaged before this field existed) or the tier is not high-risk — the check returns pass in those cases.

python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py check-plan-required <slug>

If the exit code is non-zero, abort with no writes:

✗ Cannot implement.

Triage classified this work as high-risk — a reviewable plan is required before
implementation, and no plan exists yet:
  .specwork/_plan/<slug>-plan.md

Run /sdd:plan to produce it (it discovers target files and writes the approach),
then re-run /sdd:implement.

  /sdd:plan
  /sdd:implement

Rules:

  • The gate fires only for the high-risk tier and only while the plan is absent. Once /sdd:plan has written the plan, this gate passes and the Plan Staleness Gate (Step 3.5) takes over freshness checking.
  • It is deliberately strict — high-risk is the tier where skipping discovery is most costly. Trivial/focused/standard are unaffected; the plan stays optional there.
  • The gate never writes; it only blocks and instructs. It does not run /sdd:plan for the user.

Step 3.5 — Plan Staleness Gate (STRICT, only when plan exists)

If .specwork/_plan/<slug>-plan.md exists, it must have been built against the current spec. A plan generated against an older spec describes a Target Files list, an Approach, and a Risk Assessment that no longer match the current behavior — implementing against it silently skips whatever /sdd:spec (or a manual edit) added to the spec. The gate compares the spec content fingerprint stamped into the plan by /sdd:plan, so it stays correct after git stash/checkout/rebase and /sdd:pause → /sdd:restore (which reset mtimes); for legacy plans with no fingerprint it falls back to mtime.

Skip this gate when the plan does not exist (no-plan workflow — Step 4 falls back to discovery from the spec).

python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py check-staleness <slug>

If the exit code is non-zero, abort with no writes:

✗ Cannot implement.

The spec changed after the plan was built:
  .specwork/_spec/<slug>-spec.md
  .specwork/_plan/<slug>-plan.md

The plan no longer reflects the current spec — likely after a /sdd:spec refine
or a manual spec edit. The plan's Target Files, Approach, and Risk Assessment
may miss endpoints, classes, or constraints that the new spec introduced.

Re-run /sdd:plan to regenerate the plan (idempotent — overwrites in place),
then re-run /sdd:implement.

  /sdd:plan
  /sdd:implement

If you intentionally want to discard the existing plan and let /sdd:implement
discover targets from the spec directly, delete the plan file:
  rm .specwork/_plan/<slug>-plan.md

Rules:

  • This gate is strict — /sdd:implement does not silently fall back to discovery when a stale plan exists. The user must explicitly re-plan or remove the plan.
  • The gate fires when the spec content changed since the plan was stamped (fingerprint), regardless of who edited it (/sdd:spec, a manual edit, or /sdd:resync). A touch or whitespace-only save does not fire — only real content changes do.
  • For legacy plans with no fingerprint, the gate falls back to spec mtime > plan mtime (equal mtimes treated as fresh).
  • The gate never deletes or modifies plan.md. It only blocks and instructs.

Step 4 — Identify Target Files

Plan-first path (preferred when a plan exists):

If .specwork/_plan/<slug>-plan.md exists, read its ## Target Files table as the source of truth for which files to touch. Treat the plan as binding but living:

  • Use the listed files as the primary target set for this pass
  • If, during implementation (Step 5), you confirm an additional file must change that is not in the plan, append a row to the plan's ## Target Files table and to the matching cache arrays before editing it. Log the addition in the Step 8 summary as "Plan updated: +<N> file(s)".
  • Never silently touch a file that is not in the plan and would belong on the plan's ## Out-of-Plan Files list. Stop and report instead.

Discovery-fallback path (no plan present):

Use spec context first.

Then consult implementation-cache.json before running discovery commands.

Look for:

  • explicit files
  • classes
  • endpoints
  • repositories
  • DTOs
  • test classes
  • package hints

If target files are still unclear, ask only one focused question:

Which files should this step modify?

Prefer explicit file paths over package-level discovery.

Cache-first targeting guidance:

  • if similar_classes contains a likely match, inspect that file first
  • if related_tests exists, start from those tests to locate production code
  • if repositories exists, prioritize those repositories before searching new ones

Do not scan the entire repository to find possible implementation locations.

Allowed targeted discovery:

find src -name "*KnownClassName*"
grep -r "knownMethodOrEndpoint" src/main src/test

Avoid broad commands like:

find src -type f
grep -r "<generic term>" .

unless the user explicitly approves.


Step 5 — Implement (Bounded)

Implementation rules:

  • read only required files/sections
  • apply minimal focused change
  • avoid unrelated refactors
  • avoid scanning unrelated directories
  • avoid speculative fixes outside the spec
  • do not modify unrelated production code to satisfy tests
  • do not introduce new dependencies unless explicitly requested
  • preserve existing patterns and naming conventions
  • prefer small diffs over architectural rewrites

For large files, use targeted reads (grep, line-range reads) before editing.

If the implementation reveals ambiguity:

  1. Append the question to the spec as an unresolved item:
    - [ ] <question>
    
  2. Stop immediately — do not guess, do not partially implement.
  3. Print:
    Open Question added to spec.
    
    .specwork/_spec/<slug>-spec.md
      - [ ] <question>
    
    Answer it in the spec, then rerun /sdd:implement.
    

The spec is the persistent record. Do not rely on conversation context to carry the answer.

If a required change conflicts with rules.json, stop and report the conflict.


Step 6 — Test Coverage

Create or update tests for every changed behavior.

Expected testing behavior:

  • New classes, enums, or DTOs: create a dedicated unit test when there is testable behavior
  • Changed logic: add a focused regression test close to the modified behavior
  • New endpoints: add or update an integration test when appropriate
  • Bug fixes: add a regression test that fails before the fix and passes after the fix
  • If the change has no testable surface, note the reason explicitly before proceeding

Do not generate excessive tests. Tests should be focused on the behavior described in the spec.

Run Individual Tests

Optionally run the test(s) you just created or modified to validate immediately. Use the detected test command for the stack:

# Java
./gradlew test --tests "com.example.MyTest"

# Frontend
npm test -- MyComponent.test    # or pnpm/yarn equivalent

Rules:

  • If tests pass → continue
  • If tests fail → classify the failure before attempting any fix
  • If build tooling is unavailable, skip silently and note it in the summary
  • Never run the full test suite unless explicitly requested
  • Never rewrite unrelated infrastructure to make a test pass
  • Never modify unrelated production code to make a test pass
  • Never change expected assertions unless the spec explicitly requires the behavior change

Failure Decision Matrix

When a test or validation fails, classify the failure before attempting a fix. The classification table is documented in ${CLAUDE_PLUGIN_ROOT}/skills/implement/REFERENCE.md § Failure decision matrix. Read it before classifying.

Rules:

  • Do not fix before classifying the failure.
  • Attempt a fix only when the failure is direct or clearly related to the current change.
  • Escalate immediately for infrastructure, environmental, unrelated, or ambiguous failures.
  • Never change test expectations unless the spec explicitly requires the behavior change.
  • Never modify unrelated production code to make tests pass.

Retry Tracking

Only direct or related failures are eligible for retry.

Maximum attempts:

  • Direct implementation error: 2 attempts
  • Related test setup error: 1 attempt
  • Infrastructure/environmental/unrelated/ambiguous failure: 0 attempts, escalate immediately

Track retries per failing area.

A failing area may be:

  • the same unit test
  • the same integration test
  • the same compile failure
  • the same runtime exception
  • the same Spring context failure
  • the same infrastructure/configuration issue
  • the same test data / fixture setup issue

Increment retry count only when the same failing area persists after a fix attempt.

Do not count unrelated new failures as the same retry. Report them separately.

Escalation Policy

If the same failing area persists after the allowed retry budget:

STOP and report:

  1. failing test or component
  2. exact error excerpt
  3. suspected root cause
  4. files modified
  5. fixes already attempted
  6. recommended human review area

Do not:

  • continue retrying indefinitely
  • rewrite unrelated infrastructure
  • perform broad exploratory refactors
  • modify unrelated production code attempting speculative fixes
  • change test expectations just to make tests pass
  • remove assertions unless the spec explicitly requires a behavior change

Human escalation is a valid and preferred outcome when:

  • integration tests repeatedly fail
  • infrastructure behavior is unclear
  • Spring context failures persist
  • the issue appears environmental
  • the fix requires historical or domain-specific knowledge
  • the failure cannot be tied directly to the current spec

When escalating, keep the working tree as-is and provide a concise summary so the developer can fix manually or decide the next step.

Persist Escalation to _progress/escalations.md

Every time the Escalation Policy triggers, append a dated entry to .specwork/_progress/escalations.md. This is mutable execution memory — it lives in _progress/, not in the spec or state, and /sdd:close wipes it together with the rest of .specwork/ once the feature merges.

Behavior:

  • Create .specwork/_progress/ if it does not exist (mkdir -p).
  • If escalations.md does not exist, create it with the entry below.
  • If it already exists, append the new entry separated by a blank line. Never overwrite or delete prior entries — this file is append-only within the feature.
  • The date prefix uses date +%Y-%m-%d (no time component required).

The entry format (one block per escalation) is documented in ${CLAUDE_PLUGIN_ROOT}/skills/implement/REFERENCE.md § Escalation entry format. Read it before writing.

Why this lives in _progress/:

  • Escalations are runtime learning — what blocked execution, what was tried, what the human should look at next. They are not part of the contract (_spec/) and not part of the deterministic state (_state/).
  • A future /sdd:handoff run reads this file and includes a curated Known Blockers / Escalations section in the execution capsule, so an external executor doesn't repeat the same failed attempts.
  • Persisting the escalation is mandatory. The on-screen escalation summary alone is ephemeral — the file is the persistent record.

Step 7 — Update Implementation Cache

Before finishing, update .specwork/_state/<slug>-implementation-cache.json with facts discovered during this run.

Update rules:

  • append only validated facts (no guesses)
  • deduplicate entries
  • keep entries short and searchable
  • never remove prior entries unless clearly invalid

Suggested shape:

{
  "schema_version": 1,
  "id": "<slug>",
  "repositories": ["LeadsRequestRepository"],
  "patterns": ["fallback lookup uses person + collateral identity"],
  "related_tests": ["DetailedLeadsProcessorIT"],
  "similar_classes": ["ExistingFallbackProcessor"],
  "notes": ["leadId fallback path is exercised in IT only"]
}

Cache updates are best-effort and must never block implementation. After adding facts, merge them with a single call:

python3 ${CLAUDE_PLUGIN_ROOT}/lib/gates.py merge-cache <slug> '{"repositories":["LeadsRequestRepository"],"patterns":["fallback lookup uses person + collateral identity"]}'

Step 7.5 — Simplicity Checkpoint (advisory, non-mutating)

Before recommending the next step, take one non-mutating pass over the change you just made and ask: is there a simpler way?

This is a reflective checkpoint, not a gate — it never edits code, never blocks, and never triggers a rewrite on its own. Skip it entirely for trivial changes (a rename, a copy, a one-line config tweak); run it only when the change carried real logic (focused tier and above).

Look for concrete, spec-preserving simplifications in the diff you just wrote:

  • Fewer moving parts — a new abstraction, layer, or indirection the spec did not ask for and a single call site does not justify.
  • Reuse over reinvention — an existing helper, pattern, or class in the touched area that already does what the new code does.
  • Smaller surface — a narrower signature, fewer new public methods, less config, a shorter diff that still satisfies the spec.
  • No speculative generality — parameters, hooks, or branches added "just in case" with no current caller.

If you find one, surface it to the developer as an advisory note in the Step 8 summary (a one-line Simpler alternative: …) — do not apply it silently; the developer decides. If nothing stands out, say so in one line and move on — do not manufacture a suggestion to look thorough.

Constraints:

  • Never change observed behavior to make the code "simpler" — behavior is fixed by the spec; simplification is about form, not function.
  • A simplification that would change behavior is a spec concern, not an elegance note. Do not reopen a resolved Open Question here.
  • This checkpoint adds no artifacts and no gate; it only reflects and (at most) prints one advisory line.

Step 8 — Ready for Next Step

Assess risk level based on what was just implemented and print the summary.

Risk Classification

Evaluate the observed signals and assign a final risk level. Risk is not determined by file count alone — one async change in a single class may be HIGH; dozens of DTO changes may still be LOW.

The full signal-to-risk-level table is documented in ${CLAUDE_PLUGIN_ROOT}/skills/implement/REFERENCE.md § Risk classification table. Read it before assigning a level.

Recommendation Logic

The risk-level-to-next-phase mapping is documented in ${CLAUDE_PLUGIN_ROOT}/skills/implement/REFERENCE.md § Recommendation logic.

The recommendation is advisory to the developer — they may always skip a step — but the skill must print the next phase that matches the assigned risk level, never substitute a lower one. In particular, HIGH always surfaces /sdd:test-design: do not downgrade it to /sdd:commit just because unit/integration tests were already written inline. /sdd:test-design does not duplicate those tests — it scans them and designs only the missing cases (e.g. real concurrency/race coverage, migration idempotency), which is exactly the gap a HIGH signal points at. Apply contextual judgment only within the matched phase. When more implementation steps remain before the feature is complete, recommend /sdd:implement instead.

Final summary output

The output templates (HIGH / MEDIUM / LOW completion, and the escalation block) are documented in ${CLAUDE_PLUGIN_ROOT}/skills/implement/REFERENCE.md § Output templates. Pick the block matching the assigned risk level (or the escalation block if Step 6 escalation triggered).

Do not hide failed tests behind a normal "done" message.


Requirements

  • Spec must exist
  • Open Questions must be fully resolved
  • Plan (when present) must not be older than the spec — re-run /sdd:plan if it is
  • Target files must be known or confirmed
  • No repo-wide scan by default
  • Retry loops must be bounded
  • Persistent failures must be escalated
  • Business ambiguity must become an Open Question
  • Infrastructure/environment failures must not trigger broad speculative rewrites
  • Implementation cache should be reused and updated when available

Related Skills

  • start — creates rules/state artifacts and captures the source
  • spec — drafts the spec + Open Questions, and refines it mid-pipeline; bumps the spec mtime and may trigger this skill's Plan Staleness Gate
  • plan — when the staleness gate fires, re-run /sdd:plan (idempotent) to regenerate the plan against the current spec
  • commit — stage and commit implementation changes