> For the complete documentation index, see [llms.txt](https://docs.duku.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.duku.ai/integrations/github-check-runs.md).

# GitHub check runs

Gate merges on the exploration result with a native GitHub check run.

Duku can post a **GitHub check run** on the pull request it explores - a native pass/fail check you can require in branch protection to gate merges on the exploration result. It replaces polling `batch(id) { status }` from your CI: GitHub shows the check move from *in progress* to *passed*, *failed*, or *timed out*, and the PR merge box reflects it automatically.

The check is posted by the **Duku AI GitHub App** - the same App that posts PR comments - so, as with comments, no GitHub token is handled in your CI job.

{% hint style="info" %}
The check run and the sticky PR comment are two independent surfaces built from the same exploration. The comment is the human-readable summary; the check run is the machine-readable merge gate. You can use either or both.
{% endhint %}

### Prerequisites

* The [Duku AI GitHub App](https://github.com/apps/duku-ai) installed on the repository - see [Triggering explorations from any CI](/integrations/triggering-explorations-from-any-ci.md) for setup guidance.
* The App granted the **Checks: Read & write** permission for your organisation. If your organisation installed the App before check runs were available, GitHub prompts an organisation owner to review and approve this added permission. Until it is approved, explorations run normally but no check appears - and once it is approved, Duku retroactively creates and concludes the check for in-flight explorations, so you do not need to re-run anything.

### Enabling the check

There is no separate flag. Duku creates a check run automatically whenever an exploration is started with **server-managed PR comments** and pull-request context - that is, all three of:

* `serverManagedComment: true`
* `githubRepository` (in `owner/repo` form)
* `githubPrNumber`

If you already use the `preview` GitHub Action, or the any-CI preview flow, or the any-CI environment flow in PR-gate mode, you are already requesting the check. The `environment` GitHub Action does not request a check run.

### Making it a required check

The check appears on the pull request as:

```
Duku Exploration (<your product name>)
```

To block merges until it passes, add that check to your branch protection rule (GitHub -> **Settings -> Branches -> Branch protection -> Require status checks to pass**).

{% hint style="warning" %}
The check name is keyed to the **product name**, not the repository or PR. If you rename the product in Viewport, the check is renamed too - update your required-checks list to match, or the gate silently stops applying.
{% endhint %}

### How the result maps

| Exploration                                       | Check conclusion                                                                                                   |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Completed                                         | **success** - even when issues were found; the issues are listed in the check output rather than failing the check |
| Failed                                            | **failure**                                                                                                        |
| Still running after the timeout (default 120 min) | **timed out** - deliberately blocks the merge, because an unfinished exploration must not satisfy a required check |

* The check output summarises the run counts and the **Issues** seen on the PR (new vs. pre-existing), with a link to the exploration dashboard - the same data as the PR comment.
* If a batch finishes after it timed out, the check re-converges to the real result automatically.
* To clear a timed-out or failed check, push again or re-run the workflow: a fresh exploration supersedes the previous check on the new commit.

### Replacing the polling gate

If you currently gate with a `duku_wait`-style poll of `batch(id) { status }` (see [Triggering explorations from any CI](/integrations/triggering-explorations-from-any-ci.md)), the check run replaces it: keep the explore call, drop the wait step, and require the `Duku Exploration (...)` check in branch protection instead. The check is maintained server-side, so your CI job can exit as soon as the exploration is kicked off.
