Skip to content

feat(slug): one selection resolver that reports what it matched (#2491 partial) - #2594

Merged
lidge-jun merged 1 commit into
devfrom
codex/slug-equivalence-2491
Aug 25, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/slug-equivalence-2491

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Partial work on #2491.

The issue names four relations. Checking them against the tree, two of them — catalog
visibility (provider-fetch.ts) and persisted sync (sync.ts) — already share
slugEquivalenceKey, so they agree with each other. The real gap is different from the
issue's framing: nothing lets a caller learn that a selection was ambiguous rather than
exact, so an over-grant is indistinguishable from an intended match.

The lossiness itself is externally forced and not something to remove here. Codex's
models-manager resolves per-model metadata with an exact one-slash rule, so a/b and
a-b must collapse to one Codex-facing form.

This adds resolveSlugSelection: same tolerant matching, but it also reports the exact id
when the operator typed one and whether the selection admitted more than one row. A caller
holding a complete known-id set can then prefer the exact row instead of granting the whole
collision class; a caller working from an incomplete live roster keeps today's behaviour.
Returning the ambiguity rather than resolving it is deliberate — only the caller knows
whether its id set is complete, and silently narrowing would hide a published id whenever
discovery omitted it.

A real bug found while writing the test

The first version treated every slash-bearing selection as provider-qualified. That is
wrong: p/a-b is qualified, but a/b is a bare native id that happens to contain a slash.
So the same collision reported ambiguous through the dash spelling and unambiguous
through the slash spelling — precisely the asymmetry this resolver exists to remove. Fixed,
and both directions are now pinned.

Not done

The ocx models remove relation (slugEquals) and the routing collision check
(decodeRoutedModelIdOrThrow) are not migrated in this PR. They answer different questions
— exact-selector matching and encode-collision refusal — and folding them into one relation
needs a decision about whether models remove should become tolerant, which changes
destructive-command behaviour. #2491 stays open.

Verification

$ bun test tests/slug-codec.test.ts tests/selected-models.test.ts
 43 pass, 0 fail

$ bun test tests/slug-codec.test.ts tests/selected-models.test.ts tests/router.test.ts tests/codex-catalog.test.ts
 260 pass, 0 fail, 1032 expect() calls

$ bun x tsc --noEmit
(clean)

The existing test that pins the known lossy over-grant is unchanged, so this adds a capability
without altering current visibility behaviour.

Checklist

  • Targets dev
  • Based on the current dev head
  • Existing selection/visibility behaviour unchanged
  • Typecheck clean
  • No secrets or account identifiers in the diff

Summary by CodeRabbit

  • Bug Fixes
    • Improved provider model selection to recognize both raw and encoded slug formats.
    • Added support for provider-qualified selections and nested slash-containing model IDs.
    • Clearly identifies exact matches and reports ambiguous selections instead of guessing.
    • Returns no match when a selection does not correspond to a known model.

#2491 names four slug-equivalence relations. Two of them - catalog
visibility and persisted sync - already share slugEquivalenceKey, so they
agree with each other; what neither can do is tell a caller that a
selection was AMBIGUOUS rather than exact.

The lossiness is externally forced: Codex's models-manager tolerates
exactly one slash, so a/b and a-b must share an encoded form. This does
not try to remove that. It adds resolveSlugSelection, which keeps the
tolerant matching and additionally reports the exact id and whether the
selection admitted more than one, so a caller holding a complete known-id
set can prefer the exact row instead of granting the whole collision class.

Writing its test surfaced a real asymmetry in the first version: a slash
in a selection is ambiguous on its own, since p/a-b is provider-qualified
while a/b is a bare native id containing a slash. Treating every
slash-bearing selection as qualified made the same collision report
ambiguous through one spelling and unambiguous through the other.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 25, 2026 17:30
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 25, 2026
@lidge-jun
lidge-jun merged commit b6d5509 into dev Aug 25, 2026
8 of 9 checks passed
@lidge-jun
lidge-jun deleted the codex/slug-equivalence-2491 branch August 25, 2026 17:31
@coderabbitai

coderabbitai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97d558fe-7ee0-48c6-b22f-3523cea812a4

📥 Commits

Reviewing files that changed from the base of the PR and between c17a7b8 and ef36b3d.

📒 Files selected for processing (2)
  • src/providers/slug-codec.ts
  • tests/slug-codec.test.ts

📝 Walkthrough

Walkthrough

Changes

Slug selection resolution

Layer / File(s) Summary
Resolver implementation and validation
src/providers/slug-codec.ts, tests/slug-codec.test.ts
Lines 104–155 add SlugSelectionMatch and resolveSlugSelection. The resolver handles raw, encoded, provider-qualified, and slash-containing selections. Lines 324–373 test exact matches, ambiguity, absent IDs, and nested slashes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: ingwannu, yansigit

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/slug-equivalence-2491

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.

@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: ef36b3d637

ℹ️ 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 +143 to +145
const qualified = selection.startsWith(`${provider}/`)
? selection
: routedSlug(provider, selection);

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 Disambiguate provider-prefixed native IDs

When a bare native ID begins with the provider name, this prefix test necessarily treats it as a fully routed slug. For example, resolveSlugSelection("openai", "openai/gpt-5.5", ["openai/gpt-5.5"]) returns no match, and if gpt-5.5 is also known it incorrectly selects that different model and marks it exact. This is a realistic form for provider-scoped selectedModels, so determine both interpretations from knownIds and report their ambiguity, or require the caller to specify whether the selection is qualified rather than inferring it from the prefix.

Useful? React with 👍 / 👎.

tarunravi pushed a commit to tarunravi/opencodex that referenced this pull request Sep 14, 2026
…e-jun#2594)

lidge-jun#2491 names four slug-equivalence relations. Two of them - catalog
visibility and persisted sync - already share slugEquivalenceKey, so they
agree with each other; what neither can do is tell a caller that a
selection was AMBIGUOUS rather than exact.

The lossiness is externally forced: Codex's models-manager tolerates
exactly one slash, so a/b and a-b must share an encoded form. This does
not try to remove that. It adds resolveSlugSelection, which keeps the
tolerant matching and additionally reports the exact id and whether the
selection admitted more than one, so a caller holding a complete known-id
set can prefer the exact row instead of granting the whole collision class.

Writing its test surfaced a real asymmetry in the first version: a slash
in a selection is ambiguous on its own, since p/a-b is provider-qualified
while a/b is a bare native id containing a slash. Treating every
slash-bearing selection as qualified made the same collision report
ambiguous through one spelling and unambiguous through the other.
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
…e-jun#2594)

lidge-jun#2491 names four slug-equivalence relations. Two of them - catalog
visibility and persisted sync - already share slugEquivalenceKey, so they
agree with each other; what neither can do is tell a caller that a
selection was AMBIGUOUS rather than exact.

The lossiness is externally forced: Codex's models-manager tolerates
exactly one slash, so a/b and a-b must share an encoded form. This does
not try to remove that. It adds resolveSlugSelection, which keeps the
tolerant matching and additionally reports the exact id and whether the
selection admitted more than one, so a caller holding a complete known-id
set can prefer the exact row instead of granting the whole collision class.

Writing its test surfaced a real asymmetry in the first version: a slash
in a selection is ambiguous on its own, since p/a-b is provider-qualified
while a/b is a bare native id containing a slash. Treating every
slash-bearing selection as qualified made the same collision report
ambiguous through one spelling and unambiguous through the other.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant