Zerum
Zerum — deterministic code governance for Python · Credo for Python
v0.5.0 ships ~75 native checks (ZR001–ZR510), explainable findings (curated copy for tier-1 rules; AST-precise fallbacks elsewhere), quiet default / full strict profiles, optional Ruff orchestration, human / json / sarif output, and --remediation-prompt — a deterministic markdown brief for LLM/editor agents (no model call in Zerum). Install via PyPI, Homebrew, crates.io, or GitHub Releases.
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 .
# Write a remediation prompt for an LLM / editor agent
zerum check . --remediation-prompt
# 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.
Remediation prompt (v0.5.0)
Zerum can save a deterministic markdown prompt from its findings — grouped by check type, ordered by severity (critical → info), with shared remediation text and source snippets. Zerum does not call an LLM; you paste the file into Cursor, ChatGPT, or another agent.
zerum check . --remediation-prompt
# → zerum-remediation-prompt.md
zerum check . --remediation-prompt fixes.md
zerum check . --profile strict --remediation-prompt fixes.md
Typical workflow:
zerum check . --remediation-prompt fixes.md- Open
fixes.mdin your editor / agent and ask it to apply the remediations - Re-run
zerum check .until clean
The prompt includes:
- Goal and constraints (minimal edits, preserve APIs)
- Summary counts and a type index ordered by severity
- Findings grouped by check id, shared explanation/remediation once per type
- Per-occurrence location, message, and source context
- Instructions to re-run Zerum after edits
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-E501.
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 . --format sarif
zerum check . --profile strict
zerum check . --with-external ruff
zerum check . --remediation-prompt fixes.md
zerum list-checkers
| Output | When to use |
|---|---|
human |
Terminal review — rule id, location, explanation, remediation |
json |
CI artifacts, scripts, and custom dashboards |
sarif |
GitHub code scanning and other SARIF consumers |
--remediation-prompt |
Markdown brief for an LLM/editor agent (file on disk; still prints human/json/sarif to stdout) |
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. Save a remediation prompt for an LLM / editor agent
zerum check . --remediation-prompt
# → zerum-remediation-prompt.md
zerum check . --remediation-prompt fixes.md
Findings are grouped by type and sorted by severity (critical first).
8. 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==0.5.0"
- name: Run Zerum
run: zerum check . --format human
# Optional: remediation prompt artifact for reviewers / agents
# - run: zerum check . --remediation-prompt zerum-remediation-prompt.md || true
# - uses: actions/upload-artifact@v4
# if: failure()
# with:
# name: zerum-remediation-prompt
# path: zerum-remediation-prompt.md
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==0.5.0"
- 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.5.0". - 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.” - Optionally upload
--remediation-promptoutput as a CI artifact when the check fails.
Changelog
See CHANGELOG.md. Release notes: v0.5.0.
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
cargo run -- check path/to/project --remediation-prompt /tmp/fixes.md
# 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
Coverage (rustup cargo; asdf shims break cargo +toolchain):
export PATH="$HOME/.cargo/bin:$PATH"
cargo +1.97.1 tarpaulin \
--engine llvm --all-targets --all-features --follow-exec \
--out Stdout --fail-under 70 -- --test-threads=1
Packaging notes: packaging/ (PyPI, Homebrew). Config for multi-channel scaffolding: Sastri.toml.
License
MIT — see LICENSE.
Metadata
Release files for zerum 0.5.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 | |
|---|---|---|---|
| zerum-0.5.0.tar.gz | 18.5 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| zerum-0.5.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| zerum-0.5.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 25.4 MB
Release files / zerum-0.5.0.tar.gz
| Download URL | zerum-0.5.0.tar.gz |
|---|---|
| Size | 18.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0ba45c4399711295c559409c54bfa7d430054f1a34929015a17e3a2641cff51b
|
|
BLAKE2b-256 checksum How to use checksums |
0acf63f2dff5465216fc57fdf1239426016edf61d74a31d4fafcd094c2240c3d
|
| 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 Aug 5, 2026.
Transparency logRelease files / zerum-0.5.0-py3-none-win_amd64.whl
| Download URL | zerum-0.5.0-py3-none-win_amd64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c96003aaaeb5a2bb58ae14b5388a0c2c6dd96392fc21df72e4604d6b336c9939
|
|
BLAKE2b-256 checksum How to use checksums |
76c714cf3c14e4689e4e3e9c3c79cf2e97202ec0a6866ead5d9359e3e4908ecc
|
| 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 Aug 5, 2026.
Transparency logRelease files / zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
ee1aeb74c1117674cb8ab4b5d154a6935922c58e8c14c7d81f4c27cc9e6df38f
|
|
BLAKE2b-256 checksum How to use checksums |
9a7c103d27e18d07e1f5f6cd49c2cbde498ca6d5ae9d18e6a034cb3888eb5a6d
|
| 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 Aug 5, 2026.
Transparency logRelease files / zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
1ef817ca63f8c0829343c1ab255fd4d6762528b4e60abf9bc156e2ea4bbbce6f
|
|
BLAKE2b-256 checksum How to use checksums |
438705ce996718f85998e545111b0ff81668c1692271daddb3b10fbe2bc118f8
|
| 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 Aug 5, 2026.
Transparency logRelease files / zerum-0.5.0-py3-none-macosx_11_0_arm64.whl
| Download URL | zerum-0.5.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c7585a327e2eba5e0980d56be764e2dde76528d0dd38478fed495d68c078a551
|
|
BLAKE2b-256 checksum How to use checksums |
e9a7e9afbbb9ef1bf93072817843aded4f6385af59ded897fa1d1f36c47fff8b
|
| 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 Aug 5, 2026.
Transparency logRelease files / zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
c573f7d106e5c3433739a52ef188c389121040d33cd4a61d6716fa52bb1ae1a3
|
|
BLAKE2b-256 checksum How to use checksums |
f39514c327eb11a8cc58f08c76a3e10392f3eb2777511772a6195c4a74df1425
|
| 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 Aug 5, 2026.
Transparency log