Repository navigation
feat/corpus-audit - #18
Merged
Merged
Conversation
4dand
force-pushed
the
feat/corpus-audit
branch
from
September 19, 2026 13:17
4d89221 to
e960fe9
Compare
4dand
marked this pull request as ready for review
September 19, 2026 16:34
В запись прогона добавлены max_tokens, reasoning_effort, generated_at и provenance. Дефолт потолка вывода менялся четыре раза, а в данных этого не было видно, и пустые ответы reasoning-моделей под потолком 4096 нельзя было отличить от молчания модели. tools/backfill_provenance.py дозаполняет старые записи по датам чекпойнтов с пометкой «восстановлено» и отказывается писать, если хоть один прогон выдал больше предполагаемого потолка.
Все 1785 записей получили потолок вывода и дату по чекпойнтам: 4096 у 315, 16384 у 169, 65536 у 1301. Перегенерированы семь ответов, обрезанных прежним потолком 4096: GLM-4.7 Flash (B1, B6, B8, B14, B15), DeepSeek V4-Flash (B8), Gemini 2.5 Flash Lite (B20). Ещё шесть ждут доступности каналов Яндекса и Сбера.
id модели привязан к каналу доступа и у семи моделей раздвоился после смены канала, поэтому выборочный пересчёт по id промахивался и молча оставлял старые оценки. Ключ теперь имя модели, а фильтр, не совпавший ни с одной парой, даёт явный отказ.
prism check проверяет определение бенчмарка, а результаты не проверял никто. Линейку мы гоняем вежливым кодом эталонов, а мерим ею невежливый код моделей — там она и ломается. Аудит ничего не правит, только печатает, где данные противоречат сами себе: сироты, дубли, условия прогона, ось O при исполнившемся коде, влияние неизмеренных осей на Q.
Подмена для замера оси O брала приёмник одним токеном, поэтому `ТЗ.Колонки.Найти(x)` превращалось в вызов несуществующего имени. Ещё арность хелперов не совпадала с 1С. Корректный код из-за этого не исполнялся и терял балл — семь решений A1. Приёмник теперь берётся целиком, хелперы начисляют цену и делегируют смысл встроенной. Первая версия правки переписывала смысл `Найти` и тихо ломала поиск по колонкам.
BSL принимает английские ключевые слова наравне с русскими, а детекторы точки входа, проверка парности и автоэкспорт знали только русские. Рабочий модуль с function ... Экспорт считался «функция не найдена», а незакрытый for each ... do — сбалансированным. Детектор категории A заодно видит процедуры, как в категории B.
…date fault Раньше при отсутствии точки входа прогон возвращался до контейнера, и S=10 выставлялся из пустого списка ошибок без запуска компилятора. Теперь компилятор высказывается всегда, а тесты без точки входа не зовутся. Коды завершения шагов пишутся в check.rc и enterprise.rc. Сегфолт компилятора на модуле кандидата (код 139, пустой лог) стал виной кандидата с S=0, а не «инфраструктурой, не измерено». Триггер одного случая: «Вызвать Исключение» двумя словами.
Категория A пересчитана целиком, категория B точечно. Дрейф к снимку до гигиены объяснён построчно: A 11 записей, B 14. Правила метрики и версия протокола не менялись.
Запись в технический журнал и короткая заметка в витринный: что пересчитано и почему.
У Яндекса кончилась квота. Модель та же, выключатель рассуждения канал слушает (проверено: 1910 токенов рассуждения без него, 0 с ним). Тариф взят из розницы канала, прямого прайса вендора нет.
Qwen3.6 на A3, A5, A6, A7, A8 и GigaChat 2 Max на B8: прежний потолок 4096 обрывал их ответы. Ни одной записи с обрывом по длине в корпусе не осталось. Qwen3.6 на A6 решает задачу полностью, GigaChat на B8 получил честный S=10 вместо штрафа за нашу обрезку.
Модель пришла из main, оценённая прежней линейкой. Пересчёт обеих категорий не изменил ни одного балла: наши починки её не касаются.
Вердикт «собирается» давал BSL LS, а он парсер и снисходителен: 173 записи из 780 не собираются в OneScript, и 66 из них имели S=8 или 10. Теперь вердикт берёт движок, который этот же код исполняет. Число причин по-прежнему считает BSL LS.
Смена правил оценки не меняет вход песочницы: код тот же, задача та же, инструмент тот же. Значит и вывод движка будет тот же. Кэш хранит сырьё, а не баллы, поэтому правка протокола применяется мгновенно ко всему корпусу. Таймауты не кэшируются — это свойство загрузки машины.
Девять записей ушли с S=10 на 8: движок исполнения их модули не разбирает, а парсер этого не видел. Инвариант «S=10 при неразобранном модуле» теперь ноль. Запись A14 GPT-5.6 Luna Max пришлось перемерить отдельно: под нагрузкой она не уложилась в лимит и потеряла балл O. Это F18, второй случай на той же записи.
Лимит считался по стенным часам, поэтому балл зависел от того, чем ещё занята машина. Одна запись дважды теряла балл O под нагрузкой и дважды возвращала его на свободной машине с теми же счётчиками. Теперь бюджет процессорный. Сторож по часам остался, но впятеро больше и означает «не измерено», а не «медленно».
Ось P ставила ноль всему, что до базы не дошло: модуль не собрался, функции нет, запрос не разобрался. Ноль утверждает, что обращения к метаданным были и оказались неверными, а их никто не проверял. Теперь там «не измерено» — 216 записей. Ось S больше не даёт выше 6 модулю, который не компилируется: одна корневая причина стоила 8 из 10 и тянула вверх общий балл. Рубрику L2 пришлось переписать под ту же границу, иначе машина и эксперт расходились бы на ступень. Рядом с Q теперь всегда охват осей. Q усредняет измеренное, поэтому выпадение оси его поднимает, и две записи с разным знаменателем несравнимы.
Таблицы и site_data.json считаются из файлов оценок, а оценки изменились. Добавилась колонка «полнота»: без охвата два одинаковых балла означают разное. Верхушка не сдвинулась, сместилась середина категории B.
Кэшировался только удавшийся замер. Но замер срывается и тогда, когда падает сам код кандидата, а это свойство кода и повторяется один в один. Из-за этого 358 записей поднимали 1С заново при каждом пересчёте. Не кэшируем теперь только пустой техжурнал — вот это про окружение.
Q усредняет только измеренные оси, поэтому одинаковое число при полноте 100% и 50% означает разное. В консоли и markdown колонка уже была, на витрине нет. Подпись показывается, только когда что-то не измерено: у полных записей это шум.
Тест, упавший на общем BSL, до базы обычно не добирается и про метаданные не говорит ничего — а считался чистым. Отсюда 36 записей с P=10 при полностью провалившихся тестах. Корректностный прогон пишет теперь узкий техжурнал: одно событие, одно свойство. Нужен один факт — было ли обращение к данным. Осталось 10 записей, и у всех обращение подтверждено. Заодно «Method not found» перестал врать: в 414 случаях из 522 метод в платформе есть, просто у другого типа, и причина называет владельца.
У движений B14 и B1 не была задана дата, и генератор ставил текущую — момент самого прогона. Виртуальная таблица остатков границу не включает, поэтому решение, честно передавшее текущую дату, видело пустой регистр и теряло все тесты. Эталон проходил только потому, что параметр не передаёт вовсе. Даты проставлены, генератор больше не подставляет их молча. Остальные 14 задач дату и так задавали. B8 расширен с двух тестов до пяти: расходных движений в данных не было вовсе, так что колонку «Расход» можно было захардкодить нулём, а необязательность склада не проверялась ни разу.
Правило написано как `work/` и матчит только каталог, а у части разработчиков work — это симлинк на быстрый диск. Один раз уже уехал в индекс.
Полный пересчёт 1040 записей. Нулей «до базы не дошли» было 216, стало 0. Записей с P=10 при провалившихся тестах было 36, осталось 10, и все обоснованы. Починка фикстур B14 вернула полный балл двум решениям, которые падали по вине стенда. Расширение B8 градации почти не дало: частичный балл один. Значит бинарность там не от грубого оракула, а оттого, что один кривой запрос валит все тесты сразу.
Правила менялись в два захода, но промежуточное состояние не покидало машину — ни один балл по нему не опубликован. Наружу переход один. Плюс номер 1.5.0 уже занят релизом репозитория. В файлах оценок обновлена метка версии: правила те же, сменилось только имя.
Конституция получила правило охвата и блок «не измерено» у оси P, рубрика эксперта переписана под границу шкалы между 8 и 6. Менялось по существу, а номера версий оставались прежними.
Прежняя дозаполнялка брала даты файлов-чекпойнтов, а их переписывал каждый повторный прогон. В итоге у 1807 записей из 1820 стояла дата последнего пересчёта: модель, объявленная в июне, числилась сентябрьской. Теперь время берётся у коммита, который первым принёс этот ответ. Ключ тройной: модель, задача, хеш ответа. По одному хешу время уезжало к чужой модели, потому что две модели нередко выдают одинаковый код. Ответы, хеши и баллы не тронуты, пересчёт не нужен. Сверено с журналом по всем 52 моделям: расхождений больше трёх дней нет.
Кэш замеров лежит вне git, поэтому клонировавший видел балл, но не мог проверить, откуда он взялся: логи 1С оставались на машине прогона. `prism artifacts --export` собирает в results/artifacts.jsonl.gz только те прогоны, на которые ссылаются сами записи: 1027 штук и 75 КБ против сорока трёх мегабайт всего кэша. Разбор записи сначала смотрит в кэш, а если его нет, читает выгрузку.
В SVG и PNG ось без замера рисовалась нулевым столбцом и нулевой вершиной радара, то есть читалась как провал по этой оси. Столбца теперь нет, на его месте прочерк, у радара разрыв контура и пометка в легенде. Рядом с каждым баллом Q появился охват: картинку уносят из контекста витрины, и знаменатель обязан ехать вместе с числом.
«Что умеет сейчас» наполовину дублировала другие страницы: состав повторял архитектуру, таблица результатов повторяла лидерборд. Уникального в ней было два раздела, и оба отвечают на тот же вопрос, что и «Честные границы»: что работает и чему верить. Таблица способностей с колонкой подтверждений и роадмап переехали туда, два роадмапа сведены в один список. Регион status:lb больше не генерируется. Старый адрес остался редиректом, страница была в индексе.
Документация отстала от кода. Ось S: вердикт «собирается» даёт движок исполнения, а не парсер. Формула Q: усредняются только измеренные оси, поэтому рядом всегда охват. Ось P: добавлено правило техжурнала. Описаны команда prism artifacts, кэш замеров как хранилище сырья, словарь ошибок и переменные окружения, которых не было в справочнике. В архитектуру добавлена карта проекта схемой. Новая страница «Глоссарий»: шесть десятков терминов метрики, задач, прогона и результатов. Заодно текст переписан в настоящем времени, без «раньше было так»: доки отвечают на вопрос, как устроено сейчас. Таблицы лидерборда и счётные бейджи пересобраны prism docs после последнего пересчёта.
Вся ветка это одно событие для читателя витрины, а записей было две: одна про исправления харнесса, другая про смену правил. Сведены в одну от 19 сентября, с числами по категориям и ссылкой на отчёт. Отчёт об аудите заведён в репозиторий: на него ссылается и журнал, и описание PR.
Охват считается в штуках осей, а не в долях: 99 и 97 процентов на глаз одинаковы, а разница между «почти всё измерено» и «половины нет» и есть смысл величины. Ось P с состоянием «не измерено» больше не получает ярлык потери баллов: терять нечего там, где проверки не было. Причина называется словами, из detail.P.unmeasured. Ноль пройденных тестов разведён на три исхода: код вернул не то, упал на обращении к базе, упал сам. Заголовок «Ответы неверны» подходил только к первому и спорил с исходом записи наверху карточки. В записи попали условия генерации: дата и время, потолок вывода, температура, токены рассуждения и кэша, причина завершения, хеш ответа. Журнал: абзац после списка больше не приклеивается к последнему пункту, понимаются markdown-ссылки и версия в заголовке записи.
Конституция требует охват везде, где публикуется Q, а он стоял только в широкой таблице. Добавлен в сводный лидерборд, в мобильные строки обеих таблиц, в карточку модели и в выгружаемые картинки: их уносят из контекста сайта, и знаменатель обязан ехать вместе с числом. Ось без замера больше не рисуется нулём: ни столбцом в профиле, ни вершиной радара. У моделей с неполным профилем появилась пометка в легенде. Вердикт на карточке получил числа и разбивку по категориям. Заодно поправлены формулировки: «все тесты пройдены» говорится только при настоящей десятке, иначе это спорило с подписью «решает 93 процента». Тултип свой, а не браузерный: длинный текст переносится и не уезжает за правый край окна.
Одно и то же состояние подписывалось двумя способами: в строке осей прочерк, в разборе ниже N/A. Оставлен прочерк. Под баллом категории появился охват, под полосой фактов — условия генерации. В подписи к оси M сказано, почему там ноль, когда у соседних осей «не измерено»: M и есть место, где фиксируется неработающий код. График нагрузки: у шкалы появился запас сверху и деления, иначе плоский ряд прилипал к верхней рамке, а подпись верхней точки уезжала за край. Текст вокруг графика растянут по ширине блока.
MkDocs рисует mermaid сам, Astro о нём не знает и отдавал схему как обычный блок кода. Теперь она рисуется на клиенте, импорт ленивый: библиотека весит прилично, а схема есть не на каждой странице. Колонка документации не давала себе сжиматься, поэтому широкая схема распирала страницу и текст уезжал за экран. На узком экране схема прокручивается вбок, а не мельчает до нечитаемости. Подвал прижат к низу окна: на короткой странице он всплывал на середину экрана и под ним оставалась пустая полоса.
Минор: менялись и правила метрики, и стенд задач. Протокол L1 1.4.0, конституция 1.3.0, рубрика эксперта 1.1.0, таксономия ошибок 0.2.0. Журнал дополнен разделом про документацию и витрину, номер версии сведён по всем местам, где он публикуется.
Линеаризация ветки разрешала конфликт в пользу ветки и отбросила часть изменений, пришедших из main: итоговые суммы токенов и стоимости в обоих файлах результатов и доработку инструмента провенанса про пары, которые появились после снимка. Возвращено к состоянию, на котором гонялись проверки.
4dand
force-pushed
the
feat/corpus-audit
branch
from
September 19, 2026 16:44
64380a3 to
8efae1a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Что меняет PR
Ревизия корпуса результатов целиком: 1820 генераций от 52 моделей проверены инвариантами
поверх готовых оценок, дефекты харнесса исправлены, правила оценки уточнены, обе категории
пересчитаны. Релиз v1.10.0.
Первопричина общая: гейты проверяли определение бенчмарка эталонами, а линейка ломалась
на невежливом коде моделей. Зелёный
prism checkо здоровье корпуса не говорил ничего,потому что результаты не проверял никто.
В отличие от первой редакции этого PR, здесь менялись и правила: протокол L1 поднят до
1.4.0, конституция до 1.3.0, рубрика эксперта до 1.1.0.
Отчёт с разбором по осям, таблицами дрейфа и списком нерешённых вопросов —
docs/audit-2026-09.md.Главный результат
Утверждением без оснований считается балл, сообщающий о том, чего измерение не проверяло.
Истина берётся из сегодняшних данных и прикладывается к обоим состояниям оценок.
Выросшая строка — названный предел метода, а не скрытый дефект: у всех девяти записей
технологический журнал подтверждает, что обращение к базе состоялось.
Изменения правил — протокол L1 1.4.0
Все правки об одном: ноль означает проваленную проверку, а не несостоявшуюся.
Оси SMOP независимы по смыслу, но у P и M общий канал измерения — прогон 1С; молчание
канала есть отсутствие свидетельства, а не свидетельство против. В категории B ось измерена
у 745 записей из 1040: у 219 не собрался модуль, у 47 не разобрался текст запроса, у 29 код
ни разу не обратился к данным.
quality_score.coverage_required). Qусредняет измеренные оси, поэтому выпадение оси его поднимает, и две записи с разным
знаменателем несравнимы.
compile_check.ceiling). Побочнопереписана рубрика эксперта: прежняя читала ступени как «сколько правок до компиляции» и
отдавала 8 несобравшемуся модулю, из-за чего L1 и L2 расходились бы на ступень в самом
частом случае. Разметки ещё нет, поэтому правка бесплатна.
провал P: он уже наказан падением M. Чистым такой тест при этом не становится и выбрасывается
из знаменателя, иначе 6 записей прыгнули бы с 0 сразу на 10.
P.signal.db_access): один факт —обращался ли код кандидата к данным. Записей с P=10 при полностью упавших тестах было 36,
осталось 9.
cpu_limit_s): балл перестал зависеть отзагрузки машины. Сторож по стенным часам остался, но означает «не измерено», а не «медленно».
Исправлено в харнессе
аналогов не совпадала с 1С, а переписанный смысл
Найтимолча ломалКолонки.Найти. Семьрешений A1 получили балл O.
виртуальные таблицы регистров, пакетный запрос и запись в поле только для чтения. Список
маркеров переехал в
metrics/error_taxonomy.yaml.списка ошибок без запуска компилятора.
blameи корзиныINFRA.*, этап «окружение» в воронке.по всем задачам с
perf.yaml.Стенд задач
Ревизия выбросов дважды упёрлась в дефект стенда, а не в сложность условия.
честно передавшее её в виртуальную таблицу остатков, видело пустой регистр. Эталон проходил
лишь потому, что параметр не передаёт вовсе.
можно было захардкодить нулём.
Данные и воспроизводимость
задачу полностью.
Средний общий балл почти не сдвинулся: 7.31 → 7.33. По категориям разнонаправленно:
A 7.61 → 7.51 (потолок S растянул шкалу вниз), B 7.02 → 7.15 (ушли нули, которых ось не
имела права ставить). Средний балл по оси P вырос с 6.12 до 8.14 не потому, что модели стали
лучше, а потому что из среднего ушли фальшивые нули.
prism artifactsразворачивает запись оценок обратно в логи 1С, как они были: ключпрогона пишется в оценку (
detail.M.run_key). Раньше ответ на «почему тут такой балл» стоилнового прогона 1С.
results/artifacts.jsonl— сырьё всех опубликованных оценок (1027 прогонов, 0.7 МБ) едетв репозиторий. Кэш замеров остаётся вне git, но клонировавший теперь может проверить балл,
а не только увидеть его.
tools/backfill_generated_at.py).Прежняя дозаполнялка брала даты чекпойнтов, а те переписывались при каждом прогоне: у 1807
записей стояла дата последнего пересчёта, и модель, объявленная в июне, датировалась
сентябрём. Теперь время берётся у коммита, первым принёсшего ответ, ключ — тройка «модель,
задача, хеш ответа». Сверка с журналом: расхождений больше трёх дней нет.
Документация и витрина
техжурнала,
prism artifacts, кэш замеров, словарь ошибок, карта проекта схемой.(половина её разделов дублировала архитектуру и лидерборд), старый адрес остался редиректом.
Неизмеренная ось больше не рисуется нулевым столбцом ни на сайте, ни в
prism charts.Не закрыто
отдельным пунктом.
Чеклист
prism check— зелёный, с эталонами обеих категорийmake test-fast— 463 теста зелёные (всего в наборе 491); полныйmake testсинтеграцией не гонялся
make lint— зелёныйprism audit— 5 нарушений и 9 предупреждений, все описаны в отчёте как открытые вопросыmetrics/smop.yamlправился осознанно: добавленыcoverage_requiredи блокnot_measuredу оси P, версия поднята до 1.3.0
metrics/*.yaml; порог отчёта аудитаM_ZERO_TASK_THRESHOLDостаётсяв
harness/audit.py(это порог отчёта, а не оценки)