---
title: "Routines"
description: "Routines run an AI agent when repository events happen, on a schedule, or when you call a webhook."
section: "routines"
url: "https://forkline.dev/docs/routines"
markdown: "https://forkline.dev/docs/routines.md"
source: "src/content/docs/routines.mdx"
---

# Routines

A routine starts an AI agent task for you when something happens: a pull request opens, CI fails, a comment contains a command, a schedule fires, or your own system calls a webhook. You write it as one YAML or JSON document.

A routine can also start in two other ways. **Connect another system: give it the webhook URL. Start it yourself: Run now (web app, CLI, API).** The same limits apply to both. See [Custom webhooks](https://forkline.dev/docs/routines/spec#custom-webhooks) and [Run now](https://forkline.dev/docs/routines/testing-and-activity#run-now).

> [!TIP]
> **Agent hint**
> Defaults that surprise people, with the page that explains each:
>
> - A routine already skips drafts, forks, other bots and Forkline's own activity (`draft`, `fork`, `bots`, `self` default to `exclude`). `bots` and `self` judge the **actor**, not the author of the pull request: to skip bot-written pull requests use `when: '!pr.authorIsBot'` (on GitLab that works only when the merge request is first opened). See [Filters](https://forkline.dev/docs/routines/filters#who-to-skip-recipes).
> - `limits.maxRunsPerPr` defaults to **3** per pull request and never resets, so a `pr.updated` review stops after three runs unless you raise it (at most 50). See [Concurrency and limits](https://forkline.dev/docs/routines/concurrency-and-limits#run-limits).
> - A `ci.failed` run may belong to no pull request: add `when: 'pr.number != null'` when you need one. See [Events](https://forkline.dev/docs/routines/events).
> - `concurrency` is optional. Without it, a new event for the same pull request or issue **replaces** the older run, while pushes, schedules, Run now and custom webhooks **skip** while a run is active. See [Concurrency and limits](https://forkline.dev/docs/routines/concurrency-and-limits).
> - Every filter and every template variable must exist for every listed event. A `when` field needs only one listed event that carries it; on the others it is `null` (guard with `pr.number != null && ...`). See [Spec reference](https://forkline.dev/docs/routines/spec).

> **Note**: Routines are an experimental feature. This documentation is only visible in development mode.

```yaml routine
name: review-prs
on:
  events: [pr.opened, pr.updated]
repositories:
  include: all
filters:
  branches:
    include: [main]
agent:
  prompt: |
    Review pull request #{{ pr.number }} "{{ pr.title }}" in {{ repository.fullName }}.
```

## How routines work

```
Event arrives -> repository selected? -> filters pass? -> `when` is true? -> task starts
```

1. Forkline receives an event from your git provider and turns it into one normalized shape, the same on GitHub, GitLab and Forgejo.
2. Only your own published routines for that repository are considered. An event that matches no routine does no work.
3. Each routine's filters run in a fixed order. The first one that fails ends the run for that routine, and the reason is logged.
4. The prompt is rendered from a template and an agent task starts on the repository. Forkline's own bot never triggers a routine by default, so a routine cannot start itself in a loop.

Not every event that reaches a routine starts a task. The same delivery is handled once, the routine's [concurrency rule and limits](https://forkline.dev/docs/routines/concurrency-and-limits) can skip or replace a run, and every event gets a run record with the outcome and the reason, so you can always see why nothing happened.

## Routines vs built-in automations

Forkline also has built-in automations that you switch on per repository or account: CI auto-fix, merge-conflict auto-fix, automatic pull request review, and `@forkline` mention commands. Routines are separate from them. Routines do not replace the built-ins, and the built-ins do not read your routine files.

- **Built-ins** are settings with fixed behavior, for example the CI auto-fix attempt limit and its collected failure logs.
- **Routines** are your own rules in a file: you choose the events, filters, prompt and limits, and you can test them before they run.

**If a built-in automation and a routine react to the same event, both run.** For example, with CI auto-fix on and a routine on `ci.failed` for the same repository, a failed CI run starts two tasks. Forkline does not merge them and does not pick one. To avoid double work, turn the built-in off for that repository (repository automation settings) or narrow the routine with [filters](https://forkline.dev/docs/routines/filters) and [repository selection](https://forkline.dev/docs/routines/repositories). The publish dialog warns when a built-in may run on the same events.

## Pages

- [Spec reference](https://forkline.dev/docs/routines/spec): every field of a routine file.
- [Events](https://forkline.dev/docs/routines/events): the events a routine can listen to.
- [Filters](https://forkline.dev/docs/routines/filters): conditions that decide whether an event starts a run.
- [Prompt templates and variables](https://forkline.dev/docs/routines/templates): what the prompt can read.
- [Repository selection](https://forkline.dev/docs/routines/repositories): which repositories a routine runs on.
- [Concurrency and limits](https://forkline.dev/docs/routines/concurrency-and-limits): how runs interact and the caps that apply.
- [Test, backtest, recent events, run history](https://forkline.dev/docs/routines/testing-and-activity): check a routine and read what it did.
- [Validation errors](https://forkline.dev/docs/routines/errors): the 422 format and how to fix it.
- [Routines as code with the CLI](https://forkline.dev/docs/routines/cli-workflow): keep routine files in git and sync them.
- [Cookbook](https://forkline.dev/docs/routines/cookbook): complete routines to copy.

## Next steps

- [Trigger Policies](https://forkline.dev/docs/automation/trigger-policies)
- [CI Auto-Fix](https://forkline.dev/docs/automation/ci-auto-fix)
- [Bot Mentions](https://forkline.dev/docs/automation/bot-mentions)
- [Webhooks](https://forkline.dev/docs/automation/webhooks)
