
Audit Skills
- 117 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Review agent skill definitions for unclear triggers, unsafe tool usage, missing guardrails, and inconsistent instructions before distributing skills to teammates or publishing them in a shared hub.
About
audit-skills from yonatangross/orchestkit inspects Claude Code and agent skill files for structure, safety, activation boundaries, and maintainability. It helps teams standardize skill libraries and reduce prompt drift before skills are shared broadly across repos and operators.
- Skill trigger and scope review
- Tool-use safety checks
- Prompt clarity and consistency
- Overlap and duplication detection
- Publish-ready skill hardening
Audit Skills by the numbers
- 117 all-time installs (skills.sh)
- Ranked #246 of 782 Skill Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill audit-skillsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 117 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Review agent skill definitions for unclear triggers, unsafe tool usage, missing guardrails, and inconsistent instructions before distributing skills to teammates or publishing them in a shared hub.
Files
audit-skills
Scans all src/skills/*/SKILL.md files and reports compliance with OrchestKit authoring standards. Each category has individual files in rules/ and references/ loaded on-demand.
Quick Reference
| Category | File | Impact | When to Use |
|---|---|---|---|
| Audit Checks | ${CLAUDE_SKILL_DIR}/rules/audit-checks.md | HIGH | What to validate per skill |
| Status Rules | ${CLAUDE_SKILL_DIR}/rules/audit-status.md | MEDIUM | PASS/WARN/FAIL classification |
| Output Format | ${CLAUDE_SKILL_DIR}/references/output-format.md | MEDIUM | Table layout and column definitions |
| Edge Cases | ${CLAUDE_SKILL_DIR}/references/edge-cases.md | LOW | Manifest "all", orchestration skills |
Total: 2 rules across 2 categories
CRITICAL: Task Management is MANDATORY (CC 2.1.16)
BEFORE doing ANYTHING else, create tasks to track progress:
# 1. Create main task IMMEDIATELY
TaskCreate(
subject="Audit Skills: full scan",
description="Auditing all OrchestKit skills for quality and compliance",
activeForm="Auditing skill quality"
)
# 2. Create subtasks for each audit phase
TaskCreate(subject="Discover skills", activeForm="Globbing SKILL.md files")
TaskCreate(subject="Run audit checks", activeForm="Checking each skill")
TaskCreate(subject="Classify & render", activeForm="Classifying results and rendering report")
# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"])
TaskUpdate(taskId="4", addBlockedBy=["3"])
# 4. Before starting each task, verify it's unblocked
task = TaskGet(taskId="2") # Verify blockedBy is empty
# 5. Update status as you progress
TaskUpdate(taskId="2", status="in_progress") # When starting
TaskUpdate(taskId="2", status="completed") # When doneWorkflow
1. Discover — Glob src/skills/*/SKILL.md to get full skill list 2. Check each skill — Run all checks from Read("${CLAUDE_SKILL_DIR}/rules/audit-checks.md") in parallel 3. Classify — Apply status rules from Read("${CLAUDE_SKILL_DIR}/rules/audit-status.md") 4. Render — Output table using format from Read("${CLAUDE_SKILL_DIR}/references/output-format.md") 5. Totals — Show X pass, Y warn, Z fail at bottom
Quick Start
bash src/skills/audit-skills/scripts/run-audit.shOr invoke manually — Claude scans src/skills/, applies checks, and renders the summary table.
CC 2.1.152+: After fixing SKILL.md files surfaced by the audit, run/reload-skillsto re-scan skill directories and pick up the changes in-session (no restart). For plugin-packaged skills, rebuild +/reload-pluginsinstead.
Key Decisions
| Decision | Recommendation |
|---|---|
| Manifest check | "skills": "all" in ork.json means ALL skills qualify — mark YES |
| 0 rules + refs | WARN only — some orchestration skills are legitimately rules-free |
| Broken refs | WARN (not FAIL) — file may exist under a different path |
Related Skills
ork:skill-evolution— Guidance on iterating and improving skillsork:quality-gates— Broader codebase quality checks
Audit Edge Cases
Manifest "all" Shorthand
manifests/ork.json uses "skills": "all" to include every skill in src/skills/. When this is present, every discovered skill is automatically manifest-registered — mark Mfst as YES without listing individual names.
// manifests/ork.json — "all" means everything in src/skills/ qualifies
{ "skills": "all" }When manifests/ork.json has "skills": "all", every skill in src/skills/ is registered.
Orchestration Skills with 0 Rules
Orchestration/workflow skills describe multi-phase processes rather than prescriptive code patterns. They legitimately have 0 rule files but use references/ for workflow templates, rubrics, and report formats.
Skills in this category (not exhaustive):
implement,explore,verify,brainstormreview-pr,assess,fix-issuevisualize-plan,configure,remember
These should only receive WARN: no_rules_or_refs if BOTH rules/ AND references/ are empty.
Required Frontmatter Fields
The authoring standard (src/skills/CONTRIBUTING-SKILLS.md) lists these as required:
name, description, tags, version, author, user-invocable, complexityOlder skills may be missing version and author — flag as WARN, not FAIL, since the skill still functions.
Broken Reference Detection
Scan SKILL.md body for patterns like:
rules/some-file.md
references/some-file.mdFor each mentioned path, verify the file exists under src/skills/<name>/. Flag WARN if missing.
False positive: generic markdown links to external URLs — skip http:// and https:// patterns.
Project-Level Skills
Skills under .claude/skills/ (project-level) are not registered in manifests/. Exclude them from manifest checks or mark Mfst as N/A.
Audit Output Format
Summary Table
Skill Lines FM Rules Refs Mfst Status
---------------------------------------------------------------------------
<skill-name> NNN OK N N YES PASS
<skill-name> NNN WARN N N YES WARN
WARN: missing_fm:version,author
<skill-name> NNN OK 0 0 NO FAIL
FAIL: not_in_manifest
WARN: no_rules_or_refs
---------------------------------------------------------------------------
Total: N skills | PASS: X | WARN: Y | FAIL: ZColumn Definitions
| Column | Width | Values | Meaning |
|---|---|---|---|
| Skill | 40 chars, left-aligned | <dir-name> | Directory name under src/skills/ |
| Lines | 5 chars, right-aligned | integer | Line count of SKILL.md |
| FM | 4 chars, right-aligned | OK / WARN | All required frontmatter present? |
| Rules | 5 chars, right-aligned | integer | Non-template rule files in rules/ |
| Refs | 4 chars, right-aligned | integer | Files in references/ |
| Mfst | 5 chars, right-aligned | YES / NO | Registered in ork.json? |
| Status | — | PASS / WARN / FAIL | Overall result |
Detail Lines
For each non-PASS skill, print indented detail lines directly below its table row:
FAIL: <reason>
WARN: <reason>Multiple conditions each get their own line.
Totals Line
Always show at the end:
Total: N skills | PASS: X | WARN: Y | FAIL: ZWhere N = X + Y + Z.
Rule Categories
1. Per-Skill Checks (checks) — HIGH — 1 rule
The six checks to run for every SKILL.md: line count, required frontmatter fields, rules count, references count, no-supporting-files flag, and manifest registration.
audit-checks.md— Check definitions, pass/fail criteria, command examples, parallelization guidance
2. Status Classification (status) — MEDIUM — 1 rule
How to map check results to PASS / WARN / FAIL per skill, and how to format output detail lines for non-PASS skills.
audit-status.md— Severity table, classification logic, output format, precedence rules
[Rule Name]
[Brief description — 1-2 sentences.]
Incorrect:
// Bad patternCorrect:
// Good patternKey rules:
- [Rule 1]
- [Rule 2]
- [Rule 3]
Reference: [link]
Per-Skill Audit Checks
Run these six checks for every src/skills/<name>/SKILL.md. Use parallel Glob/Grep calls where possible.
Check 1: Line Count
Count lines in SKILL.md.
Incorrect:
# Skipping line count — misses the Anthropic 500-line limitCorrect:
wc -l src/skills/<name>/SKILL.md
# Flag FAIL if count > 500
# Flag WARN if count > 400 (approaching limit)Check 2: Required Frontmatter Fields
Parse the --- block at the top of SKILL.md. Required fields:
name, description, tags, version, author, user-invocable, complexityIncorrect:
# Missing version, author — produces incomplete metadata
name: my-skill
description: Does something
tags: [tag]
user-invocable: false
complexity: lowCorrect:
name: my-skill
description: Does something. Use when X.
tags: [tag1, tag2]
version: 2.0.0
author: OrchestKit
user-invocable: false
complexity: lowFlag WARN for each missing required field. List the missing fields.
Check 3: Rules Count
Glob src/skills/<name>/rules/*.md, excluding _sections.md and _template.md.
# Count rule files (non-underscore-prefixed)
ls src/skills/<name>/rules/*.md 2>/dev/null | grep -v '^_'Store as rules_count. Used in Check 5 combined with refs count.
Check 4: References Count
Glob src/skills/<name>/references/*.md.
ls src/skills/<name>/references/*.md 2>/dev/nullStore as refs_count. Used in Check 5 combined with rules count.
Check 5: No Supporting Files
Flag WARN if rules_count == 0 AND refs_count == 0.
Exception: orchestration skills (implement, explore, verify, brainstorm, etc.) with inline workflow detail are acceptable with 0 rules — only flag if BOTH are zero.
Check 6: Manifest Registration
Check whether the skill appears in manifests/ork.json.
Correct:
with open("manifests/ork.json") as f:
ork = json.load(f)
# ork.json "skills": "all" means every src/skills/* is included
if ork.get("skills") == "all":
in_ork = True
else:
in_ork = skill_name in [s if isinstance(s,str) else s["name"]
for s in ork.get("skills", [])]Flag FAIL if skill is absent from both manifests.
Key rules:
- Run Checks 3 and 4 in parallel (independent Glob calls)
- Check 6 must handle
"skills": "all"shorthand in ork.json - Checks 1 and 2 together form the SKILL.md header validation
- Never skip Check 6 — unregistered skills are dead weight
Audit Status Classification
Maps check results from audit-checks.md to a PASS / WARN / FAIL status per skill.
Severity Table
| Condition | Severity |
|---|---|
lines > 500 | FAIL |
| Not in any manifest | FAIL |
| Missing required frontmatter field | WARN |
rules_count == 0 AND refs_count == 0 | WARN |
| Broken reference (file mentioned in SKILL.md but missing on disk) | WARN |
lines > 400 (approaching limit) | WARN |
Classification Logic
Incorrect:
# Treating all issues as WARN — masks real failures
status = "WARN" if any_issue else "PASS"Correct:
fails = []
warns = []
if line_count > 500:
fails.append(f"lines={line_count}>500")
elif line_count > 400:
warns.append(f"lines={line_count}>400 (approaching limit)")
if missing_fm:
warns.append(f"missing_fm:{','.join(sorted(missing_fm))}")
if rules_count == 0 and refs_count == 0:
warns.append("no_rules_or_refs")
if not in_manifest:
fails.append("not_in_manifest")
if broken_refs:
for ref in broken_refs:
warns.append(f"broken_ref:{ref}")
# Final status: FAIL > WARN > PASS
if fails:
status = "FAIL"
elif warns:
status = "WARN"
else:
status = "PASS"Output Detail Lines
Print WARN/FAIL details indented under the skill row:
my-skill 510 OK 3 0 YES FAIL
FAIL: lines=510>500
my-skill-2 210 WARN 0 0 YES WARN
WARN: missing_fm:version,author
WARN: no_rules_or_refsKey rules:
- FAIL takes precedence over WARN — a skill with both is FAIL
- Always print detail lines for non-PASS skills for actionability
- Treat each missing frontmatter field as a separate WARN item
#!/usr/bin/env bash
# run-audit.sh — Audit OrchestKit skills for quality and compliance
# Usage: scripts/run-audit.sh [--fail-fast]
# Requires: jq
# Run from the repo root.
set -euo pipefail
FAIL_FAST=false
while [[ $# -gt 0 ]]; do
case "$1" in
--fail-fast) FAIL_FAST=true; shift ;;
--help|-h)
echo "Usage: $0 [--fail-fast]"
echo "Audits all src/skills/*/SKILL.md for quality and compliance."
exit 0 ;;
*) echo "Unknown option: $1. Use --help." >&2; exit 2 ;;
esac
done
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
SKILLS_DIR="$REPO_ROOT/src/skills"
ORK_MANIFEST="$REPO_ROOT/manifests/ork.json"
if [[ ! -d "$SKILLS_DIR" ]]; then
echo "Error: src/skills/ not found at $REPO_ROOT" >&2; exit 1
fi
# Check if ork.json uses "all" shorthand
ORK_SKILLS_VAL=$(jq -r '.skills' "$ORK_MANIFEST" 2>/dev/null || echo "")
ORK_ALL=false
[[ "$ORK_SKILLS_VAL" == "all" ]] && ORK_ALL=true
PASS=0; WARN=0; FAIL=0
printf "%-40s %5s %4s %5s %4s %4s %s\n" "Skill" "Lines" "FM" "Rules" "Refs" "Mfst" "Status"
printf -- '-%.0s' {1..75}; echo
for SKILL_MD in "$SKILLS_DIR"/*/SKILL.md; do
SKILL_DIR=$(dirname "$SKILL_MD")
SKILL_NAME=$(basename "$SKILL_DIR")
STATUS="PASS"
WARNINGS=()
FAILS=()
# Check 1: line count
LINE_COUNT=$(wc -l < "$SKILL_MD" | tr -d ' ')
if (( LINE_COUNT > 500 )); then
FAILS+=("FAIL: skill_md_too_long:${LINE_COUNT}_lines")
STATUS="FAIL"
elif (( LINE_COUNT > 400 )); then
WARNINGS+=("WARN: approaching_500_line_limit:${LINE_COUNT}_lines")
[[ "$STATUS" == "PASS" ]] && STATUS="WARN"
fi
# Check 2: required frontmatter
FM_ISSUES=()
for FIELD in name description tags version author user-invocable complexity; do
grep -q "^${FIELD}:" "$SKILL_MD" || FM_ISSUES+=("$FIELD")
done
FM_STATUS="OK"
if (( ${#FM_ISSUES[@]} > 0 )); then
FM_STATUS="WARN"
WARNINGS+=("WARN: missing_fm:$(IFS=,; echo "${FM_ISSUES[*]}")")
[[ "$STATUS" == "PASS" ]] && STATUS="WARN"
fi
# Check 3 & 4: rules and refs count
RULES_COUNT=$(find "$SKILL_DIR/rules" -name "*.md" 2>/dev/null | grep -v '/[_]' | wc -l | tr -d ' ')
REFS_COUNT=$(find "$SKILL_DIR/references" -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
# Check 5: no supporting files
if (( RULES_COUNT == 0 && REFS_COUNT == 0 )); then
WARNINGS+=("WARN: no_rules_or_refs")
[[ "$STATUS" == "PASS" ]] && STATUS="WARN"
fi
# Check 6: manifest registration
MFST="YES"
if ! $ORK_ALL; then
IN_ORK=$(jq -r --arg n "$SKILL_NAME" '.skills | if type=="array" then (map(if type=="object" then .name else . end) | index($n)) != null else false end' "$ORK_MANIFEST" 2>/dev/null || echo "false")
[[ "$IN_ORK" != "true" ]] && MFST="NO"
fi
if [[ "$MFST" == "NO" ]]; then
FAILS+=("FAIL: not_in_manifest")
STATUS="FAIL"
fi
printf "%-40s %5s %4s %5s %4s %4s %s\n" \
"$SKILL_NAME" "$LINE_COUNT" "$FM_STATUS" "$RULES_COUNT" "$REFS_COUNT" "$MFST" "$STATUS"
for W in "${WARNINGS[@]}"; do printf " %s\n" "$W"; done
for F in "${FAILS[@]}"; do printf " %s\n" "$F"; done
case "$STATUS" in
PASS) ((PASS++)) ;;
WARN) ((WARN++)) ;;
FAIL) ((FAIL++)); $FAIL_FAST && { echo "Stopped at first FAIL (--fail-fast)"; exit 1; } ;;
esac
done
printf -- '-%.0s' {1..75}; echo
echo "Total: $((PASS+WARN+FAIL)) skills | PASS: $PASS | WARN: $WARN | FAIL: $FAIL"
(( FAIL > 0 )) && exit 1 || exit 0
{
"skill": "audit-skills",
"version": "2.0.0",
"testCases": [
{
"id": "all-skills-pass",
"rule": null,
"query": "Run a full audit of all OrchestKit skills",
"expectedBehavior": [
"Globs src/skills/*/SKILL.md to discover all skills",
"Runs all audit checks from rules/audit-checks.md in parallel",
"Renders a table with skill name, line count, frontmatter status, manifest status, and rule/ref counts",
"Shows totals summary: 'X pass, 0 warn, 0 fail' at bottom"
]
},
{
"id": "skill-over-500-lines",
"rule": "audit-checks",
"query": "Audit skills and flag any that are too long",
"expectedBehavior": [
"Checks each SKILL.md body line count (excluding frontmatter)",
"Marks any skill over 500 lines as FAIL in the audit table",
"Reports the exact line count alongside the 500-line limit",
"Suggests trimming or moving content to rules/ or references/ subdirectories"
]
},
{
"id": "missing-frontmatter-field",
"rule": "audit-checks",
"query": "Check if all skills have required frontmatter fields",
"expectedBehavior": [
"Validates each SKILL.md has name, description, tags, user-invocable, and complexity fields",
"Marks skills with missing required fields as FAIL in the audit table",
"Lists which specific fields are absent for each failing skill",
"Applies status rules from rules/audit-status.md to classify PASS/WARN/FAIL"
]
},
{
"id": "skill-not-in-manifest",
"rule": "audit-checks",
"query": "Find any skills that exist in src/ but are not registered in the manifests",
"expectedBehavior": [
"Compares discovered src/skills/ directories against manifests/ork.json skills array",
"Treats 'skills: all' in ork.json as covering all skills — marks those as YES",
"Marks skills absent from ork.json as FAIL",
"Reports manifest registration status in the output table column"
]
},
{
"id": "zero-rules",
"rule": "audit-status",
"query": "Audit skills and highlight any that have no rules or references",
"expectedBehavior": [
"Counts files in each skill's rules/ and references/ subdirectories",
"Skills with 0 rules AND 0 references are flagged as WARN (not FAIL)",
"Notes that orchestration skills may legitimately have no rules",
"Includes rule and reference file counts as columns in the output table"
]
}
]
}