Skip to content

Configuration

Shepherd is configured entirely through environment variables (read in src/config.ts). Per-deployment overrides go in ~/.shepherd/env (KEY=value lines), read by the systemd unit if present.

VariableDefaultPurpose
SHEPHERD_PORT7330HTTP/WS listen port
SHEPHERD_HOST127.0.0.1Bind address; loopback-only by default (set 0.0.0.0 to expose all NICs)
SHEPHERD_DB~/.shepherd/shepherd.dbSQLite session store path
SHEPHERD_REPO_ROOT~ (home)Repos must live under this root (spawn is confined to it)
SHEPHERD_ALLOWED_HOSTSlocalhost,127.0.0.1,::1,[::1]Comma-separated origin hostnames allowed for writes + WS (CSRF/CSWSH guard)
SHEPHERD_TOKEN(none)When set, require Authorization: Bearer <token>
HERDR_BINherdrPath to the herdr binary
HERDR_SESSIONdefaultherdr session name
SHEPHERD_FORGES~/.shepherd/forges.jsonPath to the git-host config
SHEPHERD_SANDBOX_DEFAULT_PROFILEtrustedDefault sandbox profile for every spawned agent (trusted / standard / autonomous) — see below
SHEPHERD_TRIM_AUTO_CONTEXTtrueTrim the per-turn context of auto-spawned (drain) agents (skill catalog + optional plugins disabled per-spawn). Interactive sessions untouched. Set false/0/off if drain quality regresses
VariableDefaultPurpose
SHEPHERD_PREVIEW_PORT_BASE8001First port in the live-preview range (one port per agent preview)
SHEPHERD_PREVIEW_PORT_COUNT16Size of the preview range and max concurrent previews
SHEPHERD_PREVIEW_SWEEP_MS4000Cadence (ms) of the dev-port detection sweep across active sessions
SHEPHERD_PREVIEW_AUTO_SERVEtrueDynamically register/unregister tailscale serve mappings as previews bind/tear down; set 0 to map the range manually
SHEPHERD_PREVIEW_IDLE_STOP_MS0 (disabled)When > 0, an idle previewed dev server with no proxy traffic for this many ms is stopped to reclaim RAM (no auto-wake; suggested 1800000 = 30 min)
VariableDefaultPurpose
SHEPHERD_NODE_COMPILE_CACHE(disk dir)Node compile-cache dir (kept off the /tmp tmpfs)
SHEPHERD_TMP_INODE_PCT80Inode-sweep threshold (% of /tmp inodes)
SHEPHERD_TMP_STALE_HOURS24Scratch staleness cutoff
SHEPHERD_TMP_SWEEP_DIR(default tmp root)Override the swept tmp root

See Operating Shepherd for the host-level /etc/fstab belt.

Documentation automation (PR-gated doc agent)

Section titled “Documentation automation (PR-gated doc agent)”

Opt-in, default-off. When enabled, a manual trigger (POST /api/doc-agent?repo=<path>) spawns a tightly-scoped Claude Code agent that diffs recent source changes against the hand-written docs and edits the enumerated prose pages in place. It is granted read-only git (git diff/log/show/status) for grounding plus file edits, but has no git mutation, gh, or network access, so it can neither commit nor push; the trusted server stages the in-scope doc files, commits, and opens a pull request for human review (never an auto-merge). Off by default; flip on per deployment to soak it.

Automated cadence. With the same flag on, two triggers run in addition to the manual one (a per-repo in-flight guard means at most one run per repo at a time):

  • Nightly — once per local day per repo that has the docs tree, at/after SHEPHERD_DOC_AGENT_NIGHTLY_HOUR (default 3). It first freshens the repo’s default branch from origin, then spawns a run only if the branch advanced since the last doc-agent run — quiet days cost a cheap fetch but no agent spawn. This is the reliable catch-all: it picks up any landed change, including fix: commits, config-only changes, and human/non-session or non-conventional merges (e.g. epic-landing PRs).
  • Merge-triggered — when a Shepherd-managed session’s PR merges to the default branch and its title is a feat/config conventional-commit subject, a run is considered immediately (the fast path). A doc-relevant fix: is intentionally not caught here — it’s covered by the nightly sweep instead. config (type or scope) is a forward-looking allowance and may not yet appear in a given repo’s history. Non-conventional or untitled merges simply fall through to nightly.
VariableDefaultPurpose
SHEPHERD_DOC_AGENT0 (off)Set 1 to enable the doc agent: manual trigger, nightly + merge-triggered cadence, and the boot orphan-sweep
SHEPHERD_DOC_AGENT_MODEL(none)Model alias for the doc-agent spawn; unset uses the spawn default
SHEPHERD_DOC_AGENT_NIGHTLY_HOUR3Local hour (0–23) at/after which the nightly sweep evaluates each repo; invalid values fall back to 3

Shepherd can wrap each spawned claude process in an OS-level filesystem/process sandbox via bubblewrap (bwrap). Three profiles are selectable per-repo in the repo’s Settings panel or globally via SHEPHERD_SANDBOX_DEFAULT_PROFILE:

ProfileSandboxNotes
trustedNoneDefault; today’s behavior. Escape hatch when the membrane causes problems.
standardbwrap membraneAgent confined to its worktree + git object store + read-only ~/.claude; blocks ~/.ssh, ~/.aws, sibling repos, other $HOME dotfiles; clears inherited env secrets. Does not restrict network egress. Opt-in for interactive sessions.
autonomousbwrap membrane + egress allowlistSame membrane as standard, plus network-egress confinement (outbound restricted to an allowlist: Anthropic + the forge host + operator extras). Required for auto=true drain/autopilot sessions.

Egress confinement is tied to the profile, not to auto=true. When no sandbox backend is available, manually spawned sessions degrade to unconfined with an operator-visible banner, and auto=true spawns are refused. The full residual posture — the accepted in-membrane token-readability gap and the prompt-injection posture — is documented on the Security page.

Backend requirements: bwrap installed + unprivileged user namespaces enabled. Shepherd self-tests at startup.

A few runtime toggles live in the SQLite settings table (~/.shepherd/shepherd.db) rather than env — e.g. branchPruneEnabled (hourly cleanup of merged local shepherd/* branches, on by default).