Skip to content

[Feature]: ocx doctor should warn about opencodex-derived Codex role TOMLs ($CODEX_HOME/agents/ocx-*.toml) that lack a model pin #4790

Closed

Description

@chano-gpt

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-route directive is only honoured on the Claude /v1/messages path, so on /v1/responses it is inert.
  • A Codex role TOML without model = inherits the parent model, so every ocx-gpt-5-5 / ocx-gpt-5-6-* spawn ran on the parent (gpt-6-astra) while the role file told the child it was Codex-ocx-native--gpt-5.5.
  • ocx doctor reports ok no per-role model_fallback fields in $CODEX_HOME/agents/*.toml and nothing else about these files, so the misrouting is invisible until you diff session rollouts (session_meta.agent_role vs turn_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 contains generated-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-*.md into 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 real model = 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:

  1. Rewrote each $CODEX_HOME/agents/ocx-*.toml by hand with model = "gpt-5.5" etc. plus model_reasoning_effort, and a plain developer_instructions (no ocx-route text). Verified a spawned ocx-gpt-5-5 child now records turn.model=gpt-5.5 medium.
  2. Changed [desktop] external-agent-import-sync-item-types from "all" to an inline table with SUBAGENTS = false so the import cannot recreate the broken files.

Additional context

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

  1. lidge-jun commented on Sep 16, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 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 (HEAD cf6e93953, 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.ts 1328–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에 두고 TOML model_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.ts 1328–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.ts renderAgentDef / GENERATED_MARKER).
    경로/심볼 - listCodexAgentRoles는 이미 모든 *.toml을 나열하므로, 핀 누락 스캔을 붙일 자리는 src/codex/subagent-model-fallback.ts 쪽이 자연스럽다.
    이슈 본문 - 선택 후속(가이드 문단 / TOML 자동 생성)을 doctor 경고와 한 PR에 묶으면 범위가 커지고 리뷰·회귀 비용이 커진다.

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

    • doctor 경고만 할지, Claude Code 가이드에 Codex external-agent import 제외(SUBAGENTS = false) 안내까지 같은 PR에 넣을지.
    • opencodex가 $CODEX_HOME/agents/ocx-*.toml을 직접 써 주는 옵션을 제품으로 열지(현재는 “우리가 안 만든다”가 문서 전제).
    • 경고 수준을 WARN(exit 0)으로 둘지, Claude inject가 켜져 있을 때만 강하게 할지.
    • 판별 마커를 ocx- 접두만으로 할지, generated-by: opencodex / ocx-route까지 요구할지(사용자 수동 ocx-*.toml 오탐).

    너의 추천
    작은 doctor-only PR로 가자. src/codex/subagent-model-fallback.ts 에 opencodex 파생·model 핀 누락 스캔을 추가하고 src/cli/doctor.ts Codex agent role files 섹션에 WARN 줄을 붙인 뒤, 픽스처 TOML로 단위 테스트를 추가한다. 가이드/자동 TOML 생성은 후속 이슈로 분리. 지금 dev tip(#4784 routing)과는 겹치지 않으니 독립 랜딩 가능. 중복 이슈로 보이는 열린 항목은 없고 close-don't-rebase 대상도 아니다.

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

  2. lidge-jun commented on Sep 18, 2026

    @lidge-jun
    Owner

    Landed via #4966 at f837e31.

  3. lidge-jun commented on Sep 18, 2026

    @lidge-jun
    Owner

    Fixed on dev by #4966 (feat(doctor): warn about opencodex-derived Codex role TOMLs with no model pin).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliCLI, config inject, packaging flagsenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions