v0.15.0 — "Fable Ultra"
Our biggest release ever: 42 commits, 378 files changed, ~18.5k insertions
since v0.14.1. The headline is a full plugin architecture for distributing
lint rules as PyPI packages, alongside the removal of the built-in LLM fix
engine, a new dead-file detection rule, and a long list of autofix,
correctness, security, and performance fixes.
Highlights
Plugin architecture (#312, #311, #313, #314)
Rules can now be distributed as ordinary pip-installable packages via
skillsaw.plugins entry points — reviewable, versioned, and auditable,
unlike repo-local custom rule files.
- Rule plugins: any package exposing a
skillsaw.pluginsentry point
contributes rules, namespaced and attributed (source: plugin:<name>
in JSON output). - Extension points: plugins can register custom repo types
(SKILLSAW_REPO_TYPES) and lint-tree contributors
(SKILLSAW_TREE_CONTRIBUTORS), pulling new file types into the parse
tree and content linting. - Plugin CLIs:
skillsaw <name>dispatches to a plugin's
skillsaw-<name>console script — registered plugins only; arbitrary
executables on PATH are never run. - Management: new
skillsaw pluginscommand,--no-pluginsflag, and
plugins: {disable: [...]}config block. A plugin that fails to load
reports aplugin-load-errorviolation instead of aborting the lint. - GitHub Action: new
pluginsinput installs plugins in CI (#314). - Docs: a full authoring guide (
docs/plugins.md), a scaffold example
underexamples/plugins/, and askillsaw-create-pluginskill.
⚠️ Breaking: LLM fix engine removed (#310)
The built-in LLM autofix path is gone in favor of coding agents (see the
skillsaw-fix skill and per-rule skillsaw explain guidance):
- Removed flags:
skillsaw fix --llm/--ai,--model,--max-iterations,
--all,-y/--yes,--workers,--patch-file,--apply-patch, and
the hiddenskillsaw lint --fix/--llm/--dry-run. - Removed pip extras:
skillsaw[llm],[vertexai],[bedrock]
(installing them now fails). - Removed rule API:
AutofixConfidence.LLM,llm_fix_prompt,
llm_fix_frontmatter— custom rules and plugins using them must update. - The
llm:config section is now an ignored unknown-key warning;
SKILLSAW_MODELis ignored.
⚠️ Breaking: GitHub Action defaults to --no-custom-rules (#323)
For CI safety on untrusted PRs, the Action no longer executes repo-local
.skillsaw-custom.py rules by default. Nothing fails — custom rules
silently stop running. Set no-custom-rules: false to opt back in, or
migrate to a rule plugin. The CLI default is unchanged, and custom-rule
loading now prints a clear one-line colored warning (#359).
New rule: agentskill-unreferenced-files (#347)
Detects dead files in skill directories — files never referenced from
SKILL.md or anything it transitively references. Warning severity,
enabled: auto on skill/plugin/marketplace repos, with an exclude
config parameter. Reachability is thorough: markdown links and text
mentions (case-insensitive), directory mentions (./fonts,
assets/fonts, fonts/), and Python import chains — both in .py
helpers and inside fenced code blocks — are all followed transitively.
Spec compliance & validation
metadata.pluginRoothonored when resolving marketplace plugin
sources, per the Claude Code marketplace spec — bare source names now
resolve, with a root-relative fallback for marketplaces that mix styles;
traversing/absolute pluginRoots are rejected (#355).- marketplace.json source validation per the current spec: duplicate
plugin names,../absolute paths, typed-source required fields, unknown
source types (#338). - Frontmatter hooks scanned:
hooks-dangerousandhooks-prohibited
now inspecthooks:declared in skill/agent frontmatter, not just
hooks JSON files (#346). - Hooks & MCP validation synced with current Claude Code docs —
exec-formargs, MCPtimeout,MessageDisplayevent,ws
transport (#336). - Digit-leading skill names (e.g.
1password) now valid per the
agentskills.io spec (#337).
Autofix reliability
- SAFE autofix corruption fixed: path truncation from backtrackable
lookarounds, and duplicatename:keys from non-converging
frontmatter fixes (#325). - BOM and CRLF line endings preserved byte-exactly across autofix (#332).
agentskill-nameautofix no longer folds inline YAML comments into the
rename manifest; comments are preserved on the rewritten line (#352).content-broken-internal-referenceresolves percent-encoded links and
never emits unparseable destinations (#350).
Rule accuracy
content-embedded-secrets: entropy gating + placeholder allowlist
kills documentation-placeholder false positives (password = "changeme",<your-api-key>,${VAR}templates). Structured
high-confidence tokens (AKIA…, ghp_…, JWTs, private keys) are always
reported. Configurable viaentropy-thresholdand
additional-placeholders(#354).**-glob exclude semantics fixed:**/templates/**now matches a
top-leveltemplates/directory, matching gitignore semantics — a
strict superset of the old behavior, applied to global, per-rule, and
agentskill-unreferenced-filesexcludes (#353).agentskill-descriptionmax length is configurable via
max_length(#348).- Four small bug fixes from the #322 sweep: custom-rule abstract-class
guard,@~/imports, stackeddisable-next-line, docs crash (#351).
Security & performance
- ReDoS protection: config-driven
banned-referencesregexes run under a
wall-clock timeout (regex-timeout, default 2s) (#330). - promptfoo
file://references contained to the repo root — traversal,
absolute paths, and symlink escapes are rejected (#349). - Fixed O(n²) behavior in
markdown_doc._ContentMap.locate(#328). - Benchmarks vs 0.14.1: synthetic suite at parity; plugin discovery adds
no measurable startup cost (--version/--helpnever touch entry
points).
Docs & DX
- "How to fix" guidance added to every builtin rule page — also surfaced
throughskillsaw explain, feeding agent-driven fix loops (#309). - SARIF output docs, exit-code reference, configuration reference, clean
skillsaw addscaffolds, stale pin cleanup (#326). - CLI internals:
__main__.pygod module split into acli/package
(#308); block hierarchy extracted toskillsaw.blocks(#307);
single-source rule registration (#311).
Upgrade notes — what may change on your repo
agentskill-unreferenced-filesmay fire new warnings (auto-enabled on
skill-type repos).- Expanded
marketplace-json-validand frontmatter-hooks scanning may
surface new violations; plugins undermetadata.pluginRootare now
discovered and linted. - A top-level
templates/directory is now excluded by default; digit-
leading skill names and placeholder-shaped "secrets" no longer flagged. skillsaw pluginsnow lists installed plugin packages (exit 0) instead
of linting theplugins/directory — update CI that relied on the old
behavior.- Action users: custom rules require
no-custom-rules: false(see above).
Known issues
- The secrets entropy gate trades false positives for some false
negatives on generickey = "value"assignments (e.g. long digit-only
values, values containing allowlisted words liketoken); structured
token detection is unaffected.