Precedence and merge rules
When the same setting appears in multiple places, later layers win, but only for the fields they actually set.
Effective order for loom config show
This is the precedence order for the effective config that loom config show
prints:
| Priority | Source |
|---|---|
| 1 | Built-in defaults |
| 2 | ~/.config/loom/config.yml |
| 3 | .loom/config.yml |
| 4 | Supported runtime env overlays |
Built-in defaults are minimal. Today the built-in default is:
| Key | Built-in default |
|---|---|
runtime.docker.workspaceMount | ephemeral_volume |
Supported env overlays
The env overlay layer is intentionally small. Today it includes:
LOOM_DOCKER_WORKSPACE_MOUNTLOOM_KEEPASS_DB_<ALIAS>_PATHLOOM_KEEPASS_DB_<ALIAS>_PASSWORD_ENVLOOM_KEEPASS_DB_<ALIAS>_KEYFILE_ENV
There is no matching env overlay for providers.op.serviceAccountTokenEnv. That
field comes from config files and stores the env var name Loom should read later.
How merge works
Loom merges the supported fields instead of replacing the whole tree:
runtime.docker.workspaceMountis a simple last-writer-wins value- KeePass aliases merge by alias name
- later layers replace only the KeePass alias fields they set
- empty env values are ignored instead of treated as overrides
For example, this user config:
providers:
keepass:
aliases:
team/app:
path: vaults/team-app.kdbx
passwordEnv: TEAM_APP_PASSWORD
combined with this repo config:
providers:
keepass:
aliases:
team/app:
keyfileEnv: TEAM_APP_KEYFILE
produces one effective team/app alias with all three fields merged.
Path resolution rules
KeePass path values from config files are resolved relative to the file that
declared them:
~/.config/loom/config.ymlvalues resolve relative to~/.config/loom.loom/config.ymlvalues resolve relative to.loom
Environment overlay paths are used as provided. Loom does not re-base them relative to the repo.
What changes during loom run --local
loom run --local uses the same layered config, but Docker mount mode has one
extra override above the layered result:
| Priority | Source |
|---|---|
| 1 | Built-in default ephemeral_volume |
| 2 | ~/.config/loom/config.yml |
| 3 | .loom/config.yml |
| 4 | LOOM_DOCKER_WORKSPACE_MOUNT |
| 5 | loom run --local --docker-workspace-mount ... |
That CLI flag affects the current run only. It does not change what
loom config show prints.
Quick examples
Repo default, user override
If .loom/config.yml sets:
runtime:
docker:
workspaceMount: bind_mount
and ~/.config/loom/config.yml sets:
runtime:
docker:
workspaceMount: ephemeral_volume
then loom config show prints ephemeral_volume.
Env override wins over files
If both config files exist but you run:
LOOM_DOCKER_WORKSPACE_MOUNT=bind_mount loom config show
the effective value becomes bind_mount for that process.
Execution-time detail that matters
During loom run --local, Loom fills in missing runtime env vars from the
effective config. If you already exported a concrete env var such as
LOOM_KEEPASS_DB_TEAM_APP_PATH or OP_SERVICE_ACCOUNT_TOKEN, Loom keeps that
existing value instead of replacing it with a default.