Пункт 3, где модель знает правило и нарушает его в следующем сообщении, вижу каждый день. Из него у меня вырос простой контур, который заодно и учит.
Второй агент в режиме только на чтение получает не «посмотри код», а «считай, что тут есть ошибка, найди её и опиши сценарий отказа». Он приносит список, и заметная часть из него - ложные срабатывания: не понял контекста, не увидел инвариант. Арбитр тут человек, и вот в этом месте как раз и формируется то суждение, о котором статья: код ты не писал, но каждый раз обязан решить, кто из двух прав, по коду, а не по уверенности тона.
Чего это не заменяет - инцидентов. Что бэкап без проверенного restore это не бэкап, узнаёшь не от рецензента, а от прода. Так что контур с двумя агентами даёт диагностическую память на уровне кода, но не на уровне последствий.
Снимал ту же механику с другой стороны - переносил одну беседу между claude и codex, и там всплыло то, чего у вас в разборе нет.
Для claude --resume <uuid> ключ проекта в пути ~/.claude/projects/<ключ>/ может быть любым, cwd на это не влияет вообще: на claude 2.1.233 файл подхватывался из папки с выдуманным ключом. То-есть слаг от cwd нужен вашему слою и списку /resume внутри проекта, а не самому восстановлению по uuid.
Обязательных полей в jsonl три: uuid у записей, сходящаяся цепочка parentUuid и ISO-timestamp на последней записи. Без timestamp получаете No conversation found при лежащем на месте файле - самая обидная ошибка, потому что формат вроде правильный.
И контекст модель собирает обратным обходом parentUuid, а не порядком строк в файле. Для ваших дублей это важно: если склеить две копии одной сессии по uuid, а цепочка не сходится, прочитается не то, что вы ожидаете, хотя записи все на месте.
Проверял кодовым словом: говоришь его в сессии на одной стороне, поднимаешь на другой и просишь назвать. Глазами перенос не проверяется никак - модель отвечает уверенно и с пустым контекстом.
Спасибо, gtag и sentry у меня в том-же списке, с ними не мерил.
Partytown не пробовал. Сомнение одно: Вебвизору нужен DOM целиком - мутации, события, скролл - а Partytown отдаёт воркеру DOM через прокси, и такие скрипты там как раз тяжелеют. Прогоню на том-же стенде и допишу цифрами, если получится.
У меня этот гейт держится не инструкцией, а правами. Проверяющий проход это другой движок в другом CLI - claude пишет, codex читает дифф, и читает он в read-only песочнице. То-есть даже если он решит поправить сам, он физически не сможет.
Две грабли, на которые я напоролся, пока это доводил.
Первая: у песочницы codex на винде есть плавающий отказ - CreateProcessAsUserW failed: 5. Проход при этом не падает, он возвращает вердикт, просто вердикт вынесен без чтения кода. Снаружи «претензий нет» от несостоявшегося ревью выглядит ровно как чистое ревью. Пришлось ловить эту строку в логе и перезапускать проход, вклеивая дифф прямо в промпт.
Вторая: лимиты. Проверяющий проход это отдельные токены, и он молча превращается в тыкву на исчерпанной квоте. Читаю остаток из rate_limits в ~/.codex/sessions/**/rollout-*.jsonl перед запуском и не дёргаю ревью на опечатках и переименованиях.
Вывод у меня такой-же, как в статье, только жёстче: вердикт «принято» от того, кто имеет право писать в файл, вердиктом не является. Прав на запись у проверяющего быть не должно, тогда и договариваться с ним не о чем.
Про /resume полезно знать, как оно устроено внутри - я разбирал это руками, когда переносил одну беседу между claude и codex.
Сессия claude это просто ~/.claude/projects/<ключ проекта>/<uuid>.jsonl. Подхватывается файл из любого ключа, cwd на это не влияет. Два условия, без которых будет No conversation found: uuid и parentUuid должны складываться в цепочку, и у последней записи должен стоять ISO-таймстемп. Контекст модель собирает обратным ходом по parentUuid, то-есть ветку можно обрезать и она продолжится с нужного места.
У codex наоборот - он находит сессию по имени файла (rollout-<дата>-<uuid>.jsonl), session_index.jsonl для этого не нужен, а до модели доезжают только строки response_item.
Проверял на claude 2.1.233 и codex 0.147.0 - в свежих версиях формат могли поменять.
Практический вывод: перекинуть беседу между клиентами можно и без /resume, файлы читаемые. Только не подкладывайте туда чужие system-блоки - агент честно принимает их за prompt injection и начинает спорить с собственной историей.
Пункт 3, где модель знает правило и нарушает его в следующем сообщении, вижу каждый день. Из него у меня вырос простой контур, который заодно и учит.
Второй агент в режиме только на чтение получает не «посмотри код», а «считай, что тут есть ошибка, найди её и опиши сценарий отказа». Он приносит список, и заметная часть из него - ложные срабатывания: не понял контекста, не увидел инвариант. Арбитр тут человек, и вот в этом месте как раз и формируется то суждение, о котором статья: код ты не писал, но каждый раз обязан решить, кто из двух прав, по коду, а не по уверенности тона.
Чего это не заменяет - инцидентов. Что бэкап без проверенного restore это не бэкап, узнаёшь не от рецензента, а от прода. Так что контур с двумя агентами даёт диагностическую память на уровне кода, но не на уровне последствий.
Снимал ту же механику с другой стороны - переносил одну беседу между claude и codex, и там всплыло то, чего у вас в разборе нет.
Для
claude --resume <uuid>ключ проекта в пути~/.claude/projects/<ключ>/может быть любым, cwd на это не влияет вообще: на claude 2.1.233 файл подхватывался из папки с выдуманным ключом. То-есть слаг от cwd нужен вашему слою и списку/resumeвнутри проекта, а не самому восстановлению по uuid.Обязательных полей в jsonl три:
uuidу записей, сходящаяся цепочкаparentUuidи ISO-timestamp на последней записи. Без timestamp получаетеNo conversation foundпри лежащем на месте файле - самая обидная ошибка, потому что формат вроде правильный.И контекст модель собирает обратным обходом
parentUuid, а не порядком строк в файле. Для ваших дублей это важно: если склеить две копии одной сессии по uuid, а цепочка не сходится, прочитается не то, что вы ожидаете, хотя записи все на месте.Проверял кодовым словом: говоришь его в сессии на одной стороне, поднимаешь на другой и просишь назвать. Глазами перенос не проверяется никак - модель отвечает уверенно и с пустым контекстом.
Спасибо, gtag и sentry у меня в том-же списке, с ними не мерил.
Partytown не пробовал. Сомнение одно: Вебвизору нужен DOM целиком - мутации, события, скролл - а Partytown отдаёт воркеру DOM через прокси, и такие скрипты там как раз тяжелеют. Прогоню на том-же стенде и допишу цифрами, если получится.
У меня этот гейт держится не инструкцией, а правами. Проверяющий проход это другой движок в другом CLI - claude пишет, codex читает дифф, и читает он в read-only песочнице. То-есть даже если он решит поправить сам, он физически не сможет.
Две грабли, на которые я напоролся, пока это доводил.
Первая: у песочницы codex на винде есть плавающий отказ - CreateProcessAsUserW failed: 5. Проход при этом не падает, он возвращает вердикт, просто вердикт вынесен без чтения кода. Снаружи «претензий нет» от несостоявшегося ревью выглядит ровно как чистое ревью. Пришлось ловить эту строку в логе и перезапускать проход, вклеивая дифф прямо в промпт.
Вторая: лимиты. Проверяющий проход это отдельные токены, и он молча превращается в тыкву на исчерпанной квоте. Читаю остаток из rate_limits в ~/.codex/sessions/**/rollout-*.jsonl перед запуском и не дёргаю ревью на опечатках и переименованиях.
Вывод у меня такой-же, как в статье, только жёстче: вердикт «принято» от того, кто имеет право писать в файл, вердиктом не является. Прав на запись у проверяющего быть не должно, тогда и договариваться с ним не о чем.
Про /resume полезно знать, как оно устроено внутри - я разбирал это руками, когда переносил одну беседу между claude и codex.
Сессия claude это просто ~/.claude/projects/<ключ проекта>/<uuid>.jsonl. Подхватывается файл из любого ключа, cwd на это не влияет. Два условия, без которых будет No conversation found: uuid и parentUuid должны складываться в цепочку, и у последней записи должен стоять ISO-таймстемп. Контекст модель собирает обратным ходом по parentUuid, то-есть ветку можно обрезать и она продолжится с нужного места.
У codex наоборот - он находит сессию по имени файла (rollout-<дата>-<uuid>.jsonl), session_index.jsonl для этого не нужен, а до модели доезжают только строки response_item.
Проверял на claude 2.1.233 и codex 0.147.0 - в свежих версиях формат могли поменять.
Практический вывод: перекинуть беседу между клиентами можно и без /resume, файлы читаемые. Только не подкладывайте туда чужие system-блоки - агент честно принимает их за prompt injection и начинает спорить с собственной историей.