PyQA Lint Orchestrator (pyqa_lint)
PyQA is Blackcat Informatics Inc.'s opinionated quality-assurance harness. It ships as the pyqa_lint package (install via pip install pyqa_lint) and can also be vendored as a git submodule so teams can run the Typer-based CLI (pyqa) with zero external dependencies.
TL;DR: Deterministic lint orchestration, SOLID-aware reporting, curated tool catalogs, and provenance-backed releases for modern Python repositories.
Quick Links
- Getting Started
- CLI Overview
- Feature Highlights
- Architecture & Docs
- Releases & Provenance
- Configuration & Tooling Schema
- Advanced Capabilities
- Contributing & Support
Table of Contents
- Why PyQA?
- Installation Options
- Getting Started
- CLI Overview
- Feature Highlights
- Architecture & Docs
- Releases & Provenance
- Configuration & Tooling Schema
- Advanced Capabilities
- Contributing & Support
- License
Why PyQA?
- Curated multi-language linting powered by ruff, pylint, bandit, mypy, pyright, sqlfluff, yamllint, and more.
- Polyglot coverage across Python, JavaScript/TypeScript, Go, Rust, SQL, YAML, TOML, Markdown, Dockerfiles, Bash, and Lua via the built-in catalog.
- Deterministic environments built with
uv, with optional system-tool reuse when explicitly allowed. - Explainable orchestration via
--explain-toolsand--explain-tools-json, so contributors see why tools ran or skipped. - SOLID advice + refactor navigator driven by tree-sitter and spaCy to highlight structural issues, hotspots, and symbols.
- First-class reporting to Markdown, SARIF 2.1.0, JSON, and PR summaries, plus machine-readable tool catalogs.
- Interface-first design: runtime modules consume Protocols from
pyqa.interfaces.*, keeping extensions pluggable and testable.
Language Coverage
PyQA's catalog bundles analyzers, formatters, and value-type rules for multiple ecosystems. Highlights include:
- Python – ruff, pylint, bandit, mypy, pyright, pytest helpers, value-type analysis.
- JavaScript / TypeScript – eslint, prettier, tsc, markdownlint cross-checks for front-end code.
- Go – golangci-lint, gofmt, module tidy helpers.
- Rust – clippy, cargo fmt, cargo check integrations.
- Shell & Containers – shellcheck, shfmt, hadolint, dockerfilelint.
- Data & Config – sqlfluff (SQL), yamllint (YAML), taplo (TOML), markdownlint/mdformat (Markdown), terraformer rules.
- Scripting & DSLs – luacheck (Lua), phpcs (PHP), generic tree-sitter hooks for custom DSLs.
Refer to tooling/catalog/ for the authoritative list and metadata for each tool.
Installation Options
PyPI (recommended)
pip install pyqa_lint
# exposes the `pyqa` CLI globally
Git Submodule
git submodule add https://github.com/paudley/pyqa_lint.git pyqa-lint
This layout keeps the managed scripts (lint, check-quality, security-scan, install, install-hooks, etc.) inside your repository without publishing a wheel.
Local Development
Clone the repo and sync the toolchain:
uv sync --group dev
The shims in the repo root (./lint, ./check-quality, ./install, ./security-scan) automatically target the synced .venv.
Getting Started
git submodule add https://github.com/paudley/pyqa_lint.git pyqa-lintcd pyqa-lint && uv sync --group dev./install-hooksto wirepre-commit,pre-push, andcommit-msg./lint(orpyqa lint) to run the curated pipeline
Hooks and CI both execute pyqa check-quality + pyqa lint, so the same guardrails apply everywhere.
CLI Overview
| Command | How to run | Summary |
|---|---|---|
lint |
pyqa lint or ./lint |
Runs the orchestrated lint/test pipeline, explain mode, exporters, and cache management. |
check-quality |
pyqa check-quality or ./check-quality |
Enforces SPDX headers, notices, schema freshness, file-size limits, and repo guardrails. |
security-scan |
pyqa security-scan or ./security-scan |
Performs secret scanning plus Bandit/semgrep-style analyzers. |
install |
pyqa install or ./install |
Installs the managed toolchain into the current project (legacy shell workflow parity). |
install-hooks |
pyqa install-hooks or ./install-hooks |
Symlinks vetted Git hooks that call pyqa check-quality. |
config ... |
pyqa config <subcommand> |
Show/diff/validate layered configuration, export tool schemas, inspect explainable plans. |
update |
pyqa update or ./update-packages |
Refresh pinned dependencies across Python/Node/Go/Rust workspaces. |
sparkly-clean |
./sparkly-clean |
Remove caches and artefacts without touching tracked files. |
Run pyqa --help or pyqa <command> --help for detailed options.
Feature Highlights
- Explainable selection:
pyqa lint --explain-tools [--json]renders the tool order, reasons, eligibility, and registry descriptions. Tests assert table + JSON output so UX changes stay stable. - SOLID advice + highlighting:
--adviceadds the SOLID panel, Refactor Navigator stats, and tree-sitter/spaCy highlighting. Exporters can embed the same data viapyqa.reporting.emitters.write_pr_summary(include_advice=True). - Value-type analysis: opt into
[tool.pyqa.generic_value_types]inpyproject.tomland runpyqa lint --check-value-types-generalto enforce structural traits (for example repositories must implement__len__+__contains__). - Deterministic envs:
uvmanages every dependency. PyQA reuses system binaries only when they are newer and you have not forced--use-local-linters. - Rich reporting: emit Markdown, SARIF, JSON, or PR summaries, and pipe catalogs into
ref_docs/tool-schema.jsonwithpyqa config export-tools. - Typed catalog + DI seams: runtime modules only import from
pyqa.interfaces.*, while the reusable schema lives insrc/tooling_spec/for downstream consumers.
Architecture & Docs
The REORG initiative is complete and all guidance now lives in first-class docs:
docs/ARCHITECTURE.md– package responsibilities, SOLID guardrails, and interface boundaries.SELECTION.md,SOLID_CLI.md,docs/orchestration/*– orchestration internals, DI seams, progress rendering, and state machines.docs/tooling/– catalog schemas, shared knobs, and authoring guides.docs/release/0.3.0.md– highlights for the rename + provenance work.
Key takeaways:
pyqa.cachehandles persistence and cache repositories behindpyqa.interfaces.cache.pyqa.analysisprovides spaCy/tree-sitter integrations and refactor analytics.pyqa.reportingowns console/Markdown/SARIF emitters and the SOLID advice builder.pyqa.clihosts the Typer app, option builders, and launcher shims (mirrored by./lint,./install, etc.).pyqa.toolsdefines built-in tool registrations plus parser Protocols.tooling_specis a standalone distribution exporting the catalog schema for external tooling.
Releases & Provenance
- Package name:
pyqa_lint; CLI/import namespace:pyqa. v*tags trigger.github/workflows/release.yml, which:- Runs
uv sync --group dev - Builds sdist + wheel via
python -m build - Uploads artefacts for inspection
- Generates a GitHub attestation (
actions/attest-build-provenance@v1) - Publishes to PyPI via
pypa/gh-action-pypi-publishwith attestations enabled
- Runs
- Required repo secret:
PYPI_API_TOKEN(trusted publisher token forpyqa_lint). - Release checklist: bump
pyproject.toml, updatedocs/release/<version>.md, regenerateref_docs/tool-schema.json(uv run pyqa config export-tools --check ref_docs/tool-schema.json), commit, tagvX.Y.Z, push tag.
Configuration & Tooling Schema
- Layered configuration: defaults →
~/.pyqa_lint.toml→[tool.pyqa]inpyproject.toml→<project>/.pyqa_lint.toml. Inspect withpyqa config show --root <path> --traceor compare layers viapyqa config diff. - Strict validation: pass
--strict-config(orpyqa config validate --strict) to fail on unknown keys. - License policy:
[tool.pyqa.license]declares SPDX identifiers, notices, year ranges, and exceptions enforced bypyqa check-quality. - Quality defaults:
[tool.pyqa.quality]centralizes enabled checks, schema targets, skip globs, and protected branches for hooks/CI. - Shared knobs:
[complexity]and[strictness]propagate limits to ruff, pylint, luacheck, mypy, pyright, tsc, etc. Sensitivity presets (--sensitivity low|medium|high|maximum) shift multiple thresholds together. - Tool overrides: configure
[tool.pyqa.<tool>](or.pyqa_lint.toml's[tools.<tool>]) to customize args/env per tool; CLI flags still win for ad-hoc overrides. - Schema exports:
pyqa config schema --format markdowndocuments every option;pyqa config schema --format json-tools --out ref_docs/tool-schema.jsonandpyqa config export-toolskeep the checked-in schema current.
Advanced Capabilities
Value-Type Analyzer
[tool.pyqa.generic_value_types]
enabled = true
[[tool.pyqa.generic_value_types.rules]]
pattern = "myapp.repositories.*"
traits = ["iterable", "value"]
require = ["__len__", "__contains__"]
recommend = ["__repr__"]
[[tool.pyqa.generic_value_types.implications]]
trigger = "method:__len__"
require = ["__bool__"]
severity = "warning"
Run pyqa lint --check-value-types-general (or ./lint --check-value-types-general). Diagnostics such as generic-value-types:missing-required demand a suppression_valid justification when they cannot be satisfied.
Tooling Schema Validation
./lint --validate-schema
# or
uv run python -m jsonschema -F errors \
-i tooling/catalog/languages/python/bandit.json \
tooling/schema/tool_definition.schema.json
The catalog schemas are intentionally reusable so other orchestrators can adopt the same contracts. See tooling/schema/SCHEMA.md and tooling/catalog/docs/SHARED_KNOBS.md for field-by-field detail.
NLP Requirements
Tree-sitter grammars are pinned in pyproject.toml and installed via uv. Install spaCy's English model once per environment:
uv run python -m spacy download en_core_web_sm
Override with PYQA_NLP_MODEL=<model> or disable highlighting entirely with --no-color in strict CI logs.
Contributing & Support
- Review CONTRIBUTING.md and the Code of Conduct before submitting PRs.
- Run
uv run pyqa check-qualityanduv run pytestlocally prior to opening a PR. - File issues or feature requests directly on GitHub; include the output from
pyqa lint --explain-toolswhen reporting orchestration bugs.
License
This project is licensed under the MIT License. See LICENSE for details.
Metadata
Release files for pyqa-lint 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyqa_lint-0.3.0.tar.gz | 365.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyqa_lint-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 880.7 kB
Release files / pyqa_lint-0.3.0.tar.gz
| Download URL | pyqa_lint-0.3.0.tar.gz |
|---|---|
| Size | 365.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ec2caa0f0ef3e90ab8b81a4200d1b01349e5d7f5686918d5b38b645486c9555b
|
|
BLAKE2b-256 checksum How to use checksums |
143783c43a277ef632aa9608a5297f6cefac88da911b9b1c7cb13a39673f5f4c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 12, 2025.
Transparency logRelease files / pyqa_lint-0.3.0-py3-none-any.whl
| Download URL | pyqa_lint-0.3.0-py3-none-any.whl |
|---|---|
| Size | 515.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
227ec388bf45a497869748455f547dfff28595149bc55decaf522c1fabefed7e
|
|
BLAKE2b-256 checksum How to use checksums |
25e854b8b15d48d0c719320400b4998764555b6eba1e86d1394e030f7a27eb96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 12, 2025.
Transparency log