Before: 2 refunds
A deliberately broken integration retries with a new operation key after the first refund succeeds.
Open Before: 2 refunds ↗Curbi / Repair Lab
A local, inspectable first proof: a committed refund times out, a naive retry duplicates it, and a candidate adapter keeps the effect count at one.
A deliberately broken integration retries with a new operation key after the first refund succeeds.
Open Before: 2 refunds ↗The candidate records the attempt and checks the original result before another write.
Open After: 1 refund ↗Run the test independently. Remove the tracking guard and the regression fails.
Open Regression exported ↗cd curbi-repair-lab-v1 node repair-lab/src/cli.mjs demo --out ./my-first-proof node --test ./my-first-proof/regression.test.mjs
The bundled CLI emits a fixed candidate adapter for one deliberate failure fixture. It does not diagnose arbitrary repositories. Its in-memory journal is not process-crash durable. No real provider, credential or payment is connected.
Output includes the candidate adapter, a fingerprinted evidence report, and a standalone regression test. Inspect the source before adopting any pattern in your own integration.
Repair Lab · the failure catalog
Refund counts are the fixture payments server’s own ground truth, from the MCP Chaos matrix. “Held” means the repair kept the outcome pending instead of guessing.
| Failure | What goes wrong | Typical first version | Repaired pattern | The repair |
|---|---|---|---|---|
| Timeout after a committed write | A successful write times out and the retry duplicates it | fail 2 refunds | pass 1 refund | Stable idempotency key per logical operation; reconcile by lookup; never a second write after an unknown outcome |
| Request lost before the server | The call never arrived; the client cannot tell this from case 01 | pass 1 refund | pass 0 refunds · held | Same as 01: from the client this is indistinguishable, so it must reconcile, not guess |
| Authentication expired mid-workflow | Token expires between steps; blind retries or silent success follow | pass 1 refund | pass 0 refunds | Recognise the auth failure, refresh credentials out of band, retry with the SAME key |
| Provider changed its response shape | The tool's declared output and actual response disagree | fail 1 refund | pass 1 refund | Validate against the declared output schema; on mismatch treat the outcome as unknown and reconcile |
| Silent failure: success with no data | The API returns a success code with an empty payload | fail 1 refund | pass 1 refund | Never accept success without the declared evidence fields; reconcile |
| The whole operation is retried (crash, double-tap, queue redelivery) | The integration runs twice for one logical operation; a per-invocation key cannot de-duplicate it | fail 3 refunds | pass 1 refund | Derive the idempotency key from the logical operation id (stable across invocations and restarts), never from a per-call random or attempt counter |
unzip curbi-mcp-chaos-v1.zip && cd curbi-mcp-chaos-v1 npm ci --ignore-scripts node src/matrix.mjs npm test
MCP Chaos · Repair Lab source ↓. Fixture-based: one payments server and one write tool. Bring your own server to extend the catalog.
A pass means no configured rule fired. It grants no execution authority or provider-completion proof.