Skip to content

refactor(combos): isolate combo identifier helpers (split S11 L1/5) - #3594

Closed
lidge-jun wants to merge 3 commits into
devfrom
codex/split-combos-types
Closed

refactor(combos): isolate combo identifier helpers (split S11 L1/5)#3594
lidge-jun wants to merge 3 commits into
devfrom
codex/split-combos-types

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Pure move: the combo identifier helpers of src/combos/types.ts (COMBO_NAMESPACE, id pattern/validation, targetKey, parseComboModelId/comboModelId/comboPublicModelId/comboDisabledModelId/comboDisabledModelSelectors, resolveComboId, native-alias predicate — lines 13–22, 54–124, 396–399) move verbatim to src/combos/identifiers.ts (89 lines). types.ts keeps validation/normalization and re-exports all 11 moved values, so all 22 previously exported names stay importable from combos/types and the combos/index.ts facade is untouched (19 direct importers unchanged).
  • Why: 423-line file over the 400-line module limit; identifiers are a dependency-free leaf that validation consumes, so the split removes an implicit forward reference inside the file. Zero behavior change.
  • Plan and evidence: devlog/_plan/260905_now_split_train/320_combos_types.md; rules 003_parent_decisions.md (PURE-MOVE-SIZE-01, TYPE-CYCLE-01).

Stack (S11 codex-misc — independent layers, each based on dev; no cascade between them):

# PR Branch Base Review focus
5 TBD codex/split-oauth-github-copilot dev github-copilot
4 TBD codex/split-routing-trace dev routing/trace
3 TBD codex/split-codex-cli-install-provenance dev cli-install-provenance
2 TBD codex/split-codex-subagent-defaults dev subagent-defaults
1 this PR codex/split-combos-types ← you are here dev identifiers leaf

Base: dev. Review this PR's diff only (3 files, +118/−94; non-move diff: 2 leaf imports, 5 facade wiring lines, 25 test lines). Move-aware view: git diff --color-moved=dimmed-zebra dev...HEAD.

Verification

  • bun run typecheck → exit 0
  • Focused (combos, codex-catalog, combo-management-api, provider-id-rewrite) → 372 pass / 0 fail
  • tests/lab/core-lab-boundary.test.ts → 17 pass / 0 fail
  • Cycle gate including inline import("…") type edges: 18 files walked, no path returns to types.ts/index.ts/the leaf; the three pre-existing type cycles under src/types are unchanged.
  • Red-drives, then restored: wrapping comboModelId at the facade fails the new identity assertion; breaking comboDisabledModelSelectors in the leaf fails combos.test.ts:193.
  • bun run privacy:scan → passed; git diff --check dev...HEAD clean.
  • New test: identity of all 11 moved values via facade vs leaf; leaf has no back-edge.
  • Full suite on the remote CI host (lidge) at this exact SHA: recorded in the devlog doc.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed (devlog unit records the layer; no user-facing change).
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults (combo id validation moved byte-for-byte).

Summary by CodeRabbit

  • New Features
    • Added consistent combo model identifiers and aliases for selecting configured combo models.
    • Added support for resolving combo models by canonical ID or exact configured alias.
    • Improved handling of disabled combo model selectors, including native OpenAI aliases.
    • Added validation and parsing for combo model IDs, with malformed identifiers handled safely.
  • Bug Fixes
    • Preserved physical combo provider behavior when no configured combos are present.

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 5, 2026 03:13
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). label Sep 5, 2026
@coderabbitai

coderabbitai Bot commented Sep 5, 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: Team

Run ID: db823168-3710-4e9e-9064-ee14930928da

📥 Commits

Reviewing files that changed from the base of the PR and between 3c920af and 0c914bf.

📒 Files selected for processing (3)
  • src/combos/identifiers.ts
  • src/combos/types.ts
  • tests/codex-integration/combos.test.ts

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


📝 Walkthrough

Walkthrough

The change extracts combo identifier helpers into src/combos/identifiers.ts, preserves their public exports through src/combos/types.ts, and adds integration coverage for export identity and leaf-module import boundaries.

Changes

Combo identifier handling

Layer / File(s) Summary
Identifier primitives
src/combos/identifiers.ts
Adds namespace handling, native alias detection, combo identifier formatting, parsing, and validation.
Selector and configuration resolution
src/combos/identifiers.ts
Adds disabled-model selector handling and canonical-or-alias combo resolution.
Public export wiring and validation
src/combos/types.ts, tests/codex-integration/combos.test.ts
Re-exports the helpers and verifies export identity plus leaf-module import boundaries.

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

Merge Risk: ⚪ Minimal · up to 0c914

Combo identifier helpers are now housed in a dependency-free module while existing public exports remain available. The change includes compatibility and boundary coverage, with no remaining merge-readiness risk identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately describes the main change: moving combo identifier helpers into an isolated module. It is concise and specific, although the split milestone suffix is supplementary.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/split-combos-types

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

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-09-05T03:15:50.815545Z 0c914bf 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.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 61 / 80

이 PR은 combos 모듈 스플릿 트레인 S11의 1/5층입니다. 베이스는 dev, 헤드는 codex/split-combos-types, GitHub 상태는 MERGEABLE, 라벨은 chore입니다. 하는 일은 단순합니다. 지금 devsrc/combos/types.ts는 423줄로 모듈 400줄 한도를 넘깁니다. 그중 콤보 식별자 헬퍼(COMBO_NAMESPACE, id 패턴/검증, targetKey, parseComboModelId/comboModelId/comboPublicModelId/comboDisabledModelId/comboDisabledModelSelectors, resolveComboId, native-alias 판별 등)를 새 파일 src/combos/identifiers.ts(약 89줄)로 그대로 옮기고, types.ts는 validation/normalization을 남긴 채 11개 심볼을 re-export합니다. combos/index.ts 파사드와 기존 import 경로는 안 바꿉니다. 동작 변경 없는 pure move입니다.

왜 지금이냐면, 메인테이너가 걸어 둔 types/config 대형 스플릿 캠페인과 같은 규칙입니다(PURE-MOVE-SIZE-01, TYPE-CYCLE-01). 식별자 리프는 의존성이 거의 없고 validation이 그걸 쓰므로, 파일 안 forward reference를 줄이면서 한도만 맞춥니다. 계획 문서는 devlog/_plan/260905_now_split_train/320_combos_types.md에 있습니다. 같은 S11의 다른 층(oauth-github-copilot, routing-trace, cli-install-provenance, subagent-defaults)은 각각 dev 기준 독립 층이라 이 PR과 캐스케이드하지 않습니다.

검증 메모도 스플릿 PR답게 짧고 확실합니다. typecheck 통과, combos/codex-catalog/combo-management-api/provider-id-rewrite 포커스 372 pass, cycle gate에서 identifiers → types.ts/index.ts 역엣지 없음, facade vs leaf export 동일성 테스트 추가. CI는 gates/hygiene/linux 쪽이 통과이고 macos/keyring 일부는 pending입니다. dev HEAD 3c920af5f 기준으로 충돌 없이 올릴 수 있는 형태입니다.

라인 / 경로로 보면 아래를 보면 됩니다.

경로 src/combos/identifiers.ts - ../types(전역 타입)와 ../codex/catalog/native-models만 import한다. ./types./index로 돌아가지 않는다. cycle gate 주장과 맞다
경로 src/combos/types.ts - 이동 후 re-export 한 줄 + COMBO_NAMESPACE/isValidComboId/targetKey를 leaf에서 가져와 validation에 쓴다. SUPPORTED_NATIVE_OPENAI_SLUGS import는 types 쪽 validation에 남아 있어 죽은 import가 아니다
경로 tests/codex-integration/combos.test.ts - public facade와 leaf의 11개 export가 같은 참조인지, leaf 소스에 ./types|./index back-edge가 없는지 잠근다. 스플릿 회귀에 맞는 최소 테스트다
경로 S11 나머지 층 - 이 PR과 파일 겹침이 거의 없다. 닫고 리베이스할 대상이 아니라, 각각 dev에 독립 merge 가능한 chore다
경로 대형 types.ts/config.ts 스플릿 규칙 - 이 PR은 그 캠페인의 정상 층이다. “스플릿에 무효화되니 닫아라”가 아니라 “스플릿을 진행하라” 쪽이다

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

너의 추천
exact-head CI(특히 남은 macos)가 초록이면 merge 하세요. pure move라 사용자 동작 위험이 작고, 423줄 한도 위반을 바로 깎습니다. 머지 후 열린 중복·무효 PR은 없고, leftover close 대상도 아닙니다. 이어서 S11 다음 층을 같은 방식으로 올리면 됩니다. types/config 스플릿 캠페인에 맞는 정상 chore입니다.

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

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 74 / 80

설명

이 PR은 S11(codex-misc) 스플릿 기차의 1번째 칸이다. 지금 dev HEAD는 3191fe1aa이고, 방금 #3600으로 oauth 쿼럼 테스트가 이름대로 account-removal 경로를 타게 고친 직후다. 그 위에는 이미 #3587 / #3592 / #3588 쿼터 스택이 올라가 있다. 이 PR은 그 쿼터 일과는 겹치지 않는다. 하는 일은 하나다. src/combos/types.ts 안에 붙어 있던 콤보 식별자 도우미들(COMBO_NAMESPACE, id 패턴/isValidComboId, targetKey, parseComboModelId / comboModelId / comboPublicModelId / comboDisabledModelId / comboDisabledModelSelectors, resolveComboId, isNativeAliasCombo, preservesPhysicalComboProvider)을 새 파일 src/combos/identifiers.ts로 그대로 옮긴다.

왜 옮기냐면 types.ts가 약 423줄로 400줄 모듈 한도를 넘었기 때문이다. 식별자 쪽은 다른 combos 검증 로직에 의존하지 않는 잎(leaf)이다. 검증/normalize가 이 잎을 소비하는 방향이 맞고, 파일 안에 앞으로 참조하던 느낌이 사라진다. types.ts는 검증·정규화만 남기고, 옮긴 11개 이름을 전부 다시 export 한다. 그래서 combos/typescombos/index를 쓰던 기존 importer 22곳은 손대지 않아도 된다. 행동 변화는 없다. 순수 이동이다.

diff는 파일 3개(+117/−93)다. 새로 생긴 identifiers.ts 89줄, types.ts에서 해당 블록 삭제 후 re-export 한 줄과 잎 import 몇 줄, 그리고 tests/codex-integration/combos.test.ts에 facade vs leaf 동일성 + 잎이 ./types/./index를 다시 import하지 않는지 검사하는 테스트 한 덩어리다. 로컬에서 보면 이동 후 types.ts는 333줄로 한도 아래로 내려온다. SUPPORTED_NATIVE_OPENAI_SLUGS import는 types.ts 검증(nativeAlias 검사)과 identifiers.tsisNativeAliasCombo 양쪽에 여전히 쓰이므로 죽은 import가 아니다.

지금 dev가 최적화하는 방향(쿼터 스택 마무리 + 스플릿 기차 진행)과 맞물린다. S11은 레이어가 서로 cascade 없이 각자 dev 위에 올라가는 독립 칸이라고 PR 본문에 적혀 있다. 이 L1이 먼저 들어가면 뒤에 올 oauth-github-copilot / routing-trace / cli-install-provenance / subagent-defaults 칸이 같은 파일 충돌 없이 갈 수 있다. 베이스는 예전 3c920af5f(Windows shard bump 근처)라 현재 HEAD보다 뒤처져 있지만, 건드리는 파일이 쿼터/#3600과 겹치지 않아 리베이스 압박은 작다.

라인 85 - src/combos/identifiers.ts에서 resolveComboId 끝과 isValidComboId 사이에 빈 줄이 두 줄이다다. 세 번째 커밋이 trailing blank를 정리했다고 했는데 한 줄이 더 남았다. 동작엔 영향 없다. 다만 순수 이동 PR이라 이런 자잘한 공백까지 맞추는 편이 리뷰 신호가 깨끗하다.

경로/심볼 base vs HEAD - 브랜치가 현재 dev(3191fe1aa)의 조상이 아니다. 충돌 가능성은 낮지만 merge 직전에 dev로 ff/rebase 한 번만 확인하면 된다. CodeRabbit docstring coverage 경고(41% vs 80%)는 기존에 docstring이 없던 헬퍼를 그대로 옮긴 결과라서, 이 PR 범위에서 docstring을 새로 쓰기보다는 무시하거나 후속 문서 PR로 미루는 쪽이 스플릿 규칙(PURE-MOVE)과 맞다.

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

  • S11 L2~L5를 이 PR merge 직후 연속으로 열지, 아니면 L1만 먼저 랜딩하고 CI 안정화를 볼지
  • docstring coverage 경고를 스플릿 기차 전체에서 일괄 ignore할지, leaf마다 최소 JSDoc을 채울지
  • 베이스를 merge 전에 반드시 3191fe1aa로 맞출지, 충돌 없으면 그대로 squash/merge할지

너의 추천
merge. 순수 이동 + facade 동일성 테스트 + cycle/leaf back-edge 가드가 있고, 현재 dev의 쿼터/#3600 일과 파일 겹침이 없다. merge 전 identifiers.ts 이중 빈 줄만 한 줄로 줄이거나, 무시하고 바로 랜딩해도 된다. S11 다음 칸은 이 PR이 dev에 들어간 뒤에 여는 게 안전하다.

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

@lidge-jun

Copy link
Copy Markdown
Owner Author

Superseded by aggregate PR #3668, admin-merged into dev as 6585e6a after exact-head CI and tested-tree verification. This original PR was not individually merged; its rebased content and historical records were consolidated in #3668. The original branch is preserved. Further unimplemented debt layers remain deferred.

@lidge-jun lidge-jun closed this Sep 5, 2026
@lidge-jun

Copy link
Copy Markdown
Owner Author

Landed via #3668 at 6585e6a

@lidge-jun lidge-jun added the landed-via-maintainer Original PR closed after landing via a maintainer merge train label Sep 5, 2026
@lidge-jun
lidge-jun deleted the codex/split-combos-types branch September 6, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). landed-via-maintainer Original PR closed after landing via a maintainer merge train

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant