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.
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.
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.
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.
graph TD
BB["Bugbot Scan"] --> ISS["GitHub Issue"]
ISS --> D["Phase 1: Discover (queue.ts)"]
subgraph bash["auto-dev.sh (Bash)"]
S["Phase 2: Setup Worktree"] --> E["Phase 3: Execute"]
E --> SM["Phase 4: Simplify"]
SM --> V["Phase 5: Verify"]
end
D --> S
V --> SNT["Write Sentinel JSON"]
subgraph ts["worker.ts (TypeScript)"]
SNT --> PR["Phase 6: Panel Review"]
PR -->|pass| SF["Phase 6.5: Simplify Filter"]
PR -->|fail| PFAIL["Pipeline Stopped"]
SF --> FX["Phase 7: Fix Findings"]
FX --> RV["Phase 8: Re-verify"]
RV --> PB["Phase 9: Publish Draft PR"]
end
PB --> P10["Phase 10: Self-Review"]
subgraph rev["pr-self-review.ts"]
P10 --> PRE["Phase 12a: Pre-check Triage"]
PRE -->|auto_fixable| AF["Phase 11: Auto-Fix Loop"]
PRE -->|clean / false_positive| DONE["Auto-Approved"]
PRE -->|needs_human| HPRE["Needs Human"]
AF --> REREV["Re-review Diff"]
REREV --> TR["Phase 12: Final Triage"]
end
TR --> OUT{Outcome}
OUT -->|clean| APR["Auto-Approved"]
OUT -->|fixed| SFX["Self-Fixed"]
OUT -->|scope issue| HUM["Needs Human"]
OUT -.->|"error (reserved)"| RFAIL["Review Failed"]
APR --> WP["Wave Promoter"]
SFX --> WP
WP -->|"unblocked issues"| ISS
classDef bashNode fill:#f59e0b22,stroke:#f59e0b
classDef tsNode fill:#3b82f622,stroke:#3b82f6
classDef revNode fill:#a855f722,stroke:#a855f7
classDef greenNode fill:#22c55e22,stroke:#22c55e
classDef orangeNode fill:#f9731622,stroke:#f97316
classDef redNode fill:#ef444422,stroke:#ef4444
classDef cyanNode fill:#22d3ee22,stroke:#22d3ee
class S,E,SM,V bashNode
class D,PR,SF,FX,RV,PB tsNode
class P10,PRE,AF,REREV,TR revNode
class APR,DONE greenNode
class SFX orangeNode
class HUM,HPRE,PFAIL,RFAIL redNode
class WP cyanNode
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
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
git worktree add from origin/main, create feature branch feat/gh-{N}-{slug}, symlink node_modules.3 Execute
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
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
• 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.
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
• 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
7 Fix
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.
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
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
• 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
• 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
• 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.
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.
graph TD
F["Review Finding"] --> CAT{Category?}
CAT -->|"actionable, style, test_gap"| EFF{Effort?}
EFF -->|"trivial / small"| AUTO["auto_fixable"]
EFF -->|"medium"| HUM["needs_human"]
CAT -->|"security"| SEFF{Effort?}
SEFF -->|"trivial / small"| AUTO
SEFF -->|"medium"| HUM
CAT -->|"tradeoff, question, spec_gap"| HUM
CAT -->|"scope_violation"| HUM
CAT -->|"false_positive"| FP["false_positive"]
AUTO --> SEV{Severity + Confidence?}
SEV -->|"critical + confidence < 80"| HUM
SEV -->|"otherwise"| SCOPE{"Scope check"}
SCOPE -->|"removed existing features not in spec"| HUM
SCOPE -->|"added behavior not in spec"| HUM
SCOPE -->|"within spec"| PASS["Confirmed auto_fixable"]
classDef greenNode fill:#22c55e22,stroke:#22c55e
classDef redNode fill:#ef444422,stroke:#ef4444
classDef orangeNode fill:#f9731622,stroke:#f97316
class AUTO,PASS greenNode
class HUM redNode
class FP orangeNode
Magic numbers, missing imports, unused code, missing tests for existing patterns, style issues with clear mechanical fixes.
Scope violations, cascade deletions, removed functionality, architectural choices, design tradeoffs, spec gaps, uncertain critical findings.
Reviewer was wrong. The code is correct per spec. Skipped — no action taken.
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.
Safety mechanisms that keep the pipeline running unattended overnight. These components are not phases themselves but operate across the entire pipeline.
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.
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.
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.
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.
What you see when you check nightshift the next morning. The triage section tells you exactly what needs attention.