Repository navigation
Assumptions and Deployments
William Koch edited this page Sep 30, 2026
·
12 revisions
Keryx is designed for one person on one machine. Review these assumptions before you decide where and how to run it.
-
One owner. There's no multi-user model anywhere. There's one
OWNER_NAME(what the prompts call you; blank means "the owner"), oneALLOWED_CALLERSlist, one PIN, one~/.config/keryx, one memory, one Slack DM, and one set of API keys. A second person who can call the number and knows the PIN isn't a second user. To Keryx, they're you. - Tasks run as you. They run with your full user permissions and never stop to ask for approval, and Codex runs without its sandbox. So anyone who can reach Keryx can run commands on this machine. Don't put it on a host you share.
-
Quiet hours use the machine's local time.
APPROVAL_QUIET_HOURSis compared with the machine's clock, so23:00-07:00means 11 PM to 7 AM on the host. If the host is in another time zone, set itsTZ. Keryx has no time-zone setting of its own. -
Running without a service manager is supported.
SERVICE_MANAGER=noneis a real mode. It's also whatautoresolves to when the process isn't running as the installed unit, for example akeryx serveyou started in a terminal, even on a machine where the service is installed too.autochecks how the process itself was started, not whethersystemctlorlaunchctlis onPATH. In this mode everything works except restarting. If you ask Keryx on a call to restart itself, it refuses on purpose, because stopping the process would leave nothing to start it again.keryx restartalso refuses when no unit is installed. This means a task that changes Keryx's code can't make the change take effect by restarting the service.keryx doctorreports which service manager it found, or that it found none. -
PROJECTS_ROOTis~/projectsunless you set it, and Keryx never creates it. Its subdirectories are the projects you can point a task at by name, and a task with no project starts there. If it isn't a directory, for example on a machine that keeps its code somewhere else, such a task starts inDATA_DIR/workspaceinstead, which only you can read. So does a task whose project directory was removed after it was queued.keryx doctorwarns while the root doesn't exist. -
gitis optional. A restart confirmation usesgit describeto say which version was running before and after. WithoutgitonPATH, or outside a checkout, the version shows as "unknown". Everything else still works. -
The phone is the only channel on
main, on macOS and Linux alike. Talking to Keryx locally on a Mac is in development on thefeat/local-wakewordbranch, and isn't part ofmain. -
The service sees the
PATHof the shell you installed it from. A service manager starts units with a barePATH, so the installers write your shell'sPATHinto them, along with the directories Keryx uses. The units log underSTATE_DIR. Install from the shell whose tools the tasks should have, and run the installer again after thePATHor the directories change. See Running as a Service. -
The optional voice tools are yours to turn on. Slack, email answers, billing, and
cluster stats are plugins. They're off until you install them, with
keryx setup→ Plugins orkeryx plugins install NAME. They live with your own tools inDATA_DIR/tools, outside the repository. Everything there runs inside the service, as you.cluster_statsassumes you log in to each cluster through an ssh ControlMaster, and asks only while that login is open. See Custom Tools. -
The phone channel needs a public hostname you control. That's a Cloudflare-routed
name for
cloudflared(used by the Linux installer andscripts/dev.sh), or a reserved ngrok domain (used by the macOS installer). Twilio must be able to reach the webhook, and the webhook URL must matchPUBLIC_HOSTexactly, or signature validation fails. -
Keryx doesn't text unless you turn it on.
SMS_ENABLEDisfalseby default, because many Twilio accounts have no SMS permission for their region, and every send would fail. With texting off, a finished task reaches you by an announcement during a call, by a call back, or at the top of your next call. If you turned thesend_to_slackplugin on, Slack is there when you ask for it. Keryx adjusts what it says to this setting: if you decline a call back, it tells you the answer will come in your next call. Outbound calls are unaffected, including the restart watchdog's alerts.
- Security Model — what the single-owner assumption means for who can reach what.
-
Running as a Service — the systemd and launchd units, and which one
SERVICE_MANAGERrefers to.
User documentation for Keryx.
For the threat model, see SECURITY.md;
for settings, the coding agents, and the tools, see docs/.
Apache-2.0, Copyright 2026 William Koch.
Setting up
Running it
Security and data
Tools and advanced features