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.
In this repository39 other files it gives its agents.
- AGENTS.mdAGENTS.md
- change-verdictSkill
- code-simplifySkill
- code-traceSkill
- create-prSkill
- deploy-listSkill
- doc-maintainSkill
- feature-verifySkill
- flow-driveSkill
- flow-guideSkill
- git-smart-commitSkill
- git-worktreeSkill
- harness-setupSkill
- issue-analyzeSkill
- js-static-checksSkill
- laravelSkill
- legacy-characterization-testsSkill
- library-authorSkill
- merge-prepSkill
- module-designSkill
- nextjsSkill
- opsx-apply-resumeSkill
- phpSkill
- phpunitSkill
- precommitSkill
- project-auditSkill
- project-briefSkill
- proposal-analyzeSkill
- pr-summarySkill
- pythonSkill
- reactSkill
- release-creatorSkill
- repo-intakeSkill
- repo-verifySkill
- swiftSkill
- tdd-workflowSkill
- ui-ux-verifySkill
- vue-2-notesSkill
- yii1Skill
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
- Very specific: line 31
Before invoking openspec:archive on a change (last-line safety net)
- Distinctive: line 32
After mass-rename in the openspec tree (slug normalization)
- Very specific: line 75
If both conditions are met → APPROVE.
- Very specific: line 120
If commits is substantial (≥ 3) but unchecked is still high, the tasks.md is drifting from actual progress.
- Distinctive: line 173
If no findings, output one line:
- Distinctive: line 194
Check 1 catches this. The fix is mechanical (move the diff under the change directory), but only if caught before merge.
- Distinctive: line 200
Check 4 catches this. Reduces "what's left on this change?" ambiguity.
≈ “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.
Files
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:archiveon 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:verifyalready (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/nullAlso 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
archiveAND - The same commit touches
openspec/changes/.archive/<slug>/oropenspec/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
doneSkip 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.mdexists (capability already in SSOT — change is modifying it), ORopenspec/changes/<slug>/specs/<id>/spec.mdexists withADDEDdirectives (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.mddeclared as done in a stand-up but never checked off — Check 4 catches this. Reduces "what's left on this change?" ambiguity.camelCaseslug from a quickmkdir— 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 SSOTopenspec-sync-specs— manual delta merge without archiving
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.

