Skip to content

The Config screen

Paddock’s instance config lives in paddock.config.yaml, with environment variables layered on top. Since v0.42 you don’t have to hand-edit that file: the Config screen — the gear at the bottom of the sidebar, at /config — reads the resolved config and writes the editable parts back.

Three things to know before you click Save

Section titled “Three things to know before you click Save”

This is the big one, and the screen says so in a banner that never goes away.

Paddock resolves its instance config once, at boot, and freezes it. Saving writes your changes to paddock.config.yaml on disk — it does not hot-apply them. The running process keeps the config it started with until you restart it. After a successful save the banner switches to a green “Saved to disk — these changes take effect only after the server restarts” confirmation, which is the honest version of a success message.

So the workflow is: change what you want, save, restart Paddock, verify.

2. An environment variable wins, and the screen tells you

Section titled “2. An environment variable wins, and the screen tells you”

Precedence is env → file → built-in default. A field that’s currently pinned by a PADDOCK_* variable renders read-only, showing the live value with an amber note:

Overridden by environment variable PADDOCK_SELF_MCP — edit that env var (and restart) to change it.

That’s not decoration. If the field were editable, saving it would write a value to the file that the environment variable would go on silently ignoring — a change that looks like it worked and doesn’t. Making it read-only is how the precedence stays visible.

The corollary: if you want to manage an instance from this screen, don’t also set that knob in the environment. Pick one layer.

The Advanced group is read-only by design: port, bind host, the data / projects / state / web-dist paths, the herdctl config path, the auth mode, and the GitHub client id. These are process and filesystem bindings — you change them by changing how the process is launched, not from inside the running app.

Auth is deliberately read-only too. A misconfigured auth mode can lock everyone — including you — out of the very UI you’d need to fix it, so v1 shows the mode and stops there. Change it via the environment or the config file, where you can also fix it without a browser.

GroupWhat’s in it
CurationThe three sweeper token budgets for OVERVIEW.md, CHANGELOG.md and CLAUDE.md.
SweeperMinimum interval between post-turn sweeps. Blank falls back to the 5-minute default.
CapabilitiesDrive mode, the offered-model list, native system prompt, the environment prompt, the three self-MCP gates, max spawn depth, schedule mutation, the hooks MCP, and the browser MCP. Most default off.
RecoveryThe chat recovery layers and their guards.
AttachmentsInbound upload master switch, size and count caps, allowed types.
BrandingName, logo, accent colour.
TranscriptionVoice-dictation mode, model, endpoint.
Git identityAuthor name and email for commits Paddock makes on a project’s behalf.
LoggingLog level.
AdvancedRead-only — see above.

Clearing an optional numeric field (leaving it blank) removes the key from the file, so it falls back to the built-in default rather than being pinned to zero.

Environment prompt (Capabilities) is the one multi-line field on this screen. It is appended to the system prompt of every keeper turn, and it exists because the agent otherwise has no idea where it is: on a default instance it runs on Claude Code’s stock preset, which is written for a terminal. Nothing tells it that its reply is rendered as GitHub-Flavored Markdown in a browser, that a bare #123 is dead text, or that mcp__paddock__send_file puts an image on screen.

The built-in text is deliberately two rules — show, don’t describe and make clickable things clickable — chosen from an audit of real chats rather than from first principles. Resist growing it; a long environment prompt is paid for on every single turn.

Unlike every other field here, blank is meaningful:

The box containsWhat happens
the built-in text, untouchedPaddock’s default is appended (the key stays out of your file, so you track future revisions of it)
your own textthat is appended instead — a full override, not an addition
nothing at allnothing is appended — the opt-out

“Restore default” (under the box, when your value differs) clears your override rather than pasting the text in, so you go back to tracking the built-in rather than pinning today’s copy of it.

Two interactions worth knowing:

  • It is orthogonal to “Native system prompt.” That switch picks the agent’s role prompt; this states environmental fact. The environment prompt rides on top of either. The one exception is drive mode batch, where it is withheld while the native prompt is on — see the note in Environment variables.
  • The text is not escaped or sandboxed. It is concatenated into a system prompt, so treat it as instructions you are giving the agent with full authority. It’s operator input, at the same trust level as the rest of paddock.config.yaml.

No field on this screen carries a secret value. That isn’t a masking rule applied at render time — the secret-bearing settings simply aren’t part of the surface at all, so they can’t appear in the API response in the first place. The transcription API key and the JWT/JWKS internals are the notable absences.

Two settings are marked sensitive and shown read-only because they’re semi-revealing rather than secret: the auth mode and the GitHub client id.

Deliver real credentials the way you deliver any other runtime secret — a secrets manager or a secrets file — not through this screen.

If you keep comments in paddock.config.yaml, they survive. The write round-trips the file through a YAML document parser rather than parse-then-restringify, so your comments, key order, and any keys Paddock doesn’t manage are all preserved. Only the fields you changed are touched.

The write is atomic — a temporary file in the same directory, then a rename — so a reader (or a crash) never sees a half-written config. If the file doesn’t exist yet, the first save creates it.

Validation happens server-side before anything is written: an unknown key, a read-only key, or a value the loader wouldn’t accept is rejected with a 400 naming the field and the reason, and nothing is written. The rules mirror the config loader’s own, so the screen can’t produce a file the loader would then quietly degrade.

Only fields you actually changed are sent, so a save is a patch, not a rewrite.