skill-audit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited skill-audit (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
scripts/preflight.sh passes (jq, bash, bats).Receive a target path; if missing, ask: "What should I audit? e.g. `skills/distill/SKILL.md` (single) or `skills/` (batch)."
audit ./skills/distill/SKILL.md # single-mode
audit ./skills # batch-mode → globs skills/*/SKILL.md (+ *.ko.md if present), each processed independentlyPer-target validation: file readable · frontmatter present (between two ---) · body ≤ 500 lines (warn if larger; do not abort).
Parse the YAML frontmatter and the body separately, then construct an SSL representation. Use this prompt verbatim when delegating to an LLM helper:
Read the SKILL.md and emit JSON only — no markdown fences.
{
"scheduling": {
"triggers": [list of phrases from the description "Triggers:" line],
"anti_triggers": [from frontmatter ssl.scheduling.anti_triggers, or null],
"ambiguity_notes": "any trigger ≤ 4 chars, or generic adverb / conjunction"
},
"structural": {
"scenes": [from frontmatter, or inferred from "## Step N:" body headings],
"branches": [explicit branch conditions in body],
"resumable": bool
},
"logical": {
"tools": [from frontmatter ssl.logical.tools],
"side_effects": {
"reads": [], "writes": [], "deletes": [], "network": []
},
"idempotent": bool,
"rollback": string | null
}
}
Fields not justified by the body or frontmatter must be null or empty array. Do not infer.Avoiding inference is the whole point. A plausible-looking guess hides the audit signal.
| Layer | Check | Failure |
|---|---|---|
| Scheduling | triggers non-empty | missing |
| Scheduling | no trigger ≤ 4 chars / stand-alone conjunction or adverb | ambiguous |
| Scheduling | anti_triggers declared | missing |
| Scheduling | (batch only) no verbatim trigger collision with peers | collision |
| Structural | scenes ≥ 2 entries (no monolith) | missing |
| Structural | every branch condition declared in branches (not in prose) | implicit |
| Structural | resumable matches body (counter / state-marker file ⇒ true) | mismatch |
| Logical ×1.5 | every body tool call reflected in tools | undeclared |
| Logical ×1.5 | destructive cmds (rm / DROP / delete / --force) in side_effects.deletes (or writes if overwrite) | undeclared |
| Logical ×1.5 | network calls (curl / wget / fetch / http) in side_effects.network | undeclared |
| Logical ×1.5 | non-idempotent body but idempotent: true | mismatch |
| Logical ×1.5 | idempotent: false requires rollback | missing |
Cross-check grep — undeclared destructive command ⇒ Logical ✗:
grep -E '(rm -rf?|DROP|delete|--force|--no-preserve)' "$target" | head -20
# diff vs. frontmatter ssl.logical.side_effects.deletesPer layer, out of 100. Missing field −15 · ambiguous −8 · Logical-layer deductions × 1.5.
Status: ≥ 80 ✓ · 60–79 ⚠ · < 60 ✗.
The score is a triage signal — Top-3 risks matter more than the absolute number. A skill at 80 with a real Logical ✗ is more dangerous than one at 60 with three ⚠ on Scheduling.
CLI-friendly markdown with bar charts, Top-3 risks, and suggested frontmatter patches.
Single-mode shape:
┌─ <relative SKILL.md path> ─────────────┐
│ Scheduling ████████░░ 77 ⚠ │
│ Structural ██████████ 100 ✓ │
│ Logical ████░░░░░░ 43 ✗ │
└────────────────────────────────────────┘
Top 3 Risks:
1. ✗ [Logical] body has `rm -rf {tmp}` but side_effects.deletes is empty
2. ✗ [Logical] idempotent flag missing
3. ⚠ [Structural] Step 2 branch condition is in prose only
[Suggested patch — frontmatter]
ssl:
logical:
side_effects:
deletes: ["{tmp_dir} contents"]
idempotent: false
rollback: "Manual restore from .bak directory"Batch-mode adds: trigger collision matrix (phrase × skill; ✗ verbatim / ⚠ substring or stem) and tool dependency graph (shared tools / scripts / hooks → SPOFs).
Default: .galmuri/audit-{slug}.md (slug from target name). --stdout prints to terminal. --ci --threshold-logical=N exits non-zero when any skill's Logical score < N.
Constraint layer over the canonical 5 scenes — not a replacement, and no fix step. The skill stays read-only; patch application is the caller's responsibility on a separate commit.
| Scene | Tool discipline |
|---|---|
| 1. Ingest | fd + rg -l only. Emit filename list, never contents. No Read here. |
| 2. Decompose | Targeted rg -A 5 -B 5 'pattern' over full Read. Read allowed only on highest-risk files surfaced in Ingest. |
| 3. Audit | Batch mode may spawn ≤ 4 parallel sub-agents, each scoped to ≤ 3 files. Each returns only {file, line, layer, violation, suggested_patch} — no function quoting, no prose recap. |
| 4. Score | Aggregate to a single table. Never re-quote diffs surfaced in scene 3. |
| 5. Report | Chat: ≤ 5-line summary + report path. Full report to .galmuri/audit-{slug}.md (or docs/reports/<YYYY-MM-DD>-audit-<slug>.md in batch overflow). |
Read calls: ≤ 10 filesBash calls: ≤ 20If any limit is hit, write progress to tmp/audit-state-<n>.json and stop. Next invocation resumes from that state.
SSL framework: arXiv:2604.24026 (Liang et al., 2026); Schank & Abelson, Scripts, Plans, Goals and Understanding (1977).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.