auto-dev Pipeline

bugbot → nightshift → autonomous PRs

bugbot scans the codebase for issues and files them on GitHub. nightshift picks them up and implements fixes autonomously using Claude Code, then self-reviews its own PRs and triages them for the morning summary. The wave promoter re-queues unblocked issues, creating a self-sustaining loop. 12+ phases, zero human intervention overnight.

Overview
Bugbot

Code Scanner

Scans for dead code, type holes, missing tests, stale comments, input validation gaps. Files findings as GitHub issues with nightshift, auto-ready, bugbot, bugbot:{category}, and priority:{level} labels.

Nightshift

Job Queue

Discovers nightshift-labeled issues (max 50 per run). Runs Claude Code headlessly in isolated git worktrees with a 90-minute timeout per issue. Supports scheduling (--at 2:00) and concurrency (--concurrency N) via a semaphore-based worker pool.

Self-Review

Auto-Triage

Reviews its own PRs after all issues are processed (once per batch, each PR individually). Auto-fixes mechanical issues. Flags scope/design questions for human review.

Pipeline Flow
Queue + TS (queue.ts, worker.ts)
Bash (auto-dev.sh)
Self-Review (pr-self-review.ts)
Auto-approved
Self-fixed
Needs human / Failed
bash   Phases 1-5

Phase 1 runs in TypeScript (queue.ts). Phases 2-5 run in a bash script (auto-dev.sh). Claude Code is invoked headlessly to implement the fix in a fresh git worktree. Each issue has a 90-minute timeout and up to 3 retry attempts.

1   Discover
Runs in queue.ts, not bash. Fetches nightshift-labeled issues via gh issue list --label nightshift --limit 50. Builds a prioritized work queue. If --issue flag is passed, processes specific issues instead. The worker pool (pool.ts) distributes issues across --concurrency N parallel workers, each in an isolated git worktree.
2   Setup Worktree
Clean-slate setup: remove stale worktree + local branch + remote branch. Then git worktree add from origin/main, create feature branch feat/gh-{N}-{slug}, symlink node_modules.
3   Execute
Run claude --print --permission-mode bypassPermissions with the issue spec as prompt. Claude implements the fix, runs npm run verify. Prompt includes scope constraints: no cascade deletions, replace references with inline defaults rather than deleting consuming code.
4   Simplify
Second Claude pass reviewing git diff origin/main against the spec. Simplifies for clarity, consistency, maintainability. No feature changes. Scope-limited: will not delete functions or logic blocks the spec didn't ask to remove.
5   Verify
Guardrails gate:
• Gate 1: npm run verify must pass
• Gate 2: Files changed ≤ 15
• Gate 3: Lines changed ≤ 500
• Gate 4: No unexpected dependency changes (spec must use add/install/require + dependency noun)
• Gate 5: Deletion budget — net deletions ≤ 15, gross deletions ≤ 40 (unless spec explicitly requests large-scale removal)
Writes sentinel JSON (with net_deletions and head_sha) on success. This artifact is the handoff to the TypeScript layer.
ts   Phases 6-9 — worker.ts

These phases run in TypeScript. A multi-agent panel reviews the code, filters overengineered suggestions, applies fixes, and publishes a draft PR. If the panel verdict is fail, the pipeline stops early — no PR is created.

6   Panel Review
Multi-agent review using Claude CLI:
Always: code-reviewer, spec-compliance-checker, test-coverage-checker, scope-checker
Conditional: red-team (auth/security files), ml-specialist (scoring/threshold files)
Agents run in parallel. Findings are deduplicated, scored, and compiled into a ReviewBrief.

Scope-checker verifies the diff doesn't change anything the spec didn't ask for. Detects cascade deletions and out-of-scope modifications.

If the panel verdict is fail, the pipeline stops — the issue is marked auto-failed and no PR is created.
6.5   Simplify Filter
Sonnet call removes overengineered review suggestions. Keeps real bugs, security issues, spec gaps. Removes style nits, premature abstractions, unnecessary complexity.
7   Fix
Applies actionable findings (trivial/small effort) via a punch list prompt. The spec is passed as untrusted context — Claude follows only the punch list.
8   Re-verify
npm run verify after fixes. If it fails, the pipeline stops — no broken code gets published.
9   Publish
git add -u, commit, push, gh pr create --draft. Posts ReviewBrief as PR comment. Updates labels: removes auto-ready + nightshift, adds auto-pr-ready. PR body includes Closes #N so GitHub auto-closes the issue on merge.

If no changes exist (empty diff), removes auto-ready + nightshift labels, posts an explanatory comment, and auto-closes the issue instead of creating a PR.
review   Phases 10-12 — pr-self-review.ts

After all issues are processed, nightshift reviews its own PRs. Runs once per batch, then reviews each PR individually. Triage runs twice per PR: once as a pre-check to decide whether to attempt fixes, and again after fixes to confirm resolution.

10   Self-Review
Fetches PR diff via gh pr diff. Single sonnet agent reviews against the original spec. Each finding gets a fixability tag: auto_fixable, needs_human, or false_positive.
12a   Pre-check Triage
Deterministic classification (no LLM) runs before any fix attempt:
• No findings or all false_positive → skip fixes, go straight to auto_approved
• Any needs_human finding → skip fixes, mark needs_human
• Only auto_fixable findings → proceed to Phase 11 (Auto-Fix Loop)
11   Auto-Fix Loop
For PRs with auto-fixable findings (max 2 iterations):
• Build punch list from findings
execClaude with sonnet to apply fixes
npm run verify — if fails, mark needs_human
• Commit and push
• Re-review the PR diff to confirm findings are resolved
• If findings remain, loop (up to 2 iterations total)
12b   Final Triage
Same deterministic classification, run after Phase 11 completes:
• No findings or all false_positive → auto_approved
• All auto_fixable resolved (12b returns auto_approved after Phase 11 succeeded) → orchestrator marks self_fixed
• Remaining needs_human findings → needs_human
• Review itself failed (unparseable output) → review_failed (reserved — currently unreachable; unparseable output is treated as clean)

Actions: auto-approved/self-fixed PRs get gh pr ready. Needs-human PRs get a triage comment.
Classification Decision Tree

How nightshift decides whether a review finding can be auto-fixed or needs human judgment. Classification happens inside the review prompt, not as a separate step. All three dimensions (category, severity, scope) are checked for each finding.

Auto-Fixable

Magic numbers, missing imports, unused code, missing tests for existing patterns, style issues with clear mechanical fixes.

Needs Human

Scope violations, cascade deletions, removed functionality, architectural choices, design tradeoffs, spec gaps, uncertain critical findings.

False Positive

Reviewer was wrong. The code is correct per spec. Skipped — no action taken.

Label Lifecycle
bugbot files issue auto-ready + nightshift + bugbot + bugbot:{category} + priority:{level} nightshift picks up auto-pr-ready or auto-failed or closed

nightshift

Scoped for autonomous processing. Applied by bugbot or manually. Consumed by nightshift's discovery phase.

auto-ready

Broader gate — issue is specced and ready. Used by the wave promoter for dependency tracking. Both labels required for nightshift to pick up an issue.

auto-pr-ready

PR created, awaiting human merge. Counts as "satisfied" for dependency tracking in wave promotion.

auto-failed

Pipeline failed. Issue gets a comment explaining the failure phase. Needs investigation.

bugbot + bugbot:{category}

Applied by bugbot to track scanner origin. Categories include bugbot:dead-code, bugbot:type-holes, bugbot:stale-comments, etc.

priority:{level}

Severity-based priority applied by bugbot. Levels: priority:high, priority:medium, priority:low. Nightshift processes higher-priority issues first.

infra   Infrastructure

Safety mechanisms that keep the pipeline running unattended overnight. These components are not phases themselves but operate across the entire pipeline.

Circuit Breaker

Consecutive Failure Protection

Tracks consecutive systemic failures (crashes, timeouts, setup errors) and halts the queue after N trips (default 3, configurable via --max-failures). Spec-level failures (verify gate, panel review) are treated as issue-specific and reset the counter — they don't indicate infrastructure problems.

PID Lock

Concurrent Run Prevention

Atomic O_EXCL lockfile at $STATE_DIR/nightshift.lock prevents overlapping nightshift runs. Auto-reclaims stale locks from dead processes. Safe to call nightshift start from tmux or the scheduler without risking parallel execution.

Worker Pool

Concurrency Semaphore

Controls parallel execution via --concurrency N. Each worker gets its own isolated git worktree. A single git fetch origin runs before the pool starts to avoid fetch contention between workers.

Wave Promoter

Dependency-Aware Re-queuing

Runs after each batch completes (nightshift promote). Uses Kahn's algorithm to find issues whose dependencies are all satisfied (closed or auto-pr-ready). Promotes them by adding the auto-ready label, re-entering them into the queue for the next nightshift run. This creates the self-sustaining feedback loop.

Morning Summary

What you see when you check nightshift the next morning. The triage section tells you exactly what needs attention.

= auto-approved   🔄 = self-fixed   ⚠️ = needs human # Nightshift Summary — 2026-03-14 Started: 02:00 | Finished: 02:05 | Duration: 5m 11s ## Results [PASS] #87 (3m 42s) [panel: pass] → PR #241 [PASS] #215 (2m 40s) [panel: pass] [PASS] #219 (4m 41s) [panel: pass] [PASS] #225 (4m 03s) [panel: pass] → PR #238 [PASS] #232 (4m 10s) [panel: pass] → PR #237 [PASS] #234 (4m 37s) [panel: pass] → PR #236 [PASS] #253 (5m 10s) [panel: pass] → PR #265 ## Totals Completed: 12/15 | Failed: 0 | Skipped: 0 ## Triage [APPROVED] Auto-approved: #87, #232, #253 [HUMAN] Needs human: #225 (pairwiseTokenScore not unexported) [HUMAN] Needs human: #234 (silent clamping vs error messages)