4.1. Linting
What does formatting protect?
Formatting removes review noise so behavioral changes stand out. Linting catches likely defects, insecure patterns, debug output, stale imports, and inconsistent APIs before tests run. Neither replaces tests or design review.
Which tools own which files?
| Files | Formatter/checker |
|---|---|
| Python | Ruff format and import sorting; Ruff lint; ty types |
| Markdown/JSON/TOML/YAML/Dockerfile | dprint |
| Shell | shfmt and ShellCheck |
| GitHub Actions | actionlint |
| Python metadata/lock | validate-pyproject and uv lock --check |
The root tasks delegate to the component task instead of duplicating flags.
How strict is Ruff?
The project selects broad correctness, security, modernization, performance, logging, and style rule families. Tests receive only justified exceptions such as assert and diagnostic print use. A production file should not accumulate file-wide suppressions.
[tool.ruff]
line-length = 120
[tool.ruff.format]
docstring-code-format = true
line-ending = "lf"
quote-style = "double"
The complete rule list lives in agents/python/pyproject.toml; prose should not duplicate it.
How do you format and check everything?
From the repository root:
format may modify files. Review the diff afterward. check runs docs rules/build, dprint, Python lint/types/audit, shell checks, and workflow lint without intentionally rewriting sources.
Why do docs have structural checks?
scripts/check-docs.sh verifies every course page has description front matter, an FAQ H2, question-form H2 headings, no machine-specific paths, and no retired registry reference. A site that renders can still have a broken teaching contract, so structure is checked before Zensical builds.
What is the lint checkpoint?
Continue only after reviewing formatter changes and resolving every warning at its cause. A warning-free gate is part of correctness, not optional polish.