Skip to main content

AXM Logo

axm-audit — Code auditing and quality rules for Python projects

CI axm-audit axm-init Coverage PyPI Python 3.12+ Docs


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.

📖 Full documentation

Features

  • 🔍 Linting — Ruff analysis (800+ rules)
  • 🔒 Type Checking — Strict mypy (per-project pyproject.toml config)
  • 📊 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-id with +N suffix 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 suffix
  • severity_error_multiplier — tiered severity: modules with fan-out above the effective threshold but within threshold × multiplier get 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)

Source distribution for axm-audit 0.12.0
File Size Uploaded
axm_audit-0.12.0.tar.gz 644.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for axm-audit 0.12.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.12.0 This release

2 release files

0.11.0

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page