fix: prompt delivery через stdin и захват session ID

- Зачем:
  - длинные XML-промпты (60+ строк) ломали shell quoting при inline-передаче в codex exec.
  - session ID терялся из-за 2>/dev/null на stderr, делая resume невозможным.
- Что:
  - промпт записывается в temp-файл, передаётся через stdin: `codex exec ... - < file`.
  - stderr перенаправлен в temp-файл, session ID извлекается через grep.
  - resume унифицирован: тот же stdin-механизм вместо inline-аргумента.
  - fallback fresh exec явно обновляет CODEX_SESSION_ID.
  - cleanup дополнен новыми temp-файлами (prompt, stderr).
- Проверка:
  - smoke test: plan review → 2 раунда с resume через session ID — OK.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 21:16:06 +03:00
co-authored by Claude Opus 4.6
parent 649256517e
commit 0b8891e19e
2 changed files with 34 additions and 13 deletions
+1
View File
@@ -0,0 +1 @@
.codex/
+33 -13
View File
@@ -293,13 +293,16 @@ Flags:
- `-s read-only` — reviewer only reads, does not write
- `-o /tmp/codex-review-${REVIEW_ID}.md` — file for capturing output
**Prompt delivery:** write the prompt to `/tmp/codex-prompt-${REVIEW_ID}.md` via **Write tool**, then pass via stdin redirection (`- < file`). This avoids shell quoting issues with long XML prompts.
```bash
timeout 600 codex exec \
-m gpt-5.4 \
-c model_reasoning_effort=high \
-s read-only \
-o /tmp/codex-review-${REVIEW_ID}.md \
"PROMPT"
- < /tmp/codex-prompt-${REVIEW_ID}.md \
2>/tmp/codex-stderr-${REVIEW_ID}.txt
```
**Important:**
@@ -307,13 +310,20 @@ timeout 600 codex exec \
- Use `timeout: 620000` parameter in Bash tool for headroom.
- The command is **synchronous**: when it returns, the `-o` file is ready. Do **NOT** use a poll-loop (`while/sleep`).
- If exit code = 124 (timeout) — inform the user and offer to retry.
- stderr is redirected to a temp file for session ID capture and error diagnostics.
**After launch:** find the `session id: <uuid>` line in the output and save the value as `CODEX_SESSION_ID` — needed for `resume` in subsequent rounds.
**After launch:** extract the session ID from the stderr file:
```bash
grep -o 'session id: [a-f0-9-]*' /tmp/codex-stderr-${REVIEW_ID}.txt | head -1 | sed 's/session id: //'
```
Save the result as `CODEX_SESSION_ID` — needed for `resume` in subsequent rounds. If grep returns empty — session ID not available, resume will not work (fallback to fresh exec).
**Notes:**
- Default model: `gpt-5.4` with `model_reasoning_effort=high`. User can override via arguments.
- Always `-s read-only` — reviewer must not write files.
- `-o` captures output to file. Do **NOT** run in background — the command returns control on its own.
- `-o` captures model output to file. Session ID goes to stderr (captured separately). Do **NOT** run in background.
### Step 5: Read the review and check the verdict
@@ -356,11 +366,10 @@ Based on the reviewer's findings:
**Resume is the primary path.** Saves tokens and preserves session context. A fresh `codex exec` without resume is an **emergency fallback** that costs significantly more tokens. Use only if resume fails.
1. Run resume with stderr suppressed (`2>/dev/null`):
1. Write the resume prompt to `/tmp/codex-prompt-${REVIEW_ID}.md` via **Write tool** (overwrite previous prompt):
```bash
timeout 600 codex exec resume ${CODEX_SESSION_ID} \
"I've revised based on your feedback.
```
I've revised based on your feedback.
Here's what I changed:
[List of fixes]
@@ -369,22 +378,32 @@ Re-review with the same adversarial stance. Focus on:
1. Whether my fixes actually resolve the reported issues
2. Any NEW issues introduced by the fixes
End with VERDICT: APPROVED or VERDICT: REVISE" 2>/dev/null
End with VERDICT: APPROVED or VERDICT: REVISE
```
2. Run resume via stdin redirection:
```bash
timeout 600 codex exec resume ${CODEX_SESSION_ID} \
- < /tmp/codex-prompt-${REVIEW_ID}.md \
2>/tmp/codex-stderr-${REVIEW_ID}.txt
```
Use `timeout: 620000` in Bash tool parameters.
**Why `2>/dev/null`:** `codex exec` by design separates streams — progress/metadata → stderr, final model response → stdout. Suppressing stderr gives clean output without CLI noise. The Bash tool result = review only.
stderr is redirected to temp file for diagnostics. On resume failure, check `/tmp/codex-stderr-${REVIEW_ID}.txt` for details.
2. Check the result by exit code:
3. Check the result by exit code:
- **exit 0** — success. stdout contains clean review. Show to user directly (Write to file and Read are **not needed**). Check VERDICT: the last non-empty line of stdout = `VERDICT: APPROVED` or `VERDICT: REVISE`. If verdict is missing → output may have been truncated, proceed to Fallback. Then apply verdict handling from Step 5 (APPROVED → Step 8, REVISE → Step 6).
- **exit 124** — timeout. Tell the user: "Reviewer did not respond within 10 minutes" and offer to retry.
- **other exit code** — tell the user: "Resume failed (exit code N)". Proceed to Fallback. Diagnostics without stderr are unavailable — do not try to parse stdout as an error.
- **other exit code** — tell the user: "Resume failed (exit code N)". Proceed to Fallback. Check `/tmp/codex-stderr-${REVIEW_ID}.txt` for diagnostics.
**Fallback** — if `resume` did not work (session expired, session ID not captured, error):
1. Collect the list of changed files (same as Step 3).
2. Launch a fresh `codex exec -o` with a description of previous rounds in the prompt.
2. Write the fallback prompt (with description of previous rounds) to `/tmp/codex-prompt-${REVIEW_ID}.md`.
3. Launch a fresh `codex exec` using the **same command template as Step 4** (stdin via `- < file`, stderr to temp file, `-o` for output).
4. **Extract the new session ID** from `/tmp/codex-stderr-${REVIEW_ID}.txt` and **refresh `CODEX_SESSION_ID`** — otherwise subsequent resume attempts will use the stale session ID.
Return to **Step 5**.
@@ -422,7 +441,8 @@ Return to **Step 5**.
**Outside Plan Mode:**
```bash
rm -f /tmp/claude-plan-${REVIEW_ID}.md /tmp/codex-review-${REVIEW_ID}.md
rm -f /tmp/claude-plan-${REVIEW_ID}.md /tmp/codex-review-${REVIEW_ID}.md \
/tmp/codex-prompt-${REVIEW_ID}.md /tmp/codex-stderr-${REVIEW_ID}.txt
```
If the user declined rm — continue without error.