batch-claim-audit
Offline, stdlib-only audit of documented grouped-handling promises in a
Python project against its own source code. It executes nothing, uses no
network, and never opens the contents of any .env file.
The problem
Docs often promise a specific handling shape: work handled in groups, or work handled strictly a single item at a time. Code that quietly does the other thing passes every functional test — a run succeeds either way — and the mismatch only surfaces when a user sizes throughput, quotas, or per-item error handling around the promise. This tool checks the promise statically, before any user has to discover it.
Usage
pip install batch-claim-audit
batch-claim-audit /path/to/project
batch-claim-audit --json /path/to/project
batch-claim-audit --fail-on HIGH /path/to/project
batch-claim-audit --ignore "vendor/*" /path/to/project
batch-claim-audit --version
Or without installing, from a checkout:
PYTHONPATH=src python3 -m batch_claim_audit /path/to/project
Exit codes: 0 means PASS, 2 means FAIL, 1 means a usage error.
--fail-on HIGH makes a MEDIUM-only run exit 0 while still printing
the MEDIUM findings. --ignore takes a glob matched against relative
paths and is repeatable. --verbose prints the claims found and the
verified claims; --json prints the full machine-readable report.
What it checks
Claims are read from the root README.md plus docs/**/*.md only.
Fenced code blocks are excluded from claims; inline code spans count as
prose. Sentences are normalised (lowercased, n't expanded, hyphens
turned into spaces) and matched with word boundaries on exact phrases.
A sentence containing a negation word suppresses grouped-family claims
on that sentence, but not single-item-family claims, because the
single-item phrases are themselves negative or single-item wordings.
Production Python source is everything except tests/ directories,
test_*.py / *_test.py files, fixtures/ directories, docs/,
examples/, and symlinked files. Evidence found only under tests or
fixtures is reported separately at MEDIUM severity.
Rules
The exact claim phrases and the exact finding names are listed only in the fenced block below, so that running this tool on its own tree passes with no claims. In prose: a grouped promise with no grouping evidence anywhere is a HIGH finding; the same promise with evidence only under tests or fixtures is a MEDIUM finding; a single-item promise with grouping evidence in production source is a HIGH finding, and with evidence only under tests or fixtures is a MEDIUM finding. A promise with matching production evidence is listed as verified. No promise means PASS, even with grouping calls everywhere. A promise present but with no production Python source at all is one HIGH finding per family.
Claim phrases, grouped family:
"in batches", "batched", "batch processing",
"processes in batches", "processed in batches",
"batch uploads", "batch requests", "batch inserts",
"bulk insert", "bulk update", "bulk upload", "bulk requests"
Claim phrases, single-item family:
"one by one", "one at a time", "item by item",
"no batching", "without batching", "not batched",
"does not batch", "never batches",
"processes items individually", "process items individually",
"handles items individually", "handle items individually"
Finding names:
documented-batched-claim-false (HIGH)
documented-batched-claim-false-test-only (MEDIUM)
documented-one-by-one-claim-false (HIGH)
documented-one-by-one-claim-false-test-only (MEDIUM)
Grouping evidence table:
- grouping helper call: batched / chunked, as a bare name or attribute
- stepped loop: for over range() with exactly 3 arguments and a
literal step greater than 1, or a non-literal step
- grouped-operation call: a call whose name contains batch or bulk
(but not exactly "batch" or "bulk" alone)
- executemany attribute call
- grouped-size keyword: batch_size / bulk_size with a value that is
not the literal 1 and not None
Differentiation
- pagination-claim-audit: whether results are fetched page by page from a source. This tool asks whether work is handled in groups per call, regardless of where the items came from.
- retry-claim-audit: how many times one operation is attempted. This tool asks how many items one operation covers.
- streaming-claim-audit: how much is read at once. This tool asks how many items are handled per call.
- concurrency-claim-audit: how many things run at once. A grouped call can still be single-threaded, and parallel calls can still handle items singly; the questions are independent.
- bandit / ruff: code issues, never docs promises.
- itertools grouping helpers and their documentation: libraries that provide grouping, never docs-vs-code truth.
Honest limitations
- Claims are exact phrases, not semantic judgements. A paraphrase of a grouped promise that is not in the phrase list is not detected.
- Matching is word-boundary based: a bare
batchword, a barebatch sizephrase, and the wordunbatchedare not promises. - Grouping evidence is name- and shape-based: a function merely named with batch or bulk counts even if its body is unknown, and a grouped-size keyword with a variable value counts even if that variable holds 1 at runtime. No size check is performed.
- An import of a grouping helper with no call does not count: grouping must be invoked to group anything. This differs deliberately from tools where an import alone is evidence.
- A local function, class, or parameter with the same name suppresses bare-name evidence in that file; attribute evidence is not suppressed because the receiver type is not inferred.
- Dead code counts: a grouping call in uncalled code is still evidence.
- A plain per-item loop, a single-item call, a variable or string literal merely named with batch, and a stepped loop with a literal step of 1 are not evidence.
- Only Python source is examined; other languages are out of scope.
Development
PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m build
License
MIT.
Metadata
Release files for batch-claim-audit 0.1.0
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 |
|---|---|---|---|---|
| batch_claim_audit-0.1.0.tar.gz | 15.2 kB | Without provenance | Details for batch_claim_audit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| batch_claim_audit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for batch_claim_audit-0.1.0-py3-none-any.whl |
Total release size: 24.7 kB
Release files / batch_claim_audit-0.1.0.tar.gz
| Download URL | batch_claim_audit-0.1.0.tar.gz |
|---|---|
| Size | 15.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
60ca396fd9f84f19110bb902a60292227388c8d81d599b9522ce6757bfbee594
|
|
BLAKE2b-256 checksum How to use checksums |
603d73c34f790594e9f89f7eb0ccd5e0a0973b098508891e8baa792d199bce7d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / batch_claim_audit-0.1.0-py3-none-any.whl
| Download URL | batch_claim_audit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
72dc05fa6012f05d6ed59c9f5c96a800744f3444eb2f597e08db25eeedcf24fb
|
|
BLAKE2b-256 checksum How to use checksums |
27102b7b81c05ec4deadacbb648a863ccb3f97dea85acbe06c7eb8f341c623fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for batch-claim-audit 0.1.0
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.