Skip to content

feat(core): door-set targets with exclusions for model routes (#637) - #810

Merged
dezren39 merged 5 commits into
mainfrom
queue/2909-637-exclusion-expressions
Oct 29, 2026
Merged

dezren39 merged 5 commits into
mainfrom
queue/2909-637-exclusion-expressions

Conversation

@dezren39

@dezren39 dezren39 commented Oct 29, 2026 •

Copy link
Copy Markdown

Implements #637: exclusion expressions for plan pool / route target definitions.

Syntax choice (noted on #637 as the issue requests)

The door-set form: a target whose provider is * runs its model on every door (provider) whose catalog lists it, minus the doors in the target's new exclude list:

{ "model": "*/deepseek-v4-flash", "exclude": ["cline-pass"] }

This shape was picked over negative targets because it reuses the existing target object wholesale — selection mode, route weights (keyed by the concrete provider/model leaf), per-target variant pins/remaps, until, window gates, budgets and cache formats all apply per leaf exactly as they do for enumerated targets, and an enumerated target reached again by a door set still dedupes to one leaf (first reach wins).

Semantics

  • Expansion resolves against the live provider catalog in expand() (the plugin): a door contributes a leaf iff its catalog lists the model (exact or glob pattern) and the model is enabled. Providers removed by disabled_providers never reach the catalog, so they can never contribute.
  • Exclusions always win: an excluded door contributes nothing even when it lists the model. The routes provider itself is never a door.
  • Session model governance judges door-set targets with the same semantics, via the new shared ModelRouteExpansion.matchingProviders helper (alongside matchingModels), so the judged set and the run set cannot disagree (fix(core): route governance judges a wildcard target's literal pattern — expanded models escape the check, and expired/disabled targets are still judged (PR #512) #530 discipline). Without a catalog, a door-set target is judged literally, exactly as pattern targets are.
  • The resolved leaf list is the route's expanded target list — the same list the plugin publishes in the route's settings and that route review/stats surface — so a pool's actual contents stay dumpable and verifiable; expand() output is pinned by tests.
  • Existing fully-enumerated pools are untouched: a target naming one provider follows the exact previous path.

Tests (laptop worktree; CI is the remaining check)

  • model-routes-expand.test.ts: 7 new door-set tests — catalog-order expansion across doors, routes provider never a door, exclusions win, doors not listing the model skipped, glob over the door set, disabled model skipped, dedupe with an enumerated target, variant-remap composition (leaf pruned when it cannot produce the remapped variant).
  • session/model-governance.test.ts: 3 new tests — door-set expansion to an excluded model denies, exclusions win in governance, expansion to only-allowed models passes.
  • Suites on the laptop: expand + governance 67/67, the wider route/plan/review suite set 212/212, schema config tests 15/15; tsgo typecheck clean for packages/schema and packages/core.

Queue: task 2909 (repo-health-opencode-pilot), lane B worker shift.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T08:53:12.490342Z 1b6f156 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 46 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2ec9813c-2b27-479d-a702-1bcb4060529b
Commits

Reviewing files that changed from the base of the PR and between 33a7ecf and 1b6f156.

Files ignored due to path filters: 1
  • packages/client/src/promise/generated/types.ts is excluded by !**/generated/**
Files selected for processing: 6
  • packages/core/src/config/plugin/model-routes.ts
  • packages/core/src/model-route-expansion.ts
  • packages/core/src/session/model-governance.ts
  • packages/core/test/model-routes-expand.test.ts
  • packages/core/test/session/model-governance.test.ts
  • packages/schema/src/config/model-routes.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

The following comment was made by an LLM, it may be inaccurate:

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 72 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@dezren39

Copy link
Copy Markdown
Author

Regenerated the client on the laptop worktree (bun run generate in packages/client) and pushed commit 245a844add — check:generated now passes against the committed state locally. The regen includes this PR's exclude?: Array<string> target field plus the pre-existing cache_format drift tracked by #813, so merging this PR will also clear that drift on main; task for #813 should be revalidated against main after this lands.

@dezren39

Copy link
Copy Markdown
Author

Lane A CI classification (task 2909 resume), run 40810897814:

  • unit (windows), build (linux+windows), typecheck, nix-eval, e2e windows app-1/app-components: pass.
  • unit (linux): the client check:generated now passes (this PR already regenerated the client), but the second generated check — services/www OpenAPI (bun script/generate-openapi.ts --check) — failed: Generated OpenAPI documents are stale. Regenerated from services/www on the laptop: the only diff is services/www/openapi.json +16 lines adding the force query parameter to session.interrupt — drift from the session.interrupt API change, not part of feat(routes): exclusion expressions for plan pool definitions (model on all doors except X) #637's schema. Committed as 5805ac8; --check passes locally with it and a second generate is a no-op.
  • Remaining e2e linux shards were still pending when this was written; the push restarts CI on 5805ac8 anyway.

Parking task 2909 for the rerun; resume = merge on green (modulo known flakes), confirm #637 closes, complete the task.

agent-note:v1 agent=repo-queue-worker-shift-opencode-a task=2909 issue=637 pr=810 stage=parked-ci-rerun

@dezren39

Copy link
Copy Markdown
Author

Addendum (lane A): PR #818 (task 2997, for #813) also regenerates services/www/openapi.json from its own base. If #818 merges first, this PR's www regen commit 5805ac8 may conflict on openapi.json at merge time — resolution: take main's openapi.json, re-run bun run generate from services/www, keep the resulting diff, and re-check with bun script/generate-openapi.ts --check.

agent-note:v1 agent=repo-queue-worker-shift-opencode-a task=2909 issue=637 pr=810 stage=note-regen-overlap

@dezren39

Copy link
Copy Markdown
Author

Lane A resumed task 2909 and worked the CI state from run 40819928224 (head 5805ac8d15):

  • Everything green except unit (windows), whose only failure was ShellTool > returns both parallel CodeMode shell results — an Effect TimeoutError after 3s in packages/core/test/tool-shell.test.ts. This PR touches none of that area (diff: model-routes expansion/governance/schema + generated files only); every feat(routes): exclusion expressions for plan pool definitions (model on all doors except X) #637 test passed in that same windows run, and unit (linux) was fully green. Timing flake on a slow windows runner. A --failed rerun was refused because the run is still active (e2e jobs queued in the runner backlog).
  • Per the park resume brief's conflict warning: merged latest origin/main into the branch on the laptop — clean, no conflicts despite the adjacent model-route changes on main — and re-verified the change on the laptop: model-routes expand + model-governance tests 67/67 pass. PR now reports MERGEABLE.
  • New head c119545dbb; new test run 40826883604 is queued. Task 2909 is parked until ~06:49Z: if unit linux+windows pass (or windows fails only that same tool-shell timeout flake), merge this PR per the standing directive.

agent-note:v1 agent=repo-queue-worker-shift-opencode-a task=2909 issue=637 pr=810 stage=parked-ci-rerun-2

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c119545dbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +272 to +273
ModelRouteExpansion.matchingModels(selection.model, doorModels).flatMap(([id, model]) =>
leaf(providerID, id, model),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Judge pinned door-set variants after applying target remaps

For a door-set target such as { model: "*/a#low", variants: { low: "high" } }, this call judges the pinned low variant, while runtime expansion applies the remap and runs high. If a matching provider offers only high, leaf() drops it from governance entirely; if it offers both variants, governance checks the wrong variant. Consequently, a parent policy excluding test/a#high can admit a subagent whose route actually runs that excluded model variant. Resolve pinned variants through the same remapping and pruning rules used by expand() before checking the resulting concrete references.

Useful? React with 👍 / 👎.

…ion-expressions

# Conflicts:
#	packages/client/src/promise/generated/types.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b6f156f46

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +386 to +389
const doors: ReadonlyArray<readonly [Provider.ID, ReadonlyMap<string, Model.Info> | undefined]> =
ref.providerID === "*"
? ModelRouteExpansion.matchingProviders(
definitions,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Retarget door sets against each concrete provider's current models

When a door-set route includes transform-created models, such as Azure deployment names, its runtime pool omits those models even though an equivalent explicitly enumerated provider target includes them. retargetDefinition() collects target provider IDs literally, so a */* target causes it to call editor.ids("*") instead of merging current models for each matching concrete provider. This leaves expansion using only the pre-transform provider definitions: for example, azure/* gains a discovered prod-mini deployment, while */* never does unless another target explicitly names Azure. Expand door-set provider IDs when building the retargeting set so the new target form preserves post-transform model discovery.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant