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:

  1. In the dashboard's GitHub PR list, choose watch. Open Active Watches and select the Autopilot mode for that row.
  2. Ask Neon, for example: “Put pandemicsyn/neondeck#521 on Autopilot in prepare-only mode and process the current feedback.” Neon uses neondeck_autopilot_configure_pr, not an ad hoc config edit.
  3. 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-owner conversation 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 blocked state 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 blocked state, 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_TOKEN is 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-safe and working for 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.