Skip to content

review / adversarial-review silently ignore reasoning effort — --effort unparsed, and turn/start effort omitted on the adversarial path #476

Description

@ezraaaa

Summary

review and adversarial-review silently ignore reasoning effort. --effort is not a recognized flag on either command, and adversarial-review omits effort when calling runAppServerTurn — even though the underlying turn/start request already accepts it and task threads it through correctly.

The net effect: the review commands always run at whatever model_reasoning_effort sits in ~/.codex/config.toml, and there is no way to raise effort for a review specifically. For users who treat the adversarial review as their pre-merge quality gate, this is the one place extra reasoning is most worth paying for, and it's the one place they can't buy it.

This is also silent — no "unknown flag" error. ... adversarial-review --effort xhigh is accepted and runs at the config default, which reads as if it worked.

Evidence (v1.0.6)

--model is threaded end-to-end; --effort is missing at every touchpoint on this path.

1. --effort is not parsedscripts/codex-companion.mjs:714

async function handleReviewCommand(argv, config) {
  const { options, positionals } = parseCommandInput(argv, {
    valueOptions: ["base", "scope", "model", "cwd"],   // <-- no "effort"
    booleanOptions: ["json", "background", "wait"],
    aliasMap: { m: "model" }
  });

Compare handleTask (:764), which has valueOptions: ["model", "effort", "cwd", "prompt-file"] and normalizes via normalizeReasoningEffort.

2. The call site doesn't forward itscripts/codex-companion.mjs:742

executeReviewRun({
  cwd,
  base: options.base,
  scope: options.scope,
  model: options.model,     // <-- no effort
  ...
})

3. adversarial-review drops it into a call that supports itscripts/codex-companion.mjs:411

const result = await runAppServerTurn(context.repoRoot, {
  prompt,
  model: request.model,
  sandbox: "read-only",     // <-- no effort
  outputSchema: readOutputSchema(REVIEW_SCHEMA),
  onProgress: request.onProgress
});

…but runAppServerTurn (scripts/lib/codex.mjs:1139) already forwards effort to turn/start:

client.request("turn/start", {
  threadId,
  input: buildTurnInput(prompt),
  model: options.model ?? null,
  effort: options.effort ?? null,   // always null on the review path
  outputSchema: options.outputSchema ?? null
});

So effort arrives as null and the server falls back to the config default.

Two different problems

adversarial-review — straightforward fix. It already routes through runAppServerTurnturn/start, which accepts effort. Adding "effort" to valueOptions, normalizing it with the existing normalizeReasoningEffort, and passing it through the two call sites should be sufficient.

review (native) — needs a maintainer call. It goes through runAppServerReviewreview/start, whose params are { threadId, delivery, target } — no effort field. Model is applied at startThread, but buildThreadParams (lib/codex.mjs:63) doesn't carry effort either. Does thread/start accept a reasoning effort upstream? If so, the fix is symmetric with model. If not, the limitation is worth documenting, because right now it's indistinguishable from a bug.

Repro

node scripts/codex-companion.mjs adversarial-review --wait --scope branch --effort xhigh

Expected: flag rejected, or the run honours xhigh.
Actual: flag silently ignored; the run uses model_reasoning_effort from ~/.codex/config.toml.

Why the usual workarounds don't apply

  • No effort-suffixed model slugs. models_cache.json lists gpt-5.6-sol / -terra / -luna, gpt-5.5, gpt-5.4(-mini), gpt-5.3-codex-spark, codex-auto-review — none encode an effort level, so --model can't stand in for --effort.
  • A [profiles.reviewer] block doesn't work. The companion drives the app-server protocol directly and never passes --profile or reads a profile name, so a reviewer profile is inert config. (This is the same root cause as feat: allow selecting a Codex profile for companion-launched jobs #251, which asks for profile propagation.)

That leaves editing the global model_reasoning_effort as the only lever — which also changes effort for task runs and for the user's interactive Codex sessions, since it's the same file.

Related

Happy to send a PR for the adversarial-review half if that framing is agreeable.

Environment

  • plugin codex@openai-codex v1.0.6
  • codex-cli 0.144.1
  • macOS 25.5.0, Node via npm global
  • auth: ChatGPT account

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions