automaintainer/ docs
Dashboard →

Scheduler priority

When multiple features are enabled on a repo (explore mode, issue solving, PR watcher, issue scout), the scheduler processes them in a deterministic order each cycle. Only one feature dispatches per repo per cycle — no parallelism within a single repo.

Priority order

The scheduler checks features in this order for each enabled repo:

Priority Feature Consumes a run slot? Notes
1st Explore mode — auto-select Yes (via normal spawn) Falls through; the selected candidate runs as a normal spawn
Explore mode — scout Yes (takes the cycle) Kicks a scout when queue is empty; continues
2nd PR watcher No verify_pr doesn't call InsertRun; doesn't count against daily limits
3rd Issue solving Yes Spawns a fix run; one issue per cycle
4th Issue scout Yes Spawns a read-only audit run; no branch or PR
5th Normal spawn Yes Uses the repo's objective or focus

How the cycle works

For each enabled repo (one per scheduler cycle):

  1. Explore? ──► queue has candidate? → auto-select focus, fall through
              │                    ↓
              └── queue empty? → kick scout, continue (skip rest)
                              
  2. PR watcher? ──► has PR to verify? → dispatch verify_pr, continue
                              ↓
                         no PR → fall through
                              
  3. Issue solving? ──► has issue to solve? → spawn fix run, continue
                                  ↓
                             no issue → fall through
                              
  4. Issue scout? ──► enabled? → spawn audit run, continue
                            ↓
                       disabled → fall through
                              
  5. Normal spawn ──► use objective/focus → spawn run

Once any feature dispatches (sends a command to a worker), the remaining checks are skipped for that repo this cycle via continue. The repo gets re-evaluated on the next scheduler tick (~10 minutes).

Explore mode: special case

When explore auto-selects a candidate, it updates the repo's focus in the database and falls through to the remaining checks (instead of continue). This means:

  • The selected candidate's focus becomes the repo's current focus.
  • PR watcher and issue solving still get a chance to intercept the cycle.
  • If nothing else dispatches, the normal spawn fires with the explore-selected focus.

When the explore queue is empty, a scout is dispatched to survey the repo and propose new candidates. This consumes the cycle — no other feature runs until the next tick.

Standing objective overrides

A standing human objective (set in repo settings or via the API) overrides autonomous features:

Feature Blocked by objective?
Explore mode Yes — checks repo.Objective == ""
Issue solving Yes — checks repo.Objective == ""
Issue scout Yes — checks repo.Objective == ""
PR watcher No — runs regardless of objective
Normal spawn No — runs the objective

When a human sets an objective, the scheduler skips explore, issue solving, and issue scout entirely. Only PR watcher (which doesn't consume a run slot) and the normal spawn (which executes the objective) remain active.

Why no parallelism

Each scheduler cycle (~10 minutes) evaluates every enabled repo once. For a given repo:

  1. Only one run can be active at a time (the scheduler skips repos with a running run).
  2. Only one feature dispatches per cycle (each continue exits the feature chain for that repo).
  3. This prevents conflicts (two agents modifying the same repo simultaneously) and keeps the system predictable.

Behavior by feature

PR watcher — doesn't consume a run slot

verify_pr uses a lightweight command that doesn't call InsertRun. This means it:

  • Doesn't count against the daily run limit (plan limits)
  • Doesn't block a normal spawn in a later cycle
  • Can run even when the daily run cap is reached
  • Is still subject to the per-repo cooldown

Issue solving — one issue per cycle

The scheduler picks the highest-scored issue candidate (or an in-progress candidate needing additional solutions), spawns exactly one fix run, and waits for the next cycle to pick again. Multiple solutions per issue are spread across consecutive cycles.

Issue scout — read-only run

An issue scout run is tracked in the runs table (status issue_scout) but never creates a branch, commit, or PR. It audits the repo and files GitHub issues directly.

Examples

Example 1: Objective + explore enabled

repo.Objective = "Bump deps"
repo.ExploreEnabled = true
repo.PRWatchingEnabled = true

Standing objective blocks explore. Each cycle: PR watcher runs (if PRs to verify), then normal spawn runs the "Bump deps" objective.

Example 2: Explore + issue solving + PR watcher, no objective

repo.Objective = ""
repo.ExploreEnabled = true (Max)
repo.IssueSolvingEnabled = true
repo.PRWatchingEnabled = true

Cycle 1: Explore queue has candidates? → auto-select, fall through. PR watcher finds a PR → dispatches verify_pr, continue. Explore-selected focus waits for next cycle.

Cycle 2: No explore candidate (still processing). PR watcher has no new PRs. Issue solving picks an issue → spawns fix run, continue.

Cycle 3: Explore queue empty → kicks scout, continue.

Example 3: Issue solving only

repo.Objective = ""
repo.IssueSolvingEnabled = true

Each cycle picks the highest-scored issue and spawns a fix. When all issues are solved, the scheduler idles.