<!--
Sitemap:
- [Installation](/installation)
- [Upgrading](/upgrading): Version-specific steps for upgrading an existing Bento install.
- [Concepts](/concepts)
- [Build your first pipeline](/tutorials/pipeline-args)
- [Target a specific issue or PR from a URL](/tutorials/url-targeting)
- [Keep state across runs](/tutorials/pipeline-state)
- [Fire a pipeline on a schedule or on demand](/tutorials/schedule-and-fire)
- [Deploy a box to Railway](/tutorials/deploy-to-railway)
- [Operate a hosted daemon](/tutorials/operate-a-hosted-daemon)
- [Configuration](/configuration)
- [Members](/members)
- [Knowledge base](/knowledge-base/)
- [Method and delivery](/knowledge-base/modes)
- [Config](/knowledge-base/config)
- [MCP](/knowledge-base/mcp)
- [Pipeline configuration reference](/pipelines/config)
- [Filters](/pipelines/filters)
- [Triggers](/triggers/)
- [GitHub trigger](/triggers/github)
- [Linear trigger](/triggers/linear)
- [Webhook trigger](/triggers/webhook)
- [Schedule trigger](/triggers/schedule)
- [Manual trigger](/triggers/manual)
- [Traces](/pipelines/traces)
- [Slack](/integrations/slack)
- [Public access](/public-access)
- [Context engineering](/context-engineering)
- [Best practices](/best-practices)
- [Troubleshooting](/troubleshooting)
- [Architecture](/architecture/vision)
- [Workspaces](/workspaces)
- [Authentication](/authentication)
- [Identity](/identity)
- [Security](/security)
- [References](/references)
- [Changelog](/changelog): Bento release history.
- [CLI reference](/cli/)
- [Setup](/cli/setup)
- [Secrets](/cli/secrets)
- [Lifecycle](/cli/lifecycle)
- [Sandbox image](/cli/image)
- [Sandboxes](/cli/sandbox)
- [Observability](/cli/observability)
- [Diagnostics](/cli/diagnostics)
- [Triggers](/cli/triggers)
- [Workbench](/cli/workbench)
- [Auth](/cli/auth)
- [Knowledge](/cli/knowledge)
- [Evals](/cli/evals)
- [Bento](/index)
- [Runtime wrapper](/architecture/runtime-wrapper)
- [Skill evolve](/architecture/skill-evolve)
-->

# Filters

Every event-based trigger — `github`, `linear`, and `webhook` — supports a `filter:` block. A filter lets several pipelines subscribe to the same event type under different criteria, and the daemon enqueues only the pipelines whose filters pass.

A `filter:` block combines its conditions with AND. Every condition passes before the pipeline fires.

## `filter.repos`

An allow-list of GitHub `repository.full_name` values. The daemon drops an event from a repository outside the list.

```yaml
filter:
  repos: [acme/frontend, acme/backend]
```

This filter applies only to a `github` trigger.

## `filter.labels`

An allow-list of label names. The event fires only when its subject carries at least one listed label. The subject is the pull request or the issue the event is about.

```yaml
filter:
  labels: [review:agent]
```

For a `github` trigger, the daemon reads the labels off the payload. For a `linear` trigger on an agent-session event, the session payload carries no labels, so the daemon reads the issue from Linear once for each event, with the session principal's token. A lookup that fails declines the event under `filter_unavailable` instead of treating the issue as unlabelled.

`labels`, `not_labels`, and `states` are also accepted on a [per-event entry](./config#linear). Use that to gate one event and not another.

## `filter.not_labels`

A deny-list of label names. The event fires only when its subject carries none of the listed labels.

```yaml
filter:
  not_labels: [deferred, underspecified]
```

## `filter.states`

An allow-list of state names. The event fires only when its subject's state is one of those listed. A GitHub pull request is `open` or `closed`. A Linear issue is in a workflow state that the team names.

```yaml
filter:
  states: [Candidate, In Progress]
```

## `filter.when`

Equality checks against nested payload paths. Every entry matches before the pipeline fires.

```yaml
filter:
  when:
    review.state: approved
    pull_request.user.login: my-bot   # PR must be authored by the bot
```

Paths use dot notation to traverse nested JSON. The check is strict equality (`===`).

## `filter.not`

Equality checks against nested payload paths. If any entry matches, the daemon drops the event. Use this filter to stop the bot from reacting to its own events.

```yaml
filter:
  not:
    review.user.login: my-bot         # ignore reviews submitted by the bot
    comment.user.login: my-bot        # ignore comments from the bot
```

## `filter.mentioned`

This filter checks whether the configured GitHub login of the daemon appears as an `@mention` in the text body of the event, such as a comment body or a review body.

```yaml
filter:
  mentioned: true    # fire only when @-mentioned
  # or
  mentioned: false   # fire on all events
```

Two pipelines on the same event type split by mention status. One observes, and one acts:

```yaml
# pr-review-comment.yaml — observe all inline comments
trigger:
  github: [pull_request_review_comment.created]
  filter:
    not: { comment.user.login: my-bot }
    mentioned: false
agent: reviewer
skill: pr-comment-review

# pr-review-comment-mentioned.yaml — act when @-mentioned
trigger:
  github: [pull_request_review_comment.created]
  filter:
    mentioned: true
agent: editor
skill: pr-comment-act
```

## `filter.assignee`

This filter checks `payload.assignee.login`. The special value `bot` resolves to the configured GitHub login of the daemon.

```yaml
filter:
  assignee: bot     # only fire when the event is assigned to the bot
```

## `filter.participants`

An allow-list of GitHub logins. The event fires only when at least one listed login left a review, a review comment, or an issue comment on the pull request. The special value `bot` resolves to the configured GitHub login of the daemon, as it does for `assignee`.

Unlike every other filter, this one costs a GitHub API call, so the daemon evaluates it last, after the free filters pass. A lookup failure declines the run instead of treating the pull request as quiet.

```yaml
filter:
  participants: [bot, my-reviewer]     # only fire once a listed login has spoken
```

This filter applies only to a `github` trigger.

## Example: combined filter

Every condition in the block passes together. This example fires only for an approved review on a bot-authored pull request, where a person and not the bot submitted the review:

```yaml
trigger:
  github:
    - pull_request_review.submitted
  filter:
    when:
      review.state: approved
      pull_request.user.login: my-bot
    not:
      review.user.login: my-bot
```
