docs(skills): предполёт в рецептах Кодекса, урок отдал форму сбора
- Зачем:
- среда сама отвечает за пять секунд, теряет она унаследованный файловый
дескриптор или нет, поэтому документ несёт проверку, а не ответ; форма
сбора вывода за вечер менялась дважды и не должна жить в двух местах.
- Что:
- в «Сквозные правила» codex-exec.md добавлен предполёт: самотест
`codex --version > f; wc -c f`, ветка «ноль байт» с раздельными каналами
и `set -o pipefail`, оговорка про `wait`.
- предполётная проверка песочницы переехала туда же из пункта про AppArmor,
три рецепта не тронуты — их POSIX-форма и код возврата остались честными.
- урок 2026-08-06 отдал самотест и форму предполёту, оставил находки:
дефект `2>&1 | cat`, съеденный каналом код возврата, ненужный `script`.
- Проверка:
- `false | cat > f; echo $?` — 0, с `set -o pipefail` — 1.
- `bash -c 'echo "{}"; echo err >&2' 2> >(cat > e) | cat > o` — потоки
в разных файлах, `jq` по логу проходит.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5665b96641
commit
1b73419c1d
2 files changed
+29
-27
No files matched your search
@@ -15,6 +15,24 @@ WSL2 Ubuntu: exec/resume/`-o`/фоновый Bash — весь конвейер)
|
|||||||
|
|
||||||
## Сквозные правила (любая ветка)
|
## Сквозные правила (любая ветка)
|
||||||
|
|
||||||
|
- **Предполёт — один раз на новой машине или в новом харнессе.** Две
|
||||||
|
проверки. Песочница: диагностика из
|
||||||
|
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md) (сигнатура поломки
|
||||||
|
и лечение — там же). Вывод доходит до файла: `codex --version > f;
|
||||||
|
wc -c f` — 18 байт значит, что рецепты ниже работают как написаны. Ноль
|
||||||
|
байт: среда теряет унаследованный файловый дескриптор (известный случай —
|
||||||
|
T3 Code, [lessons.md](lessons.md) 2026-08-06), и тогда каждый поток идёт
|
||||||
|
своим каналом в свой файл, а код возврата держит `pipefail`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -o pipefail
|
||||||
|
cat "$D/task-prompt.md" | codex exec --json … -o "$D/task-result.md" - \
|
||||||
|
2> >(cat > "$D/task-stderr.txt") | cat > "$D/task-stdout.jsonl"
|
||||||
|
```
|
||||||
|
|
||||||
|
Без `pipefail` статус вернёт `cat`, и отказ Кодекса прочтётся успехом.
|
||||||
|
Подстановка процесса дописывает stderr асинхронно: читаешь этот файл тем
|
||||||
|
же вызовом — поставь `wait`.
|
||||||
- **Промпт — файлом, шум — в файлы.** Промпт подавай через stdin (`-`): вход
|
- **Промпт — файлом, шум — в файлы.** Промпт подавай через stdin (`-`): вход
|
||||||
этого вызова занят промптом и должен оставаться открытым — правило
|
этого вызова занят промптом и должен оставаться открытым — правило
|
||||||
`< /dev/null` для фоновых команд сюда не относится (закроешь — получишь
|
`< /dev/null` для фоновых команд сюда не относится (закроешь — получишь
|
||||||
@@ -103,9 +121,7 @@ WSL2 Ubuntu: exec/resume/`-o`/фоновый Bash — весь конвейер)
|
|||||||
паникует; полный фикс — AppArmor-профиль, и он под sudo: сам не применяй,
|
паникует; полный фикс — AppArmor-профиль, и он под sudo: сам не применяй,
|
||||||
дай пользователю готовые команды из
|
дай пользователю готовые команды из
|
||||||
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md) (`!`-префикс в чат),
|
[codex-sandbox-apparmor.md](codex-sandbox-apparmor.md) (`!`-префикс в чат),
|
||||||
после применения профиля напомни убрать `use_legacy_landlock`. Перед первым
|
после применения профиля напомни убрать `use_legacy_landlock`.
|
||||||
прогоном конвейера на новой Linux-машине прогони оттуда же диагностику
|
|
||||||
превентивно.
|
|
||||||
- **Блок классификатора — сначала сузь песочницу, потом зови пользователя.**
|
- **Блок классификатора — сначала сузь песочницу, потом зови пользователя.**
|
||||||
Первая проверка: нет ли в команде `-s danger-full-access` — классификатор
|
Первая проверка: нет ли в команде `-s danger-full-access` — классификатор
|
||||||
его блокирует, и он не нужен (почему — в ветке исполнителя). Если блок не
|
его блокирует, и он не нужен (почему — в ветке исполнителя). Если блок не
|
||||||
|
|||||||
@@ -362,30 +362,16 @@ codex-cli 0.146.0 и была неверна. Развели две провер
|
|||||||
- **Не всякий харнесс — этот харнесс.** В Claude Code CLI 2.1.223 на той же
|
- **Не всякий харнесс — этот харнесс.** В Claude Code CLI 2.1.223 на той же
|
||||||
машине и той же 0.146.1 всё штатно: файл на выходе — 18 байт, лог — семь
|
машине и той же 0.146.1 всё штатно: файл на выходе — 18 байт, лог — семь
|
||||||
строк, `- < prompt.md` читается. Ярлыку «я в агенте» не верь, спроси среду
|
строк, `- < prompt.md` читается. Ярлыку «я в агенте» не верь, спроси среду
|
||||||
сама, это пять секунд:
|
сама — самотест стоит пять секунд и живёт предполётом в
|
||||||
|
[codex-exec.md](codex-exec.md).
|
||||||
```bash
|
- **Лечение живёт в рецептах, не здесь.** Форма сбора — каждый поток своим
|
||||||
codex --version > f; wc -c f # 0 — среда теряет унаследованный файловый
|
каналом в свой файл — стоит там же, в предполёте, и включается по
|
||||||
# дескриптор, собирай вывод каналом
|
результату самотеста; сами рецепты не правились. Три вещи, которые стоили
|
||||||
# 18 — рецепты codex-exec.md как написаны
|
отдельной проверки. `2>&1 | cat` короче и подкладывает ошибку разбора:
|
||||||
```
|
строка stderr в JSONL ломает `jq` и может встать первой вместо
|
||||||
- **Правило, годное в обеих средах**: и промпт, и вывод гнать каналами,
|
`thread.started`. Канал глотает код возврата (`false | cat` даёт ноль) —
|
||||||
потоки при этом не сливать —
|
отсюда `set -o pipefail` в форме. Псевдотерминал из первой редакции не
|
||||||
|
нужен: `script` давал тот же JSONL ценой `\r` и непереносимости.
|
||||||
```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` не правились — форма выше их не отменяет, а
|
|
||||||
дописывает сбор вывода.
|
|
||||||
- **Механизм не вскрыт.** Известно поведение, не причина: файл на входе и
|
- **Механизм не вскрыт.** Известно поведение, не причина: файл на входе и
|
||||||
выходе дочернего процесса пуст, канал цел, песочница ни при чём. Пишу это
|
выходе дочернего процесса пуст, канал цел, песочница ни при чём. Пишу это
|
||||||
свойством среды и не выдаю за объяснение.
|
свойством среды и не выдаю за объяснение.
|
||||||
|
|||||||
Reference in new issue
Block a user