Drop a markdown task in tasks/, and Detroit drives a coding agent through the whole pipeline — triage → plan → build → test → ship — running your tests and opening a PR with screenshots. It's a shell script you own, not a hosted black box, and it runs on Grok (default), Claude, dotbot, or opencode (a local model).
Tip
One factory.md runs the whole line. A single file at your repo root declares the pipeline and the standards every change must meet — style, build, testing, security — in named sections. Edit it to control exactly what the agent does. Clone a factory, run it anywhere.
- Picks the next task file from
tasks/ - Routes to the repo (local, GitHub, or creates a new one)
- Agent codes it, runs tests, commits, opens a PR
- Gates + CI + verify must pass — success →
tasks/done/; quality fail after ship →tasks/failed/(never green on soft failure)
Detroit expects your repos to live in the parent directory:
projects/
detroit/ # this repo
my-app/ # a repo detroit can work on
another-app/ # another repo
If a repo isn't local, Detroit searches your GitHub account and clones it automatically.
Or set DETROIT_PROJECTS to point elsewhere:
export DETROIT_PROJECTS="$HOME/code"./factory.sh # run one task (Grok by default)
./factory.sh --dry-run # preview what it would pick
./factory.sh --parallel 3 # run 3 tasks in parallel
./factory.sh --shift # keep running tasks until the usage window hits 80%
./factory.sh --issues owner/repo # pull GitHub issues into tasks/
./factory.sh --verify owner/repo # re-verify all open PRs
./factory.sh --verify owner/repo 42 # re-verify a specific PR
DETROIT_AGENT=claude ./factory.sh # use Claude Code instead of Grok
DETROIT_AGENT=dotbot ./factory.sh # use dotbot instead of Grok
DETROIT_AGENT=dotbot DETROIT_PROVIDER=anthropic ./factory.sh # dotbot + Anthropic
DETROIT_AGENT=opencode ./factory.sh # use opencode on a local model (no API key)
DETROIT_MODEL=grok-4.7-build ./factory.sh # pin the model for every agent callRun in its own terminal — not inside another tool. Monitor progress in a second terminal:
tail -f logs/*.logCancel anytime with Ctrl+C — Detroit cleans up the branch and returns to the default branch.
A local dashboard for the factory floor — the task queue, live agent status and stage, streaming logs, and shipped PRs — plus controls to create a task, trigger a run, and approve a plan at the gate.
rustc -O web.rs -o detroit-web # one-time build (needs Rust)
./detroit-web # http://127.0.0.1:4600 (DETROIT_UI_PORT to override)Run it in a second terminal alongside the factory. Std-only Rust — no crates, one rustc build, no database. It reads and writes the same files factory.sh uses.
Local-only by design: it binds 127.0.0.1 and can start runs, so don't expose it. Runs triggered from the UI approve their plan in the browser (DETROIT_APPROVE_PLAN=web) — the agent pauses at the plan gate until you click Approve or Reject.
Use Detroit from inside an agent session without leaving it. The skill is a thin router over factory.sh — the agent performs triage/plan/code inline, bash keeps owning locks, worktrees, gates, CI, and ship detection.
detroit run # run the next task from tasks/
detroit dry-run # resolve task/repo/branch, print prompt, run nothing
detroit parallel 3 # spawn 3 factory agents (worktree-isolated)
detroit shift # run tasks until the usage window hits 80%
detroit for my-app # only run tasks whose repo: matches my-app
detroit sync issues owner/repo # pull open issues labeled detroit into tasks/
detroit verify owner/repo # screenshot open PRsFull trigger table, gate reference, and prompt fragments live in skills/detroit/SKILL.md. Install it where your agent looks for skills, then call factory.sh flags from the detroit repo root.
Each task is a markdown file in tasks/. The filename becomes the task name. The file body is the full prompt sent to the agent — write as much or as little as you need.
Existing repo — add repo: in frontmatter:
---
repo: my-app
---
Add a dark mode toggle to the settings page. Should respect system
preference by default. Use the existing ThemeProvider context.Screenshot verification — if agent-browser is installed and the project has a dev/start/preview script, Detroit starts the dev server after shipping, reads the git diff to figure out which pages were affected, and uses the agent + agent-browser to take targeted screenshots of the changes. Screenshots are committed to the branch and commented on the PR.
New repo — omit repo: and Detroit creates one (named from the filename):
Build a weather dashboard that shows 5-day forecast.
Use OpenWeatherMap API. Include a search bar for city lookup.Tasks run in alphabetical order by filename. Prefix with numbers to control priority:
tasks/
01-fix-auth.md ← runs first
02-add-dashboard.md
03-refactor-api.md
Completed tasks move to tasks/done/.
Pull issues from any repo into your task queue:
./factory.sh --issues owner/repoThis fetches open issues labeled detroit and creates task files from them. After the factory completes a task, it comments the PR link on the issue and closes it.
Detroit is designed to run unattended. Point cron at it and your issues get solved while you sleep.
Every hour — process one task from the queue:
0 * * * * /path/to/detroit/factory.sh >> /path/to/detroit/detroit.log 2>&1Every hour — pull new GitHub issues, then process them:
0 * * * * /path/to/detroit/factory.sh --issues owner/repo >> /path/to/detroit/detroit.log 2>&1Budget shift — one worker runs task after task while the resetting usage window has room, then stops:
0 * * * * /path/to/detroit/factory.sh --shift >> /path/to/detroit/detroit.log 2>&1A shift reads Omarchy's usage record (~/.local/state/omarchy/agents/usage/$DETROIT_AGENT.json) and stops when the 5-hour session or the weekly window reaches DETROIT_BUDGET_STOP (default 0.80). Only one shift runs at a time, so an hourly cron is safe. A task that fails or stops before SHIP runs once per shift and the rest of the queue keeps going. It sleeps while a focused Herdr workspace has the same agent working, never starts on stale usage, never replays tasks/failed/, and never starts on a prepaid balance. Its log is logs/*-shift.log. Tune with DETROIT_SHIFT_PAUSE (default 30s) and DETROIT_USAGE_MAX_AGE (default 900s). Spec: docs/budget-shift.md.
Night shift — at 01:00 Detroit clocks in: first it spends what your subscription window has left, then a local model takes the rest of the queue:
bash scheduling/install.sh # systemd user timer: every night at 01:00The timer runs scheduling/night-shift.sh: one --shift per agent in DETROIT_NIGHT_AGENTS (default grok opencode), in order. The Grok shift stops at DETROIT_BUDGET_STOP like any budget shift, and steps aside while you are using Grok. With opencode the shift skips the usage record and keeps going until the queue is empty or DETROIT_SHIFT_MAX_HOURS (default 6) have passed. Before each task it checks that gh is signed in and that the model endpoint (DETROIT_MODEL_ENDPOINT, default http://127.0.0.1:8090/v1) answers and serves the model, and stops cleanly if not. The service pins opencode to the installed version so it can't upgrade mid-shift. DETROIT_MODEL picks the opencode model as provider/model (default studio/mlx-community/Qwen3-Coder-Next-4bit). Output goes to logs/nightly.log, which nothing rotates. Details: docs/scheduling.md.
Nightly batch — run 5 tasks in parallel at 2am:
0 2 * * * /path/to/detroit/factory.sh --parallel 5 >> /path/to/detroit/detroit.log 2>&1Label a GitHub issue detroit, go to bed, wake up to a PR with screenshots. That's the workflow.
Based on patterns from Ramp Inspect and Stripe Minions:
- Task queue —
tasks/folder, one markdown file per task - Task routing — finds repo locally, clones from GitHub, or creates new
- Branch isolation — agents work on feature branches, never the default branch
- Autonomous coding — agent runs non-interactively (Grok by default, Claude, dotbot, or opencode)
- Test verification — run tests, fail fast if broken
- PR creation — open a PR via
ghCLI for every task - CI gate — auto-generates GitHub Actions workflow, watches CI, fixes failures
- Task completion — move task file to
tasks/done/ - Visual verification — targeted screenshots of changes via agent-browser
- Streaming output — real-time agent session output via streaming JSON
- Parallel execution — run multiple tasks concurrently with
--parallel N - Budget shift —
--shiftkeeps one worker busy until the usage window is nearly spent - Logging — timestamped logs per run for debugging
- Scheduling — cron or trigger to run without you
A single file controls the factory: factory.md at the repo root. A Dockerfile for code factories — all the standards an autonomous agent needs to ship code in a repo, in one file you can clone and run anywhere. See the factory.md spec for the full format.
factory.md has 8 reserved sections. Each section is a bullet list of rules.
| # | Section | Covers |
|---|---|---|
| 1 | ## style |
Formatting, naming, function size, imports, changelog hygiene |
| 2 | ## build |
Runtime, package manager, CI workflow, version bumping |
| 3 | ## testing |
Test framework, pass/fail gates, new-code test requirements |
| 4 | ## documentation |
Doc comments, README, AGENTS.md updates |
| 5 | ## environment |
Dev tools, branching rules, worktrees |
| 6 | ## quality |
File size, function size, TODO/FIXME, complexity |
| 7 | ## observability |
Logging, error reporting, tracing |
| 8 | ## security |
Hardcoded credentials, dangerous patterns, dependencies |
Every bullet is one rule. The framework reads each bullet and either:
- Runs it as a gate if it recognizes the rule (e.g. "no secrets in diff", "tests pass")
- Forwards it to the agent as an additional rule to honor if it doesn't recognize it
Prefix a bullet with ! to mark it strict — the framework must verify it deterministically or the pipeline fails. Use strict for security, correctness, and release-critical rules you refuse to trust a model on:
## security
- ! No hardcoded credentials
- ! No eval
- Dependency audit cleanEdit any section to match your preferences. factory.md is framework-agnostic — the same file can drive any autonomous agent pipeline, not just Detroit.
Detroit's pipeline is an implementation detail of factory.sh:
- Pick the next task from
tasks/ - Route it to a repo (local, GitHub, or new)
- Prepare a feature branch (worktree)
- Scaffold a CI workflow if missing
- Run the agent with every
factory.mdrule injected into the prompt - Dispatch every rule bullet through
check_gate; recognized gates run as checks, unrecognized gates are forwarded - Fix gate failures by re-engaging the agent (max 2 attempts)
- Confirm the PR, watch CI, fix failures (max 2 attempts)
- Screenshot affected pages via agent-browser
- Move the task file to
tasks/done/, close the issue, return to the default branch
- The Grok CLI (default; signed in with a SuperGrok subscription or
XAI_API_KEY), Claude Code, dotbot, or opencode (any provider it is configured for, local models included) ghCLI (authenticated)agent-browser(optional, for screenshot verification)- Rust (optional, only to build the web UI)
Detroit does the same thing as GitHub Copilot Coding Agent and Claude for GitHub — task in, PR out, automated. The difference is it's a shell script you own.
- Task queue with priority — file-based, numbered for order, not one-off prompts
- Configurable standards and workflow — edit
factory.md(a portable, framework-agnostic spec) to control exactly what the agent does - Screenshot verification — starts the dev server, reads the diff, screenshots the actual pages that changed
- Runs locally — no data leaves your machine except API calls
- Swappable agent — the xAI Grok CLI (default), Claude Code, dotbot (any provider: xAI, Anthropic, OpenAI, Ollama), or opencode on a local model
- GitHub issues integration — pull labeled issues into the queue, close them on completion
- No vendor lock-in — swap Claude for another model, change the pipeline, fork it
- Hosted infrastructure (no local machine needed)
- Web UI
- No setup
Developers who want to own their code factory. Same idea as self-hosting vs SaaS — you trade convenience for control.
git clone https://github.com/stevederico/detroit
cd detroitEdit factory.sh or factory.md. Open a PR.
MIT — see LICENSE.
