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 + инвентарь (файлы, типы, точки входа/выхода-кандидаты) — через Agent subagent_type=Explore или general-purpose model=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.

Протокол выделения:

  1. Инвентарь кандидатов вход/выход — делегируется Haiku (grep сигнатур).
  2. Для каждого входа — трассировка вперёд до выхода(ов): трансформации, ветвления, await, поднятые события, тронутое общее состояние, пересечения границ. Не делегируется — семантика.
  3. Таблица нитей: {id, вход→выход, длина(хопы), ветвление, S, пересечения}.

Единица доказательства — нить, не счётчик: «нить #2 от Run() до LoadAndPlay рвётся на fake-null», а не «1 нарушение».


4. Протокол ветки A — моно (≤2000 LOC)

  1. Выделить нити (раздел 3), собрать таблицу.
  2. По каждой нити — оси 1/2/3/5 и S по references/axes.md (прочитать файл целиком перед этим шагом).
  3. Построить граф нитей → Ось 4 и проверка рекурсии по references/axes.md.
  4. Формула (раздел 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) при сомнении доверять чтением перед принятием как факт.
  • Не смягчать балл «потому что фикс дорогой». Объём фикса — отдельно.