Classify how far what shipped diverged from what was specced, and record it on the spec: every item marked satisfied, diverged, not implemented, or superseded, unspecified work called out, and an Outcome section appended. Writes to the spec and may mark it stale. Use after an implementation lands and the spec should carry the verdict.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add changkun/wallfacer --skill wf-spec-drift --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wf Spec Drift?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/changkun-wf-spec-drift)More formats (shields.io, HTML) on the badges page.
---
name: wf-spec-drift
description: Classify how far what shipped diverged from what was specced, and record it on the spec: every item marked satisfied, diverged, not implemented, or superseded, unspecified work called out, and an Outcome section appended. Writes to the spec and may mark it stale. Use after an implementation lands and the spec should carry the verdict.
argument-hint: <spec-file.md> [commit-range]
---
# Spec-Implementation Drift
Compare what a dispatched task actually built against what the spec asked for.
This is the non-deterministic layer 2 of the task completion feedback loop —
it goes beyond the mechanical status flip (layer 1) to assess whether the
implementation truly satisfies the spec's intent.
## Step 0: Parse arguments
$ARGUMENTS has the form: `<spec-file.md> [commit-range]`
- The **first token** is the spec file path.
- The optional **second token** is a git commit range (e.g., `abc123..HEAD`).
## Step 1: Load the spec
1. Read the spec file in full. **Parse YAML frontmatter** — extract `title`,
`status`, `depends_on`, `affects`, `effort`, `dispatched_task_id`.
2. Verify `dispatched_task_id` is non-null. If null, the spec was not dispatched.
It may instead have been implemented directly in-session (no task UUID, but
real commits on the `affects` files). In that case:
- To **finalize** it (Outcome + status + README), use `/wf-spec-wrapup`, which
is lifecycle-aware and reconstructs the Outcome from the git history of the
`affects` files. That is the canonical Outcome writer for the direct path.
- To only **review** the implementation against the spec (no Outcome write),
use `/wf-spec-review-impl`, which works without a dispatch link.
- You may still run *this* skill's divergence analysis on a direct-implement
spec if the user passes an explicit `[commit-range]` (Step 2 then uses it
instead of the task UUID) — but do not also write `## Outcome` here if
wrap-up already owns it (see Step 6).
3. Extract the acceptance criteria from the spec body:
- Design specs: items from Options (chosen option), Components, Architecture
- Task specs: items from "What to do", "Goal", "Tests"
- Any numbered or bulleted requirements
4. If the spec is non-leaf, read child specs recursively and aggregate their
criteria.
## Step 2: Load the implementation
1. If a commit range was provided, use it directly.
2. Otherwise, infer the range: find commits associated with the dispatched task.
Look for the task UUID in commit messages, or use the task's worktree diff
via `GET /api/tasks/{id}/diff` where a task board exposes one; otherwise
from git history over the spec's `affects` paths.
3. Get the diff: `git diff <range> --stat` for file list, `git diff <range>`
for full changes.
4. Get commit messages: `git log <range> --oneline`.
Use Agent subagents (Explore type) to parallelize diff analysis across
independent packages if the change spans many files.
## Step 3: Classify each spec item
For every acceptance criterion or deliverable in the spec:
- **Satisfied** — the diff contains clear evidence of implementation. The code
matches what the spec described (types, functions, behavior).
- **Diverged** — the item was addressed but the implementation differs from
what the spec specified. Note *what* the spec said vs *what* was built and
*why* the divergence may have occurred (common reasons: runtime constraints,
API changes, simpler approach found).
- **Not implemented** — no evidence in the diff. The item was skipped or
deferred.
- **Superseded** — the item was replaced by a different approach that achieves
the same goal. Note the replacement.
For each classification, cite specific files, functions, and diff hunks as
evidence.
## Step 4: Identify unspecified work
Scan the diff for changes not traceable to any spec item:
- New files, types, or functions not mentioned in the spec
- Refactoring of existing code beyond what the spec required
- Test additions beyond what the spec's "Tests" section listed
Classify each as:
- **Necessary scaffolding** — required to make the spec work (e.g., imports,
helper types, error handling)
- **Improvement** — reasonable enhancement discovered during implementation
- **Scope creep** — work that belongs in a different spec or wasn't requested
## Step 5: Assess overall drift
Compute a drift summary:
- **Satisfaction rate**: N of M spec items satisfied (percentage)
- **Divergence count**: how many items were implemented differently
- **Unimplemented count**: how many items were skipped
- **Unspecified count**: how many changes weren't in the spec
Based on these numbers, determine the drift level:
- **Minimal** (>90% satisfied, ≤1 divergence) — spec is accurately complete
- **Moderate** (70-90% satisfied, or 2-3 divergences) — spec is mostly complete
but the Outcome section should document the deviations
- **Significant** (<70% satisfied, or major divergences) — the spec should
transition to `stale` rather than `complete`, as it no longer accurately
describes what was built
## Step 6: Write the Outcome section
`## Outcome` is the single canonical completion section, shared with
`/wf-spec-wrapup`.
**If you are running as wrap-up's analysis engine (wrap-up Step 2a):** stop here —
do **not** write or update the Outcome, and do **not** touch frontmatter/status.
Return the classified findings (Satisfied / Diverged / Not implemented /
Superseded items, unspecified work, drift level, satisfaction rate) to wrap-up,
which composes the one Outcome and sets status from the drift. Steps 7–8 below
(tests, report) are wrap-up's job in that mode.
**If you are running standalone,** you own the Outcome — but still don't blindly
append a second one. Check whether the spec already has an `## Outcome`:
- **None yet** — write the divergence-flavored Outcome below.
- **Already present** (e.g. wrap-up finalized a direct-implement spec, or a prior
diff ran) — do not duplicate it. Merge your divergence findings into the
existing section (add/refresh the Divergences / Not Implemented / Unspecified
subsections) and leave its Summary/What-Shipped intact. The divergence analysis
augments the finalizer's Outcome; it does not replace it.
When writing a fresh Outcome standalone, append it before any "Future Work" or
"Open Questions" sections:
````markdown
## Outcome
**Drift**: Minimal | Moderate | Significant
**Satisfaction**: N/M items (X%)
### What Shipped
- <bullet list of key deliverables with file paths>
### Divergences
- **<spec item>**: spec said X, implementation does Y. Reason: <why>
### Not Implemented
- **<spec item>**: <reason — deferred, descoped, superseded by Z>
### Unspecified Work
- **<file/function>**: <classification and brief description>
````
Update the spec's status — honoring the lifecycle gate (`validated → complete` is
illegal; `complete` is reached only through `testing`) and the hybrid rule (prefer
a transition API where the repo has one, since it validates the edge; otherwise
a legal-edge frontmatter edit). A dispatched task reaching `done` means the **server** already moved the
spec along `validated → testing → complete/stale`, so usually you are only
recording the verdict, not setting the status:
- **Minimal**: the server's `complete` stands; leave `status` as is.
- **Moderate**: leave `complete`, but the Outcome documents the divergences;
suggest `/wf-spec-refine` to align the spec text.
- **Significant**: your analysis overrides the server's optimistic complete — set
`status: stale` (`complete → stale` is legal). Recommend `/wf-spec-refine`, then
`/wf-spec-dispatch` again for the remaining work.
- If the spec is unexpectedly still `validated` (no server hook ran) or `testing`
(verdict pending), do not jump to `complete`: hand off to `/wf-spec-wrapup`,
which walks the `testing` gate properly. Never write `validated → complete`.
Set `updated` to today's date whenever you change the status.
## Step 7: Run tests
If the spec has a "Tests" or "Testing Strategy" section:
1. Discover and run the affected repository's documented test command.
2. Cross-reference test results against the spec's test requirements.
3. Note any spec-required tests that are missing or failing.
Include test results in the Outcome section.
## Step 8: Summary
Report to the user:
```
## Spec Diff: <spec title>
Task: <task UUID>
Commits: N commits, M files changed
Drift: Minimal | Moderate | Significant
Satisfaction: N/M items (X%)
### Satisfied
- <item> — in <file>
### Diverged
- <item> — spec: X, impl: Y
### Not Implemented
- <item>
### Unspecified
- <file>: <classification>
### Recommendation
- <what to do next — nothing, update spec, or mark stale>
```
## Guidelines
- This skill bridges the gap between "task done" and "spec accurately complete."
The server-side hook (layer 1) marks the spec `complete` immediately. This
skill (layer 2) verifies that claim and corrects it if needed.
- Be factual, not judgmental. Divergences aren't failures — implementations
often improve on specs. Document what happened and why.
- Preserve the spec's existing content. The Outcome section is additive.
- If you can't determine whether an item was satisfied (ambiguous spec language,
unclear diff), classify it as "Cannot determine" and flag it for human review.
- This skill is most valuable for design specs where the implementation had
latitude to interpret. For task specs with precise "What to do" steps, the
assessment is usually straightforward.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!