Skip to main content

SlopCop

Static analysis deep enough for CI, fast enough to run on every edit.

CI Release npm PyPI License Go

slopcop sends one git patch, from the base commit to the working tree, to the hosted check API at https://slopcop.com. The service applies it, runs the hosted policy catalog plus the repository rules you selected, and returns the report: every finding with its severity, the file and line that triggered it, and the certainty behind it. The analysis is Bifrost, an open-source static analysis engine rather than a language model, so a finding traces back to a rule instead of to a guess.

There is no local analyzer and nothing to install per language: the CLI ships the change and prints what comes back, and it never decides on its own that there is nothing to check. The command is built for agents and one-shot CI: no prompts, one request, and the analyzer's exit contract.

Install

npm, PyPI, the release archive, and the PowerShell installer all install the same release binary for macOS, Linux, and Windows on x64 and arm64, so slopcop version reports which release it came from. The Go toolchain can build that binary from source instead.

Channel Platforms Needs
npm macOS, Linux, Windows Node 22 or newer
PyPI macOS, Linux, Windows Python 3.9 or newer
Release archive macOS, Linux, Windows nothing
PowerShell installer Windows PowerShell
Go built from source Go 1.25 or newer

npm

npm install --global @brokkai/slopcop
slopcop --help

The tarball carries the release binary for every supported platform, so it needs no Go toolchain. npx @brokkai/slopcop runs it without installing it.

PyPI

pip install brokk-slopcop

pipx install brokk-slopcop or uv tool install brokk-slopcop puts it in an environment of its own. The wheels carry the release binary, so no Go toolchain is needed either. The package is brokk-slopcop because PyPI already has an unrelated project named slopcop; the command it installs is still slopcop, and python -m brokk_slopcop runs the same binary.

Release archive

Each release publishes slopcop_v<version>_<os>_<arch>.tar.gz (.zip on Windows) holding the binary, README.md, and LICENSE, plus a checksums.txt covering every archive. Download them from https://github.com/BrokkAi/slopcop/releases/latest and check the sha256 before unpacking:

ver=0.0.3; os=linux; arch=amd64   # darwin/arm64 on Apple silicon
base=https://github.com/BrokkAi/slopcop/releases/download/v$ver
curl -fsSLO "$base/slopcop_v${ver}_${os}_${arch}.tar.gz"
curl -fsSLO "$base/checksums.txt"
grep "${os}_${arch}" checksums.txt | sha256sum -c -   # shasum -a 256 -c - on macOS
tar -xzf "slopcop_v${ver}_${os}_${arch}.tar.gz" slopcop
sudo install -m 755 slopcop /usr/local/bin/slopcop

PowerShell installer

irm https://raw.githubusercontent.com/BrokkAi/slopcop/master/install.ps1 | iex

It takes the latest release, verifies the archive against checksums.txt, installs slopcop.exe to %LOCALAPPDATA%\Programs\slopcop, and adds that directory to the user Path. SLOPCOP_VERSION, SLOPCOP_INSTALL_DIR, and SLOPCOP_NO_MODIFY_PATH override its defaults.

Go

go install github.com/BrokkAi/slopcop/cmd/slopcop@latest

Go 1.25 or newer is required to build. A plain go install reports dev as its version; in a clone, make install stamps the version from git describe.

Enable it in an agent

The binary carries the agent skill that teaches a coding agent how to run slopcop. slopcop init installs it into each well-known skills directory whose harness is present, and names what it did:

Location Harness
~/.agents/skills/slopcop/ Codex, opencode
~/.claude/skills/slopcop/ Claude Code, opencode
$CODEX_HOME/skills/slopcop/, or ~/.codex/skills/slopcop/ Codex home

A skill that is already there is left alone by init, so running it again is safe. slopcop login and every check also install the skill in those directories, rewriting one that differs from the skill bundled into the binary, so an agent follows the instructions of the slopcop version it runs; local edits to an installed skill do not survive them. slopcop init --no-skill skips the install and any update of it.

Sign in

slopcop login                           # browser device flow
slopcop login --token "$SLOPCOP_TOKEN"  # existing credential, for CI and agents

The browser flow prints a URL and a code and stores the token once the login is approved. The service URL defaults to https://slopcop.com; --service, $SLOPCOP_SERVICE, or a stored value override it.

The credential lives in slopcop/config.json under the user config directory and is written owner-only. slopcop logout clears it.

Precedence:

Value Order
Service URL --service, $SLOPCOP_SERVICE, stored by slopcop login, https://slopcop.com
Token $SLOPCOP_TOKEN, stored value

Check

slopcop                          # check the change in the current checkout
slopcop check --format json      # same, machine-readable
slopcop --root ../repo --base HEAD~1

The base commit defaults to the merge base with the branch upstream, then the merge base with origin/HEAD, then HEAD. The service must already have the base commit in its clone; a missing one comes back as the service's base_not_found message and remedy.

Every run sends one check request, even when the working tree matches the base and the patch is empty. A clean result or a failure always comes from the service.

Flags:

Flag Meaning
--root PATH repository to check (default .)
--base REV base commit or revision for the change
--format human|json|sarif report format (default human)
--fail-on never|finding|note|warning|error exit-1 threshold for new findings (default finding)
--show-existing also list the findings that were already in the code
--policy PATH repository-relative .rqlp file to evaluate (repeatable)
--no-policy-discovery skip .slopcop/policies rules
--timeout DURATION how long to wait for the result (default 10m)
--verbose print the resolved request to stderr

What is sent

One git patch from the base commit to the working tree. An empty change is sent as an empty patch, not filtered out. 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.

The service owns the limits on what a check accepts. When a change is too large or touches too many files, the service's payload_too_large response is printed verbatim; the CLI does not impose its own limits.

Every check also runs the hosted catalog. Rules under .slopcop/policies/**/*.rqlp are added automatically unless --no-policy-discovery is set.

New and pre-existing findings

A check fails only on findings the change introduced or touched: the service marks a finding new when it is in a file the change writes and its lines meet a line the change added, or the line beside one it removed. Findings that were already in the code are counted, never fail the check, and are listed only with --show-existing. A change that introduces nothing exits 0, however many findings the repository already holds.

Ignore a false positive

Each finding a check reports carries an id. When a finding is a false positive, ignore it:

slopcop ignore 0f8fad5b-d9cb-469f-a165-70867728950e

That finding is not reported again for this repository. Ignoring covers that one finding, its rule plus its place in the code, in its repository for your workspace; the rule keeps reporting everything else. Ignoring a finding twice is fine. ignore uses the same login and service URL as a check, exits 0 with a one-line confirmation, and otherwise exits 2 with the service's message and remedy; finding_not_found means the id is unknown or comes from a check outside your workspace.

Output and exit codes

The service answers structured data; the CLI renders it. human prints one block per new finding, with an ID: line when the service names one, then the pre-existing ones with --show-existing, a summary line such as 1 new finding across 1 file(s); 72 already in the code (--show-existing lists them) | Analysis complete, and any omitted or incomplete checks. json prints status, baseCommit, summary (newFindings and existingFindings count the split), findings (each with new and its id), incomplete, and failure when the analysis did not complete. sarif prints a SARIF 2.1.0 log whose results carry baselineState new or unchanged and the finding id in properties["slopcop.findingId"]. --format and --show-existing only change the rendering, never the request, so the service answers the same check whichever is used.

Exit Meaning
0 Check completed; no new finding crossed the --fail-on level
1 A new finding crossed --fail-on
2 No new finding crossed --fail-on, but a check was incomplete; or the CLI or service failed
3 The check was still running when --timeout ran out

An inconclusive check fails the check only when it concerns a file the change writes. One about other files is listed on an Inconclusive outside the change line (inconclusiveElsewhere in json, a note notification in sarif) and never changes the exit code. A check that timed out counts wherever it is. The service can place an inconclusive check only once Bifrost reports which files it concerns; until then every one counts as in the change.

The service applies --fail-on and sets the status; the exit code follows it. 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 failOn is Bifrost's warning; pass --fail-on warning to match it. New findings that cross --fail-on exit 1 even when some check did not complete.

While the service answers check_running, the CLI waits the Retry-After 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 {"status": "pending", "retryAfter": 5, "message": …, "remedy": …} on stdout (sarif prints a run with slopcop.status pending). Running the same check again picks up the same analysis.

Service failures print the closed contract exactly: message, remedy, and any install URL. The codes, messages, and remedies are defined by the service in server/src/check.rs of BrokkAi/bifrost-service; the CLI does not rewrite them. The remedies name no client, so when one says to sign in the CLI adds the slopcop login command after it. A failed request prints no report on stdout.

API

The CLI calls POST <service>/v1/check with a bearer token:

{
  "repoUrl": "https://github.com/owner/name",
  "baseCommit": "0123456789abcdef0123456789abcdef01234567",
  "change": "<base64 git patch>",
  "selection": {"files": [".slopcop/policies/rule.rqlp"]},
  "failOn": "finding"
}

The service rejects any other field. The response carries status, baseCommit, applied, summary, findings, incomplete, and failure when the analysis did not complete. Against a service from before findings were marked new, the CLI treats every finding as new, as that service gated on all of them. Non-2xx responses carry code, message, remedy, retryable, and an optional installUrl.

Each finding in the response carries an id; a service from before findings could be ignored omits it.

slopcop ignore <id> calls POST <service>/v1/ignore with the same bearer token and {"findingId": "<id>"}, and gets back {"findingId": "<id>", "status": "ignored"}. Failures use the same closed contract, including finding_not_found.

slopcop login uses the device flow: POST /api/device returns a deviceCode, userCode, verificationUri, expiresIn, and interval, and POST /api/token returns 202 while pending or 200 with a token once approved. The polling codes are authorization_pending, slow_down, expired_token, and access_denied.

Development

make test        # go test ./...
make vet         # go vet ./...
make build       # bin/slopcop-<goos>-<goarch>
make cross-check # linux, darwin, and windows on amd64 and arm64
make npm-test    # node --test npm/test
make wheels      # pypi-dist/, one wheel per release target

Releases are tag-driven. Pushing a v*.*.* tag runs GoReleaser, which builds linux, darwin, and windows for amd64 and arm64, packages tar.gz archives (zip on Windows) with checksums.txt, and publishes the GitHub release. .goreleaser.yaml is the single source of truth; CI runs goreleaser check and a snapshot build on every change, and make release-check runs the same locally when GoReleaser is installed. The same tag push then packs @brokkai/slopcop from those release archives and publishes it to npm with trusted publishing, so the package needs no npm token.

The same tag also packs a wheel per release target from the binaries GoReleaser just built, installs the wheel for every platform GitHub can run, and publishes brokk-slopcop to PyPI with trusted publishing, so that package needs no PyPI token either.

Layout:

Path Purpose
cmd/slopcop process entry point
internal/cli cobra commands, selection, exit codes
internal/gitx remote canonicalization, base resolution, patch building
internal/service /v1/check client and the wire contract
internal/report human, JSON, and SARIF rendering from the structured response
internal/config stored service URL and token
npm launcher, packer, and tests of the @brokkai/slopcop package
packaging/pypi wheel packer and launcher of the brokk-slopcop package
skills/slopcop the agent skill the binary embeds and installs
docs/npm-publishing.md npm release flow and trusted publisher setup
docs/pypi-publishing.md PyPI release flow and trusted publisher setup
.goreleaser.yaml tag release build, archives, and checksums

Metadata

Release files for brokk-slopcop 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for brokk-slopcop 0.0.5
File Actions
brokk_slopcop-0.0.5-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details for brokk_slopcop-0.0.5-py3-none-win_arm64.whl
brokk_slopcop-0.0.5-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for brokk_slopcop-0.0.5-py3-none-win_amd64.whl
brokk_slopcop-0.0.5-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for brokk_slopcop-0.0.5-py3-none-musllinux_1_2_x86_64.whl
brokk_slopcop-0.0.5-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for brokk_slopcop-0.0.5-py3-none-musllinux_1_2_aarch64.whl
brokk_slopcop-0.0.5-py3-none-manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for brokk_slopcop-0.0.5-py3-none-manylinux_2_17_x86_64.whl
brokk_slopcop-0.0.5-py3-none-manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for brokk_slopcop-0.0.5-py3-none-manylinux_2_17_aarch64.whl
brokk_slopcop-0.0.5-py3-none-macosx_12_0_x86_64.whl Python 3 none macOS 12.0+ x86-64 Details for brokk_slopcop-0.0.5-py3-none-macosx_12_0_x86_64.whl
brokk_slopcop-0.0.5-py3-none-macosx_12_0_arm64.whl Python 3 none macOS 12.0+ ARM64 Details for brokk_slopcop-0.0.5-py3-none-macosx_12_0_arm64.whl

Total release size: 27.0 MB

Release files / brokk_slopcop-0.0.5-py3-none-win_arm64.whl

Download URL brokk_slopcop-0.0.5-py3-none-win_arm64.whl
Size 3.2 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
c161f0050cad56c66b49fe7cc47c550abc8d69615ef171fd09aa85c6d5dcec1f
BLAKE2b-256 checksum
How to use checksums
5d08d561a3020f6f95a572602fc86a36874282708d78d669725b33c0c5f27f26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-win_amd64.whl

Download URL brokk_slopcop-0.0.5-py3-none-win_amd64.whl
Size 3.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
dd0d76b3af53786c8f5f589fb31fbd6b13aaf951f4bde59acd12785ab4aee417
BLAKE2b-256 checksum
How to use checksums
c2ff3e7bc52570e39a25aa23b60e1916ab5c74c710d0ea84a6b2e7c48772c973
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-musllinux_1_2_x86_64.whl

Download URL brokk_slopcop-0.0.5-py3-none-musllinux_1_2_x86_64.whl
Size 3.5 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
c2764f9871322bf6a55d0cdc87e53a8e42cd6b959425409855d5be0e363b319e
BLAKE2b-256 checksum
How to use checksums
91af27c4ee558e7e2c55cfe077ffb34163dccc5367c39af1919048ece08a2318
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-musllinux_1_2_aarch64.whl

Download URL brokk_slopcop-0.0.5-py3-none-musllinux_1_2_aarch64.whl
Size 3.2 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
54d4f2a0b267c8817ca779a0a8dc825e49bc83e577e248a873b64e8030fd41d3
BLAKE2b-256 checksum
How to use checksums
817e5f1b935c0154c9afd27dd5ee89a6d9197aac110d09951fcf65cd377fb3ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-manylinux_2_17_x86_64.whl

Download URL brokk_slopcop-0.0.5-py3-none-manylinux_2_17_x86_64.whl
Size 3.5 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
af5f71b6cd6084b8c7602e744b666d76fc9035b85c6be1b8a08c197249a4164f
BLAKE2b-256 checksum
How to use checksums
b3dc66379f93b3e51e8f414ba1c4d91d78b3255fccf4824052669c5ec11608f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-manylinux_2_17_aarch64.whl

Download URL brokk_slopcop-0.0.5-py3-none-manylinux_2_17_aarch64.whl
Size 3.2 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
21893ce4fe73184d3da71cc24576f1bbd27f583c3b2263e41b02e74db74e688d
BLAKE2b-256 checksum
How to use checksums
7ae0505c83b3d0b0c9273544204c27c85e4b8917d3b642bd866c3bca1a6b6f40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-macosx_12_0_x86_64.whl

Download URL brokk_slopcop-0.0.5-py3-none-macosx_12_0_x86_64.whl
Size 3.5 MB
Tags Python 3 macOS 12.0+ x86-64
SHA-256 checksum
How to use checksums
aceacc9a172d00d2ef3526e775b21236663d18dda43e13eb60d57d77f2b8c4ea
BLAKE2b-256 checksum
How to use checksums
8e28ae6b98d79701a1f0e86d7c8756f6fbbdbdded689e1ff6eec3d4b4a46b0f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / brokk_slopcop-0.0.5-py3-none-macosx_12_0_arm64.whl

Download URL brokk_slopcop-0.0.5-py3-none-macosx_12_0_arm64.whl
Size 3.3 MB
Tags Python 3 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
f4aca78131fcf11c2df4aa3547fe4687822aa117923604a7781c552bea0626f0
BLAKE2b-256 checksum
How to use checksums
793b2a1ee97694271834d5704a6237b020d926b927ad0b3e48501be926a86be3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for brokk-slopcop 0.0.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for brokk_slopcop-0.0.5-py3-none-win_arm64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page