Repository navigation
[Feature]: ocx doctor should warn about opencodex-derived Codex role TOMLs ($CODEX_HOME/agents/ocx-*.toml) that lack a model pin #4790
Description
Area
CLI
What are you trying to accomplish?
Run Codex sub-agents on the models featured in the opencodex roster (ocx agent subagents), with the Claude Code integration (claudeCode.injectAgents) enabled at the same time, and have ocx doctor tell me when the Codex-side role files silently defeat that.
What prevents this today?
When the Codex desktop app's external-agent import is enabled ([desktop] external-agent-import-sync-enabled = true, item types "all"), it converts the opencodex-generated Claude Code agents ~/.claude/agents/ocx-*.md into $CODEX_HOME/agents/ocx-*.toml. The conversion drops the model: frontmatter (a claude-ocx-native--gpt-5.5 id is not a Codex model) and keeps only developer_instructions, including the <!-- ocx-route: ... --> directive with "Claude Code" text-replaced to "Codex".
Result:
- The
ocx-routedirective is only honoured on the Claude/v1/messagespath, so on/v1/responsesit is inert. - A Codex role TOML without
model =inherits the parent model, so everyocx-gpt-5-5/ocx-gpt-5-6-*spawn ran on the parent (gpt-6-astra) while the role file told the child it wasCodex-ocx-native--gpt-5.5. ocx doctorreportsok no per-role model_fallback fields in $CODEX_HOME/agents/*.tomland nothing else about these files, so the misrouting is invisible until you diff session rollouts (session_meta.agent_rolevsturn_context.model).
Verified on opencodex 2.54.0, Codex CLI 0.154.0, Codex desktop 26.908 (Windows 11).
Rollout evidence (before the fix):
role=ocx-gpt-5-6-terra src=subagent turn.model=gpt-6-astra high
role=ocx-gpt-5-6-luna src=subagent turn.model=gpt-6-astra medium
I understand opencodex does not generate Codex role TOMLs itself (sub-agent guide), so this is not an opencodex bug. But the files are recognisably opencodex-derived (generated-by: opencodex marker, ocx- prefix, ocx-route directive), and ocx doctor already scans $CODEX_HOME/agents/*.toml, so it is well placed to catch this.
What should OpenCodex do?
ocx doctor (section "Codex agent role files") should warn when a role file in $CODEX_HOME/agents/ looks opencodex-derived but has no effective model pin, for example:
- name starts with
ocx-or the body containsgenerated-by: opencodex/<!-- ocx-route:, and - the file has no
model =key.
Suggested text:
warn $CODEX_HOME/agents/ocx-gpt-5-5.toml carries an ocx-route directive but no `model` pin.
Codex will run this role on the parent model; the ocx-route directive is only honoured
on the Claude Code path. Add `model = "gpt-5.5"` or remove the file. This usually comes
from the Codex desktop external-agent import of ~/.claude/agents/ocx-*.md.
Optional follow-ups (lower priority):
- Mention in the Claude Code guide that the Codex app import can copy
ocx-*.mdinto Codex role files, and how to exclude it (external-agent-import-sync-item-types = { SUBAGENTS = false, ... }). - Or, when the Claude Code integration is enabled and
$CODEX_HOME/agents/exists, offer to write matching role TOMLs with a realmodel =pin (roster model id) so both harnesses stay in sync.
Example usage or interface
Before (current 2.54.0):
Codex agent role files
ok no per-role model_fallback fields in $CODEX_HOME/agents/*.toml
After:
Codex agent role files
ok no per-role model_fallback fields in $CODEX_HOME/agents/*.toml
warn 2 opencodex-derived role file(s) without a `model` pin: ocx-gpt-5-5.toml, ocx-gpt-5-6-luna.toml
These roles inherit the parent model. Add `model = "<id>"` or remove them.
Alternatives or workarounds
What I did, which works:
- Rewrote each
$CODEX_HOME/agents/ocx-*.tomlby hand withmodel = "gpt-5.5"etc. plusmodel_reasoning_effort, and a plaindeveloper_instructions(noocx-routetext). Verified a spawnedocx-gpt-5-5child now recordsturn.model=gpt-5.5 medium. - Changed
[desktop] external-agent-import-sync-item-typesfrom"all"to an inline table withSUBAGENTS = falseso the import cannot recreate the broken files.
Additional context
- Sub-agent guide: https://opencodex.me/guides/sub-agent-surface/ (states fallback belongs in opencodex config, not role TOMLs; does not cover role files without
model). - Claude Code guide: https://opencodex.me/guides/claude-code/ (ocx-route directive).
- Related upstream (Codex app import mangling): Claude Code skill import rewrites
.claude/paths to.Codex/, producing directories that don't exist openai/codex#40147 — skill import rewrites.claude/to.Codex/. The same text replacement shows up in the imported role files (Codex-ocx-native--gpt-5.5,Codex-api).
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
lidge-jun commentedon Sep 16, 2026
리뷰 · 우선순위 62 / 80
이 이슈는
ocx doctor가$CODEX_HOME/agents/*.toml을 이미 훑으면서도, opencodex가 만들어 둔 Claude Code 에이전트(~/.claude/agents/ocx-*.md)가 Codex 데스크톱의 external-agent import로ocx-*.toml로 복사된 뒤model핀이 빠진 상태를 전혀 경고하지 않는 구멍을 막아 달라는 요청입니다. 보고자는 Claude Code 통합(claudeCode.injectAgents)과 Codex 쪽 서브에이전트를 같이 쓰는 실제 워크플로에서, 역할 파일은Codex-ocx-native--gpt-5.5같은 문구를 들고 있는데 실제turn.model은 부모(gpt-6-astra)로만 돌아가는 불일치를 롤아웃으로 확인했습니다.지금
dev(HEADcf6e93953, tip #4784 pool recovery limiter, package 2.57.0) 기준으로 보면 관련 코드는 이미 분명히 갈라져 있습니다.src/claude/agents-inject.ts의renderAgentDef는 Claude 쪽에model:프론트매터와<!-- ocx-route: ... -->,generated-by: opencodex마커를 넣고,src/claude/inbound-model-options.ts/src/server/claude-messages.ts는 그 라우트 지시자를/v1/messages경로에서만 해석합니다. 반대로 Codex 역할 TOML 쪽 doctor는src/cli/doctor.ts1328–1335행 근처Codex agent role files섹션이scanCodexAgentRolesWithTomlModelFallback(src/codex/subagent-model-fallback.ts) 만 호출해model_fallback필드 유무만 봅니다. 필드가 없으면ok no per-role model_fallback fields...한 줄로 끝나고,model =핀 누락·ocx-접두·opencodex 파생 마커는 검사하지 않습니다. 이슈 본문이 말하는 “doctor는 초록인데 세션은 부모 모델로만 돈다”는 현재 코드와 정확히 맞습니다.opencodex가 Codex role TOML을 직접 생성하지 않는다는 전제도 맞습니다. 서브에이전트 가이드와
types/config.ts의subagentModelFallbackByModel주석(#1190)은 fallback을 config에 두고 TOMLmodel_fallback은 피하라고만 가르칩니다. 문제는 Codex 앱 import가 Claude용ocx-*.md를 가져오면서model:을 버리고ocx-route텍스트만 남기는 외부 경로입니다. 그 파일이$CODEX_HOME/agents/에 앉으면 Responses/Codex 경로에서는 지시자가 무력하고, 모델 없는 역할은 부모 모델을 상속합니다. doctor가 이미 그 디렉터리를 스캔하므로, 경고를 붙이는 자리는 자연스럽고 범위도 작습니다.제안된 판별 규칙(이름
ocx-접두 또는 본문에generated-by: opencodex/<!-- ocx-route:, 그리고model =없음)은 Claude inject 마커와 맞고, 오탐을 줄이려면 기존listCodexAgentRoles+ TOML 인식 파서 패턴을 재사용하는 편이 안전합니다. 선택 후속(가이드에 import 제외 안내, 또는 매칭 TOML을 직접 써 주기)은 doctor 경고보다 넓고 제품 결정이 필요합니다. types.ts/config.ts 스플릿 캠페인과는 무관하고, 프리뷰 배포도 이 이슈 범위가 아닙니다.라인 / 경로 - doctor는 model_fallback만 보고, opencodex 파생인데 model 핀이 없는 TOML은 조용히 통과한다 (
src/cli/doctor.ts1328–1335,scanCodexAgentRolesWithTomlModelFallback).경로/심볼 -
ocx-route해석은 Claude messages 쪽에만 있고 Responses/Codex 역할 상속과는 연결되지 않는다 (src/claude/inbound-model-options.ts,src/server/claude-messages.ts).경로/심볼 - Claude 정의는
model:+generated-by: opencodex+ocx-route를 쓰지만, Codex import가 model을 버린 결과물을 doctor가 “opencodex-derived”로 분류하는 헬퍼가 아직 없다 (src/claude/agents-inject.tsrenderAgentDef/GENERATED_MARKER).경로/심볼 -
listCodexAgentRoles는 이미 모든*.toml을 나열하므로, 핀 누락 스캔을 붙일 자리는src/codex/subagent-model-fallback.ts쪽이 자연스럽다.이슈 본문 - 선택 후속(가이드 문단 / TOML 자동 생성)을 doctor 경고와 한 PR에 묶으면 범위가 커지고 리뷰·회귀 비용이 커진다.
메인테이너의 판단이 필요한 지점
SUBAGENTS = false) 안내까지 같은 PR에 넣을지.$CODEX_HOME/agents/ocx-*.toml을 직접 써 주는 옵션을 제품으로 열지(현재는 “우리가 안 만든다”가 문서 전제).ocx-접두만으로 할지,generated-by: opencodex/ocx-route까지 요구할지(사용자 수동ocx-*.toml오탐).너의 추천
작은 doctor-only PR로 가자.
src/codex/subagent-model-fallback.ts에 opencodex 파생·model핀 누락 스캔을 추가하고src/cli/doctor.tsCodex agent role files섹션에 WARN 줄을 붙인 뒤, 픽스처 TOML로 단위 테스트를 추가한다. 가이드/자동 TOML 생성은 후속 이슈로 분리. 지금devtip(#4784 routing)과는 겹치지 않으니 독립 랜딩 가능. 중복 이슈로 보이는 열린 항목은 없고 close-don't-rebase 대상도 아니다.이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Sep 18, 2026
Landed via #4966 at f837e31.
lidge-jun commentedon Sep 18, 2026
Fixed on
devby #4966 (feat(doctor): warn about opencodex-derived Codex role TOMLs with no model pin).