Select a Runner
Every job in the three shipped workflows (devflow.yml, devflow-implement.yml, devflow-retrospective.yml) runs on ubuntu-latest by default. One GitHub Actions variable, DEVFLOW_RUNNER, changes all of them at once.
Set it under Settings → Secrets and variables → Actions → Variables.
Keep the
DEVFLOW_ prefix exactly as written. There is no PRFLOW_RUNNER alias.
Send the Light Jobs to a Cheaper Runner
A second optional variable,DEVFLOW_LIGHT_RUNNER, moves the light (mostly one-core) jobs onto a cheaper runner while the heavy jobs stay on DEVFLOW_RUNNER. It takes the same value shapes — a bare label or a JSON label array.
The light jobs are, in devflow.yml: config, review_dedupe, gate, review_finalize, and the command job when the triggering comment is a standalone /prflow:review. In devflow-implement.yml: config and gate. Everything else keeps DEVFLOW_RUNNER — a /prflow:review-and-fix or /prflow:pr-description command job, the implement claude job (which runs the test suite, and since issue #402 prefers its own optional DEVFLOW_IMPLEMENT_RUNNER, falling back to DEVFLOW_RUNNER), and every devflow-retrospective.yml job.
When DEVFLOW_LIGHT_RUNNER is unset or empty, each light job falls back to the DEVFLOW_RUNNER chain — DEVFLOW_RUNNER’s value, or ubuntu-latest when that is also unset. Set nothing new and no job moves.
Provision a Self-Hosted Runner
Install these before you point PRFlow at the runner:git.- GitHub CLI (
gh). jq.- Python 3.11 or newer, available as
python3. - A POSIX bash on
PATH. openssl,curlandnohup. The long-run credential refresher needs all three.- Docker, when
setup.servicesor your own checks need it.
ok, and the version should be 3.11 or higher. Fix each MISSING line before you continue.
Windows Runners
Windows Runners
The workflows force It refuses to create a shim when no compatible interpreter is present, so a clean exit means the runner is ready.PRFlow cannot make its job credential files owner-only on Windows, because Windows ignores POSIX file modes. Those files live in the runner’s temporary directory under its work directory. Isolation is your host setup:The first command grants the runner account Modify, which it needs to run jobs. The second removes every inherited entry. The third displays the result, which should list only those two entries.Runner services that share one account also share that account’s
bash for their run: steps, so install Git Bash or an equivalent POSIX bash. If Python is available only as python or py -3, run the shipped shim provisioner once on the runner, from a checkout that has the plugin tree:- Run each runner service under its own account. Register it with
--windowslogonaccount, because the defaultNETWORK SERVICEaccount is shared by every service that uses it. - Restrict each runner’s work directory to that account and administrators. With the service stopped, run:
.claude/settings.json, and each can read the others’ job credential files.Executables in Nonstandard Locations
Executables in Nonstandard Locations
Set
DEVFLOW_GH, DEVFLOW_JQ or DEVFLOW_BASH only when the working executable is somewhere the normal search path does not reach. A correct PATH is simpler and less likely to drift.Interruptible (Spot) Capacity
Self-hosted heavy runners on interruptible capacity (for example EC2 Spot) trade cost for the chance that the provider reclaims the instance mid-run. If that happens to a long/prflow:implement job, the runner disappears before the job finishes and the run ends without completing. A recovery job then reconciles the lost run automatically: it resumes a failed run with a bounded request, terminalizes it to 💥 Failed when it cannot resume, and names the real cause of the loss in its comment. For a Linux EC2 Spot runner you can additionally opt in to confirmed reclaim detection by setting prflow_implement.spot_interruption_watcher.enabled to true, so a reclaim is named as such rather than as a generic runner loss. See Cloud Recovery for what survives an interruption, the recovery job, the opt-in Spot watcher, and how to pick the work back up.
Use Claude Code on Windows
The action’s bundled Claude Code installer is Unix-only. On a self-hosted Windows runner, install Claude Code yourself and point.prflow/config.json at it:
This is a trigger-time setting. It takes effect only after the configuration change is merged into your default branch, not while it sits in a pull request.
Avoid Two Configuration Traps
Leavesetup.git_dir_pin and setup.git_work_tree_pin at false unless you have validated their constraints:
git_dir_pinis not honored by implementation runs and can misdirect repository-root configuration reads.git_work_tree_pinbreaks remote marketplace cloning. It suits a local-only marketplace list and nothing else.