Tidebase Tidebase GitHub Start self-hosting
Docs

Human approval gates for AI agents

To pause an AI agent until a human approves a risky action, call run.gate(). The workflow blocks on a durable gate stored in Postgres; it can be approved or rejected from Tidebase Studio, your own product UI, a Slack-style adapter, or a plain webhook — and the decision survives crashes and replays exactly once.

const decision = await run.gate('approve-send', {
  prompt: 'Send this report to the customer?',
  data: { reportId },
  channels: [{ type: 'webhook', url: process.env.REVIEW_WEBHOOK_URL! }],
  capability: {
    name: 'report.send',
    scopes: ['report:send'],
    reason: 'agent wants to send an external report'
  }
})

if (decision.decision !== 'approved') {
  throw new Error('Report was not approved')
}

Tidebase is an open-source checkpoint layer for AI agents: wrap your steps, and failed runs resume from the last safe point — in your own Postgres, without moving execution into a new runtime.

Gate semantics

  • Durable: the gate is a Postgres row, not an in-memory promise. The process can die while waiting; on resume, a still-pending gate keeps waiting, and an already-resolved gate replays its decision.
  • Exactly-once: resolution requires the gate’s resolveToken and only succeeds while the gate is pending. A second resolve attempt gets a 409, not a double-approval.
  • Decisions: approved, rejected, or canceled, with optional actor and payload recorded for audit.

Delivering the gate to a reviewer

Webhook channels push gate events to any surface you own:

await tide.run('generate-report', {
  input: { topic: 'channels' },
  channels: [{
    type: 'webhook',
    url: 'https://your-app.example.com/api/tidebase-events',
    events: ['run.failed', 'step.failed', 'gate.created']
  }]
}, workflow)

The webhook payload for gate.created includes a resolveUrl and resolveToken, so the receiving surface can render an approve/reject UI and resolve directly:

curl -X POST "$RESOLVE_URL" \
  -H 'content-type: application/json' \
  -d '{"token":"<resolveToken>","decision":"approved","actor":"yao"}'

A slow or hung channel endpoint never blocks other writers to the run.

Capability metadata

The capability field (name, scopes, reason) is audit metadata only — Tidebase records what the agent asked permission for, but does not store or broker API keys or credentials.

See also: The replay contract · Quickstartpnpm example:review runs a local approval surface you can click through.