Code auditing and quality rules for AXM
Project description
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 works as a CLI, Python API, and MCP tool for AI agents.
Features
- 🔍 Linting — Ruff analysis (800+ rules)
- 🔒 Type Checking — Strict mypy (per-project
pyproject.tomlconfig) - 📊 Complexity — Cyclomatic complexity via radon (Python API with subprocess fallback)
- 🛡️ 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 audit .
# JSON output
axm-audit audit . --json
# Agent-optimized output (compact, actionable)
axm-audit audit . --agent
# Filter by category
axm-audit 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 .
# Agent-optimized test output (compact, actionable)
axm-audit test . --agent
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 |
5 |
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 (alias TestMirrorRule) 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 four rules (private-imports,
pyramid-level, duplicate-tests, tautology) 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.
Hooks
axm-audit ships hooks for use with the axm.hooks entry point group:
| Hook | Entry point key | Description |
|---|---|---|
AutofixHook |
audit:autofix |
Run ruff check --fix + ruff format |
QualityCheckHook |
audit:quality-check |
Run audit categories and report violations |
QualityCheckHook accepts working_dir (str) and categories (list, default ["lint", "type"]) via params. It returns HookResult.ok(has_violations=bool, violations=list[dict], summary=str) for injection into protocol session context. Each violation dict includes a snippet field with ±5 lines of source around the violation line (line-numbered, with > marker), or None when the file/line is unresolvable. When working_dir points at a multi-package workspace (packages/*/src/), each package is audited independently and violations are reported per-package.
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
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 axm_audit-0.10.0.tar.gz.
File metadata
- Download URL: axm_audit-0.10.0.tar.gz
- Upload date:
- Size: 552.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39b21dd660e02dd126969b5cd81e57460793f96992be672d015591b65d2d4283
|
|
| MD5 |
ab2648274715f9eed392ab88b1b9b40c
|
|
| BLAKE2b-256 |
b6fef025445242245b7fc79ec4b1e8600a849ef7ea5028fb1c5cf65d79171a5d
|
Provenance
The following attestation bundles were made for axm_audit-0.10.0.tar.gz:
Publisher:
publish.yml on axm-protocols/axm-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axm_audit-0.10.0.tar.gz -
Subject digest:
39b21dd660e02dd126969b5cd81e57460793f96992be672d015591b65d2d4283 - Sigstore transparency entry: 1803941339
- Sigstore integration time:
-
Permalink:
axm-protocols/axm-forge@6dfb594c800a283ea1542aacd81ecbdef38151f6 -
Branch / Tag:
refs/tags/audit/v0.10.0 - Owner: https://github.com/axm-protocols
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6dfb594c800a283ea1542aacd81ecbdef38151f6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file axm_audit-0.10.0-py3-none-any.whl.
File metadata
- Download URL: axm_audit-0.10.0-py3-none-any.whl
- Upload date:
- Size: 265.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
702e10de2c502cde5c34b82eb857cde8bef0f66fc7065df4737edd452c87a4d1
|
|
| MD5 |
fbd58d4e0bd6249d309b0a2da1fc3932
|
|
| BLAKE2b-256 |
8729c0578671b6a04ffd01a3cef36e5adce2841d88fa9a99404bab809082d164
|
Provenance
The following attestation bundles were made for axm_audit-0.10.0-py3-none-any.whl:
Publisher:
publish.yml on axm-protocols/axm-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axm_audit-0.10.0-py3-none-any.whl -
Subject digest:
702e10de2c502cde5c34b82eb857cde8bef0f66fc7065df4737edd452c87a4d1 - Sigstore transparency entry: 1803941483
- Sigstore integration time:
-
Permalink:
axm-protocols/axm-forge@6dfb594c800a283ea1542aacd81ecbdef38151f6 -
Branch / Tag:
refs/tags/audit/v0.10.0 - Owner: https://github.com/axm-protocols
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6dfb594c800a283ea1542aacd81ecbdef38151f6 -
Trigger Event:
push
-
Statement type: