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
ctxpass trivially — route real side effects throughctx.effector the harness cannot observe them. state_lostvsresume_diverged: an empty state after restart is "lost"; a non-empty but different final state is "diverged". Expose astate()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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| crashresume-0.1.0.tar.gz | 11.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.