Raccoon daemon · the forge-side reviewer

The Raccoon is hungry.
It works the night shift.

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.

Never auto-merges, never closes, never deletes. That is a source-level guarantee in the binary, not a config option someone can flip. The Raccoon posts exactly three advisory labels — Sober clean, Sober findings, Sober error — and stops. Merge authority stays with the human, because in the environments Sober is built for, the merge is a responsibility.

What the Raccoon watches

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.

Forgejo + GitLab
Signed webhooks, mention aliases, catchup for missed events.
Advisory labels
Sober clean, Sober findings, or Sober error.
Podman-ready
Sober Enterprise Container or Debian community image; scp + load, no public registry required.
Deploy anywhere
Container images integrate natively with Forgejo + GitLab for remote team forges — and run locally just as well. The systemd service is the natural fit for local machines; the plain binary works fine on a remote server.
[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
time=12:41:02 level=info msg="raccoon started" time=12:41:03 level=info msg="claimed review job" time=12:41:18 level=info msg="evidence stored" time=12:41:20 level=info msg="waiting idle"
The Sober Raccoon wearing a review vest at a workbench, pointing at a monitor that flags critical AI-generated slop in a code review, surrounded by review logs and a bowl labeled AI slop.
Review log #19 — slop detected, evidence stored, merge authority untouched.

raccoon.kdl — the daemon's allowlist

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.

Talk to the Raccoon from any MR comment

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.