TimoBy Amotion AI

Configuration Management: CCDV-F study guide

CCDV-F · Applications and Integration, topic weight 4.1% of the exam

Configuration Management sits in Domain 2, Applications and Integration, the largest CCDV-F domain at 33.1% of the exam. This topic carries 4.1%. It tests whether you can keep a Claude system predictable as it changes: the right settings file for each setting, a pinned model, versioned prompts and plugins whose dependencies cannot break you on update.

What the official guide covers

The Claude Certified Developer Foundations exam guide (version 1.0, effective July 2026) describes this topic as configuration management for Claude system components:

What the guide listsWhat it means in practice
CLAUDE.md filesInstruction files committed with the project; the hierarchy is covered in CCAR-F 3.1
settings.jsonChoose the right scope (user, shared project, project local, managed) and know which value wins
Model version pinningUse full model IDs, not moving aliases, wherever behaviour must not change without a test
Prompt versioningTreat system prompts and agent definitions as versioned artefacts with review, tests and controlled rollout
Plugin dependenciesDeclare which plugins yours needs and constrain their versions so an upstream release cannot break it

settings.json: which file, and which value wins

Claude Code reads settings from four files plus managed settings:

ScopeFileWho it affectsUse it for
User~/.claude/settings.jsonYou, in every projectPersonal preferences
Shared project.claude/settings.jsonEveryone who clones the repository, once committedTeam permissions, hooks, plugins, environment variables
Project local.claude/settings.local.jsonYou, in this project only; kept out of gitPersonal overrides and testing
Managedmanaged-settings.json, MDM policy or server-managed settingsEveryone the organisation deploys it toSecurity and compliance policy

When a key is set in several places, the highest level wins: managed, then command-line arguments (--settings, --model), then project local, shared project and user. List keys such as permissions.allow merge across files. Some committed keys (permissions.allow, extraKnownMarketplaces, most env values) wait until each teammate trusts the folder; deny and ask rules apply at once. Run /status to see which files loaded and claude doctor to see rejected entries. Settings files are strict JSON.

Permission rules follow a different rule from ordinary keys. Claude Code checks deny rules first, then ask, then allow, and the first match decides. Scope does not change that order: a deny in any file blocks a call that an allow in any other file approves, and a broad deny such as Bash(aws *) cannot be narrowed by a more specific allow. Deny rules also hold in every permission mode, including bypassPermissions. That is why an organisation-wide block belongs in a managed deny rule: no developer file can lift it.

A team file that pins the model, sets permissions and installs a plugin:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "sonnet",
  "env": {
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "<full Sonnet model ID your team has tested>"
  },
  "permissions": {
    "allow": ["Bash(npm run lint)", "Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  },
  "extraKnownMarketplaces": {
    "acme-tools": { "source": { "source": "github", "repo": "acme/claude-plugins" } }
  },
  "enabledPlugins": {
    "deploy-kit@acme-tools": true
  }
}

Replace the placeholder with a real model ID. In the Agent SDK, setting_sources=[] stops these files loading at all.

Model version pinning

On the Claude API, a model ID names a fixed model: when you use a model ID in a request, the model behind it stays the same for the lifetime of that ID, and each ID has its own deprecation and retirement schedule. Newer models use IDs without a date, and each of those is a fixed snapshot. Some older models also have short aliases that point to the most recent dated snapshot, so an alias can change what you get.

Claude Code adds its own aliases: opus, sonnet and haiku point to the recommended version for your provider and update over time. To pin, use a full model name (for example in --model or the model setting) or set ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL or ANTHROPIC_DEFAULT_HAIKU_MODEL. The documentation tells teams deploying through Amazon Bedrock, Google Cloud's Agent Platform or Microsoft Foundry to pin versions before rolling out to users, because an alias resolves to a built-in default for each provider.

Claude Code picks the model in this order: /model, --model, ANTHROPIC_MODEL, the model setting, ANTHROPIC_DEFAULT_MODEL, then the account default. Administrators restrict choices with availableModels.

Prompt versioning

A system prompt is code that changes behaviour, so manage it like code:

  1. Keep prompts in files in the repository, not inline strings scattered through the codebase. Claude Code can load them with --append-system-prompt-file or --system-prompt-file; the Agent SDK accepts a file path for system_prompt.
  2. Change them through pull requests, and run your evaluation set against the new version before merging.
  3. Record the prompt version alongside each request in your logs, so a change in output can be traced to a change in prompt.
  4. Change one thing at a time: a new prompt and a new model in the same release make failures impossible to attribute.

Claude Managed Agents builds versioning in. An agent's configuration (model, system prompt, tools, MCP servers, skills) is a versioned resource: the version starts at 1 and increases each time an update changes the agent. Passing the agent ID as a plain string starts a session on the latest version. Passing an object pins the version, so you can stage a rollout:

pinned_session = client.beta.sessions.create(
    agent={"type": "agent", "id": agent.id, "version": 3},   # stays on version 3 until you move it
    environment_id=environment.id,
)

Roll a change forward on evidence, back in one line

Pinning only pays off if releases use it. Treat a new model ID, a new prompt file or a new agent version the same way:

  1. Keep the current pinned value recorded, so rollback is a one-line change rather than a hotfix.
  2. Run your evaluation set on the candidate and compare it with the score the current version holds.
  3. Send a small share of traffic or sessions to the candidate and watch the same metrics.
  4. Promote by moving the pin, or roll back by restoring the recorded value.

The failure this prevents: a deployment on a moving alias changes output format overnight, a parser breaks, and there is no earlier pinned value to return to.

Plugin dependencies

A Claude Code plugin declares the plugins it needs in the dependencies array of .claude-plugin/plugin.json. An entry can be a bare name (resolved in the same marketplace), "name@marketplace", or an object with a semantic-version range:

{
  "name": "deploy-kit",
  "version": "3.1.0",
  "dependencies": [
    "audit-logger",
    { "name": "secrets-vault", "version": "~2.1.0" }
  ]
}

Without a range, a dependency moves to each new release. With ~2.1.0, it installs at the highest git tag in the range (tags look like <plugin-name>--v<version>), so users get 2.1.x patches but never 2.2. If two plugins need ranges that do not overlap, the second install fails. A dependency from another marketplace installs only if the root marketplace allows it in allowCrossMarketplaceDependenciesOn. Run claude plugin validate in CI and claude plugin list to see resolved versions.

Shared configuration must work on someone else's machine

A plugin can install cleanly everywhere and still fail everywhere except on its author's laptop. Installing copies files; running resolves paths and variables on the machine that runs them. Three habits close the gap:

  • No machine-specific paths. Reference bundled scripts with ${CLAUDE_PLUGIN_ROOT} and project scripts with ${CLAUDE_PROJECT_DIR}, never /Users/<name>/.... Both resolve in hook commands, MCP server config and skill content; in a skill, write the braced form in the text, because commands Claude runs through the Bash tool do not receive these variables.
  • Declare what the user must supply. A required token goes in the manifest's userConfig; marked sensitive, it is kept in the platform's secure credential store rather than settings.json. An undocumented variable in the author's shell profile surfaces only mid-run.
  • Keep secrets out of committed files. .mcp.json expands ${VAR} in url, headers, command, args and env, so the file holds a reference and the value stays in the environment. A key committed inline stays in git history after you remove it, so treat it as exposed and rotate it.
{
  "mcpServers": {
    "warehouse": {
      "type": "http",
      "url": "https://warehouse.internal/mcp",
      "headers": { "Authorization": "Bearer ${WAREHOUSE_MCP_TOKEN}" }
    }
  }
}

A plugin also carries only what it bundles. Its own settings.json applies just the agent and subagentStatusLine keys, so a deny rule in the author's settings does not travel with it; a guardrail the plugin needs must ship as a hook in the plugin or as a managed rule. In the other direction, a plugin's hooks fire from the moment a session loads it, and its agent key runs one of its agents as the main thread, with that agent's prompt and model. Read a plugin before you enable it, and test your own on a clean machine before you publish.

SituationChooseWhy
A setting every teammate needs.claude/settings.json, committedShared through version control
A personal override in one project.claude/settings.local.jsonStays out of git, overrides the shared file
A policy no one may overrideManaged settingsHighest precedence
Output must not change without a testFull model ID or ANTHROPIC_DEFAULT_*_MODEL pinAliases move to newer versions
Rolling out a new agent prompt graduallyManaged Agents version pin per sessionNew sessions move only when you change the pin
Your plugin calls another plugin's MCP tooldependencies entry with a version rangeAn upstream rename cannot reach your users untested

Rules that decide exam answers

  • Higher scope wins for keys; deny wins for permissions. Managed beats command line, local, project and user for a key, but a deny rule from any scope beats an allow from any scope.
  • Aliases move, IDs do not. If behaviour must stay fixed, pin a full model ID; an alias is a moving pointer.
  • Team settings go in the committed project file. A setting in ~/.claude/settings.json reaches only one person.
  • Version prompts with the code and test before release. A prompt change is a behaviour change.
  • Constrain dependencies you call. A bare dependency name tracks the latest release; a range keeps you on what you tested.
  • Shared config holds references, not secrets or home paths. Use ${VAR} and the plugin path variables; a committed key must be rotated.

Where it appears in the exam

Configuration Management is part of Domain 2, Applications and Integration (33.1% of the exam), and carries 4.1% on its own, roughly two items on a 53-item exam. Expect scenarios where a setting does not reach a teammate, where a model or plugin update changed behaviour overnight, or where a team needs to roll out a prompt change safely.

Two sample questions

These are original Timo practice questions. They are not official exam questions.

Question 1

A platform team rolls out Claude Code to 200 developers through Amazon Bedrock. Settings use the sonnet alias. After an update, the alias resolved to a different model and the output of the team's review skill changed overnight. The team wants model changes only after testing. What should they do?

Answer: A. Pinning the full ID fixes what the alias resolves to, and managed settings apply it to everyone. B limits the family but the alias still moves to newer versions. C depends on 200 people remembering a manual step. D is an instruction to Claude, not a configuration that selects the model.

Question 2

A team's deploy-kit plugin calls an MCP tool from the secrets-vault plugin and lists it as "secrets-vault" in dependencies. A new major release of secrets-vault renamed the tool, and deploy-kit broke for everyone who updated. How should the team prevent this?

Answer: C. A version range resolves the dependency to the highest tagged release inside the range, so untested major releases never install. A changes the team's own plugin version, not the dependency's. B forks the dependency and stops it receiving fixes. D freezes every plugin, not just the one dependency.

Build exercise

  1. Create .claude/settings.json and .claude/settings.local.json in a test repository that set the same key to different values. Run /status and confirm which file wins.
  2. Set ANTHROPIC_DEFAULT_SONNET_MODEL to a full model ID, start Claude Code with --model sonnet and run /status to confirm which model the session uses.
  3. Move a system prompt into a file, load it with --append-system-prompt-file, and write a five-case check you run before changing it.
  4. Build two local plugins where one depends on the other, load both with --plugin-dir, then disable the dependency and read the error.

Practise this topic

Sources