Coverage you can check
Large diffs are reviewed in bounded chunks, including files larger than one chunk. Unreviewed files are named and coverage stays incomplete; synthesis cannot turn a gap into a clean review.
Raccoon daemon · the forge-side reviewer
It forages every diff for AI slop (the confident-but-wrong output a model produces under pressure) and it eats bugs for breakfast. It drains webhook queues, reviews allowlisted repos, stores evidence, and posts advisory notes. It never merges, never closes, never deletes. It reviews, and the human decides.
Sober in review, Sober clean,
Sober findings, Sober blocked,
or Sober error — and stops. Merge authority stays with the
human, because in the environments Sober is built for, the merge is a
responsibility.
The raccoon is the daemon: a quiet background worker that drains webhook queues, reviews allowlisted repos, stores evidence, and posts advisory forge notes. It does not auto-merge, close MRs, or delete branches.
Sober in review, Sober clean, Sober findings, Sober blocked, or Sober error.[Service]
ExecStart=/usr/local/bin/sober raccoon run \
--repo /srv/repo \
--profile background
Restart=on-failure
Nice=10
IOSchedulingClass=idle
gunzip -c sober-ee_latest_linux_amd64.tar.gz | podman load
podman run --rm \
-e SOBER_SECRETS_BACKEND=env \
--env-file /etc/sober/secrets.env \
-v /etc/sober/raccoon.kdl:/etc/sober/raccoon.kdl:ro \
-v /var/lib/sober:/var/lib/sober \
localhost/sober-enterprise:latest \
raccoon forge catchup --once
*/5 * * * * cd /srv/repo && \
sober raccoon run --once --json \
>> .sober/raccoon.log 2>&1
The daemon only acts on repos you name. The
/etc/sober/raccoon.kdl file is a plain-text KDL with
one stanza per repo:
provider "forgejo"
token_env "FORGEJO_TOKEN"
workdir "/var/lib/sober/repos"
store_root "/var/lib/sober/stores"
repo "janus/janus-lang" remote="/opt/forgejo/data/forgejo/git/repositories/janus/janus-lang.git" branch="unknown" review_on_push=true
repo "libertaria/libertaria-stack" remote="/opt/forgejo/data/forgejo/git/repositories/libertaria/libertaria-stack.git" branch="main"
repo "libertaria/dmp" remote="/opt/forgejo/data/forgejo/git/repositories/libertaria/dmp.git" branch="master" disabled=true # opt-out
The branch field defaults to whatever the forge
considers the default branch. review_on_push=true
turns bare pushes into review runs (default false — the daemon
only reviews PR/MR lifecycle events). disabled=true
opts a repo out of every cycle while keeping it in the
doctor allowlist so the opt-out is auditable. Full field
reference lives in
docs/connectors-and-routes.md.
More pull requests need clearer evidence and a fair queue.
Large diffs are reviewed in bounded chunks, including files larger than one chunk. Unreviewed files are named and coverage stays incomplete; synthesis cannot turn a gap into a clean review.
Workers take turns across repositories. A moved PR head replaces its queued review, while transient provider throttles get bounded retries. Review receipts show the triggering request and revision.
A failed model request gets a job reference, not a fabricated finding against the code. Administrators can inspect provider attempts while credentials stay out of public failure comments.
CE and EE quarterly images run on Linux AMD64 and ARM64. The client also ships Debian 12/13 packages and Nix support on both; Arch/AUR serves AMD64.
On any repo it watches, mention @sober to explain a
finding, summarize a review, rerun a review, or record a
false-positive verdict — all recorded in evidence, all advisory.