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

# PR watch: keep an open pull request moving

> Fermata watches a piece's open pull request in rounds: it reads new comments and checks, fixes what it can, pushes, and leaves you what it disagrees with or cannot fix. It never merges.

Once a piece opens its pull request, the work is not quite finished. Reviewers leave comments, a check goes red, someone merges first and the branch falls behind. PR watch picks that up for you. It looks at the pull request in rounds, hands the agent what needs doing, pushes the fix, and waits for the next round. It never merges; you do.

New pull requests are watched by default. The watch lives on the piece's Done view, inside the pull request card.

## The pull request card

The Done view shows one card per pull request. Its header holds the title, the PR number, the **Watch** toggle and **View on GitHub**, in every state, so the pull request is always one click away. **Merge PR**, **View Changes** and the **⋯** menu stay below the card.

Under the header, one neutral line says what the watch is doing, for example "Round 6 · 1 of 5 this run · fixing ci / Test", with **Pause** or **Resume** and **Stop** beside it. Below that come the pull request's checks and reviews, and the round log.

Turning **Watch** off stops future rounds without changing the piece's settings. Turning it back on carries on from where it stopped.

## What a round does

Each round reads the pull request and builds a list of what needs work:

* new review comments, line threads and review bodies alike;
* failing checks;
* a branch that is behind its base;
* merge conflicts with the base.

The agent works through the list on the piece's own branch and worktree. For each item it either fixes it, or says why it disagrees or why it cannot. Fermata commits the round's changes and pushes them, then waits for the checks from that push to finish before the next round can start. A comment the watch has already handled never produces work again.

Up to two rounds run at once across all your pieces. Another watch that is ready waits, and its line reads "queued for a round slot". Marking a piece Done, archiving it, deleting it, or merging its pull request stops its watch and frees its slot for the next one.

## Runs and the round budget

A run is one stretch of watching, from the moment you start the watch until it stops. Each run gets its own budget of rounds, five by default, and the line counts against it: "Round 6 · 1 of 5 this run" is the sixth round in the piece's history and the first of this run.

Round numbers never repeat. They count up across the piece's whole history, so a watch you stop and start again carries on at the next number. The round log marks each new run with a "Watch restarted" divider and its time, and folds the earlier runs into one row you can open with **Show earlier runs**.

Pausing is not a restart. **Pause** lets a running round finish first, and paused time uses up no rounds. **Resume** carries on in the same run with the same budget. **Stop** asks first ("Stop watching this PR?"); the round log stays, and turning the watch back on starts a new run.

A run ends on its own when one of these holds. The line then reads "Watch stopped · " followed by the reason.

| Reason shown | When |
| - | - |
| "Reached the round limit" | The run spent its whole budget. |
| "Nothing left to address and checks are green" | Stop early is on and enough quiet rounds in a row passed with green checks. |
| "ci / Test still fails after repeated fixes" | The same check failed again after as many tries as the stuck limit allows. |
| "The PR was merged" or "The PR was closed" | The pull request left the open state. |
| "Stopped by you" | You pressed **Stop**. |

## Check rows

Every check row on the card says what the watch is doing about it, so a check is never red without a reason next to it. Passed checks fold into one row ("4 passed") that opens on a click; failing checks always show.

| What the row reads | What it means |
| - | - |
| "Watch: fixing in round 6" | The running round is working on this check. |
| "Watch: fixed in round 6, waiting for checks" | The fix is pushed and the new run of the check has not finished. |
| "Re-running after push" | The agent expects the check to pass once the push triggers it again. It resolves when that run finishes. |
| "Passed after re-run" | The re-run passed. |
| "Failed again after push" | The re-run failed. The next round picks it up as new work. |
| "Watch: can't fix · Flaky" | The agent judged the failure flaky. |
| "Watch: can't fix · Not caused by this PR" | The failure comes from somewhere else. |
| "Watch: can't fix · Needs a secret" | The check needs a credential the agent does not have. |
| "Watch: can't fix · no verdict" | The agent left the check without an answer. The row stays red so you look. |
| "Watch: can't fix · Reported fixed, but nothing changed" | The agent said it fixed the check, but the round changed no file. |
| "Watch: can't fix · nothing was pushed to re-run it" | The agent expected a re-run, but the round pushed nothing to trigger one. |

A failing check is always treated as work. The agent fixes it or says why it can't; a check with no answer is never quietly skipped. "Re-running after push" only counts when the round actually pushed something.

Each round in the log shows the worst row it left behind. A round never shows green while one of its checks is red.

## Conflicts and a branch behind its base

When the branch conflicts with its base, or is behind it, the round brings the base in. By default it rebases the branch onto the base, lets the agent resolve any conflict commit by commit, runs the same checks as any round, and pushes with lease protection: the push only goes through if the branch on GitHub still sits where it was when the round started. If anyone pushed in between, nothing is overwritten and the watch pauses with "Push failed". **Retry push** tries the same protected push again and never forces.

A rebase rewrites the branch, so the watch only rebases a branch that nobody else pushes to. It merges the base in instead, and says why on the card, in these cases:

| Reason shown | When |
| - | - |
| "Merged instead of rebasing: Fermata did not create this branch" | The piece works on a branch it adopted rather than one Fermata created. |
| "Merged instead of rebasing: the branch has commits from other authors" | A commit on the branch since it left the base was written by someone else. |
| "Merged instead of rebasing: pieces on an Echo never force-push" | The piece runs on an Echo. |
| "Merged instead of rebasing: Fermata could not read the branch on the remote to pin the push" | Fermata could not read where the branch sits on GitHub, so it has nothing to protect the push with. |

If the project or app sets **Conflict resolution** to Merge in Settings → Git & Worktrees, the watch always merges and states no fallback.

While a conflict is being resolved, the watch can stop and hand it to you. The card then offers **Take over in a session**, which hands you the conflict and lets the watch carry on once you resume it, and **Abort**, which undoes the rebase or merge and puts the branch back as it was.

With the watch off, a conflicting pull request shows a "Conflicts with main" row with **Rebase onto main**, or **Merge main in** when one of the reasons above applies. Both ask first and name the push before anything happens.

## When the agent disagrees

Sometimes the agent reads a review comment and decides the change is not needed. It does not make the change; it records its reason, and the review row on the card reads "The agent disagrees:" followed by that reason. That row carries two actions.

**Agree and reply…** sides with the agent and tells the reviewer. It opens a confirmation card titled "Agree and reply to" and the reviewer's name that lists every step Fermata will post to GitHub, in order, with the exact text of each. A line comment is answered in its thread; a review body or a top-level comment has no thread, so the reason goes out as a comment on the pull request that links to it. You can edit the reply before you send it. Nothing is posted until you press **Send**, and Fermata posts as you, stopping at the first step that fails. Afterwards the row reads "Agreed and replied". While the reviewer's review still requests changes it reads "Waiting for CodeRabbit to re-check" instead, with that reviewer's name. If a step fails, the row says which one and what was already posted, and offers **Open on GitHub** to finish by hand.

**Dismiss (local only)** marks the disagreement as seen and posts nothing on GitHub. Use it when you will handle the comment yourself. The row then reads "Dismissed here only", and if the reviewer still requests changes, it says so.

In the round log, a disagreement with a person reads "Needs you"; one with a bot reads as a "Note", since a bot's comment is context rather than a question for you. Bot notices are dimmed there with a "bot notice" tag.

## Settings

The watch's settings live in Settings → Pieces, under "PR watch". Each one can be set for the app, for a project, and for a single piece in its Flow Configuration sheet.

| Setting | Choices | Default |
| - | - | - |
| **Watch pull requests** | "Off" or "When a PR opens" | "When a PR opens" |
| **Rounds** | 1 to 20 rounds per run | 5 |
| **Wait between rounds** | 5 min to 1 h. The wait starts after the checks from the round's own push finish. | 10 min |
| **Address** | **Review comments**, **Failing checks**, **Branch behind base**. Merge conflicts are always addressed. | All three |
| **Whose comments** | "Everyone, bots included", "Humans only", or "Reviewer allowlist…" with the GitHub logins to follow | Everyone |
| **Stop early** | Off, or after 1, 2, 3 or 5 quiet rounds with green checks | After 2 quiet rounds |
| **Stuck limit** | Stop after 1, 2, 3 or 5 tries at the same failing check | 3 tries |
| **Before pushing** | "Push automatically" or "Ask before each push" | Push automatically |

**Watch pull requests** applies when a piece opens its pull request. Pull requests that were already open are not swept in; turn **Watch** on in their card to start one.

With "Ask before each push", each round commits locally and the watch waits for you on the card ("Ready to push"). The round clock stops until you choose **Push** or **Discard**.

For how the pull request opens in the first place, see [Review the diff and open the pull request](https://docs.fermata.run/piece/review-and-pull-request.md).


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