Polyglot lint orchestration toolkit
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyqa_lint-0.3.0.tar.gz.
File metadata
- Download URL: pyqa_lint-0.3.0.tar.gz
- Upload date:
- Size: 365.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec2caa0f0ef3e90ab8b81a4200d1b01349e5d7f5686918d5b38b645486c9555b
|
|
| MD5 |
517c5842dbef2570845795681e4eee66
|
|
| BLAKE2b-256 |
143783c43a277ef632aa9608a5297f6cefac88da911b9b1c7cb13a39673f5f4c
|
Provenance
The following attestation bundles were made for pyqa_lint-0.3.0.tar.gz:
Publisher:
release.yml on paudley/pyqa_lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyqa_lint-0.3.0.tar.gz -
Subject digest:
ec2caa0f0ef3e90ab8b81a4200d1b01349e5d7f5686918d5b38b645486c9555b - Sigstore transparency entry: 695912094
- Sigstore integration time:
-
Permalink:
paudley/pyqa_lint@35ef9ea9d34be79b1588c356c3e23702ec14392a -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/paudley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@35ef9ea9d34be79b1588c356c3e23702ec14392a -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyqa_lint-0.3.0-py3-none-any.whl.
File metadata
- Download URL: pyqa_lint-0.3.0-py3-none-any.whl
- Upload date:
- Size: 515.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
227ec388bf45a497869748455f547dfff28595149bc55decaf522c1fabefed7e
|
|
| MD5 |
5f568ea0311cb2ddbe491d91f8388859
|
|
| BLAKE2b-256 |
25e854b8b15d48d0c719320400b4998764555b6eba1e86d1394e030f7a27eb96
|
Provenance
The following attestation bundles were made for pyqa_lint-0.3.0-py3-none-any.whl:
Publisher:
release.yml on paudley/pyqa_lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyqa_lint-0.3.0-py3-none-any.whl -
Subject digest:
227ec388bf45a497869748455f547dfff28595149bc55decaf522c1fabefed7e - Sigstore transparency entry: 695912106
- Sigstore integration time:
-
Permalink:
paudley/pyqa_lint@35ef9ea9d34be79b1588c356c3e23702ec14392a -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/paudley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@35ef9ea9d34be79b1588c356c3e23702ec14392a -
Trigger Event:
push
-
Statement type: