Skip to content

Run a check

Terminal window
slopcop # check the change in the current checkout
slopcop check --format json # same, machine-readable
slopcop --root ../repo --base origin/main

Running slopcop with no subcommand runs the check; slopcop check is the same command. Every run sends one check request and prints what the service answers. A clean result or a failure always comes from the service; the CLI never decides on its own that there is nothing to check.

One git patch from the base commit to the working tree. The patch carries committed but unpushed work, unstaged edits, untracked files, deletions, renames, mode changes, and binary content. Git-ignored files stay out, except selected .slopcop/policies rules, which must travel because the service evaluates them from the patched checkout.

An empty change is sent as an empty patch, not filtered out. The service owns the limits on what a check accepts: when a change is too large or touches too many files, its payload_too_large response is printed verbatim, and the CLI imposes no limits of its own.

With the patch go the repository’s URL (canonicalized from the origin remote), the base commit’s full hash, the policy selection, and the --fail-on level. Run from a Claude Code or Codex session, a check also sends which models wrote each changed file. What leaves your machine lists every field.

The base is the commit the service applies the patch to. It must already be in the service’s clone, which is why it should be a commit origin has. By default the CLI resolves it in this order:

  1. the merge base with the branch’s upstream;
  2. when that gives an empty patch, as on a branch whose commits are all pushed, the merge base with origin/HEAD, so a check right after a push still covers the branch;
  3. HEAD, when neither is known.

On the default branch with nothing unpushed, the base is HEAD and the patch is empty.

FlagMeaning
--base REVThe branch or revision the change started from. Like git diff REV...HEAD, the base is the merge base of REV and HEAD, so commits that landed on REV after the branch point are not sent as reverse edits. Stops with an error when REV shares no history with HEAD.
--base-exact REVThat exact commit, without a merge base. A target branch that moved on then shows up as reverse edits.

The two cannot be combined. When you check work you have already committed, pass --base with the branch the change targets, such as the pull request’s base:

Terminal window
slopcop --base origin/main

A base the service’s clone lacks comes back as base_not_found with its remedy. The CLI then asks origin for its default branch (git ls-remote, no prompt, ten-second limit) and adds a line when the clone explains the failure: origin’s default branch was renamed and origin/HEAD still names the old one, or the base is not on origin’s default branch. Follow that line.

An empty patch is a real check, not a skip: one request goes out and the service answers. The report then has "emptyChange": true (sarif: properties["slopcop.emptyChange"]), and stderr says so and suggests --base. A clean status on an empty change means nothing was checked, not that the work passed.

FlagMeaning
--root PATHrepository to check (default .)
--base REVbranch or revision the change started from; the base is its merge base with HEAD
--base-exact REVexact base commit or revision, without a merge base
--format human|json|sarifreport format (default human); see Output formats
--fail-on never|finding|note|warning|errorexit-1 threshold for new findings (default finding)
--policy PATHrepository-relative .rqlp file to evaluate (repeatable); see Repository rules
--no-policy-discoveryskip .slopcop/policies rules
--timeout DURATIONhow long to wait for the result (default 10m); a check still running then exits 3
-w, --workspace NAME|IDcheck in, and bill, this workspace of the account instead of the login’s; see Workspaces
--add-repositoryadd the repository to the workspace --workspace names, which then pays for it, without asking at a terminal; for after the user approved it. See Repositories
--service URLthe check service (also SLOPCOP_SERVICE)
--verboseprint the resolved request to stderr, and name each inconclusive check in human

The CLI always sends --fail-on, defaulting to finding: a check fails only on findings the change introduced, so any of them, a note or an unrated one included, is worth fixing before the change lands. The service’s own default for a request without a level is Bifrost’s warning; pass --fail-on warning to match it. New findings that cross the threshold exit 1 even when some rule did not complete.

While the analysis runs, the service answers check_running and the CLI waits the interval it names and asks again, until --timeout runs out. Every ask attaches to the same running check. If it is still running then, the CLI exits 3, prints the service’s message and remedy on stderr, and in json prints a pending report. Running the same check again picks up the same analysis: an identical request by the same login within an hour attaches to it rather than starting a new one.

A check that is interrupted (Ctrl-C, or SIGTERM) prints no report and exits 130 or 143. Interrupted before it was sent, nothing reached the service; after, the service keeps running it, and running the same check again picks up its result.

A first check adds the repository to your workspace; there is no repo add. When the workspace would then pay for it, the check asks at a terminal, and without one exits 4 with repository_add_unconfirmed until a person confirms. Repositories explains the rule and the --add-repository flag. A private repository needs the workspace’s GitHub App, GitLab, or Bitbucket connection first.