Automations
A board can carry Butler-style rules — trigger → filters → actions — that run automatically when board events happen. Managing rules requires board admin (and, for API tokens, the automations:write scope).
The distinctive twist: agents can author rules too. A human describes a rule in plain language; an agent drafts it over MCP. See Agents → REST and the MCP automation_write tool.
Rule shape
{
"name": "Changelog reminder",
"enabled": true,
"trigger": {
"verb": "card.moved", // any activity verb
"filters": { // ALL must hold (ANDed); every field optional
"toListRole": "done", // destination list marked role=done
"labelId": "<uuid>",
"priorityIn": ["high", "urgent"],
"actorType": "human", // human | agent that triggered the event
"titleMatches": "^\\[release\\]", // safe-subset regex
"fieldEquals": { "fieldId": "<uuid>", "value": "QA" },
"toListId": "<uuid>", "fromListId": "<uuid>"
}
},
"actions": [ // ordered, max 8; run as the "Automation" actor
{ "type": "add_comment", "template": "{{actor.name}} moved {{card.key}} to Done — add a changelog entry?" }
]
}Every action runs as the board's system "Automation" agent actor (created on the first rule), so automated changes are visibly non-human, and each carries payload.automationRuleId in the activity log — that log is the per-rule run history.
Action vocabulary
Deliberately tight (v1):
move_card · set_priority · add_label / remove_label · assign / unassign · set_field · set_due ({inDays} or {clear:true}) · set_completed · add_comment {template} · archive_card · add_checklist_item.
Comment templates substitute only a whitelisted set of variables (no expression evaluation) — anything else renders empty:
{{card.title}} {{card.key}} {{actor.name}} {{trigger.verb}}Safety rails
- Loop guard (depth-1): events authored by the Automation actor never trigger rules — a rule fires at most one hop of follow-on work.
- Rate limit: a rule that runs more than
AUTOMATION_RULE_RATE_LIMITtimes a minute (default 30) auto-pauses and notifies its creator. - Per-board cap:
AUTOMATION_MAX_PER_BOARD(default 32). - Per-action isolation: a failing action records
lastErrorand continues to the next — one bad action never aborts the rest or the triggering mutation. - Defaults: every new board is seeded with two visible, deletable rules — "card moved into a Done-role list → set completed" and "card archived → clear due date". Mark a list as the completion column with
role: "done".
Recipes
// Triage: label `bug` on an urgent card → assign the on-call human + due in 2 days
{ "name": "Bug triage",
"trigger": { "verb": "card.labeled",
"filters": { "labelId": "<bug-label-uuid>", "priorityIn": ["high","urgent"] } },
"actions": [ { "type": "assign", "actorId": "<oncall-uuid>" },
{ "type": "set_due", "inDays": 2 } ] }
// When an agent fails a session, flag the card for human review
{ "name": "Agent failed → review",
"trigger": { "verb": "agent_session.failed", "filters": {} },
"actions": [ { "type": "add_label", "labelId": "<needs-review-uuid>" },
{ "type": "add_comment", "template": "{{actor.name}} could not finish {{card.key}} — please review." } ] }VCS integration
GitHub/GitLab integrations drive cards from PR lifecycle through the same rules engine: they emit vcs.* events (vcs.pr_opened, vcs.pr_merged, …) carrying the linked card, and you write rules that move/label/complete the card. Installing an integration with in-progress + done list ids seeds two ready-made rules. See Agents → REST → VCS deep-linking and Development → Plugins.