iso-route v0.3.0 — bundled preset system
Bundled preset system — `extends: standard` + `iso-route init`
Ships an opinionated cost-tiered preset so newcomers don't have to know that OpenCode takes `opencode/*` prefixes, Codex accepts Anthropic natively, or which Haiku variant to pin. The decision is centralized in iso-route and evolves with releases.
`extends:` in models.yaml
Pulls in the named preset as the base layer, then deep-merges the user's fields on top. User wins at every key. `targets.` sub-objects merge atomically per harness. Explicit `null` on a target removes the preset's override.
```yaml
extends: standard
Everything below is optional — override only what differs:
roles:
quality:
targets:
codex:
provider: openai
model: gpt-5.4
```
`iso-route init`
```
iso-route init # writes ./models.yaml (extends: standard)
iso-route init --preset standard # explicit
iso-route init --out custom/path.yaml
iso-route init --force # overwrite existing
```
Preset content — `standard`
Verified against 2026-04 provider catalogs (Anthropic, OpenAI, OpenCode Zen/Go):
| Role | Anthropic (Claude Code) | OpenCode | Codex (OpenAI) |
|---|---|---|---|
| default | `claude-sonnet-4-6` | `opencode/glm-5.1` | — |
| `fast` | `claude-haiku-4-5` | `opencode/big-pickle` | `gpt-5.4-mini` |
| `quality` | `claude-opus-4-7` (high reasoning) | `opencode-go/kimi-k2.5` | `gpt-5.4` (high reasoning) |
| `minimal` | `claude-haiku-4-5` | `opencode/minimax-m2.5-free` | `gpt-5.4-nano` |
Cursor has no programmatic model binding, so it gets the advisory README with resolved picks users select manually in the Cursor UI.
Backwards-compatible
A `models.yaml` without `extends:` behaves exactly as before.
Deferred follow-up
An optional cron-scraper that auto-bumps the preset when upstream ships new model versions. Until then, preset maintenance is a normal release-cycle concern.
10 new tests cover preset loading, scalar overrides, atomic target replacement, null-to-remove semantics, unknown preset rejection, and adding-new-roles-alongside-preset.