0 means it passed. Anything else means it failed.
Gates live under environment.gates in .bellows.yaml. For image, setup and cache, see Configure your repo.
.bellows.yaml
When gates run
1
While the agent works
The agent can run any declared gate by name, as often as it likes, and read the output. It is told to run the gates that cover its change before it pushes.
2
When the agent finishes
Bellows runs every declared gate once, in the order you wrote them. Gates marked
on_demand are skipped. A gate that the agent already ran unfiltered, and that passed on exactly the final tree, is reused instead of run again.When a gate fails
A failing gate fails the run. The task page shows the badge gate failed and a Verification failed pill. By default, Bellows then starts an automatic repair round: the agent gets the failing gate’s name and output and tries to fix it. The limit is the Gate repair rounds setting on the executor. The default is 3, the maximum is 10, and 0 turns repair off. The limit is fixed when the task is created. A repair round that leaves the tree unchanged ends the loop, because the same gate would fail the same way.If repair rounds run out, the work still ships as a draft pull request, unless your repo sets
policy: gates: required. Then nothing is published until the gates pass. See Policy and reviewers.Gate options
You can declare up to 16 gates. Values may be bare,
'single' or "double" quoted. There are no escape sequences. If a command needs real quoting, put it in a script in your repo and call the script.
On-demand gates
Useon_demand: true for checks that are too slow or too specific to run on every task, such as an end-to-end suite. The agent runs it only when its change touches what the gate checks, and a failure never fails the task.
Filters
Withfilter: true the agent can run part of a suite. Your command must read $GATE_FILTER, or the filter does nothing.
on_demand gate with a full gate that has the same command and no filter.
Where results show
Open the task and find the Verification panel. Each gate has a pill and, once it has run, its exit code and output. The panel shows the newest run only. A failed gate starts open, and its output has a Copy button.Tips for fast, reliable gates
- Put the cheapest check first (
buildortypecheck) so failures show up early. - Set a
timeoutfor each gate. A hung test then fails with a clear exit code instead of eating the run. - Make gates deterministic. Pin versions, avoid the network, and don’t depend on wall-clock time.
- Install once in
setup, not in each gate. Usecachefor package caches. - Run the same command locally in the same image before you commit it:
docker run --rm -v "$PWD":/w -w /w golang:1.25 sh -c 'go test ./...'. - If a gate needs a database, declare it as a service.
- Don’t let a gate rewrite tracked files. A formatter that edits the tree voids the reuse of later gates.