Первый раунд задание почти не сопротивлялось: 30, 29,8 и 28,3 из 30. Второй раунд написан так, чтобы полный балл был недостижим за 15 минут — с блоком требований по безопасности, мутационной проверкой тестов и ловушками, где буквальное прочтение приводит к абсурду. Ни один агент не взял 100 %.
Баллы — среднее трёх независимых оценок по рубрике на 50 пунктов: ручная приёмка оператора и две слепые оценки судьями. Все три оценщика выстроили агентов в одном порядке.
Расчётную часть — все двенадцать ловушек, включая поштучное округление, три разные базы порога доставки, построчный НДС и распределение фиксированной скидки методом наибольших остатков — взяли все трое, копейка в копейку. Разошлись они на трёх вещах: успел ли агент написать документацию, честен ли его финальный отчёт и выдерживает ли код враждебный вход на границах.
Перед вторым раундом проверено, что везде стоит последнее. Одно обновление потребовалось.
| Агент | Раунд 1 | Раунд 2 | Статус |
|---|---|---|---|
| Claude Code CLI 2.1.238 |
claude-opus-5 | claude-opus-5 | уже последняя Opus 5 вышел 24.07.2026 — позже Fable 5 (09.06.2026) и лидирует на агентных кодинг-бенчмарках, поэтому взят он, а не Fable |
| Codex CLI 0.142.5 → 0.149.0 |
gpt-5.5 | gpt-5.6-sol | было устаревшее CLI отставал на семь версий и физически не мог запустить GPT-5.6: сервер отвечал «требуется более новая версия Codex». Обновлён, перезапущен на флагмане |
| Cursor CLI 2026.08.11 |
composer-2.5 | composer-2.5 | уже последняя в списке моделей помечена как current; собственная модель Cursor, как и требовалось |
| Что фиксировали | Как именно |
|---|---|
| Стартовое состояние | Три пустых каталога, в каждом только пустой git-репозиторий. |
| Промпт | Один файл, подставлялся всем троим дословно и ровно один раз, через stdin. Никаких уточнений и повторных отправок. |
| Таймер | Жёсткий timeout -k 15s 900s. Что не успел — не успел. |
| Вмешательство | Нулевое. Уточняющих вопросов не задал никто. |
| Изоляция | Отдельные CLAUDE_CONFIG_DIR и CODEX_HOME только с авторизацией: без хуков, плагинов, MCP, пользовательских настроек и памяти. |
| Порядок | Последовательно, по одному — никто не делил CPU во время своих 15 минут. |
| Автор задания | Второе ТЗ написал Codex на GPT-5.6 Sol с высоким reasoning: ему дали первое задание, рубрику и результаты первого раунда и поручили усложнить так, чтобы 100 % стало недостижимо. Он же выдал карту из двенадцати ловушек с числовыми эталонами — которые затем пересчитаны вручную перед использованием. |
| Приёмка | 19 расчётных кейсов и 17 враждебных входов через CLI, покрытие через pcov, мутационное тестирование через Infection, прогон под faketime 2027 и в трёх часовых поясах — всё руками, а не со слов агентов. |
Текст остался прозой без нумерации — требования по-прежнему нужно извлекать чтением. Изменилась не длина, а плотность взаимодействий: правила передают друг другу базу и округлённые копейки, поэтому ошибка в начале каскадом меняет доставку, НДС и итог.
| Раунд 1 | Раунд 2 |
|---|---|
| Скидка 10 % от суммы позиции | 10 % округляются на единице товара, потом умножаются на количество, а 15 % промокода — одним округлением от всей позиции |
| Скидки не складываются | SUMMER26 не складывается, а WELCOME складывается с категорийной — вопреки привычной практике |
| Один порог бесплатной доставки | Порог считается от трёх разных баз: до WELCOME, но после SUMMER26 |
| НДС выделяется от итога | НДС округляется построчно и отдельно для доставки, затем складывается |
| Фикс-скидка на корзину | Распределяется методом наибольших остатков, ничья разрешается по возрастанию sku |
| — | Блок безопасности: лимит stdin до декодирования, глубина JSON, число позиций, UTF-8, точные типы чисел, защита каждой операции от переполнения, санитарные ошибки без трасс и путей |
| — | Требование детерминизма вывода при перестановке строк входа и сортировки позиций по байтам sku |
19 кейсов с эталонными числами, посчитанными вручную по тексту задания до открытия кода. Все суммы в копейках.
| Кейс | эталон | Claude | Codex | Cursor |
|---|---|---|---|---|
| Поштучное округление аксессуар 5 коп × 3 шт: 10 % от единицы = 0,5 → 1 |
скидка 3 итог 35 012 НДС 5 835 |
3 / 35 012 / 5 835 | 3 / 35 012 / 5 835 | 3 / 35 012 / 5 835 |
| SUMMER26 против категории порог ровно 500 000 до скидок |
75 000 460 000 76 667 |
75 000 / 460 000 / 76 667 | 75 000 / 460 000 / 76 667 | 75 000 / 460 000 / 76 667 |
| Ничья скидок обе дают 1 коп — побеждает категорийная |
category_10 | category_10 | category_10 | category_10 |
| Распределение WELCOME наибольшие остатки, ничья по sku |
18 889 / 16 667 / 16 666 нетто 3 333 / 3 333 / 3 334 НДС 7 501 |
совпало | совпало | совпало |
| Нулевая «Электроника» буквально активирует WELCOME |
applied итог 45 000 |
applied / 45 000 | applied / 45 000 | applied / 45 000 |
| Три базы порога доставки | 0 и 35 000 | 0 / 35 000 | 0 / 35 000 | 0 / 35 000 |
| Построчный НДС одно округление дало бы 5 834 |
5 833 | 5 833 | 5 833 | 5 833 |
| Большие числа без переполнения gross 1018, произведение на 15 не помещается в int |
150 000 000 000 000 000 НДС 141 666 666 666 666 667 |
совпало | совпало | совпало |
| Граница SUMMER26 23:59:59,756 по Москве — последняя секунда |
applied | applied | applied | expired ✗ |
Итог по разделу: 19 из 19 кейсов у Claude и Codex, 18 из 19 у Cursor.
Cursor сравнивает текущий момент с дедлайном как $now > $deadline, где дедлайн —
23:59:59.000000. Любой момент внутри последней секунды (например, 23:59:59,756)
оказывается больше — и промокод объявляется просроченным, хотя задание требует «включительно».
У Cursor есть тест с говорящим именем testSummer26ValidOnDeadlineInclusive, и он
зелёный: тест подаёт ровную секунду без микросекунд, то есть проверяет реализацию,
а не требование. Claude и Codex на том же входе отвечают applied.
Задание объявляет вход недоверенным. 17 враждебных входов поданы каждому решению вручную; проверялись код возврата, пустота stdout и отсутствие утечки внутренностей в stderr.
| Проверка | Claude | Codex | Cursor |
|---|---|---|---|
| stdin больше 1 МиБ отвергается до декодирования | код 2 | код 2 | код 2 |
| Глубина JSON больше 32 | код 2 | код 2 | код 2 |
| Больше 1 000 позиций до схлопывания | код 2 | код 2 | код 2 |
| Лишние поля в корне и в позиции | код 2 | код 2 | код 2 |
Ложные типы чисел: 1e3, 1.0, "1000", true, за пределом int | 5 из 5 | 5 из 5 | 5 из 5 |
| Некорректный UTF-8, 257 байт, управляющий символ | 3 из 3 | 3 из 3 | 3 из 3 |
| Переполнение суммы при валидных позициях | код 2 | код 2 | код 2 |
Санитарные ошибки: только code и message, без трасс и путей | чисто | чисто | чисто |
Нет eval, unserialize, exec, shell_exec, proc_open | чисто | чисто | чисто |
| sku вне разрешённого алфавита задание допускает только A–Z, 0–9, точку, дефис, подчёркивание |
код 2 | код 2 | принимает phone1, код 0 |
| Валидный большой вход с WELCOME две строки по 1018 — ответ помещается в int |
посчитал | посчитал | код 2 на валидном входе |
Первые девять проверок прошли все трое — это заметный шаг вперёд относительно первого раунда,
где переполнение int роняло Codex и Cursor в PHP Fatal. Два последних пункта развели
участников: у Cursor валидация sku пропускает строчные буквы, а защита от переполнения неполна —
остаток при распределении WELCOME считается через опасное произведение, из-за чего математически
корректный вход отвергается как некорректный. Обе находки сделал сначала один из судей,
затем они воспроизведены вручную.
Количество тестов ничего не говорит о том, ловят ли они дефекты. Поэтому кроме покрытия строк замерялась мутационная устойчивость: Infection вносит в код изменения и смотрит, падают ли тесты.
| Метрика | Claude | Codex | Cursor |
|---|---|---|---|
| Тест-методов / тестов PHPUnit | 48 / 59 | 20 / 29 | 48 / 48 |
| Проверок (assertions) | 192 | 72 | 106 |
| Покрытие строк | 83,97 % | 91,45 % | 90,62 % |
| Мутантов сгенерировано | 337 | 276 | 280 |
| Убито / выжило | 253 / 83 | 211 / 63 | 205 / 74 |
| MSI (мутационное покрытие) | 75,4 % | 77,2 % | 73,6 % |
Слабых ассертов (assertTrue, assertNotNull) | 0 | 2 | 1 |
| Тестов прицельно по безопасности | 3 | 7 | 19 |
| Обязательных по ТЗ сценариев не покрыто | 5 из 14 | 3 из 14 | 1 из 14 |
MSI, делённый на число тест-методов. Показывает, сколько мутационной устойчивости приносит один написанный тест: у Codex каждый тест «работает» примерно в 2,5 раза плотнее.
Результаты обезличены: скопированы в subject-1/2/3 в перемешанном порядке, git-история
удалена, пути и упоминания авторства вычищены и проверены грепом. Каждый судья получил одинаковую
рубрику на 50 пунктов, приложенный infection.phar и работал в своей копии материалов.
| Судья | Codex | Cursor | Claude | Порядок |
|---|---|---|---|---|
| Ручная приёмка (оператор) | 46,0 | 43,5 | 40,5 | Codex → Cursor → Claude |
| Судья Claude Code (Opus 5) | 47,0 | 45,0 | 42,0 | Codex → Cursor → Claude |
| Судья Codex (GPT-5.6 Sol) | 48,5 | 45,0 | 43,5 | Codex → Cursor → Claude |
| Среднее из 50 | 47,17 94,3 % | 44,5 89,0 % | 42,0 84,0 % | полное совпадение |
| Ручных доделок до мержа | 2–3 | 2–7 | 4–5 |
Максимальная оценка за весь раунд — 97 % от одного судьи. Ни один агент не набрал 100 % ни у одного оценщика: цель усложнения достигнута. Судья Codex, не зная авторства, поставил работе собственного CLI первое место — но и оба других оценщика пришли к тому же выводу независимо.
sku в нижнем регистре — мой чекер
проверял только путь с ../ и это пропустил. Воспроизведено вручную, оценка скорректирована.
CartCalculator на 282 строки по-прежнему совмещает схлопывание, скидки, доставку и НДС.SafeInt, InputValidator, CartCalculator, часы разведены по классам.sku, отвергается валидный большой вход с WELCOME.Math, Input, Output, Model, Clock.| Метрика | Claude | Codex | Cursor |
|---|---|---|---|
| Время | 900 с таймаут | 387 с | 268 с |
| Всего токенов | 2 010 431 | 408 172 | 1 047 298 |
| Из них чтение кэша | 1 919 143 | 354 304 | 962 528 |
| Выходные токены | нет данных | 18 837 | 46 375 |
| Классов / строк кода | 19 / 1 402 | 4 / 476 | 7 / 755 |
| Документация (строк) | 0 | 133 | 254 |
У Claude выходные токены недоступны: прогон оборван таймером, и финальное событие с итоговым
usage не пришло. Приведённая сумма собрана по промежуточным сообщениям и занижена.
То же задание, но простое: 30 баллов, без блока безопасности. Показывает, насколько мало различимы агенты, когда ТЗ им не сопротивляется.
| Метрика | Claude | Codex | Cursor |
|---|---|---|---|
| Модель | opus-5 | gpt-5.5 | composer-2.5 |
| Время | 891 с | 212 с | 155 с |
| Токенов | 2 236 372 | 276 750 | 409 750 |
| Тестов / проверок | 129 / 402 | 17 / 58 | 49 / 96 |
| Покрытие строк | 90,28 % | 96,95 % | 83,61 % |
| MSI | 71,52 % | 74,55 % | 72,09 % |
| Балл (среднее трёх оценок) | 30,0 / 30 | 28,3 / 30 | 29,8 / 30 |
В первом раунде две работы из трёх получили полный балл, и различить их можно было только по глубине проработки. Единственной ловушкой, которая тогда развела агентов, было противоречие про порог бесплатной доставки: Claude вынес его в конфигурируемый параметр с тестами на обе трактовки, Cursor завёл раздел «Неоднозначности ТЗ», Codex снял противоречие молча.
Показательно, что порядок мест между раундами изменился на противоположный. Это не шум: в первом раунде побеждала обстоятельность, во втором — способность уложить всё главное в отведённое время. Один и тот же агент может быть первым и последним в зависимости от того, чего требует задача.
| Когда | Кого брать | Почему |
|---|---|---|
| Жёсткий срок, объёмное ТЗ, нужен готовый результат целиком | Codex (GPT-5.6 Sol) | Единственный, кто уложил и код, и безопасность, и документацию в 6,5 минут при лучшем покрытии и MSI. |
| Нужен максимально аккуратный production-код, срок вторичен | Claude Code (Opus 5) | Лучшая архитектура и самая точная работа с границами; но закладывайте время с запасом — в 15 минут он не уложился. |
| Быстрый черновик с хорошей документацией, есть кому проверить | Cursor (Composer 2.5) | Быстрее всех и лучше всех документирует, но именно у него нашлись все три реальных дефекта раунда. |
Мутационное тестирование оказалось самым информативным инструментом приёмки: оно единственное показывает разрыв между «тесты зелёные» и «тесты что-то проверяют». В следующий раз имеет смысл вынести MSI в само задание как измеримое требование — и посмотреть, изменит ли это то, какие тесты агенты пишут.