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

# Select items with filter

> Keep only the items in a list that pass a condition.

`breaking_changes` keeps the commits since a git ref whose subject marks a breaking change, like `feat!:`. Its `breaking` step checks each commit once.

```yaml .graph/plans/breaking_changes.yaml theme={null}
version: 2
identifier: breaking_changes
name: Breaking changes
description: The breaking changes since a release tag.
input_schema:
  type: object
  required:
  - base
  properties:
    base:
      type: string
      description: The ref to start after, such as a release tag
steps:
- id: commits
  tool_name: github__tool__git_log
  input:
    base: '{{input.base}}'
    head: HEAD
- id: breaking
  tool_name: filter
  input:
    over: '{{commits.commits}}'
    where:
      value: '{{item.subject}}'
      op: contains
      to: '!:'
finish:
  output:
    kept: '{{breaking.count}}'
    dropped: '{{breaking.dropped_count}}'
    commits: '{{breaking.items}}'
```

## Keep the items that match

`where` compares a field of each item, read as `{{item.<field>}}`, with no model call. Run the plan from a release tag:

```bash theme={null}
graph plan run breaking_changes \
  --input base=v0.15.0
```

`{{breaking.items}}` holds the 7 commits that passed, in their original order, and `{{breaking.dropped}}` the 21 that didn't:

```text theme={null}
→ filter {"concurrency":1,"mode":"where","over":28}
✓ filter 788.0µs
{
  "commits": [
    {
      "short_sha": "648d34e",
      "subject": "feat!: plans state how they finish with a required finish key…",
      …
    },
    …
  ],
  "dropped": 21,
  "kept": 7
}
```

## Ask a model about each item

When no field decides, replace `where` with an `infer` question. Each item gets its own yes/no verdict, and `concurrency` sets how many run at once:

```yaml .graph/plans/breaking_changes.yaml theme={null}
- id: breaking
  tool_name: filter
  input:
    over: '{{commits.commits}}'
    infer: 'Could this change break an existing plan, config or script? {{item.subject}}'
    concurrency: 8
```

The same run now makes one model call per commit:

```text theme={null}
→ filter {"concurrency":8,"mode":"infer","over":28}
✓ filter 6.2s
  28 calls · 22k in / 3k out · $0.04
{
  …
  "dropped": 4,
  "kept": 24
}
```

## Related guides

> **[Iterate with map and reduce](/plans/guides/map-and-reduce)**
>
> Run steps on each item that passed.

> **[Branch with route](/plans/guides/branching)**
>
> Take different steps depending on the data.

> **[Stop early with exit gates](/plans/guides/exit-gates)**
>
> End the plan when nothing passes.

> **[Run a plan](/plans/guides/run-a-plan)**
>
> Run a plan with inputs and use its result.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.