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.
License
MIT
Metadata
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)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| commitpreflight-0.1.1.tar.gz | 13.5 kB | Without provenance | Details for commitpreflight-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| commitpreflight-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for commitpreflight-0.1.1-py3-none-any.whl |
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}
|
Security for commitpreflight 0.1.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.