Skip to content

feat(autopilot): the Autopilot Orchestrator agent decides; the rules only guard - #266

Merged
hoangsnowy merged 2 commits into
mainfrom
feat/autopilot-orchestrator
Oct 22, 2026
Merged

hoangsnowy merged 2 commits into
mainfrom
feat/autopilot-orchestrator

Conversation

@hoangsnowy

Copy link
Copy Markdown
Owner

Summary

Autopilot was fixed-rule code — "not really orchestrated". Now, by default (Settings › Autopilot › Decided by), an AI lead — the Autopilot Orchestrator agent — decides every time a board's state changes.

It reads every ticket + dependencies, every task and proposed change (checks, review, testing, findings), stuck tasks, free slots and its recent decisions, and returns its reasoning plus:

  • moves: which legal moves to make, in its order (unblock the most first, nearly-done work before new work);
  • retries: stuck tasks (couldn't finish / out of fix rounds) started again with concrete guidance for the Coding agent;
  • questions: one precise question for a person, posted on the ticket — instead of a flat "needs a person".

Guardrails — the rules keep authority: the planner offers only legal moves (uncapped), AutopilotPlanner.WithinCaps applies slot caps / one acceptance run at a time / one move per task to its picks, retries are bounded (2 per task), and anything outside the brief (unknown ids, retries of non-stuck tasks, …) is dropped. It answers on the member's computer (no API cost), is asked only when the board changed (state signature), and when it can't answer that pass follows the rules. Its reasoning appears in the Autopilot log as "Orchestrator: …".

Named Autopilot Orchestrator with its own prompt routing key so it can't be confused with the 5-agent pipeline's Orchestrator (IOrchestratorAgent, incl. the MAF Workflow engine).

Test plan

  • AutopilotOrchestratorTests (9): legal-move filtering + order, bounded retries / questions only for stuck tasks, non-JSON → rules, board state fenced as data, routing key, WithinCaps (slots, one test, one move per task), uncapped candidates, state signature.
  • Existing planner/review tests unchanged; full suite green.
  • Lab: Autopilot log shows "Orchestrator: …" reasoning; a stuck task gets retried with guidance or a question on its ticket.

🤖 Generated with Claude Code

https://claude.ai/code/session_018WAdQ7Rm24xss5QDSvXtJB

hoangsnowy and others added 2 commits October 22, 2026 23:14
…only guard

Autopilot was fixed-rule code. Now, by default (Settings › Autopilot › Decided by), an AI lead decides each time a
board's state changes: it reads every ticket with its dependencies, every task and proposed change (checks, review,
testing, findings), stuck tasks, free computer slots and its recent decisions, and returns its reasoning plus:
- which legal moves to make, in its order (prefer what unblocks the most, then nearly-done work);
- retries of stuck tasks (couldn't finish / out of fix rounds) with concrete guidance for the Coding agent;
- one precise question for a person, posted on the ticket, instead of a flat "needs a person".

Guardrails: the planner offers only legal moves (uncapped); AutopilotPlanner.WithinCaps applies the slot caps and
one-acceptance-run-at-a-time to the agent's picks; retries are bounded (2 per task); unknown ids, retries of tasks
that aren't stuck and questions about tasks that aren't stuck are dropped. It runs answer-only on the member's
computer, is asked only when the board changed (state signature), and when it can't answer the pass follows the
rules. Its reasoning lands in the Autopilot log ("Orchestrator: …").

- Domain: IAutopilotOrchestrator, OrchestratorBrief/Move/StuckTask/Decision.
- Pipeline: AutopilotOrchestratorAgent ("You are the Autopilot Orchestrator Agent" — its own routing key, distinct
  from the 5-agent pipeline's Orchestrator), AutopilotSettings (Autopilot:DecidedBy, UI-first).
- Web: ProjectOrchestrator.Agent (brief, signature, guardrails, retries, questions); planner caps as parameters.
- IssueWorkPrompt: a fresh attempt carries the orchestrator's guidance, fenced as data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WAdQ7Rm24xss5QDSvXtJB
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WAdQ7Rm24xss5QDSvXtJB
foreach (var s in sessions.Where(s => s.Status is "Failed" or "Blocked" && s.IssueNumber is { } n && openTickets.Contains(n)))
{
var why = string.Join(" | ", repos[s.Id].Select(r => r.Error).Prepend(s.Error).Where(e => !string.IsNullOrWhiteSpace(e)).Distinct());
stuck.Add(new OrchestratorStuckTask(s.Id, s.IssueNumber!.Value, titles.GetValueOrDefault(s.IssueNumber.Value, s.Title),
@hoangsnowy
hoangsnowy merged commit 0175eb4 into main Oct 22, 2026
4 checks passed
@hoangsnowy
hoangsnowy deleted the feat/autopilot-orchestrator branch October 23, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants