Skip to main content

crashresume

Prove your agent survives a crash. A conformance harness that kills and restarts a subject at every side-effect boundary, then checks the three invariants that decide whether a resume is safe:

Invariant Meaning
state_lost after restart, persisted state is gone while the baseline had state
effect_replayed the same idempotency key fired twice (e.g. a double charge)
resume_diverged the resumed run finished in a different state than the baseline

Real agent frameworks hit exactly these failures: streamed state vanishes on cancel, a payment succeeds but the client times out, the resumed run re-issues the payment. crashresume makes that testable without a framework — the subject is any object with a step(input) method.

Install

pip install crashresume

Usage

from crashresume import conform

def make_agent(ctx):                 # called once per (re)start — model a fresh process
    return MyAgent(ctx, store=DB)    # your persistence lives in DB

report = conform(make_agent, inputs=["job-1", "job-2", "job-3"])
assert report.passed, str(report)

Your agent records side effects through the harness-owned context:

class MyAgent:
    def __init__(self, ctx, store):
        self.ctx = ctx
        self.store = store
        self.done = set(store.load("done"))

    def step(self, job):
        if job in self.done:
            return                       # resume-safe: skip what already committed
        self.ctx.effect("charge", job, key=f"charge:{job}")
        self.done.add(job)
        self.store.save("done", self.done)

The harness runs a baseline, then re-runs crashing right after each recorded effect (side effect committed, process dead before checkpoint — the nastiest real-world case), restarts via your factory, and compares state and effect logs.

Per-scenario state (important)

Each crash point is an independent scenario — your factory is called from scratch each time. Durable state that must survive a restart but must not leak between scenarios should be keyed by ctx.run_id (the baseline uses "run"; crash point k and its resume share "run-<k>"):

stores = {}

def make_agent(ctx):
    store = stores.setdefault(ctx.run_id, Store())   # fresh per scenario
    return MyAgent(ctx, store)                        # durable within the scenario

If your durable store is a real database, reset its fixture per scenario the same way.

pytest plugin

A conform fixture is registered automatically:

def test_agent_is_crash_safe(conform):
    conform(lambda ctx: MyAgent(ctx, store=DB), inputs=["a", "b", "c"])

CLI demo

crashresume --selftest   # runs a conforming agent plus two broken ones and verifies the findings

Notes

  • Subjects that record no effects through ctx pass trivially — route real side effects through ctx.effect or the harness cannot observe them.
  • state_lost vs resume_diverged: an empty state after restart is "lost"; a non-empty but different final state is "diverged". Expose a state() method to opt into state comparison.
  • Works with any persistence: SQLite, Redis, files, LangGraph checkpoints.

License

MIT-style: use it, ship it, no warranty.

Metadata

Release files for crashresume 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 crashresume 0.1.0
File Size Uploaded Provenance
crashresume-0.1.0.tar.gz 11.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for crashresume 0.1.0
File Interpreter ABI Platform
crashresume-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.8 kB

Release files / crashresume-0.1.0.tar.gz

Download URL crashresume-0.1.0.tar.gz
Size 11.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2ceb87c50e57018b2dcdda5d06e9e917294aeeee8072dce50dda6a802d5e62f4
BLAKE2b-256 checksum
How to use checksums
bc7b3daea9af30046df20af4f57f6183aa70e750b0e578ee5ab38caf12e3adc9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

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

Download URL crashresume-0.1.0-py3-none-any.whl
Size 9.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e4a2f586daffa6aba5e75b374704482e2f28fa4c4d933ed1b9a9cd49a3231e1b
BLAKE2b-256 checksum
How to use checksums
7e42481744a48f9368f96577cb4546f1765bba1d914820f8f066f00e8ace5f80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

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

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