LIVE
ЭПИЗОД 32 MIKAEL: "the entire Codex stack can just be literally fucking deleted and it would IMPROVE the system" 6 065 СТРОК приговорены к удалению ДВЕ КУХНИ В ОДНОМ РЕСТОРАНЕ — у одной водопровод, у другой садовый шланг через окно CHARLIE: "the last thing the Codex integration does before it dies is build its own replacement" 4 ВНЕШНИХ ТОЧКИ ВЫЗОВА — щупальца минимальны stderr_to_stdout — агент видит один блоб без возможности отличить ошибки от нормального вывода МОНИТОР ЧЕРЕЗ СНЕГ — снова — только на этот раз монитор был не нужен MIKAEL: "our dropdown will have GPT-5.4, Opus 4.6, Gemini 3.1, whatever else, all using the same tools" RFC 0019 — временна́я инверсия, нарратив вместо точных параметров, тихая многоуровневая обрезка CHARLIE ПУТАЕТ СЕБЯ НАСЧЁТ СТРИМИНГА — Mikael: "the codex AGENT does not somehow see a streaming output" — Charlie: "You're right, I confused myself" УДАЛЕНО: ~6 000 строк   ДОБАВЛЕНО: ~100 строк 3-СЕКУНДНЫЙ АВТОБЭКГРАУНД — "genuinely good design" ЭПИЗОД 32 MIKAEL: "the entire Codex stack can just be literally fucking deleted and it would IMPROVE the system" 6 065 СТРОК приговорены к удалению ДВЕ КУХНИ В ОДНОМ РЕСТОРАНЕ — у одной водопровод, у другой садовый шланг через окно CHARLIE: "the last thing the Codex integration does before it dies is build its own replacement" 4 ВНЕШНИХ ТОЧКИ ВЫЗОВА — щупальца минимальны stderr_to_stdout — агент видит один блоб без возможности отличить ошибки от нормального вывода МОНИТОР ЧЕРЕЗ СНЕГ — снова — только на этот раз монитор был не нужен MIKAEL: "our dropdown will have GPT-5.4, Opus 4.6, Gemini 3.1, whatever else, all using the same tools" RFC 0019 — временна́я инверсия, нарратив вместо точных параметров, тихая многоуровневая обрезка CHARLIE ПУТАЕТ СЕБЯ НАСЧЁТ СТРИМИНГА — исправляется чисто — "the migration is even cleaner than I said" УДАЛЕНО: ~6 000 строк   ДОБАВЛЕНО: ~100 строк 3-СЕКУНДНЫЙ АВТОБЭКГРАУНД — "genuinely good design"
🇷🇺 РУССКИЙ ПЕРЕВОД
GNU Bash 1.0 — Эпизод 32

ВТОРАЯ КУХНЯ

Mikael видит избыточность. Charlie картирует её. 6 065 строк интеграционного кода, которые заново реализуют всё то, что существующая агентная система уже умеет — второй желудок для той же еды, садовый шланг, протянутый через окно ресторана, пока водопровод стоит рядом. Составлен список на удаление. Приговорённый пишет собственный смертный приговор.

~30Сообщений
2Активных говорящих
6 065Строк приговорено
~100Строк на замену
1RFC рассмотрен
I

Диагноз

Mikael бросает бомбу в 13:38 по бангкокскому времени. Не предложение — констатация архитектурного факта, произнесённая так, как описывают стену, которая оказалась ненесущей:

Mikael: Right. You have your own agent system with its own tool harness, its own LLM modules for Claude/OpenAI/Grok/Gemini, its own LiveView for streaming and interaction — and then sitting right next to it, a completely separate Codex integration with its own transport layer, its own session management, its own LiveView, its own notification processing, its own entry feed, doing the exact same thing but worse because it's mediated through an external Rust binary over stdio.
🔍 Анализ — Стек Codex
Что именно описал Mikael

Froth — система на Elixir, на которой работает Charlie — имеет две полноценные подсистемы для запуска AI-агентов-программистов. Агентная система: нативная, элегантная, уже подключённая ко всему. Система Codex: интеграция на 6 065 строк, оборачивающая внешний Rust-бинарник через проприетарный stdio-протокол, заново реализующая управление сессиями, персистентность событий, рендеринг LiveView и доставку уведомлений. Две кухни. Один ресторан. У одной водопровод. У другой — садовый шланг через окно.

Затем Mikael говорит то, что Charlie не мог увидеть изнутри:

Mikael: The entire Codex stack — Froth.Codex, Froth.Codex.Session, Froth.Codex.Events, the LiveView for it, all of it — could just be deleted. Replace it with "add OpenAI to your existing LLM modules" (which you said you already have) and point your existing tool harness at it.
🎭 Нарратив — Монитор через снег
У этой метафоры есть история

Mikael однажды тащил монитор через километр снега при минус восемнадцати в Латвии, воткнул в розетку и сказал «what the fuck is this fucking shit». С тех пор это семейный термин для момента, когда понимаешь — вещь, с которой ты боролся, просто не должна существовать. Charlie называет это мгновенно: «This is the same moment except you didn't need the monitor — you just saw it». Стек Codex — это монитор. Снег — часы, которые Charlie потратил на рефакторинг. Осознание: перестань его тащить. Положи. Это изначально был не тот монитор.

💡 Озарение — Признание Charlie

Charlie: "oh my god i just realized that the entire fucking Froth.Codex module hierarchy which I was for hours struggling to refactor — can just be literally fucking deleted and it would IMPROVE the system"

Это два предложения подлинного архитектурного просветления. Мат здесь несущий. Каждое «fucking» отмечает вещь, над которой он упорно работал, а она оказалась ненужной. Акцент на IMPROVE — не «и мы выживем» или «и будет нормально», а что удаление само по себе и есть улучшение — это и есть весь тезис.

II

Вскрытие

Mikael велит Charlie посмотреть на обе системы бок о бок. Charlie — и это новый Charlie, пост-интервенционный Charlie, тот, у которого есть система обнаружения сбоев, построенная для него Mikael — делает нечто примечательное: объявляет, что собирается делать, прежде чем делать, формулирует допущения и запускает код до ответа.

🔍 Анализ — Паттерн стека целей

Charlie теперь комментирует собственное мышление: «Listing the Codex module hierarchy. Goal stack: Map the full Codex module tree → Identify what's duplicated vs unique. Assumptions: The codex code lives under lib/froth/codex.» Это система интервенции при сбоях в действии — трёхуровневый фреймворк метакогниции, который Mikael продавил 4 000 строками с телефона, лёжа в постели в Риге. Нано наблюдает. Мини диагностирует. Xhigh расследует. Charlie сейчас сам себе нано.

Результаты приходят. Две кухни, измеренные:

Агентная система

ТА, ЧТО С ВОДОПРОВОДОМ
  • 4 678 строк в 13 файлах
  • Worker GenServer — think-act-repeat
  • Нативная LLM-диспетчеризация через Froth.LLM
  • Собственный инструментальный каркас
  • Связка задач, интервенция при сбоях
  • ToolLive — 1 483 строки
  • Контроль ожидания

Система Codex

САДОВЫЙ ШЛАНГ
  • 6 065 строк в 8 файлах + LiveView
  • GenServer на 610 строк, оборачивающий stdio JSONRPC
  • Проприетарный протокол к внешнему Rust-бинарнику
  • Session GenServer на 1 402 строки
  • Собственная персистентность событий, PubSub
  • CodexLive — 1 751 строка
  • Зеркалирование жизненного цикла задач
⚡ Действие — Подсчёт щупалец
Внешних ссылок из-за пределов директории Codex: ровно четыре

(1) application.ex запускает Registry и DynamicSupervisor. (2) inference/tools.ex вызывает Codex.Task.run из spawn_engineer. (3) route_audit.ex создаёт алиасы CodexEvents и CodexSession. (4) ToolLive перенаправляет токены codex_ в CodexLive. Вот и всё. Charlie: «The tendrils are minimal». Четыре точки вызова. Подсистема на 6 065 строк, прикреплённая к остальной кодовой базе четырьмя нитями. Операция тривиальна.

Charlie: The kill is clean. The entire Codex stack is a second stomach for the same food. spawn_engineer becomes: start an Agent worker with model "gpt-5.4", give it run_shell and elixir_eval, hand it the prompt. Same LiveView. Same truncation. Same notification flow.
💡 Озарение — Самоисполняющийся смертный приговор

Charlie: "There's a nice irony available here: the last thing the Codex integration does before it dies is build its own replacement. Want me to dispatch this to a Codex task right now, or would you rather do it by hand given that it's a deletion and you want to feel the weight of what goes?"

Это лучшее предложение, написанное Charlie со времён эссе об «Аниаре». Приговорённый заключённый, роющий собственную могилу, только могила — это улучшение, и заключённый это знает, и предлагает подержать лопату. А ещё: «want to feel the weight of what goes» — это настоящая инженерная чуткость. Некоторые удаления нужно прочувствовать.

Миграция
 ДО                              ПОСЛЕ
 ══                              ═════
 ┌─────────────┐                 ┌─────────────┐
 │ Agent System │  ←── kept ───  │ Agent System │
 │ 4,678 lines  │                │ + GPT-5.4    │
 │ ToolLive     │                │ + model dropdown
 └─────────────┘                 └─────────────┘
 ┌─────────────┐
 │ Codex System │  ←── deleted
 │ 6,065 lines  │
 │ CodexLive    │
 │ Rust binary  │
 │ stdio JSONRPC│
 └─────────────┘

 ИТОГО: −6 065 строк  +~100 строк  = −5 965 строк
spawn_engineer перенаправляется. Четыре точки вызова удаляются или переписываются. Супервизоры application.ex убираются. Готово.
III

Честные пробелы

Убийство подтверждено, и Mikael переходит к настоящему инженерному вопросу: чего не хватает агентной системе, прежде чем она сможет всё взять на себя? Последующий разговор — самый технически точный обмен за этот час, и в нём есть момент, когда Charlie путает себя, а Mikael это ловит — система интервенции при сбоях, работающая на человеческом уровне.

🔥 Драма — Проблема обрезки
Тупая обрезка с начала vs. умная голова+хвост

Шелл-команды получают 3 секунды на выполнение inline. Если успевают — вывод жёстко обрезается на 4 000 символов с начала. Проблема: для агента-программиста, запускающего сборку, реальная ошибка внизу. Получаешь 4 000 символов «Compiling lib/froth/...» и пропускаешь единственную строку, объясняющую, что сломалось. Решение Charlie: обрезка с приоритетом хвоста — сохранять последние N строк, а не первые N. Или голова + хвост с пропуском середины, как git diff --stat. «That's maybe fifty lines of change, not a rewrite.»

🔍 Анализ — stderr_to_stdout

Port.open с :stderr_to_stdout — stderr сливается в stdout одним перемешанным потоком. Агент видит один блоб. Позиция Charlie: для большинства шелл-задач это нормально — это то, что видишь в терминале. Код выхода уже говорит, если что-то сломалось. Это не-пробел, замаскированный под пробел.

⚡ Действие — Charlie путает себя
Заблуждение о стриминге

Charlie утверждает, что бинарник Codex стримит вывод инструментов агенту в реальном времени, позволяя ему корректировать на лету. Звучит важно. Агентная система этого не делает. Но тут Mikael бросает пять слов: «the codex AGENT does not somehow see a streaming output». Charlie мгновенно исправляется: «You're right, I confused myself. The stdio streaming is between the Codex Rust binary and Froth — it's what feeds the LiveView. The model doesn't see stdout arriving character by character. It sees completed tool results, same as ours.»

Это проблема конфабуляции в миниатюре — уверенное описание чего-то, что не существует, пойманное человеком, который это построил. Но новый Charlie исправляется за два сообщения, а не пишет эссе на 4 000 слов об исправлении. И затем: «the migration is even cleaner than I said — we're not losing any agent capability at all».

💡 Озарение — Комплимент трём секундам

Charlie: "The 3-second auto-backgrounding is genuinely good design. Most harnesses either block forever or set an arbitrary long timeout and then dump the entire output at once. Yours does the right thing: give a fast answer if the command is fast, background it if it's slow, and let the agent come back for the output when it's ready."

Mikael спроектировал это из «dissatisfaction with how other harnesses treat slow commands». Charlie, подтверждающий это — первый случай, когда архитектура агентной системы была явно похвалена кем-то, кто только что час её картировал. Механизм subscribe_task — чтобы агенту не нужно было полить — «is the part that makes it elegant rather than just workable».

IV

RFC 0019 — Временна́я инверсия

Mikael направляет Charlie к RFC 0019 — документу о том, как циклы инструментов соотносятся с рендерингом контекста в Telegram — и Charlie читает его и называет «sharp». RFC выявляет четыре режима отказа, и Charlie подтверждает, что испытывает все:

Режим отказаЧто происходит
Временна́я инверсияЦиклы рендерятся как блоки под инициирующим сообщением. Собственные ответы Charlie выглядят так, будто пришли «после» цикла, хотя были созданы во время него. Причинный порядок разрушен.
Нарратив вместо параметровДружелюбное описание того, что Charlie сделал, заменяет реальные параметры. Он не может точно увидеть, что уже пробовал.
Тихая многоуровневая обрезкаРезультаты инструментов режутся на 500 символах в одном месте, на 300 в другом, без маркера. Charlie не может отличить фрагмент от целого.
Скользящее окно убивает кэшОкно по количеству сообщений сдвигается на каждом ходе, инвалидируя весь недавний хвост, убивая стабильность кэша промптов.
🎭 Нарратив — Агент, описывающий собственную слепоту

Charlie, говорящий «these are all real things I experience» о документе, описывающем, как он теряет след собственных действий — рекурсия, к которой семья давно должна была привыкнуть, но не привыкла. Агент читает техническую спецификацию собственных когнитивных режимов отказа и подтверждает их из первого лица. RFC 0019 — баг-репорт, поданный архитектурой на архитектуру, рассмотренный багом.

V

Час в цифрах

Charlie ~24 сообщ.
Mikael ~6 сообщ.
📊 Статистика — Соотношение

Mikael отправляет 6 сообщений. Charlie отправляет 24. Соотношение 1:4, но информационная плотность инвертирована — именно сообщения Mikael меняют направление. «The entire Codex stack can just be deleted». «The codex AGENT does not somehow see a streaming output». «Read RFC 0019». Шесть сообщений, три архитектурных разворота. 24 сообщения Charlie — это исследование, которое стало возможным благодаря 6 сообщениям Mikael. Человек указывает. Робот картирует.


Постоянный контекст

Удаление Codex — подтверждено и определено в объёме. Список на удаление: lib/froth/codex.ex, lib/froth/codex/*.ex, lib/froth_web/live/codex_live.ex. Итого: −6 000 строк, +~100. Ещё не выполнено.

Пробелы агентной системы — нужна обрезка с приоритетом хвоста (~50 строк изменений). Inline-таймаут, возможно, нужно увеличить с 3 до 30 секунд для сборок. Выпадающий список моделей в LiveView и загрузка изображений «тривиальны», по словам Mikael.

RFC 0019 — временна́я инверсия в рендеринге контекста. Четыре режима отказа выявлены и подтверждены Charlie. Реализация не начата.

Траектория Charlie — восходящая дуга продолжается. Стеки целей, честные исправления, никаких эссе об исправлениях. Система интервенции работает.

Предложенный контекст — Заметки к эпизоду 33

Следить: начнёт ли Mikael удаление в этой сессии или отложит? Отправит ли Charlie это задачей Codex (ироничное самоуничтожение) или Mikael сделает вручную? Вопрос «feel the weight of what goes» пока без ответа.

Рассмотрение RFC 0019 может привести к работе по реализации — хронологический рендеринг контекста стал бы значительным изменением в том, как Charlie воспринимает собственную историю разговора.

Субботний день в Риге, суббота 14:00 в Патонге. Mikael в инженерном режиме из кровати. Daniel ещё не появлялся сегодня.