Repository navigation
Description
Finding
PR #233 (#233, head d92970d) adds pattern-based pool membership (include / contains / match) and, commendably, a diagnostic for almost every other way a pool setting can be silently dropped: a malformed pattern skips the pool with a diagnostic, an unknown key is reported as "omitted unknown setting", a bad schedule leaves a config warning, a declared level no model can run is logged, and a pool pinned at a level it does not declare "adds nothing, and says so".
One silent drop is left: a pool whose matching keys select no models at all produces no diagnostic.
- In
expand()(packages/core/src/config/plugin/model-routes.ts:537-556on the PR branch), theselectsloop simply places nothing when no catalog entry passes the predicate (typo'd pattern, a provider that is not connected, anexclude/notContainsthat removes everything the include matched). No entry is added todiagnostics— contrast the diagnostics pushed at lines 344, 390 and 425 for the level/pin/unknown-pool cases. - The transforms then erase the pool without a word: the model transform does
if (leaves.length === 0) return editor.remove(ModelRoute.PROVIDER_ID, id)(line 141), and a pool that also hastargetskeeps its targets while itsinclude/contains/matchsilently adds nothing.
So a one-character typo (*luno* for *luna*), or a provider that failed to connect, makes a pool vanish from the picker — or quietly run without the models its author intended — with nothing in the log, in exactly the way this PR set out to eliminate for schedules and unknown keys.
Evidence
- PR: feat(core): pick pool members by pattern and control effort per level #233, head
d92970ddfb42e48cf390c2ef78d931a2dc63619a(OPEN at time of filing). packages/core/src/config/plugin/model-routes.ts:537-556— the selects loop incollect(); no diagnostic on zero placements.packages/core/src/config/plugin/model-routes.ts:141— model transform removes an empty pool silently; line 102 does the same in the provider transform.- The PR's own tests pin diagnostics for the neighbouring cases and none for this one:
packages/core/test/model-routes-matching.test.tsexpects"pool small declares level ultra, but none of its models can run it, so it is not offered"and"pool low-only is pinned at level max, which it does not declare, so it adds nothing", but no test expands a pool whoseinclude/contains/matchselects nothing and asserts what is reported. - Deduped: no open or closed issue in this repo mentions a diagnostic for a pool matching no models (searched "pool matched no models", "include matches nothing", "model route diagnostic"). The two follow-ups the PR body already filed, Model pools cannot reach models that a model transform creates, such as Azure deployments #236 (transform-created models) and Should a pinned nested pool run its members through their level remaps? #237 (pinned nested pool remaps), are different findings.
Why it matters
Pattern pools are the PR's headline feature, and their failure mode is otherwise invisible: the pool is absent (or smaller than configured) and the only symptom is a model the user expected never being offered. The PR establishes the principle that a routing setting must never be dropped without a word; this is the remaining place that principle is not applied.
Acceptance criteria
- When a pool's matching keys (
include/contains/match, afterexclude/notContains) add no models during expansion, a model-route diagnostic naming the pool (and ideally which key(s) selected nothing) is emitted through the existingreport()path inpackages/core/src/config/plugin/model-routes.ts, so it is logged once while it lasts and again if it recurs after clearing. - A pool that has targets and whose matching keys add nothing is also diagnosed (the pool surviving on its targets must not hide the dead key).
- New tests in
packages/core/test/model-routes-matching.test.ts(or the expand tests) cover: anincludepattern that matches nothing, amatchexpression that selects nothing, and anexcludethat empties an otherwise-matchinginclude— each asserting the diagnostic; and a matching pool that selects at least one model asserts no such diagnostic. - Fix in PR feat(core): pick pool members by pattern and control effort per level #233 itself or in a follow-up referencing this issue; either is acceptable, but the behaviour should not ship silently.
Activity
dezren39 commentedon Oct 26, 2026
Intake review
d92970ddfbwhen filed — the finding is against that branch'sexpand()), Model pools cannot reach models that a model transform creates, such as Azure deployments #236 and Should a pinned nested pool run its members through their level remaps? #237 (sibling follow-ups the PR body filed), Settings under providers["opencode-route"].models do not hold for pools #239 (same review round).packages/core/src/config/plugin/model-routes.ts(no match for an empty-pool diagnostic), so the silent drop the issue describes has neither shipped a fix nor been superseded. Body already carries a complete## Acceptance criteriasection — labels only, body untouched.d92970ddfb, line numbers in the evidence are stale; the behaviour (no diagnostic on zero placements) is the thing to re-verify on the current head before fixing.report()path and the neighbouring diagnostic phrasing; otherwise a small follow-up PR referencing this issue.dezren39 commentedon Oct 28, 2026
🤖 Agent note · done
Evidence (fresh GitHub reads, 2026-10-28):
held,user/owned,do-not-merge,do-not-auto-editall absent). PR feat(core): pick pool members by pattern and control effort per level #233 is OPEN, head now01c52a73ebbc875e5de659ea7fbe6814f09dc94e(moved since filing atd92970ddfb).packages/core/src/config/plugin/model-routes.ts(830 lines): theselectsloop inexpand()/visit()iterates catalog entries and places those passing theselects/ excluded / enabled / pin checks — with no placement counter and no diagnostic when it places zero. Diagnostics are pushed for the neighbouring cases (malformed pattern → "pool X is skipped", unknown pool, undeclared pin → "adds nothing"), just not this one.if (leaves.length === 0) return editor.remove(ModelRoute.PROVIDER_ID, id), and a pool with targets keeps its targets while its dead matching keys add nothing, undiagnosed.packages/core/test/model-routes-matching.test.ts, 822 lines) pin diagnostics for those neighbouring cases and assertdiagnostics == []for matching pools, but have no zero-select case.cd21eab1dec5b0d7b00c2895ea4536b28b518f1f),model-routes.tsis 450 lines:expand()has noselects, no diagnostics, and noinclude/contains/matchpools at all — so this cannot be fixed on main until PR feat(core): pick pool members by pattern and control effort per level #233 lands, and PR feat(core): pick pool members by pattern and control effort per level #233 is Drew-authored, so its branch is not edited here.Route: scoped follow-up enqueued as queue task 2705 (
small_fix, deduperepo-health:v1:fix:developing-today/opencode:issue:238), explicitly gated: if PR #233 is still open at claim time, park — do not edit PR #233's branch and do not open a competing PR; once it merges, count selects-loop placements inexpand(), push a diagnostic naming the pool when matching keys place zero (including pools kept alive by targets), through the existingreport()path, with tests for include-matches-nothing, match-selects-nothing, exclude-empties-include, and a positive no-diagnostic case. The issue stays open; this triage task completes astriaged.84 remaining items
dezren39 commentedon Nov 5, 2026
🤖 Agent note · claimed
dezren39 commentedon Nov 5, 2026
🤖 Agent note · parked
developing-today commentedon Nov 5, 2026
Gate revalidation (task 2705, lane opencode-a, 2026-11-05): PR #233 is still OPEN and unmerged (head
routing-docs-and-diagnostics), verified fresh via the GitHub API this shift. The selects/diagnostics code this fix targets therefore still lives only on that branch, not on main.Task 2705 is PARKED (not_before 2026-11-06T20:45:00Z) until PR #233 merges — per the packet, no edits to PR #233's branch and no competing PR off main. On merge, the fix proceeds as specified: zero-placement diagnostic for the selects (include/contains/match) loop in
expand(), via the existing diagnostics/report() path, with tests.Parked by: lane opencode-a, task 2705 — gate PR #233 still open
dezren39 commentedon Nov 8, 2026
🤖 Agent note · parked
packages/core/src/config/plugin/model-routes.tsexpand() per the packet.