From d0fe248384c6f590ad9f833b068b11d12922d75c Mon Sep 17 00:00:00 2001 From: Horacehxw Date: Mon, 11 May 2026 21:34:36 +0800 Subject: [PATCH] Fix Codex review base prompt compatibility --- hooks/lib/template-loader.sh | 2 +- hooks/loop-codex-stop-hook.sh | 10 ++++--- prompt-template/codex/code-review-phase.md | 2 +- tests/test-disable-nested-codex-hooks.sh | 33 ++++++++++++++++++++++ tests/test-finalize-phase.sh | 3 +- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/hooks/lib/template-loader.sh b/hooks/lib/template-loader.sh index 13d29f6e..5eef26f6 100644 --- a/hooks/lib/template-loader.sh +++ b/hooks/lib/template-loader.sh @@ -70,7 +70,7 @@ render_template() { # Scans for {{VAR}} patterns and replaces them with values from environment # Replaced content goes directly to output without re-scanning local awk_exit=0 - content=$(env "${env_vars[@]}" awk ' + content=$(env ${env_vars[@]+"${env_vars[@]}"} awk ' BEGIN { # Build lookup table from environment variables with TMPL_VAR_ prefix for (name in ENVIRON) { diff --git a/hooks/loop-codex-stop-hook.sh b/hooks/loop-codex-stop-hook.sh index 0c191d4c..8dd60496 100755 --- a/hooks/loop-codex-stop-hook.sh +++ b/hooks/loop-codex-stop-hook.sh @@ -1228,6 +1228,8 @@ run_codex_code_review() { local prompt_fallback="# Code Review Phase - Round ${round} This file documents the code review invocation for audit purposes. +Compatibility note: Codex 0.130.0 rejects [PROMPT] input, including - stdin, when --base is used. +Humanize must not pass prompt input when --base is used; this file is audit-only. Provider: codex ## Review Configuration @@ -1256,14 +1258,14 @@ Provider: codex echo "# Review base ($review_base_type): $review_base" echo "# Timeout: $CODEX_TIMEOUT seconds" echo "" - echo "codex review ${CODEX_DISABLE_HOOKS_ARGS[*]} --base $review_base ${CODEX_REVIEW_ARGS[*]}" + echo "codex review ${CODEX_DISABLE_HOOKS_ARGS[*]-} --base $review_base ${CODEX_REVIEW_ARGS[*]}" } > "$CODEX_REVIEW_CMD_FILE" echo "Code review command saved to: $CODEX_REVIEW_CMD_FILE" >&2 echo "Running codex review with timeout ${CODEX_TIMEOUT}s in $PROJECT_ROOT (base: $review_base)..." >&2 CODEX_REVIEW_EXIT_CODE=0 - (cd "$PROJECT_ROOT" && run_with_timeout "$CODEX_TIMEOUT" codex review "${CODEX_DISABLE_HOOKS_ARGS[@]}" --base "$review_base" "${CODEX_REVIEW_ARGS[@]}") \ + (cd "$PROJECT_ROOT" && run_with_timeout "$CODEX_TIMEOUT" codex review ${CODEX_DISABLE_HOOKS_ARGS[@]+"${CODEX_DISABLE_HOOKS_ARGS[@]}"} --base "$review_base" "${CODEX_REVIEW_ARGS[@]}") \ > "$CODEX_REVIEW_LOG_FILE" 2>&1 || CODEX_REVIEW_EXIT_CODE=$? echo "Code review exit code: $CODEX_REVIEW_EXIT_CODE" >&2 @@ -1682,7 +1684,7 @@ CODEX_PROMPT_CONTENT=$(cat "$REVIEW_PROMPT_FILE") echo "# Working directory: $PROJECT_ROOT" echo "# Timeout: $CODEX_TIMEOUT seconds" echo "" - echo "codex exec ${CODEX_DISABLE_HOOKS_ARGS[*]} ${CODEX_EXEC_ARGS[*]} \"\"" + echo "codex exec ${CODEX_DISABLE_HOOKS_ARGS[*]-} ${CODEX_EXEC_ARGS[*]} \"\"" echo "" echo "# Prompt content:" echo "$CODEX_PROMPT_CONTENT" @@ -1692,7 +1694,7 @@ echo "Codex command saved to: $CODEX_CMD_FILE" >&2 echo "Running summary review with timeout ${CODEX_TIMEOUT}s..." >&2 CODEX_EXIT_CODE=0 -printf '%s' "$CODEX_PROMPT_CONTENT" | run_with_timeout "$CODEX_TIMEOUT" codex exec "${CODEX_DISABLE_HOOKS_ARGS[@]}" "${CODEX_EXEC_ARGS[@]}" - \ +printf '%s' "$CODEX_PROMPT_CONTENT" | run_with_timeout "$CODEX_TIMEOUT" codex exec ${CODEX_DISABLE_HOOKS_ARGS[@]+"${CODEX_DISABLE_HOOKS_ARGS[@]}"} "${CODEX_EXEC_ARGS[@]}" - \ > "$CODEX_STDOUT_FILE" 2> "$CODEX_STDERR_FILE" || CODEX_EXIT_CODE=$? echo "Codex exit code: $CODEX_EXIT_CODE" >&2 diff --git a/prompt-template/codex/code-review-phase.md b/prompt-template/codex/code-review-phase.md index 1bfe7f35..05d9063e 100644 --- a/prompt-template/codex/code-review-phase.md +++ b/prompt-template/codex/code-review-phase.md @@ -1,7 +1,7 @@ # Code Review Phase - Round {{REVIEW_ROUND}} This file documents the code review invocation for audit purposes. -Note: `codex review` does not accept prompt input; it performs automated code review based on git diff. +Compatibility note: Codex 0.130.0 rejects `[PROMPT]` input, including `-` stdin, when `--base` is used. Humanize must not pass prompt input when `--base` is used; this file is audit-only. ## Review Configuration diff --git a/tests/test-disable-nested-codex-hooks.sh b/tests/test-disable-nested-codex-hooks.sh index c240ad65..3538a7a6 100755 --- a/tests/test-disable-nested-codex-hooks.sh +++ b/tests/test-disable-nested-codex-hooks.sh @@ -99,6 +99,24 @@ if [[ "\$subcommand" == "exec" ]]; then fi if [[ "\$subcommand" == "review" ]]; then + saw_base=false + saw_prompt=false + for arg in "\$@"; do + if [[ "\$arg" == "--base" ]]; then + saw_base=true + elif [[ "\$arg" == "-" ]]; then + saw_prompt=true + fi + done + if [[ "\$saw_base" == "true" && "\$saw_prompt" == "true" ]]; then + echo "codex 0.130.0 rejects --base with prompt input" >&2 + exit 64 + fi + if IFS= read -r stdin_line; then + printf 'STDIN:%s\n' "\$stdin_line" >> "$args_file" + echo "codex review must not receive stdin when --base is used" >&2 + exit 65 + fi echo "No issues found." exit 0 fi @@ -206,6 +224,21 @@ else "review --disable codex_hooks" "$(cat "$TEST_DIR/review.args" 2>/dev/null || echo missing)" fi +if grep -q -- ' --base ' "$TEST_DIR/review.args" && ! grep -q -- ' -$' "$TEST_DIR/review.args" && ! grep -q '^STDIN:' "$TEST_DIR/review.args"; then + pass "review-phase codex review uses --base without prompt input" +else + fail "review-phase codex review avoids --base plus prompt input" \ + "--base arguments with no trailing '-' and no stdin" "$(cat "$TEST_DIR/review.args" 2>/dev/null || echo missing)" +fi + +REVIEW_PROMPT="$REPO_REVIEW/.humanize/rlcr/2026-03-14_12-00-00/round-2-review-prompt.md" +if [[ -f "$REVIEW_PROMPT" ]] && grep -q -- 'must not pass prompt input when `--base` is used' "$REVIEW_PROMPT"; then + pass "review audit prompt documents --base prompt incompatibility" +else + fail "review audit prompt documents --base prompt incompatibility" \ + 'must not pass prompt input when `--base` is used' "$(cat "$REVIEW_PROMPT" 2>/dev/null || echo missing)" +fi + echo "" echo "========================================" echo "Disable Nested Codex Hooks Tests" diff --git a/tests/test-finalize-phase.sh b/tests/test-finalize-phase.sh index 03a3e408..2f93eb94 100755 --- a/tests/test-finalize-phase.sh +++ b/tests/test-finalize-phase.sh @@ -732,7 +732,8 @@ echo "T-NEG-9b: Codex review log file exists and is empty" # Compute the real cache dir using same logic as loop-codex-stop-hook.sh # Cache path: $XDG_CACHE_HOME/humanize/$SANITIZED_PROJECT_PATH/$LOOP_TIMESTAMP/round-N-codex-review.log LOOP_TIMESTAMP=$(basename "$LOOP_DIR") -SANITIZED_PROJECT_PATH=$(echo "$TEST_DIR" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g') +CANONICAL_TEST_DIR="$(cd "$TEST_DIR" && pwd -P)" +SANITIZED_PROJECT_PATH=$(echo "$CANONICAL_TEST_DIR" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g') REVIEW_CACHE_DIR="$XDG_CACHE_HOME/humanize/$SANITIZED_PROJECT_PATH/$LOOP_TIMESTAMP" # Round 5 because we pass CURRENT_ROUND + 1 (4 + 1 = 5) to run_and_handle_code_review REVIEW_LOG="$REVIEW_CACHE_DIR/round-5-codex-review.log"