Global options work anywhere in the args: --config <path>, --dry-run, --backend <internal|relay>, --agent-exit-timeout <ms>.
Run
factory run-once # one discover → triage → dispatch cycle, then exit
factory loop # a bounded multi-iteration loop, then exit
factory start --mode live # long-lived daemon — the production entrypointAdd --dry-run to run-once to discover and triage while writing nothing and spawning nothing.
One issue at a time
factory triage <KEY> # triage and print the decision, change nothing
factory dispatch <KEY> # triage + dispatch, honors --dry-run
factory babysit <PR> # shepherd an existing open PRtriage is the one to reach for when you're wondering why an issue was routed the way it was — it prints the decision without acting on it.
babysit is opt-in on its own and doesn't need babysitter.enabled. It takes a number (using repos.default) or a full PR URL, rejects closed, merged, and draft PRs, and always leaves final review and merge to a human.
Operate
factory status # current status as JSON
factory loop-status # is the loop alive
factory kill-loop # stop it
factory reap-orphans # clean up stale factory-owned agents
factory close-probe # probe or close a PR for an issueCanary
factory canary <KEY>The regression detector for upstream sync drift. Point it at a standing "Ready for Agent" issue: if a synced issue stops carrying enough state to be dispatchable, a known-good issue flips from dispatch-ready to skipped and this catches it. Prints {ok,issue,status,reason} and exits non-zero with the skip reason.
scripts/factory-canary.sh wraps it for cron or launchd, bounds a hung run, and posts a Slack alert on failure.
Backends
--backend internal runs agents on this machine; --backend relay places them on fleet nodes through the hosted engine. See Where it runs.