Repository navigation
v0.15.0
0.15.0 — per-agent model routing + preset-aware defaults (2026-05-18)
Token-cost optimization across Claude Code / Cursor / Codex via declarative
per-agent model pinning. 13 ADRs locked in PLAN-model-routing-multi-ide.md.
8 implementation phases shipped via /hm:loop with per-phase /hm:review.
Added
- Per-agent model schema (ADR-001/002) — new
HarnessConfig.agent_models: dict[str, AgentModelSpec]with nested{claude, cursor, codex: {model, reasoning_effort}}.recommended_model: strrenamed todefault_model: str
(deprecated read-side property kept for 0.15.x / 0.16.x; removed no earlier
than 0.17.0 per ADR-012). - Preset-aware defaults (ADR-005) — new
src/harness_maker/presets.py
shipsPRESET_AGENT_MODELSfor Production (opus on 3 reasoning agents,
sonnet on 11 reviewers) and Side (sonnet everywhere with downshifted
reasoning_effort). 3-tierresolve_agent_spec(): explicit override →
preset map →_spec_from_default_modelfallback (never KeyErrors on
user-authored agents). - Canonical Cursor ID table (ADR-003) —
CURSOR_MODEL_IDSmaps aliases
(opus/sonnet/haiku) to concrete IDs. Users write aliases in
agent_models; renderer normalizes via this table at render boundary
(single-point upgrade across Claude releases). Templates lint-enforced
against raw concrete IDs. - Codex profiles (ADR-008) —
.codex/config.tomlnow renders
[profiles.cheap](reasoning_effort=minimal) +[profiles.deep]
(reasoning_effort=high). Codex agent TOMLs render
model_reasoning_effortper-agent (the dominant cost lever; keepmodel =
omission per RESEARCH-codex-plan-validator-model-unavailable). - /hm:health Layer-1 sub-check (ADR-010) — new
model_routingdimension
with 3 advisory signals: Claude #43869 reliance, Cursor alias-form
warnings, Codex reasoning_effort coverage. Weight 0 (advisory only;
doesn't change composite). - CLI
--default-modelflag + back-compat alias--recommended-model
(ADR-012) with DeprecationWarning. --updatecwd guard (ADR-013) — rejects snapshot regen invoked from
inside.worktrees/<branch>/, turning the documented footgun
([fail:snapshot-regen-inside-worktree]count:4) into enforced
prevention with actionable error message.- Silent schema migration (ADR-004 + ADR-011) —
recommended_model:in
v1 harness.yaml migrates silently todefault_model; INFO log gated on
schema_version<2to avoid noise on fresh v2 renders. Multi-doc YAML
provenance frontmatter handled viaio_utils.load_harness_yaml(). - HOW-IT-WORKS docs — new "Agent Models" section with worked example
covering preset defaults, per-agent override, and the 3-tier resolution chain.
Changed
HarnessConfig.schema_version: 1 → 2.- 14 agent
.md.j2templates: hardcodedmodel: opus|sonnet→model: {{ claude_model }}(context driven byresolve_agent_spec). - 2 preset YAML templates + 5 foreign-config templates:
recommended_model:
→default_model:rename.
Fixed
- Pydantic dual-key handling for AliasChoices +
extra="forbid"—
model_validator(mode="before")silently dropsrecommended_modelwhen
default_modelis also present (avoidsextra_forbiddenon rendered
output round-trip). agent_modelsparse path catchespydantic.ValidationErrorin addition
toTypeError/ValueErrorso a malformed override drops with a WARNING
log instead of silently nuking the wholeanswers_from_harness_yaml
return (Phase 2 /hm:review consensus-passed P1 fix).- Migration log message sanitizes newline + ANSI escape sequences in
user-provided values (security-reviewer P1 fix). - Migration log includes the harness.yaml path so multi-repo runs can
identify which file triggered the advisory (code-reviewer P1 fix).