Zerum
Zerum is deterministic code governance for Python — Credo for Python.
v0.4.1 ships ~75 native checks (ZR001–ZR510), explainable findings, quiet default / full strict profiles, optional Ruff orchestration, and human / json output. Install via PyPI, Homebrew, crates.io, or GitHub Releases. No LLM in the core path.
Zerum is not a Ruff replacement. It focuses on maintainability, consistency, architecture boundaries, and deterministic AI-slop patterns.
Install
Pick one. After install you get a zerum command on your PATH.
Standalone binary
Download a release archive for your OS/arch from
GitHub Releases, extract, and put zerum on your PATH.
Homebrew (tap formula; after the formula is published):
brew install latentmeta/tap/zerum
crates.io (requires Rust 1.70+):
cargo install zerum --locked
Python (recommended for most Python projects)
No Rust toolchain required — prebuilt wheels:
pip install zerum
Isolated tool installs:
pipx install zerum
# or
uv tool install zerum
Verify:
zerum --version
zerum --help
Quick start
cd your-python-project
# Optional: write a starter zerum.toml (default profile)
zerum init
# Run checks on the project
zerum check .
# Browse the catalog and learn a rule
zerum list-checks
zerum explain ZR001
Exit codes for zerum check:
| Code | Meaning |
|---|---|
| 0 | No issues |
| 1 | Issues found |
| 2 | Operational error (bad path, CLI error, etc.) |
Using Zerum
Check a project
zerum check .
zerum check path/to/package
zerum check src/
Human-readable output is the default. Each finding includes rule id, location, explanation, and remediation.
Profiles: default vs strict
With no zerum.toml (or [profile] name = "default"), Zerum uses the built-in default profile: noisy pattern heuristics are off so greenfield modules stay quieter.
Enable the full catalog:
zerum check . --profile strict
Or persist it:
zerum init --strict
# writes a strict starter config
[profile]
name = "strict"
Compare:
zerum check . # default — quieter
zerum check . --profile strict # all ~75 rules
Configuration (zerum.toml)
zerum init # default template
zerum init --strict # strict template
Common knobs:
[profile]
name = "default"
[checks.ZR001]
enabled = true
max_lines = 50
[checks.ZR401]
severity = "high"
# Architecture layers (ZR207)
[[checks.ZR207.rules]]
from = "app.domain"
forbidden = "app.infrastructure"
# Always run Ruff when you check (requires ruff on PATH)
# external_checkers = ["ruff"]
Custom profiles can inherit:
[profiles.team]
extends = "default"
[profiles.team.checks.ZR001]
max_lines = 60
zerum check . --profile team
Starter files in the repo: zerum.toml.example, zerum.toml.strict.example.
Explain a rule
zerum explain ZR001
zerum explain ZR401
zerum explain ZR501
Shows category, severity, rationale, false positives, tradeoffs, examples, and remediation.
List checks and external checkers
zerum list-checks
zerum list-checkers
list-checks prints the full ZR catalog. list-checkers shows external adapters (e.g. Ruff) and whether they are available on PATH.
Optional Ruff orchestration
Zerum can run Ruff alongside native checks and merge findings:
# one-off
zerum check . --with-external ruff
# or persist in zerum.toml
# external_checkers = ["ruff"]
zerum check .
Requires ruff on PATH. External findings use ids like EXT-RUFF.
Rule categories
| Range | Category |
|---|---|
| ZR001–015 | Readability |
| ZR101–110 | Consistency |
| ZR201–210 | Design |
| ZR301–315 | Refactor |
| ZR401–415 | Warning |
| ZR501–510 | AI (deterministic) |
Output formats
zerum check . --format human # default
zerum check . --format json
zerum check . --profile strict
zerum check . --with-external ruff
zerum list-checkers
| Format | When to use |
|---|---|
human |
Terminal review — rule id, location, explanation, remediation |
json |
CI artifacts, scripts, and custom dashboards |
Optional external checkers (Ruff) are available from v0.4.0. Use the default profile for low noise on greenfield code; use --profile strict for full catalog coverage.
Tutorial
Educational material lives under docs/tutorial/:
- 00 — Introduction
- 01 — Static analysis basics
- 02 — Parsing Python in Rust
- 03 — Building a rule engine
- 04 — Writing checks
- 05 — Explain mode and configuration
- 06 — Config and profiles
- 12 — Roadmap
Feature demos
Assume a project directory with some Python sources.
1. First pass (quiet default)
zerum check .
# exit 0 → clean under default profile
# exit 1 → findings printed to stdout
2. Full catalog
zerum check . --profile strict
Expect more findings on small modules (docstring / comment / heuristic rules).
3. Machine-readable report
zerum check . --format json > zerum-report.json
4. Learn why a finding fired
zerum check . --format human
# note a rule id, e.g. ZR003
zerum explain ZR003
5. Team config + architecture boundary
zerum init
# edit zerum.toml — set ZR207 rules for your layers
zerum check .
6. Zerum + Ruff in one command
zerum list-checkers
zerum check . --with-external ruff --format json
7. Upgrade later
pip install --upgrade zerum
# or: pipx upgrade zerum
# or: uv tool upgrade zerum
# or: brew upgrade zerum
zerum --version
Add Zerum to CI/CD (Python project)
Fail the job when Zerum finds issues (exit 1). Use JSON if you want artifacts.
GitHub Actions (pip)
name: Zerum
on:
pull_request:
push:
branches: [main]
jobs:
zerum:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Zerum
run: pip install zerum
- name: Run Zerum
run: zerum check . --format human
# Optional: stricter gate + JSON artifact
# - run: zerum check . --profile strict --format json > zerum.json
# - uses: actions/upload-artifact@v4
# if: always()
# with:
# name: zerum-report
# path: zerum.json
GitHub Actions (uv)
- uses: astral-sh/setup-uv@v4
- run: uv tool install zerum
- run: zerum check .
GitHub Actions (pipx)
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pipx install zerum
- run: zerum check .
Pre-commit
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: zerum
name: zerum
entry: zerum check .
language: system
pass_filenames: false
types: [python]
Install Zerum on the machine (or in CI) before running pre-commit, e.g. pipx install zerum.
GitLab CI
zerum:
image: python:3.12-slim
script:
- pip install zerum
- zerum check .
Tips for CI
- Start with default profile; move to
--profile strictonce the baseline is clean. - Pin the version in CI:
pip install "zerum==0.4.1". - Combine with Ruff only if
ruffis installed in the job:
zerum check . --with-external ruff. - Treat exit code
2as infra failure;1as “findings to fix.”
Changelog
See CHANGELOG.md. Release notes: v0.4.1.
Building from source (contributors)
For hacking on Zerum itself — not required for normal use.
git clone https://github.com/latentmeta/zerum.git
cd zerum
cargo build --release
./target/release/zerum check path/to/python/project
# or run without installing
cargo run -- check path/to/python/project
cargo run -- explain ZR001
cargo run -- list-checks
cargo run -- init
# editable Python-env install via maturin
pip install "maturin>=1.7,<2.0"
maturin develop
Tests and lint:
cargo test
cargo clippy --all-targets --all-features -- -D warnings
Packaging notes: packaging/ (PyPI, Homebrew). Config for multi-channel scaffolding: Sastri.toml.
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 zerum-0.4.1.tar.gz.
File metadata
- Download URL: zerum-0.4.1.tar.gz
- Upload date:
- Size: 62.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
381b29745a276294559be03ef1269c3047adfc696cf5e8817cd5b48558056ec3
|
|
| MD5 |
d0c055c9776b562a320ae26e2be843d3
|
|
| BLAKE2b-256 |
60ae534738cb0970204c0a5cc1d63c04d5f77d93792520f37989d35a4f8c1deb
|
Provenance
The following attestation bundles were made for zerum-0.4.1.tar.gz:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1.tar.gz -
Subject digest:
381b29745a276294559be03ef1269c3047adfc696cf5e8817cd5b48558056ec3 - Sigstore transparency entry: 2341629030
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file zerum-0.4.1-py3-none-win_amd64.whl.
File metadata
- Download URL: zerum-0.4.1-py3-none-win_amd64.whl
- Upload date:
- Size: 1.3 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81600e62c91fb51e7c7d859154a09fbf1fc03bce0e03e13aca449c7b7ae3408e
|
|
| MD5 |
8f464cc1efa696f38144a5d4905d1683
|
|
| BLAKE2b-256 |
d6cf4b4e0812f291b1f82bbb7f98f0a9283672db2cfc4e52956bc945b2a3da97
|
Provenance
The following attestation bundles were made for zerum-0.4.1-py3-none-win_amd64.whl:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1-py3-none-win_amd64.whl -
Subject digest:
81600e62c91fb51e7c7d859154a09fbf1fc03bce0e03e13aca449c7b7ae3408e - Sigstore transparency entry: 2341629114
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file zerum-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: zerum-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
550dba4b99817653e041a2d28bba202fd645a9f97b1923537511835a9fb0d602
|
|
| MD5 |
4b67d008f6ce883382c61ed2849515da
|
|
| BLAKE2b-256 |
7c70931310245e0ecc921e213c6b01e876bae3d09721f33e354f789459960277
|
Provenance
The following attestation bundles were made for zerum-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
550dba4b99817653e041a2d28bba202fd645a9f97b1923537511835a9fb0d602 - Sigstore transparency entry: 2341629073
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file zerum-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: zerum-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.3 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cafc3c51e46d8902ffc45d90e032a5bc455ab36a3fa0650f4f55999235ba1555
|
|
| MD5 |
a93e0f4c795c0f2eb286826eeb877816
|
|
| BLAKE2b-256 |
674fd2cb03e4ad392bb30ae85b9202577ad17481ba6bd71301f07ab7c0d2e390
|
Provenance
The following attestation bundles were made for zerum-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
cafc3c51e46d8902ffc45d90e032a5bc455ab36a3fa0650f4f55999235ba1555 - Sigstore transparency entry: 2341629082
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file zerum-0.4.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: zerum-0.4.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.3 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bacd65d4df3179eb2297ca7c828deadf77830ad5baa19c8a25568738b46c9c7
|
|
| MD5 |
38eab3dc8554e892bc0d00fdc2428f39
|
|
| BLAKE2b-256 |
26d57abbe0b1be2cb646e665eb57bfd63d2224728d744e2c56c1ba2c7b5acb4d
|
Provenance
The following attestation bundles were made for zerum-0.4.1-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1-py3-none-macosx_11_0_arm64.whl -
Subject digest:
7bacd65d4df3179eb2297ca7c828deadf77830ad5baa19c8a25568738b46c9c7 - Sigstore transparency entry: 2341629055
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type:
File details
Details for the file zerum-0.4.1-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: zerum-0.4.1-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ca7518dec86c67e1d767aae02eba43962d1f9b12c86432f1e911fc24ff2da55
|
|
| MD5 |
ee8f78adda64d862a09ce99d88fbcc09
|
|
| BLAKE2b-256 |
e693af644e86c4f0acc0653eb0ddd51fa1b59328d19b08b2be56736ef93c04c4
|
Provenance
The following attestation bundles were made for zerum-0.4.1-py3-none-macosx_10_12_x86_64.whl:
Publisher:
publish-pypi.yml on latentmeta/zerum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zerum-0.4.1-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
5ca7518dec86c67e1d767aae02eba43962d1f9b12c86432f1e911fc24ff2da55 - Sigstore transparency entry: 2341629096
- Sigstore integration time:
-
Permalink:
latentmeta/zerum@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/latentmeta
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f87ca30f15ce0f5080c15d277bd3239ac5ad5ce -
Trigger Event:
push
-
Statement type: