> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Automations

> Start factory sessions from GitHub, Linear, Jira, schedules and webhooks, with queueing, rate limits, per-run budgets and pull-request reviews.

An automation binds a trigger to a factory: when the trigger fires, the automation renders its prompt template and starts (or continues) an agent session in that factory. Manage automations under **Factories** > the factory > **Automations**.

## Triggers and actions

| Field                    | Purpose                                                                                                                                                                                                                                                    |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `trigger.provider`       | `github`, `linear`, `jira`, `slack`, `schedule` or `webhook`.                                                                                                                                                                                              |
| `trigger.event`          | Provider event such as `pull_request.opened`, `issues.labeled`, `Issue.create`, or a cron expression for `schedule`.                                                                                                                                       |
| `trigger.filter`         | Optional matchers: `label`, `repository`, `action`, `conclusion`, `cron`.                                                                                                                                                                                  |
| `action.mode`            | `new_session` starts a session per run; `continue_session` reuses the newest ready or paused session of the automation.                                                                                                                                    |
| `action.prompt_template` | Prompt with `{{title}}`, `{{body}}`, `{{url}}`, `{{number}}`, `{{repository}}`, `{{ref}}`, `{{labels}}`, `{{sender}}`, `{{action}}`, `{{event}}` plus the triage variables `{{issue_type}}`, `{{priority}}`, `{{owner}}`, `{{route}}`, `{{duplicate_of}}`. |
| `action.open_pr`         | Opens a pull request from the session workspace after a successful run and comments on the source issue.                                                                                                                                                   |
| `action.post_review`     | Posts the agent's structured findings as a pull-request review (see [Pull-request reviews](#pull-request-reviews)).                                                                                                                                        |
| `action.auto_fix`        | After a posted review with findings, continues the session to apply the fixes and pushes a commit to the pull-request branch.                                                                                                                              |

GitHub events reach the platform through the GitHub App webhook; Linear and Jira through their connection webhooks. `POST /v2/automations/{automation_id}/trigger` fires an automation manually with caller-supplied variables, which is also how the generic webhook adapter works.

## Runs, queue and limits

Every invocation is recorded as an **automation run** in `workspaces.automation_runs`. A run moves through `queued` → `running` → `completed` or `failed`, or is recorded as `skipped` without a session.

`Automation.limits` controls how invocations turn into sessions:

| Limit                      | Default    | Behavior                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `max_concurrent_runs`      | `1`        | Runs above this number wait in the queue. The control plane drains the queue oldest-first whenever a run finishes and on every reconcile sweep (about once a minute), holding a per-automation lease so several platform-api replicas never admit more runs than the limit.                                                                                         |
| `max_invocations_per_hour` | `20`       | Counted over a rolling hour across queued, running, completed and failed runs. Invocations above the cap are recorded as `skipped` with `skip_reason: rate_limited` and never create a session.                                                                                                                                                                     |
| `run_budget_usd`           | `0` (none) | Creates a one-time `API_KEY`-scoped budget of that amount on the session key of each run, so the gateway stops the run's model calls at the cap. `continue_session` runs keep the budget of the reused session.                                                                                                                                                     |
| `policy_profile_id`        | unset      | A [policy profile](/docs/ai-studio/ai-engineering/agent-sessions/policy-profiles) applied after the workspace and factory profiles as a mandatory ceiling for sessions this automation starts. It can only tighten agents, models, templates, repositories, connections, hours, approvals and repository-config trust; egress stays a factory-level network policy. |

Disabling an automation leaves its queued runs waiting until it is enabled again; deleting it fails them. A run whose session never starts within 40 minutes, or whose session run ended without the control plane noticing, is settled by the reconcile sweep.

The **Activity** view under the automation lists queued, running, completed, failed and skipped runs with their linked sessions and posted reviews; the automation row shows how many runs are queued and running and a 30-day sparkline of daily invocations. `GET /v2/factories/{factory_id}/automations/activity` returns the same counts per automation.

## Pull-request reviews

The **Code review** and **Security audit** templates set `action.post_review`. For such automations the run prompt is extended with an output contract, and when the repository contains a `REVIEW.md` at its root (read at the pull request's head ref), its content is added to the prompt as the repository's review guidelines.

The agent ends its final message with a JSON block:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "summary": "One paragraph verdict.",
  "findings": [
    {
      "severity": "high",
      "confidence": 0.9,
      "cwe": "CWE-79",
      "file": "src/render.ts",
      "line": 42,
      "rationale": "User input is interpolated into HTML without escaping.",
      "suggestion": "Escape the value or use the template helper."
    }
  ]
}
```

| Field                     | Meaning                                                                                      |
| ------------------------- | -------------------------------------------------------------------------------------------- |
| `severity`                | `critical`, `high`, `medium`, `low` or `info`; unknown values become `medium`.               |
| `confidence`              | 0–1 (percentages are accepted).                                                              |
| `cwe`                     | Optional CWE identifier for weaknesses.                                                      |
| `file`, `line`            | Path relative to the repository root and the line in the pull request's version of the file. |
| `rationale`, `suggestion` | Why it matters and the concrete fix.                                                         |

The block is parsed leniently (last fenced JSON block, bare object or bare array). Findings are stored on the run and posted as one pull-request review through the GitHub App: findings with a file and line become inline comments, the rest go into the review body, and when GitHub rejects a line outside the diff the review is re-posted with every finding folded into the body. Free-text final messages without a JSON block are posted as the review summary.

With `action.auto_fix`, a review with at least one finding above `info` continues the same session with the findings to fix; when that run completes, the platform commits the workspace and pushes `fix: apply review findings` to the pull-request branch (same-repository branches only). The review URL and fix commit appear on the run. Merging stays a human decision.

Reviews require a GitHub repository credential: the GitHub App installation or a personal access token on the factory's connection. GitLab merge-request discussions are not supported yet; review automations on GitLab repositories fail with an explanatory error.

## Factory as code

`factory.yaml` `automations[]` carries the same `action.post_review`, `action.auto_fix` and `limits` fields as the API; Terraform `orq_automation` exposes them as `action` and `limits` attributes.

## API

| Method and path                                       | Purpose                                                                                        |
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `POST /v2/factories/{factory_id}/automations`         | Create an automation (`limits` optional; defaults apply).                                      |
| `GET /v2/factories/{factory_id}/automations`          | List the automations of a factory.                                                             |
| `GET /v2/factories/{factory_id}/automations/activity` | Queue depth, running and outcome counts, daily invocations per automation.                     |
| `PATCH /v2/automations/{automation_id}`               | Update display name, trigger, action, visibility, enabled or limits.                           |
| `POST /v2/automations/{automation_id}/trigger`        | Fire the automation; the response carries the recorded run (`running`, `queued` or `skipped`). |
| `GET /v2/automations/{automation_id}/runs`            | List runs with sessions, errors and reviews, newest first.                                     |
| `DELETE /v2/automations/{automation_id}`              | Delete the automation and fail its queued runs.                                                |
