Skip to main content

CONFIGURATION LAYERS

The primitives that make up Swamp — models, 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 model 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. 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.

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.