atomic-claim-audit
Offline audit of documented atomic-write claims against Python source. Version 0.1.0; Python 3.9 or newer; MIT; no runtime dependencies.
The CLI reads documentation and parses Python ASTs. It never executes audited
code, uses no network, never reads .env file contents, and never writes to
the audited tree. Symlinked files and directories are skipped.
Usage
python3 -m pip install .
atomic-claim-audit /path/to/project
python3 -m atomic_claim_audit /path/to/project --json
atomic-claim-audit . --ignore 'vendor/*' --ignore 'generated.py' --verbose
atomic-claim-audit tests/fixtures/testonly --fail-on HIGH
atomic-claim-audit --version
The path defaults to the current directory. --ignore is repeatable and matches
case-sensitive relative-path globs. --verbose also shows verified families.
--json returns findings, verified_claims, and errors arrays; findings
include rule, severity, family, claims, and all evidence records
(path, line, kind). Verified records include family and claims.
Unreadable, invalid UTF-8, and syntactically invalid input files are reported
as errors, with exit 1, rather than silently treated as clean scans.
Rules
| Condition | Rule | Severity |
|---|---|---|
| Claim and production direct writes | documented-atomic-claim-false | HIGH |
| Claim and no production Python source | documented-atomic-claim-false (no-source) |
HIGH |
| Claim, production source, only test/fixture writes | documented-atomic-claim-false-test-only | MEDIUM |
| Claim and no direct-write evidence | verified atomic-write family | PASS |
| No claim | no finding, regardless of writes | PASS |
One finding contains every relevant evidence item; multiple phrases still form
one atomic-write family. Exit codes are 0 for PASS, 2 for findings at the
threshold, and 1 for usage/input errors. The default --fail-on MEDIUM includes
both severities. --fail-on HIGH retains MEDIUM findings but exits 0 for them.
Claims come only from root README.md and docs/**/*.md. Fenced code is
excluded; inline code counts. A sentence containing no, not, never, without,
doesn't, don't, or isn't suppresses every claim in that sentence.
The exact case-insensitive phrases are: atomic write(s), atomically writes,
atomically saves, atomically updates, atomic save(s), atomic update(s),
crash-safe write(s), crash safe write(s), all-or-nothing write(s), and atomic
file write(s). Parenthetical (s) here means the singular and plural forms.
Direct-write evidence consists of open, io.open, or any .open call with
a literal mode containing w, a, x, or +; any .write_text or
.write_bytes call; and shutil.copy, shutil.copy2, or shutil.move.
Production excludes tests/ and fixtures/ directories, test_*.py, *_test.py,
docs/, and examples/. Test/fixture evidence is collected separately; docs and
examples never contribute source evidence.
Differentiation
| Neighbour | Different question |
|---|---|
| readonly-claim-audit | Whether writes exist, never their atomicity |
| determinism-claim-audit | Run-to-run stability, never write safety |
| security-claim-audit | eval/shell/pickle hazards, never write patterns |
| bandit / ruff | Code issues, never documentation promises |
| atomicwrites / filelock | Runtime helpers that perform writes or locking; this tool statically audits promises |
Honest limitations
Only the exact listed phrases count: bare “atomic”, “atomic operations”,
“atomic config writes”, and “atomic JSON writes” do not. Sentence splitting
uses ., !, and ?; this is a heuristic, not natural-language understanding.
Static evidence is not a crash-safety proof. Dead code counts. Receiver types,
import aliases, dynamic calls, and descriptor provenance are not inferred.
Variable modes and absent modes are skipped as UNKNOWN, never evidence.
print(..., file=...), os.replace, os.rename, deletion and directory
operations (remove, unlink, mkdir, rmdir), and os.write are excluded.
Replace/rename are the atomic step themselves; descriptor writes are untracked.
Temp-var tracking is per-file and by variable name, without scope or order
analysis. Names assigned from tempfile.NamedTemporaryFile, mkstemp,
TemporaryFile, or SpooledTemporaryFile (including with bindings and tuple
unpacking) are tracked. A write whose target is such a name or an attribute
based on it is excluded. Other direct writes in the same function still count.
This can miss writes after reassignment or name reuse. No replace-step proof
is required: a temp write with no replace can leak a file, but does not corrupt
a final path, so this deliberate leniency is outside the corruption audit.
Filesystem durability, fsync, cross-filesystem rename, concurrency, and locking
are not proven. Copy/move destinations count unless they are tracked temp vars.
Development
PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m build
The build produces a wheel and sdist under dist/. Fixtures ship in the sdist.
If isolated builds are unavailable offline, use python3 -m build --no-isolation.
Metadata
Release files for atomic-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 |
|---|---|---|---|---|
| atomic_claim_audit-0.1.0.tar.gz | 10.2 kB | Without provenance | Details for atomic_claim_audit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| atomic_claim_audit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for atomic_claim_audit-0.1.0-py3-none-any.whl |
Total release size: 18.5 kB
Release files / atomic_claim_audit-0.1.0.tar.gz
| Download URL | atomic_claim_audit-0.1.0.tar.gz |
|---|---|
| Size | 10.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
99341f2b60e2a855101467375c9cea0fc4bdb2400c60d57d7841727b4a6ac096
|
|
BLAKE2b-256 checksum How to use checksums |
e39dc42f826d9c176752851cf2d98108c7e25926533756fa2fd60d8cc9b1f672
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / atomic_claim_audit-0.1.0-py3-none-any.whl
| Download URL | atomic_claim_audit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a651a317ea07d7b66796dd7167d99cfc59fb3bdd5ef28e117623a64ddebd7db2
|
|
BLAKE2b-256 checksum How to use checksums |
ad8399e72a52ccd2c1fa461f1e250315a018994d4508981f35ac2d04099cf33a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for atomic-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.