Zerum
Zerum is deterministic code governance for Python — Credo for Python.
v0.4.2 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):
crates.io (requires Rust 1.70+):
Python (recommended for most Python projects)
No Rust toolchain required — prebuilt wheels:
Isolated tool installs:
# or
Verify:
Quick start
# Optional: write a starter zerum.toml (default profile)
# Run checks on the project
# Browse the catalog and learn a rule
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
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:
Or persist it:
# writes a strict starter config
[]
= "strict"
Compare:
Configuration (zerum.toml)
Common knobs:
[]
= "default"
[]
= true
= 50
[]
= "high"
# Architecture layers (ZR207)
[[]]
= "app.domain"
= "app.infrastructure"
# Always run Ruff when you check (requires ruff on PATH)
# external_checkers = ["ruff"]
Custom profiles can inherit:
[]
= "default"
[]
= 60
Starter files in the repo: zerum.toml.example, zerum.toml.strict.example.
Explain a rule
Shows category, severity, rationale, false positives, tradeoffs, examples, and remediation.
List checks and external 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
# or persist in zerum.toml
# external_checkers = ["ruff"]
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
| 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)
# exit 0 → clean under default profile
# exit 1 → findings printed to stdout
2. Full catalog
Expect more findings on small modules (docstring / comment / heuristic rules).
3. Machine-readable report
4. Learn why a finding fired
# note a rule id, e.g. ZR003
5. Team config + architecture boundary
# edit zerum.toml — set ZR207 rules for your layers
6. Zerum + Ruff in one command
7. Upgrade later
# or: pipx upgrade zerum
# or: uv tool upgrade zerum
# or: brew upgrade zerum
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:
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:
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.2". - 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.2.
Building from source (contributors)
For hacking on Zerum itself — not required for normal use.
# or run without installing
# editable Python-env install via maturin
Tests and lint:
Packaging notes: packaging/ (PyPI, Homebrew). Config for multi-channel scaffolding: Sastri.toml.
License
MIT — see LICENSE.