axm-audit — Code auditing and quality rules for Python projects
axm-audit audits Python project quality across 9 scored categories (plus structure and tooling, which emit findings but are not scored), producing a composite 0–100 score with an A–F grade. It is available through the unified axm CLI, the Python API, and MCP for AI agents.
Features
- 🔍 Linting — Ruff analysis (800+ rules)
- 🔒 Type Checking — Strict mypy (per-project
pyproject.tomlconfig) - 📊 Complexity — Cyclomatic + cognitive complexity (radon + complexipy)
- 🛡️ Security — Bandit integration + hardcoded secrets detection
- 📦 Dependencies — Vulnerability scanning (pip-audit) + hygiene (deptry) with false-positive filtering for entry-point and optional-dependency packages, uv workspace support (auto-aggregation across members), and dual-format text output (
• pkg ver→fix CVE-idwith+Nsuffix for multiple CVEs) - 🧪 Testing — Coverage enforcement via pytest-cov
- 🏗️ Architecture — Circular imports, god classes, coupling metrics, duplication detection
- 📐 Practices — Docstring coverage (with cross-file abstract override detection), bare except detection, hardcoded secrets, blocking I/O, test mirroring (unit 1:1 with src) and scenario naming (integration/e2e)
- 🔧 Tooling — CLI tool availability checks
- 📈 Composite Scoring — Weighted 9-category 0–100 score with A–F grade
Installation
uv add axm-audit
Quick Start
CLI
# Full audit
axm audit .
# Filter by category
axm audit . --category lint
# Deterministically reorganise the test suite (dry-run by default)
axm audit_fix .
axm audit_fix . --apply
# Run tests with structured output
axm audit_test .
# Validate the documentation build
axm doc_gate .
Python API
from pathlib import Path
from axm_audit import audit_project
result = audit_project(Path("."))
print(f"Grade: {result.grade} ({result.quality_score:.1f}/100)")
print(f"Checks: {result.total - result.failed}/{result.total} passed")
for check in result.checks:
if not check.passed:
print(f" ❌ {check.rule_id}: {check.message}")
if check.fix_hint:
print(f" Fix: {check.fix_hint}")
MCP (AI Agent)
axm-audit is available as an MCP tool via axm-mcp. AI agents can call audit(path) or verify(path) directly:
# Agent-optimized output: passed checks as compact strings,
# failed checks as dicts with rule_id, message, details, fix_hint
from axm_audit.formatters import format_agent
data = format_agent(result)
# data["score"], data["grade"], data["passed"], data["failed"]
See the MCP how-to guide for details.
Scoring Model
9-category weighted composite on a 100-point scale:
| Category | Weight | Tool |
|---|---|---|
| Linting | 15% | Ruff |
| Type Safety | 15% | mypy |
| Complexity | 15% | radon + complexipy |
| Security | 10% | Bandit |
| Dependencies | 10% | pip-audit + deptry |
| Testing | 10% | pytest-cov |
| Test Quality | 10% | AST analysis |
| Architecture | 10% | AST analysis |
| Practices | 5% | AST analysis |
Categories structure and tooling emit findings but are not scored.
Categories
| Category | Rules | Count |
|---|---|---|
lint |
LintingRule, FormattingRule, DiffSizeRule, DeadCodeRule |
4 |
type |
TypeCheckRule |
1 |
complexity |
ComplexityRule |
1 |
security |
SecurityRule (Bandit), SecurityPatternRule |
2 |
deps |
DependencyAuditRule, DependencyHygieneRule |
2 |
testing |
TestCoverageRule |
1 |
test_quality |
DuplicateTestsRule, FileNamingRule, NoPackageSymbolRule, PrivateImportsRule, PyramidLevelRule, TautologyRule |
6 |
architecture |
CircularImportRule, GodClassRule, CouplingMetricRule, DuplicationRule |
4 |
practices |
MirrorRule, AntiMirrorRule, BareExceptRule, BlockingIORule, DocstringCoverageRule, EnvCredentialsRule, ToolSecretLocationRule |
7 |
structure |
PyprojectCompletenessRule, TestsPyramidRule |
2 |
tooling |
ToolAvailabilityRule |
1 |
Configuration
Coupling Thresholds
The CouplingMetricRule reads thresholds from pyproject.toml:
[tool.axm-audit.coupling]
fan_out_threshold = 15 # default: 10
severity_error_multiplier = 2 # default: 2, minimum: 1
[tool.axm-audit.coupling.overrides]
"my_package.hub" = 20 # allow higher fan-out for hub modules
"registry" = 25 # matches any module ending with .registry
fan_out_threshold— global fan-out limit (modules above this are flagged)overrides— per-module thresholds; keys match by exact name or suffixseverity_error_multiplier— tiered severity: modules with fan-out above the effective threshold but withinthreshold × multiplierget a warning (−3 pts); beyond that they get an error (−5 pts). Only errors cause the check to fail; warnings alone still pass.
When no configuration is present, the default threshold of 10 and multiplier of 2 are used.
Mirror Exemptions
MirrorRule reads optional exemptions for both
mirror directions from pyproject.toml:
[tool.axm-audit.mirror]
exempt_paths = ["commands/*.py", "schemas/*.py", "**/_facade.py"]
exempt_tests = ["conformance/**", "contracts/*.py"]
exempt_paths covers the forward direction: globs anchored at
src/<top_pkg>/; exempted modules do not require a matching
tests/unit/test_*.py and surface in details["exempt"].
exempt_tests covers the reverse direction: globs anchored at
tests/unit/; cross-cutting test files with no source mirror (e.g.
conformance suites that exercise every dispatcher) are whitelisted out
of the orphan list and surface in details["exempt_tests"].
For both keys, * and ? never cross / and ** matches zero or more
path segments. The two keys are independent: exempt_paths never clears
an orphan and exempt_tests never clears a missing source module.
Invalid TOML or a wrong exempt_paths / exempt_tests type fails the
rule with a fix_hint instead of raising.
UV Workspace Support
DependencyHygieneRule automatically detects uv workspaces via [tool.uv.workspace].members in the root pyproject.toml. When a workspace is detected, deptry runs on each member package independently and results are aggregated into a single CheckResult with per-member attribution in top_issues.
Test Quality
The test_quality category ships six rules (private-imports,
pyramid-level, duplicate-tests, tautology, file-naming, no-package-symbol)
plus the v6 pyramid stack and the v4 tautology triage ladder. See docs/test_quality.md
for the full guide, including the 5 pyramid scoping rules, the 3 + 4
duplicate signals/rescues, and the 22-step triage ladder.
Witness Rules
axm-audit ships a witness rule for use with the axm.witnesses entry point group:
| Rule | Entry point key | Default categories |
|---|---|---|
AuditQualityRule |
audit_quality |
lint, type |
AuditQualityRule runs audit_project for each configured category independently (a lint failure does not prevent type checking) and returns structured agent-friendly feedback via format_agent, with a compact text summary via format_agent_text.
Params:
| Param | Type | Purpose |
|---|---|---|
categories |
list[str] |
Categories to audit (default ["lint", "type"]). Must be a subset of the auditor's valid categories — see below. |
working_dir |
str |
Project root to audit (overridable per-call via a working_dir kwarg). |
scope |
str |
Reserved sub-scope selector. |
exclude_rules |
list[str] |
Rule-id prefixes to drop from the failure list (e.g. ["QUALITY_DIFF_SIZE"]). |
extra_dirs |
list[str] |
Extra directories to audit with the same categories (e.g. blast-radius packages). |
guidance |
str | None |
Extra instructions appended to the failure how message. |
Valid categories = the auditor's, not a private subset. The witness accepts exactly the categories audit_project knows how to run (architecture, complexity, deps, lint, practices, security, structure, test_quality, testing, tooling, type). A category outside that set is a hard config error: the gate returns WitnessResult.failure(...) (RED) rather than silently skipping it. An empty categories list is likewise RED. This is deliberate: a quality gate must never pass green having audited nothing — a mis-configured gate that swallowed unknown categories used to do exactly that.
Development
This package is part of the axm-forge workspace.
git clone https://github.com/axm-protocols/axm-forge.git
cd axm-forge
uv sync --all-groups
uv run --package axm-audit --directory packages/axm-audit pytest -x -q
License
Apache-2.0 — © 2026 axm-protocols
Metadata
Release files for axm-audit 0.12.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 | |
|---|---|---|---|
| axm_audit-0.12.0.tar.gz | 644.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| axm_audit-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 973.1 kB
Release files / axm_audit-0.12.0.tar.gz
| Download URL | axm_audit-0.12.0.tar.gz |
|---|---|
| Size | 644.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e2b22e2a75aa5d24bf7e8aa99cc85a41b1f15b7fb457122c77072e82e13d2616
|
|
BLAKE2b-256 checksum How to use checksums |
b3f4202e6298f7d9380937b250393880286779ce80872fd74aa04a73b730576d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 8, 2026.
Transparency logRelease files / axm_audit-0.12.0-py3-none-any.whl
| Download URL | axm_audit-0.12.0-py3-none-any.whl |
|---|---|
| Size | 328.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
80d088c27eb4505f3b5a05742063a2e2fe09fc14fbde912859cd44159cb14e15
|
|
BLAKE2b-256 checksum How to use checksums |
5cc3381174d3d71062293182ce2189a56c35543aaf32aa51bd453b961f5bb982
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 8, 2026.
Transparency log