Autopilot
Autopilot is the working watched-PR loop in Neondeck. Meaningful review feedback or failing checks can notify you, task a continuing Neon owner to prepare a focused commit, wait for your approval, or autonomously deliver a sound, proportionately validated commit according to the watch's current mode. It continues watching the same PR after a successful delivery.
The loop is intentionally small. Each watched PR has one persistent
pr-autopilot-owner Flue instance and one Neondeck-managed worktree,
created lazily on the first actionable event that needs an owner. Later
events and restarts reuse both identifiers. The Flue instance owns one continuing
canonical conversation; the managed worktree and its local commits remain
the source of truth for code.
Model used by Autopilot
Autopilot does not currently have a separate model role. Every
pr-autopilot-owner turn uses
models.displayAssistant and
models.displayAssistantThinkingLevel. The three fixing
modes use the same configured model; their difference is delivery
authority, not model selection. notify-only does not start
an owner turn, so it does not invoke the owner model merely to report a
watch event.
Do not confuse models.prReview with the Autopilot owner. The
PR-review role powers each separate, fresh bounded initial-review agent
submission. Utility, self-improvement, and named subagent models likewise
do not replace the Autopilot owner model. The optional
explore delegate uses its independently configured subagent
model, falling back to the display-assistant model. Configure model roles
in the dashboard's
Runtime
panel or through neondeck_config_update_agent_models.
Fixing-mode owners may delegate focused repository investigation to
explore. The child receives a fresh context but inherits
the owner's managed-worktree local sandbox, so its read-only contract
is an instruction boundary rather than separate filesystem or shell
isolation. The parent owner remains solely responsible for edits,
commits, push decisions, and PR responses.
Start a watched PR
You can enter the same typed service through three product surfaces:
- In the dashboard's GitHub PR list, choose watch. Open Active Watches and select the Autopilot mode for that row.
-
Ask Neon, for example: “Put
pandemicsyn/neondeck#521on Autopilot inprepare-onlymode and process the current feedback.” Neon usesneondeck_autopilot_configure_pr, not an ad hoc config edit. - Use the CLI when you want the same operation directly:
neondeck watch-pr pandemicsyn/neondeck#521 \
--mode prepare-only \
--process-existing \
--confirm-autopilot
The typed action takes an explicit mode and an explicit current-feedback choice:
neondeck_autopilot_configure_pr
{
"ref": "pandemicsyn/neondeck#521",
"mode": "prepare-only",
"processExisting": true,
"confirm": true
}
Set processExisting to true to process actionable
feedback already present when the watch starts. Set it to
false to baseline current feedback and act only on later meaningful
changes.
Modes and authority
notify-only
Records and notifies meaningful changes without starting an owner mutation turn. A new notify-only watch does not create its managed worktree merely to report an event.
prepare-only
Gives the watcher turn a full repository-native coding workspace rooted in the managed worktree. The owner may inspect and edit files and run relevant tests, formatters, typechecks, generators, builds, or language tooling. The result is a normal local commit for you to review. This mode never gives the owner push or PR-response tools.
autofix-with-approval
The watcher turn can prepare and commit but cannot push. When a commit
is ready, the watch enters waiting and holds the worktree steady.
The watcher turn has the same full coding workspace as every fixing mode,
but no delivery tools. The human must review the held diff and approve its
exact current revision through Active Watches or the typed approval API.
Generic messages in the owner conversation can request more work but never
add push or PR-response authority.
autofix-push-when-safe
The only mode that can push from a watcher-generated turn. It grants the same coding workspace plus guarded push and PR-response tools. “Safe” is semantic engineering judgment: the owner inspects the feedback in repository context and decides whether it is reasonable, relevant, technically sound, appropriately scoped, and sufficiently validated. When satisfied, it may implement, validate, commit, push, and respond without human approval. Otherwise it retains any useful commit and explains why human review is needed.
View and customize owner prompts
The dashboard's Runtime panel includes an
Autopilot owner prompt editor. It exposes the effective
full system prompt for prepare-only,
autofix-with-approval, and
autofix-push-when-safe. notify-only has no owner
prompt because it does not start an owner turn. Save replaces the full prompt
for that mode; reset default removes the override and restores
the shipped template.
Prompt changes apply on the next owner turn, including turns for an
already-existing owner conversation. Neondeck does not version owners
or mark them stale when a template changes. The editor accepts up to
20,000 characters and supports these runtime tokens:
{{source}}, {{mode}},
{{status}}, {{capabilities}}, and
{{workspaceInstructions}}.
An override is deliberately a full replacement, including the shipped behavioral guidance; Neondeck does not append a hidden owner prompt after it. Tool availability and the mechanical delivery checks remain outside prompt text: changing words cannot grant a push tool, change the current watch mode, bypass exact-head checks, or create an external delivery capability.
Neon can read and change the same templates through
neondeck_config_read_autopilot_prompts and
neondeck_config_update_autopilot_prompt. The local
access-controlled API mirrors those operations at
GET /api/autopilot/prompts and
POST /api/autopilot/prompts; posting
{"mode": "…", "prompt": "…"} updates one mode, while
prompt: null resets that mode to its default.
Increasing authority requires confirmation
Every increase in mode rank—including the first move above
notify-only—requires explicit confirmation. The Active
Watches selector presents a separate confirm increase step.
Neon may set confirm: true only after you explicitly approve
the increase. Lowering authority does not require that confirmation, and
a running turn rechecks current authority before an external effect.
Review and control a watch
Active Watches shows the current mode and the minimal loop status:
watching, working, waiting,
blocked, or complete. From the watch row you
can:
- choose review diff to inspect the committed worktree change against the exact PR head used to create the worktree;
-
choose review agent to open the durable
pr-autopilot-ownerconversation for that PR; -
in approval mode while
waiting, review the current diff and choose approve & push for that exact revision; use the owner conversation separately when you want to request more work; - pause or resume scheduler polling;
-
retry a visible
blockedstate after you inspect the PR, owner conversation, and retained worktree; and - stop the watch through its confirmation step. An active owner turn must settle before terminal cleanup can complete. If the managed worktree holds an unpushed prepared commit, stopping requires a separate explicit confirmation that the reviewed commit may be discarded.
Approval is an exact current reviewed-revision decision made through Active Watches or the equivalent typed API. The revision key is bound to the delivery turn without creating a separate prepared-diff record or workflow-per-transition chain. Generic owner messages and GitHub feedback cannot impersonate approval because they never receive push capability.
Product boundaries
These are the core boundaries of the current loop, independent of how you configure a particular repository:
- Neondeck creates, binds, reviews, commits, and delivers through the one managed worktree assigned to the watched PR. The owner is instructed not to use the primary checkout.
- Every fixing mode receives the same trusted coding workspace. Mode changes external delivery authority, not which repository commands the owner may run.
- Current watch mode and turn source determine the actual tools supplied to the owner. Prompt text alone never grants capability.
- Approval-mode watcher turns cannot push. Only the exact-revision approval turn created by Active Watches or the typed approval API can receive the approval-mode push tool.
- Autonomous delivery always uses a non-force push bound to the expected current PR head. Neondeck does not silently rebase or force-push around a changed remote branch.
-
When autonomous delivery becomes uncertain after a commit is
prepared, Neondeck retains that local commit, exposes a visible
blockedstate, and requires human review instead of expanding policy or guessing about an external effect.
The coding shell is trusted local execution, not OS-level containment. It starts in the managed worktree with common credential paths removed, but it runs as the Neondeck server user and can see more of the host filesystem than the bound repo tools expose. The managed worktree is a strong task and delivery boundary; it is not a container or virtual machine boundary. See safety and sandboxes before enabling a fixing mode.
Autonomous judgment and validation
Selecting autofix-push-when-safe delegates the scope, soundness,
and validation decision to the continuing owner. It chooses proportionate
repository-native commands for the actual change. A focused unit test may
be sufficient for a small fix; a compiler, formatter, typecheck, generator,
or build may be relevant elsewhere. A repository with no test suite can
still receive a sound small fix, while a risky change with no meaningful
validation path must be escalated.
Effective guardrails.requiredChecks values may appear in the
turn as useful repository hints, but they are not a command allowlist, are
not automatically rerun by the delivery tool, and are not required for an
autonomous push. The owner's chosen commands and reasoning remain in its
continuing conversation.
Mechanical delivery prerequisites
After the owner has made the semantic decision to deliver, the narrow push tool checks only authority, destination, credential, and race conditions:
-
GITHUB_TOKENis valid for current PR facts and login identity; the repository's git remote also has valid push credentials, git identity, branch permissions, and destination access. - GitHub returns complete current facts, the remote PR head exactly matches the head used by the managed worktree, and direct push access is proven.
-
The watch is still
autofix-push-when-safeandworkingfor the current watcher turn, and the validated managed worktree is clean with a committed change. - The final operation is a non-force push of that exact commit, guarded by the expected remote head and bound GitHub identity.
Fail-closed behavior
After the owner prepares a commit, any of the following prevents an autonomous push and leaves the commit available for review in a visible blocked watch:
- the owner judges the request absurd, ambiguous, scope-exploding, technically unsound, or inadequately validated;
- GitHub facts are incomplete, truncated, stale, or show a new head;
- the watch mode or status changed before the external effect;
- GitHub or git credentials, login identity, push permission, remote, or destination cannot be proven;
- the worktree changes before delivery, the expected-head push is rejected, or another unexpected error makes the outcome uncertain.
Retry is deliberately explicit. Inspect the retained diff and owner conversation first, then use retry; Neondeck fetches current facts before another eligible owner turn. It does not create an automatic rebase, effect-reconciliation, or multi-stage recovery engine.
Restart and crash recovery
On startup, Neondeck first reattaches a recoverable canonical pending
Flue submission. If the exact intended commit or stable response
marker already reached GitHub, narrow reconciliation records that
effect without repeating it. An orphaned or otherwise uncertain watch
left in
working becomes blocked; its owner and
worktree remain available for inspection before explicit retry.
Neondeck never guesses from an ambiguous remote state or speculatively
repeats a push or PR response.
Completion and cleanup
After a push, Autopilot returns to polling for later feedback. When
the PR is merged or closed, it waits for the watch's terminal checks
to stop being pending, marks the watch complete, disables
polling and direct owner turns, and cleans only eligible
Neondeck-created worktrees. Adopted, dirty, or policy-retained
worktrees remain for manual handling, and a cleanup failure stays
visible. Explicit stop also retains a held unpushed prepared commit
unless the stop request separately confirms that destructive discard.
The durable pr-autopilot-owner conversation is retained after
completion or an explicit stop as the audit trail of current facts, human
instructions, tool calls, approvals, and results. Neondeck does not delete
that conversation merely because its disposable worktree is cleaned up.
Verification scope
The repository proves the minimal loop with automated coverage for mode capability ceilings, owner/worktree reuse, exact-head handling, managed-worktree command execution, exact-revision human approval, autonomous delivery without configured checks, semantic escalation, mechanical delivery guards, blocked restart recovery, and terminal cleanup. Live migration acceptance also exercised approval-mode and autonomous push, response, retry, restart reconciliation, and idempotency against two explicitly authorized disposable GitHub PRs that were closed without merge after validation. Validate your own token, git remote, identity, permissions, and repository instructions before enabling autonomous delivery.