ReplayGuard SDK
ReplayGuard makes retrying failed background jobs safe by preventing duplicate side effects like double payments, emails, or data corruption. It tracks every operation through a full lifecycle - from intent to verification - giving you complete execution memory for AI agents.
The Safety Guarantee
ReplayGuard sits between your job logic and its side effects. It fingerprints every operation and ensures they happen exactly once, regardless of how many times you press "Retry". Every side effect follows a strict lifecycle: INTENDED → EXECUTING → COMMITTED → VERIFIED, with UNKNOWN (timeout) and FAILED branches.
Rollback-Aware Workflows
Sometimes a job fails mid-way, leaving your system in an inconsistent state. ReplayGuard allows you to register Compensation Hooks that run automatically if the job terminates unsuccessfully.
await guard.compensate('PAYMENT', 'stripe-charge', inputs, {
type: 'HTTP_DELETE',
target: `https://api.stripe.com/v1/refunds/${paymentId}`,
payload: { reason: 'Job failed' }
});Installation
pnpm add @replaysafe/guard-sdkUsage
Wrap your job with withReplayGuard and use the guard instance for side effects. guard.effect() is the primary primitive - it gives you full lifecycle tracking and automatic deduplication.
import { withReplayGuard } from '@replaysafe/guard-sdk'
export const processPayment = async (orderId: string) => {
return await withReplayGuard(config, async (guard) => {
// This DB write will be skipped on replay if it succeeded before
await guard.wrap('DB', 'orders', { orderId }, async () => {
await db.order.update({ where: { id: orderId }, data: { status: 'PAID' } })
})
// This HTTP call is automatically guarded
await guard.fetch('https://api.stripe.com/v1/charges', {
method: 'POST',
body: JSON.stringify({ orderId })
})
}, orderId)
}Deduplication Scope & Boundaries
To ensure execution safety without sacrificing flexibility, the ReplayGuard deduplication engine operates under strict guarantees and boundaries:
1. Scope Boundaries
Deduplication is session-scoped by default using a unique externalId. To share execution memory across monitors or sessions (e.g. unique user creation webhooks), configure your checks with scope: 'PROJECT'.
2. Fingerprint Determinism
Fingerprints are generated via hash(type, target, hash(inputs)). Transient noise (timestamps, traceIds) is stripped automatically. If semantic business inputs change, a new fingerprint is generated, executing the action again.
3. Storage & Durability
All completed side effects are stored durably in the PostgreSQL database. Caching layers are used for fast inline loop detection, but the persistent database guarantees idempotency even if retries occur days or weeks later.
4. State Drift Mitigations
ReplayGuard is a safety layer for execution, not database replication. Use guard.snapshot() to track external state shifts, or register compensation rollbacks with guard.compensate().
Integration with Replaysafe
Once integrated, your job executions will appear in the Guard Dashboard under "Guarded Replays", where you can audit every side effect, view verification results, trigger resume, and safely retry failed workflows.