Configuration reference
The manager reads a single YAML file at ~/.config/agentarivm/agentarivm.yml (override with --config <path> or $AGENTARIVM_CONFIG). It is validated at startup and the process refuses to run on a bad config, loudly — a control plane for remote code execution should not start half-configured.
The file is policy: paths, allowlists, cadences, and setup profiles. Repositories themselves live in the manager’s database and are added at runtime with agentarivm project add; the projects: block here only refines them.
This page summarises the sections that matter. Defaults shown are the shipped ones.
real (default) or fake. In fake mode every external adapter — git, GitHub, the agent — is swapped for a deterministic double, giving you an offline development loop.
server
Section titled “server”server: host: 127.0.0.1 # loopback by default port: 8787 publicUrl: https://your-host.example:8443 # what pairing tells devices to talk to tls: mode: managed # off | managed | files requireClientCert: true extraHosts: [] # managed: extra names the server certificate must coverhost— loopback by default. Binding anything else while TLS is off is refused at config load, because the misconfiguration looks perfectly healthy from the inside while your tokens are on the wire in cleartext.publicUrl— the origin devices should use. The manager cannot guess this; it is whatagentarivm pairprints, so an unset value means a pairing code with no address attached.tls.mode—off(plain HTTP, right for loopback and tests),managed(the manager runs its own private CA, issues its own server certificate and one client certificate per paired device), orfiles(bring your own certificate, e.g. Let’s Encrypt — setcertFile,keyFileandclientCaFile).tls.requireClientCert— on by default whenever TLS is on. This is what turns strangers away during the handshake.trustProxyandallowInsecureBindexist for deployments with their own proxy in front; leave them off unless that describes you.
All required, no defaults — these are decisions about your disk:
paths: gitRoot: /home/agent/git # canonical clones worktreeRoot: /home/agent/worktrees # one worktree per session, under here secretsRoot: /home/agent/secrets # per-project secret files copied by setup profiles stateDir: ... # the SQLite database runtimeDir: ... # sockets, runtime files logDir: ...Every generated worktree path is checked to remain inside worktreeRoot.
git: executable: git # absolute path recommended on a deployed machine signing: off # off | ssh | inherit # signingKey: ~/.ssh/id_ed25519.pub # required by signing: ssh # authorName / authorEmail # override commit attribution; usually unsetsigning: off is the default deliberately: a global commit.gpgsign=true inherited on a headless machine makes every commit die inside gpg, because pinentry has no terminal to prompt on. ssh is the mode that works unattended.
github
Section titled “github”github: ghExecutable: gh requireWritePermission: true # only repos the gh user can push to may be added expectedAccount: your-login # refused at boot if gh is logged in as anyone else issueTaskLabel: agent-task # marks an issue as agent work issueReadyLabel: agent:ready # authorises a session for it issueWatch: enabled: false # off by default — see GitHub issue automation intervalSeconds: 60 allowedActors: [] # empty means NOBODY may authorise via labelPin expectedAccount: a manager authenticated as the wrong account works perfectly and simply does everything under somebody else’s name. See GitHub issue automation for issueWatch.
exec: path: /usr/local/bin:/usr/bin:/bin:/home/agent/.local/binThe PATH given to every subprocess, replacing the inherited one. Not optional in practice on a deployed machine: a daemon inherits a minimal PATH, and tools like gh and claude are shims that call node, which is not on it — they exit 127 with no explanation. Unset means inherit, which is right for a development machine. See Troubleshooting.
agent: claudeExecutable: /home/agent/.local/bin/claude permissionMode: bypassPermissions # maxBudgetUsd: 25 # hard ceiling per session; unset by default extraArgs: [] stopGraceSeconds: 10 preTrustWorktrees: falseclaudeExecutable is the agent itself. The manager runs one claude per session, for as long as the session lives, and talks to it over pipes — so an absolute path matters here more than anywhere else in this file.
permissionMode decides what an agent may do without asking, and the default is a real decision rather than an oversight. An unattended agent cannot answer a permission prompt, and anything short of bypassPermissions stalls it at the first git commit — so the honest options are “let it work inside its own worktree” or “do not run it unattended at all”. The blast radius is the worktree, on a machine whose entire purpose is running agents.
A question the agent genuinely asks still reaches you: it arrives in the app as a card, with whatever answers the agent suggested, and the session waits.
preTrustWorktrees pre-accepts Claude Code’s “is this a project you trust?” dialog for each new worktree. Off by default: the manager runs the agent in print mode, where the dialog is skipped, so this would write to ~/.claude.json before every session for a prompt that cannot appear. Turn it on only if a session ever hangs before producing any output.
session
Section titled “session”session: allowedModels: [opus, sonnet] allowedEfforts: [low, medium, high, max] defaultModel: opus defaultEffort: high staleMinutes: 20 # a running session with no activity is flagged launchTimeoutMinutes: 5 # stuck in `starting` this long → failed maxConcurrentPerProject: 3The app can only pick from the allowlists; there is no way to request an arbitrary model.
How often the manager re-reads reality — the trade between a responsive timeline and a machine that spends its day forking git and gh:
poll: enabled: true activeSeconds: 5 # a session that changed something recently idleSeconds: 30 # running but quiet pullRequestSeconds: 60 # waiting on review githubSeconds: 30 # floor between GitHub calls per sessionsetupProfiles and projects
Section titled “setupProfiles and projects”A setup profile prepares a worktree before the agent starts:
setupProfiles: none: {} # must exist; the default for new projects flutter: copyFiles: [.env] # copied from secretsRoot/<owner>/<repo>/ into the worktree setupCommands: - [flutter, pub, get] verifyCommands: # the definition of done, written into the prompt - [flutter, analyze] - [flutter, test] timeoutSeconds: 600Commands are argument arrays, never shell strings — nothing here is ever passed to sh -c.
The projects: block refines repositories already registered (or clones them at boot with bootstrap: true):
projects: owner/repo: displayName: My App components: - id: app dir: apps/mobile profile: flutter