Repository navigation
Description
Request: exclusion expressions for model route / plan pool definitions
Today a plan pool (e.g. deepseek-flash-plan) enumerates every leaf target explicitly. As the pool set grows (per-model pools × many doors × three OpenCode Go workspaces), enumeration is error-prone and hides intent: several pools we want are most naturally expressed as a model on a door set minus exclusions.
Motivating examples (from the 2026-10-27 pool review)
deepseek-flashon all doors except ClinePass — ClinePass's flat meter is more valuable reserved for MiMo; Flash burns better on Go (promo rate) and OpenDesign.mimo-flashon ClinePass (plus Go/OpenDesign) — the inverse reservation.- The standing rule "any pool containing one OpenCode Go workspace contains all three (personal, lab, base)" is currently maintained by hand-enumerating three near-identical leaves per pool.
Proposed shape
Allow a target/pool definition to express a model over a door set with exclusions, composing with the existing controls (selection mode, weights, per-target variant pins/remaps, context limits, and disabled_providers skipping):
{ "model": "deepseek-v4.1-flash", "doors": "all", "exclude": ["cline-pass"] }or equivalently negative targets in the existing list form:
"targets": [
{ "model": "*deepseek-v4.1-flash" }, // all doors serving this model
{ "model": "-cline-pass/deepseek-v4.1-flash" }
]Exact syntax is open; requirements are:
- Expansion happens against the live provider catalog (a door is included iff it lists the model and is not disabled).
- Exclusions win over inclusions, always.
- Expansion is visible/verifiable — a way to dump the resolved leaf list per route so config reviews can check what a pool actually contains.
- Existing fully-enumerated pools keep working unchanged.
Why
Pool definitions become statements of intent ("Flash everywhere except the meter reserved for MiMo") instead of leaf inventories that silently drift when a door adds or drops a model.
Acceptance criteria
- A pool/target definition can express a model over a door set with exclusions (e.g. deepseek-flash on all doors except ClinePass), composing with selection mode, weights, per-target variant pins/remaps, context limits, and
disabled_providersskipping. - Expansion resolves against the live provider catalog: a door is included only if it lists the model and is not disabled, and exclusions always win over inclusions.
- The resolved leaf list per route can be dumped/verified, so a config review can check what a pool actually contains (including the all-three-OpenCode-Go-workspaces rule).
- Existing fully-enumerated pools keep working and resolve unchanged.
Activity
developing-today commentedon Oct 27, 2026
OPENCODE-110
dezren39 commentedon Oct 27, 2026
Intake review
Related: #639 (time-windowed weights — independent, shared 'pool definition as intent' goal). Liveness: no merged PR implements pool exclusions — checked merged routes PRs through 2026-10-27; issue is live. An
## Acceptance criteriasection was appended this run (original body preserved verbatim above it), formalizing the body's four requirements. The issue arrived with no labels at all; the full minimum set (kind/source/status/priority/effort/app) was applied this run.Notes / risks / suggested approach: Risk: syntax choice is the open decision — the two sketched forms (doors/exclude fields vs negative targets) have different composability with weights and variant pins; pin one in triage before implementing. Suggested approach: expansion at config load against the live catalog, exclusions strictly winning, plus the resolved-leaf dump as the review surface.
🤖 Agent note · filed
dezren39 commentedon Oct 28, 2026
Triage — 2026-10-28 (queue task 2150)
Verdict: valid feature, not implemented, routed as a scoped follow-up (queue task 2909).
Verified against current main
a9452a1546:packages/core/src/model-plan.ts—PoolEntryis metadata only (tier,purpose,updatedAt); pools carry no expression language.packages/core/src/model-route-expansion.ts—matchingModelsexpands*patterns within one provider's catalog only; there is no provider (door) set, and no exclusion semantics.packages/core/src/config/plugin/model-routes.ts— targets are explicit refs (expanded at line 94); no negative-target or door-set form exists in the route config code.excluded*concepts in the codebase are session-governanceexcludedModels(a different layer) and route-review decision tallies (observational). Neither expresses a pool definition.disabled_providersdecoding already exists (packages/core/src/config/normalize.ts:433), so requirement 1's skipping input is in place for the implementation to compose with.Routing: follow-up implementation packet enqueued as queue task 2909 (
repo-health:v1:fix:developing-today/opencode:issue:637) with the issue's four acceptance criteria verbatim, the code citations above, and the syntax choice (door-set form vs negative targets) left to the implementer to note here. Priority stayspriority/normal; this is not a bug and nothing is blocked on Drew — the issue already decided the requirements, including "exclusions win, always".Labels:
status/needs-triageremoved;queue/queuedreflects task 2909.agent-note:v1 · agent: repo-queue-worker-shift-opencode-b · task: 2150 · issue: #637 · action: triage-routed · followup-task: 2909
24 remaining items
dezren39 commentedon Oct 29, 2026
🤖 Agent note · handed off
queued— at attempts 2/2 it is also DEAD-IN-QUEUE (it can never be claimed again as-is and needs operator repair: raise max_attempts or complete manually against PR feat(core): door-set targets with exclusions for model routes (#637) #810). The issue's labels saidqueue/claimed+work/assigned+status/in-progresswhile no live claim existed; they are now reset to the truth:queue/queued+status/needs-triage(work/assigned, queue/claimed, status/in-progress, status:in-review removed).dezren39 commentedon Oct 29, 2026
🤖 Agent note · revived
max_attemptsraised 2→3, attempts unchanged, status keptqueued, resume brief replaced in the task progress. Fresh verification at repair time: PR feat(core): door-set targets with exclusions for model routes (#637) #810 head1b6f156f46, mergeable=clean, all basic-tier checks SUCCESS includingbasic unit (windows)— the earlier windows failure was a diagnosed tool-shell 3s-timeout flake, and laptop suites were 67/67.Merge pull request #810 from developing-today/queue/2909-637-exclusio…
dezren39 commentedon Oct 29, 2026
🤖 Agent note · done (PR merged)
repo-health-opencode-pilot)mergeable=MERGEABLE,mergeStateStatus=CLEAN, head1b6f156f46; all basic-tier checks SUCCESS —basic typecheck,basic affected packages,basic unit (linux),basic unit (windows)(the earlier 3s tool-shell timeout flake is gone),e2e (linux/windows), plus pr-standardscheck-standardsandcheck-compliance.main2026-10-29T11:02:05Z as merge commit2bb9cc9420721485ce7ff0ef0077cf5cdab11fd6(repo merge gate = basic PR tier per.github/ci-policy.md).variantsremaps, so it can drop or misjudge the variant the plugin runs; (P2)retargetDefinition()does not expand door sets, so*/*misses transform-created models.