name: applied-quality description: Оценка ПРИКЛАДНОГО качества Unity-кода (пакета/системы/подсистемы) по канону «Сценарная прочность» — трассировка логических нитей вход→выход, их прочность, ступенчатость, спутанность и рекурсия. Дополняет code-quality: тот меряет ФОРМУ кода в покое (метрики/формулы), этот — ПОВЕДЕНИЕ в динамике (нить от входа к выходу, что рвётся при повторном входе/сбое/гонке). Триггеры — как у code-quality, но БЕЗ слова «качество»: вместо него корректность/логичность/адекватность/правильность. Развилка по LOC: моно (≤2000), шардинг с реконструкцией графа (2000–10000), частичный (>10000). when_to_use: Триггеры — «оцени корректность пакета», «проверь систему на логичность», «оцени адекватность кода», «прогони на правильность», «оцени спутанность», «что рвётся в рантайме». Слово «качество» — триггер близнеца code-quality, не этого скилла. Запускать и без явного слова «корректность», когда просят оценить поведение/прикладную логику конкретного Unity-пакета или подсистемы (нити, re-entry, гонки, утечки, ступенчатость).
Прикладное качество кода — «Сценарная прочность» (Unity)
На вход — целевой пакет/система/подсистема (или конкретная фича/дифф). На выходе — оценка прочности логических нитей: балл по осям + множитель спутанности + потолок катастроф, с доказательствами в виде сценариев отказа, а не абстрактных счётчиков.
Как читать этот скилл
SKILL.md — каркас: триггер, замер размера, развилка по LOC, модель нити, протоколы веток, формула, формат вывода, жёсткие правила. Детальное — в референсах:
references/axes.md— читается целиком перед анализом нитей (оси 1/2/3/5, ступенчатость S, Ось 4 «Спутанность», ярус катастроф «Рекурсия»). Не работать по памяти.references/sharding.md— читается целиком при ветках A+ и B (протокол шардинга с реконструкцией графа, ветка частичного анализа).
Граница с code-quality (не дублировать)
| code-quality | applied-quality (этот) | |
|---|---|---|
| Меряет | форму: метрики, структуру, паттерны | пригодность в работе: поведение нити вход→выход |
| Единица доказательства | посчитанное нарушение (grep/формула) | сценарий отказа (прогон в голове) |
| Метод | детерминированный | семантический (чтение + рассуждение о рантайме) |
| Пример | Fat Interface, DIT, аллокации | dangling-ссылки, гонки, утечки на re-entry, over-fetch, ступенчатость |
Пересекающиеся термины разводятся: «атомарность» здесь — НЕ размер модели (это code-quality 2.2), а over-fetch по нити; «однонаправленность» здесь — реальная спутанность нитей в рантайме, а не статичный счётчик зависимостей.
0. Триггер и проверка контекста
⚠️ Подтверждение направления (ПЕРЕД запуском, обязательно)
Этот скилл меряет ПРИКЛАДНУЮ ЛОГИКУ / поведение: корректность логических нитей вход→выход, спутанность, ступенчатость, рекурсию — код «в движении», что рвётся на re-entry/сбое/гонке.
Рядом — скилл-близнец code-quality: он меряет ФОРМУ / архитектуру (метрики, структуру, паттерны, связность) — код «в покое».
Триггеры близнецов похожи, поэтому до анализа убедиться, что пользователь хочет именно прикладную логику/корректность. Если формулировка неоднозначна (или могла относиться к архитектуре/форме) — задать ОДИН вопрос и дождаться ответа:
«Оценить прикладную корректность (нити, спутанность, что порвётся в рантайме — applied-quality), или архитектуру/форму (метрики, паттерны, связность — code-quality)?»
- Явно «корректность / логичность / адекватность / правильность / спутанность / что рвётся» → продолжать без вопроса.
- Явно «качество / архитектура / метрики / паттерны» → предложить переключиться на code-quality.
- Просят и то, и другое («качество и корректность») → НЕ пинг-понг между близнецами: выполнить applied-quality и предложить вторым проходом прогнать code-quality (или наоборот), уточнив объём.
Запускается, когда просят оценить прикладное качество / прочность / спутанность конкретного пакета.
Если цель не указана — уточнить:
«Какой пакет/система/фича оценивается? Канон точен на одном пакете ≤2000 LOC; больше — шардинг с предупреждением о деградации.»
Без цели скилл НЕ выполняется.
1. Шаг 0 — измерение размера (всегда)
Измерить LOC всех релевантных .cs (исключить *.Designer.cs, // <auto-generated>, *Tests*, .meta). wc -l достаточно для гейтинга.
bash:
find <target> -name "*.cs" -not -name "*.Designer.cs" -not -path "*/Tests/*" -not -path "*Tests*" -exec wc -l {} + | tail -1
Делегирование: подсчёт LOC + инвентарь (файлы, типы, точки входа/выхода-кандидаты) — через
Agentsubagent_type=Exploreилиgeneral-purposemodel=haiku. Основной контекст не занимать инвентаризацией.
2. Развилка по LOC
Пороги ниже, чем в code-quality: трассировка нитей дороже формул.
| Ветка | LOC | Протокол |
|---|---|---|
| A — моно | ≤ 2000 | весь граф нитей в одном контексте → протокол ниже (раздел 4) |
| A+ — шардинг с реконструкцией графа | 2000–10000 | 2–4 шарда по естественным швам (asmdef/системы), каждый ≤ ~2500 LOC → references/sharding.md |
| B — частичный (предупреждение) | >10000 или деление неестественное | по-шардовый анализ + швы выборочно, дисклеймер → references/sharding.md |
Границы шардов — по швам asmdef/систем, чтобы внутришардовые нити были самодостаточны, а межшардовые рёбра — редкими и явными (проходят через шов). Соотношение размеров max/min ≤ 3, не более 4 групп.
3. Модель анализа: сценарная нить
Единица — логическая нить: путь от точки входа до точки выхода.
Точки входа (нить начинается):
- ввод:
AddActionUser(,performed +=, Unity-input; - события/шины:
On[A-Z]\w+ +=,OnUpdateData +=,OnGameStateChanged; - публичный API, вызываемый другими: методы контроллера,
Run(,Executeкоманд; - Unity-lifecycle с логикой:
OnEnable/Awake/Update/spine-events.
Точки выхода (нить заканчивается):
- представление:
switcher.Set(,ChangeVisibility(,SetActive(, запуск анимации/spine,image.sprite=; - мутация общего состояния: реактив
.Set(, запись модели, смена game-state; - персист:
SaveGlobal, запись сейва; - отдача наружу:
?.Invoke(),LoadAndPlay,PlaySound,return.
Протокол выделения:
- Инвентарь кандидатов вход/выход — делегируется Haiku (grep сигнатур).
- Для каждого входа — трассировка вперёд до выхода(ов): трансформации, ветвления,
await, поднятые события, тронутое общее состояние, пересечения границ. Не делегируется — семантика. - Таблица нитей:
{id, вход→выход, длина(хопы), ветвление, S, пересечения}.
Единица доказательства — нить, не счётчик: «нить #2 от Run() до LoadAndPlay рвётся на fake-null», а не «1 нарушение».
4. Протокол ветки A — моно (≤2000 LOC)
- Выделить нити (раздел 3), собрать таблицу.
- По каждой нити — оси 1/2/3/5 и
Sпоreferences/axes.md(прочитать файл целиком перед этим шагом). - Построить граф нитей → Ось 4 и проверка рекурсии по
references/axes.md. - Формула (раздел 5), формат (раздел 6).
5. Итоговая формула
База = (A1 + A2 + A3 + A5) / 12 × 10 # каждая ось 0–3
Сырой = База × 0.6^tangle_hidden × 0.9^tangle_visible
Итог = min(Сырой, CAP)
CAP = 1 если есть цикл БЕЗ гарантии стопа (гарантированный hang/overflow)
CAP = 2 если цикл с хрупким/частичным стопом
CAP = 10 (нет потолка) если катастроф нет
Дизамбигуация: проблема, попавшая и в спутанность, и в другую ось, считается один раз — в более тяжёлой (Ось 4 / потолок). Ступенчатость заряжает Ось 3 (база) и, при утечке half-state, Ось 4 (множитель) — но одну и ту же точку не считать дважды в множителе.
Чувствительность
| hidden | visible | Множитель |
|---|---|---|
| 0 | 0 | 1.000 |
| 0 | 1 | 0.900 |
| 0 | 2 | 0.810 |
| 1 | 0 | 0.600 |
| 1 | 1 | 0.540 |
| 1 | 2 | 0.486 |
| 2 | 0 | 0.360 |
Скрытая спутанность бьёт резко намеренно: невидимые сцепки не чинятся коммитом.
6. Формат вывода
[applied-quality] <target> · Ветка X · <LOC>
⛔ КАТАСТРОФА: <есть/нет> ← если есть, баннер первой строкой, CAP применён
## Карта нитей
| id | вход → выход | S | пересечения |
## Манифест швов (только A+) ← сшитые cross-shard рёбра
| идентити | из→в | канал | скрытое/явное |
## Циклы (проверка рекурсии)
| цикл | гарантия стопа | вердикт |
## Оси (рубрика; для A+ — со столбцами по шардам + min–max)
| Ось | балл | доказательство (id нити / файл:метод) |
## Спутанность (Ось 4)
| пересечение | нити | канал | скрытое/явное |
## Итог
- База / множитель (0.6^h·0.9^v) / CAP / Итог / шкала
- Диагностический сигнал: разрыв База↔Итог
Шкала итога (интервалы полуоткрыты — граница уходит в верхнюю корзину)
- [8–10] — прочный: нити чистые, распутанные.
- [6–8) — хороший, minor проблемы жизненного цикла.
- [4–6) — приемлемый, локальные баги на re-entry/границах.
- [2–4) — проблемный, сложно поддерживать (спутанность/ступенчатость).
- [0–2) — критический (или сработал потолок катастроф).
Диагностический сигнал (обязателен)
- Разрыв База↔Итог большой (Итог < 0.6×База): «Низкий Итог при более высокой Базе — над локальными багами есть скрытая спутанность/рекурсия, которую усреднённые оси не ловят. Смотреть швы прицельно.»
- Разрыв малый: «Оси и Итог близки — спутанности мало, минусы локальны и чинятся коммитами.»
7. Делегирование
- LOC + инвентарь входов/выходов → Haiku (
Explore/general-purpose). - Пер-шардовый анализ нитей + манифест границы (A+) → Sonnet-агенты параллельно (
run_in_background). - Сшивка графа, Ось 4, рекурсия, применение формулы/CAP → основной контекст, не делегируется (семантика).
8. Жёсткие правила
- Единица доказательства — сценарий отказа на конкретной нити, не абстрактный счётчик. Каждый минус привязан к
файл:метод/id нити, иначеn/a. - Размер носителя не оценивается (это code-quality). Оценивается over-fetch по нити + доменная замкнутость.
- Чистота — в динамике: паттерн, чистый в покое, но текущий на re-entry (replay/close→open) — минус. «Держит при повторном входе» — обязательный вопрос.
- Рекурсия без гарантии стопа = потолок, не множитель. Гарантированный стоп (dedup/guard/прогресс/base-case) снимает катастрофу.
- Fan-out события ≠ спутанность. Спутанность — общий мутабельный пивот или окно рассинхрона, не чистая событийная развязка.
- Проверять downcast в ОБЕ стороны. Не только «нить лезет в чужой concrete», но и «нить приводит СВОЮ декларированную абстракцию (
IX) к concrete» — ложная точка расширения в динамике: рвётся при подмене реализации. Разрыв засчитывать только при реальном пути подмены (иначе латентный смелл). - Гард ≠ проход по ложной точке расширения. Звонкий
throw/null-гард закрывает только ТИХИЙ разрыв (Ось 3). Сам ложный шов (абстракция загружена → низведена в concrete, декларированная расширяемость обнулена) остаётся и идёт в Ось 4 (скрытое ×0.6) НЕЗАВИСИМО от гарда. Никогда не выдавать «эталон/done right» за одно лишь наличие гарда наas Concrete. - A+: граф пересобирается на швах. Спутанность и рекурсия считаются глобально, не усредняются. Оси — среднее + разброс min–max.
- Результаты агентов — гипотезы до верификации. Самые тяжёлые находки (катастрофа, деление на ноль, гонка, always-return) при сомнении доверять чтением перед принятием как факт.
- Не смягчать балл «потому что фикс дорогой». Объём фикса — отдельно.