Skip to main content

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:

PrioritySource
1Built-in defaults
2~/.config/loom/config.yml
3.loom/config.yml
4Supported runtime env overlays

Built-in defaults are minimal. Today the built-in default is:

KeyBuilt-in default
runtime.docker.workspaceMountephemeral_volume

Supported env overlays

The env overlay layer is intentionally small. Today it includes:

  • LOOM_DOCKER_WORKSPACE_MOUNT
  • LOOM_KEEPASS_DB_<ALIAS>_PATH
  • LOOM_KEEPASS_DB_<ALIAS>_PASSWORD_ENV
  • LOOM_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.workspaceMount is 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.yml values resolve relative to ~/.config/loom
  • .loom/config.yml values 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:

PrioritySource
1Built-in default ephemeral_volume
2~/.config/loom/config.yml
3.loom/config.yml
4LOOM_DOCKER_WORKSPACE_MOUNT
5loom 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.