P001 inline-tool
A run: step calls pnpm, go, docker or another tool directly.
Fix or allow it →
The same check on a workflow that calls pnpm directly, next to a Taskfile that already wraps those commands:
.github/workflows/ci.yml 9:14 P001 inline-tool step "Install" in job "test" runs 'pnpm install --frozen-lockfile' directly; already available as 'task install' 11:14 P001 inline-tool step "Test" in job "test" runs 'pnpm test' directly; already available as 'task test' 13:19 P002 unknown-task 'task lint' is not defined in Taskfile.yml (closest: test)
3 errors, 0 warnings, 0 tolerated, 0 allowedEach finding names the step, the command, and the task that already runs it. Getting started walks through it.
flowchart LR
wf["Workflows and<br/>composite actions"] --> cp
rf["Taskfile, Makefile,<br/>justfile or mise.toml"] --> cp
bl["Baseline"] --> cp
cp(["ci-parity<br/>reads them, runs nothing"]) --> ann["Annotations on<br/>the pull request"]
cp --> cs["Code scanning<br/>alerts"]
cp --> fix["ci-parity fix<br/>rewrites safe steps"]
It reads the files as text: it never runs your task runner, your scripts or the network. Every finding is on the exact line and column, in four formats.
With the GitHub Action, each finding lands on its line in the pull request, and with SARIF it shows up in code scanning too. These are from a real pull request on this repository.


CI setup has both workflows.
- uses: go-task/setup-task@v2- run: task testThe default: no config needed. Internal tasks (internal: true) are reported as
P003.
- run: make testWith runner: make in .ci-parity.yml. Includes are followed; .PHONY and pattern
rules aren’t targets.
- uses: extractions/setup-just@v4- run: just testWith runner: just. Imports and modules are followed, and [private] recipes are
reported as P003.
- uses: jdx/mise-action@v5- run: mise run testWith runner: mise. Tasks in mise.toml, includes and file tasks; hide = true is
reported as P003.
Recipes has a passing setup for each.
A repository with dozens of inline steps doesn’t have to fix them first.
ci-parity baseline records each workflow’s count, the check tolerates that many, and the
count can only go down.
ci-parity baselinelocks in a lower count, and a rise fails the check.Adopting with a baseline shows each step, and
ci-parity fix rewrites the steps it safely can.
P001 inline-tool
A run: step calls pnpm, go, docker or another tool directly.
Fix or allow it →
P002 unknown-task
CI calls a task the runner doesn’t define, with the closest name. Details →
P003 internal-task
CI calls an internal, private or hidden task. Details →
P004 regression
A workflow has more inline steps than its baseline allows. Details →
P005 unsupported
A step it can’t analyze, such as a PowerShell step, is reported as a warning. Details →
Everything else
Steps that call your task runner pass. All the rules →