Docs

Everything you need: install, what the checks catch, how to configure, and how to read a receipt. Five minutes, start to finish.

Install

  1. Go to github.com/apps/codecop-codes and click Install.
  2. Pick the repositories to watch (or all of them).
  3. Done. The next pull request on those repos gets a verdict. No configuration required.

Codecop asks for the minimum permissions that make a review possible: read contents, read metadata, write pull request comments, write checks.

The three checks

CheckSeverityWhat it catchesWhat keeps it quiet
deps-exist HIGH Dependencies and imports added by the PR that do not exist on npm or PyPI - hallucinated packages and typosquats. Evidence includes the registry URL that returned 404. Only added lines are checked. A network timeout never flags. Private scoped packages (@yourcorp/...) are skipped, requirements files pointing at private indexes are skipped whole, and Python source imports are never guessed at (the package for import cv2 is opencv-python).
secrets HIGH Credentials on added lines - tokens, cloud keys, private key blocks - detected by gitleaks rules. Generic high-entropy matches report as MEDIUM. Only added lines are scanned, so deleting a leaked key is never punished. Lockfiles and minified bundles are skipped. Matches are redacted to first and last four characters before anything is stored or posted.
test-theater MEDIUM Tests that verify nothing: new test blocks with zero assertions, tautologies (expect(x).toEqual(x), assert True), and skips added in a PR that also changes source code. JavaScript, TypeScript, and Python. Only tests the PR adds are judged - pre-existing tests are never dredged up. Anything assertion-shaped counts (expectValidUser(), ava's t.*, throw-based tests). skipif platform gates and pytest fixtures are exempt. A file that fails to parse is skipped silently.

Verdicts and check conclusions

The receipt

One sticky comment per PR, rewritten in place on every push - never a pile of comments. It carries the verdict, the exact commit, an evidence table, what your config suppressed, and a collapsed machine-readable JSON copy:

{
  "version": 0,
  "engine_version": "0.1.0",
  "repo": "you/service",
  "pr": 14,
  "head_sha": "dbc82b4...",
  "verdict": "HIGH",
  "ai": { "authored": true, "agent": "Claude Code" },
  "mode": "advisory",
  "config_hash": "3329969eb316",
  "suppressed_count": 0,
  "checks": [
    { "id": "deps-exist", "duration_ms": 56, "findings": [ ... ] }
  ]
}

The same JSON rides inside the Check Run, so the agent that wrote the PR can read the verdict and fix its own mistakes without parsing markdown.

Codecop also tags whether the PR was AI-authored (bot account, agent branch prefix, Co-Authored-By trailer, or a "Generated with ..." footer) and names the agent.

codecop.yml

Optional. Put it on your default branch - Codecop deliberately ignores the PR's own copy, so a pull request can never weaken the gate that judges it.

version: 1
mode: advisory            # advisory | enforce
checks:
  deps_exist: true
  secrets: true
  test_theater: true
ignore:
  paths: ["vendor/**", "dist/**"]        # excluded from review entirely
allow:
  packages: ["@mycorp/*"]                # private registry packages
  secrets_paths: ["tests/fixtures/**"]   # dummy keys that are supposed to be there
  assertion_helpers: ["expectValid"]     # custom matchers that count as assertions

Unknown keys are rejected loudly: the PR gets a neutral receipt explaining the exact config error instead of a silent wrong review. Suppressed findings are counted on every receipt - the gate never hides what it was told to ignore.

Privacy and safety

FAQ

Will it spam my PRs like other review bots?

No. One comment, updated in place. No inline review comments, ever - at most 10 annotations in the checks tab. If nothing is wrong, the verdict is a quiet green LOW.

What about PRs written by humans?

Same checks, same verdict. The AI-authorship tag is informational today; it exists so your policies (and our reporting) can treat agent PRs differently later.

Huge PRs?

Above 300 changed files or 5MB of diff, Codecop posts an honest "too large for v1" receipt instead of pretending it reviewed everything.

My private packages get flagged?

They should not - scoped packages are skipped by default. If you use unscoped internal names, add them to allow.packages. Every suppression is counted on the receipt.