diff --git a/plugins/codex/commands/adversarial-review.md b/plugins/codex/commands/adversarial-review.md index da440ab4..503feec0 100644 --- a/plugins/codex/commands/adversarial-review.md +++ b/plugins/codex/commands/adversarial-review.md @@ -1,7 +1,6 @@ --- description: Run a Codex review that challenges the implementation approach and design choices argument-hint: '[--wait|--background] [--base ] [--scope auto|working-tree|branch] [focus ...]' -disable-model-invocation: true allowed-tools: Read, Glob, Grep, Bash(node:*), Bash(git:*), AskUserQuestion --- @@ -17,6 +16,7 @@ Core constraint: - Do not fix issues, apply patches, or suggest that you are about to make changes. - Your only job is to run the review and return Codex's output verbatim to the user. - Keep the framing focused on whether the current approach is the right one, what assumptions it depends on, and where the design could fail under real-world conditions. +- Only run this command when the user has explicitly asked for an adversarial Codex review — by slash command, by naming it in a message, or through another skill or workflow that clearly invokes it. Do not run it on your own initiative as a speculative quality check. Execution mode rules: - If the raw arguments include `--wait`, do not ask. Run in the foreground. diff --git a/plugins/codex/commands/cancel.md b/plugins/codex/commands/cancel.md index a1472b83..03cbc054 100644 --- a/plugins/codex/commands/cancel.md +++ b/plugins/codex/commands/cancel.md @@ -1,8 +1,9 @@ --- description: Cancel an active background Codex job in this repository argument-hint: '[job-id]' -disable-model-invocation: true allowed-tools: Bash(node:*) --- +Only cancel a job when the user has explicitly asked to cancel or stop it. Do not cancel jobs on your own initiative. + !`node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-companion.mjs" cancel "$ARGUMENTS"` diff --git a/plugins/codex/commands/result.md b/plugins/codex/commands/result.md index 3abc2d93..7fb065be 100644 --- a/plugins/codex/commands/result.md +++ b/plugins/codex/commands/result.md @@ -1,7 +1,6 @@ --- description: Show the stored final output for a finished Codex job in this repository argument-hint: '[job-id]' -disable-model-invocation: true allowed-tools: Bash(node:*) --- diff --git a/plugins/codex/commands/status.md b/plugins/codex/commands/status.md index 8f70663d..61e096c0 100644 --- a/plugins/codex/commands/status.md +++ b/plugins/codex/commands/status.md @@ -1,7 +1,6 @@ --- description: Show active and recent Codex jobs for this repository, including review-gate status argument-hint: '[job-id] [--wait] [--timeout-ms ] [--all]' -disable-model-invocation: true allowed-tools: Bash(node:*) --- diff --git a/tests/commands.test.mjs b/tests/commands.test.mjs index ef5adb09..20514109 100644 --- a/tests/commands.test.mjs +++ b/tests/commands.test.mjs @@ -164,14 +164,33 @@ test("result and cancel commands are exposed as deterministic runtime entrypoint const cancel = read("commands/cancel.md"); const resultHandling = read("skills/codex-result-handling/SKILL.md"); - assert.match(result, /disable-model-invocation:\s*true/); - assert.match(result, /codex-companion\.mjs" result \$ARGUMENTS/); - assert.match(cancel, /disable-model-invocation:\s*true/); - assert.match(cancel, /codex-companion\.mjs" cancel \$ARGUMENTS/); + assert.match(result, /codex-companion\.mjs" result "\$ARGUMENTS"/); + assert.match(cancel, /codex-companion\.mjs" cancel "\$ARGUMENTS"/); assert.match(resultHandling, /do not turn a failed or incomplete Codex run into a Claude-side implementation attempt/i); assert.match(resultHandling, /if Codex was never successfully invoked, do not generate a substitute answer at all/i); }); +test("model invocation policy: review is user-only, other commands are model-invokable", () => { + const review = read("commands/review.md"); + const adversarialReview = read("commands/adversarial-review.md"); + const cancel = read("commands/cancel.md"); + const result = read("commands/result.md"); + const status = read("commands/status.md"); + + // review is intentionally kept user-only to avoid proactive Codex spend + assert.match(review, /disable-model-invocation:\s*true/); + + // other commands are model-invokable so Claude can route explicit user requests + assert.doesNotMatch(adversarialReview, /disable-model-invocation:\s*true/); + assert.doesNotMatch(cancel, /disable-model-invocation:\s*true/); + assert.doesNotMatch(result, /disable-model-invocation:\s*true/); + assert.doesNotMatch(status, /disable-model-invocation:\s*true/); + + // commands with side effects have explicit guardrails against proactive invocation + assert.match(adversarialReview, /Only run this command when the user has explicitly asked/i); + assert.match(cancel, /Only cancel a job when the user has explicitly asked/i); +}); + test("internal docs use task terminology for rescue runs", () => { const runtimeSkill = read("skills/codex-cli-runtime/SKILL.md"); const promptingSkill = read("skills/gpt-5-4-prompting/SKILL.md");