Add Model Authentication
The default Anthropic route needs one repository or environment secret:GITHUB_TOKEN handles GitHub operations and needs no setup.
A fully provider-routed installation can use
DEVFLOW_PROVIDER_API_KEY instead. Route every active section before you remove CLAUDE_CODE_OAUTH_TOKEN. A partly routed installation may need both secrets, because each section chooses its route independently. See Providers.Review Repository Configuration
The installer creates.prflow/config.json. Commit it, because the workflows read it from the repository, not from your machine.
At minimum, review:
base_branchandclaude_model.prflow.allowed_usersandprflow.allowed_bots, which decide who may start a run.- The
setupblock, for runtimes and install commands. prflow.allowed_toolsandprflow_implement.allowed_tools, for repository-specific commands.workflows.prflow, which enables the shipped command and implementation paths.
/prflow:init after an installation or an upgrade is recommended. It adds newly scaffolded settings without replacing values you already set, detects common project tools, and — when the config enables a workflow tier — runs install.sh --apply itself to place or refresh the cloud-tier .github/workflows/ files, so you can initialize and install the workflows in one step.
Provision the Runtime
PRFlow prepares the runner in this order:- Set up Python.
- Set up Node.js.
- Set up PHP.
- Start the service containers named in
setup.services, using Docker. - Run each
setup.installline from the repository root.
Optional GitHub App
The default path needs no GitHub App. Add one when a cloud implementation run has to push changes under.github/workflows/, when you want a dedicated automation identity or when a configured stall backstop has to post a resume comment that starts another run.
Install the App on the repository with
Contents: write, Workflows: write, Pull requests: write, Issues: write and Actions: read.
An unset App falls back to GITHUB_TOKEN. A configured but invalid App fails loudly at the token-creation step.
Optional Reviewer App
This is a second, separate GitHub App, used only by the/prflow:review comment command.
Install it on the repository with a narrower permission set than the primary App:
Contents: read, Issues: read, Pull requests: write and Actions: read. It reads the repository, the issue and CI results, and it posts comments and formal reviews. It cannot push.
Why a second App exists: GitHub does not let an identity approve or request changes on its own pull request. When the same identity both authors a pull request and reviews it, the formal review cannot be recorded.
Two details are easy to miss:
/prflow:review-and-fixand/prflow:pr-descriptiondo not use the reviewer App. They push or author content, so they stay on the primary App token.- Both halves of the pair matter, and they fail differently. If the variable is missing or misspelled, the reviewer step is skipped silently, exactly as if you had chosen not to configure it. If the variable resolves but the secret is wrong, the step fails loudly.
Why these settings are still called DEVFLOW_* — and what happens if you rename them
The product was renamed DevFlow → PRFlow, and the rename stopped at the repository’s own
files: the state directory, the vendored plugin path and the config keys moved, and
/prflow:init migrates all four together. The variables, secrets and environment
overrides below did not move, and they are not going to move on their own.
They live outside the repository — in GitHub’s settings and in your shell profile — so
nothing PRFlow ships can migrate them. More to the point, nothing in PRFlow reads a
PRFLOW_* equivalent: every one of these names is read under its DEVFLOW_ spelling
and under no other. So renaming one is not a migration. It is a deletion.
It is also, in almost every case, a silent deletion. GitHub has no concept of “this
variable used to be called something else”: an unresolvable vars.X evaluates to the
empty string, which is exactly what a variable you deliberately never configured
evaluates to. Every gate that reads one takes its “not configured” arm, every job
falls back to its default, and the run goes green — under a degraded identity, or on
a runner you did not choose. The advisory below therefore states, for each name, what
renaming it actually does.
If the brand inconsistency bothers you, the answer is a future PRFlow release that
accepts both spellings — not a rename you perform yourself today.
These names are frozen. Do not rename them. PRFlow reads each one under itsThe two GitHub App pairs fail asymmetrically. The asymmetry inverts what a careful consumer would guess. Rename the SECRET alone and the mint step fails loudly — you find out immediately. Rename the VARIABLE alone and nothing fails: the mint is gated onDEVFLOW_spelling and under no other spelling — there is noPRFLOW_*equivalent anywhere in the plugin. Renaming one of these does not move a setting; it removes it.
vars.<NAME> != '', an unresolvable name reads exactly like deliberately not configured, so every job falls back to steps.app-token.outputs.token \|\| secrets.GITHUB_TOKEN and the run goes GREEN under a degraded identity. Rename BOTH — the natural thing to do, since they are one setting in the consumer’s head — and the variable’s silent skip gates off the secret’s loud guard, so the loud half never runs. The safe rename order is therefore the one nobody would guess, which is the reason this block exists.
Set in GitHub — repository or organization settings
You set these under Settings → Secrets and variables → Actions. PRFlow can only read them.Set on your machine — shell profile or install one-liner
You set these in your own environment. Every one resolves through a${NAME:-…}-style default, so a name that stops resolving is byte-identical to one that was never set.
Not on this list and wondering why:
DEVFLOW_PROMPT_EXTENSION_ROOT is written by the cloud workflows that run the review engine and never set by you, and DEVFLOW_CONFIG_FILE is an internal seam that has never been published as a consumer setting. Both are recorded with their reasoning in lib/rename-map.json.