agentleFS
hmj1026hmj1026/dhpk/skills/openspec-artifact-guard/SKILL.md

openspec-artifact-guard

Skill2 starsChanged 7 days agoMITView on GitHub

Use when validating OpenSpec artifact shape, delta placement, task/git alignment, and safe change slugs. Apply while editing OpenSpec files or reviewing them before archive. Not for implementation or archive itself. Output: a verdict with artifact and task evidence.

The file

We split this skill into the rules it gives an agent

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

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    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. Very specific:

    Before invoking openspec:archive on a change (last-line safety net)

    line 31
  2. Distinctive:

    After mass-rename in the openspec tree (slug normalization)

    line 32
  3. Very specific:

    If both conditions are met → APPROVE.

    line 75
  4. Very specific:

    If commits is substantial (≥ 3) but unchecked is still high, the tasks.md is drifting from actual progress.

    line 120
  5. Distinctive:

    If no findings, output one line:

    line 173
  6. Distinctive:

    Check 1 catches this. The fix is mechanical (move the diff under the change directory), but only if caught before merge.

    line 194
  7. Distinctive:

    Check 4 catches this. Reduces "what's left on this change?" ambiguity.

    line 200

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “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

OpenSpec artifact guard

OpenSpec's directory shapes are easy to mis-name. The most expensive mistake — editing openspec/specs/ directly during an active change — is also the most invisible: nothing throws, the file commits cleanly, and the delta-merge step on archive silently does nothing because the SSOT already matches.

This skill is the fast pre-archive guard. The deep verifier is openspec-verify-change (different skill). Run this one whenever openspec/** files are in the diff.

The checks below contain the naming and shape rules needed by this guard; no sibling module or repository policy file is required.


When to run

  • Editing any file under openspec/
  • Reviewing a PR whose diff touches openspec/
  • Before invoking openspec:archive on a change (last-line safety net)
  • After mass-rename in the openspec tree (slug normalization)

When NOT to Use

  • Editing source code that has nothing to do with the spec
  • Running openspec:verify already (it covers a superset of these checks)

Inputs

The diff under openspec/ (or, if no diff, the current working tree state):

git diff --name-only -- openspec/
# or, if no diff:
find openspec/ -type f -name '*.md' -newer openspec/project.md 2>/dev/null

Also read openspec/changes/*/ directory shapes (regardless of diff).


Checks

Check 1 — Direct SSOT edit during active change (CRITICAL)

Find files matching openspec/specs/** in the diff that are NOT in an archive commit.

git diff --name-only | grep -E '^openspec/specs/[^/]+/'

A new file or modified file here is suspect. The only legitimate way to update openspec/specs/ is through openspec:archive which applies delta directives from openspec/changes/<slug>/specs/ to the SSOT.

Confirm legitimacy by:

  • The commit message contains archive AND
  • The same commit touches openspec/changes/.archive/<slug>/ or openspec/changes/archive/<slug>/

If both conditions are met → APPROVE. Otherwise → CRITICAL: redirect the edit to openspec/changes/<current-change>/specs/<capability>/spec.md with delta markers.

Check 2 — Spec-delta missing directive markers (CRITICAL)

For every file matching openspec/changes/*/specs/**/spec.md:

grep -lE '^## (ADDED|MODIFIED|REMOVED) Requirements' <file>

A spec-delta with no ## ADDED Requirements / ## MODIFIED Requirements / ## REMOVED Requirements heading is indistinguishable from an SSOT spec. On archive, no delta directives → no SSOT mutation → silent no-op.

Fix: the writer must declare each requirement under the appropriate directive. The mechanical fix is to prefix existing ## Requirements with ADDED (or whichever matches intent).

Check 3 — Required artifacts present (HIGH)

For every directory openspec/changes/<slug>/:

test -f openspec/changes/<slug>/proposal.md || echo "MISSING proposal.md"
test -f openspec/changes/<slug>/tasks.md    || echo "MISSING tasks.md"
test -d openspec/changes/<slug>/specs/      || echo "MISSING specs/ dir"

design.md is optional and skipped from this check.

Check 4 — tasks.md vs git log drift (HIGH)

For each active change:

slug="$(basename "$change_dir")"
# Count unchecked items in tasks.md
unchecked="$(grep -cE '^\s*-\s*\[ \]' openspec/changes/$slug/tasks.md)"
# Count commits in this branch that reference the slug
commits="$(git log --grep="$slug" --oneline | wc -l)"

If commits is substantial (≥ 3) but unchecked is still high, the tasks.md is drifting from actual progress. Flag as HIGH and quote the 3 most recent slug-referencing commits.

This check is heuristic — false positives are possible if commit messages don't reference the slug. Report as suggestion ("review whether these commits closed any open tasks"), not assertion.

Check 5 — Slug normalization (MEDIUM)

for dir in openspec/changes/*/; do
    slug="$(basename "$dir")"
    if echo "$slug" | grep -qE '[A-Z_]'; then
        echo "MEDIUM: non-kebab slug '$slug' (use lowercase + hyphens)"
    fi
done

Skip openspec/changes/archive/ and openspec/changes/.archive/.

Check 6 — proposal.md capability references (HIGH)

For each proposal.md, extract referenced capability IDs (look for lines like - **<capability-id>**: or capability: <id>). For each ID, verify either:

  • openspec/specs/<id>/spec.md exists (capability already in SSOT — change is modifying it), OR
  • openspec/changes/<slug>/specs/<id>/spec.md exists with ADDED directives (change is creating it)

A referenced capability with neither presence → HIGH: the proposal cites a capability that doesn't exist anywhere.


Output

[CRITICAL|HIGH|MEDIUM|LOW] <check-name>
File: openspec/<path>
Issue: <one-line description>
Fix: <one-line recommendation, often with exact command>

End with:

Verdict: APPROVE | WARNING | BLOCK
  • APPROVE = no CRITICAL/HIGH
  • WARNING = HIGH only
  • BLOCK = any CRITICAL

If no findings, output one line:

APPROVE: openspec/ shape is valid. <N> change(s) checked.

Verification

  • All six checks ran against the current openspec/ diff (or working tree).
  • No openspec/specs/ SSOT edit outside an archive commit (Check 1).
  • Every spec-delta carries ADDED / MODIFIED / REMOVED markers (Check 2).
  • Each active change has proposal.md, tasks.md, and specs/ (Check 3).
  • Slugs are kebab-case (Check 5); proposal capability refs resolve (Check 6).
  • Verdict emitted: APPROVE / WARNING / BLOCK.

Common traps the guard catches

  • Writer "fixes" the SSOT directly because the change felt small — Check 1 catches this. The fix is mechanical (move the diff under the change directory), but only if caught before merge.
  • Spec written without delta markers because the author copied an SSOT file as the template — Check 2 catches this. The whole spec is well- formed but it's a no-op on archive.
  • tasks.md declared as done in a stand-up but never checked off — Check 4 catches this. Reduces "what's left on this change?" ambiguity.
  • camelCase slug from a quick mkdir — Check 5 catches this. Tool slug derivation typically splits on hyphens; a camel slug becomes one giant token.

Related skills

  • openspec-verify-change — full pre-archive verifier (this skill is the fast subset)
  • openspec-archive-change — applies delta directives to SSOT
  • openspec-sync-specs — manual delta merge without archiving

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.