work/caduceus
in development · 2026
caduceus
label an issue. wake an agent. get a pull request.
a self-hosted rust daemon + hermes plugin. polls github for labeled issues, hands each one to a configurable ai harness in an isolated worktree, and finalizes the result as a branch + push + pr.
the story
caduceus is what happens when you stop pretending your ai agent is a chat partner and start treating it like a cron job that writes code.
the daemon owns everything deterministic: polling, claims, worktrees, timeouts, git, github, retries. the worker is a black box that reads env vars and exits with a code. they never share a library.
that contract is the whole point. you can swap the worker for opencode, codex, claude code, or your own custom script without touching the daemon. the daemon never imports a harness library; the harness never imports a github library.
what it does
- harness-agnostic — the bridge is a small python script you can edit. the daemon doesn’t care.
- worker sandbox is air-gapped: sanitized env, no github credentials ever reach the agent.
- deterministic infrastructure (etag-aware polling, posix flock queue, hard worker timeouts) keeps the plumbing boring on purpose.
- zero inbound networking. refuses to listen on any port. refuses to publish a comment with a hardcoded list of internal tool names.
decisions i’m proud of
▸ two processes, one contract
an llm call is non-deterministic. a state machine is not. the second you let either side reach into the other, you’ve bought a future where a stalled token stream holds your queue hostage. we didn’t buy it.
▸ the worker is a subprocess with env vars
caduceus doesn’t ship an "agent sdk". it ships `worker-bridge.py`. you can read it in a minute. you can replace it in an afternoon. the daemon is unopinionated about which model you call — because the daemon will outlive whichever model is hot this month.
▸ public-voice rule is enforced, not documented
the daemon refuses to post a comment that names internal tools. not because the rule is important in itself — because the rule is a forcing function to keep the agent’s voice something a stranger could read without a decoder ring.