[FEATURE] Allow agent config model field to be non-overridable (hard enforcement)

Resolved 💬 4 comments Opened Mar 10, 2026 by fernandoslee Closed Apr 7, 2026

Problem

When an Opus session spawns sub-agents via the Agent tool, the calling LLM can override the model: field defined in .claude/agents/*.md frontmatter — either by explicitly passing model: "opus" in the tool call (mirroring its own model), or by losing the model instruction after context compaction in long sessions.

The Agent tool docs confirm this is by design: the tool's model: parameter "takes precedence over the agent definition's model frontmatter."

In a multi-agent project with 16 custom agents defined in .claude/agents/, this caused 9 out of 27 sessions for one agent to run on Opus despite its config specifying model: sonnet. The calling LLM sometimes passes its own model explicitly, overriding the agent config.

Use Case

Running a custom orchestrator command on Opus (needed for complex multi-step reasoning) that spawns domain-specific custom sub-agents which should run on cheaper models:

# .claude/agents/my-reviewer.md
---
model: sonnet      # <-- This should be a hard constraint
maxTurns: 25
memory: true
---

The orchestrator (Opus) invokes the Agent tool:

{
  "subagent_type": "my-reviewer",
  "model": "opus",        // <-- LLM mirrors its own model, overriding config
  "prompt": "Review this..."
}

The config says sonnet, but the tool call says opus, and the tool call wins.

Proposed Solution

Add an optional modelEnforcement (or similar) field to agent config frontmatter:

---
model: sonnet
modelEnforcement: strict   # "strict" = config wins over tool call parameter
---

Behavior:

  • strict (or locked / fixed): The agent ALWAYS runs on the configured model, regardless of what the calling LLM passes in the Agent tool's model: parameter
  • Default (omitted or flexible): Current behavior — tool call parameter overrides config

Alternative: a simpler boolean like modelLocked: true.

Why This Matters

In multi-agent frameworks, model selection is an architectural decision (cost, capability, scope). It shouldn't be subject to LLM non-determinism. The calling LLM is following natural language instructions to "use sonnet for this agent" — but LLMs don't follow instructions 100% of the time, especially after context compaction erases the instruction.

The tools: field in agent configs already provides hard enforcement (an agent with tools: [Read, Grep, Glob] physically cannot write files). The model: field should have an equivalent enforcement option.

Related Issues

  • #2532 — [Feature] Model Selection of Sub Agents (closed, implemented — added the model: field)
  • #4549 — Model Configuration Support for Sub Agents (closed, implemented)
  • #10993 — Subagent model selection behavior unclear (closed, docs)
  • #25546 — Allow configuring model for built-in agents (closed)

These issues requested the ability to specify a model. This issue requests the ability to enforce it.

Environment

  • Claude Code version: latest
  • OS: macOS (Darwin 25.3.0)
  • Using 16 custom agents via .claude/agents/*.md with an Opus orchestrator session

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗