Trigger
A Trigger is a persistent resource that automatically creates a new task for an agent when an inbound event matches its source conditions. It is the event-driven counterpart to Schedule — where a Schedule fires on a time cadence, a Trigger fires on an external signal.
kind: "commonagents.info/v1beta2/trigger"
name: str
agent: str
owner: str
source:
type: str
before: list[MiddlewareStep] | None
message: str | None
inputs: object | None
enabled: bool
Fields
kind— Identifies this manifest as a Trigger. Must be"commonagents.info/v1beta2/trigger".name— Identifies the trigger. A name identifies one resource (see Concepts).agent— Identifies the agent that a new task is created for when the trigger fires.owner— Identifies the user associated with all tasks created by this trigger. Used for identity, access control, and OAuth token resolution. The task runs with this user's identity and OAuth tokens — not the identity of the event sender.source.type— The event source type this trigger listens to (e.g."github","email","slack"). Must match a receive runtime configured in the server.source.before— When present, CEL assert steps evaluated against the raw incoming event. If any assert fails, no task is created. Supportsevent.payload.*to access the raw event body.message— When present, used as the input message for the created task. Supports{event.payload.*}interpolation to include event data. When absent, the task is created with no initial message.inputs— When present, passed as structured input satisfying the agent'sparametersschema. Required agent parameters must be present.enabled— Whentrue, the trigger is active. Whenfalse, the trigger is inactive and no tasks are created.
Status
A trigger has no status.
Status describes what is true of a resource now, and a trigger has nothing of that kind: unlike a schedule, it has no cadence, so there is no next firing to compute. What a trigger has done — when it last fired, how many times, which tasks it produced, why an attempt failed — accumulates without the trigger changing, so a status carrying it would be a field whose value moves when nothing about the resource has. How an implementation records execution history, and whether it exposes one at all, is outside this specification.
Trigger vs Event Subscription
There are two ways events can activate an agent:
| Trigger | Event Subscription | |
|---|---|---|
| Creates | A new task | Input to an existing task |
| Declared in | Trigger manifest | Tool event + agent capability |
| Task identity | trigger.owner | Original task owner (unchanged) |
| Payload access | event.payload.* (raw) | event.<field> (via tool parameters map) |
| Filtering | source.before CEL asserts | Tool receive.filter + binding scope |
Use a Trigger when an event should start a new agent conversation. Use a tool event subscription when an event should continue an existing one.
Identity and RBAC
Tasks created by a Trigger run with the owner field's identity — not the identity of the event sender. The event sender may appear in the message content (via {event.payload.*} interpolation) but never determines authentication context.
The same self-restriction model applies as for Schedules:
| Role | Create | Read | Update | Delete |
|---|---|---|---|---|
agent_user (non-admin) | Own triggers only | Own triggers only | Own triggers | Own triggers |
admin | Any owner | All | All | All |
read_only | ❌ | All | ❌ | ❌ |
Raw Payload Access
Triggers receive raw event payloads directly — they are not processed through a tool's event parameters map. Use event.payload.* to access the unprocessed event body in both source.before and message fields:
source:
before:
- assert: "event.payload.repository.private == false"
message: "New PR from {event.payload.pull_request.user.login}: {event.payload.pull_request.title}"
Example
Inbound Support Email
kind: "commonagents.info/v1beta2/trigger"
name: "inbound_email"
agent: "support-agent"
source:
type: email
before:
- assert: "!has(event.payload.headers.in_reply_to)"
message: >
New support email from {event.payload.from}:
Subject: {event.payload.subject}
{event.payload.body_text}
enabled: true
New GitHub Issue (Public Repos Only)
kind: "commonagents.info/v1beta2/trigger"
name: "new_github_issue"
agent: "triage-agent"
source:
type: github
before:
- assert: "event.payload.action == 'opened'"
- assert: "event.payload.repository.owner.login == 'buoyant-systems'"
- assert: "event.payload.repository.private == false"
message: >
New issue #{event.payload.issue.number} in {event.payload.repository.name}:
{event.payload.issue.title}
{event.payload.issue.body}
enabled: true