CertSafari
    CLAUDE-CERTIFIED-DEVELOPER-FOUNDATIONS-CCDV-F · Lessons

    Domain 2 · Lesson 9/25

    Model Pinning and Plugin Dependency Versions in Claude Code

    Configuration Management

    9 min read
    5.52% of exam
    5 sources
    Published 29 Sep 2026
    Docs as of 26 Sep 2026

    What you will be able to do

    • Tell a moving model alias apart from a pinned full model name, and pick the right one
    • Work out which model a session starts on when several sources set one
    • Restrict model choice with availableModels through a delivery channel that actually reaches the session
    • Declare plugin dependencies with semver ranges, tag releases, and read dependency errors

    1.Aliases move, full names pin

    You can give Claude Code a model as an alias or as a model name. An alias such as sonnet or opus points at the latest model in that family, so what it resolves to depends on your provider and changes when a new model ships. If you need a fixed version, use the full model name. On Amazon Bedrock that means an inference profile ARN, and on Microsoft Foundry it means a deployment name.

    What the opus and sonnet aliases resolve to on each provider
    Provideropussonnet
    Anthropic APIOpus 5.5Sonnet 5
    Claude Platform on AWSOpus 5.5Sonnet 4.6
    Amazon Bedrock, Google Cloud’s Agent PlatformOpus 5.5Sonnet 4.5
    Microsoft FoundryOpus 4.6Sonnet 4.5

    Environment variables such as ANTHROPIC_DEFAULT_SONNET_MODEL and ANTHROPIC_DEFAULT_FABLE_MODEL control what each alias resolves to. That is how you pin a version on a provider that uses its own model IDs. Two values are not ordinary aliases. default clears any override and returns to your account's default, and opusplan plans with opus and then executes with sonnet.

    Sources1

    2.Which model setting wins

    You can set the model in five places: /model during a session, the --model flag at launch, the ANTHROPIC_MODEL environment variable, the model field in any settings file, and ANTHROPIC_DEFAULT_MODEL for new sessions. Putting the model in the committed project settings file sets it for the whole team:

    Setting the model in a settings file next to permissionsjson
    {
        "permissions": {
            "allow": ["Bash(npm run lint)"]
        },
        "model": "opus"
    }

    When you run /model, it saves your choice to ~/.claude/settings.json, but that choice can be outranked. A model value in project or managed settings, ANTHROPIC_MODEL in your shell, or an organization default that is set to override user choices applies again at every launch. When project or managed settings set the model, the startup header names the file responsible. Some choices last for one session only: --model, pressing s in the picker, and /model in non-interactive mode. A session you resume with --resume or --continue usually keeps the model it was already using.

    A large monorepo has a root `CLAUDE.md` with general repository conventions and a `frontend/CLAUDE.md` with React-specific rules. An engineer launches Claude Code from inside `frontend/` and asks it to edit a file in `frontend/components/`. In what order does the content from these two files enter context, and when is `frontend/CLAUDE.md` loaded?

    Sources1

    3.Locking the model list with availableModels

    A managed model only decides which model a session starts on, and users can still switch with /model. The actual lock is availableModels. It limits /model, --model and the model key in users' own files. It also covers subagent models, skill frontmatter and the alias environment variables.

    A managed allowlist that permits only the sonnet and haiku familiesjson
    {
      "availableModels": ["sonnet", "haiku"]
    }
    What happens when a requested model is outside the allowlist
    Where the model was requestedResult
    /modelClaude Code rejects the switch with an error
    --model flag, ANTHROPIC_MODEL, or the model settingThe value is replaced at startup with a warning, and the session starts on the default model
    ANTHROPIC_DEFAULT_MODELClaude Code ignores the variable
    Skill or command overrideThe override is ignored and the skill runs on the session model

    Sources1

    4.Prompt versioning: what these sources cover

    The exam guide lists prompt versioning, but the Claude Code documentation used for this lesson has no mechanism for versioning prompts sent to the Messages API. It only describes versioning the instructions Claude Code itself reads. Project CLAUDE.md files and .claude/settings.json are shared by committing them, so git history becomes their version history. A change to a team instruction is then a reviewed commit, not an edit on one person's machine. For prompts inside your own application, look for versioning practice in API-side material. It is not documented here.

    Sources2

    5.Plugin dependencies and semver ranges

    A plugin declares the other plugins it needs in the dependencies field of its plugin.json. A dependency can be a bare name, or an object with a semver range such as ~2.1.0, ^2.0, >=1.4 or =2.1.0. Claude Code installs the highest git tag that satisfies the range, which means ranges only work if the maintainer tags releases. The convention is {name}--v{version}, for example secrets-vault--v2.1.0, and claude plugin tag --push creates and pushes the tag. The command refuses to run if the tag already exists or if the working tree is not clean.

    A plugin that depends on audit-logger at any version and on secrets-vault within ~2.1.0json
    {
      "name": "deploy-kit",
      "version": "3.1.0",
      "dependencies": [
        "audit-logger",
        { "name": "secrets-vault", "version": "~2.1.0" }
      ]
    }
    How ranges from two plugins that share a dependency combine
    Plugin A requiresPlugin B requiresResult
    ^2.0>=2.1One install at the highest 2.x tag at or above 2.1.0; both load
    ~2.1~3.0Installing plugin B fails with range-conflict
    =2.1.0noneStays at 2.1.0; auto-update skips newer versions while plugin A is installed

    A dependency from another marketplace is blocked unless the root marketplace lists that marketplace in allowCrossMarketplaceDependenciesOn. For local development, claude --plugin-dir ./my-dependency --plugin-dir ./my-plugin loads both plugins without checking versions. If you leave the dependency's --plugin-dir flag off, the dependency shows up as not installed.

    Dependency errors and how to fix them
    ErrorMeaningFix
    dependency-unsatisfiedNot installed, or installed but disabledRun the claude plugin install command from the error, or enable the dependency
    range-conflictNo single version satisfies every rangeUpdate or uninstall one of the conflicting plugins, or ask the upstream author to widen the range
    dependency-version-unsatisfiedThe installed version is outside the declared rangeclaude plugin install <dependency>@<marketplace>
    no-matching-tagNo {name}--v* tag satisfies the rangeCheck the upstream tags, or relax the range

    An enterprise admin sets `availableModels: ["sonnet", "claude-opus-4-6"]` in managed settings to restrict which models developers can select, but does not set `enforceAvailableModels`. A developer who has never touched `/model` opens a fresh session. Which model does that session start on, and why?

    Sources34

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Setting "model": "sonnet" pins the team to one Sonnet version.Why is that wrong?

      An alias points at the latest model in its family and resolves differently on each provider. A full model name is what fixes the version.

      Covered in Aliases move, full names pin

    2. 2.Putting a model in managed settings stops users from switching to another model.Why is that wrong?

      A managed model only sets the starting model, and /model can still change it. availableModels is the setting that restricts the choice.

      Covered in Locking the model list with availableModels

    3. 3.Bumping the version in plugin.json is enough for dependents with a semver range to receive the new release.Why is that wrong?

      Ranges resolve against git tags, so the maintainer has to create a {name}--v tag for the release, for example with claude plugin tag --push.

      Covered in Plugin dependencies and semver ranges

    Practise it for real

    Watch model precedence decide which model a Claude Code session starts on

    1. 1.Add "model": "opus" to .claude/settings.json in a test project and launch claude.

      Why: A model in project settings applies at every launch.

      You should see: The startup header names the settings file that set the model.

    2. 2.Exit, then launch claude --model sonnet in the same project.

      Why: --model applies to this session only.

      You should see: The session runs on sonnet, and your saved default in ~/.claude/settings.json is unchanged.

    3. 3.Launch plain claude again, then run /model sonnet and press s in the picker.

      Why: Pressing s switches the model for this session only.

      You should see: The next plain launch goes back to the opus model set in project settings.

    Stuck? Get a nudge

    If a /model choice seems to be ignored, look for ANTHROPIC_MODEL in your shell or a model set in project or managed settings. Those outrank what /model saves.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “A model name Anthropic API: a full model name Amazon Bedrock: an inference profile ARN”
      ↩︎ Aliases move, full names pin
      “Your /model choice is still saved; it’s outranked.”
      ↩︎ Which model setting wins
      “usually keeps the model it was using rather than your current default.”
      ↩︎ Which model setting wins
      “Claude Code replaces the value at startup with a warning naming both the requested and substituted models”
      ↩︎ Locking the model list with availableModels
      “settings deployed to your device do not reach them, so deliver the allowlist through server-managed settings.”
      ↩︎ Locking the model list with availableModels
      “Uses the latest Sonnet model for daily coding tasks”
      ↩︎ Exam trap 1
    2. 3.
      “Cross-marketplace dependencies are blocked unless the target marketplace is listed in allowCrossMarketplaceDependenciesOn in the root marketplace’s marketplace.json.”
      ↩︎ Plugin dependencies and semver ranges
    3. 4.
      “No version needed: the local plugin.json doesn’t need a version either, because a version constraint isn’t checked against a local copy.”
      ↩︎ Plugin dependencies and semver ranges
      “The dependency installs at the highest git tag that satisfies this range, so the dependency’s maintainer must tag releases.”
      ↩︎ Exam trap 3

    Also cited

    Ready to test yourself?

    Practise the 20 questions on this subdomain.