Skip to main content

idempotency-claim-audit

Offline audit of documented re-run claims against Python source.

Version 0.1.0. Python 3.9 or newer; standard library only at runtime. The auditor compares documentation promises about repeated runs with static file-writing and SQL evidence. It executes no audited code, uses no network, and never reads .env contents. Reports go to stdout; diagnostics go to stderr. The audited tree is read only. Symlinked files and directories are skipped.

Usage

python3 -m pip install .
idempotency-claim-audit /path/to/project
idempotency-claim-audit /path/to/project --json
python3 -m idempotency_claim_audit /path/to/project --verbose
idempotency-claim-audit . --ignore 'generated/*' --ignore 'vendor/*' --fail-on HIGH
idempotency-claim-audit --version

The optional directory defaults to the current directory. --ignore accepts repeatable, case-sensitive glob patterns matched against relative POSIX paths; a matching directory prunes its subtree. --verbose adds claim locations and verified families to text output. JSON always includes findings, verified_claims, claims, errors, production_source_count, and status. Each finding includes rule, severity, family, claim locations, evidence, and a note. Evidence includes path, line, and kind, except the no-source sentinel.

Exit status: 0 for PASS, 2 for findings meeting the threshold, 1 for usage, read, or parse errors. The default threshold is MEDIUM. --fail-on HIGH retains MEDIUM findings in reports but permits a successful exit.

Claims

Only root README.md and docs/**/*.md supply claims. Fenced code is excluded; inline code counts as prose. Matching lowercases sentences, expands n't to not, changes hyphens to spaces, and collapses whitespace. Exact phrases with word boundaries are required; no optional middle words are inferred. These are the complete phrase families:

idempotent family:
  idempotent
  safe to run twice
  safe to rerun
  safe to re run
  running it twice is safe
  re running is safe
  rerunning is safe

overwrite family:
  overwrites
  replaces the existing
  does not append
  never appends

Negation asymmetry: a sentence containing no, not, never, or without suppresses the first family only. The second family retains negative wordings as promises. Bare-word exclusions include idempotency and append-positive prose such as “appends to the log”. Both families may be present and are evaluated independently. This README keeps matching phrases and rule names inside fences so its self-audit has no claims.

Rules

Family Condition Result
First Any production append evidence HIGH, all append evidence
First Only test append evidence MEDIUM, all test append evidence
First No append evidence anywhere Verified
Second Any production append evidence HIGH, all append evidence
Second Production content-replacement evidence, no production append Verified
Second No production evidence, test append evidence MEDIUM, all test append evidence
Second No production evidence or test append evidence HIGH, no overwrite evidence note
Either No production Python source HIGH, no-source sentinel
Neither Any code PASS

There is one finding per family, with append evidence taking precedence over missing replacement evidence. Production replacement evidence wins over test-only append evidence for the second family. No-source takes precedence for either family. Repeated claims do not multiply findings.

HIGH rules:
  documented-idempotent-claim-false
  documented-overwrite-claim-false
MEDIUM rules:
  documented-idempotent-claim-false-test-only
  documented-overwrite-claim-false-test-only

Named evidence

Kind Static source shape
append-open Literal mode containing a in builtin open, io.open (including module aliases), or receiver.open
insert String literal containing insert into without or ignore, or replace, or on conflict, case insensitive
overwrite-open Literal mode containing w in those open calls
path-write Any receiver.write_text or receiver.write_bytes call
no-source No production Python source available

Builtin and io calls take mode as the second positional argument; bound receiver methods take it as the first. The mode keyword also counts. A file-local function, class, or parameter named open suppresses builtin open evidence throughout that file. Evidence is deduplicated by file, line, and kind. SQL literals are counted once per such location.

Differentiation

Neighbour Its question compared with this tool
readonly-claim-audit Whether filesystem writes occur at all, rather than repeat-run semantics
atomic-claim-audit Single-write crash safety, rather than repeat-run safety
determinism-claim-audit Reproducibility of one run, rather than composition of two runs
security-claim-audit Execution safety, rather than append/insert evidence
bandit / ruff Code issues, rather than documentation promises
Runtime double-run tester below Executes functions twice, rather than comparing docs with source
idempotency-kit Runtime idempotency-key library, rather than documentation auditing
Runtime double-run tester: pytest-idempotent

Honest limitations

This is a literal-shape audit, not proof of repeat-run correctness. Production source excludes tests/, fixtures/, test_*.py, *_test.py, docs/, and examples/. Test and fixture source is collected separately; docs and examples are never evidence. Build, distribution, virtual environment, Git metadata, bytecode, and package metadata directories are skipped.

  • Variable modes such as open(path, mode) are UNKNOWN and skipped.
  • Exclusive mode x counts as neither append nor content replacement; it may fail on a repeated run.
  • os.remove, os.replace, and shutil.copy are not content evidence here.
  • print(file=...) handle provenance is not tracked, including append handles.
  • Module, class, and function docstring SQL literals are excluded.
  • Dead code counts. An uncalled append call still supplies evidence.
  • One append item falsifies a whole first-family promise regardless of whether its actual content would duplicate: intentional existence over-approximation.
  • Guarded INSERT shapes are excluded even in dead code. Guards are not proved.
  • Receiver types are not inferred: unrelated methods with matching names can count. Imported builtin aliases and dynamically computed SQL are not resolved.
  • Exact-phrase claims can miss paraphrases, and sentence-level negation can suppress an unrelated promise in the same sentence.
  • Parse or read failures return status 1 and errors, rather than a clean bill.

Development

PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m pip install build
python3 -m build
# Offline fallback only if isolated build cannot obtain its requirements:
python3 -m build --no-isolation
PYTHONPATH=src python3 -m idempotency_claim_audit . --json

Setuptools builds the wheel and source distribution. Fixtures and unittest sources are included in the source distribution through MANIFEST.in. Licensed under MIT; see LICENSE.

Metadata

Release files for idempotency-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)

Source distribution for idempotency-claim-audit 0.1.0
File Size Uploaded Provenance Actions
idempotency_claim_audit-0.1.0.tar.gz 15.8 kB Without provenance Details for idempotency_claim_audit-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for idempotency-claim-audit 0.1.0
File Interpreter ABI Platform Actions
idempotency_claim_audit-0.1.0-py3-none-any.whl Python 3 none any Details for idempotency_claim_audit-0.1.0-py3-none-any.whl

Total release size: 25.5 kB

Release files / idempotency_claim_audit-0.1.0.tar.gz

Download URL idempotency_claim_audit-0.1.0.tar.gz
Size 15.8 kB
Tags Source
SHA-256 checksum
How to use checksums
649ef6d284f43b0cefec6c028375c855012f59f1a77c926282df6845163d60cb
BLAKE2b-256 checksum
How to use checksums
c5a3336e1db48445135ff399d101db15cb822548fbdbbf6a961b17402aac9bc5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / idempotency_claim_audit-0.1.0-py3-none-any.whl

Download URL idempotency_claim_audit-0.1.0-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14bc97bca9f32a4fb39f1c397a34cc1e1acd7167430020ee6135c26cdc9c4c5f
BLAKE2b-256 checksum
How to use checksums
0cb202414c1c8ee0ebf8353dc8b0f3a0328bc7b398545a78860e817505da2f8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for idempotency-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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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