Semantic Lint

VerifiedSafe

Semantic lint of staged changes for issues static analysis misses: spelling errors, stale comments/docstrings, and house-style idioms. Report-only; --fix for safe mechanical fixes.

Sby Skills Guide Bot
DevelopmentIntermediate
7/27/2026
Claude Code
#linting#code-review#git-staged#semantic-analysis#python

Recommended for

Automated summary

Runs a semantic review of git staged changes to catch what ruff, black and formatters miss: typos, comments and docstrings that drifted from the code, stale docs, and house-style idioms.

Strengths

  • Defaults to the staged diff (git diff --cached), so it slots naturally into a pre-commit workflow
  • Pairs a candidate-gathering script (scan.sh) with LLM-only passes such as docstring/signature drift
  • Clearly separates safe mechanical fixes (--fix) from judgment findings, which are never auto-applied
  • Concrete check catalog: spelling, f-strings vs .format(), print vs logging, copy-paste residue, misleading names

Limitations

  • Heavily tuned to the Pegasus WMS repo (src/Pegasus/cli/ exclusion, internal conventions), so not directly reusable elsewhere
  • Report-only by default: without --fix nothing is modified and you must edit findings yourself
  • Semantic passes rely on the model reading the diff, so they are subject to false positives and variance
When to use it

Use it right before committing to re-read staged changes for typos, stale comments and documentation drift.

When not to use it

Don't use it as a replacement for ruff, black or formatters, nor on a repo lacking the scan.sh script and expected plugin layout.

Security analysis

Safe
Quality score85/100

All shell access is pinned to a single bundled scanner script plus read-only git and codespell invocations; there is no curl|sh piping, no recursive deletion, no credential/token handling, and no obfuscated payloads. The only notable surface is the unpinned `uvx codespell` network fetch and the Edit grant, both of which are conventional and scoped by documentation rather than being destructive or exfiltrating. No meaningful execution risk for listing.

Findings
  • •`uvx codespell` executes a package fetched from PyPI at runtime (network + remote code); it is a well-known linting package on a documented fallback path, but the version is unpinned
  • •Edit tool is granted to a skill described as report-only, though edits are documented as gated behind the explicit `--fix` flag and limited to trivial mechanical fixes
How this analysis is made

Examples

Lint staged changes
/lint — check my staged changes for typos, stale comments and docstring drift before I commit.
Fix safe mechanical issues
Run /lint --fix on the staged files and apply only the spelling corrections and trivially safe f-string conversions.
Scope to one file
Lint packages/pegasus-python/src/Pegasus/submitdir.py for comment/code drift and docstring that no longer matches the signature.

name: lint description: Semantic lint of staged changes for things static analysis misses — spelling/typos, comments that no longer match the code, docstring/signature drift, stale docs & manpages, and house-style idioms (f-strings over .format()/%, logging over print). Use when asked to lint, run /lint, check staged changes for typos or spelling, find stale comments/docs, or review changes for issues ruff/pre-commit won't catch. Report-only; pass --fix for safe mechanical fixes. model: sonnet effort: medium allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh:), Bash(bash ${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh:), Bash(git diff:), Bash(git status:), Bash(uvx codespell:*), Read, Edit

/lint — semantic linter for Pegasus WMS

/lint is a semantic reviewer, not another formatter. Pegasus already runs ruff, ruff-format, black/isort/autoflake, google-java-format and mdformat on every commit (pre-commit + the GitLab Lint job). This skill covers what those cannot: defects only a reader catches — misspellings, comments/docs that drifted from the code, and house-style idioms a formatter can't reason about.

It is driven by a candidate-gathering script, ${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh, plus LLM-only passes over the staged diff. Default target is the git staged set (git diff --cached). Report-only by default; --fix applies only safe mechanical fixes.

Explicit paths passed to the scanner are relative to the target repo's root, not the plugin.

Run (agent path)

  1. Gather mechanical candidates — run the scanner over the staged set (or pass explicit paths to scope it):

    ${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh                                   # staged files
    ${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh packages/pegasus-python/src/Pegasus/submitdir.py   # explicit path
    

    It prints grouped path:lineno: snippet sections (spelling, formatting, print). These are candidates — you confirm or dismiss each (see Gotchas for the false positives).

  2. Read the actual staged changes for the semantic passes:

    git diff --cached
    
  3. Triage + run the semantic checks below, then assemble the report (format below).

  4. If invoked with --fix: apply only the mechanical findings (spelling corrections; .format()/% → f-string where the conversion is trivially safe) via Edit. Never auto-apply a semantic/judgment finding — those go in the report only.

Check catalog

Mechanical (scan.sh surfaces, you confirm)

  • Spelling — comments, docstrings, identifiers, user-facing strings, and .rst/.md docs. (codespell; falls back to your reading of the diff if codespell is unavailable.)
  • .format() / % → f-strings — the repo is overwhelmingly f-strings (1000+ vs ~110).
  • print() in library code → logging — src/Pegasus/cli/ is the sanctioned exception and is excluded by the scanner.

Semantic (LLM-only — read the diff; no script can do these)

  • Comment ⇄ code drift — comment/docstring claims X but the code does Y; comment references a renamed variable/param; stale comment left behind after a refactor.
  • Docstring ⇄ signature drift — Google-style :param:/:type:/return don't match the actual args or return; a documented raises that can't happen, or a raised exception that isn't documented.
  • Doc staleness — changed CLI flags/options, class signatures, or behavior not reflected in doc/sphinx/ (autodoc + sphinx_click manpages), the package README.md, or examples. Flag example commands/snippets that would no longer run.
  • Misleading names — get_*/is_* that mutates; a name that says one unit but the code uses another.
  • Error/log quality — message text that contradicts the actual failure; wrong log level (logging.error on a normal path); bare except: pass that swallows.
  • Copy-paste residue — a duplicated block where one variable wasn't updated.
  • Magic numbers/strings — unexplained literals a named constant or comment would clarify.
  • Terminology consistency — the same concept named differently across code and docs.
  • Stale TODO/FIXME — markers referencing work that's already done or removed.
  • Hardcoded paths/URLs/secrets — absolute paths, hostnames, or credentials that belong in config.

Report format

Group by check. One line per finding: file:line — issue — suggested fix. Order high→low confidence. State plainly when a section had no findings. End with a one-line summary count, e.g. Summary: 3 spelling, 1 comment-drift, 0 doc-staleness.

Gotchas

  • codespell isn't installed directly — the scanner runs it via uvx codespell (~1.5s startup). If neither codespell, the codespell_lib module, nor uvx is present, the spelling section prints a degrade notice and you cover spelling by reading the diff.
  • codespell exits non-zero when it finds typos — handled in the script (keys off output, not exit status); don't "fix" that with set -e.
  • %/.format() false positives — many % hits are regex, SQL LIKE, or strftime patterns, not string formatting. The scanner already drops logging-format lines (log.info("%s", x) is correct lazy logging); confirm the rest before flagging.
  • print() under cli/ is fine — those are user-facing CLI tools and are excluded.
  • --fix is mechanical-only — applying a semantic finding without human judgment is how you introduce bugs. Report them; don't edit them.
  • Empty staged set — scan.sh with nothing staged exits cleanly with a hint; stage files (git add) or pass explicit paths.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/semantic-lint-ms2s7c29/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/semantic-lint-ms2s7c29' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/semantic-lint-ms2s7c29/download' --output '.skill-downloads/semantic-lint-ms2s7c29/SKILL.md.part' && mv '.skill-downloads/semantic-lint-ms2s7c29/SKILL.md.part' '.skill-downloads/semantic-lint-ms2s7c29/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Tools declared by the author (check availability in your agent): Bash(${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh:*), Bash(bash ${CLAUDE_PLUGIN_ROOT}/skills/lint/scan.sh:*), Bash(git diff:*), Bash(git status:*), Bash(uvx codespell:*), Read, Edit

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/semantic-lint-ms2s7c29/SKILL.md' && test -s '.skill-downloads/semantic-lint-ms2s7c29/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/lint' && cp -R '.skill-downloads/semantic-lint-ms2s7c29' '.claude/skills/lint'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/semantic-lint-ms2s7c29'

openskills read 'semantic-lint-ms2s7c29'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/semantic-lint-ms2s7c29/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills