Skip to main content

Zerum

Zerum — Rust crab administering analysis extract to a Python snake

Zerum — deterministic code governance for Python · Credo for Python

crates.io PyPI GitHub release CI docs.rs MIT license Rust 1.70+ Python 3.9+ wheels

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:

  1. zerum check . --remediation-prompt fixes.md
  2. Open fixes.md in your editor / agent and ask it to apply the remediations
  3. 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/:


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 strict once the baseline is clean.
  • Pin the version in CI: pip install "zerum==0.5.0".
  • Combine with Ruff only if ruff is installed in the job:
    zerum check . --with-external ruff.
  • Treat exit code 2 as infra failure; 1 as “findings to fix.”
  • Optionally upload --remediation-prompt output 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zerum-0.5.0.tar.gz (18.5 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

zerum-0.5.0-py3-none-win_amd64.whl (1.4 MB view details)

Uploaded Python 3Windows x86-64

zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

zerum-0.5.0-py3-none-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file zerum-0.5.0.tar.gz.

File metadata

  • Download URL: zerum-0.5.0.tar.gz
  • Upload date:
  • Size: 18.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for zerum-0.5.0.tar.gz
Algorithm Hash digest
SHA256 0ba45c4399711295c559409c54bfa7d430054f1a34929015a17e3a2641cff51b
MD5 d353cbef29c8b9c8594dce4a970d534c
BLAKE2b-256 0acf63f2dff5465216fc57fdf1239426016edf61d74a31d4fafcd094c2240c3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0.tar.gz:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zerum-0.5.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: zerum-0.5.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for zerum-0.5.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c96003aaaeb5a2bb58ae14b5388a0c2c6dd96392fc21df72e4604d6b336c9939
MD5 aad6b7bde134d235d53c7aa28ed86b9e
BLAKE2b-256 76c714cf3c14e4689e4e3e9c3c79cf2e97202ec0a6866ead5d9359e3e4908ecc

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0-py3-none-win_amd64.whl:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ee1aeb74c1117674cb8ab4b5d154a6935922c58e8c14c7d81f4c27cc9e6df38f
MD5 1ab5fad6c18e42f699bfc50952702fa7
BLAKE2b-256 9a7c103d27e18d07e1f5f6cd49c2cbde498ca6d5ae9d18e6a034cb3888eb5a6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1ef817ca63f8c0829343c1ab255fd4d6762528b4e60abf9bc156e2ea4bbbce6f
MD5 5303b1025034493384cc06fe3e8ebcb2
BLAKE2b-256 438705ce996718f85998e545111b0ff81668c1692271daddb3b10fbe2bc118f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zerum-0.5.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: zerum-0.5.0-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

Hashes for zerum-0.5.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c7585a327e2eba5e0980d56be764e2dde76528d0dd38478fed495d68c078a551
MD5 2d4aff855556bc6a8f70c0e0330381e8
BLAKE2b-256 e9a7e9afbbb9ef1bf93072817843aded4f6385af59ded897fa1d1f36c47fff8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0-py3-none-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c573f7d106e5c3433739a52ef188c389121040d33cd4a61d6716fa52bb1ae1a3
MD5 84a2e80214efb1b64b4d55f0194bbc4b
BLAKE2b-256 f39514c327eb11a8cc58f08c76a3e10392f3eb2777511772a6195c4a74df1425

See more details on using hashes here.

Provenance

The following attestation bundles were made for zerum-0.5.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: publish-pypi.yml on latentmeta/zerum

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page