Бесплатный интерактивный курс · aicoding.space
Проектирование агентных петель: loop-designer
Курс про пакет @dzhechkov/loop-designer-plugin: как спроектировать агентную петлю — план, проверка, сборка скрипта и гейт — и почему пакет сознательно не умеет её запускать. Двенадцать секций и сквозной пример — рой ревьюеров, который ты собираешь вместе с Мирой.
Содержание курса
1. Граница: пакет проектирует петли, но не запускает их
Что решает пакет loop-designer и чего он принципиально не делает
Ключевая мысль: граница между авторингом петли и её запуском
Привет! Этот курс — про @dzhechkov/loop-designer-plugin: плагин для Claude Code, который помогает проектировать агентные петли. Петля — это многошаговый сценарий, где несколько агентов работают параллельно, сходятся в общей точке, повторяют шаг при неудаче или ждут ответа человека.
Знакомься: Мира. Ты уже встречал её в курсах про dz и про конвейер фич. Сегодня ей поручили собрать «рой ревьюеров»: четыре агента читают код независимо, а пятый сводит их отчёты в один вердикт. Мира набросала это прямо в промпте — и рой молча прочитал результат только одного агента из четырёх. Ошибку никто не заметил: проверять было нечего — кроме текста промпта ничего и не было.
Отсюда главная фраза пакета, и это не оговорка мелким шрифтом, а сам продукт:
> dz создаёт, проверяет и читает петли — но никогда их не запускает.
Граница проходит ровно здесь. Плагин делает четыре вещи: создаёт типизированный план петли (loop-plan/1), проверяет его на нарушения, превращает план в скрипт и читает трассу уже завершённого прогона. Запуск скрипта — работа принимающей среды: в Claude Code это Workflow({ scriptPath }).
Читай эту границу как разделение труда, а не как нехватку возможностей. План, который можно проверить до того, как потрачен первый токен агента, стоит дороже, чем запускалка, за которой можно наблюдать только тогда, когда деньги уже потрачены.
Чем пакет не является — три честных ограничения из README:
- не среда выполнения: у него нет глагола exec, start или «запусти петлю», и это закреплено тестом;
- не вторая реализация: он вызывает установленный dz, а не тащит внутрь его движки проверки и сборки;
- не копия навыка: skills/loop-plan-author/ — побайтовая проекция канона, которую чинит dz sync-canonical.
Исходники и публичное зеркало: github.com/djd1m/dz-harness.
Компромиссы: граница делает поведение честным и позволяет ловить дефекты до трат, но требует лишнего шага — скрипт нужно осознанно передать в среду выполнения, сам он не запустится.
💬 Просто попроси.
- «Объясни, что умеет плагин loop-designer» → ассистент откроет README пакета и перескажет границу между созданием и запуском петли.
- «Мне нужен рой ревьюеров, помоги спроектировать» → ассистент предложит собрать план петли и провести его через проверку и сборку.
2. Установка плагина: маркетплейс и два запасных пути
Как поставить плагин, если маркетплейс доступен — и что делать, если нет
Ключевая мысль: установка плагина loop-designer
Мира хочет, чтобы плагин появился в её сессии. Путей три, и они не равноценны — выбирай по тому, что у тебя под рукой.
Путь A — маркетплейс (рекомендуемый способ). Две строки прямо в сессии Claude Code:
/plugin marketplace add djd1m/dz-harness-hub/plugin install loop-designer@loop-designer-marketplace
Путь B1 — загрузка плагина на одну сессию. Работает без маркетплейса и даёт и навык, и все пять команд, но живёт только до конца сессии:
claude --plugin-dir "$(npx -y @dzhechkov/loop-designer-plugin init --print-plugin-dir)"
Путь B2 — голый навык в проект. Одна команда кладёт навык в .claude/skills/, и это единственный путь, где команд со слэшем не будет:
npx -y @dzhechkov/loop-designer-plugin init --dir .
Вот что эта команда печатает на самом деле (измерено на пустом проекте): «installed 2 file(s)», имя регистрации — loop-designer-plan-author, и прямая приписка, что команды сюда не входят.
Второй запуск ничего не портит. Плагин отказывается перезаписывать чужие файлы и печатает поимённо, что он бы заменил, — до тех пор пока ты не добавишь --force. Причём в конфликты попадают файлы из обоих наборов сразу: файл, оставшийся от старого выпуска и отсутствующий в новом, тоже назван по имени и с --force будет удалён, а не тихо оставлен лежать в каталоге, который README называет побайтовой копией канона.
Компромиссы: установка через маркетплейс самая короткая и постоянная, но требует доступа к нему; путь B1 ничего не требует, зато исчезает вместе с сессией; путь B2 переживает перезапуск, но лишает тебя пяти команд.
💬 Просто попроси.
- «Поставь мне плагин loop-designer в этот проект» → ассистент выберет путь по доступности маркетплейса и покажет вывод установки целиком.
- «Установка ругается, что файлы уже есть» → ассистент прочитает список «would replace» и подскажет, нужен ли --force.
3. Проверка регистрации: раскладка на диске — это ещё не факт
Почему установку проверяют живой сессией и что означает неопределённый исход
Ключевая мысль: проверка регистрации навыка живой сессией
Мира выполнила установку, увидела файлы на диске и решила, что дело сделано. Это и есть ловушка: раскладка файлов — только косвенный признак, а факт даёт лишь перечень живой сессии.
Этот урок обошёлся репозиторию дорого: однажды пакет ушёл в релиз с зелёным тестом на раскладку и нулём зарегистрировавшихся навыков. Тест смотрел на диск и был честен; он просто отвечал не на тот вопрос.
Поэтому у плагина есть отдельная проверка регистрации, в двух режимах:
loop-designer verify --static— быстрое сканирование раскладки, безопасное для непрерывной интеграции: сессию не поднимает.loop-designer verify— поднимает настоящую сессию и читает авторитетный перечень зарегистрированного.
Коды выхода: 0 — прошло, 1 — не прошло, 2 — неопределённо. И вот главное правило: неопределённо никогда не значит «прошло». Второй код означает, что регистрацию честно не удалось наблюдать, а не что с ней всё в порядке.
К этой же теме — матрица честности из README, где для каждого способа доставки прямо сказано, что ты получаешь и чего не получаешь. Загрузка плагина и голый навык измерены на Claude Code 2.1.233 с указанными шагами воспроизведения; маркетплейс и Codex помечены как заявленные до живой проверки опубликованного пакета. Если на проверяемом клиенте команды не появятся, строку понизят до «только навык», а не выпустят как непроверенное обещание.
Компромиссы: живая проверка регистрации даёт настоящий ответ, но требует запуска сессии и времени; статический режим мгновенный, но отвечает лишь на вопрос о раскладке.
💬 Просто попроси.
- «Проверь, что навык действительно зарегистрировался» → ассистент запустит loop-designer verify и покажет код выхода без пересказа.
- «У меня в CI нет сессии, как проверить установку?» → ассистент предложит verify --static и сразу оговорит, чего эта проверка не доказывает.
4. Какой dz будет работать: разрешение версии в диапазоне ^0.4.6
Как плагин выбирает исполнителя и почему код возврата не доказывает версию
Ключевая мысль: разрешение версии dz в диапазоне ^0.4.6
Плагин не тащит dz внутрь себя и не зависит от него через npm. Вместо этого он разрешает исполнителя в момент запуска, по трём шагам:
- спрашивает у
dzиз твоегоPATHего версию — быстрый путь; - берёт его, только если ответ разбирается и попадает в диапазон
^0.4.6, то есть>=0.4.6 <0.5.0; - иначе откатывается на
npx -y @dzhechkov/harness-cli@^0.4.6.
Почему нижняя граница 0.4.6, а не 0.4.0. Проверка регистрации передаёт флаг --plugin-dir, а он появился именно в 0.4.6. Более старая версия из ветки 0.4 отвергает этот флаг по имени — поэтому такой dz отклоняется сразу, с причиной и подсказкой «обнови», вместо того чтобы умереть позже необъяснимой ошибкой дочернего процесса.
Код возврата никогда не является доказательством версии. До 0.4.6 команда dz --version печатала целое руководство и завершалась нулём (измерено на 0.4.5). Сторож, который смотрел бы на статус, принял бы старый бинарник за новый. Поэтому этот сторож смотрит на разобранное число и больше ни на что.
Версия новее диапазона не отвергается за одну лишь новизну. Её проводят через проверку способностей: dz workflow --help обязан завершиться нулём и по-прежнему перечислять обёрнутые глаголы. Только провал этой проверки отправляет тебя на npx. О пройденной проверке сообщает обычная информационная строка — никогда сигнал отказа.
У Миры в PATH стояла версия 0.4.5, и первая же команда честно сказала об этом отдельной строкой, вместо того чтобы упасть где-то внутри. Мира обновила dz одной командой и вернулась к работе — потратив минуту, а не полдня на разбор чужой ошибки.
Компромиссы: такое разрешение версии переживает и старый, и новый dz, но добавляет к каждому запуску пробу, а откат на npx требует сети.
💬 Просто попроси.
- «Какой dz сейчас возьмёт плагин?» → ассистент проверит версию из PATH и скажет, попадает ли она в нужный диапазон.
- «Почему меня отправили на npx?» → ассистент найдёт строку отказа и назовёт причину: старая версия, неразобранный ответ или провал проверки способностей.
5. Сигналы отказа: четыре строки, по которым читают проблему
Именованные строки на stderr и почему их читают вместо кодов возврата
Ключевая мысль: именованные сигнальные строки отказа LOOP-DZ
Когда что-то идёт не так, плагин называет проблему по имени — отдельной строкой на потоке ошибок. Мира сначала считала эти строки шумом; на деле это единственный канал, по которому пакет сообщает об отказе.
Четыре сигнала и их смысл:
LOOP-DZ-STALE—dzиз PATH отклонён: он ниже нижней границы диапазона, его ответ не разобрался или он провалил проверку способностей. Работа продолжилась черезnpx.LOOP-DZ-UNAVAILABLE— годногоdzнет вообще:npxотсутствует либо его загрузка провалилась (нет сети, сбой реестра, истекло время ожидания). Ничего не выполнялось.LOOP-DZ-RANGE-UNSATISFIABLE—npxпринёсdzвне диапазона^0.4.6. Ничего не выполнялось.LOOP-DZ-PLUGIN-ROOT-UNSET— обёртка команды не смогла разрешить свой корень плагина и ушла в запасную форму черезnpx.
Ключевое правило: смотри на строку сигнала, а не на число. Обёртка передаёт код возврата дочернего процесса как есть — например, проверка скрипта отвечает 0, 1 или 3, — и ничто не закрепляет будущие подкоманды dz за сегодняшними числами. Строка отказа стабильна, число — нет.
И симметричное правило: сигнал появляется только при отказе. Принятое разрешение версии либо молчит, либо печатает обычную информационную строку. Если ты видишь LOOP-DZ-*, что-то точно было отвергнуто; если не видишь — отказа не было.
Компромиссы: именованные сигналы делают отказ читаемым человеком и машиной, но добавляют строки в поток ошибок, и их приходится учить — зато не приходится гадать по числам.
💬 Просто попроси.
- «Что означает LOOP-DZ-UNAVAILABLE в моём журнале?» → ассистент расшифрует сигнал отказа и скажет, что ничего не выполнялось.
- «Почему команда ушла в npx?» → ассистент найдёт сигнальную строку и назовёт конкретную причину отказа.
6. Пять команд и сквозной путь от плана до трассы
Главный рабочий сценарий: init → validate → render → lint → запуск → trace
Ключевая мысль: пять команд плагина и порядок их применения
Вот и главный рабочий сценарий. Пять команд, каждая — тонкая обёртка над соответствующим глаголом dz:
/loop-designer:init— создаёт заготовку плана. Коды: 0 записано, 1 отказано./loop-designer:validate— проверяет план на нарушения. Коды: 0 годен, 1 ошибка разбора или нарушение инварианта./loop-designer:render— превращает план в скрипт. Коды: 0 собрано, 1 отказано или расходится./loop-designer:lint— прогоняет скрипт через гейт. Коды: 0 прошло, 1 провал, 3 неопределённо — и это никогда не проход./loop-designer:trace— читает трассу завершённого прогона. Коды: 0 прочитано, 1 нечитаемо.
Мира прогнала все пять команд подряд в пустом каталоге и получила ровно то, что обещает README. Заготовка записалась, проверка ответила «годен» с отпечатком плана, сборка выдала скрипт и сама подсказала следующую команду, гейт вернул «прошло» с одним предупреждением о размере, а последняя команда сказала: трассы нет.
И вот эта последняя строка — граница, ставшая видимой. Скрипт существует и прошёл свой гейт, а трассы нет, потому что его никто не запускал. Запуск — отдельное осознанное действие в принимающей среде:
Workflow({ scriptPath: 'review-swarm.js' })
Обрати внимание и на то, чего в выводе НЕ было: при подходящем dz быстрый путь не печатает ни одной строки отказа. Тишина здесь — нормальный признак, а не потеря сообщений.
Компромиссы: пять шагов вместо одного дают проверяемый артефакт после каждого, но заставляют пройти всю цепочку даже ради небольшой правки.
💬 Просто попроси.
- «Проведи меня по всем пяти командам на моей петле» → ассистент выполнит цепочку по порядку и покажет вывод каждой команды дословно.
- «Почему у меня пустая трасса?» → ассистент напомнит, что трасса появляется только после запуска скрипта принимающей средой.
7. Когда петля вообще заслуживает плана
Признаки, по которым отличают петлю со структурой от одиночного промпта
Ключевая мысль: признаки петли, которой нужен план
Мира задала тот же вопрос, что и ты: обязательно ли теперь описывать планом каждую просьбу к ассистенту? Нет. План окупается только там, где у работы есть структура, которую стоит проверять.
Вот признаки, по которым навык предлагает завести план:
- два и более агента работают одновременно — именно ради этого существуют инварианты про ограниченное размножение и точку схода;
- шаг может быть повторён — тогда придётся честно сказать, безопасно ли повторять его дважды;
- есть пауза, на которую отвечает человек, а потом работа возобновляется — план обязан сделать паузу возобновляемой;
- есть вердикт, который может вернуть работу назад — это отдельная форма петли с ограниченным числом заходов.
И один зеркальный признак — когда плана НЕ нужно: один агент, один промпт, один ответ. Здесь навык обязан прямо сказать «плана не надо» и не тратить твоё время.
У Миры сошлись сразу два признака: четыре ревьюера параллельно и один сводящий шаг после них. Значит, план оправдан.
Компромиссы: план окупается на структуре и защищает от тихих ошибок вроде чтения одной полосы вместо четырёх, но на линейной задаче он — чистые накладные расходы.
💬 Просто попроси.
- «Моей задаче нужен план петли?» → ассистент пройдётся по признакам и честно скажет «нет», если структуры нет.
- «У меня четыре агента и один сводящий шаг» → ассистент опознает признаки схода полос и предложит соответствующий паттерн.
8. Четыре паттерна: конвейер, схождение, размножение, вердикт
Как выбрать форму петли по форме работы, а не по её размеру
Ключевая мысль: четыре паттерна петли и выбор по форме работы
Заготовка плана создаётся по одному из четырёх паттернов, и она сразу проходит проверку и собирается в скрипт без замечаний. Паттерн выбирают по ФОРМЕ работы, а не по её размеру — это правило Мира усвоила не сразу.
pipeline — один предмет проходит через упорядоченные стадии. Каждый участник идёт по цепочке шагов в заданном порядке. Бери, когда всем предметам нужна одна и та же последовательность, а стадии различаются.
barrier — независимые полосы, потом одно сведение. Размножение на независимых участников, точка схода, которая их дожидается, и потребитель, висящий на точке схода, а не на развилке. Эта деталь — отдельное правило гейта, потому что повесить потребителя на развилку — ровно тот способ, которым «параллельная» петля тихо читает результат одной полосы.
fanout — та же форма на уровне плана, что и barrier. Заготовка совпадает; различается намерение: размножение раздаёт работу, схождение раздаёт и сводит. Выбирай имя, которое правильно прочитает следующий человек.
gate — сначала произвести, потом судить, с ограниченным возвратом. Рабочий шаг плюс судейский шаг, маршрут возврата к рабочему и ограниченное число повторов. Промпт судьи обязан разбирать вердикт, а не сочинять его: пустой или неразбираемый ответ — не проход.
Мире подошёл паттерн схождения: четыре ревьюера независимы, сводящий шаг один. Именно на нём и ломался её первый набросок: потребитель висел на развилке.
Компромиссы: четырёх паттернов хватает на подавляющее большинство петель и они дают общий словарь, но два из них совпадают на уровне плана — различие держится на намерении автора, а не на проверке.
💬 Просто попроси.
- «Какой паттерн взять для роя ревьюеров?» → ассистент опознает независимые полосы со сведением и предложит соответствующую заготовку.
- «Создай заготовку плана по этому паттерну» → ассистент выполнит создание и покажет, какие поля-заглушки нужно заменить.
9. Восемь инвариантов плана: что проверка отказывается пропускать
INV-1..8 и закрытый мир схемы loop-plan/1
Ключевая мысль: восемь инвариантов плана INV-1..8
Проверка плана выдаёт по одному диагнозу на каждое нарушение, называя инвариант и путь внутри плана. Это и есть причина, по которой план стоит записывать.
Восемь инвариантов, по одной фразе каждый:
- INV-1 — ссылка на несуществующий шаг или цикл в зависимостях.
- INV-2 — размножение без ограничения сверху и без непустого реестра участников: безграничное размножение здесь просто невыразимо, а не «не рекомендуется».
- INV-3 — параллельная область без именованной точки схода либо политика схода вне закрытого набора.
- INV-4 — повторы больше одного у шага, не объявленного безопасным для повтора (и число попыток включает первую).
- INV-5 — объявленная пауза без достижимого шага паузы или без аргумента возобновления: пауза, которую нельзя возобновить, — это ложь.
- INV-6 — кэшируемость у шага, который не безопасен для повтора и не свободен от побочных эффектов.
- INV-7 — заявленный порядок фаз, противоречащий порядку их первого упоминания в скрипте.
- INV-8 — выведен из обращения и поглощён другим правилом; номер сохранён, чтобы старые планы и отчёты читались верно.
И отдельно — закрытый мир. Схема loop-plan/1 отвергает любой незнакомый ключ как ошибку разбора, а не терпит его как безобидную добавку. Причина названа в самой схеме: ключ, который разбирается, попадает в отпечаток, но никем не исполняется, — это обещание поведения, которого никто не выполняет.
Мира считала инварианты придиркой, пока INV-2 не поймал её реестр ревьюеров без верхней границы. Ограничение сверху она просто забыла — а рой без него однажды разошёлся бы по всему списку.
Компромиссы: инварианты ловят целые классы дефектов до трат, но закрытый мир означает, что любое расширение схемы требует изменения самой схемы — «просто добавить своё поле» не выйдет.
💬 Просто попроси.
- «Проверь мой план и объясни каждое нарушение» → ассистент выполнит проверку и расшифрует каждый инвариант с путём внутри плана.
- «Проверка ругается на незнакомый ключ» → ассистент напомнит про закрытый мир схемы и поможет убрать или узаконить поле.
10. Контракт claims и defers: за что шаг отвечает, а что передаёт дальше
Почему заглушка читается как чистое ревью и что это предотвращает
Ключевая мысль: контракт claims и defers у каждого шага
Каждый шаг плана обязан сказать две вещи, и обе пишутся явно.
claims — что шаг обязуется выдать: артефакт или возвращаемое значение. Если результат — файл, записанный где-то вне процесса, план обязан нести и проверку, что файл действительно лёг. Если результат — возвращаемое значение, то заглушка обязана быть распознаваема как заглушка.
defers — что шаг сознательно НЕ делает и кто делает это вместо него.
Отказ, который этот контракт предотвращает, вполне конкретен и уже случался. Шаг, результатом которого было именно возвращаемое значение, передали обёртке, которая лишь отправляет задачу и сразу возвращает управление. Обёртка вернула заглушку — и заглушка прочиталась ровно как чистое ревью. Никто не соврал; просто никто не спросил, чем именно является результат шага.
Отсюда правило, которое стоит запомнить дословно: куда отправить шаг, решает его результат, а не название обёртки. Соответствующее правило гейта следит, чтобы это оставалось честным.
Мира примерила контракт на своём рое: четыре ревьюера обязуются выдать отчёты в виде возвращаемых значений, сводящий шаг обязуется выдать один файл-вердикт и передаёт дальше — запуск, который делает принимающая среда.
Компромиссы: явные claims и defers превращают тихую ошибку в ловимую и делают план читаемым, но требуют дисциплины — заполнять их придётся руками для каждого шага.
💬 Просто попроси.
- «Заполни claims и defers для шагов моего плана» → ассистент пройдёт по шагам и предложит формулировки, отделяя файл от возвращаемого значения.
- «Можно ли отправить этот шаг в асинхронную обёртку?» → ассистент посмотрит на результат шага и предупредит, если ответом станет заглушка.
11. Сборка скрипта и регионы USER, переживающие повторную сборку
Где живёт ручная правка и почему всё остальное перезаписывается
Ключевая мысль: регионы USER переживают повторную сборку скрипта
Сборка превращает план в скрипт, размеченный на области. Области, обрамлённые парой маркеров BEGIN USER <метка> и END USER <метка>, — единственные части, которые можно править руками, и они сохраняются побайтово при повторной сборке.
Всё, что снаружи, — сгенерировано и будет перезаписано. Отсюда простое правило распределения: суждение клади в регионы USER, а механику — в план.
Три вещи, которые стоит знать про повторную сборку:
- Регионы USER переживают её без единого изменённого байта — это обещание, а не «обычно получается».
- Режим сверки собирает предлагаемый вариант в отдельный файл и показывает расхождение вместо записи.
- Если шаг, которому принадлежали регионы USER, исчез из плана, это сообщается, а не тихо выбрасывается.
Мира держала в регионах USER формулировку критериев ревью — то самое место, где нужна её голова. Всё остальное — размножение, сход полос, границы — она правила в плане и пересобирала скрипт, ни разу не потеряв своих формулировок.
Компромиссы: сохранение регионов USER даёт безопасную пересборку и чёткую границу ручного и машинного, но требует дисциплины: правка вне региона будет молча стёрта следующей сборкой.
💬 Просто попроси.
- «Пересобери скрипт из плана, мои правки не потеряй» → ассистент выполнит сборку и подтвердит, что регионы USER сохранены побайтово.
- «Покажи, что изменится при пересборке, но не пиши» → ассистент запустит режим сверки и покажет расхождение.
12. Гейт скрипта и чтение трассы: где исход бывает неопределённым
Восемнадцать правил гейта, три кода выхода и три правила честности читателя трассы
Ключевая мысль: гейт скрипта, где неопределённый исход не считается проходом
Последняя пара шагов: гейт над собранным скриптом и чтение трассы уже завершённого прогона.
Гейт — это детерминированная проверка, самый дешёвый слой обнаружения дефектов. У него восемнадцать правил, среди которых полнота заголовка, соответствие фаз, запреты песочницы, пометки у агентов, бюджет до порождения, ограниченность размножения, потребитель на точке схода, повторы только у безопасных шагов, привязка к плану и бюджет размера.
Три кода выхода: 0 — прошло, 1 — провал, 3 — неопределённо. И снова то же правило, что и у проверки регистрации: неопределённый исход никогда не считается проходом.
Два правила гейта стоит назвать отдельно, потому что за ними стоят реальные потери, а не вкусовые предпочтения:
- запреты песочницы — у среды выполнения нет часов, случайности, доступа к файловой системе и загрузки модулей: файловой системой служит сам агент;
- привязка к плану — заголовок скрипта несёт отпечаток того плана, из которого он собран, поэтому скрипт, собранный из ДРУГОГО плана, не сможет выдать себя за привязанный.
Чтение трассы отвечает на вопрос «что прогон сделал на самом деле»: показывает хронологию и проверяет инварианты, выведенные из плана. У читателя три правила честности, и их стоит пересказывать всем, кто просит у тебя цифры:
- пустая трасса — это ожидаемо, а не ошибка: петля могла просто ничего не писать, и пустота докладывается как пустота;
- прогон без кадра закрытия имеет, возможно, обрезанный хвост — проверки, зависящие от окна, дают неопределённый исход, а не проход;
- инварианты считаются по порядковым номерам событий, никогда по времени на часах.
Мира прошла путь целиком: план проверен, скрипт собран, гейт вернул «прошло» с одним предупреждением о размере. И это всё, что можно узнать до запуска, — а значит, ровно то, ради чего пакет и существует.
Компромиссы: гейт даёт дешёвый и повторяемый вердикт до трат, но проверяет только структуру скрипта; смысл петли по-прежнему на твоей ответственности, а трасса появится лишь после настоящего прогона.
💬 Просто попроси.
- «Прогони мой скрипт через гейт и объясни каждое замечание» → ассистент выполнит проверку и покажет вердикт с кодом выхода дословно.
- «Что на самом деле сделал вчерашний прогон?» → ассистент прочитает трассу и честно скажет, если её нет или хвост обрезан.
Частые вопросы
- Почему пакет не умеет запускать петли — это ведь неудобно?
Это его продукт, а не недоделка. Пакет создаёт план, проверяет его, собирает скрипт и читает трассу; запуск делает принимающая среда — в Claude Code это Workflow({ scriptPath }). План, проверенный до траты первого токена агента, ценнее запускалки, за которой можно следить только тогда, когда деньги уже потрачены.
- Нужно ли ставить dz отдельно?
Отдельная установка не обязательна. Плагин сперва спрашивает версию у dz из PATH и берёт его, если ответ разбирается и попадает в ^0.4.6; иначе откатывается на npx -y @dzhechkov/harness-cli@^0.4.6. Глобальный dz просто делает запуск быстрее и работает без сети.
- Я поставил голый навык, но команд со слэшем нет. Это поломка?
Нет, это заявленное поведение пути B2. Голый навык кладёт в проект только сам навык под именем loop-designer-plan-author. Пять команд приходят вместе с загрузкой плагина — через маркетплейс или через claude --plugin-dir.
- Гейт вернул 3, а тесты у меня зелёные. Можно считать это проходом?
Нельзя. Код 3 означает неопределённый исход: вердикт не удалось получить честно. Ровно то же и у проверки регистрации с кодом 2. Неопределённость — отдельное состояние, а не мягкая форма успеха.
- Мои правки в собранном скрипте переживут пересборку?
Только те, что лежат внутри регионов USER — они сохраняются побайтово. Всё вне регионов сгенерировано и будет перезаписано. Правило простое: суждение клади в регионы USER, механику — в план.
- Можно ли пользоваться этим в Codex?
Навык доступен и там, а dz вызывается через оболочку Codex — можно создать план, проверить его, собрать скрипт и прогнать гейт. Чего в Codex нет — так это среды выполнения: готовый скрипт передают в Claude Code, чтобы запустить.
- Почему схема плана отвергает мои дополнительные поля?
Схема loop-plan/1 работает в закрытом мире: незнакомый ключ — ошибка разбора. Причина названа в самой схеме — ключ, который разбирается и попадает в отпечаток, но ничего не исполняет, обещает поведение, которого никто не выполняет.