[T-A355AA] Autopilot mode#60
Conversation
Add three execution modes (manual/hybrid/autopilot) that control how much human intervention the pipeline requires: - manual: current behavior, human approves all plans - hybrid: AI supervisor auto-approves/rejects plans, standard auto-retry on review failures - autopilot: fully automated with supervisor making intelligent retry decisions on review failures, extending review cycles when needed, and escalating only when stuck New files: - server/src/supervisor.js: supervisor evaluation logic using CLI --print mode for plan approval and review failure analysis - server/src/supervisor.test.js: unit tests for decision parsing Modified: - config.js: autopilotMode setting with defaults, normalization, validation - orchestrator.js: supervisor integration at plan-complete and review-failure decision points with race condition guards - index.js: broadcast supervisor:decision events via WebSocket - App.jsx: segmented button group for execution mode in Settings General tab - useFactory.js: handle SUPERVISOR_DECISION WebSocket messages 🤖 Ban Kan Autopilot
…sionBlock Replace regex-based feedback extraction with slice-based approach to capture all lines after the FEEDBACK/ENHANCED_FEEDBACK label. The previous non-greedy regex with $ in multiline mode only captured the first line. 🧑🏻💻 Weekly Daniel
Add decision validation in supervisor.js to ensure parsed decisions are one of the expected values (APPROVE/REJECT/ESCALATE for plans, RETRY/ESCALATE for reviews). Invalid decisions fall back to ESCALATE as a fail-safe. Add comprehensive integration tests covering supervisor plan approval, review failure paths, and result structure contracts. 🧑🏻💻 Weekly Daniel
Prevent unbounded cycle extensions when autopilot supervisor keeps returning RETRY at max review cycles. Caps extensions at 2 beyond the configured maxReviewCycles, then blocks the task for human input. 🧑🏻💻 Weekly Daniel
There was a problem hiding this comment.
Pull request overview
Adds an Autopilot execution mode to the task pipeline by introducing a Supervisor agent that can auto-approve plans and guide retries/escalations on review failures, with corresponding server config + UI controls.
Changes:
- Add
server/src/supervisor.js(and tests) to query a CLI model and parse structured supervisor decisions. - Integrate supervisor decision points into
server/src/orchestrator.jsfor plan completion and review-failure handling (including a hard cap on cycle extensions). - Add
autopilotModeto settings defaults/normalization/validation and expose it in the Settings modal; broadcast supervisor decisions to the client.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| server/src/supervisor.js | New supervisor query + decision parsing/validation; emits fail-safe ESCALATE outcomes. |
| server/src/supervisor.test.js | Unit tests for decision parsing and validation helpers. |
| server/src/supervisor-integration.test.js | Integration tests around evaluatePlan/evaluateReviewFailure with mocked execFile. |
| server/src/orchestrator.js | Hooks supervisor into plan auto-approval (autopilot/hybrid) and review-failure retry/escalate logic (autopilot). |
| server/src/orchestrator.test.js | Adds basic assertion for MAX_SUPERVISOR_EXTENSIONS export/default. |
| server/src/config.js | Adds autopilotMode default + normalization + validation. |
| server/src/config.test.js | Adds tests for autopilotMode defaulting/normalization and validation. |
| server/src/index.js | Broadcasts new SUPERVISOR_DECISION event to clients. |
| client/src/useFactory.js | Displays notifications for supervisor decisions. |
| client/src/App.jsx | Adds execution-mode selector to Settings modal and validates autopilotMode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix BLOCKING race: set task status to 'evaluating' before async
supervisor call to prevent poll loop from re-spawning reviewers
- Convert plan auto-approval from fire-and-forget .then()/.catch()
to proper async function with error handling
- Normalize supervisor return shape: both evaluatePlan and
evaluateReviewFailure now return { decision, feedback, logMessage }
- Add queue depth cap (20) and slot acquisition timeout (30s) to
supervisor concurrency limiter with proper cleanup on reset
- Sanitize stderr before storing in task log / broadcasting to clients
- Add structured error logging with taskId, cli, elapsed time
- Use consistent 'review' stage value (was 'review-failure'/'review-max-cycles')
- Deduplicate RETRY updateTask calls in handleSupervisorReviewDecision
- Include stage context in ESCALATE notification message
- Handle non-Error throws safely in catch blocks
🐛 Fixes issues identified by hardcore-code-reviewer
👨🏻💻 Daniel Stilero Eliasson
- Add 'evaluating' to restartRecovery map so tasks stuck mid-supervisor evaluation are recovered to 'review' on server restart - Move acquireSupervisorSlot() inside try block so slot-acquisition rejections (queue full, timeout) don't leak slots permanently - Fix releaseSupervisorSlot counter to use Math.max(0, ...) guard - Update isMaxReviewCyclesBlocker regex in workflow.js and TaskDetailModal.jsx to match supervisor-blocked reason strings (exhausted extensions, escalated) so UI action buttons render - Strip decision markers from task fields before interpolating into supervisor prompts to prevent prompt injection attacks - Fix _isError flag leaking through evaluatePlan spread operator - Add .catch() to fire-and-forget autoApprovePlan call - Expand sanitizeStderr to cover Bearer tokens, GitHub PATs, AWS keys 👨🏻💻 Daniel Stilero Eliasson
- Wrap handleSupervisorReviewDecision calls in try/catch to prevent tasks from being permanently stuck in 'evaluating' if the function throws — catch block rescues to 'blocked' or 'queued' as appropriate - Pass supervisor prompt via stdin instead of CLI argument to avoid ARG_MAX (256KB on macOS) overflow with large plans/reviews - Guard releaseSupervisorSlot with slotAcquired flag so finally block doesn't release a slot that was never acquired on queue-full rejection - Add reject parameter to inner Promise to handle sync exceptions - Add 'evaluating' to statusToStage mapping (→ review stage) - Add 'evaluating' to orphan-check exclusion list to prevent conflicting status updates during supervisor evaluation - Remove unused _isError flag from supervisor error responses 👨🏻💻 Daniel Stilero Eliasson
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…on and update tests for new implementation
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| const parsed = parseDecisionBlock(stdout); | ||
| if (!parsed) { | ||
| console.error('Supervisor returned unparseable output', { ...context, cli, elapsed, output: stdout?.slice(0, 500) }); |
There was a problem hiding this comment.
When the supervisor output is unparseable, the code logs a raw stdout snippet (stdout?.slice(0, 500)). Supervisor stdout can contain task content, code, or other sensitive data, so this risks leaking secrets into server logs. Consider omitting stdout entirely, or sanitizing it similarly to sanitizeStderr (and/or only logging a hash/length plus the first line) before writing to logs.
| console.error('Supervisor returned unparseable output', { ...context, cli, elapsed, output: stdout?.slice(0, 500) }); | |
| console.error('Supervisor returned unparseable output', { ...context, cli, elapsed }); |
…and enhance autopilot mode features
Summary
Add an Autopilot mode with a Supervisor Agent that auto-approves plans and makes intelligent retry decisions on review failures, reducing human intervention in the task pipeline.
Key Changes
Review