Operational safeguards

Automation Safety

Automation power must ship with guardrails. This section covers grants, triggers, runtime-event automation lanes, limits, and operational controls that prevent accidental abuse.

Safety constraints for resilient and user-safe automation design.

Implementation focus

Use this page before enabling webhooks, schedules, or external automation flows in production.

Expected outcomes

Automation Safety (Creator-Safe Defaults)

Runtime-event automations can be triggered by any viewer who can run your vibe. This is intentional: you can share a link and have automations work immediately.

What this means

Threat model (what to protect against)

Treat viewer-triggered automations like a public integration surface. The main risks are cost and spam, not cross-tenant data access.

Platform safety rails (already enforced)

Rate limits

Scoped execution

Short-lived grants

Audit telemetry

Beginner Path: Moment To Pulse

The simplest production automation is: choose a moment, wake a Pulse, choose Pulse State memory, then check recent runs. The Pulse receives the moment payload and can send a message, call an API, or update Pulse State without exposing secrets to the browser.

1. Choose the moment

Start with a schedule, webhook, manual run, filtered runtime event, Pulse event, or safe social event. In v1, Pulse and social moments use the runtime-event trigger path with a normalized safe event identity.

2. Wake a Pulse

Pick a saved Pulse action when Vibecodr should do the backend work for you.

3. Choose memory

Use Run every time for intentional repeats, or Run once per event with runOnce().

4. Review runs

Use Recent runs to see what ran, what failed, what was Already handled, and what Could not replay safely.

Batch and retry behavior

Batched runtime events return a result for each submitted event. If one event is rejected, the response still shows which index failed, why it failed, and which entries were accepted. Retry only the failed entries after fixing the reason.

Batch result shape

{
  "ok": true,
  "accepted": 1,
  "failed": 1,
  "partial": true,
  "results": [
    { "index": 0, "ok": true, "status": 202, "eventType": "vibe.view" },
    { "index": 1, "ok": false, "status": 400, "error": "eventType is invalid" }
  ]
}

Creator-safe defaults (recommended checklist)

Do this for every public or unlisted automation

Example: verify a Stripe webhook before parsing

env.webhooks.verify("stripe",...) is the first certified provider helper, not the whole webhook model. Other signed providers can use env.secrets.verifyHmac(...) in advanced/manual handlers until their provider helpers have fixture-backed conformance.

Pulse webhook receiver

import { definePulse } from "@vibecodr/pulse";

// Pseudocode: persist dedupe keys for 1-10 minutes in a short-lived store you control
async function seenRecently(dedupeKey: string): Promise<boolean> {
  return false;
}

export default definePulse(async (_input, env) => {
  const event = await env.webhooks.verify("stripe", {
    secret: "STRIPE_WEBHOOK_SECRET",
  });

  const dedupeKey = "stripe:" + event.id;
  if (await seenRecently(dedupeKey)) return new Response("ok", { status: 200 });

  // Perform your side effect (send email, write DB row, call 3rd party, etc.)
  // Handle event.type and event.data here.
  return new Response("ok", { status: 200 });
});

Example: verify a signed webhook manually

Generic HMAC webhook receiver

import { definePulse } from "@vibecodr/pulse";

export default definePulse(async (_input, env) => {
  const rawBody = await env.request.raw.arrayBuffer({ maxBytes: 1024 * 1024 });
  const verified = await env.secrets.verifyHmac("GITHUB_WEBHOOK_SECRET", {
    format: "github-sha256",
    message: rawBody,
    signatureHeader: env.request.headers.get("x-hub-signature-256"),
    maxBytes: 1024 * 1024,
  });
  if (!verified.ok) return new Response("unauthorized", { status: 401 });

  const text = new TextDecoder("utf-8", { fatal: true }).decode(rawBody);
  const payload = JSON.parse(text);

  return Response.json({ accepted: true, event: payload.action ?? "unknown" });
});

Automation risk model

Automation turns a vibe or Pulse from something a person opens into something that can react to events, time, webhooks, or runtime signals. That power needs explicit limits because retries, external callers, and schedules can multiply mistakes quickly.

Safe automation starts with narrow moments, Pulse State duplicate protection, bounded retries, clear grants, and logs that explain what happened without exposing secrets. For most creators, the easiest production path is moment, Pulse action, Pulse State memory, then Recent runs.

  • Validate incoming webhook payloads and signatures.
  • Use Run once per event for external side effects; use Run every time only when repeats are intentional.
  • Use least-privilege grants and owner-controlled secrets.
  • Bound retry behavior and avoid unbounded fan-out.
  • Keep operational telemetry metadata-only.

Beginner automation path

Choose the moment first: schedule, webhook, manual run, filtered runtime event, Pulse event, or safe social event.

In v1, Pulse and social moments are normalized into the supported runtime_event trigger path. The product can say Pulse event or social event, while the backend still receives one safe runtime event identity.

Choose a Pulse action when Vibecodr should do backend work for you. The Pulse receives the moment payload plus a friendly Pulse State memory hint.

Use Run once per event when a Pulse writes to Discord, Notion, Stripe, GitHub, email, or another external service. Manual test runs can use Run every time when repeated tests are intentional.

Check Recent runs after setup. Already handled means the event was completed before; Could not replay safely means the result was intentionally not retained.

  • Start with one moment and one Pulse action.
  • Filter runtime events instead of listening to every event.
  • For schedules, use the scheduled window key. For runtime, Pulse, and social moments, use the normalized safe event identity. For provider webhooks, verify first; body event ids are only hints until the caller is trusted.
  • Retry only failed batch entries when a batch response is partial.

When to add automation

Add automation when it removes real manual work or enables a project behavior that cannot happen in a single viewer session. Do not add it as a shortcut around missing validation or unclear product rules.

If an automation touches money, accounts, external APIs, or user data, treat the handler as production backend code.

  • Prefer explicit user action until the trigger rules are clear.
  • Test failure paths, duplicate delivery, and out-of-order events.
  • Document what the automation is allowed to do before expanding it.

Example and read next

Example: a scheduled Pulse sends reminders every morning. Validate the target, cap retries, keep secrets server-side, and make the operation idempotent enough that a retry cannot spam users or duplicate writes.

Use these related pages when you need the next layer of guidance. They point to the most likely follow-up tasks, not every page that happens to touch the same system.

Related documentation