Overview
Rousseau's design makes one daemon per project the safest posture: distinct state.path, distinct agent.skills_dir, distinct provider credentials, distinct approval rules. But it's not the only option — a single daemon with multiple bind mounts also works if the trade-offs suit you.
Options
Recommended for platform teams.
Each project gets its own:
- Config file (
/etc/rousseau/projects/<slug>/config.yaml). state.pathunder/var/lib/rousseau/<slug>/.- Systemd unit (
rousseau-<slug>.service). - Provider credentials (env or LoadCredential).
Pros:
- Clean blast radius: one project's compromise does not touch another's session store.
- Per-project cost accounting: LLM spend maps cleanly.
- Independent restart cadence — upgrade one at a time.
Cons:
-
More processes to monitor.
-
More systemd units to templatise.
Fine for solo operators; risky for platform teams.
One daemon, one config, one state.path, one workspace bind mount that contains every project.
Pros:
- Minimal footprint.
- One place to update the provider.
Cons:
-
Every prompt sees every project. Approval rules must be very tight.
-
Cost accounting is per-user, not per-project.
-
Data-store nuking affects everyone.
Templatising with systemd
# /etc/systemd/system/rousseau-slack@.service
[Unit]
Description=Rousseau Slack bridge for %i
After=network-online.target
[Service]
User=rousseau
WorkingDirectory=/var/lib/rousseau/%i
EnvironmentFile=/etc/rousseau/projects/%i/secrets.env
ExecStart=/usr/local/bin/rousseau --config /etc/rousseau/projects/%i/config.yaml slack
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
systemctl enable --now rousseau-slack@alpha.service
systemctl enable --now rousseau-slack@bravo.service
Directory conventions
/etc/rousseau/projects/<slug>/config.yaml
/etc/rousseau/projects/<slug>/secrets.env
/var/lib/rousseau/<slug>/sessions.db
/var/lib/rousseau/<slug>/whatsapp.db
Verification
-
systemctl list-units 'rousseau-*.service'shows one unit per project. -
ls /var/lib/rousseau/*/sessions.dbshows one file per project, distinct sizes. - A search in one project's
rousseau session searchdoes not return the other project's hits.
Failure modes
- Shared state.path — the biggest mistake. Two units read/write the same DB; results are undefined. Enforce distinct paths in a smoke-test.
- Skills bleed — if you share
agent.skills_diracross projects and one skill references project-specific paths, it will misfire. - Session store growth — plan an rsync/backup rotation per project. See Best Practices: Disaster recovery.