spec-verify
Skill0 starsChanged 6 months agoMITView on GitHub
Verify a spec against its implementation and repair violations
We split this skill into the rules it gives an agent
48 rules. 0 are common, 39 are distinctive, and 9 are very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
39
Distinctive
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 9
Verify a spec's requirements against the current implementation.
- Distinctive: line 14
Spec violations are broken contracts, not backlog items: Every downstream consumer (work-plan, spec-author, audit, domain analysis) …
- Distinctive: line 24
Run structural validation on the spec file:
- Distinctive: line 30
If validation fails, report errors and stop.
- Distinctive: line 33
Check the spec's current state.
- Distinctive: line 38
Stop. This prevents double-verification of the same version.
- Distinctive: line 46
Read the spec file's machine section (requirements only, not narrative).
- Very specific: line 54
If .feature/<slug>/ exists for this feature, read the work plan and implementation files listed there.
- Very specific: line 72
Test names/assertions that correspond to requirements (e.g., testNullKeyRejection → R15 null key check)
- Very specific: line 76
If a test validates a requirement but lacks an @spec annotation, add it.
- Distinctive: line 78
Track test coverage gaps: After annotating both implementation and test files, identify requirements with:
- Distinctive: line 97
Place above the enforcing method or code block
- Very specific: line 101
After discovery and annotation, run spec-trace.sh again to confirm coverage.
- Distinctive: line 141
If no such test exists, the verdict is at most PARTIAL — the behavior may happen to work but is not protected against regression.
- Distinctive: line 156
If any matches survive in production code paths, the verdict is VIOLATED.
- Distinctive: line 157
If matches only exist in tests for the retired behavior (verifying it doesn't run), the verdict is SATISFIED.
- Distinctive: line 180
If any requirements are PARTIAL or VIOLATED, proceed to Phase 2.
- Distinctive: line 236
Use AskUserQuestion with options:
- Distinctive: line 243
If "fix the code": reclassify as code-bug
- Distinctive: line 244
If "amend the spec": reclassify as stale-spec
- Distinctive: line 245
If "defer": create an obligation and exclude from repair
- Very specific: line 246
If "need more analysis": pause spec-verify, invoke /architect with the ambiguity framed as a constraint.
- Distinctive: line 249
After all decisions are resolved, proceed to Phase 4.
- Distinctive: line 257
Draft the amendment: Write the updated requirement text.
- Distinctive: line 261
Check for displacement: Run displacement detection against other specs in the same domains:
- Distinctive: line 267
If the amendment would displace requirements in another spec, stop and present the chain to the user.
- Distinctive: line 274
Apply the amendment: Update the requirement text in the spec file.
- Distinctive: line 283
After all amendments are applied, proceed to Phase 5.
- Distinctive: line 295
Before writing any code, present the fix plan for all code-bug findings together:
- Distinctive: line 327
Run the test suite. Confirm all new regression tests fail.
- Very specific: line 330
Read .feature/project-config.md for test framework, conventions, and source directories.
- Distinctive: line 336
Follow the project's coding conventions
- Distinctive: line 337
Do not modify existing tests — only add new regression tests
- Distinctive: line 338
Do not refactor surrounding code — fix only the violation
- Very specific: line 339
Add @spec annotations to the new/changed code
- Distinctive: line 341
Run the test suite after each fix.
- Distinctive: line 346
After all fixes are implemented and tests pass, re-verify each fixed requirement against the spec:
- Distinctive: line 350
Update the evidence reference
- Distinctive: line 352
If any requirement is still not SATISFIED after the fix, investigate.
- Distinctive: line 420
If any requirements were amended, note the old and new text:
- Distinctive: line 431
Update the spec file's front matter:
- Distinctive: line 443
Do NOT change state
- Very specific: line 444
Ensure obligations exist in _obligations.json for each deferred finding
- Very specific: line 448
Check _obligations.json for obligations targeting this spec.
- Distinctive: line 483
Never verify a spec that fails structural validation
- Distinctive: line 484
Never double-verify the same version (idempotency check in pre-flight)
- Distinctive: line 493
Displacement chains are not auto-followed: If a spec amendment would displace requirements in another spec, present the chain and let the …
- Distinctive: line 496
@spec annotations are added to all new/changed code: Every regression test and every code fix must be annotated with the requirement it …
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/spec-verify <feature-id>
Verify a spec's requirements against the current implementation. When violations are found, repair them inline — fix code or amend spec text — then re-verify. A spec is not done until every requirement is SATISFIED or the user explicitly defers a finding.
Spec violations are broken contracts, not backlog items. Every downstream consumer (work-plan, spec-author, audit, domain analysis) operates on the assumption that specs are true. A VIOLATED requirement means the system doesn't do what it claims. This skill owns the full lifecycle: diagnose, classify, repair, confirm.
Pre-flight guard
- Run structural validation on the spec file:
If validation fails, report errors and stop. Never verify a structurally invalid spec.spec_file=$(jq -r --arg id "$ARGUMENTS" \ '.features[$id].latest_file // ""' .spec/registry/manifest.json) bash .claude/scripts/spec-validate.sh ".spec/$spec_file" - Check the spec's current state. If already APPROVED at this version,
report:
Stop. This prevents double-verification of the same version.Spec <id> v<version> already verified. No changes needed.
Phase 1 — Verify all requirements
Step 1.1 — Load the spec
Read the spec file's machine section (requirements only, not narrative). Note the feature ID and version.
Step 1.2 — Discover and annotate implementation
Identify the implementation files. Sources (in priority order):
- @spec annotations — run
bash .claude/scripts/spec-trace.sh <id>to find all annotated enforcement points. - If
.feature/<slug>/exists for this feature, read the work plan and implementation files listed there. - Otherwise, use the spec's
domainsto identify likely source directories and read the relevant files.
Focus on the code that implements the requirements. Do not read the entire codebase — read targeted files.
Annotate implementation as you go. For every enforcement point
discovered during verification — whether from existing annotations, work
plans, or domain scanning — ensure an @spec annotation exists in the
code. If an enforcement point is found but not annotated, add the
annotation before proceeding to the verdict.
Annotate tests as you go. For every test method that validates a
requirement, ensure an @spec annotation exists on the test. Find tests
by:
- Existing
@specannotations in test files (from spec-trace.sh) - Test names/assertions that correspond to requirements (e.g.,
testNullKeyRejection→ R15 null key check) - Adversarial test classes that reference spec findings
If a test validates a requirement but lacks an @spec annotation, add it.
Track test coverage gaps. After annotating both implementation and test files, identify requirements with:
- Implementation annotation but no test annotation — test gap
- Neither implementation nor test annotation — missing implementation
Report test gaps in the verification output. Requirements with test gaps are still verifiable (the implementation exists) but the test traceability is incomplete. Phase 5 (repair) should write structural/behavioral tests for requirements that have zero test coverage, including:
- Reflection tests for structural requirements (final class, sealed interface, absent methods, package visibility)
- Behavioral tests for validation/rejection requirements
- Skip negative concurrency claims (flaky test territory)
Annotation rules (from .spec/CLAUDE.md Code Traceability section):
- Format:
// @spec <spec-id>.RNor// @spec <spec-id>.RN — brief description - Spec ID can be legacy
FXX(e.g.,F13.R5) or new domain.slug (e.g.,schema.field-access.R5). Match the project's convention — check.spec/domains/to see which is in use. - Place above the enforcing method or code block
- Same format in both implementation and test files
- Multiple requirements per annotation:
// @spec <spec-id>.R1,R3,R7
After discovery and annotation, run spec-trace.sh again to confirm
coverage. Report any requirements with zero enforcement points — these
are candidates for UNTESTABLE or may indicate missing implementation.
Step 1.3 — Verify each requirement
For each numbered requirement (R1, R2, ...), determine one of:
| Verdict | Meaning |
| SATISFIED | Implementation fully meets the requirement (see enforcement check below) |
| PARTIAL | Implementation partially meets the requirement — note what's missing |
| VIOLATED | Implementation contradicts the requirement |
| UNTESTABLE | Requirement cannot be verified from code alone (e.g., performance claims) |
For each verdict, provide a one-line evidence reference (file:line or method name).
Enforcement check (MANDATORY before claiming SATISFIED)
Per the annotation contract in rules/completeness-contract.md §4, a
@spec R<n> annotation is a claim that the annotated code ENFORCES the
R-clause — not just that the annotation exists. Before assigning SATISFIED
to any requirement, apply the appropriate check below:
For ASSERT-style requirements ("input X must produce Y", "type Z must be enforced", "the system MUST reject malformed P"):
- Find the actual assertion / validation / type-check in code. A method that could enforce the requirement but doesn't actually contain the check counts as PARTIAL, not SATISFIED.
- The check must be in the production code path — internal SPI adapters and isolated codec utilities don't count if the requirement governs observable behavior at the public API boundary.
For BEHAVIOR-style requirements ("on event X, do Y", "format conversion must preserve Z"):
- Find a test that exercises the requirement through the production entry point. A test that bypasses the production code path (constructs an internal class directly, mocks the live dependency) does not count.
- If no such test exists, the verdict is at most PARTIAL — the behavior may happen to work but is not protected against regression.
For RETIRE / REMOVE-style requirements ("v5 writer path has been retired", "the legacy XYZ codec is no longer used", "the old API has been removed"):
- Grep the WHOLE codebase for the deprecated symbol or path, not just the file containing the annotation. A spec marked SATISFIED because the symbol no longer appears in one file is wrong if the symbol still lives in another file.
- Run:
If any matches survive in production code paths, the verdict is VIOLATED. If matches only exist in tests for the retired behavior (verifying it doesn't run), the verdict is SATISFIED.grep -rn "<deprecated-symbol>" --include="*.<ext>" . | grep -v "<expected-locations>"
Why this matters. Phantom annotations — @spec R<n> on code that
doesn't enforce the clause — are worse than missing annotations: they
tell downstream consumers (work-plan, audit, spec-author) that the
requirement holds when it doesn't. The 2026-05 jlsm session shipped a
sstable.sparse-key-index.R2 marked SATISFIED ("v5 writer path removed")
while the v5 writer was still the sole footer writer on the encrypted
path. Catching this requires reading what the code DOES, not what the
annotation CLAIMS.
Step 1.4 — Check for undocumented behavior
Scan the implementation for significant behavior that is NOT covered by any requirement. Note these as informational findings — they may become new requirements during the repair phase.
Step 1.5 — Present verification results
Display the full verdict table. If all requirements are SATISFIED (or SATISFIED + UNTESTABLE only), skip to Phase 6 (Finalize).
If any requirements are PARTIAL or VIOLATED, proceed to Phase 2.
Phase 2 — Classify findings
For each non-SATISFIED requirement, classify it into one of three categories:
| Classification | When to use | Repair action |
| code-bug | Spec is correct, code doesn't match | Fix code + write regression test |
| stale-spec | Code is correct (or stricter), spec text is outdated | Amend spec text |
| needs-decision | Genuinely ambiguous — code does Y, spec says X, both are defensible | User decides direction |
| test-gap | Requirement SATISFIED but no test-side @spec annotation | Write/annotate tests |
Present ALL findings batched, grouped by classification:
── Verification findings: <id> ─────────────────────
Needs decision (resolve before fixes):
R39g — spec requires IOException on buffer exceed, code gracefully falls
back. Fallback may be the better design (avoids data loss on large
files). Which is correct?
Code bugs (will write regression tests + fix):
R33 — readKeyIndexV2 missing bounds validation on blockIndex/intraBlockOffset.
Corrupt data throws internal exceptions instead of descriptive IOException.
Stale spec text (code is correct, spec needs update):
R42 — spec says "silently ignores trailing bytes" but code now rejects them.
Code is stricter, which is better.
R43 — spec says "document in public API" but javadoc is missing.
Test gaps (SATISFIED but no test traceability):
R1 — final class, testable via reflection (Modifier.isFinal)
R54 — private final fields, testable via reflection
R62 — no toString override, testable via reflection
... (N requirements with implementation but no linked tests)
Use AskUserQuestion with relevant options.Phase 3 — Resolve decisions
For each needs-decision finding, present the tradeoff and ask the user to choose a direction.
For each finding, present:
- What the spec says
- What the code does
- Why each approach is defensible
- The implication of each direction
Use AskUserQuestion with options:
- "Fix the code (spec is correct)"
- "Amend the spec (code is correct)"
- "Defer (create obligation for later)" — only if user explicitly chooses
- "Need more analysis" — invoke
/architectif a design decision is needed
After each decision:
- If "fix the code": reclassify as code-bug
- If "amend the spec": reclassify as stale-spec
- If "defer": create an obligation and exclude from repair
- If "need more analysis": pause spec-verify, invoke
/architectwith the ambiguity framed as a constraint. Resume after the decision is made.
After all decisions are resolved, proceed to Phase 4.
Phase 4 — Amend stale specs
For each stale-spec finding:
- Draft the amendment. Write the updated requirement text. The requirement number stays the same — this is an in-place update, not a new requirement.
Check for displacement. Run displacement detection against other specs in the same domains:
NEW_SPEC_FILES=".spec/$spec_file" \ bash .claude/scripts/spec-resolve.sh "<domains>" 2>&1If the amendment would displace requirements in another spec, stop and present the chain to the user. Do not auto-follow displacement chains.
Use AskUserQuestion with options:
- "Apply amendment (I'll handle downstream impact separately)"
- "Skip this amendment"
- Apply the amendment. Update the requirement text in the spec file.
- Bump the version in the spec's front matter (increment by 1).
- Re-validate structure:
bash .claude/scripts/spec-validate.sh ".spec/$spec_file"
After all amendments are applied, proceed to Phase 5.
Phase 5 — Fix code violations (TDD)
This is the core repair phase. For each code-bug finding, run a scoped TDD cycle: write a regression test that enforces the spec requirement, then implement the fix.
Step 5.1 — Plan all fixes
Before writing any code, present the fix plan for all code-bug findings together:
── Fix plan: <id> ──────────────────────────────
<n> code violations to fix:
R33 — Add bounds validation to readKeyIndexV2
Test: verify IOException on out-of-range blockIndex
Fix: add range check before CompressionMap.entry() call
R15 — Add blank key rejection to JsonObject.of/Builder.put
Test: verify IAE on blank/whitespace key
Fix: add isBlank() check after requireNonNull
Use AskUserQuestion with options:
- "Approve fix plan"
- "Adjust" (with Other for custom input)Step 5.2 — Write regression tests (all violations, batched)
For each code-bug finding, write a test that:
- Is annotated with
@spec <id>.R<n>linking it to the requirement - Exercises the specific violation (e.g., passes corrupt data, passes blank key)
- Asserts the behavior the spec requires (e.g., IOException with descriptive message, IAE on blank key)
- Currently fails against the unfixed code — this confirms the violation is real and the test is meaningful
Run the test suite. Confirm all new regression tests fail. If a test passes, the violation may not be real — re-examine the finding.
Read .feature/project-config.md for test framework, conventions, and
source directories. Follow the project's existing test patterns.
Step 5.3 — Implement fixes
For each violation, implement the minimum correct fix:
- Follow the project's coding conventions
- Do not modify existing tests — only add new regression tests
- Do not refactor surrounding code — fix only the violation
- Add
@specannotations to the new/changed code
Run the test suite after each fix. All tests (existing + new regression tests) must pass before proceeding to the next fix.
Step 5.4 — Verify fixes
After all fixes are implemented and tests pass, re-verify each fixed requirement against the spec:
- Re-read the implementation code at the fix location
- Confirm the verdict is now SATISFIED
- Update the evidence reference
If any requirement is still not SATISFIED after the fix, investigate. Either the fix is incomplete (iterate) or the spec needs amendment (reclassify as stale-spec and return to Phase 4).
Step 5.5 — Fill test gaps
For each test-gap finding (requirement SATISFIED but no test-side
@spec annotation):
- Check if an existing test already validates this requirement. Search
test files for assertions that exercise the requirement's behavior (e.g.,
a test named
testNullKeyRejectionlikely covers a null-rejection requirement). If found, add the@specannotation to the existing test. If no existing test covers the requirement, write one. Categorize the requirement and write the appropriate test type:
Requirement type Test approach Behavioral (validation, rejection, output) Standard input/output assertion Structural (final class, sealed, package) Reflection test (Modifier checks) Absent behavior (no toString, no Serializable) Reflection test (method/interface absence) Documentation (javadoc, API contract) Skip — not testable Negative concurrency (no synchronization) Skip — flaky test territory - Annotate every test with
@spec <spec-id>.RNlinking it to the requirement (FXX.RN or domain.slug.RN, matching the project's convention). - Run the test suite to confirm all new tests pass. Test-gap tests must pass immediately (unlike regression tests for violations which must fail first) — the implementation already satisfies the requirement, the test just didn't exist.
Present test-gap results:
── Test gap results: <id> ──────────────────────
Existing tests annotated: <count>
New tests written: <count>
Skipped (untestable): <count>
Total test coverage: <annotated>/<total requirements>Phase 6 — Finalize
Step 6.1 — Write verification note
Append to the spec file's ## Verification Notes section:
### Verified: v<version> — <date>
| Req | Verdict | Evidence |
|-----|---------|----------|
| R1 | SATISFIED | <file:line or method> |
| R2 | SATISFIED | <file:line or method> |
| ... | ... | ... |
**Overall: PASS | PASS_WITH_NOTES | FAIL**
Amendments applied: <count or "none">
Code fixes applied: <count or "none">
Regression tests added: <count or "none">
Obligations deferred: <count or "none">
Undocumented behavior: <count or "none">If any requirements were amended, note the old and new text:
#### Amendments
- R42: "silently ignores trailing bytes" → "rejects trailing bytes with
IllegalArgumentException"Step 6.2 — Update state and registry
If all requirements are SATISFIED (or SATISFIED + UNTESTABLE only):
Update the spec file's front matter:
state: DRAFT → APPROVED
Update the registry:
tmp=$(mktemp)
jq --arg id "<feature-id>" '.features[$id].state = "APPROVED"' \
.spec/registry/manifest.json > "$tmp" \
&& mv "$tmp" .spec/registry/manifest.jsonIf any requirements remain VIOLATED or PARTIAL (deferred by user):
- Do NOT change state
- Ensure obligations exist in
_obligations.jsonfor each deferred finding
Step 6.3 — Resolve existing obligations
Check _obligations.json for obligations targeting this spec. If any
are now resolved by the fixes applied in Phase 5, update their status:
{ "status": "resolved", "resolved_by": "spec-verify", "resolved_date": "<date>" }Run obligations GC:
bash .claude/scripts/spec-obligations-gc.shStep 6.4 — Report
── Verification complete: <id> v<version> ──────
Overall: <PASS | PASS_WITH_NOTES | FAIL>
SATISFIED: <count>
PARTIAL: <count>
VIOLATED: <count>
UNTESTABLE: <count>
Repairs applied:
Amendments: <count>
Code fixes: <count>
Regression tests: <count>
Deferred: <count>
State: <DRAFT → APPROVED | DRAFT (unchanged)>Hard constraints
- Never verify a spec that fails structural validation
- Never double-verify the same version (idempotency check in pre-flight)
- State and status are updated together or not at all
- Verification notes are append-only — never delete previous notes
- Violations are repaired inline, not parked as obligations. Obligations are created ONLY when the user explicitly defers a finding via AskUserQuestion — never as the default path.
- Regression tests are mandatory for code fixes. A code fix without a regression test is incomplete — the violation will recur on the next change that touches the same code.
- Displacement chains are not auto-followed. If a spec amendment would displace requirements in another spec, present the chain and let the user decide. Do not create a cascade of automated amendments.
- @spec annotations are added to all new/changed code. Every regression test and every code fix must be annotated with the requirement it enforces.
Other versions10 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 10
- jh941213/my-claude-code-asset★ 126same name
- arfar-x/agent-skills★ 13same name
- sourjya/kiro-rails★ 9same name
- pivoshenko/pivoshenko.ai★ 6same name
- orrrrli/clawd-harness★ 2same name
- anxndsgn/skills★ 1same name
- rainmancswh-dot/claude-skills★ 1same name
- ba0918/claude-skills★ 0same name
- cldanielhernandez/claude-skills★ 0same name
- mahdyarief/spec-driven-agent-kit★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use handoff.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillhandoff
Compact the current conversation into a handoff document for another agent to pick up.
Also in 3 projects that use this
In this repository45 other files it gives its agents.
- decisions/CLAUDE.mdCLAUDE.md
- kb/CLAUDE.mdCLAUDE.md
- spec/CLAUDE.mdCLAUDE.md
- work/CLAUDE.mdCLAUDE.md
- script-devSkill
- architectSkill
- auditSkill
- capabilitiesSkill
- curateSkill
- decisionsSkill
- feature-cleanupSkill
- feature-completeSkill
- feature-coordinateSkill
- feature-domainsSkill
- feature-hardenSkill
- feature-implementSkill
- feature-planSkill
- feature-prSkill
- feature-quickSkill
- feature-refactorSkill
- feature-resumeSkill
- feature-retroSkill
- featureSkill
- feature-testSkill
- kbSkill
- project-contextSkill
- researchSkill
- setup-vallorcineSkill
- spec-authorSkill
- spec-backfillSkill
- spec-initSkill
- spec-resolveSkill
- specSkill
- spec-splitSkill
- spec-writeSkill
- uninstall-vallorcineSkill
- upgrade-vallorcineSkill
- vallorcine-helpSkill
- work-decomposeSkill
- work-planSkill
- work-resumeSkill
- work-runSkill
- workSkill
- work-startSkill
- work-statusSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

