agentleFS
pivoshenkopivoshenko/pivoshenko.ai/skills/spec-verify/SKILL.md

spec-verify

Skill6 starsChanged 44 days agoMITView on GitHub

Check that an OpenSpec change's implementation actually matches its spec, before anything is archived - artifact validity via `openspec validate --strict`, the repo's own verify gate run for real, and scenario-by-scenario conformance against the spec delta. Read-only: it reports, it never fixes. Use when the user says "verify the change", "/spec-verify", "does the code match the spec", "check spec conformance", "is this ready to archive", "did we actually build it", "audit the ticks", or whenever `spec-apply` has ticked the last task. Boundaries - tasks still unticked -> `spec-apply`; verified and ready to fold into the specs -> `spec-archive`; reviewing a diff for bugs rather than for spec conformance -> `/code-review`; something is broken and needs diagnosing -> `diagnosing-bugs`.

We split this skill into the rules it gives an agent

10 rules. 0 are common, 7 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 10 edited versions we read keep these.

  • 7

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read-only by default. This skill fixes nothing.

    line 23
  2. Very specific:

    Every #### Scenario: in the change's specs//*.md delta is a promise about observable behavior.

    line 58
  3. Distinctive:

    Missing: - no counterpart found. This is the finding

    line 68
  4. Very specific:

    Read tasks.md at its path from artifactPaths, not the lossy tasks[] from openspec instructions apply --json - that array strips the files: …

    line 76
  5. Distinctive:

    Every finding routes to the skill that owns the fix.

    line 101
  6. Distinctive:

    Read-only. Report findings, fix nothing, tick nothing, archive nothing

    line 116
  7. Distinctive:

    Never report a check you did not run, and never report one this file predicts - verdicts come from the run

    line 118
  8. Distinctive:

    Never invent a verify command.

    line 119
  9. Distinctive:

    Never mutate the global openspec profile.

    line 121
  10. Very specific:

    Never --no-verify, never openspec archive from here

    line 122

“Common” is measured: kept by at least 6 in 10 of the 10 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Spec Verify

change -> validate -> gate -> scenario conformance -> report.

Three independent checks, reported separately, in increasing order of what they prove. openspec validate reads documents. The repo gate runs the code. Scenario conformance is the only one that asks whether the behavior the spec promised exists, and it is the reason this skill is in the set. Never collapse them into one verdict.

Read-only by default. This skill fixes nothing. Why -> a verifier that quietly patches what it finds stops being independent evidence and starts being a second author of the same claim.

Preflight

openspec context --json

no_openspec_root -> stop, offer openspec init --tools claude, wait. Never auto-init, never fall back to the current directory. Use the returned root.path. The user naming a store -> openspec store list --json for ids, then --store <id> on every command below, sticky for the run.

.claude/commands/opsx/verify.md present -> the OpenSpec-side mechanics are its job; invoke it and own only the conformance and gate halves. Absent, which is the usual case -> run the flow below off the CLI directly. Mention the opt-in exactly once, as an offer:

openspec config set profile custom
openspec config set workflows '["propose","explore","apply","update","sync","archive","verify"]'
openspec init --tools claude

Accepted or declined, do not raise it again in this run, and never run it unasked. Why -> the profile is global state shared by every repo on the machine, so this is a machine-wide flip made to satisfy one change in one repo.

Flow

  1. Resolve the change and read its shape:
    openspec status --change "<name>" --json
    Keep changeRoot and artifactPaths. Treat every status field as file-existence only - it says an artifact was written, never that it is right. isComplete is the sharpest example: it goes true once all four artifact files exist, so a change with 1 of 3 tasks ticked still reports isComplete: true. Task progress comes from openspec instructions apply --change "<name>" --json instead
  2. Artifact validity. openspec validate <change> --strict --json -> parse items[].issues[], report each with its id and type. This checks the spec documents are well-formed and nothing more. A clean run is not evidence about the code
  3. The repo gate. Find the project's own verify command by reading the justfile or the package scripts - just check here, a test suite elsewhere. Never invent one; nothing found -> ask. Then run it yourself as a shell command. Why -> this is the only check in the set that executes the code; the other two only read documents, and a worker's "tests pass" is a claim, not a result
  4. Scenario conformance. Walk the delta as in Scenarios
  5. Tick audit. Walk tasks.md the other way, as in Ticks
  6. Report as in Report, then hand back as in Handback. Stop. Change nothing

Scenarios

Every #### Scenario: in the change's specs/**/*.md delta is a promise about observable behavior. Enumerate them, then find each one's counterpart in the implementation:

grep -rn '^#### Scenario:' "<changeRoot>/specs"

A counterpart is a test, an assertion, or a code path that would actually differ if the scenario were false. Grade each one:

  • Covered - a named test or assertion exercises it. Cite path:line
  • Implemented, untested - the code path exists, nothing pins it. Cite the path
  • Missing - no counterpart found. This is the finding

Why -> openspec status reports that specs/ exists and the repo gate reports that whatever tests exist pass; neither one notices a scenario nobody ever wrote a test for. Only this walk does.

A scenario whose counterpart contradicts the delta is drift, and drift is a finding. Never resolve it by editing the spec to match what was built. Why -> rewriting the promise to fit the code makes every future reader believe that is what was agreed, and destroys the only record that it was not.

Ticks

Read tasks.md at its path from artifactPaths, not the lossy tasks[] from openspec instructions apply --json - that array strips the files: and needs: continuation lines and renumbers ids, so it cannot support this check. Key tasks on the N.M label parsed out of the text.

For every - [x], confirm its files: were actually touched on this branch:

base=$(git symbolic-ref --short refs/remotes/origin/HEAD)
git diff --name-only "$(git merge-base HEAD "$base")"...HEAD

Detect the base, never assume origin/main - ref missing -> git remote set-head origin -a and re-read, no remote -> main, fall back master. Why -> a repo based on develop diffs against a parent it never branched from, and every task reads as a false tick.

A ticked task whose files: appear nowhere in that list is a false tick - report it by label. Why -> a checkbox is a claim made by whoever ticked it, and it is the only thing spec-archive's gate counts; a false tick walks a never-built feature straight into openspec/specs/.

Report

Three buckets, one line each, most severe first. No narration of the process, no per-file walkthrough, no agent-count.

  • action - a promise is unmet: a missing scenario, a false tick, a red gate, a strict-validate error
  • attention - real but not blocking: implemented-untested scenarios, validate warnings, drift worth a decision
  • ok - checks that ran clean, named so the user can see coverage: "validate strict clean, gate green, 9/9 scenarios covered"

Lead with the counts: 3 ok, 2 attention, 1 action. Never report a check you did not run - a gate you could not find is action: no verify command, never a silent ok.

Handback

Every finding routes to the skill that owns the fix. Name it, do not do it:

  • Code does not meet the spec -> back to spec-apply
  • The spec itself was wrong, so the artifact needs correcting -> back to spec-propose, or /opsx:update where it is installed
  • Clean across all three checks -> spec-archive

When Not To Use This

  • Tasks still unticked -> spec-apply. There is nothing to verify yet
  • Verified and ready to fold the deltas into the specs -> spec-archive
  • Reviewing a diff for bugs rather than for spec conformance -> /code-review
  • Something is broken and needs diagnosing -> diagnosing-bugs

Rules

  • Read-only. Report findings, fix nothing, tick nothing, archive nothing
  • Three checks, three verdicts. Never let a green gate stand in for conformance, or a clean validate stand in for either
  • Never report a check you did not run, and never report one this file predicts - verdicts come from the run
  • Never invent a verify command. Read the justfile or the package scripts, or ask
  • Drift is a finding, never a reason to edit the spec
  • Never mutate the global openspec profile. Offer the opt-in once, then drop it
  • Never --no-verify, never openspec archive from here

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.