| name | sdd-apply |
| description | Use when implementing tasks from a change's tasks.md. Triggers: "apply tasks", "implement the change", "work through tasks", "start implementing", "continue implementing", "apply the change". |
SDD Apply
Implement tasks from SPECS_ROOT/changes/<name>/tasks.md.
Check off each task as it completes.
SPECS_ROOT is resolved by the sdd router before this skill runs.
Replace .specs/ with your project's actual specs root in all paths below.
Invocation Notice
- Inform the user when this skill is being invoked by name:
sdd-apply.
Hard Gate
If tasks.md does not exist for the active change: STOP.
"No tasks to implement. Run sdd-propose first to create the change artifacts."
Do not proceed without tasks.md.
Critical Constraints
Never reference ephemeral scaffolding in any persisted artifact.
Ephemeral scaffolding includes:
- Task IDs and task numbers (e.g.
Task 7.4, T12)
- Group names and group numbers (e.g.
Group 8, G3)
- Design-section IDs (e.g.
D12, design §4.2)
- Other planning-artifact identifiers that won't outlive the change
These must not appear in:
- Code, symbols, or filenames
- Comments or docstrings
- Commit messages (subject, body, or footer)
- PR titles or descriptions
- Any other artifact that persists after the change is archived
Tasks, groups, and design-section IDs are scaffolding for the current change.
Once archived, only the spec name persists — references to ephemeral IDs become meaningless noise to future readers.
Name things after what they do, not where they came from in tasks.md or design.md.
If you catch yourself writing "D12 wiring" or "Task 7.4 implementation," restate it in terms of the behavior or component being changed.
This applies whether or not the commit-message skill is available.
When drafting a commit message during apply:
- Prefer invoking
commit-message if it is loadable in this environment.
- Otherwise, draft a Conventional Commit (
type(scope): subject) that describes what changed and why, and apply the constraints above.
- Do not paste design or task identifiers into the message even if they appear in the surrounding tasks/design files.
When to Use
- A change has
tasks.md and implementation should begin or continue
- Resuming implementation after a pause
When Not to Use
- No
tasks.md exists — run sdd-propose first
- All tasks complete — run
sdd-verify, then sdd-sync, then sdd-archive
Process
Phase 1: Load Context
- Confirm which change to apply (ask if multiple active changes exist)
- Read
.specs/changes/<name>/tasks.md — full task list
- Read
.specs/changes/<name>/design.md — architectural decisions to follow
- Read
.specs/changes/<name>/specs/ — delta specs for behavioral requirements
- Read
.specs/specs/ — baseline specs for full context
- Read
.specs/changes/<name>/proposal.md § User Stories and .specs/NORTH-STAR.md — the value this work serves.
Each requirement's Serves: backlink names the stories it advances; these bound scope (see The story ceiling below).
- Check task ordering against
references/sdd-change-formats.md § 4 — each task should depend only on capabilities built by earlier tasks.
The schema-config rule below is the named instance: if .specs/.sdd/schema-config.yaml exists, identify tasks that define schema contracts (endpoint definitions, model schemas, DDL changes) and confirm they are sequenced before any tasks that consume them.
Surface any ordering gaps to the user before implementing (advisory — the user may decide the order is intentional).
Phase 2: Identify Starting Point
Check tasks.md for already-completed tasks (- [x]).
Start from the first unchecked task.
If all tasks are complete:
"All tasks are already complete. Run sdd-verify to confirm the implementation, then sdd-sync and sdd-archive."
Stop.
Phase 3: Implement Task-by-Task
For each unchecked task:
- Read the task — understand what it requires
- Check dependencies — are earlier tasks complete?
If not, implement them first
- Implement — write the code to the depth the served story requires, no further (see The story ceiling below)
- Check for newly-emerged write-sites — see § Write-site emergence below
- Test — run the project's standard test command at its broadest reasonable scope (e.g.
pytest with no --ignore / --deselect / -m filters).
Inner-loop iteration may use a narrower scope, but the verification you act on — and any pass/fail count you report — must come from a broad-scope run.
If you exclude any path, marker, or file, name the exclusion and justify it in the same message.
"Not part of this change" is not a valid justification for a class or module rewrite — every test that imports the rewritten symbol is part of the change by definition.
If a test fails, stop and resolve the failure before proceeding to the next step.
- Check off — update
tasks.md: - [ ] → - [x]
Follow design decisions in design.md — don't diverge without reason.
Follow behavioral requirements in delta specs — these define what "correct" means.
Apply the Critical Constraints above to every artifact you produce — code, comments, and commit messages alike.
If .specs/.sdd/schema-config.yaml exists and a task consumes a schema contract that is not yet defined, pause before implementing it.
Surface the dependency gap and confirm with the user whether to reorder tasks in tasks.md first.
The story ceiling
Each requirement's Serves: backlink (and the stories in proposal.md § User Stories) names the user value the work exists to deliver.
That value is the scope ceiling: implement to the depth the served story requires, and no further.
When implementing surfaces behavior that no story motivates — extra configuration knobs, speculative generality, defensive paths beyond the contract, broader abstraction than the requirement needs — stop and surface it rather than building it silently.
It is likely over-engineering, the failure mode this ceiling exists to bound.
The user decides whether the extra work is justified (and, if so, which story it serves); the default is to leave it unbuilt.
A requirement you are implementing that carries no Serves: backlink is itself a flag — confirm it advances a real story before building to it.
Write-site emergence
A SHALL requirement may end up with multiple code paths that produce or modify the contract-asserted value during implementation — not just the canonical path.
Common examples: deduplication shortcuts, cache fast-paths, retry/fallback branches, idempotency early-returns, merge or composition steps that write the same fields.
When implementing a task introduces such a path for an existing SHALL:
- Pause before checking off the implementation task.
- Add a paired test task to
tasks.md that exercises the contract through the new path.
The new test task must produce runnable evidence (test, schema check, or captured output) — same standard as the original SHALL coverage rule.
- Implement the test as part of the same work, or sequence it as the immediately-following task.
- Then check off the original implementation task.
A test exercising only the canonical path does not stand in for evidence on a shortcut, retry, or composition path.
This rule is what sdd-verify's write-site enumeration is checking; cover it at apply time and verify has nothing to flag.
When unsure whether a path is contract-relevant, surface it to the user rather than skipping the test task silently.
Phase 4: After All Tasks
Before checking off the final task (hard gate):
- Run the full suite as CI would — no programmatic exclusions unless they appear in the project's CI config.
rg/grep for tests that import any symbol you changed and confirm they ran in step 1.
The blast-radius check is what catches tests pinned to rewritten classes or modules that a marker filter would silently skip.
- Tests rendered obsolete by the change must be deleted or updated with reasoning recorded in the diff — not silently skipped.
- Report results with scope alongside counts (e.g. "407 passed, 1 file excluded because…").
Pass/fail counts without an exclusion list are not a verification report.
When the gate passes and all tasks are checked off:
"All tasks complete. Recommended next steps:
- Run
sdd-verify to confirm implementation matches the change artifacts
- Run
sdd-sync to merge delta specs into main specs
- Run
sdd-archive to complete the change"
Fluid Workflow
This skill can be invoked at any point after tasks.md exists — not only when all artifacts are complete.
- If implementation reveals a design issue, pause and suggest updating
design.md or delta specs before continuing.
- If scope changes mid-implementation, suggest updating
proposal.md and tasks.md.
- Don't treat the artifact set as frozen — work fluidly, but document changes.
Common Mistakes
- Implementing without reading design.md (misses architectural decisions)
- Gold-plating beyond the served story — building behavior no user story motivates instead of surfacing it (see The story ceiling)
- Not checking off tasks as they complete
- Implementing tasks out of order when dependencies exist
- Continuing past a failed task without resolving it
- Diverging from design decisions without documenting why
- Treating artifacts as frozen when implementation reveals issues (update them)
- Adding a deduplication shortcut, cache fast-path, retry branch, or composition step for a SHALL-covered value without adding a paired test task that exercises the new write-site (see § Write-site emergence)
- Checking off the implementation task before the paired test task for a newly-emerged write-site is added and runnable
- Referencing ephemeral scaffolding — task IDs, group names, design-section IDs (e.g.
D12) — in code, comments, commit messages, or PR descriptions (see Critical Constraints)
- Drafting a commit message inline without invoking
commit-message when it is available, or without applying the Critical Constraints when it is not
- Excluding a test file, path, or marker from a verification run without naming the exclusion and justifying it in the same message — especially fatal when the change rewrites a class or module that the excluded tests pin
- Reporting "N passed, 0 failed" without also reporting what was excluded and why — scope must travel with the counts
References
references/sdd-schema.md — schema config format (§ 3) and lifecycle policy (§ 4)