plugins/build/skills/check-readme/SKILL.md
Audits a project's top-level README.md against 28 deterministic checks across seven scripts (secret scanning, H1 uniqueness & position, heading-hierarchy skips, section presence & order, TOC threshold, line count & length, code-block language tags, shell-prompt prefixes, smart quotes in code, relative-link resolution, fragment-anchor resolution, image alt text, badge/image byte size, destructive-command flagging, pipe-to-shell patterns, TLS-disable instructions, non-reserved hostnames/IPs, emoji in headings, LICENSE file presence & link, CONTRIBUTING link, TODO/FIXME/XXX markers, README gitignore status) plus seven judgment dimensions and a Tier-3 cross-README collision check. Use when the user wants to "audit a README", "lint a README", or "run linters on README.md". Not for sub-package READMEs (different rubric) or docs-site pages (different toolchain).
npx skillsauth add bcbeidel/wos check-readmeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit a project's top-level README.md for structural soundness, safety, prose quality, and freshness. The rubric — what makes a README load-bearing in the top 30 seconds — lives in readme-best-practices.md.
This skill follows the check-skill pattern. Tier-1 detection is in 7 scripts emitting JSON envelopes via _common.py (28 rule_ids total). Tier-2 has 7 judgment dimensions read inline by the primary agent. Tier-3 is collision (cross-README duplication, judgment-driven).
Also fires when the user phrases the request as:
Read $ARGUMENTS:
Refuse on sub-package READMEs (under packages/*/README.md) — different rubric. Confirm scope aloud.
Invoke 7 detection scripts:
SCRIPTS="${SKILL_DIR}/scripts"
TARGETS="$ARGUMENTS"
python3 "$SCRIPTS/check_secrets.py" $TARGETS # 1 rule: secret (FAIL)
python3 "$SCRIPTS/check_structure.py" $TARGETS # 7 rules: h1-present (FAIL), heading-hierarchy, section-coverage, section-order, toc-threshold, size, prose-line-length
python3 "$SCRIPTS/check_codeblocks.py" $TARGETS # 4 rules: fence-language, shell-prompt, smart-quotes, code-line-length (all WARN)
python3 "$SCRIPTS/check_links.py" $TARGETS # 3 rules: broken-relative (FAIL), broken-anchor, broken-external
python3 "$SCRIPTS/check_images.py" $TARGETS # 3 rules: alt-text, image-size, badge-overload (all WARN)
python3 "$SCRIPTS/check_safety.py" $TARGETS # 5 rules: destructive (FAIL), pipe-to-shell (FAIL), tls-disable (FAIL), non-reserved-hosts (FAIL), emoji-headings
python3 "$SCRIPTS/check_completeness.py" $TARGETS # 5 rules: license-file (FAIL), license-link, contributing-link, todo-markers, readme-gitignored
Each script emits a JSON array of envelopes. recommended_changes is canonical — copy through verbatim.
Script-to-rules map (28 Tier-1 rule_ids):
| Script | rule_ids | Severity |
|---|---|---|
| check_secrets.py | secret | fail |
| check_structure.py | h1-present | fail |
| check_structure.py | heading-hierarchy, section-coverage, section-order, toc-threshold, size, prose-line-length | warn |
| check_codeblocks.py | fence-language, shell-prompt, smart-quotes, code-line-length | warn |
| check_links.py | broken-relative | fail |
| check_links.py | broken-anchor, broken-external | warn |
| check_images.py | alt-text, image-size, badge-overload | warn |
| check_safety.py | destructive, pipe-to-shell, tls-disable, non-reserved-hosts | fail |
| check_safety.py | emoji-headings | warn |
| check_completeness.py | license-file | fail |
| check_completeness.py | license-link, contributing-link, todo-markers, readme-gitignored | warn |
Tier-2 exclusion list. Any FAIL in secret, h1-present, broken-relative, destructive, pipe-to-shell, tls-disable, non-reserved-hosts, or license-file excludes the README from Tier-2.
Missing-tool degradation. check_links.py requires lychee or markdown-link-check for the broken-external rule; when neither is installed, that envelope emits overall_status: inapplicable (other rule_ids continue).
For each README that passed the Tier-2 exclusion gate, evaluate against the 7 judgment rules at references/check-*.md:
| File | Dimension | Severity |
|---|---|---|
| check-opening-clarity.md | D1 — H1 + one-sentence problem statement orient in 5 seconds | warn |
| check-installation-correctness.md | D2 — install steps are copy-pasteable and complete | warn |
| check-quickstart-effectiveness.md | D3 — quickstart produces a runnable artifact in <10 minutes | warn |
| check-placeholder-discipline.md | D4 — every <placeholder> is justified, not copy-paste padding | warn |
| check-warning-prominence.md | D5 — destructive ops carry visible warnings | warn |
| check-maintenance-posture.md | D6 — README freshness signals (last-updated, contributor links) | warn |
| check-style-and-voice.md | D7 — direct, plain English; no marketing prose | warn |
Evaluator policy: see check-skill-pattern.md §Evaluator policy. Read all 7 rule files first, then evaluate the README in one LLM call.
Evaluate against check-collision.md. For multi-README scope (org-wide audits, monorepos), surface duplicate Installation / Contributing / License prose across sibling READMEs as warn. Single-README scope returns inapplicable.
Merge Tier-1 (script JSON) + Tier-2 (judgment) + Tier-3 (collision) findings into a unified table:
| Tier | rule_id | Location | Status | Reasoning |
|------|---------|----------|--------|-----------|
Sort: fail before warn before inapplicable; Tier-1 before Tier-2 before Tier-3 within severity. Each Recommendation: line copies through recommended_changes verbatim.
Ask exactly once:
"Apply fixes? Enter y (all), n (skip), or comma-separated numbers."
For each selected finding:
/build:build-readme.After each applied fix, re-run the relevant Tier-1 script. Terminate when the user enters n or exhausts findings.
lychee/markdown-link-check is absent, the broken-external envelope emits inapplicable — surface it.recommended_changes. Each rule's recipe constant is canonical guidance from readme-best-practices.md.inapplicable.Chainable to: /build:build-readme (rebuild non-compliant README from scratch).
tools
Use when the user wants to "audit a help skill", "review my plugin index", or "verify my help-skill is up to date". Audits a plugins/<plugin>/skills/help/SKILL.md against the help-skill rubric — coverage, freshness, frontmatter fidelity, plus five judgment dimensions and a trigger-collision check.
tools
Use when the user wants to "scaffold a help skill", "add a /<plugin>:help command", or "build a plugin index skill", or wants to give a plugin an orientation surface that lists its skills and common workflows. Produces a SKILL.md at plugins/<plugin>/skills/help/SKILL.md.
tools
Audits pair-level integrity of a primitive-pair (the artifact `/build:build-skill-pair` produces) by walking the four required artifact slots — principles doc, `build-<primitive>/SKILL.md`, `check-<primitive>/SKILL.md`, and the `primitive-routing.md` registration — and reports cross-artifact issues a per-SKILL.md checker cannot see: missing principles doc, divergent principles paths between halves, absent routing registration, missing build→check handoff. Per-half structural compliance with the unified pattern (`check-skill-pattern.md`) is delegated to `plugins/build/_shared/scripts/check_skill_pattern.py`. Use when the user wants to "audit a skill pair", "review a primitive pair", or "validate the skill pair for X". Not for auditing a single SKILL.md — route to `/build:check-skill`. Not for re-distilling a stale principles doc — route to `/build:build-skill-pair`.
testing
Audit a root-level resolver — verify AGENTS.md pointer, managed-region integrity, filing-table coverage against disk, context-table actionability, and trigger-eval pass rate. Use when the user wants to "audit a resolver", "validate routing table", or "find dark capabilities".