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

# Dynamic CI

> Run only the CI jobs a pull request needs, decided from your own CI history.

<Warning>
  Dynamic CI is in **private beta**. Recommendation quality is still improving,
  and setup details may change between releases. Reach out on
  [Slack](https://slack.trunk.io) to have it enabled for your organization.
</Warning>

Dynamic CI decides which CI jobs a pull request actually needs to run. For each
job, it weighs that job's history, what the pull request changed, and where the
pull request sits in a stack. Anything it can safely skip, it skips, so you
spend less on CI and wait less on each push.

## What it helps with

Traditional CI was built on a zero-trust model. Engineers couldn't be trusted to run the right tests before pushing, and reviewers wanted a green run before they would look at the code. So every push ran everything.

Agentic engineering has rewritten those rules. Agents happily run tests locally, but they also iterate on pull requests constantly. Under the old model, every one of those pushes restarts your full CI suite, and you pay for it in runner time and wait time.

The ideal CI run executes only the tests that are going to fail. Short of precognition, Dynamic CI gets as close as it can by deciding, push by push, which jobs a pull request still needs:

* **A maturing pull request runs less.** As a pull request becomes more solid, fewer jobs need to run, and earlier results tell Dynamic CI whether a job needs to be retested at all.
* **Small tweaks don't restart everything.** A job that just passed doesn't need to run again because someone addressed a review comment or made a minor change.
* **Failures always get a second look.** A job that just failed is rerun to confirm the fix actually works.
* **Stacks are verified as a stack.** Pull requests in the middle of a stack are likely to merge together, so they don't each need full individual verification.

The goal is simple: run the minimal set of jobs needed to get a pull request into the merge queue, and rely on the merge queue as the ultimate safeguard against regressions.

## Backed by the merge queue

A skip on a pull request is only safe if something stronger stands behind it.
With a Trunk [merge queue](/merge-queue/merge-queue), your `main` is protected: the queue
tests the exact commit about to land, and it holds a higher bar than the pull
request.

* **The merge queue skips nothing by default.** On a merge-queue run, Dynamic CI
  skips a job only when a paths filter you configured says the change does not
  touch it. With no paths filter, every job runs.
* **The engine learns from the queue.** When a job the pull request skipped
  fails in the merge queue, Trunk records it as a false skip. The engine learns
  from those outcomes, so its skip recommendations get more accurate over time.
  A job that rejected a pull request from the queue always runs on that pull
  request's next push. See [Merge queues](/ci/dynamic-ci/merge-queue).

## How it decides

For every job, Dynamic CI combines several independent kinds of evidence into
one verdict, **run** or **skip**:

* **The job's own track record**: how often it fails, and how much it costs to run.
* **What the change touches**: how often changes to these files have broken this
  job before.
* **This pull request so far**: whether the job has already run on it, and how it
  went.
* **Where the pull request sits**: whether other pull requests are stacked on top
  of it, and whether the job gates the merge.
* **What the merge queue found**: recent merge-queue failures for this pull
  request, and skips the queue later caught.
* **What you told it**: your paths filters, per-job policies and overrides always
  take precedence.

Everything it learns comes from your organization's own CI history. The system
evolves to keep your pull requests moving quickly.

It is also built to fail safe:

* **A job with no history always runs.**
* **If Trunk is slow or unreachable, everything runs.**
* **Learning mode comes first.** A repository starts in **Learning** mode, where
  Trunk records a verdict for every job but skips nothing. Switch it to
  **Enforced** once the recommendations look right.

## Get started

Dynamic CI is in private beta, so [reach out to Trunk](https://slack.trunk.io)
for access. Then set up Trunk CI, add Dynamic CI to your CI provider, and turn
on enforcement. See [Getting started](/ci/dynamic-ci/getting-started).

## Feedback

Dynamic CI is being tuned against real repositories during the beta, and the
fastest way to change it is to tell us what it got wrong. Reach out on
[Slack](https://slack.trunk.io).
