← Docs
RUNNING TASKS · VERSION 1.0

Automated review

What a reviewing session is, how it differs from a coding session, and what to expect on this machine.

When a project has automated review switched on in Meshly Build, a completed task does not sit and wait for a person straight away. Build dispatches a review to a Build Station, the Station spawns a session to read the diff, and the reviewer returns a verdict. A human still decides what happens to the task — the reviewer's verdict is an input to that decision, not a replacement for it.

This page is about what that looks like on the machine. The rules about when a review is dispatched, and what a verdict means, live in Meshly Build.

Note: Off unless the project turns it on

Automated review is off by default and is enabled per project in Meshly Build, not here. Nothing on this Station switches it on, and a Station with no review-enabled projects never spawns a reviewing session.

A reviewing session is not a coding session

The Station shows Reviewing as its own state, separate from an agent writing code, and the Dashboard counts working and reviewing separately.

This distinction matters more than it sounds. A reviewer reads and reasons; it does not edit files, run builds, or emit the steady stream of output a coding session produces. It therefore looks idle while working normally. Before the two states were told apart, a task sitting in Review with an agent apparently busy on it was the most common reason people suspected the Station was stuck.

Coding session Reviewing session
Writes to the working tree Yes No
Holds the project lock Yes No
Waits for the project lock Yes No
Counts against Concurrent sessions Yes Yes
Shown as Working Reviewing

Reviews do not queue behind the work they review

A reviewer neither waits for the checkout nor holds it against anyone else, so:

  • A review runs alongside the coding session in the same project.
  • Two reviewers can run in one project at once.
  • A review is never refused because the project is busy.

The reason is what a review does. It reads the working tree and writes nothing to it, so it cannot corrupt what a coding session is doing, and serializing the two bought no safety. It did cost reviews: eight review requests were destroyed on 2026-08-12, and one of three on 2026-08-14, each waiting behind a coding session with far more time left than the review had.

Reviews still count against the station-wide ceiling. See Concurrency limits.

What the Station checks before spawning a reviewer

Two guards, both there because the failure they prevent actually happened.

The right repository. A reviewer resolves its folder from the task's project, not from the agent. An agent configured across several projects used to review whichever checkout happened to be listed first, which meant reading an empty diff and judging nothing. If the Station cannot determine the correct folder it refuses to start rather than review the wrong tree — a confident review of the wrong code is worse than no review.

The review is still wanted. A review has a deadline. Build stops waiting at that deadline and records the outcome. Queued requests are flushed when a Station reconnects, which is what makes an offline Station recoverable — but a Station offline overnight was spawning full reviewer sessions for reviews that had been closed hours earlier, each producing a verdict too late to record. The request is now checked against its deadline, and against the review itself, before anything is spawned.

Commits are registered as a session finishes

A review needs to know which commits belong to the task. A session registers its commits as it finishes, before the review is requested — the working tree is read from the baseline recorded when the session was spawned through to HEAD.

Two consequences worth knowing:

  • A reviewer registers nothing. It writes no code, and a reviewer that reported an empty commit set used to retire the commits the author had just registered — destroying the diff under review, and any later review of that task with it.
  • If a diff falls back to a cumulative range rather than only the new work, the reviewer is told so, rather than being left to claim it read only the new changes.

Rubric criteria reach the reviewer

When a project's review charter defines rubric criteria, those criteria are rendered into the reviewer's prompt, keyed, so each annotation comes back tied to the criterion it answers. Without that, whether any annotations came back at all varied from run to run, and two rounds of the same task could not be lined up against each other.

Running the checks your repository already declares

A reviewer reads. Until now that was all it could do, so every statement about whether the code runs came from the agent that wrote it — the one party a review exists to check.

A review charter can now ask for two more things, and the Station is what carries them out.

Your repository's own checks, run here. The Station reads the checks your repository declares in .github/meshly-review.yml, runs them in the worktree it already provisioned, and reports what each returned. It runs the command your repository supplies; it never composes one.

# .github/meshly-review.yml
gates:
  unit: npm run test:unit
  bicep-validate: az bicep build --file infra/main.bicep

Your CI's results, read. Nothing is executed for these — your host already ran them. The Station reads the checks on the pull request for the branch under review and passes them on.

Warning: Bounded by your declaration, and only yours

A charter naming a check your repository has not declared is refused when it is saved, not quietly ignored. A project this Station has never reported a declaration for permits nothing at all rather than everything.

This is deliberately not general shell access and is not a step towards it. The charter chooses which of your declared checks runs. What each one does is your repository's business, written in your repository.

A check that did not run is never reported as one that passed

Each check comes back as passed, failed, or not assessed with a reason — and the last of those is the point. A missing result reads as a pass to whoever finds it later, so nothing is ever simply left out.

What happened Recorded as
Ran, exit 0 Passed
Ran, non-zero exit Failed
Crashed, or exceeded its own time limit Errored, with which
The review's time budget ran out first Not assessed — deadline exhausted
The checkout was not at the commit under review Not assessed — worktree not at head
Your CI check is still pending, skipped or cancelled Not assessed — never a pass

That last row matters more than it looks: a check that has not finished is not a check that succeeded, and it is not reported as one.

Checks run against the commit under review, or not at all. If the checkout has moved on, the Station records that rather than running against different code — a result carrying a commit it was not produced from is worse than no result, because a verdict can cite it.

A failing or unavailable check never stops the review. The reviewer still decides, and says what it could not verify. Checks share a portion of the review's deadline rather than all of it, so a slow one cannot leave the reviewer without time to think.

What you can do from here

Very little, deliberately — review is Build's decision, and the Station executes it.

  • Watch it: the live console works for a reviewing session exactly as it does for a coding one. See Watching the live console.
  • Stop dispatch to this machine: set the project to be driven by hand. See Projects you drive by hand. That stops reviews as well as tasks.
  • If a check reports not assessed: that is the honest answer, not a fault. The reason says which — most often your repository declared nothing to run, or the branch has no pull request for the CI read.
  • If a review seems stuck: check the session state first — Reviewing is quiet by nature. Then see When an agent stalls.

Warning: Requires Meshly Build 3.8.0 or later

The review behaviour described here depends on the dispatch contract introduced in Build 3.8.0. Against an older Build, reviews may be dispatched but will not complete correctly.

Still stuck?

If this page did not answer the question you arrived with, tell us what it was. That is a documentation bug on our side, and we would rather fix it than have you guess.