Model Selection Policy
This reference selects no stage or transition. Resolve one tier, then return control to the active skill. Do not activate another Buddy skill.
This is the runtime source of truth for stage tiers, packaged defaults, profile resolution, and dispatch. Stored preferences belong in .buddy/model-profile.yaml or ~/.buddy/model-profile.yaml, never this installed skill.
Stages and tiers
fast— bounded fact collection, normal implementation after a detailed spec, mechanical edits, narrow scope, low-risk changes, parallel fan-out over small files.balanced— codebase analysis, solution-oriented research, direct implementation without a detailed spec, integration-heavy implementation, debugging, or phases whose brief names moderate ambiguity.frontier— architecture, ambiguous design, cross-cutting refactors, decision settling inside spec, ideation.
| Stage | Default | Runner |
|---|---|---|
| research | balanced; fast for bounded facts |
researcher |
| innovate | frontier |
innovator |
| spec | frontier |
developer main agent |
| specified implement | fast by default per phase |
one implementor per phase |
| direct implement | balanced by default per task |
host or bounded implementor |
The developer orchestrator sequences stages and pins workers to their tier. Its own model remains the user's choice. Implementation uses per-phase implementors unless a phase says Main.
Packaged defaults
Use only when neither profile has the current product section:
cursor:
fast: composer-2.5-fast
balanced: cursor-grok-4.6-high-fast
frontier: kimi-k3-max
claude_code:
fast:
model: claude-sonnet-5
effort: low
balanced:
model: claude-sonnet-5
effort: high
frontier:
model: claude-opus-5
effort: high
codex:
fast:
model: gpt-5.6-terra
model_reasoning_effort: low
balanced:
model: gpt-5.6-terra
model_reasoning_effort: high
frontier:
model: gpt-5.6-sol
model_reasoning_effort: high
# opencode / unknown: omit model; inherit parent default.
Resolution
Before dispatch, check both profile paths. If either exists, first read the complete profile contract.
For the selected tier, choose:
- An explicit model override in the current task.
- Project profile's current-product section.
- User profile's current-product section, only if the project profile lacks it.
- Packaged current-product default, only if both profiles lack it.
- Orchestrator default when the selected value is
inherit, invalid, incomplete, unsupported, or rejected by live dispatch.
A current-product section atomically replaces lower-priority mappings. File existence alone does not win: a project file lacking that section falls through to the user file. Never fill a missing, invalid, or rejected tier from a lower source. Preserve exact native strings and field names.
Resolution never edits profiles. Report a malformed or stale selected section, recommend configure-models, and omit its override.
When using packaged defaults, report once per top-level workflow: Using Buddy's packaged model defaults because no project or user profile configures this harness. Run configure-models to personalize them. Continue without repeating it per worker.
Reasoning controls
Codex stores model_reasoning_effort; dispatch it with model only through the live interface's exact field (for example reasoning_effort), never an unsupported config key. For every product, pass reasoning/effort only when that exact model and live interface support it; otherwise omit it.
Artifact provenance
Before a research or spec artifact is authored, establish its model_slug. For a concrete override, use the exact accepted runtime model slug. When dispatch omits an override or uses inherit, obtain the artifact author's concrete inherited runtime slug from the task or dispatch context. Pass that exact value to a worker that authors the artifact. Never substitute inherit, a tier, a profile source, or a packaged default. If the harness cannot expose the concrete inherited slug, report the missing provenance and do not write a false value.
Dispatch
- Resolve stage tier, then the explicit/profile/packaged definition.
- Before every override, revalidate the exact model against the live dispatch allowed list; shell catalogs prove discovery, not dispatch. For Cursor, follow cursor-task-dispatch.md.
- Send
modelonly if its exact string is accepted. Send its exact reasoning/effort field and value only if supported for that model; otherwise omit the whole override. - Never translate, normalize, abbreviate, guess, substitute, or borrow a model slug across products.
- If a saved definition is rejected, inherit and report that it needs reconfiguration; do not choose another concrete model.
- Omitting the override makes the worker inherit the orchestrator default, the required fallback for unsupported or unknown interfaces.