Workflow rules
A workflow rule is a sentence: when something happens, if some condition holds, do this.
Rules are defined per project, so a hobby board and a production service can behave completely differently.
Triggers
Rules fire on events inside Projectrr, on events arriving from an integration, or on a schedule.
| Source | Triggers |
|---|---|
| Projectrr | Issue created, status changed, assignee changed |
| GitHub | Push, PR opened, PR merged, PR closed without merging, release published |
| Trello | Card created, moved, updated, commented, label added, label removed |
| Sentry | Error created, error resolved, error regressed |
| Schedule | Every 5 minutes, 15 minutes, 30 minutes, or hour |
Conditions
Conditions narrow a trigger down. A rule with no condition runs on every matching trigger.
- Status is / is one of — match specific statuses
- Status category is / is one of — match
open,active,closedordone, so a rule works across projects that name their columns differently - Assignee is
- Source is — which system the change came from
- Contains issue reference — the event’s own text mentioning an issue key
like
WEB-14orWEB #14: a pull request’s title and body, a release’s body, or the commit messages in a push. The prefix must name a real project in the same product, soRevert PR #99does not count as one - Target branch is, source matches pattern
- Event field is — match a field on the event that fired the rule:
leveliserroron a Sentry error,sentryProjectis a particular Sentry project. The field names are whatever the event carries, and the dialog suggests the common ones
Label contains does not work yet. It is still offered in the rule dialog, but labels are not carried on the event a rule fires from, so the condition never matches and a rule that uses it never runs. Don’t build a rule around it.
Actions
- Move issue to status, or move every matching issue to one
- Create issue
- Create issue from event — open an issue from the event that fired the rule, using its title and details, in the column you name. Only one issue is ever created per event, so a second rule (or a redelivered webhook) picks up the existing one rather than opening a duplicate. This is how Sentry errors reach a board
- Assign to user — sets the assignee, subscribes them to the issue, and fires assignee changed so rules watching that trigger see the change too
- Log activity — writes a row into the activity feed, attributed to Automation and showing the message you wrote on the rule
- Sync to external — push the change to GitHub, Trello or Sentry. For
Sentry the action is
resolve,ignoreorunresolve, applied to the Sentry issues behind the Projectrr issue; an issue Sentry never knew about is recorded asskipped, not a failure - Poll external — pull changes in from Trello or Sentry
- Trigger a Claude routine — hand the issue to a coding agent
Add label does nothing yet. There is no way to create or read a label
anywhere in Projectrr, so the action attaches nothing and is recorded as
skipped rather than reported as a success. Like label contains, it is
waiting on labels being built.
Loop prevention
Two-way sync invites infinite loops: Projectrr updates Trello, Trello’s webhook tells Projectrr something changed, Projectrr updates Trello again.
Two guards stop that:
- Source tracking — an action never pushes a change back to the system it came from
- Depth limit — a chain of rules triggering rules stops at three
Execution log
Every rule keeps a log of what it did, when, and to which issue — so when
something moves on its own you can find out which rule moved it. Read it in the
UI or with prr rules log <id>.
Every entry lands in one of three states:
- success — the conditions matched and the actions ran without error. An action can still legitimately affect nothing, e.g. a move where every issue is already in the target status
- skipped — the rule did nothing: a condition did not match, or every action declined to act (an action that isn’t implemented, for instance)
- error — an action failed. The entry keeps the error message and the actions that had already run before it failed, so a partial run is visible. A GitHub sync the API rejects lands here, not in success
Examples
Close the loop on merged PRs. When a GitHub pull request linked to an issue is merged, move the issue to In Review.
Keep Trello in step. When an issue’s status changes and the change did not come from Trello, move the linked card to the mapped list.
Poll for what webhooks miss. Every 15 minutes, poll linked Trello boards for changes.
Triage production errors. When Sentry reports a new error, if its level is
error, create an issue from the event in Triage — see
Integrations.
Close the error when the fix ships. When an issue’s status changes to one in
the done category, sync to external sentry with the action resolve.
Reopen when it comes back. When a resolved Sentry error starts happening again, move the issue back to Triage — the Error Regressed trigger carries the issue the first rule opened, so it moves rather than being opened twice.
Triage new work. When an issue is created in a status in the open
category, assign it to the triage lead — which fires assignee changed, so a
second rule can pick it up from there.