Skip to content

Automations

A board can carry Butler-style rulestrigger → 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

jsonc
{
  "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_LIMIT times 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 lastError and 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

jsonc
// 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.

Released under the AGPL-3.0 license.