Which model runs where

As of 23 September 2026 — read out of src/config.ts, data/models.json, src/queue/route.ts.

The pins

Claudeclaude-opus-5 · claude-fable-5-1 · claude-sonnet-5 · claude-haiku-4-5
Concrete ids, never aliases — a bare "opus" is not guaranteed to be the newest one.
Codex (your ChatGPT Plus)gpt-5.6-sol
Your pick from 2026-09-16.

Where each one actually runs

This Signal conversationclaude-opus-5, effort high
The default in data/models.json; no conversation overrides it right now.
Queue: container and 🧬 self lanesclaude-opus-5, effort medium
The default when you name no prefix. self is Claude-only — it rewrites and restarts me, and that path is only proven on Claude.
Queue: laptop lanes (widget, tiny-tube, handstand, widget-anna, energizer, puppeteer, cooky)gpt-5.6-sol, effort medium
Default for every laptop worker since 2026-09-16. Falls back to claude-opus-5 if Codex can't start on the laptop or is parked on its limit.
Classifying every incoming messageclaude-haiku-4-5-20251001
One small call per message picking the lane and reply type. The cheapest call I make, and the most frequent.
Starting a new 5-hour quota window, and reading the quotaclaude-haiku-4-5-20251001
One ~23-token request whose response headers carry the usage numbers.
Sandbox workers (one-shot, as user jarvisw)claude-opus-5, effort high
Voice noteswhisper.cpp ggml-large-v3-turbo-q5_0
Local, on the VPS, no API. Falls back to ggml-base only on a timeout. Those are the two models actually on disk.

What overrides it

A prefix on your message: Sonnet/Low: …, Fable: …, GPT,NOW: … — model and effort per request. Naming gpt also switches the engine to Codex. If the engine you asked for is parked on its usage limit and the other one is free, the run goes there instead and the queue page marks it "↪ on Claude instead".
Unused in practice right now: claude-sonnet-5 and claude-fable-5-1 are pinned and selectable but nothing defaults to them.