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
- Set safe trigger and permission boundaries for automations.
- Prevent runaway jobs, overbroad grants, and unsafe retries.
- Preserve user trust while still enabling powerful automation.
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
- Public: anyone can view and can trigger your runtime-event automations.
- Unlisted is link-accessible: anyone with the link can trigger runtime-event automations.
- Private: not link-accessible (only you and moderators/admins can access).
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.
- Spam automation events to burn your webhook/pulse quotas.
- Replay the same event repeatedly to cause duplicate side effects.
- Send unexpected payload shapes to break fragile code paths.
- Use high-cardinality event types to create noisy logs/alerts.
Platform safety rails (already enforced)
Rate limits
- Per-IP and per-owner limits on grant minting and event emission.
- Invocation limits are aligned with plan trigger rates.
Scoped execution
- Automation events can trigger only capabilities owned by the post author.
- Event types are constrained to safe characters and blocked from internal namespaces.
Short-lived grants
- Grants expire quickly (about 180 seconds) and are tied to a specific post.
- Grants are issued from a no-store endpoint (never embedded in cached public responses).
Audit telemetry
- Grant mints and automation event outcomes are recorded as operator telemetry (IP is hashed).
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
- Filter events: specify the exact runtime event types you need (avoid "all events" in production).
- Duplicate protection: for side effects, use Pulse State Run once per event with the scheduled window key, verified webhook event id, or safe runtime/social event identity. This makes repeated wakes safe; it is not an exactly-once guarantee for third-party side effects.
- Rate limit side effects: protect downstream APIs (email/SMS/Discord/Stripe/etc.).
- Validate payloads: treat all fields as untrusted; ignore unknown fields instead of crashing.
- Let Pulses do the work: keep the moment narrow and put provider calls, secrets, and Pulse State memory inside the Pulse.
- Webhook secrets: when using webhook actions, set a secret and verify
X-Vibecodr-Signatureon your receiver.
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.
- Read next: Secrets & APIs
- Read next: Calling Pulses
- Read next: Pulse Routing
- Read next: How-To Guides