Files
FabledGrimoire/tests/test_skill_structure.py
T
bvandeusenandClaude Opus 5.5 ba0b56018e docs(6209): calibration stamp, after-write hook, usage seam, work log, duplicates, skill structure, tuning and rulebook routes, kind surface, prompt filter, moments, strict args, auth, lesson write path
Fourteen more test files: docstrings state the failure each guard defends
as a present-tense shape instead of the incident that found it, and issue,
milestone and rule numbers leave comments and assertion messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 21:35:44 -04:00

109 lines
4.2 KiB
Python

"""Every bundled skill keeps the shape Agent Skills can load well.
WHY THIS EXISTS
Anthropic's skill authoring guidance
(platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices):
keep the SKILL.md body under 500 lines, split into reference files as it
nears that, and link each reference file ONE level deep from SKILL.md —
Claude may only preview a file reached through another reference file.
using-scribe grows because every new practice lands there. What matters on
most turns stays in SKILL.md; what matters at one moment (placing a rule, a
missed retrieval, starting a project) lives in files SKILL.md names with the
moment to open them. These tests keep that shape from quietly undoing
itself.
WHAT IT PINS
1. A BUDGET BELOW THE GUIDELINE. 500 is where loading degrades; the budget
sits under it so the next addition is a choice about what moves out, not
a squeeze past the line.
2. EVERY REFERENCE FILE IS LINKED FROM SKILL.md. A file nothing links is
never read — it states guidance that reaches nobody.
3. NO REFERENCE FILE LINKS ANOTHER. One level deep, per the guidance.
4. A LONG REFERENCE FILE OPENS WITH ITS CONTENTS, so a partial read still
shows what the file covers.
"""
from __future__ import annotations
import pathlib
import re
SKILLS = pathlib.Path(__file__).resolve().parents[1] / "plugin" / "skills"
SKILL_LINE_BUDGET = 350
TOC_AFTER_LINES = 100
_MD_LINK = re.compile(r"\]\(([^)#\s]+\.md)\)")
def _skill_dirs() -> list[pathlib.Path]:
return sorted(p.parent for p in SKILLS.glob("*/SKILL.md"))
def _refs(folder: pathlib.Path) -> list[pathlib.Path]:
return sorted(p for p in folder.glob("*.md") if p.name != "SKILL.md")
def over_budget(texts: dict[str, str], budget: int) -> list[str]:
return [f"{k}: {len(t.splitlines())} lines" for k, t in texts.items()
if len(t.splitlines()) > budget]
def unlinked(skill_md: str, ref_names: list[str]) -> list[str]:
linked = set(_MD_LINK.findall(skill_md))
return [n for n in ref_names if n not in linked]
def nested(refs: dict[str, str]) -> list[str]:
return [f"{name} → {target}" for name, text in refs.items()
for target in _MD_LINK.findall(text)]
def missing_contents(refs: dict[str, str], after: int) -> list[str]:
return [name for name, text in refs.items()
if len(text.splitlines()) > after and "## Contents" not in text]
def test_every_skill_md_fits_its_budget():
found = over_budget({d.name: (d / "SKILL.md").read_text() for d in _skill_dirs()},
SKILL_LINE_BUDGET)
assert not found, (
f"SKILL.md over {SKILL_LINE_BUDGET} lines: {found}. Move what matters at "
f"one moment into a reference file SKILL.md links with that moment, "
f"rather than raising the budget toward 500."
)
def test_every_reference_file_is_linked_from_skill_md():
found = [f"{d.name}/{n}" for d in _skill_dirs()
for n in unlinked((d / "SKILL.md").read_text(), [p.name for p in _refs(d)])]
assert not found, (
f"reference files no SKILL.md links: {found}. Nothing reads a file "
f"nothing names — link it from SKILL.md with the moment to open it."
)
def test_reference_files_are_one_level_deep():
found = [f"{d.name}/{x}" for d in _skill_dirs()
for x in nested({p.name: p.read_text() for p in _refs(d)})]
assert not found, (
f"reference files linking other files: {found}. Link each from SKILL.md "
f"directly; a file reached through another may only be previewed."
)
def test_long_reference_files_open_with_contents():
found = [f"{d.name}/{n}" for d in _skill_dirs()
for n in missing_contents({p.name: p.read_text() for p in _refs(d)},
TOC_AFTER_LINES)]
assert not found, f"reference files over {TOC_AFTER_LINES} lines with no '## Contents': {found}"
def test_the_guards_can_fail():
"""Each guard bites on the failure it exists for."""
assert over_budget({"s": "x\n" * 400}, SKILL_LINE_BUDGET) == ["s: 400 lines"]
assert unlinked("see [a](a.md)", ["a.md", "b.md"]) == ["b.md"]
assert nested({"a.md": "then [b](b.md)"}) == ["a.md → b.md"]
assert missing_contents({"a.md": "x\n" * 150}, TOC_AFTER_LINES) == ["a.md"]