-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
Caduceus resolves its config from the first of these that exists:
-
$CADUCEUS_CONFIG— an explicit path to a YAML file (the Hermes plugin path sets this). -
$HERMES_HOME/config.yaml, under thecaduceus:key (HERMES_HOMEdefaults to~/.hermes). -
~/.config/caduceus/config.yaml, under thecaduceus:key (the standalone fallback).
Everything below lives in a caduceus: block. A minimal
Hermes install works with no config at all — the defaults
are the sensible ones. You add keys when you want to change
behaviour.
| Key | Default | What it does |
|---|---|---|
watched_repos |
[] |
owner/repo slugs to poll. Empty means "discover everything the token can see" — set this if the account has repos you don't want automated. |
ticket_label_code |
🤖 auto-fix |
Label that marks a code ticket. The daemon polls for it; you create it in the target repos. |
ticket_label_investigation |
🤖 auto-fix-investigate |
Label that marks an investigation ticket. |
worker_command |
plugin bridge path | The exact argv used to run your worker. Required for standalone installs. |
worker_parallelism |
1 |
How many workers run at once per tick. |
max_issues_per_tick |
worker_parallelism × 4 |
How many issues one tick will claim before returning. 0 = drain the whole queue. |
worker_timeout_seconds |
3600 |
Hard kill for a hung worker (SIGTERM → SIGKILL). |
poll_interval_seconds |
120 |
Minimum cadence. Cron can fire faster; the daemon gates. |
state_dir |
$HERMES_HOME/caduceus-state |
Every on-disk artefact Caduceus owns lives here. |
dry_run |
false |
Preview mode: does everything except commit / push / comment / PR / label changes. Writes a .dry-run.md report instead. |
github_token |
null |
Leave it null. Prefer CADUCEUS_GITHUB_TOKEN (or GITHUB_TOKEN, or gh auth token) so the secret never sits in a YAML file. |
state_backend |
json |
json (default) or sqlite — switched by caduceus migrate-state --to-sqlite. |
A config that does something interesting:
caduceus:
watched_repos:
- acme/widgets
- acme/gadgets
worker_command:
- python3
- ~/.hermes/caduceus/worker-bridge.py
worker_parallelism: 2
dry_run: true # watch it work without touching GitHubThe daemon polls for two labels: code tickets
(🤖 auto-fix) and investigation tickets
(🤖 auto-fix-investigate). You create them in each target
repo:
gh label create "🤖 auto-fix" --repo acme/widgets
gh label create "🤖 auto-fix-investigate" --repo acme/widgetsLabel an issue with the code label and the daemon will eventually claim it, run the worker, and open a PR. Label it with the investigation label and the daemon runs the worker and posts the findings as a comment instead. Change the label names in config and you must update the repos at the same time — the daemon doesn't rename labels for you.
Fields you'll rarely touch, in one table. Each is read at config-load; changing them needs a daemon restart (cron restarts every 2 minutes, so edits land quickly).
| Key | Default | Meaning |
|---|---|---|
log_path |
<state_dir>/processor.log |
Structured daemon log. |
workdir_base |
~/projects |
Parent dir for repo clones. Caduceus does not clone missing repos — put each at <workdir_base>/<owner>/<repo>. |
http_timeout_seconds |
60 |
Per-GitHub-request budget. |
git_timeout_seconds |
300 |
Per-git-subprocess budget. |
transcript_max_bytes |
10 MiB |
Cap on captured worker output per run. |
run_retention_days |
30 |
How long inactive transcripts/results hang around. |
stale_run_hours |
1 |
Crash-recovery threshold: claims older than this get reaped and requeued. |
max_retries_per_issue |
3 |
Worker-failure budget before an issue goes Failed. GitHub/Git/rate-limit failures don't consume it. |
retry_backoff_seconds |
300 |
Wait between worker-failure retries. |
feedback_author_allowlist |
[] |
Logins (or numeric IDs) whose review comments are trusted. |
comment_ignore_patterns |
[] |
Regexes matched against comment author logins to exclude them. |
comment_forbidden_strings |
[] |
Substrings that get every outbound comment/PR title/body rejected before it's sent. This is the public-voice rule's teeth — see the FAQ. |
worker_env_allowlist |
curated | Extra env vars the worker may inherit. PATH/HOME/USER/SHELL/LANG/LC_ALL/TERM/TMPDIR + OPENAI_*, ANTHROPIC_*, OPENROUTER_*, OPENCODE_* by default. GitHub credential names are always denied — that is not configurable, ever.
|
api_base |
https://api.github.com |
Restricted to GitHub.com or a GHES host. Anything else is a config error, on purpose. |
max_issues_per_tick |
see above | Already covered. |
discovery_max_pages |
20 |
Pagination cap for repo/issue discovery. |
circuit_failure_threshold |
3 |
Consecutive failures before a destination's circuit opens. |
circuit_backoff_seconds |
30, 120, 600 |
Escalating waits between open-circuit retries. |
circuit_open_interval_seconds |
1800 |
How long a circuit stays open. |
circuit_max_degraded_seconds |
86400 |
Worst-case degraded window before hard reset. |
scheduler_lease_ttl_seconds |
60 |
Leader-lease TTL for the tick lock. |
worker_lease_ttl_seconds |
600 |
Claim lease before an issue looks stale. |
drain_timeout_seconds |
30 |
Grace period when shutting down mid-tick. |
repo_storage_root |
repos |
Where daemon-owned repository storage lives. |
executor_mode |
trusted_host |
Worker execution mode (trusted host, or OCI container isolation when configured). |
OCI keys (oci_*) |
— | Container-executor settings: CLI, image, pull policy (never/if_missing/always), stop/kill/reconcile timeouts. Only relevant if you run the OCI executor. |
-
CADUCEUS_CONFIG— explicit config path. -
CADUCEUS_DRY_RUN—1/true/yesforces dry-run;0/false/nodisables. Read every tick, so toggling is instant. -
CADUCEUS_GITHUB_TOKEN— the preferred way to give Caduceus its token. -
GITHUB_TOKEN,gh auth token— fallbacks, in that order. -
HERMES_HOME— overrides~/.hermes. Relative values are rejected.
The daemon redacts token-shaped values from its own logs. You don't need to scrub env dumps by hand.
Nearly everything is read once at startup and held. The one
exception: dry_run (and CADUCEUS_DRY_RUN) are read every
tick — flipping preview mode is a one-tick operation.
Everything else: edit, wait up to two minutes for the next
cron tick, done.
Caduceus docs
- Home — what it is, and the one rule
- Installation — get it running
- Configuration — the settings that matter
- The-Bridge — make the worker yours
- State-Recovery — when things go wrong
- Troubleshooting — fix it
- FAQ — quick answers