Two targeted fixes: AGY dispatches were silently no-op'ing, and the Codex hard band was still pinned to the previous generation.
AGY dispatch was a silent no-op
resolveTiers() returned the whole agy models row — id<TAB>Display Name — so dispatches ran as:
# ⚠️ the bug, not a command to run — that is a literal tab in the --model value
agy --model "gemini-3.8-flash-high⇥Gemini 3.8 Flash (High)"
agy does not reject that. It prints its interactive model picker and exits 0 without ever running the prompt. The result is non-empty and plausible-looking, so it slips past orchestrate §3's "empty result = dispatch failure" backstop: the task never ran, the wallet was never touched, and the orchestrator carried on as if it had an answer.
agyTiers()now parses rows into{id, name}and drops theFetching available models...status line.resolveTiers()resolves by ID and ranks by the version parsed out of the ID, so a tier never depends on the orderagy modelshappens to print. Addsgemloandprohi; display names move to.names, used only for §9 attribution.probe.mjsandquota.mjsprint the bare ID with the display name behind a//, and say plainly which half goes to--model.mc-agyrefuses a--modelvalue containing a space, tab, paren, or slash rather than firing the no-op.
Codex routing: GPT-6 Astra
mc-codex hard-enumerated gpt-5.6-{luna,terra,sol} and would have rejected Astra outright.
| Band | Was | Now |
|---|---|---|
| Mechanical | gpt-5.6-luna @ medium |
unchanged |
| Standard | gpt-5.6-terra @ high |
unchanged |
| Hard | gpt-5.6-sol @ xhigh |
gpt-6-astra @ xhigh |
| Escalation | — | gpt-6-astra @ ultra (new) |
gpt-5.6-sol is the documented hard-band fallback: Astra is account-gated and needs Codex CLI ≥ 0.153. Routine burn rate is unchanged — only the top bands moved.
Verified against the live CLIs
Exact commands, copy-pasteable. Note that the prompt is attached to --print:
a valueless --print swallows the next flag as its prompt (agy 1.1.27 now catches
this and says so, rather than acting on the literal flag text).
agy --print="reply with exactly: OK" --model gemini-3.8-flash-high --output-format json
# → {"status":"SUCCESS","response":"OK\n","usage":{"total_tokens":5478}}
codex exec -m gpt-6-astra -c model_reasoning_effort="ultra" \
--skip-git-repo-check "reply with exactly: OK"
# → OK, 4,812 tokens
# probe — from a clone of this repo:
node multiclaude/scripts/probe.mjs
# ...or from anywhere, against the installed plugin:
node ~/.claude/plugins/cache/multiclaude/multiclaude/2.6.0/scripts/probe.mjs
# → all six tiers resolve to bare IDsInside a Claude Code session the orchestrate skill runs the probe itself as
node "${CLAUDE_PLUGIN_ROOT}/scripts/probe.mjs" — the paths above are only for
checking it by hand from a shell.
Known gap
Nothing yet verifies that an AGY dispatch actually ran. This release removes the cause of the silent no-op, but agy exits 0 on both known failure modes, so the exit code remains useless as a success signal. agy --output-format json exposes status and usage.total_tokens — a deterministic check plus proof the work landed off-wallet. Tracked in docs/NEXT_STEPS.md.
Full changelog: v2.5.1...v2.6.0