Execution Safety · For AI Agents & Autonomous Systems

Your agent retried.
The charge went through twice.

Verity wraps your side effects so they can't run twice — ever.

AI agents are taking real-world actions — charging cards, sending emails, provisioning infrastructure. When they fail, retry, or run concurrently, those actions repeat. Verity ensures every action happens exactly once, is fully auditable, and can be proven months later.

Works withAny AI agentTemporalTrigger.devInngestQueue workersPlain codeFor loops
The problem

Agents fail. Retries repeat. The real world doesn't forget.

Every retry-capable system — AI agent, queue worker, workflow engine — can accidentally repeat an action that already succeeded. The external API has no idea it was a mistake.

💳 Payments

Double charges

An agent retries a payment after a timeout. The first charge already went through. The customer sees two charges. You find out in a Stripe dispute three days later.

🏗️ Infrastructure

Zombie resources

A VM gets provisioned, then the commit crashes before it's recorded. The retry provisions a second one. You're paying for both — and neither is tracked correctly.

📧 Notifications

Duplicate messages

A worker restarts mid-batch. Customers who already received the email get it again. Five times. Your unsubscribe rate spikes. Trust erodes.

🔍 Observability

No audit trail

Something went wrong. Did the refund go through? Did the Slack message send? You have logs — but no way to know what actually happened in the external world.

What Verity is

One SDK.
Four safety primitives.

Wrap any side effect in verity.protect(). That's it. Works across any agent, any framework, any external system.

LEASE

Exclusive ownership

A fence token ensures only one agent acts on an effect at a time. Zombie agents are fenced out even if their network recovers late.

OBSERVE

Check before acting

If an agent crashed, the next attempt checks the external system first. Charge already exists? Return it — don't call Stripe again.

ACT

Safe execution

Before calling the external API, Verity validates the lease is still valid (begin-act checkpoint). If the agent froze, the stale token is rejected. Lease auto-renews to prevent timeout mid-action.

COMMIT

Sealed forever

The result is written to an immutable ledger. Any future call with the same effect key returns the cached result instantly. Idempotent forever.

agent.ts
// Works anywhere — agents, for loops,
// queue workers, plain async functions.

const verity = new VerityClient({
  apiKey: process.env.VERITY_API_KEY,
});

// Exactly once — even across crashes.
const charge = await verity.protect(
  `charge-${orderId}`,
  {
    observe: () =>
      stripe.charges.retrieve(orderId),

    act: () =>
      stripe.charges.create({
        amount: 5000,
        currency: 'usd',
      }),
  }
);

// Also works in for loops — entire batch
// is safe to retry with zero duplicates.
for (const order of pendingOrders) {
  await verity.protect(
    `charge-${order.id}`,
    { act: () => processOrder(order) }
  );
}
Crash recovery

Agent died mid-action? The next one picks up safely.

01 · LEASE

Acquire exclusive ownership

A fence token is issued. No other agent or concurrent retry can act on the same effect. Stale agents are fenced out even if their network recovers late.

02 · OBSERVE

Check the external system first

Prior agent crashed? Verity checks the external system before acting. Charge already exists? Return it and commit — don't call Stripe again.

03 · ACT

Execute safely

Before the external API call, the SDK runs a begin-act checkpoint — validating the lease, fence token, and expiry. If the agent froze and woke up late, the stale token is rejected and the call never fires. Lease auto-renews in the background to prevent timeout on slow operations.

04 · COMMIT

Seal the record

The result is written to the immutable ledger. Any future call with the same effect key returns the cached result instantly. Idempotent forever.

Without Verity
1Agent calls Stripe — charge succeeds
2Agent crashes before returning
3System retries the agent
4Stripe gets called again — duplicate charge
💳 Customer charged twice
With Verity
1Agent calls Stripe via verity.protect()
2Agent crashes before returning
3Retry runs — Verity checks Stripe first
4Charge found — returns result, skips act()
✓ Zero duplicates. Always.
Multi-step workflows

Step 3 of 5 failed. Re-run from scratch — safely.

Group related effects into named workflows. If a run crashes halfway through, the next run skips completed steps and picks up exactly where it failed. No custom recovery logic. No duplicate actions.

refund_flow · order_1232 RUNS · RECOVERED
Run 001 — crashed
validate_ordercommitted
process_refundcommitted
notify_customercrashed
Recovery run
Run 002 — completed
validate_ordercached
process_refundcached
notify_customercommitted

Cases map to your business entities

Each workflow case represents a real business object — an order, customer, or tenant. Easy to find in Explorer, easy to reason about in code.

Completed steps are cached, not re-run

Deterministic effect keys mean the same step across different runs maps to the same cache entry. Steps 1 and 2 return instantly. Only step 3 executes.

Works across multiple external systems

One workflow can span Stripe, SendGrid, Salesforce, and AWS — each step in its own namespace, all tracked together in the audit trail.

Your code stays clean

No recovery logic in your business code. Write the happy path with run.protect() for each step. Verity handles the rest.

Observability

Know exactly what happened. Prove it months later.

charge-order-456COMMITTED
Lease → Grantedfence=1
10:34:12.003 · 10.0.4.22
Observe → Miss
10:34:12.058 · no prior record
Act → Executingfence=1
10:34:12.341 · stripe.charges.create
Commit → Acceptedfence=1
10:34:12.892 · 10.0.4.22
"chargeId": "ch_3Qx7bK2eZvKYlo2C0k9Z",
"amount": 5000,
"currency": "usd",
"status": "succeeded"

Every event, every timestamp

Lease grants, observe results, act executions, commits — all recorded with millisecond precision, fence tokens, and agent IPs.

Immutable. Append-only.

The ledger can't be altered. When a payment dispute arrives months later, you can prove exactly what ran, when, and what Stripe returned.

Visual Explorer UI

Browse every effect and workflow case, drill into crash recovery traces, reset stuck effects, and watch live executions in real time.

Full result payloads stored

The complete response from every external call — charge IDs, resource ARNs, message IDs — stored alongside the audit events and queryable.

Reliability

We're on your critical path. We take that seriously.

Verity sits between your agent and the external world. Here's what that means for your system's resilience.

FAIL SAFE

What if Verity goes down?

The SDK surfaces errors clearly and immediately. Your code decides whether to fail safe or degrade gracefully. We never silently swallow failures or let through unprotected actions.

ISOLATED

Your data, isolated

Effect data is namespaced per API key with row-level security enforced at the database level. Test and live environments are completely separated — not just at the app layer.

PRODUCTION

Built for real money

Postgres with RLS for the ledger. Fence tokens enforced atomically. Lease auto-renewal in the background. Not a prototype — built for real charges, real infrastructure, real customers.

Early Access · Design Partners

Stop hoping retries
don't cause damage.

We're working directly with early teams to integrate Verity into production systems. No pricing, no self-serve — just you, us, and your use case.

npm install @verityinc/sdk  ·  pip install verityinc-sdk