Autopilot
Autopilot hands the manager chat the queue for a while. The five power stops, max_parallel and failures_in_row, park, skip and retry, the no-autopilot and operator labels, and the report.
01what it is#
Autopilot lets the operator hand a project's manager chat the go and approve presses for a while. Only the operator switches it on, from the window or with a Discord press. The conductor's autopilot tools work only while it is on, for that project and that conversation, and they press through the same functions the window does, marked as autopilot's.
The conductor can propose it with propose_autopilot_on and propose_autopilot_off, which are cards the operator presses. The on card takes the project, the conversation, a queue, an until time, max runs, max parallel, max failures in a row and a power.
When it is switched on the desk checks the settings:
- The queue is exactly one of a phase, a list of tickets, or everything ready.
- The until time is still to come, and max runs and max failures in a row are at least 1.
- The power is a stop from 1 to 5. With none given it is 3.
The desk then registers a wake for the chat, says so in the thread, and tells the conductor with the autopilot brief for that power. The state is kept in autopilot.json. A saved state with no valid power reads as 3, or as 4 when it carries the old sync switch.
02power stops#
The power slider has five stops. A new session starts at stop 3. The names are in the code twice, as autopilotStops in the conductor package and as powerName in the desk package, and tests check this page against both. What the conductor may do alone at each stop is the line autopilotStopLine puts in its brief. Each stop includes everything the stops before it allow.
- 1 · launches. The conductor drafts launch cards and presses go on them with
autopilot_go. It never callsautopilot_approve: every gate waits for the operator. It doesn't propose a sync either, since main is left for the operator. - 2 · non-ui gates. It may approve a gate that is accepted with its checks passed on non-UI work, giving the why from the summary in the news line (or from
gate_summaryif the summary was cut). A UI gate, one with a mock or a ticket labelledui, waits for the operator. No sync. - 3 · ui gates. It also decides UI gates. It puts the build beside the mock and measures it, approves if it would, files the small defects, and holds a gate only for a real question. At this stop that look is the conductor's, not the operator's. No sync.
- 4 · syncs. It also proposes a sync when work has landed. Autopilot presses the conductor's
propose_syncas soon as no other sync is running, even with runs still live. They rebase onto the new main when they land. - 5 · fafo. It approves any gate whose checks passed, even when review didn't accept it, and files the review's unmet items as a follow-up ticket with the review's notes. A failed run gets one retry before
autopilot_park. It never approves red checks or an empty diff. Syncs are as at stop 4.
03limits#
- max_parallel. How many autopilot runs may be live at once. While a slot is free the conductor calls
autopilot_nextandautopilot_goagain. The operator's ask is clamped to the project's ownmax_parallel, and to 1 for a workspace built in place; none given means 1. When every slot is taken a go is refused with "N of M slots busy". - failures_in_row. The operator sets "stop after N failures in a row". Retries and parks both count toward it. Runs failed by the machine itself (host loss) are counted apart and stop autopilot at the same limit. Exactly when the count goes back to zero is not checked.
- Other stops. Autopilot also stops at its until time, when it has used its max runs and none is live, and when the tracker has been unreachable for 10 minutes. The operator can switch it off at any time. Each stop writes its reason, which opens the report.
04park, skip and retry#
The loop the conductor works is autopilotBriefHead and autopilotBriefTail around the stop line.
autopilot_nextpicks the ticket. If it returns none, the conductor says why in a line and stops.- The conductor drafts a launch card from the ticket's title, summary, comments and template, then presses go with
autopilot_goon its own fresh card. - On run news:
- A rejected gate (needs_human, or out of revise loops) gets
autopilot_park, with the unmet items as the why. - A failure of infrastructure (tracker 5xx, a runtime or protocol failure, a model runtime down) gets one retry.
- A close miss, with only a few named tests red, gets one retry on its own leftovers. The conductor adds a ticket comment naming the failing tests, drafts a fresh card for the same ticket and presses
autopilot_go. The new run records the failed run it started from. - Anything else, or a second failure of the same ticket, gets
autopilot_parkwith the unmet items as the why, thenautopilot_next.
- A rejected gate (needs_human, or out of revise loops) gets
- A completed run has landed.
Park. autopilot_park stops a run autopilot started, or takes one that has finished, failed or stopped, and saves its unfinished work on a side branch autopilot/<ticket>-<run> in the project's workspace, leaving the workspace clean. A clean workspace saves nothing.
Skip. The conductor skips only a ticket that can't be a run, such as a deploy, a hand config change or work on another machine. It labels the ticket no-autopilot, calls autopilot_skip with a why, and calls autopilot_next again. A skip lasts one autopilot session.
05labels#
no-autopilot.autopilot_nextpasses over a ticket with this label. It is the only label it skips on.operator. The conductor labels a ticket it files when only the operator can do it. The report lists such a ticket, and a skipped one, as needing the operator.
06the tools#
autopilot_status: whether autopilot is on for this chat, and its queue, until time, limits, power and counts so far. Every autopilot action result and wake turn already carries the status, so it is called only when missing.autopilot_next: the next ticket autopilot may go on. It is unblocked, picked by priority then wave, not already started or parked, and there is none while every slot is busy.autopilot_go: presses go on a launch card's ticket as the window's go does. It is refused when autopilot is off, past its limits, or the ticket is not in the queue the operator chose.autopilot_approve: presses approve and land on the gate of a run autopilot started. It can never send a run back.autopilot_parkandautopilot_skip, above.
The conductor never runs git itself, and never sends a run back, stops other runs, edits config or hands off while autopilot is on. The desk keeps its place in every wake turn, so register_wake is only for a note or a time of its own. See conductor.
07report and summary#
When autopilot stops, the desk writes one report card. It is built from autopilot's state and the runs' journals, never from what the conductor said. It holds the reason, the start and stop times, the counters, the power and max parallel, and four lists:
- Landed. Tickets whose run landed a commit, with the closer's headline, any earlier failed runs of the ticket in the same stretch, and whether the commit is on main.
- Parked. Runs whose work was saved on a side branch, with the why and the branch.
- Failed. Runs that failed or were stopped, with the node and the error.
- Skipped. Queued tickets autopilot never reached, and those that need the operator.
Discord gets one line: "autopilot stopped: ", then the counts landed, parked, failed and not reached, the number that need the operator, max parallel and the power.
The summary is a short markdown text the conductor writes once, after autopilot stops. The desk gives it the facts (the landed, parked, failed and needs-you lists and the number not reached) and the record number of the report. autopilot_summary takes that report number and a text of at most 1500 characters. It should cover what landed and what it means, what failed or was parked and why, anything half-done, and the one or two things to look at first. It is refused for a second write, or when a newer report exists.