Skip to content

Merge Strategies

ccpod merges configuration in layers. Each asset has a documented strategy so the result is predictable.

Merging happens across three independent axes — each has its own control:

AxisControlled byConfigurable?
ccpod settings (network, ports, services, env, claudeArgs)merge in .ccpod.ymlyes
CLAUDE.md contentconfig.claudeMd in .ccpod.ymlyes
.claude/settings.jsonno — always deep-merged, project wins on conflicts

They are separate flags because the assets have different merge semantics: CLAUDE.md is text (append vs. replace), settings.json is always deep-merged, and ccpod settings vary per asset type.

SettingWhereValuesDefault
merge.ccpod.ymldeep | overridedeep
config.claudeMd.ccpod.ymlappend | overrideappend
isolationprofile.ymltrue | falsefalse

merge: override makes the project config replace the profile entirely for the listed sections. merge: deep (default) layers the project on top of the profile per asset, with the rules below.

When the profile sets isolation: true, all project config is ignored — merge strategy, CLAUDE.md, settings.json, env keys, MCP ports, and .claude/ assets. The profile config is used as-is. See Profile Configuration.

AssetRule
settings.jsonDeep merge. Project wins on conflicting keys.
CLAUDE.mdProfile content first, then project appended. Set config.claudeMd: override to replace.
skills/Union. Symlinks are skipped.
enabledPluginsUnion. Project can add but not remove profile plugins (use merge: override to remove).
hooks/Arrays merged by event type.
marketplacesObject spread; project keys win.
servicesMerged by key. Project can add or replace specific sidecars.
env (forwarded var names)Union of both lists.
ports.listConcatenated.
network.allowConcatenated.
network.policyProject value wins if set.

Run-level flags take final precedence:

FlagEffect
--profile <name>Override which profile to use.
--env KEY=VALUEInject an env var (or override one already forwarded).
--rebuildForce image rebuild / repull regardless of cache.
--no-stateForce state: ephemeral for this run only.
--file <path>Headless mode via file. Path is normalized; absolute paths and .. traversals are rejected.
"prompt text"Headless mode via inline prompt. Mutually exclusive with --file.
-- <args>Flags appended verbatim to the claude command. Appended after claudeArgs from profile/project.
Terminal window
ccpod config show

The output shows the fully resolved ResolvedConfig: image, env (resolved key→value), ports, services, mounts, and the final merged config dir under /tmp/ccpod-<hash>/.