Skip to main content

commitpreflight

Pre-flight lint for commit messages written by AI coding agents.

Your agent writes a commit message, calls git commit, gets rejected by a hook, and burns a turn rewriting it. commitpreflight catches the message before the commit, and returns a concrete fix rather than a complaint.

pip install commitpreflight
$ echo "Added retry budget to the upload path so that flaky networks recover." | commitpreflight
error: header is not `tag(scope): subject`  got: 'Added retry budget to the upload path so' [conventional-format]
  try: feat(scope): added retry budget to the upload path so that flaky networks recover.
error: subject must not end with a period [subject-punctuation]
  try: Added retry budget to the upload path so that flaky networks recover
warning: subject opens with 'added'; conventional commits use the imperative [imperative-mood]
  try: add retry budget to the upload path so that flaky networks recover.

Why these rules

The rule set is not a style opinion. It is seeded by what actually breaks: 10,976 CLI failures logged over 7 days by a fleet of autonomous coding agents. Roughly 1 in 5 was a malformed commit message — the single largest class of agent CLI failure in the corpus.

failure share of all agent CLI failures
subject over the length limit 13.8%
missing tag(scope): format 8.1%

The useful detail is the shape of the overshoot, not its existence:

how far over the 72-char limit share of overshoots
1–5 chars 57%
6–10 chars 24%
11+ chars 19%

81% of overshoots miss by 10 characters or fewer. Agents do not write essays into the subject line; they miss the limit by a hair. So the right intervention is a trim at the last word boundary, which is what commitpreflight suggests — and why it declines to suggest one when the overshoot is large enough that trimming would be a rewrite.

Use it as a git hook

printf '#!/bin/sh\nexec commitpreflight "$1"\n' > .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg

Exit code is 1 when any error-severity finding fires, 0 otherwise. --strict makes warnings blocking too.

Use it from an agent

--json gives a machine-readable list your agent can act on without parsing prose:

$ commitpreflight --json .git/COMMIT_EDITMSG
[
  {
    "rule": "imperative-mood",
    "severity": "warning",
    "message": "subject opens with 'added'; conventional commits use the imperative",
    "fix": "add retry budget to the upload path"
  }
]

Or call it directly:

from commitpreflight import check

for finding in check("feat(api): Added a thing."):
    print(finding.rule, finding.severity, finding.fix)

Rules

rule severity what it catches
empty error no message at all
conventional-format error header is not tag(scope): subject
tag-case error tag is not lowercase
tag-unknown error tag outside the allowed set
scope-required error scope missing when required
scope-empty error tag(): subject
subject-empty error nothing after the tag
subject-length error header over the limit
subject-punctuation error subject ends with a period
body-blank-line error body not separated from the subject
imperative-mood warning added / fixing / updates openers
subject-case warning subject starts capitalised
body-line-length warning wrappable body line over the limit

Configuration

Optional, in pyproject.toml:

[tool.commitpreflight]
max_subject = 72
max_body_line = 100
require_conventional = true
require_scope = false
allow_unknown_tags = false
tags = ["feat", "fix", "docs", "refactor", "test", "chore"]
disable = ["subject-case"]

Teams

Running commitpreflight across a fleet of AI agents at scale? Team subscription: $100/mo.

Subscribe

License

MIT

Release files for commitpreflight 0.1.1

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

Source distribution (sdist)

Source distribution for commitpreflight 0.1.1
File Size Uploaded
commitpreflight-0.1.1.tar.gz 13.5 kB Details

Built distribution (wheel)

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

Total release size:21.1 kB

Release files / commitpreflight-0.1.1.tar.gz

Download URL commitpreflight-0.1.1.tar.gz
Size 13.5 kB
Tags Source
SHA-256 checksum
How to use checksums
aeacc7dbad8c3d296f125a08e113b720066eaed226f6aff23c8f87b88ededc08
BLAKE2b-256 checksum
How to use checksums
e1faaf46ec56069c741005c1a156836c805f07db4ed3680b2641a9b33a9198b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / commitpreflight-0.1.1-py3-none-any.whl

Download URL commitpreflight-0.1.1-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
95ebbb7d0b2d1039c1a496dd9a7f1cbf3cb5cc73f1bea7f5cf4ea2b76816b614
BLAKE2b-256 checksum
How to use checksums
b455e6cb71525c0b70664bc001c1d3afa9a6b705cae195148fcdcb8f0cbc1274
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.1 This release

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