Skip to main content

CONFIGURATION LAYERS

The primitives that make up Swamp — behaviors, workflows, vaults, extensions, skills, and data — need configuration to do useful work, and that configuration comes from four sources: .swamp.yaml (repo-level, checked into version control), swamp config set (user-level, stored in ~/.config/swamp/), environment variables prefixed with SWAMP_, and CLI flags. Precedence follows a strict order: CLI flags override environment variables, which override user config, which overrides repo config, which overrides built-in defaults.

This layering exists because different decisions belong to different scopes.

Repo config (.swamp.yaml) holds settings the whole team shares: which behavior types to trust, auto-GC policies, datastore backend selection. These belong in version control because they define how the repo behaves — changing the trusted collective list or the garbage collection window affects everyone who works in the repo. See the repository configuration reference for the full .swamp.yaml schema.

User config holds personal preferences: log verbosity, telemetry opt-out, default output format. These should not be version-controlled because one developer's preference for debug-level logging shouldn't force that on the rest of the team.

Environment variables provide the override layer for CI/CD pipelines and scripted environments. Swamp uses the SWAMP_ prefix convention — variables like SWAMP_REPO_DIR, SWAMP_LOG_LEVEL, SWAMP_NO_TELEMETRY, and SWAMP_DATASTORE — so there is no ambiguity about which env vars belong to Swamp versus the surrounding toolchain. The one deliberate exception is DO_NOT_TRACK, covered below. Env vars always win over both config files, which means a CI pipeline can force specific settings without forking the repo's .swamp.yaml or modifying user config on ephemeral runners.

CLI flags sit at the top of the precedence chain for one-off overrides: a developer running a single command with --log-level debug shouldn't need to change any persisted configuration.

Serve-specific config: .swamp/serve.yaml

swamp serve adds a fifth source that sits alongside the repo-level .swamp.yaml: a server config file at .swamp/serve.yaml (or a custom path via --config). It exists because the settings it holds — port, timeouts, webhook registrations, multi-instance tuning — are operational concerns of a running server instance, not properties of the repository's shared behavior/workflow definitions. A team's .swamp.yaml travels with the repo and belongs in version control; a server's bind address and TLS proxy settings vary per deployment and do not.

The serve config file occupies the same precedence slot as .swamp.yaml — below environment variables and CLI flags, above built-in defaults. Within that slot the two files are complementary, not competing: .swamp.yaml configures the repo, .swamp/serve.yaml configures the server. Security-sensitive settings (authentication mode, admin identity, TLS certificates) are excluded from the serve config file entirely and remain CLI-only or environment-variable- only.

See Serve Flags — Config file for the full schema and supported keys.

Telemetry opt-outs

Usage telemetry is the one setting that does not follow this precedence. Its opt-outs — the user's telemetry.collection, a repository's telemetryDisabled, SWAMP_NO_TELEMETRY, DO_NOT_TRACK, and --no-telemetry — combine rather than override each other. If any layer says off, telemetry is off, and no layer can turn it back on.

An opt-out is a statement of consent, and consent belongs to the person it concerns. Under ordinary precedence, SWAMP_NO_TELEMETRY=0 in a shared CI template would outrank a developer's own user setting, and a repository's .swamp.yaml, committed by someone else, would decide for everyone who clones it. Earlier versions of Swamp had a version of this problem: the user-level opt-out was read only outside repositories, so it stopped applying at the first repository a user worked in. Making every opt-out final means each layer can only widen what is switched off. A user who opts out is opted out in every repository, and a team that opts out a repository covers everyone who works in it, whatever their own setting.

DO_NOT_TRACK breaks the SWAMP_ prefix convention on purpose. It is a cross-tool variable: set once in a shell profile or a CI image, it opts out of every tool that honours it, so a user does not have to find each tool's own switch.

See the Usage Telemetry reference for each opt-out and its scope.

Tradeoffs

The tradeoff this design makes is explicitness over convenience. Rather than merging configuration from implicit locations, each layer has a clear scope and a predictable override relationship. When something behaves unexpectedly, the precedence order tells you exactly where to look.