Skip to main content

CI codecov PyPI PyPI downloads Python versions License: MIT

CheckOwners

Keep CODEOWNERS aligned with reality.

$ checkowners --offline drift

severity: HIGH (Δmax=1.00)
                                CODEOWNERS Drift                                
┏━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Category ┃ Path       ┃    Δ ┃ Reason                                        ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ changed  │ /payments/ │ 1.00 │ owners diverge on 2 of 2 covered path(s)      │
│          │            │      │ (line 1)                                      │
└──────────┴────────────┴──────┴───────────────────────────────────────────────┘

CheckOwners analyzes git and review history to infer who actually knows each part of your repository, then compares that evidence with your CODEOWNERS policy. Use it to detect stale or incorrect rules, find code with dangerously concentrated knowledge, recommend knowledgeable reviewers, and discover ownership gaps before they become operational risk.

Local-first. Git-native. No source-code upload. No LLM required. The core install is pure git. With no token, CheckOwners sends nothing anywhere. checkowners --offline opens no network connection. PyPI releases use Trusted Publishing. Sigstore signs each distribution.

This is a knowledge-risk tool, not a performance-measurement tool. Using it for individual evaluation is unsupported and harmful.

uvx checkowners drift

Install

Requires Python 3.11 through 3.14 and Git 2.23 or newer.

pip install checkowners               # core CLI (pure git, zero API deps)
pip install "checkowners[graph]"      # + networkx-backed graph / topology / onboard
pip install "checkowners[github]"     # + GitHub API handle/team/review resolution
pip install "checkowners[all]"        # everything

Run

checkowners --offline drift

Exit status is the same for every command: 0 clean, 1 internal error, 2 configuration or usage, 3 findings, 4 git or GitHub failure. checkowners --exit-zero hides findings only. See Exit codes.

CI

Least privilege (job summary only; no pull-request comment):

name: checkowners
on: [pull_request]

jobs:
  drift:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: smusali/checkowners@v0
        with:
          config: .github/checkowners.yml
          comment_on_pr: false

Same-repo comments need pull-requests: write. The comment workflow and the pre-commit hooks are in GitHub Actions and Pre-commit.

CheckOwners treats code ownership as a confidence-scored spectrum rather than a static binary declaration.

No other open-source tool combines git-history inference, per-path ownership scores with evidence quality, pattern-aware drift with severity tiers, and knowledge-risk reporting behind a single CI-native JSON contract.

See it

checkowners --offline drift on a sanitized two-person tree. The committed rule is /payments/ @platform.

checkowners drift reporting high severity on /payments/

The composite Action posts that finding as one comment on same-repo pull requests:

CheckOwners pull-request comment for high-severity drift

generate --force on the same tree writes examples/sample-CODEOWNERS:

# Generated by checkOwners. Do not edit manually.

/payments/ @alice @bob

How it works

analyze reads git log and git blame and caches an ownership map per repo under ~/.checkowners/.

  • Noreply addresses become GitHub @handles locally. Other addresses use the GitHub API when a token is set.
  • One person with several emails counts once.
  • generate writes CODEOWNERS and collapses a directory of identical owners into one dir/ rule.
  • drift matches the committed file with GitHub's CODEOWNERS rules: directories, globs, last match wins.

Other reports use that same map. The table below lists them. In CI, the composite Action writes GITHUB_OUTPUT, a job summary, and one pull-request comment on same-repo pull requests.

Scoring commands accept --json, --as-of, and SOURCE_DATE_EPOCH. The default instant is the HEAD committer time. graph uses --export dot instead of --json.

The full pipeline is in docs/USAGE.md.

Command What it does
checkowners analyze Infer ownership scores, qualified owner count, and continuity-risk warnings
checkowners generate Write CODEOWNERS, ordered by ownership score; optional inline annotations
checkowners explain-path <path> Show which CODEOWNERS rule owns a path, and the full match chain
checkowners explain <path> Decompose inferred scores (signals, evidence, --why-not, --owner)
checkowners owners <path> Minimal ranked owner list (who is an alias)
checkowners print Print inferred ownership to stdout
checkowners validate Validate existing CODEOWNERS syntax
checkowners drift Compare inferred vs current; severity + max ownership-score delta
checkowners baseline create Write an accepted-findings file so later runs fail only on new findings
checkowners sync Generate CODEOWNERS and commit the result
checkowners expertise <path> Evidence ranking for one path from cached analysis
checkowners decay Report ownership freshness and continuity risk; suggest a transfer
checkowners graph [--export dot] Render the ownership graph
checkowners qualified-owners [<path>] [--all] Per-path qualified owner count (capped by top_n_owners) with candidate backup reviewers
checkowners topology Exploratory repository topology from commit co-occurrence
checkowners balance Compare a git authorship proxy, or completed reviews when the API is available
checkowners onboard <path> Learning path from broadly shared paths to concentrated qualified ownership
checkowners trends [--periods N] [--period-days D] Historical activity and qualified owner count over time
checkowners github-action Run the full CI flow and write GITHUB_OUTPUT; used by the composite Action

Trimmed JSON from this repository is in examples/sample-output.md. Reference configs live under examples/.

Trust

Core inference is local git. checkowners --offline opens no network connection. With no token, CheckOwners sends nothing anywhere.

PyPI releases use Trusted Publishing. The publish workflow authenticates with a GitHub OIDC token and does not store a PyPI API token. Sigstore signs each distribution.

Each GitHub release also carries a CycloneDX SBOM and a signed build-provenance attestation.

This repository moved here from a previous GitHub organization; Sigstore attestations for 0.5.0 and earlier record that earlier publisher. 0.5.1 and later are published from smusali/checkowners.

Inference is deterministic git analysis; the scoring heuristics live in analyze.py and are auditable. The codebase has been built with agent assistance. Every AI-assisted change is human-reviewed, tested, and signed off.

What the tool reads, what leaves the machine, what the cache holds, how tokens are handled, and which permissions are required is in docs/PRIVACY.md.

Documentation

License

MIT

Metadata

Release files for checkowners 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for checkowners 0.6.0
File Size Uploaded
checkowners-0.6.0.tar.gz 622.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for checkowners 0.6.0
File Interpreter ABI Platform
checkowners-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 730.9 kB

Release files / checkowners-0.6.0.tar.gz

Download URL checkowners-0.6.0.tar.gz
Size 622.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8a72e07f471ac8aa566b6b1374df8355169a618556c3ea1d78521e181763db25
BLAKE2b-256 checksum
How to use checksums
cf933840a3881098940185b4bb38f4018bc3b5e7e2de1bab3996ffa105ac2699
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 Sep 24, 2026.

Transparency log

Release files / checkowners-0.6.0-py3-none-any.whl

Download URL checkowners-0.6.0-py3-none-any.whl
Size 108.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f8151810780dc82a430ea62d4d2e8b078a3254760c76756a9ab3d2c94d2c6c50
BLAKE2b-256 checksum
How to use checksums
0ebb2be2765e69c902453f793b7120f224e9e03ceb380c40c08095b8bbe70ac0
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 Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page