# Rules (https://docs.vitrinka.ai/pm/rules)



## What a rule is [#shape]

A rule defines a **trigger** (a task event or schedule), **conditions** and **actions**. Configure rules through the API or MCP tools. The server validates each rule against its published JSON schema.

```json
{
  "trigger": { "kind": "event", "event": "updated" },
  "conditions": [ { "field": "group", "op": "in", "value": ["completed"] } ],
  "actions": [ { "kind": "add_label", "value": "archived" } ]
}
```

Actions are `set_status`, `set_group`, `set_priority`, `comment`, `add_label`, `remove_label` and `assign`. Three more work at project level or through Eve: `tick_date_gates` names a checklist field and ticks its reached `date` items, `brief` asks Eve for the brief, and `eve_flow` hands the task to an Eve flow (`pm-distill` · `pm-summarize`); `brief` and `tick_date_gates` take a schedule trigger, no conditions, and stand alone. Labels starting `eve-` are reserved: a user rule cannot add or remove them. The schema is served at `GET /api/v1/rules/schema`.

## The built-ins [#builtins]

Eleven workspace-wide rules are enabled by default and apply across projects. Seven run without an AI backend; four hand work to Eve and stay inert without one:

| Rule                     | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stale-nudge`            | Adds a comment and `stale` label to unstarted or started tasks with no update for 14 days.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `auto-archive-completed` | Adds `archived` to completed tasks with no update for 30 days.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `due-tomorrow-reminder`  | Adds a comment and `due-soon` label to open tasks due within a day.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `merged-pr-completes`    | A merged pull request that claims the task completes it: the task's `vt-<id>` in the PR's branch or title, a closing keyword in its body (`Closes vt-12`), or a PR attached by hand. It fires once, at the merge or when a person attaches an already-merged PR: a task reopened afterwards stays open through later attachments and PR updates, and it completes only the work nothing else holds: while any checklist item is open (a gate, an action, a step) or another pull request claiming the task is still open, the merge only lands on its ref and the task stays open for whoever finishes the rest. A PR that only mentions the task links it and never completes it, and so does a key or keyword in a PR from a repository outside the ones the project lists. |
| `run-starts-work`        | A live run starting on a backlog or unstarted task marks it in progress ([the work loop](/pm/work-loop)).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `open-pr-reviews`        | An open pull request that claims the task marks it in review. A PR that only mentions the task in its body links it and never moves its state.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `gate-date-reached`      | Every hour, ticks the `date` gates on an epic's gates checklist whose day has come (UTC calendar), with the evidence `reached <date>`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `morning-brief`          | Once a day, on the first sweep after 05:00 UTC, asks Eve for each project's narration and plan proposals ([the brief](/pm/brief#morning)).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `morning-ws-brief`       | The same sweep asks Eve for the workspace home's narration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `eve-distill`            | Adding the label hands the task to Eve's distill flow once.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `eve-summarize`          | While the label is on, task changes are coalesced into Eve summaries, capped per project per day.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

At startup, the server refreshes built-in rule definitions by name and preserves whether an administrator enabled or disabled them. Disabling a built-in applies across the workspace.

## How the runner behaves [#runner]

The runner wakes on every task change, claims each `(rule, event)` pair before acting so a rule fires once per event even across restarts, runs its actions as the actor `rule:<name>`, and never reacts to rows it wrote itself — a rule cannot loop on its own output.

## Dry-run before switching on [#dryrun]

A dry-run evaluates an event rule against recent task history, or a scheduled rule against current tasks, without applying its actions. You can also supply an unsaved definition in a stored rule's slot. Review the matches before enabling the rule.

```bash
curl -sS -X POST -H "Authorization: Bearer $VITRINKA_TOKEN" \
  "$VITRINKA_URL/api/v1/rules/12/dry-run" -d '{"events": 200}'
```

## Who may do what [#permissions]

Writing or enabling a rule is an admin action, because its actions run on everybody's tasks. Reading the rules and dry-running one inside your own project is for every member; a workspace-wide built-in needs a named project to dry-run against. Agents use `create {kind: "rule"}` and `dry_run_rule`; a rule can also be written in natural language through [Eve](/pm/eve), which produces the same document.
