Triggers
Webhooks, thresholds, and events that activate goal phases or advance execution.
Triggers
Triggers let external events drive goal execution. Instead of polling or looping, goals can wait for webhooks, threshold crossings, or manual events to activate phases.
Trigger Types
| Type | Description | Use Case |
|---|---|---|
webhook | HTTP POST to a registered endpoint | CI/CD events, external API callbacks |
threshold | Metric crosses a defined threshold | "When signups > 500, start Phase 3" |
schedule | Time-based activation | "Start Phase 2 on Monday at 9am" |
phase-complete | Another phase completes | Standard sequential advancement |
manual | Explicit trigger via tool or CLI | Human-initiated phase activation |
Webhook Triggers
Register a webhook endpoint for a goal phase:
goals({
action: "trigger",
goalId: "g_abc123",
phaseIndex: 2,
event: "deploy-approved"
})Webhook HTTP Endpoint
The gateway exposes webhook endpoints at:
POST /api/goals/triggers/:pathExternal systems hit this URL to fire the trigger. The trigger engine:
- Looks up the registered path in the in-memory webhook registry
- Validates the goal exists and the phase index is valid
- If the phase is
pending, sets it torunning - Logs the trigger event
Registering webhooks programmatically
The registerWebhookTrigger function (used internally by the goals RPC) registers a path:
import { registerWebhookTrigger } from "../../goals/triggers.js";
registerWebhookTrigger("g_abc123", 2, {
path: "deploy-approved",
match: { status: "success" } // Optional: only fire if payload matches
});
// Returns: "/api/goals/triggers/deploy-approved"Example: CI/CD integration
// Goal with event-driven deploy phase
goals({
action: "create",
goal: {
title: "Release pipeline",
phases: [
{ name: "Build & test", type: "once" },
{ name: "Staging verification", type: "event-driven" },
{ name: "Production deploy", type: "once" }
]
}
})
// In your CI config (GitHub Actions, etc.):
// curl -X POST https://your-gateway/api/goals/triggers/staging-verifiedThreshold Triggers
Threshold triggers activate when a goal metric crosses a defined value. These are evaluated during heartbeat checks via goals/heartbeat-hook.js.
How threshold monitoring works
- Agent updates a metric:
goals({ action: "metric", goalId: "g_abc123", name: "signups", value: 510 }) - On the next heartbeat, the heartbeat hook checks all active goals
- If a metric exceeds a threshold defined for an event-driven phase, the phase activates
Example
// Create goal with threshold-triggered phase
goals({
action: "create",
goal: {
title: "Growth milestone campaign",
phases: [
{ name: "Build funnel", type: "once" },
{ name: "Scale when ready", type: "event-driven" },
{ name: "Celebrate & report", type: "once" }
]
}
})
// Agent tracks signups as a metric
goals({ action: "metric", goalId: "g_abc123", name: "signups", value: 245 })
// ... later ...
goals({ action: "metric", goalId: "g_abc123", name: "signups", value: 510 })
// Threshold crossed → Phase 2 activatesManual Triggers
Fire a trigger manually via the goals tool or CLI:
// Via agent tool
goals({ action: "trigger", goalId: "g_abc123", phaseIndex: 1, event: "manual-approval" })# Via CLI (approve also works as a manual trigger for paused goals)
reeve goal approve <goal-id>When a manual trigger fires:
- If the phase is
pending, it's set torunning - A log entry records:
"Trigger fired on phase 2: Scale when ready (event: manual-approval)" - If the phase is already
runningorcompleted, the trigger is logged but status doesn't change
Trigger Cleanup
When a goal completes, fails, or is cancelled:
- All webhook registrations for that goal are removed from the in-memory registry
- Cron jobs for loop phases are cleaned up
- Service loops are stopped
import { removeWebhookTriggers } from "../../goals/triggers.js";
removeWebhookTriggers("g_abc123"); // Returns number of webhooks removedWebhook registrations are in-memory — they don't survive gateway restarts. On startup, the gateway re-registers webhooks for all active goals with event-driven phases. This is handled by goals/scheduler.js during startup sync.
Combining Triggers with Service Loops
A common pattern: use a webhook trigger to activate a monitoring phase, then start a service loop:
// Phase 2 activates via webhook
goals({ action: "trigger", goalId: "g_abc123", phaseIndex: 1, event: "campaign-live" })
// Then start monitoring loop
goals({
action: "start_loop",
goalId: "g_abc123",
phaseIndex: 1,
intervalMs: 300000 // Check every 5 minutes
})See Service Loops for more on fast execution loops.