plugins/build/skills/check-python-script/SKILL.md
Audits a standalone Python 3 script against 25 deterministic checks (shebang, `__main__` guard, argparse shape, declared dependencies, ruff-backed AST lints, line count, secret patterns) plus nine judgment dimensions (output discipline, input validation, dependency posture, performance intent, naming, function design, module-scope discipline, literal intent, commenting intent) and a Tier-3 cross-script collision check. Use when the user wants to "audit a python script", "lint a python script", or "review this script". Not for general-purpose shell scripts — route to `/build:check-bash-script`.
npx skillsauth add bcbeidel/wos check-python-scriptInstall 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 standalone Python 3 script for structural soundness, dependency posture, ruff-backed lint cleanliness, and adherence to the project's Python conventions. The rubric — what makes a Python script load-bearing, the anatomy template, the patterns that work — lives in python-script-best-practices.md.
This skill follows the check-skill pattern. Tier-1 detection is in 6 base scripts plus 2 profile-specific scripts emitting JSON envelopes via _common.py. Tier-2 has 9 base judgment dimensions plus up to 3 profile-specific dimensions read inline by the primary agent. Tier-3 is collision (cross-script duplication).
Profiles. This skill audits three python-script shapes: cli (default), library, skill-helper. The applicable Tier-1 scripts and Tier-2 dimensions vary per profile. See python-script-profiles.md for the complete applicability matrix.
Also fires when the user phrases the request as:
Read $ARGUMENTS. Resolve to a .py file or directory walking top-level for Python scripts. Confirm scope aloud.
Resolve profile. If $ARGUMENTS carries --profile=<name> (one of cli, library, skill-helper), use that. Else run the detector and use its result:
PROFILE=$(python3 "${SHARED_SCRIPTS}/detect_python_profile.py" "$TARGET")
The detector is heuristic and best-effort; ambiguous cases default to cli. Print the resolved profile to the user before continuing — if it looks wrong, they can re-run with --profile=<name>.
Per-profile invocation list (full matrix in python-script-profiles.md):
SCRIPTS="${SKILL_DIR}/scripts"
TARGETS="$ARGUMENTS"
# Base set — runs under cli + skill-helper
bash "$SCRIPTS/check_secrets.sh" $TARGETS # 1 rule: secret (FAIL) — all profiles
bash "$SCRIPTS/check_deps.sh" $TARGETS # 1 rule: declared-deps (WARN) — all profiles
bash "$SCRIPTS/check_ruff.sh" $TARGETS # 13 rules wrapping ruff codes — all profiles
bash "$SCRIPTS/check_size.sh" $TARGETS # 1 rule: size (WARN) — all profiles
# CLI-shell rules — skip when profile=library
if [[ "$PROFILE" != "library" ]]; then
bash "$SCRIPTS/check_structure.sh" $TARGETS # 6 rules
bash "$SCRIPTS/check_argparse.sh" $TARGETS # 3 rules
fi
# Profile-specific
case "$PROFILE" in
library)
python3 "$SCRIPTS/check_library_discipline.py" $TARGETS # 2 rules
;;
skill-helper)
python3 "$SCRIPTS/check_skill_helper_contract.py" $TARGETS # 3 rules
;;
esac
Each script emits a JSON array of envelopes. recommended_changes is canonical — copy through verbatim.
Script-to-rules map (Tier-1 rule_ids per profile):
| Script | rule_ids | Severity | Profiles |
|---|---|---|---|
| check_secrets.sh | secret | fail | cli, library, skill-helper |
| check_structure.sh | shebang, guard-missing, guard-shape, syntax | fail | cli, skill-helper |
| check_structure.sh | main-returns, keyboard-interrupt | warn | cli, skill-helper |
| check_argparse.sh | argparse-when-argv, add-argument-help, subprocess-check | warn | cli, skill-helper |
| check_deps.sh | declared-deps | warn | cli, library, skill-helper |
| check_ruff.sh | ruff-D100, ruff-SIM115, ruff-PLW1514, ruff-PTH, ruff-F401, ruff-ANN, ruff-format, ruff-fstring-modernize | warn | cli, library, skill-helper |
| check_ruff.sh | ruff-E722, ruff-shell-true, ruff-S307, ruff-F403, ruff-S108 | fail | cli, library, skill-helper |
| check_size.sh | size | warn | cli, library, skill-helper |
| check_library_discipline.py | library-no-side-effects | fail | library |
| check_library_discipline.py | library-public-api-declared | warn | library |
| check_skill_helper_contract.py | skill-helper-stdin-json | fail | skill-helper |
| check_skill_helper_contract.py | skill-helper-atomic-write, skill-helper-distinct-error-codes | warn | skill-helper |
The previously-INFO exec-bit rule is dropped (the pattern has no INFO; the executable-bit check still runs in _ast_checks.py for parity but emits no finding).
ruff-S602 and ruff-S604 consolidate into single rule_id ruff-shell-true (both about shell=True in subprocess). ruff-UP031 and ruff-UP032 consolidate into ruff-fstring-modernize (both about printf-style → f-string).
Tier-2 exclusion list. Any FAIL in secret, shebang, guard-missing, guard-shape, syntax, ruff-E722, ruff-shell-true, ruff-S307, ruff-F403, or ruff-S108 excludes the script from Tier-2.
Missing-tool degradation. check_ruff.sh emits all 13 envelopes with overall_status: inapplicable and exits 0 when ruff is absent. Other scripts continue.
For each script that passed the Tier-2 exclusion gate, evaluate against the 9 base judgment rules at references/check-*.md (all profiles), plus the profile-specific dimensions from the table below:
| File | Dimension | Severity | |---|---|---| | check-output-discipline.md | D1 — data to stdout, chatter to stderr | warn | | check-input-validation.md | D2 — argparse types narrow input early | warn | | check-dependency-posture.md | D3 — stdlib first; declared deps for the rest | warn | | check-performance-intent.md | D4 — generators / context managers / file streaming | warn | | check-naming.md | D5 — snake_case, intent-naming | warn | | check-function-design.md | D6 — small functions; main() orchestrator | warn | | check-module-scope-discipline.md | D7 — import + constant + main; no top-level work | warn | | check-literal-intent.md | D8 — magic numbers / strings named via constants | warn | | check-commenting-intent.md | D9 — docstring + why-comments, no what-comments | warn |
Profile-specific dimensions:
| File | Dimension | Severity | Profile | |---|---|---|---| | check-no-import-time-side-effects.md | Library — no work at import time | warn | library | | check-public-symbols-typed.md | Library — type hints on public surface | warn | library | | check-public-symbols-documented.md | Library — docstrings on public symbols | warn | library | | check-structured-stderr-errors.md | Skill-helper — JSON to stderr, not tracebacks | warn | skill-helper | | check-exit-code-meaning.md | Skill-helper — distinct exit codes by recovery class | warn | skill-helper |
Evaluator policy: see check-skill-pattern.md §Evaluator policy. Read all 9 rule files first, then evaluate the script in one LLM call.
Evaluate against check-collision.md. Surface duplicate logic across scripts (e.g., copy-pasted helper functions, duplicated argparse setups) as warn. Single-script scope returns inapplicable.
Merge findings from all 3 tiers. Sort fail before warn before inapplicable; Tier-1 before Tier-2 before Tier-3. Each Recommendation: line copies through recommended_changes verbatim.
Ask once: "Apply fixes? Enter y (all), n (skip), or comma-separated numbers."
For each selected finding:
__main__ guard, argparse help text, pathlib.Path over os.path, etc. Show diff; write on confirmation./build:build-python-script.After each fix, re-run the relevant Tier-1 script.
pass envelope.inapplicable — surface them.recommended_changes. Copy through; do not paraphrase.check_ruff.sh consolidates 15 ruff codes into 13 rule_ids (ruff-shell-true covers S602+S604; ruff-fstring-modernize covers UP031+UP032).Chainable to: /build:build-python-script (rebuild non-compliant scripts 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".