Skip to main content

exactly-once

Idempotency middleware for agent side-effects

The primitive agent frameworks forgot. Wrap any tool call that must never fire twice — a payment, an email, an onchain transaction — and exactly-once guarantees it runs a single time, even across retries, crashes, and replays.

See it prevent a double-charge in one command:
python examples/crash_mid_payment.py — an agent crashes mid-payment, resumes, and does not double-charge (with vs without).

v0.1 — zero-LLM, tiny surface, drop-in.


Why

Agents retry. They crash and resume. They get replayed during debugging. Every one of those can fire a side-effect twice — a card charged twice, an email sent twice, a transaction submitted twice. In systems that touch money, duplicate side-effects are the difference between a bug and a lawsuit. Frameworks give you retries and checkpoints but not idempotency for the effects those retries cause.

Install

pip install exactly-once            # core, zero heavy deps
pip install "exactly-once[redis]"   # + Redis store   (also: [postgres])

Quickstart

from exactly_once import once, Store, current_key

store = Store.sqlite("effects.db")   # or .memory() / .redis(url) / .postgres(dsn)

@once(store, key=lambda order, **_: f"charge:{order.id}")
def charge_card(order):
    # pass our key through as Stripe's own idempotency key — belt and suspenders
    return stripe.charge(order.customer, order.amount, idempotency_key=current_key())

charge_card(order)   # runs the charge
charge_card(order)   # replays the stored result — Stripe is NOT called again

# context-manager form for an inline effect
with once(store, key="send-welcome:user-4471") as guard:
    if guard.fresh:
        guard.result = send_email(...)        # skipped on any replay

⚠️ Key on stable business identity (order_id), never on a mutable value like amount — two distinct $50 charges must not collapse into one.

See it prevent a double-charge in 15 seconds:

python examples/crash_mid_payment.py    # agent crashes mid-payment, with vs without

More runnable examples in examples/.

The guarantee (honestly scoped)

Classic idempotency-key pattern adapted for agents: compute a stable key → atomically check-and-claim → if committed, return the stored result without re-running; if in-flight, block/deny per policy; if new, run and commit. On a crash mid-effect the key is left in-flight and quarantined — a half-completed payment must never silently re-fire. Single-writer semantics are strong; multi-writer needs a real transactional store (documented, not overpromised).

Pluggable stores: memory · SQLite · Redis · Postgres. An onchain adapter (dedupe by nonce + calldata-hash) is planned for v0.2. See SPEC.md and ROADMAP.md.

What it guarantees — and what it doesn't

Guarantees (given a store with an atomic claim): the effect is entered at most once per key across retries, concurrent workers, crashes, and replays; after a commit every later call replays the stored result; a concurrent second caller never runs in parallel; a crash mid-effect never auto-re-fires.

Does not: it is exactly-once effect (at-most-once execution + replay-on-success), not exactly-once delivery — that's impossible (Two Generals / FLP). It can't know the outcome of a crash-mid-effect; it refuses to guess (quarantine) and lets a prober or a provider idempotency key narrow the window. It's only as strong as the store you pick:

Store Guarantee Use for
memory strong within one process tests, dev
SQLite strong on one host single-node agents, jobs, CI
Redis strong single-instance, best-effort under failover distributed workers, one Redis
Postgres SERIALIZABLE true multi-writer, linearizable multi-host production

Full boundary in docs/ARCHITECTURE.md §9.

Development

uv venv --python 3.11 && uv pip install -e ".[dev]"
uv run pytest                              # full suite (Redis/Postgres tests need Docker)
uv run mypy src/exactly_once               # strict typing
uv run ruff check src tests examples       # lint
uv run python scripts/check_docs_honesty.py  # the docs-honesty gate

Part of the Swarm Proof toolkit

Trust infrastructure for the agent economy — seven projects, one thesis.

Project What it does
stampede Point a herd of realistic agents at your system before real ones arrive
mockworld A synthetic internet for agents — fake Stripe, Gmail, exchange, instantly
mcp-probe The CI quality suite for MCP servers — lint, contract-test, benchmark, load
costbomb Denial-of-wallet fuzzing — find the inputs that make your agent spend $500
exactly-onceyou are here Idempotency middleware so agent side-effects fire once
agent-postmortems A structured incident database + post-mortem standard for agent failures
awesome-agent-reliability The curated map of the field

License

MIT. No LLM anywhere — it's plumbing. Citable via CITATION.cff.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

exactly_once-0.1.0.tar.gz (82.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

exactly_once-0.1.0-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file exactly_once-0.1.0.tar.gz.

File metadata

  • Download URL: exactly_once-0.1.0.tar.gz
  • Upload date:
  • Size: 82.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for exactly_once-0.1.0.tar.gz
Algorithm Hash digest
SHA256 73b7999c4859702ebfbbeee9ec7e878db779618ac1a16fd7e99a4c3e65a01b2b
MD5 ea2e2bc9ad7b715cf68ddf69e54c6578
BLAKE2b-256 3b7568d1aa3c72890cee342208b6c12309901a9bc7b1a29742a29a79d2788397

See more details on using hashes here.

Provenance

The following attestation bundles were made for exactly_once-0.1.0.tar.gz:

Publisher: release.yml on swarmproof/exactly-once

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file exactly_once-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: exactly_once-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for exactly_once-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8da5c5cd4723dfc84e65a1a295473c94917b26fa6bf73f4dc8f5b85aa94b1715
MD5 16dd540b7efb81bcb5b8d1e1284ac46d
BLAKE2b-256 fa16f2db13546fca769c70d12e716f7a6e228788df3ea3868e0dd349e48340df

See more details on using hashes here.

Provenance

The following attestation bundles were made for exactly_once-0.1.0-py3-none-any.whl:

Publisher: release.yml on swarmproof/exactly-once

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.1

2 files

0.2.0

2 files

This release

0.1.0 This release

2 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