docs: say what models Iris suggests, what they cost, and that $0 is one of the answers (#454)
The page agent runs `us.openai.gpt-5.6-luna` on the reference deployment as of
2026-09-10 (#344). This is everything in the repo that had to agree with that,
plus the framing asked for alongside it.
**Suggestions, not defaults.** Iris names no model in its own code —
`resolveAgentModel` reads the config and nothing else. models.md opens by saying
that, and every model in it reads as a measurement with a date and a deployment
attached.
**$0 is real and now documented.** `providers.openrouter.base_url` replaces the
endpoint and that adapter speaks OpenAI-compatible `POST /chat/completions`, so a
local ollama / vLLM / llama.cpp server runs Iris with no per-token bill. Stated
with its two caveats wherever it is offered: no round in these documents ran that
way, and the agents that read page images need a model that accepts images. Keep
the block NAMED `openrouter` — `ProviderRouter.build` can construct exactly two
names.
**$X is what was measured, not arithmetic across rounds.** About 10.7¢ a page,
from `runs-postswap-312`, a round that ran Kimi on `page`. cost.md says so
outright rather than subtracting #344's 15.9%: that figure came from a round whose
Kimi page bill was $6.1201 against this round's $2.6098. The measured per-step
table is untouched.
**The loss, stated first.** Reading #344's own thread back turned up a finding no
document here carried: luna is one axe violation worse than Kimi over the same
corpus, and on the nine map-and-key pages it passes `page_verify_ok` clean while
asserting legend categories the page never prints — it says less, so there is
less to fail. Four review rounds then took the count apart. It cannot rank these
arms: by page luna's four are its own, by class only one is, by severity Kimi is
worst (3 criticals to 1), and 5 of the 10 violations are `definition-list` hits
that only fire on a `<dl>` an arm bothered to emit — discount those and the order
inverts to luna 2, Kimi 3, Sonnet 0. So the document publishes the map-and-key
finding as the firm part and the count as too crude to settle the axis either way.
Also priced: the pinned Sonnet checker is 63.8% of the page step against 51.8%
under Kimi (#365's target).
**The swap inverted a claim six files were making.** The id rule had never fired
on the deployed page model — 0 of Kimi's 328 replies — and that zero was the
stated reason to read a non-zero `ids_duplicated` as a regression. One of the two
hits in 1,501 replies is `fnref-1` twice on luna, so the arm that produced a hit
is the one running: one non-zero is the measured rate, several is the signal.
Every per-arm figure in the repo now names its arm instead of "the shipped model",
which after 2026-09-10 pointed at a different model than when it was written.
**Plain language as a requirement.** CONTRIBUTING.md gains a Documentation
section making concise plain language a requirement, stated as things a reader can
check. Teaching the CI reviewer to enforce it is deliberately a separate PR:
`code-review.yml`'s "do not flag style" rule has to be reconciled with it in the
same edit.
Four review rounds, each APPROVED, ten non-blocking notes, all fixed. Rounds 2, 3
and 4 each found a defect created by the previous round's fix, all three inside the
same paragraph. Gates at `8e4b443`: typecheck clean, `npm test` 1692/1692,
`./test/e2e.sh` ALL ENDPOINTS PASSED, config.example.yaml parses. Only comments
changed under `src/`; no behaviour.
Closes #344
Co-Authored-By: bbertucc <bbertucc@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>