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.
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, orSober 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
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.