Skip to content

fix(catalog): widen the dated-variant fold and guard its direction at the merge loop - #3100

Merged
lidge-jun merged 2 commits into
devfrom
codex/3024-dated-variant-fold
Sep 1, 2026
Merged

fix(catalog): widen the dated-variant fold and guard its direction at the merge loop#3100
lidge-jun merged 2 commits into
devfrom
codex/3024-dated-variant-fold

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Summary

Supersedes #3034 and #3041, which found the same defect from two directions. This carries the better half of each.

isDatedVariantId only matched -YYYYMMDD, so every dated alias a provider actually publishes in another shape fell through to droppedConfiguredIds while discovery still reported ok (#3024). The matcher now accepts YYYYMMDD, YYMMDD, MMDD and YYMM with calendar validation, so -2048, -4096, -8192, -20250229 and -0431 stay rejected. -1024 is October 24th and is the one irreducible collision; the test table pins it rather than pretending otherwise.

The first commit is #3034's work, cherry-picked with authorship intact.

The second commit moves the direction guard to where a resurrection would actually happen. #3034 pins one-wayness with a predicate assertion — isDatedVariantId("deepseek-v4-pro", "deepseek-v4-pro-0813") === false — which is true of every implementation, including one whose merge loop calls the predicate a second time with the arguments swapped. That is exactly what #3041 first proposed and then withdrew, so the guard needs to outlive the proposal. Three tests carried from #3041 drive mergeConfiguredModelsIntoLiveCatalog itself.

This does not close #3024. The reported case is a configured dated id against a live base id, and that still drops — deliberately, because a live base row is not callability evidence for a dated snapshot. Retaining it needs #1690's retainModels opt-in. Executed on this branch:

configured deepseek-v4-pro-0813 + live deepseek-v4-pro
  -> dropped: ["deepseek-v4-pro-0813"]
configured deepseek-v4-pro + live deepseek-v4-pro-0813
  -> dropped: [], ids: ["deepseek-v4-pro-0813","deepseek-v4-pro"]

Verification

bun test tests/codex-catalog.test.ts   -> 254 pass / 0 fail / 980 expect()
bun x tsc --noEmit                     -> exit 0

Both directions mutation-checked, then restored:

mutation result
add || isDatedVariantId(candidate.id, live.id) to the merge loop 253 pass / 1 fail — only the merge loop does not infer a configured dated id from a live base id
narrow the suffix back to /^\d{8}$/ 241 pass / 13 fail — every MMDD/YYMM/YYMMDD fold plus the calendar rejections

Neither mutation is caught by the predicate test alone, which is the argument for the second commit.

Suffix behavior probed directly over 22 shapes: accepted 2510 2412 2409 1024 2401 2101 0813 2407 1231 2612; rejected 2048 4096 8192 2413 2400 3012 1912 0000 0100 1300 1601.

Checklist

Triaged in the 2026-08-31 non-priority-70 bug round.

Summary by CodeRabbit

  • Bug Fixes
    • Improved recognition of dated model variants across multiple date formats.
    • Prevented ordinary numeric suffixes, version numbers, variant names, and invalid dates from being misidentified as dated variants.
    • Correctly handles leap days and other calendar-specific date validation.
    • Preserved configured model entries according to catalog merge rules.

kaicot and others added 2 commits September 1, 2026 03:03
`isDatedVariantId` only accepted an 8-digit `YYYYMMDD` suffix, so the
dated-alias fold in `mergeConfiguredModelsIntoLiveCatalog` never fired for
providers that publish shorter release dates. On a real multi-provider
install the `\d{8}` rule matched none of the 26 numeric-suffixed ids
present, dropping DeepSeek, Kimi, Mistral, Qwen and Solar aliases into
`droppedConfiguredIds` even though a live row for the same model existed.

Widen the suffix to the formats upstreams actually publish -- `YYYYMMDD`,
`YYMMDD`, `MMDD` and `YYMM` -- behind a calendar guard so ordinary numeric
suffixes are not read as dates. `-2048`, `-4096` and `-8192` are rejected;
`YY` is `2\d` rather than `\d\d` so `1301` is rejected too. `-1024` is a
valid `MMDD` and is therefore accepted -- an irreducible collision, pinned
by a test so it stays a known cost.

The fold stays one-directional (`configured=base` -> `live=dated`). A
configured id the provider no longer lists must not be retained on the
strength of a format match alone; #1690 is the explicit opt-in for that.
Hyphenated ISO suffixes (`-2024-08-06`, `-05-06`) remain out of scope.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 0a6393d)
(cherry picked from commit 6dd0850)
…t the predicate

#3034 widens the dated-suffix matcher and pins it with a predicate test that the
fold stays one-way: isDatedVariantId("deepseek-v4-pro", "deepseek-v4-pro-0813")
is false. That assertion is true of every implementation, including one whose
merge loop calls the predicate a second time with the arguments swapped -- which
is exactly what #3041 originally proposed and then withdrew.

So the guard is moved to where the resurrection would actually happen. These
three drive mergeConfiguredModelsIntoLiveCatalog itself, carried from #3041:

- a live base row must not resurrect a configured dated id
- a live MMDD dated row still folds onto its configured base
- a dated id named in retainConfiguredModelIds survives

Both directions were mutation-checked. Adding
|| isDatedVariantId(candidate.id, live.id) to the merge loop fails only the
first test (253 pass / 1 fail); narrowing the suffix back to /^\d{8}$/ fails 13,
including the MMDD and YYMM folds. Neither mutation is caught by the predicate
test alone.

The retention test is labelled for what it actually covers: production fills
retainConfiguredModelIds from combo targets, not from providers.*.models, so it
pins the OCX-111 path. The operator-facing opt-in is #1690's retainModels, which
does not exist yet -- and until it does, the dated id #3024 reports is still
dropped. This lands the safe half of #3024 and says so.

(cherry picked from commit a909682)
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 31, 2026 18:04
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 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-08-31T18:08:15.832381Z 7063e3e PR opened
ℹ️ 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.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 31, 2026
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 81a6bd41-674a-4c6a-bf5b-dc541ae878fd

📥 Commits

Reviewing files that changed from the base of the PR and between 15f92e3 and 7063e3e.

📒 Files selected for processing (2)
  • src/codex/catalog/provider-fetch.ts
  • tests/codex-catalog.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

The change expands dated model variant detection to four validated suffix formats. It preserves strict rejection of invalid dates and numeric context-size suffixes. Tests cover matching, merge direction, live catalog folding, and explicit configured-model retention.

Changes

Dated variant catalog folding

Layer / File(s) Summary
Calendar-validated suffix matching
src/codex/catalog/provider-fetch.ts
isDatedVariantId now recognizes YYYYMMDD, YYMMDD, MMDD, and YYMM suffixes. Leap years, month lengths, and ambiguous numeric suffixes receive explicit validation.
Catalog merge behavior coverage
tests/codex-catalog.test.ts
Tests cover valid and invalid suffixes, both fold directions, direct catalog merge results, context-size exclusions, and retainConfiguredModelIds.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 7063e

The PR broadens dated model alias recognition while preserving calendar validation and one-way matching. Focused tests and type checks pass, and no actionable merge-blocking risk remains.

Suggested reviewers: ingwannu, olddonkey

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR addresses the YYYYMMDD and MMDD dated-suffix defect in #3024 and adds validation for invalid dates and numeric suffixes. However, #3024 also requires the reverse case where a configured dated I… Implement the reverse configured-dated/live-base fold required by #3024, including tests for a configured dated ID such as deepseek-v4-pro-0813 with live ID deepseek-v4-pro. If that behavior is intentionally excluded, remove or revise t…
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary changes: broader dated-variant folding and protection of the merge direction. It is specific, concise, and related to the changed implementation.
Out of Scope Changes check ✅ Passed The implementation changes in src/codex/catalog/provider-fetch.ts and the tests in tests/codex-catalog.test.ts are directly related to dated-variant detection and catalog merge behavior described …
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files.
Full details: Linked Issues check

Explanation

The PR addresses the YYYYMMDD and MMDD dated-suffix defect in #3024 and adds validation for invalid dates and numeric suffixes. However, #3024 also requires the reverse case where a configured dated ID must survive when the live catalog contains the corresponding base ID. The PR explicitly preserves one-way folding and tests that this reverse case is not inferred, so the linked issue remains only partially implemented.

Resolution

Implement the reverse configured-dated/live-base fold required by #3024, including tests for a configured dated ID such as deepseek-v4-pro-0813 with live ID deepseek-v4-pro. If that behavior is intentionally excluded, remove or revise the direct issue linkage and document the reduced scope.

Full details: Out of Scope Changes check

Explanation

The implementation changes in src/codex/catalog/provider-fetch.ts and the tests in tests/codex-catalog.test.ts are directly related to dated-variant detection and catalog merge behavior described in #3024. The added calendar validation, numeric-suffix rejection, merge-direction tests, and retention tests support those objectives. No unrelated code changes are identified.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/3024-dated-variant-fold

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.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 70 / 80

설명

이 PR은 카탈로그 합치기에서 "날짜처럼 생긴 모델 별명"을 너무 좁게만 인정하던 버그를 고칩니다. 지금 devsrc/codex/catalog/provider-fetch.tsisDatedVariantId는 접미사가 정확히 숫자 8자리(YYYYMMDD)일 때만 날짜 변형으로 봅니다. 그런데 DeepSeek, Kimi, Mistral, Qwen, Solar 같은 제공자는 -0813, -2507, -260806처럼 더 짧은 날짜 꼬리를 실제로 씁니다. 그래서 설정에는 기본 모델 이름이 있고 라이브 카탈로그에는 날짜 꼬리 버전이 있어도, 접미사가 8자리가 아니면 접히지 않고 droppedConfiguredIds로 떨어집니다. 발견(discovery)은 성공했다고 나오는데 설정한 모델은 빠진 것처럼 보이는 #3024 증상입니다.

고치는 방식은 두 겹입니다. 첫째, #3034에서 가져온 부분으로 날짜 접미사 판별을 YYYYMMDD / YYMMDD / MMDD / YYMM까지 넓히고, 달력에 없는 값(-2048, -4096, -8192, -0431, 윤년 아닌 2월 29일 등)은 거절합니다. -1024만은 10월 24일로도 읽혀서 막을 수 없는 충돌인데, 테스트로 그 비용을 고정해 두었습니다. 둘째, #3041에서 가져온 방향 가드를 서술 검사가 아니라 mergeConfiguredModelsIntoLiveCatalog 자체에 겁니다. 서술만으로는 "인자를 바꿔 한 번 더 호출하는 구현"도 통과하기 쉽기 때문입니다. 현재 dev의 합치기 루프(대략 1672행 근처)는 이미 isDatedVariantId(live.id, candidate.id) 한 방향만 쓰므로, 이 PR은 그 한 방향을 유지한 채 접미사만 넓히고, 반대 방향이 들어오면 깨지도록 통합 테스트를 세 개 심습니다.

현재 dev 방향과 맞춰 보면, HEAD 15f92e3f6은 제공자 마크 테마 생존(#3098)과 spill 디스크 예산(#3097) 쪽이고, 카탈로그 dated-fold는 round-2 우선 목록(#3026/#3029/#3008/#3019) 밖이지만 멀티 프로바이더 실설치에서 설정 모델이 통째로 빠지는 결함입니다. 본문도 분명히 말하듯 이 PR만으로 #3024를 닫지는 않습니다. 설정이 날짜 id이고 라이브가 기본 id인 반대 경우는 여전히 drop이며, 그걸 남기려면 #1690의 retainModels 같은 명시적 옵트인이 필요합니다. 안전한 반쪽만 먼저 넣는 판단은 dev 카탈로그 불변(라이브 증거가 없는 설정 id를 이름 형식만으로 부활시키지 않기)과 맞습니다. CI에서 gates/hygiene/keyring/api 등은 이미 통과했고 일부 test/macos shard는 아직 진행 중이었습니다.

라인 939 근처(PR의 isDatedVariantSuffix 추가분) - MMDDYYMM을 같은 4자리로 같이 받습니다. 2407처럼 둘 다 되는 값은 어느 해석이든 true라 접힘 자체는 되지만, "날짜인지 버전/용량인지"를 사람이 읽을 때는 모호합니다. 지금 테스트가 2048/4096/8192와 1024만 고정하므로, 비슷한 4자리 용량 꼬리가 더 생기면 표에 추가해야 합니다.

isDatedVariantId / 합치기 루프 - 런타임은 계속 isDatedVariantId(live, configured) 한 방향입니다. 서술 테스트 does not fold configured=dated against live=base만으로는 부족하고, 이번에 넣은 merge 루프 세 테스트가 있어야 반대 방향 부활을 막습니다. 그 설계는 맞습니다. 다만 #3024 본문의 "설정 dated + 라이브 base" 재현은 여전히 drop이라, 이슈를 닫으면 안 됩니다.

경로 #3034/#3041 - 이 PR이 둘을 대체한다고 본문에 적혀 있는데 아직 둘 다 OPEN입니다. 머지 후 landed-via-maintainer로 닫지 않으면 열린 PR 수가 부풀고 기여자가 헷갈립니다.

경로 #3024/#1690 - #3024의 반대 방향(설정 dated → 라이브 base)은 의도적 drop이고, 남기려면 #1690이 필요합니다. 이 PR 머지 후에도 #3024는 부분 수정으로 남기고, 닫을 조건(#1690 또는 정책 변경)을 이슈에 짧게 적는 편이 좋습니다.

메인테이너의 판단이 필요한 지점

  • #3024를 이 PR 머지 직후 부분 수정으로 두고 열어둘지, 아니면 "안전한 반쪽 완료"로 라벨만 정리할지
  • fix(catalog): recognize YYMMDD/MMDD/YYMM dated model id suffixes (#3024) #3034/#3041을 머지와 동시에 landed-via-maintainer로 닫을지(권장) 아니면 작성자 확인을 기다릴지
  • -1024 충돌을 계속 허용할지, 아니면 나중에 용량 접미사 화이트리스트/블랙리스트로 더 조일지
  • 하이픈 ISO 접미사(-2024-08-06)를 이번 범위 밖으로 둔 결정을 유지할지

너의 추천
CI 테스트 shard가 초록이면 #3100을 dev에 머지하세요. 머지 직후 #3034와 #3041에 Landed via #3100 at <commit> 댓글을 달고 landed-via-maintainer로 닫으세요. #3024는 닫지 말고, 남은 반쪽은 #1690 retainModels에 묶인다는 한 줄을 이슈에 남기세요. types/config 분할과 무관한 카탈로그 접미사 수정이라 close-don't-rebase 대상이 아닙니다.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun

Copy link
Copy Markdown
Owner Author

Administrator bypass record\n\nOwner authorization was explicit in Codex session 01a05a34-1e3a-73f2-8607-15e517cbec11 on 2026-09-01 KST. Exact head: 7063e3e. Current exact-head check rollup: 0 failing, 0 pending. Independent A-gate review found no unresolved code blocker. Using the maintain/admin pull_request bypass documented in MAINTAINERS.md because the author cannot approve their own PR. This bypass does not waive CI or security review.

@lidge-jun
lidge-jun merged commit b46164e into dev Sep 1, 2026
27 checks passed
@lidge-jun
lidge-jun deleted the codex/3024-dated-variant-fold branch September 1, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants