An automated software factory that runs Claude AI agents on a remote worker machine to implement tasks, reviews the code with Crucible, and opens pull requests — all from a single command.
factory run "Add a health check endpoint that returns {\"status\": \"ok\"}" --repo owner/my-repoClaude runs on the worker, implements the task, Crucible reviews the result, and if anything needs fixing it retries automatically. A PR is opened on pass.
Label issues with factory, then:
factory poll owner/my-repoEvery labeled issue gets picked up in parallel — each becomes a task for Claude to fix, with a PR opened on success.
Before you start, ask your admin to set up:
- SSH access to ares — your public key needs to be added to the worker machine
- Claude authenticated on ares — already done once for the team, nothing to do here
git clone https://github.com/silverpond/silverforge
cd silverforge
pip install -e .cp .env.example .envThen edit .env and add:
| Variable | Where to get it |
|---|---|
FACTORY_GITHUB_TOKEN |
Create at https://github.com/settings/tokens — scopes: repo, issues, pull_requests, workflows |
SLACK_BOT_TOKEN |
Ask your admin — from the shared Slack app at api.slack.com/apps |
SLACK_APP_TOKEN |
Ask your admin — same Slack app, under "App-Level Tokens" |
SLACK_DEFAULT_REVIEWERS |
Comma-separated Slack member IDs to invite to each run's channel (find yours at slack.com/account/profile) |
Slack is optional — leave those blank to skip notifications.
factory setupThis asks for your username on the worker machine, your SSH key, writes your GitHub token to the worker so clone/push works, and optionally creates the standard factory labels on your repo.
Note:
workers.yamlis already configured for the Silverpond ares machine. Your personal SSH key and username stay in.env(gitignored) — not in the repo.
claudeCLI installed and authenticatedtmuxcrucible—nix profile install github:jonochang/crucible(for code review)untangle—cargo install untangle(Rust projects only)
# Basic
factory run "Fix the login bug" --repo owner/my-repo
# With eval commands (run after the agent finishes each iteration)
factory run "Add input validation" --repo owner/my-repo --eval "pytest" --eval "ruff check ."
# Override model and effort (haiku + low is cheapest)
factory run "Refactor the auth module" --repo owner/my-repo --model haiku --effort low
# Use codex as a fallback if claude hits a rate limit
factory run "Add input validation" --repo owner/my-repo --agent claude --agent codex
# Control how many Crucible review rounds run (0 = skip Crucible)
factory run "Add a loading spinner" --repo owner/my-repo --crucible-rounds 2
# If you're inside a git repo, --repo is inferred automatically
cd ~/projects/my-repo
factory run "Add a health check endpoint"Without --eval, Crucible is the only quality gate — it reviews the diff and sends feedback to Claude if it finds critical issues.
# Basic — picks up all issues labeled 'factory'
factory poll owner/my-repo
# With eval commands
factory poll owner/my-repo --eval "bundle exec rails test"
# Override model/effort for all issues in this poll
factory poll owner/my-repo --model haiku --effort low
# Use codex as a fallback if claude hits a rate limit
factory poll owner/my-repo --agent claude --agent codex
# Control crucible rounds
factory poll owner/my-repo --crucible-rounds 2
# Cap how many issues run in parallel (default: worker slot count)
factory poll owner/my-repo --max-concurrency 2Individual issues can override model/effort via labels:
factory:model:opus— run that issue with Opusfactory:effort:low— run with low effort
If SLACK_BOT_TOKEN and SLACK_APP_TOKEN are set, each run gets a Slack thread with live status updates.
Send messages to the running Claude agent directly from Slack. Start the bridge listener on your local machine:
factory slack-listenAny message posted in the factory Slack channel that starts with run: launches a new task:
run: Add a health check endpoint --repo owner/my-repo
run: Fix the login bug --repo owner/my-repo --model haiku --effort low --crucible-rounds 2
Messages posted in an existing run's thread are forwarded to the Claude session on the worker — useful for giving the agent mid-task guidance.
When Slack is configured, pause-and-review is on by default. After the agent finishes, a prompt appears in the run's Slack thread asking you to approve before the PR is opened. Reply approve (or yes) to open it, or reject to skip. If no reply arrives within 5 minutes, the PR is opened automatically.
The terminal frees up immediately after launch. Use these to check on runs:
factory status # list all runs (includes PR URL)
factory status <run_id> # detail for one run
factory attach <run_id> # attach to the live tmux session on the worker
factory logs <run_id> # tail agent output
factory kill <run_id> # stop a run
factory workers # show active sessions + CPU/mem on each worker# Remove worktrees on the worker for finished runs
factory cleanup # remove all dead worktrees on ares
factory cleanup --dry-run # preview first
# Remove local run history
factory runs-clean # remove finished runs older than 7 days
factory runs-clean --days 1 # keep only last day
factory runs-clean --all # remove all finished runs
factory runs-clean --dry-run # preview firstFor repeatable or complex tasks, define them in a YAML file:
factory run tasks/my-task.yaml # run from YAML
factory poll owner/my-repo --template tasks/my-task.yaml # poll with YAML templateYAML files let you configure the full pipeline — eval commands, crucible rounds, untangle, evaluator, Slack reviewers, service ports, and more. See tasks/todo.yaml for a complete example.
worktree → agent → eval → crucible (N rounds) → evaluator → pause-and-review → PR
Any stage that fails sends feedback back to the agent for another iteration (up to max_iterations, default 3). Stages not configured are skipped.