docs(skills): урок 08-06 — среда названа по имени, потоки не сливаются

- Зачем:
  - «изнутри харнесса» читалось как «в любом агенте»: в Claude Code CLI
    2.1.223 на той же машине и версии всё штатно, и читатель пошёл бы
    чинить работающее. И советованный `2>&1 | cat` кладёт stderr в JSONL:
    `jq` спотыкается, а первой строкой вместо thread.started может встать
    предупреждение конфига.
- Что:
  - отказ назван свойством T3 Code, а не Bash Клода; читателю дан
    самотест `codex --version > f; wc -c f` вместо веры в ярлык.
  - форма сбора вывода заменена на раздельную: stderr через подстановку
    процесса, stdout каналом; добавлена оговорка про `wait`.
- Проверка:
  - раздельная форма прогнана целиком: лог 6 строк, `jq -r .type`
    проходит по всем, thread_id из первой строки, command_execution — 2,
    stderr отдельным файлом, отчёт -o на месте.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dmitry DementievandClaude Opus 5 committed 2026-08-06 18:49:49 +03:00
1 parent 1538fdaf4e
commit 5665b96641
1 file changed
+28 -7
@@ -347,7 +347,7 @@ codex-cli 0.146.0 и была неверна. Развели две провер
на версию — первый соблазн: он объясняет всё и не требует ничего. Цена
проверки — десять минут на установку в отдельный префикс, и она стоит
того, чтобы гипотеза не уехала в журнал утверждением.
- **Ось — файл против канала.** Изнутри харнесса (Bash Клода, T3 Code) на
- **Ось — файл против канала.** Изнутри харнесса T3 Code (SDK-хост) на
0.146.1: `codex --version > f` — ноль байт и код 0, `codex --version |
cat > g` — 18 байт. То же на полном вызове: `exec --json … > log` — пусто,
он же через `2>&1 | cat > log` — семь строк, thread_id в первой,
@@ -359,12 +359,33 @@ codex-cli 0.146.0 и была неверна. Развели две провер
`No prompt provided via stdin` и код 1, `cat prompt.md |` работает; вне
харнесса работают оба. Одна причина на обе находки первой редакции — и обе
снимаются каналом.
- **Правило для этой среды**: и промпт, и лог гнать каналом —
`… 2>&1 | cat > "$D/…jsonl"`. Так живут все три механизма рецептов:
thread_id из первой строки, сторож по росту лога, проверка отписки через
`command_execution`. Псевдотерминал из первой редакции не нужен: `script`
давал тот же JSONL ценой `\r` и непереносимости. Сами рецепты
`codex-exec.md` вне харнесса верны и не правились.
- **Не всякий харнесс — этот харнесс.** В Claude Code CLI 2.1.223 на той же
машине и той же 0.146.1 всё штатно: файл на выходе — 18 байт, лог — семь
строк, `- < prompt.md` читается. Ярлыку «я в агенте» не верь, спроси среду
сама, это пять секунд:
```bash
codex --version > f; wc -c f # 0 — среда теряет унаследованный файловый
# дескриптор, собирай вывод каналом
# 18 — рецепты codex-exec.md как написаны
```
- **Правило, годное в обеих средах**: и промпт, и вывод гнать каналами,
потоки при этом не сливать —
```bash
cat "$D/task-prompt.md" | codex exec --json … -o "$D/task-result.md" - \
2> >(cat > "$D/task-stderr.txt") | cat > "$D/task-stdout.jsonl"
```
`2>&1 | cat` был бы короче и подложил бы ошибку разбора: строка stderr
в JSONL ломает `jq` и может встать первой вместо `thread.started`. В
разъехавшемся виде живут все три механизма рецептов — thread_id из первой
строки, сторож по росту лога, проверка отписки через `command_execution`.
Оговорка: подстановка процесса дописывает stderr асинхронно, перед чтением
этого файла в том же вызове нужен `wait`. Псевдотерминал из первой редакции
не нужен: `script` давал тот же JSONL ценой `\r` и непереносимости. Сами
рецепты `codex-exec.md` не правились — форма выше их не отменяет, а
дописывает сбор вывода.
- **Механизм не вскрыт.** Известно поведение, не причина: файл на входе и
выходе дочернего процесса пуст, канал цел, песочница ни при чём. Пишу это
свойством среды и не выдаю за объяснение.