feat(route): give the advisor a writer, on a need and per row

route.sh now emits `--advisor opus` into the startup command it prints.
The flag existed and worked, but nothing generated it, so it went unused:
the only mechanism that ever set an advisor here was `/advisor`, which
writes the global advisorModel setting -- every session, every repo -- and
was abandoned for burning quota. Nothing replaced it.

Two independent triggers, almost disjoint by construction:

  rows 1-2  always. Sonnet main model, so opus is a capability LIFT rather
            than a peer. Load-bearing: every fallback is one row cheaper and
            the cheap rows are Sonnet, so this makes the quota fallback safe.
  rows 3-4  only at reversibility=costly|one-way. Opus main model, so the
            advisor buys peer review where a mistake is not cheap to undo.
  rows 5-6  never. The CLI rejects every advisor for a Fable main model.

costly forces row 3 and one-way forces row 4, so a Sonnet row always has
reversibility=cheap and neither rule reaches the other's rows.
verification=none is deliberately not a third trigger: beyond the stakes
rule it adds only cheap-to-reverse mistakes, docs sessions among them.
Applied per ROW, so fallback-command carries its own correct answer.

route-selftest.sh 56 -> 73. Section 14 gates the three CLI facts the rule
rests on against the installed claude without spending a token: advisor
validation runs before the empty-prompt check, so `-p ""` reaches the
validator and stops. --help cannot gate this -- it short-circuits before
option validation, so an unknown flag would pass the gate untested.

Three pre-existing checks updated rather than worked around: two asserted
whole command strings that now carry the advisor, and section 11's effort
extraction swallowed the tail of the command line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X8N8hQEJSWWtieWUx37txT
This commit is contained in:
Kjell Tore Guttormsen 2026-07-31 21:39:59 +02:00
commit 9cb405c2cd
10 changed files with 272 additions and 13 deletions

View file

@ -5,6 +5,51 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.13.0] - 2026-07-31
### Added
- **`route.sh` now emits `--advisor opus` into the startup command, per row and
on a need.** The advisor is a second, stronger model consulted at key moments
during a session; Claude Code exposes it both as a launch flag and as the
global `advisorModel` setting that `/advisor` writes. The setting was tried
and abandoned here because it applies to every session in every repo and
burned quota accordingly — but nothing replaced it, so the flag went
effectively unused and `route.sh` never mentioned it. Two independent
triggers now decide it:
- **rows 1-2, always.** The main model is Sonnet, so `opus` is a capability
*lift* rather than a peer — Opus judgement at Sonnet cost. This half is
load-bearing: every `fallback-command` is one row cheaper and the cheapest
rows are the Sonnet ones, so this is what makes the quota fallback safe to
take.
- **rows 3-4, only at `reversibility=costly|one-way`.** The main model is
already Opus, so the advisor buys peer review — worth paying for when a
mistake is not cheap to undo.
- **rows 5-6, never.** Not a judgement call: the CLI rejects every advisor
for a Fable main model, and refuses `opus` as under-capable for one.
The two triggers are almost disjoint by construction, since `costly` forces
row 3 and `one-way` forces row 4 — so a Sonnet row always has
`reversibility=cheap`, and neither rule can reach the other's rows.
`verification=none` is deliberately **not** a third trigger: beyond the stakes
rule the only cases it would add are mistakes that are cheap to reverse, docs
sessions (`known/none/cheap/local`) among them. The decision is applied per
ROW rather than once, so `fallback-command` carries its own correct answer.
`route-selftest.sh` grows 17 checks (56 -> 73). Section 14 pins the rule and
gates the three CLI facts it rests on against the installed `claude` without
spending a token: advisor validation runs before the empty-prompt check, so
`-p ""` reaches the validator and stops there. `--help` cannot serve as that
gate — it short-circuits before option validation, so even an unknown flag
exits 0 and the gate would pass without testing anything.
`skills/route/SKILL.md` gains the two failure modes worth naming: paste
`command` verbatim rather than dropping the advisor as noise, never add one to
a command that came back without it, and remember that `--advisor` is a launch
flag — `/clear` reuses the process and keeps whatever advisor the session
started with, so it is not enough when the advisor changes.
## [0.12.1] - 2026-07-31
### Fixed