Configuration

Retry limits

Control how long the agents work on an issue before they give it back to a person.

Overview

A mission runs as a loop. The Builder pushes a commit, CI runs, the Reviewer reads the diff, and QA verifies the acceptance criteria. If one of these gates fails, the mission goes back to the Builder with the feedback from that gate. Then the loop runs again.

Two types of limit stop the loop and give the issue to a person:

LimitWhat it countsDefault
Oscillation limitsRounds in which a gate fails the same way again2
Outer ceilingAll Builder attempts, whatever the result25
tip

An oscillation is the same failure, repeated. For example, the Reviewer gives the same blocking comment in consecutive rounds, or QA fails the same criterion in consecutive rounds. A gate that fails in a different way each round makes progress, and those failures do not count toward the limit.

In practice, the oscillation limits are what stop missions, because a stuck mission usually fails the same way each time. The ceiling is a backstop. It is much higher than the oscillation limits, so it rarely stops a mission.

note

If you increase only maxRetries, usually nothing changes. If missions stop earlier than you want, the cause is almost always an oscillation limit.

Configuration

Add a retries block to the ship.yml at the root of your repository. Every field is optional. A field that you leave out keeps its default.

version: 1

retries:
  qaOscillationLimit: 5
  reviewOscillationLimit: 4

deployments:
  # ...
FieldMeaningDefaultRange
reviewOscillationLimitNumber of review rounds that ask for changes before the mission stops21 to 50
qaOscillationLimitNumber of failed QA rounds before the mission stops21 to 50
ciOscillationLimitNumber of consecutive CI failures with the same signature before the mission stops21 to 50
maxReviewGrantsExtra review rounds that SHIP allows when it finds that the work makes progress30 to 50
maxRetriesOuter ceiling on Builder attempts251 to 200

SHIP changes a value outside its range to the nearest end of that range. A value that is not a number gets the default. An invalid entry can never turn a limit off.

When changes take effect

SHIP reads retries from ship.yml on your main branch, as it does the agents block. A pull request cannot change the limits for its own review, so a new value applies after the change merges.

Each mission reads its limits when it starts and keeps them until it ends. If you edit ship.yml while a mission runs, the change applies to the next mission, not to the current one.

Choosing values

If your codebase needs more rounds to get to a correct result, increase the oscillation limits. For example, acceptance criteria can depend on integration behavior that takes a few attempts to get right. Each extra round is a full agent run, so each round costs money.

If you prefer to see a stuck issue early, keep the defaults. It usually costs less to give the issue to a person after two identical failures than after five.

warning

A higher limit does not make a stuck mission succeed. If the Reviewer gives the same comment again and again, more rounds usually give the same result. The limits give time to work that improves from round to round, not to a problem that the agents cannot solve.

What happens at the limit

The console shows the mission as Needs attention, and the Linear issue moves to In Review. SHIP posts the reason on the issue. The reason names the gate that stopped the mission and gives the feedback from the last round. The pull request stays open. You can take over the branch, or you can reply on the issue to send the agents back with new instructions.

A reply sets the counters back to zero. The limits apply to each period of autonomous work, not to the full life of the issue.

How is this page?

On this page