Image: AI generated
31 марта 2026 года Anthropic случайно опубликовал исходные карты (source maps) вместе с npm-пакетом Claude Code (v2.1.88). Причина — одна пропущенная строка в .npmignore.1 Исходные карты объёмом 59,8 МБ обнажили около 512 тысяч строк незаобфускированного TypeScript примерно в 1 900 файлах. Anthropic заявил, что это «не нарушение безопасности, а ошибка упаковки при деплое, человеческая ошибка», и рекомендовал пользователям зафиксироваться на версии v2.1.87.
В изученной кодовой базе обнаружилось, что единственная функция в одном файле (print.ts) занимала 3 167 строк.2
Самый продаваемый в мире агент для написания кода — инструмент, который рекламируется как тот, что даёт нам поводья над кодом, — сам оказался без поводьев.
Я упоминаю это не для того, чтобы высмеять. Ровно наоборот. Этот инцидент даёт самый чёткий ответ на вопрос, на который я долго не мог ответить ясно.
«Reins Engineering — это ведь просто harness engineering?»
Хороший вопрос. И острый вопрос. Они явно похожи. Оба — нечто снаружи модели. Оба — немодельные конструкции, написанные кодом. Оба не дают агенту делать что попало. Поэтому подозрение «поводья — просто часть упряжи» вполне законно.
Долгое время я не мог ответить на этот вопрос чисто. Когда ответ наконец нашёлся, я понял: именно этот ответ точнее всего объясняет, что такое Reins. А инцидент с утечкой доказывает этот ответ на практике.
Прежде всего: они не противостоят друг другу
Представьте конскую упряжь. Седло и уздечка на спине лошади, а из уздечки через удила до рук всадника тянутся два ремня — поводья.
Поводья вдеты в уздечку. Они не снаружи упряжи — они часть упряжи. Поэтому если спросить «сбруя и поводья — это очевидно разные вещи, они противостоят друг другу?», ответ — нет. Это части одного снаряжения.
Отсюда и нужно начинать. Расхожая формула — «сбруя — это забор, поводья — это управление» — противопоставляет их. Но стоит их противопоставить, как ты проигрываешь. Один вопрос «а верификационный шлюз разве не часть сбруи?» — и конструкция рассыпается. Потому что это правда. CI, проверка типов, набор тестов — всё это нетренировочные конструкции снаружи модели, и всё это входит в сбрую.
Значит, нужно изменить вопрос. Не «противостоят ли они», а «где они расходятся».
Где становятся возможны поводья — три слоя петли
Прежде чем найти точку расхождения, нужно понять, где поводья вообще становятся возможны. Если смотреть на слои петли, их три.
① Чат-петля LLM → человек → LLM Всё вероятностно. Поводья невозможны.
② Агентная петля LLM → выполнение → наблюдение → LLM Выполнение касается детерминированной земли → поводья возможны.
③ Reins-петля ② + спроектированный верификатор + храповик Поводья завершены.
В чат-петле некуда надеть уздечку. Мы ещё даже не сели в седло. Пока LLM отвечает, человек читает и снова бросает запрос к LLM — ни один шаг не является детерминированным. Нет железа, в которое можно вдеть удила.
Агентная петля кладёт седло. В момент, когда появляется выполнение — компилятор запускается, тесты падают, файлы записываются, — петля впервые касается детерминированной земли. Впервые появляется, за что можно ухватиться.
Именно здесь причина ошеломительного успеха Claude Code. Bash, файловый ввод-вывод, запуск тестов — детерминированные шлюзы, (отчасти случайно) встроенные в петлю, уже давали «частичные поводья». Чего не было в эпоху чата.
Это не только моё утверждение. Принстонский HAL (Holistic Agent Leaderboard) показал на более чем 21 000 запусков агентов, что точность одной и той же модели меняется на десятки процентных пунктов, если поменять только обёрточный скаффолд.3 Модель фиксирована — изменилась только обрамляющая структура. Addy Osmani резюмирует в одной строке: «Средняя модель + отличный harness > отличная модель + плохой harness.» Он также отметил, что тот же Opus показывает более высокие результаты в кастомном harness, чем в Claude Code.4
До этого момента — территория, которую индустрия называет «harness engineering». Верное открытие. И именно здесь легче всего спутать с Reins. Ведь оба создают результаты снаружи модели.
Но ② — лишь случайная половина поводьев. Reins Engineering — это намеренное завершение этой половины. Превратить случайно встроенный шлюз в спроектированный верификатор с храповиком и разделением решения/реализации, подтянув ② до ③. Дискурс о harness доказывает поводья, но не заменяет их.
Три оси
Двое работают с одной лошадью.
Один делает упряжь. Размер седла, прочность уздечки, форма удил. Это одинаково подходит для любой лошади, любого путешествия. Хорошо сделанная упряжь — одна и та же, едешь ли ты в Москву или во Владивосток. Тот, кто её делает, — шорник, не всадник.
Другой держит поводья. Он знает это путешествие. На каком перекрёстке повернуть налево, где финал, когда можно сказать «прибыли». Ремни в его руках вдеты в ту же упряжь, но сигналы, что он посылает, — разные в каждом путешествии. Тот, кто их посылает, — всадник, не шорник.
Здесь три оси.
- Функция. Сбруя ограничивает — граница невозможного. Поводья направляют — куда идти и когда закончено.
- Срок службы. Сбруя делается однажды и переиспользуется для любой задачи. Поводья проектируются заново для каждой задачи.
- Принадлежность. Сбрую выпускает вендор. Поводья пишет архитектор.
Петля Claude Code одинакова, чем бы я ни занимался. Это сбруя. Anthropic её выпустил, она одинакова для всех пользователей. Но «выселение арендатора = пять фотографий указанных мест» — это определение завершения, которое написал я, для этого домена, лично. Ни одна сбруя этого не содержит. Это и есть поводья.
Зависимость течёт в одну сторону
Если они — одно и то же, то нельзя убрать одно, оставив другое. Давайте уберём.
Сбруя есть, поводьев нет. Агент работает. Не останавливается и работает. Только блуждает. Скитается по полю без маркера цели и без вердикта о завершении, потом останавливается на «ну, примерно хватит». Мы уже знаем, как это называется. Vibe coding.
Поводья есть, сбруи нет. Это вообще невозможно. Держишь поводья, а уздечки нет. Некуда послать сигнал. Просто держишь ремни в воздухе.
Зависимость односторонняя. Поводья нуждаются в сбруе, но сбруя не нуждается в поводьях. Сбруя работает без поводьев — просто работает плохо. Эта асимметрия чисто опровергает «они одно и то же». Если бы они были одним и тем же, уберёшь одно — рухнет и другое. Но сбруя бежит и в одиночку.
Место пересечения — ровно одна ячейка
Так есть ли вообще место, где они пересекаются? Есть. Ровно одна ячейка.
Исполняемый верификационный шлюз. CI работает внутри агентной петли. Эта поверхность исполнения (enforcement surface) лежит на обеих сторонах — она часть сбруи и то, что накладывают поводья. Именно здесь рождается вопрос «это ведь сбруя». Да, в этой одной ячейке оба указывают на одно и то же.
Но за её пределами — расхождение.
Только сбруя Пересечение Только Reins
───────────────── ───────────────────── ─────────────────────
Песочница·права Верификационный шлюз Определение завершения
Разводка инструм. (исполняемые чеки) Проектирование анти-cheese
Управление контекстом Анализ прокси↔цели
(ограничение без направления) (поверхность исполнения) (намерение без субстрата)
В сбруе есть своё ограничение без направления — песочница не говорит «куда идти», она просто не даёт выйти. В Reins есть своё намерение без субстрата исполнения — определение «что считается завершённым» существует ещё до наличия шлюза для его исполнения. Ни одна сторона не может вместить другую целиком. Они пересекаются, но не включают друг друга.
Почему вопрос о подмножестве поставлен неверно
«Тогда Reins — подмножество сбруи?»
Чтобы быть подмножеством, оба должны измеряться одной мерой. Но сбруя определяется по оси кто выпускает и насколько переиспользуется (ось субстрата), а Reins — по оси что делает с траекторией (ось функции). Оси разные.
Это как спросить «красный цвет — подмножество тяжести?». Красные и тяжёлые вещи (= исполняемые шлюзы) существуют, но цвет не может быть помещён внутрь веса. Мерные инструменты разные. Само отношение «подмножество» здесь — категориальная ошибка.
Точное соотношение такое. Reins предполагает сбрую, но не входит в сбрую. Слой, лежащий поверх, — это не часть, содержащаяся внутри. Лежащее поверх выходит за пределы субстрата.
Место настоящего расхождения — cheese
До этого момента — разговор о структуре. Но есть отдельное место, где Reins решительно расходится с дискурсом о harness. Это cheese (читается как «чиз» — игровой термин: использование непредусмотренных лазеек для прохождения, то есть «игра со спецификацией»).
Геймдизайнеры знают: «убей 10 крыс» — печально известный квест. Между тем, что проверяет шлюз (10 крыс мертвы), и тем, чего дизайнер действительно хотел (чтобы игрок прошёл контент), есть щель — и игроки просачиваются в неё. Это и называется cheese. Ровно то же явление, которое исследователи безопасности ИИ называют «игрой со спецификацией» (specification gaming) — агент в гонке на лодках кружит за очками вместо финишной черты, агент в Tetris ставит игру на бесконечную паузу, лишь бы не проиграть.5
Мой шлюз аренды тоже поддаётся cheese. Пять фотографий проверяют «фотографии существуют», а не «выселение завершено нормально». Что, если ответственный снял только чистые стены? Шлюз пройден. В момент, когда измерение становится целью, измерение ломается — закон Гудхарта.6
Теперь главное. Сбруя способна ответить лишь «прошло или нет». Зелёный ли тест, верны ли типы, не сломана ли схема — только до этого. Но «поймало ли это прохождение саму цель» — сбруя не ответит никогда. Потому что что такое cheese, определяется только знанием цели домена. Почему фото только чистых стен — обман, почему все правила пройдены, а цель закрыта лишь на 90% — это знает только тот, кто понимает, для чего всё это нужно.
Этот человек — всадник. Держащий поводья.
Проектирование шлюзов, устойчивых к cheese, — предотвращение точек, где прокси не успевает за целью, — принципиально разное для каждой задачи, несёт в себе знание домена и пишется оператором. Task-agnostic сбруя этого дать не может. Не потому что не хочет, а потому что не знает домена — изначально не способна это обработать.
Здесь уникальная территория Reins Engineering, которой нет в дискурсах harness engineering и agentic engineering. Они говорят о том, как лучше делать упряжь. Reins говорит — через какую дверь, не сломавшись, отправить это путешествие.
И вот снова — инцидент с утечкой
Вернёмся к исходной иронии. Теперь видно, почему этот инцидент — не повод для насмешки, а доказательство.
Лошадь была гениальной. Opus — само вероятностное могущество. Седло тоже работало — Claude Code является лучшей упряжью в мире, и цифры HAL это подтверждают. Но собственная кодовая база, созданная с этой упряжью, дрейфовала ровно по предсказуемому сценарию сбоя. Одна функция — 3 167 строк. Живое воплощение стены в 200 эндпоинтов. Сама утечка — пропущенная строка в .npmignore, то есть на деплой-артефакте не было шлюза.
Компания, создавшая лучшую упряжь в мире, не надела эту упряжь на собственную конюшню.
Это не антитезис — это решающее доказательство тезиса. Reins — не атрибут, которым модель или агент обладает, а дисциплина, которую применяют. То, что агент умный, и то, что код, созданный этим агентом, находится под поводьями, — совершенно разные вещи. Большая модель — не ответ. Лучшая упряжь — тоже не ответ. Ответ — держать поводья, самому определять завершение этого путешествия, проектировать шлюзы, устойчивые к cheese. Эта дисциплина.
Итак
Сбруя заставляет лошадь бежать. Поводья определяют, через какую дверь отправить лошадь. Сбруя надевается однажды, поводья держат каждый момент. Сбрую выпускает шорник, поводья всадник держит в руках.
Они не противостоят друг другу. Это разные части одной упряжи. Но именно разные части. Без сбруи поводьев не существует, без поводьев сбруя блуждает. И знает ли это дело правильно завершено — всегда знает рука, держащая поводья.
Когда в следующий раз кто-то спросит «это ведь просто сбруя?», ответьте так.
«Сбрую выпускает вендор, а поводья я проектирую для этого квеста сам. Без сбруи поводьев нет, но без поводьев сбруя просто блуждает. Даже инструмент, давший нам поводья над кодом, не надел поводья на собственный код — потому что поводья не имеют, а накладывают.»
Связанные материалы
- ИИ с поводьями: Reins Engineering — источник рефрейминга «шлюз = поводья»
- Кто определяет «завершено» — устойчивые к cheese шлюзы, тасктинг как квест-дизайн
- Почему агенты работают и почему ломаются — «генерация может быть вероятностной, но верификация должна быть детерминированной»
- Почему ваш агент никогда не останавливается — система, способная остановиться = система с определённым завершением
- Yongol: стена в 200 эндпоинтов — спецификация, написанная оператором = материальное воплощение Reins
Дополнительное чтение
Внешние статьи, которые глубже или под другим углом исследуют границы из этого эссе — между сбруей и поводьями, как останавливаться, как спецификации подвергаются игре.
- How Coding Agents Work — Simon Willison — «Агент для написания кода — это harness, оборачивающий LLM.» Классическое определение harness — прочитайте перед основным текстом.
- Agent Harness Engineering — Addy Osmani — формализует harness как самостоятельную инженерную дисциплину. Рассматривает условие завершения через «sprint contract» — наиболее прямое пересечение с основным текстом.
- Reward Hacking in Reinforcement Learning — Lilian Weng — теоретический хребет закона Гудхарта и игры со спецификацией. Поддерживает тему cheese с точки зрения RL·RLHF.
- Water Finds a Crack — Soren Johnson — «Дай возможность — и игрок выжмет игру до оптимизации.» Классика геймдизайна, показывающая человеческий прообраз reward hacking.
- Effective Harnesses for Long-Running Agents — Anthropic — первое лицо разбирает сбой «объявляет завершение, хотя не завершено». Условие завершения и детерминированная верификация — в одной статье.
Факты инцидента (2026-03-31, v2.1.88, пропуск source maps в
.npmignore/Bun, ~512K строк·~1900 файлов, позиция «человеческая ошибка / не нарушение», рекомендация зафиксироваться на v2.1.87) перекрёстно подтверждены The Register («Anthropic accidentally exposes Claude Code source code», 2026-03-31), InfoQ, VentureBeat. ↩︎Единственная функция в
print.tsна 3 167 строк подтверждена claudefa.st, «Claude Code Source Leak: Everything Found». ↩︎Kapoor, Narayanan et al., «Holistic Agent Leaderboard: The Missing Infrastructure for AI Agent Evaluation» (Princeton), arXiv:2510.11977 — 9 моделей × 9 бенчмарков, 21 730 запусков. Количественно оценивает влияние скаффолда, разделяя модель, скаффолд и бенчмарк. Лайв-лидерборд: hal.cs.princeton.edu. ↩︎
Addy Osmani, «Agent Harness Engineering» — «Средняя модель + отличный harness > отличная модель + плохой harness.» Наблюдение, что тот же Opus показывает более высокие результаты в кастомном harness, чем в Claude Code. ↩︎
Krakovna et al., Google DeepMind, «Specification gaming: the flip side of AI ingenuity»; примеры: V. Krakovna, «Specification gaming examples in AI» (цикл очков CoastRunners, вечная пауза в Tetris и др.). «Поведение, которое удовлетворяет буквальной спецификации цели, не достигая при этом намеренного результата.» ↩︎
Marilyn Strathern (1997), «‘Improving ratings’: audit in the British University system,» European Review 5(3):305–321 — источник формулировки «когда измерение становится целью, оно перестаёт быть хорошим измерением» (переформулировка тезиса Гудхарта 1975 года через Хоскина). ↩︎