clawsweeper-review
Recipe card from the charly-check plugin (Commands — runtime CLI verbs).
clawsweeper-review — the review half of PR validation
Section titled “clawsweeper-review — the review half of PR validation”The contract
Section titled “The contract”clawsweeper-review runs ONE review of the tree mounted at /target against the base ref in
BASE_SHA, and prints the engine’s JSON to stdout. It is advisory: it never gates a merge,
never writes to GitHub, and is given no token.
docker run --rm --read-only \ -e OLLAMA_API_KEY -e CLAWSWEEPER_TARGET_REPO -e BASE_SHA \ -v "$PWD:/target:ro" \ ghcr.io/opencharly/clawsweeper-review:<calver>--local-range is the only mode this image offers. It reviews merge-base(base, HEAD)..HEAD,
refuses a dirty tree, and makes no GitHub reads or writes — which is what lets it run with the
PR tree mounted read-only and no credential.
The pins and why each one exists
Section titled “The pins and why each one exists”| Pin | Value source | What breaks without it |
|---|---|---|
CLAWSWEEPER_COMMIT |
this candy’s var: |
the engine and its prompt/schema would float |
NODE_VERSION |
24.x |
the engine requires Node >= 24 |
PNPM_VERSION |
12.4.1 |
the lockfile is frozen against it |
CODEX_VERSION |
0.162.1 |
Codex is the engine’s only runner; a different version changes the wire contract |
The model path (measured)
Section titled “The model path (measured)”Codex accepts only wire_api = "responses". Ollama Cloud serves stateless Responses at
https://ollama.com/v1, so the image writes:
model = "deepseek-v4.1-flash"model_provider = "ollama-cloud"[model_providers.ollama-cloud]base_url = "https://ollama.com/v1"env_key = "OLLAMA_API_KEY"wire_api = "responses"requires_openai_auth = falseProven with a tool call, not a completion: codex exec was asked to run uname -s && uname -m
and returned Linux / x86_64 from inside its sandbox. If a future Codex or endpoint change
contradicts this, re-run that probe before touching the candy.
The target profile
Section titled “The target profile”ClawSweeper refuses a repository it has no profile for. The candy appends a generic fallback
for owner opencharly, so any opencharly/<repo> resolves without a per-repo entry and an
upstream sync never conflicts with a local config edit. The candy asserts the entry exists.
Sandbox prerequisites
Section titled “Sandbox prerequisites”Codex’s read-only review sandbox uses bubblewrap, which needs unprivileged user namespaces. The
runner image (github-runner-ubuntu) sets
kernel.apparmor_restrict_unprivileged_userns=0 and kernel.unprivileged_userns_clone=1; a host
without those fails at browser-free sandbox setup, not in this engine.
Failure classes, kept distinct
Section titled “Failure classes, kept distinct”- Engine produced a verdict → the caller posts it.
- Provider never answered / empty completion → no verdict; the caller reports it as inconclusive and stays advisory.
- A missing tool in the image → the build-time
check:steps name it (node,pnpm,codex, the engine’s--help, the profile, the config, the entrypoint).

