Communitygithub.com

sauerlandtreffi/Codex-W-Workflow

Codex CLI as the executor: Claude specs, reviews and verifies while Codex types. Five selectable engines — Luna/Sol/Terra on OpenAI, DeepSeek and GLM-5.3 Flash via Codex Router.

Codex-W-Workflow とは?

Codex-W-Workflow is a Claude Code agent skill that codex CLI as the executor: Claude specs, reviews and verifies while Codex types. Five selectable engines — Luna/Sol/Terra on OpenAI, DeepSeek and GLM-5.3 Flash via Codex Router.

対応Claude CodeCodex CLI~CursorOpenCode
npx skills add sauerlandtreffi/Codex-W-Workflow

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Codex-W

Trigger: any message containing Codex-W (any casing), optionally with an engine name — Codex-W Luna, Codex-W Sol, Codex-W DS, Codex-W GlmFlash, Codex-W Terra. The legacy prefix Codex-First … means the same thing and still applies.

Claude Code sessions only. Codex/other harnesses: skip; never self-delegate.

Rationale: Claude (Fable/Opus) tokens metered + expensive; the Codex lanes are flat-rate. A current Codex engine (Luna / Sol / DS / GlmFlash / Terra — see below) is usually the better and faster model at writing/implementing code; Claude wins at ergonomics — judgment, design, spec-writing, review, orchestration. So Codex types, Claude thinks and verifies.

Route

Delegate to Codex (default for hands-on work):

  • implementation from a frozen spec; refactors; mechanical migrations
  • bug fixes with known repro; test writing; coverage fills
  • CI fixes, dependency bumps, scripts/tooling
  • bulk codebase exploration where raw reading ≫ the answer

Keep in Claude:

  • design, API design, architecture, naming, UX judgment
  • tasks where writing the spec IS the work (ambiguity = design)
  • tiny edits (~<20 lines, single obvious change) — delegation overhead loses
  • anything needing session tools: MCP (browser/computer-use/chronicle), 1Password, secrets
  • destructive/irreversible ops, releases, pushes, GitHub mutations — Claude-side per git rules
  • review of Codex output — never delegated, never skipped

Mixed task: Claude designs first, freezes spec, delegates build-out. Heuristic: prompt reads as a work order → delegate; writing it forces decisions → design, Claude. Portfolio/multi-repo work: $maintainer-orchestrator instead.

Two axes: Codex engine × Claude side

Independent choices. Engine = who types (the Codex CLI model). Claude side = who specs, reviews, verifies, and in fan-out plans.

Engine — "Codex-W Luna" / "Codex-W Sol" / "Codex-W DS" / "Codex-W GlmFlash" / "Codex-W Terra"

Codex always does the typing; which model does it is selectable. Pass the engine flags verbatim — never fall back to Codex's configured default.

Luna = OpenAI's Luna. Never a resold Luna. Only -c model="gpt-5.6-luna" on the default provider counts as Luna. A Luna served by opencode Go or any other reseller lane (opencode-go/…, opencode-go-messages/…, commandcode-…, clinepass-…, anything reached via model_provider="codex-router") is a different model wearing the name — not permitted for this engine, not as a fallback, not "close enough". If OpenAI's Luna is unavailable, stop and ask; do not accept a routed substitute.

CommandEngine flagsEffortOnly permitted fallback
Codex-W Luna (default)-c model="gpt-5.6-luna"no model_providermaxxhigh
Codex-W Sol-c model="gpt-5.6-sol"no model_providerhighnone — see below
Codex-W DS-c model_provider="codex-router" -c model="opencode-go/deepseek-v4-flash"maxhigh — DS has no xhigh
Codex-W GlmFlash-c model_provider="codex-router" -c model="opencode-go/glm-5.3-flash"maxhigh — ladder is low|high|max
Codex-W Terra-c model="gpt-5.6-terra"maxxhigh

Effort is per engine, not global. Luna, DS, GlmFlash and Terra run at max. Sol runs at high — that is the pin, not a starting point: do not raise it to xhigh/max to "try harder", and do not lower it to save money. Because high is already the pinned rung rather than a ceiling, Sol has no permitted fallback: if high is rejected, stop and ask rather than picking a neighbouring rung.

Pick per work order:

  • Luna — house default. Fast, affordable, metered OpenAI usage. Take it unless a reason below applies. Luna is the OpenAI lane, exclusively. It means OpenAI's own gpt-5.6-luna (catalog entry owned_by: "openai"), reached over the default provider. Never route Luna through model_provider="codex-router", and never substitute any opencode-go/* or opencode-go-messages/* model for it — the opencode Go subscription is the DS lane and nothing else. Writing the id as openai/gpt-5.6-luna is only how the lane is named in prose; that literal is not a valid slug (the catalog has no provider-prefixed Luna), so the flag stays the bare -c model="gpt-5.6-luna".
  • Sol — OpenAI's gpt-5.6-sol at high, over the default provider. The reasoning lane: use it when the work order is settled but the implementation still needs real judgment — tricky root causes with a known repro, refactors whose contracts are subtle, migrations where the mechanical edit is easy and the edge cases are not. Cheaper than Terra and more deliberate than Luna at the same typing job. Same OpenAI-only rule as Luna: only the bare -c model="gpt-5.6-sol" on the default provider counts. A Sol reached through model_provider="codex-router", a vendor-prefixed slug, or any reseller catalog entry is a different model wearing the name — stop and ask. Note gpt-5.6-sol-wm also exists in the catalog. It is not this engine; the slug is exactly gpt-5.6-sol. Sol is separately the read-only oversight model in the Codex-side ds-workflow/lama-workflow profiles (there at xhigh). Here it is a writer like any other engine, at high — the two uses share a model, not a role.
  • DS — DeepSeek V4 Flash 0731 via the flat-rate opencode Go subscription, routed through the local codex-router provider (defined in ~/.codex/config.toml). Cheapest lane: bulk mechanical work, wide refactors, test/coverage fills, long exploration — volume over finesse. Reasoning ladder is shorter than the GPT lane (low | high | max only).
  • GlmFlash — GLM-5.3 Flash via the same flat-rate opencode Go subscription as DS, routed through codex-router. The second bulk lane: reach for it when DS is saturated, when a job wants a different failure mode than DeepSeek's, or simply as the cheap default for high-volume mechanical work. Measured ladder: low | high | max — all three accepted, max is the pin, high the only downgrade. Like DS it is text-only and has no usable visual judgment — the read-only Terra companion below applies to it exactly as it does to DS.
  • Terra — strongest and priciest of the five. Hard cross-cutting reasoning, and the visual lane whenever DS is typing (below).

Rules:

  • The OpenAI lanes never touch opencode Go. The lanes are luna = OpenAI, sol = OpenAI, ds = opencode Go, glmflash = opencode Go, terra = OpenAI; they never borrow each other's provider. Whichever way a routed Luna shows up — a model_provider flag on the Luna line, a prefixed slug, a catalog entry named "Luna" or "GPT Luna" under an opencode/reseller vendor — it is not this engine. Stop and ask.

  • Check before you dispatch if anything about the id differs from the exact bare gpt-5.6-luna / gpt-5.6-sol. The lane is identified by the catalog entry, not by the word "luna" or "sol":

    curl -s "$(sed -n 's/^openai_base_url = "\(.*\)"/\1/p' ~/.codex/config.toml)/models" | grep -o '{[^}]*luna[^}]*}'
    curl -s "$(sed -n 's/^openai_base_url = "\(.*\)"/\1/p' ~/.codex/config.toml)/models" | grep -o '{[^}]*sol[^}]*}'
    

    must print exactly {"id":"gpt-5.6-luna","object":"model","owned_by":"openai"} and, for Sol, an entry {"id":"gpt-5.6-sol","object":"model","owned_by":"openai"} (the sol grep also matches gpt-5.6-sol-wm — ignore that line). Any other owned_by, or any id with a / or vendor prefix, is the wrong model.

  • Never switch engines inside one work item. resume does not inherit the engine — repeat the same flags as the original run.

  • "Codex-W DS" is not the Codex-side ds-workflow skill (~/.codex/skills/ds-workflow/SKILL.md, profiles ~/.codex/agents/ds-*.toml). That one orchestrates inside Codex with a SOL root plus DeepSeek writer agents. Here Claude stays the orchestrator and only the typing model swaps.

  • The opencode Go lanes need a running Codex Router and the model registered in it. A model new to the router is not routable until it is added and the routes are regenerated — otherwise the call falls through to the ChatGPT backend and dies with "… model is not supported when using Codex with a ChatGPT account". That error means "not routed", not "wrong flags". Registration: drop a config under config/opencode/go/<model>.json, then bin/refresh-catalog and bin/enable (refresh alone updates the catalog but not the gateway routes).

  • If an engine is unavailable (router down, model absent from the catalog), stop and ask. Do not silently retarget another engine — the cost profile is the whole point of the choice.

Visual work: Terra rides along with the opencode Go lanes (DS, GlmFlash)

The opencode Go lanes cannot do visual judgment. With engine = ds or engine = glmflash, every visual decision and every visual QA pass belongs to a separate read-only Terra run; the opencode Go engine stays the only writer. (The catalog advertises image input for DS but not supports_image_detail_original — treat its visual verdicts as unusable regardless. GLM-5.3 Flash is registered text-only, so it has nothing to judge with.)

Luna, Sol and Terra are not restricted this way — they own their visual work themselves, no companion run.

Visual = layout, hierarchy, spacing, typography, color, motion, responsive/interaction states, accessibility presentation, consistency with the existing design language.

Loop (mirrors ds-workflow): Terra brief → DS/GlmFlash implements → rendered evidence → Terra QA → the same engine fixes → Claude verifies.

V=$(mktemp); cat >"$V" <<'EOF'
<brief request or QA request: exact files/routes, the design language to match, what to judge>
EOF
command codex exec -s read-only -C <repo> \
  -c model="gpt-5.6-terra" -c model_reasoning_effort="max" \
  -i <screenshot.png> \
  -o /tmp/terra-visual.md - <"$V" 2>/dev/null
  • -s read-only, never the bypass flag: Terra directs and reviews, it never writes. One writer per item, and that is the opencode Go engine.
  • -i attaches rendered evidence (repeatable); omit it for a pure up-front brief.
  • Terra's output is spec text for DS's next resume — hand it over verbatim, don't let Terra produce the patch.
  • Nonvisual questions don't belong in the Terra run; they go back to Claude.

Claude side — "Codex-W Fable" / "Codex-W Opus"

The Claude side (spec, review, verify, and — in fan-out — planning) can run on Fable (cheap, default) or Opus (better decomposition/judgment on ambiguous or high-stakes goals). Pick by command:

  • "Codex-W Fable" — default. Cheapest orchestration.
  • "Codex-W Opus" — when the goal is ambiguous, cross-cutting, or the spec quality is the risk.

Default = the Claude Code harness/session model. Both surfaces follow the model you're already running (Opus now); a fable/opus command only pins an override.

  • Single-session skill (this file): the Claude side is whatever model the current session runs. So it already tracks the harness model. "Codex-W Opus" ⇒ run codex-w from an Opus session; "…Fable" ⇒ from a Fable session. There is no per-call model switch inside one session.
  • Fan-out (codex-fanout workflow): the planner inherits the session model by default — just Workflow({ name: 'codex-fanout', args: { goal } }). To pin it regardless of the session, pass args.model: 'opus' (or 'fable'). Workers stay Codex; final integration/review runs in the calling session.
  • Engine in fan-out: args.engine: 'luna' | 'sol' | 'ds' | 'glmflash' | 'terra' (default 'luna') picks the Codex model every worker delegates to. Independent of args.model, e.g. { goal, model: 'opus', engine: 'ds' } = Opus plans, DeepSeek types. The luna and sol entries in codex-fanout's ENGINES map are the OpenAI lanes (-c model="gpt-5.6-luna" / -c model="gpt-5.6-sol", no provider) — same rule as above: only ds and glmflash may carry opencode Go. Each engine's effort travels with it in that map, so sol workers run at high while the others run at max.

Invoke

Prompt via temp file, never inline quoting:

P=$(mktemp); cat >"$P" <<'EOF'
<goal, repo + key paths, constraints ("don't touch X"), non-goals, proof expected, output shape>
EOF
# pick exactly ONE engine line — default Luna
ENGINE=(-c model="gpt-5.6-luna" -c model_reasoning_effort="max")                                                        # Luna  — OpenAI lane, NO model_provider
ENGINE=(-c model="gpt-5.6-sol" -c model_reasoning_effort="high")                                                        # Sol   — OpenAI lane, NO model_provider, effort HIGH (not max)
ENGINE=(-c model_provider="codex-router" -c model="opencode-go/deepseek-v4-flash" -c model_reasoning_effort="max")       # DS
ENGINE=(-c model_provider="codex-router" -c model="opencode-go/glm-5.3-flash" -c model_reasoning_effort="max")           # GlmFlash
ENGINE=(-c model="gpt-5.6-terra" -c model_reasoning_effort="max")                                                        # Terra

command codex exec --dangerously-bypass-approvals-and-sandbox -C <repo> "${ENGINE[@]}" \
  -o /tmp/codex-last.md - <"$P" 2>/dev/null
  • Always pass the engine flags from the table above; never rely on Codex's configured default model.
  • The Luna and Sol lines carry no model_provider and no provider-prefixed slug — either one diverts them off the OpenAI lane. Only the DS and GlmFlash lines name codex-router / opencode-go/*.
  • Bash tool calls don't share shell state — define ENGINE in the same call as the codex exec that uses it (same for every resume).
  • Reasoning effort comes from the engine's row in the tablemax for Luna/DS/Terra, high for Sol. Never copy one engine's effort onto another. If a max run errors because max is unavailable, retry the same command with that engine's fallback (xhigh for Luna/Terra, high for DS/GlmFlash) — that is the only permitted downgrade. Sol has no fallback: high is its pin, so a rejected high is a stop-and-ask, not a retry at another rung.
  • --dangerously-bypass-approvals-and-sandbox is the house default; Codex may run commands/tests freely. Keep prompts scoped to the target repo.
  • command codex bypasses the interactive zsh wrapper; if not on PATH: fnm exec --using default -- codex
  • stderr suppressed (thinking noise bloats context); drop 2>/dev/null only to debug a failing run
  • read -o file for the result; don't parse the JSONL stream
  • long runs: Bash run_in_background, read -o file on exit; don't kill quiet runs <30 min
  • parallel independent tasks OK: separate repos/dirs, separate -o files
  • outside a git repo add --skip-git-repo-check

Follow-up fixes — cheaper than fresh runs, keeps context. resume has no -C: run from the repo dir and keep the long bypass flag:

ENGINE=(-c model="gpt-5.6-luna" -c model_reasoning_effort="max")   # SAME engine AND effort as the original run
(cd <repo> && command codex exec resume --last \
  --dangerously-bypass-approvals-and-sandbox \
  "${ENGINE[@]}" \
  -o /tmp/codex-last.md - <"$P2" 2>/dev/null)

Prompt contract

Codex starts with zero session context. Every prompt: goal, exact repo/paths, constraints, non-goals, proof expected (exact test command), output shape ("report files changed + test output"). Spec quality decides success.

Verify (Claude, always)

  • git status -sb + read the full diff; judge like a contributor PR
  • run focused tests yourself or demand proof output; Codex claims are advisory
  • iterate via resume; after 2 failed rounds, take over and do it directly
  • normal closeout still applies: $autoreview before ship

Economics

Win = generation + exploration tokens moved to Codex; Claude spends only on spec + diff review. Don't ping-pong trivia through delegation; don't re-read what Codex already summarized.

関連スキル