From 47d6c280dcb432dfb906b44870a65772bf8feba0 Mon Sep 17 00:00:00 2001 From: garrytan Date: Mon, 12 Oct 2026 00:59:45 +0000 Subject: [PATCH] fix(codex): effort flags sit among /codex's leading flags; the probe names an unfilled '' placeholder Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 2 +- bin/gstack-codex-probe | 4 ++++ codex/SKILL.md | 7 ++++--- codex/SKILL.md.tmpl | 7 ++++--- test/codex-effort.test.ts | 6 +++++- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9441bb42f..1256f5bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ ### What this means for you - **`--effort ` on any `/codex` mode.** `/codex review --effort medium`, `/codex challenge --effort=low` and so on set the effort for that request only. It outranks an exported `GSTACK_CODEX_EFFORT`, `codex_effort` and the per-mode defaults. `--xhigh` keeps working as shorthand for `--effort xhigh`. -- **Flags only where flags go.** The flag counts directly after `/codex` or its mode word, before your prompt. `/codex what does --effort do?` sends that question to Codex instead of eating `--effort` as a setting, and `/codex review --effort medium` stays on native review. +- **Flags only where flags go.** The flag counts directly after `/codex` or its mode word, alongside `-m`/`--model`/`--role`, before your prompt. `/codex what does --effort do?` sends that question to Codex instead of eating `--effort` as a setting, and `/codex review --effort medium` stays on native review. This also applies to `--xhigh`, which used to count anywhere in the input: `/codex review fix the parser --xhigh` now sends `--xhigh` as part of the instructions, so put it first (`/codex review --xhigh fix the parser`). - **A typo costs nothing and says what to fix.** `--effort turbo` stops before any Codex call, including the model probe on a cold cache, with `'turbo' from /codex --effort is not a Codex reasoning effort level` and the list of levels. A missing value or conflicting effort flags stop with a message too. - **docs:** `docs/model-policy.md` documents the per-request flag, and `docs/skills.md` documents `codex_effort` and `--effort` and no longer claims Challenge runs at `xhigh` (it runs at `high`). diff --git a/bin/gstack-codex-probe b/bin/gstack-codex-probe index 712fb9e3a..181aa85eb 100755 --- a/bin/gstack-codex-probe +++ b/bin/gstack-codex-probe @@ -859,6 +859,10 @@ _gstack_codex_effort_check() { # levels are model-dependent. A default outside it is a usage error (64). local _default="$1" _request="${2:-}" _chosen _source _cfg case "$_default" in minimal|low|medium|high|xhigh|max|ultra) ;; *) return 64 ;; esac + if [ "$_request" = "" ]; then + echo "CODEX_EFFORT: invalid — the '' placeholder was left unfilled. Pass '' when the request has no --effort. No Codex call was made." >&2 + return 1 + fi if [ -n "$_request" ]; then _chosen="$_request"; _source="/codex --effort" elif [ -n "${GSTACK_CODEX_EFFORT:-}" ]; then diff --git a/codex/SKILL.md b/codex/SKILL.md index 45d413164..0f986da69 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -484,9 +484,10 @@ set `_CODEX_ROLE='plan-review'` below and in the mode block; the mode block then probes and dispatches the policy model within its own timeout. [Policy setup](https://github.com/garrytan/gstack/blob/main/docs/model-policy.md). **Effort flags, read before the mode:** `--effort `, `--effort=` or `--xhigh` -(= `--effort xhigh`) directly after `/codex` or its mode word, before any prompt text, set -`` (else empty); remove them before Step 1. A later `--effort` is prompt text. -Missing value, not one lowercase word, or conflicting flags: stop and say so. +(= `--effort xhigh`) directly after `/codex` or its mode word, among its leading flags +(`-m`, `--model`, `--role`) and before any prompt text, set `` (else `''`); +remove them before Step 1. A later `--effort` is prompt text. Missing value, not one +lowercase word, or conflicting flags: stop and say so. ```bash _CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe diff --git a/codex/SKILL.md.tmpl b/codex/SKILL.md.tmpl index 226219b6f..2e0aee42e 100644 --- a/codex/SKILL.md.tmpl +++ b/codex/SKILL.md.tmpl @@ -78,9 +78,10 @@ set `_CODEX_ROLE='plan-review'` below and in the mode block; the mode block then probes and dispatches the policy model within its own timeout. [Policy setup](https://github.com/garrytan/gstack/blob/main/docs/model-policy.md). **Effort flags, read before the mode:** `--effort `, `--effort=` or `--xhigh` -(= `--effort xhigh`) directly after `/codex` or its mode word, before any prompt text, set -`` (else empty); remove them before Step 1. A later `--effort` is prompt text. -Missing value, not one lowercase word, or conflicting flags: stop and say so. +(= `--effort xhigh`) directly after `/codex` or its mode word, among its leading flags +(`-m`, `--model`, `--role`) and before any prompt text, set `` (else `''`); +remove them before Step 1. A later `--effort` is prompt text. Missing value, not one +lowercase word, or conflicting flags: stop and say so. ```bash _CODEX_PROBE=~/.claude/skills/gstack/bin/gstack-codex-probe diff --git a/test/codex-effort.test.ts b/test/codex-effort.test.ts index 19db2ba14..4a8f04b9a 100644 --- a/test/codex-effort.test.ts +++ b/test/codex-effort.test.ts @@ -42,7 +42,7 @@ describe('manual /codex modes (#3098)', () => { for (const want of ['GSTACK_CODEX_EFFORT', 'codex_effort', 'run-with-timeout --effort ', '--request-effort']) expect(body).toContain(want); const flags = between(body, '**Effort flags, read before the mode:**', '```bash'); expectTokens(flags, ['--effort ', '--effort=', '--xhigh', '--effort xhigh', ''], 'codex effort flags'); - expectMentions(flags, [['directly after', 'mode word', 'before any prompt text'], ['later', 'prompt text'], ['remove', 'before Step 1'], + expectMentions(flags, [['directly after', 'mode word', 'leading flags', '--model', '--role', 'before any prompt text'], ['later', 'prompt text'], ['remove', 'before Step 1'], ['missing', 'lowercase word', 'conflicting', 'stop']], 'codex effort flags'); const step1 = between(body, '## Step 1: Detect mode', '- Review (2A)'); expectMentions(step1, [['effort flags removed'], ['--request-effort', 'outranks']], 'codex Step 1'); @@ -173,6 +173,10 @@ echo '{"type":"item.completed","item":{"type":"agent_message","text":"SCORE: 8"} expect(bad.stdout).toBe(''); expect(bad.stderr).toContain("'turbo' from /codex --effort"); expect(bad.stderr).not.toContain('export GSTACK_CODEX_EFFORT'); + const unfilled = check(['high', '--request', '']); + expect(unfilled.status).toBe(1); + expect(unfilled.stderr).toContain("'' placeholder was left unfilled"); + expect(unfilled.stderr).not.toContain('from /codex --effort'); expect(check(['high', '--request']).status).toBe(64); expect(check(['high', '--bogus', 'low']).status).toBe(64); });