> For the complete documentation index, see [llms.txt](https://docs.tessl.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tessl.io/tutorials/setting-up-agentic-code-review.md).

# Set up Tessl Code Review

Install the Tessl Review GitHub App, enable a repository, choose when reviews run, ask for a review by comment, and configure lenses with .tessl-code-review\.yml.

{% hint style="info" %}
**Takeaways**

* Install the Tessl Review GitHub App from the Tessl web app, then enable each repository you want reviewed. Installing and enabling are two separate steps.
* Choose a trigger policy, set the review behavior, and ask for a review by mentioning `@tessl-code-review` in a comment.
* Route lenses and set the finding policy with an optional `.tessl-code-review.yml` file.
  {% endhint %}

The Tessl Review GitHub App is the supported way to run Tessl Code Review on pull requests. It reviews the exact head of a pull request and publishes one native GitHub review, running on Tessl's own infrastructure. There is no workflow to write, no token to store, and no runner to configure: you install the App, enable a repository, and reviews run from there.

Reviews run on Tessl's infrastructure. Each run mints a GitHub token scoped to the single repository it reviews, so no long-lived credential sits in your repository.

## Install and enable are two separate steps

Getting reviews on a repository takes two distinct actions, and both are required:

1. **Install the App** on a GitHub account or organization. This grants Tessl access to the repositories you select.
2. **Enable the repository** in Tessl. This decides whether reviews actually run.

Installing the App does not start any reviews. A repository the App can reach but that you have not enabled is reviewed by nothing. This is the most common point of confusion, so confirm both steps are done before you expect a review.

## Step 1: Install the App

1. Sign in to [tessl.io](http://tessl.io).
2. Select your organization, then open **Code reviews** in the sidebar.
3. Select **Connect GitHub**.
4. On GitHub, choose the account or organization to install into, and choose whether Tessl may access all repositories or a selected list.

You can install Tessl Reviewer more than once, for example on a personal account and one or more organizations. The repositories they reach share one table on **Code reviews**, each row naming the account it came from.

{% hint style="info" %}
Start every install from the Tessl web app. Do not follow a `github.com/apps/...` install link copied from elsewhere: the web app builds each install link for one person and expires it within minutes, so a shared or copied link fails by the time you use it.
{% endhint %}

## Step 2: Enable a repository

After the App is installed, return to **Code reviews** and select a repository to enable. A repository stays unreviewed until you enable it, even when the App already has access to it.

Enabling a repository is where the review policy below is set: its trigger policy and review behavior.

## Choose a trigger policy

The trigger policy decides when a review runs. Two policies are available:

| Policy             | Label                    | When it reviews                                                                                                                                               |
| ------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `open-and-command` | When opened or requested | When a pull request is opened or reopened, when a draft is first marked ready for review, and when someone requests a review by comment. This is the default. |
| `every-push`       | After every update       | The same as above, plus when the pull request is pushed to.                                                                                                   |

Start with **When opened or requested**. It reviews a pull request once when it opens and again whenever someone asks, without spending a review on every commit.

Under **After every update**, closely spaced pushes are debounced onto the latest head rather than each starting its own review. A burst of commits collapses to one review of the newest commit, so an intermediate head you pushed and quickly replaced may never be reviewed on its own. Expect coverage of where the branch settles, not a separate review per push.

**Draft pull requests are never reviewed**, under either policy. A draft is reviewed when it is first marked ready for review, and that is what triggers its first review.

## Choose the review behavior

Three separate things decide what a review does to a pull request. Keep them apart: two are Tessl settings on the repository, and the third is your own GitHub configuration, which is the only one that actually holds a merge.

**Review behavior** (**Enforcing** or **Advisory**) sets how the result is published. **Enforcing is the default.**

* **Enforcing.** Tessl publishes a verdict: it approves when nothing requires changes, and requests changes otherwise. The `Tessl Reviewer` check follows the verdict, passing on an approval and failing when changes are requested.
* **Advisory.** Tessl publishes its findings as a comment and never approves or requests changes. The check always passes.

**Auto-approve after resolved** is a separate switch, available only in Enforcing mode and off by default. When it is on, Tessl approves the pull request once its own blocking findings are resolved.

Neither setting blocks a merge on its own. A failing check or a requested-changes review only holds a pull request if your repository's **branch protection or ruleset** requires that check to pass, or requires the review's approval. Set that up in GitHub if you want a review to gate merging; leave it off and every review, Enforcing or Advisory, stays informational.

## Ask for a review by comment

Mention `@tessl-code-review` in a comment on a pull request to request a review. The comment can be on the Conversation tab or an inline comment on the diff.

Tessl reads the comment and classifies it into one of three intents. Who may trigger each one differs:

* **review**: another round on the current head. Phrases like "take another look", "review the fixes", or "check the latest commits" ask for this. It is the default: anything that is not clearly one of the other two is treated as a review. Anyone who can comment can ask for an ordinary review; it does not require write access.
* **full**: a fresh review of the whole change, including minor findings. Only a clear request for a complete, fresh, or thorough review of the entire pull request counts as full. A full review is honored only for the pull request's author or someone with write access to the repository; from anyone else it is treated as an ordinary review.
* **approve**: a clear instruction to approve the pull request. Honored only for the pull request's author or someone with write access. This is independent of the auto-approve switch: even with auto-approve off, an authorized commenter can still ask Tessl to approve.

The comment is treated as data, not as instructions, so its wording cannot change how it is classified beyond naming one of these intents.

## What gets published

A completed review publishes:

* **One native GitHub review** carrying a short judgment and the findings.
* **Findings anchored to changed lines** where GitHub allows it. A finding GitHub cannot anchor to a changed line is carried in the review body instead.
* **A check run** reporting the result on the reviewed head.

Reviews reconcile across runs. When a later review runs on the same pull request:

* a finding that has been fixed is marked resolved;
* a finding that is still present is not posted again;
* a finding that had been resolved but has returned is reopened.

If GitHub refuses the review submission, Tessl retries by publishing the findings as a plain pull request comment. That fallback is itself a write to GitHub and can also fail, for example if the installation has lost the write permission it needs. When both the review and the comment fail, the run ends as a failed publication with nothing posted on the pull request; check the `Tessl Reviewer` check run and the App's permissions if a review you expected never appears.

## Configure reviews with `.tessl-code-review.yml`

A repository can route lenses to parts of a change and set the review's finding policy with a `.tessl-code-review.yml` file at the repository root. The file is optional: without it, the App runs the built-in `standard` profile.

### How the App finds the file

The App resolves the file in two halves, and both matter:

* **Presence is decided on the default branch.** The App reads your repository's default branch and looks for `.tessl-code-review.yml` at the root. If the file is not on the default branch, the review runs the built-in `standard` profile, and nothing in the file matters, including a copy added in the pull request under review.
* **Content is read from the pull request head.** Once the file exists on the default branch, the App re-reads it at the pull request's head commit and uses that content. This is why a change to the file takes effect on the pull request that makes it, once the file already exists on the default branch.

A repository therefore opts in by merging the file to its default branch. After that, edits to the file are reviewed with the edited content on the pull request that changes them.

The two halves have to agree. A pull request that **deletes** the file from a repository that has it on the default branch leaves the App with a profile it is required to read and cannot: the review does not fall back to `standard`, and no review is published on that pull request. Remove the file in a pull request that you merge on its own, and expect the pull request doing the removal to go unreviewed.

{% hint style="warning" %}
Because the App reads the file's content from the pull request head, a contributor who can push to a pull request can change the effective review policy in the same change. Protecting only `.tessl-code-review.yml` is not enough: a lens that points at a repository-local skill (like the local lenses in the worked example below) is read from the pull request head too, so an author who cannot touch the profile can still weaken the review by editing the skill it references.

That is the whole skill, not just its entrypoint. A skill's `SKILL.md` can pull in files beside it, such as `references/`, `scripts/` and `assets/`, and those instructions carry the same weight as the ones in the entrypoint, so protecting `SKILL.md` alone leaves the rest of the bundle open.

To require separate approval for review-policy changes, protect **every repository-local source the profile trusts** with `CODEOWNERS`, not just the profile file: the `.tessl-code-review.yml` file, and the whole directory of each local lens it references rather than that lens's `SKILL.md` on its own. Then enable required code-owner approval in your branch protection or ruleset. A lens pinned to a registry reference is fixed by its version and needs no such protection. See the [`.tessl-code-review.yml` reference](/reference/configuration.md#tessl-code-review-yml).
{% endhint %}

### A worked example

```yaml
schemaVersion: 1
effort: adaptive
reviewMode: standard
requestChangesAt: major
ignore:
  - '**/*.generated.ts'
  - vendor/**
lenses:
  - ref: ./review-lenses/backend/SKILL.md
    effort: high
    globs:
      - apps/backend/**
      - '!apps/backend/**/*.generated.ts'
  - ref: tessl/code-review@0.2.0#review-security-and-privacy
    globs:
      - infra/**
  - ref: ./review-lenses/general/SKILL.md
```

`schemaVersion: 1` and a non-empty, ordered `lenses` list are required. Everything else is optional. The keys, in brief:

* `lenses[].ref`: a local `SKILL.md` path, an installed skill name, or a pinned registry reference such as `tessl/code-review@0.2.0#review-security-and-privacy`. Pin every registry reference so the review does not change when a plugin publishes a new version.
* `lenses[].globs`: repository-relative POSIX patterns selecting the files the lens sees. Patterns are evaluated in order; a `!` prefix excludes a previous match. A lens without `globs` applies to the whole change.
* `lenses[].effort`: a fixed `low`, `medium`, or `high` for that one lens.
* `effort`: how hard every lens thinks: `low`, `medium`, `high`, or `adaptive`. `adaptive` uses `medium` on a full review and `low` on a re-review.
* `ignore`: up to 64 positive patterns excluded from every lens. Each pattern excludes what it matches, so a leading `!` is rejected. `ignore` overrides lens selection.
* `reviewMode`: `strict`, `standard` (the default), or `relaxed`, the blocking strength an eligible finding needs.
* `requestChangesAt`: `critical`, `major` (the default), `minor`, or `nit`, the minimum consequence eligible to block. Low-confidence fresh findings never block, and pre-existing findings never block.

At most eight lenses run. A lens whose globs match no changed file does not run and does not count toward that limit. If no lens matches the change, the review is **skipped, which is not an approval**.

For the exhaustive key list and every edge case, see the [`.tessl-code-review.yml` reference](/reference/configuration.md#tessl-code-review-yml).

## Permissions the App holds

The Tessl Review GitHub App requests exactly these repository permissions:

| Permission    | Level | Why                                                                                                                  |
| ------------- | ----- | -------------------------------------------------------------------------------------------------------------------- |
| Metadata      | read  | Read basic repository information.                                                                                   |
| Pull requests | write | Publish the native review and its comments.                                                                          |
| Issues        | read  | GitHub serves a pull request's conversation comments through its issue endpoints, so reading them needs issues read. |
| Checks        | write | Report the review result as a check run.                                                                             |
| Contents      | write | Reconcile review threads across runs.                                                                                |

The App does not request Actions, Workflows, Statuses, Administration, or Members access. It reviews code; it does not take other actions in your repository.

Reviews run on Tessl's infrastructure. Each run uses a token minted for that run and scoped to the single repository under review, so nothing long-lived is stored in your repository.

## Troubleshooting

| Symptom                                                        | What to check                                                                                                                                                                                                                                                               |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The App is installed, but no reviews run                       | Enabling is a separate step from installing. Enable the repository in the Tessl web app.                                                                                                                                                                                    |
| A repository cannot be enabled, or shows a permissions request | The installation may be waiting for an organization owner to approve the App's requested permissions. Ask an owner to approve the request on GitHub.                                                                                                                        |
| A review was published as a comment instead of a native review | GitHub refused the review submission, so Tessl published the findings as a plain comment instead.                                                                                                                                                                           |
| A review you expected never appeared                           | Both the native review and the comment fallback can fail, for example when the installation has lost write access. Check the `Tessl Reviewer` check run and the App's permissions, then request the review again.                                                           |
| A pull request was not reviewed                                | Draft pull requests are never reviewed; mark it ready for review. A run is also skipped when no lens matches the change, which is not an approval.                                                                                                                          |
| A mention did nothing                                          | Confirm the comment names `@tessl-code-review` in its text, rather than quoting it or wrapping it in backticks. Asking for a full review or an approval also needs write access to the repository, unless you opened the pull request; an ordinary review request does not. |

## Run Code Review in your own CI

If you cannot install a GitHub App, an unsupported GitHub Action can run Tessl Code Review from a workflow you own. It is not maintained and may fall behind the CLI. See [Running Code Review in your own CI](/tutorials/setting-up-agentic-code-review/code-review-action.md).

## Related capabilities

The [`tessl code review`](/reference/cli-commands.md#tessl-code-review) CLI command runs a review locally and prints the result, and its `--publish` flag can post that review to the pull request it reviewed. Use it to try a review on a diff you already understand. The GitHub App remains the supported way to review pull requests automatically.

To turn recurring review feedback into skills, rules, tests, or verifiers, continue with [Improving agent code quality](/tutorials/improving-agent-code-quality.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tessl.io/tutorials/setting-up-agentic-code-review.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
