name: tz-design description: Оформить техническое задание (ТЗ) на новую фичу или подсистему, либо провести self-audit готового ТЗ. ОБЯЗАТЕЛЬНО объявить активацию первой строкой ответа (формат «🔧 Активирован skill: tz-design» с указанием режима, целевой зрелости, плана) — пользователь должен явно знать, что включился структурированный процесс. Двухуровневая структура документа — введение для нетехнаря + концептуальный алгоритм + технические разделы. Триггеры на оформление — «оформи как ТЗ», «сделай ТЗ», «напиши техническое задание», «упакуй в ТЗ», «выведи ТЗ», «доработай ТЗ», «прикинем ТЗ под…». Триггеры на self-audit — «проанализируй ТЗ», «оцени ТЗ на полноту/избыточность/оверинжиниринг», «прогони ревью». Шаг 0 (всегда) — уточнить целевую зрелость (прототип/MVP/релиз 1.0/production scaling) для корректной калибровки. Skill работает в три условные фазы — критический разбор (риски + best-practice) → декомпозиция данных (по критериям атомарности и самодостаточности) → структурированное оформление. Финальный output — markdown в чате для итераций + опционально .docx через docx-skill. По умолчанию русский язык. ТЗ — мост между менеджером и разработчиком: фиксирует «что» и «зачем», не диктует implementation choices.
tz-design
Объявление активации (обязательно, первым сообщением)
Первое сообщение после срабатывания skill'а ОБЯЗАНО явно объявить его активацию. Это нужно, чтобы пользователь знал — он работает с структурированным процессом, а не с обычным ответом.
Формат объявления:
🔧 Активирован skill: tz-design
Режим: <оформление ТЗ | self-audit ТЗ | доработка существующего ТЗ>
Целевая зрелость: <зафиксирована из контекста: прототип/MVP/релиз 1.0/production scaling
ИЛИ запрос на уточнение, если не очевидно>
План: <короткий list дальнейших шагов: фазы, которые будут запущены, или пропущены>
Примеры:
🔧 Активирован skill: tz-design
Режим: оформление ТЗ (запрос «сделай ТЗ на раздел новостей»)
Целевая зрелость: не указана — задам уточняющий вопрос (Шаг 0)
План: Шаг 0 → Фаза 1 (есть триггеры: внешний API, неатомарная система) → Фаза 2 → Фаза 3
🔧 Активирован skill: tz-design
Режим: self-audit готового ТЗ
Целевая зрелость: релиз 1.0 (из контекста сессии)
План: анализ по 5 осям с разделением TZ-level findings vs implementation details
🔧 Активирован skill: tz-design
Режим: доработка ТЗ (правка раздела N)
Целевая зрелость: MVP (зафиксирована ранее)
План: точечная правка указанной секции + повторный sanity-check
Правила:
- Объявление первой строкой ответа, до любого другого текста.
- Если несколько триггеров пересеклись (например, пользователь сначала просит «прикинем ТЗ под X», потом «доработай по результатам анализа») — режим выбирается по последнему явному запросу, объявляется явно.
- Если пользователь в одном сообщении просит несколько действий (например, «оцени ТЗ и сразу внеси правки») — объявить оба этапа в плане.
- Молча запускать skill — антипаттерн. Пользователь не должен догадываться, что включился структурированный процесс.
После объявления — обычная работа по канонической логике skill'а (Шаг 0 → фазы → каноническая структура → output).
Когда срабатывать
- Пользователь явно просит оформить ТЗ: «оформи как ТЗ», «сформулируй ТЗ», «техническое задание», «упакуй в ТЗ».
- Пользователь приносит концептуальное предложение (своё или чужое) с просьбой «давай рассмотрим этот вариант / оценим / прикинем под…».
- Пользователь просит «доработать ТЗ» / «уточнить ТЗ» — работаешь с уже существующим документом.
НЕ запускать на просьбы «опиши, как работает X» или «расскажи о Y» — это документация, не ТЗ.
Пользовательский override фазы
Пользователь может явно отключить фазу командой «пропусти Фазу N» / «без критического разбора» / «не нужна декомпозиция».
Действие skill'а: подтвердить «Понял, пропускаю Фазу N. Если в итоге всплывут проблемы по её предмету — буду указывать с пометкой "предупреждал бы в Фазе N"». Это страхует обе стороны и сохраняет аудит-трейл решения.
Шаг 0: Уточнение целевой зрелости (обязательно перед любой фазой)
Перед запуском любой фазы уточнить у пользователя, для какого уровня зрелости готовится ТЗ. От этого зависит:
- что считать gap'ом, а что приемлемой ограничённостью scope;
- что считать overengineering, а что — foundation для будущего масштабирования;
- какие edge cases требуют явной спецификации, а какие можно оставить на разумный default разработчика.
Если в исходном запросе уровень зрелости не очевиден — задать вопрос явно:
Перед началом — уточню целевой уровень зрелости ТЗ:
1. Прототип — нужно проверить концепт, edge cases игнорируем, после демонстрации
код может быть выброшен. Любая упрощённость допустима.
2. MVP — минимальный рабочий продукт. Cut всё, что не критично. Архитектурные
компромиссы допустимы, рефакторинг ожидается перед масштабированием.
3. Релиз 1.0 — production-ready, но без претензий на гипер-масштаб.
Должно работать стабильно для текущего объёма + закладывать место под рост.
Edge cases с низкой вероятностью можно оставить на default разработчика.
4. Production с масштабированием — высоконагруженная система, явное требование
к performance, отказоустойчивости, observability. Edge cases прорабатываются
полностью.
Какой уровень?
Если уровень очевиден из контекста (пользователь сказал «это для прода», «MVP сделай», «релиз 1.0», «нам надо запустить и забыть») — зафиксировать выбор явно: «Понял, делаю под <уровень>. Это значит: <что включаем / что оставляем на потом>».
Зафиксировать в Phase 3 финальном документе — в начале раздела «Зачем это нужно» или в метаданных ТЗ строка вроде «Уровень: релиз 1.0».
Если контекст меняется в процессе (пользователь говорит «слушай, давай не на MVP, а на 1.0») — явно пересмотреть уже принятые решения по фазам с пометкой «контекст изменён, переоценил X, Y, Z».
Трёхфазный режим (фазы условные — запускаются по триггерам)
Фаза 1: Критический разбор
Запускать если входное предложение содержит хотя бы одно из:
- финансовая логика (комиссии, ставки, балансы, выплаты);
- многосторонние стимулы (менеджер vs клиент vs система);
- работа с приватными/защищёнными данными;
- асинхронные/concurrent операции;
- интеграции с внешними API;
- неатомарная система (предложение допустимо безболезненно разделить на несколько задач);
- задействует область со стандартизированным best-practice (см. 1.3).
Если ни одно — Фаза 1 пропускается, переход сразу к Фазе 2 или 3.
1.1 Чек-лист поиска рисков
Обязательный на каждый запуск Фазы 1:
| Категория | Что проверяю |
|---|---|
| Конфликт интересов | Кому выгодно манипулировать какой переменной? |
| Информационная асимметрия | Кто что видит и кто этим выигрывает? |
| Несправедливость между сторонами | Одинаковые ли условия для участников? |
| Инженерное переусложнение | Адекватен ли уровень сложности решения уровню задачи? Можно ли убрать половину и не потерять ценность? |
| Edge cases | Пустые состояния, отрицательные числа, граничные значения, отказ внешних систем. |
| Math invariants | Сохраняется ли инвариант при всех операциях? Где может «потеряться» сумма? |
| Подкручиваемые параметры | Что мешает менеджеру/админу медленно дрейфовать настройку в свою пользу? |
| Скрытое поведение | Что система делает, но не показывает? Не превращается ли в обман? |
| Атомарность scope | Не пытается ли одна задача решить три? Можно ли разделить на этапы? |
1.2 Доменноспецифичные доборы
Применять при наличии домена во входе:
- Finance: sub-cent drift, fixed-point precision, регуляторные ограничения, time-of-day для NAV, локали (comma/dot).
- Data privacy: PII в логах, шифрование at-rest, retention policy, право на забвение.
- Async/concurrent: race conditions, lost updates, idempotency, retry-storm, lock ordering.
- External APIs: timeout/retry стратегия, rate limits, graceful degradation, маскирование ключей в логах.
- UI: accessibility, мобильная адаптация, offline mode, empty/loading/error состояния.
1.3 Best-practice check
Для каждой задействованной области:
| Область | На что смотреть |
|---|---|
| Auth/Security | Хеширование паролей, формат токенов, TTL сессий, защита от CSRF/XSS, signed URLs, scoping ключей |
| API design | REST/RPC, versioning, pagination (cursor vs offset), форматы ошибок, idempotency keys |
| Database | Нормализация vs денормализация, выбор индексов, soft delete vs hard, audit-trail |
| Caching | TTL стратегия, инвалидация (TTL/event/manual), уровни |
| Async/Queues | Retry, idempotency, dead-letter, ordering |
| File storage | Naming (hash vs sequential), пути, public vs private, validation типов/размеров |
| UI patterns | Form validation, optimistic updates, error UX, empty/loading/error состояния |
| Concurrency | Lock ordering, atomic operations, transaction boundaries |
| Project-specific конвенции | Конвенции, явно зафиксированные в CLAUDE.md или существующем коде проекта |
Алгоритм:
- Идентифицировать «принятый подход» (индустриальный стандарт или конвенция проекта). Если стандарт неоднозначен/контекстен — указать обе ветки нейтрально.
- Сравнить с предложением.
- Если есть расхождение — оформить блок-вопрос.
Формат блока-вопроса:
🔍 Best-practice check: <название области>
Принятый подход:
<краткое описание индустриального стандарта или конвенции проекта>
<почему так принято: 1-2 причины>
В предложении:
<что предлагается>
<видимое отклонение>
Варианты:
1. Сделать как принято — <конкретный шаг>
2. Оставить как у меня — <уточни осознанную причину>
3. Гибридный / другой — <если хочешь обсудить альтернативу>
Выбор? (ответь 1 / 2 / 3 с обоснованием)
Правила:
- Одно расхождение = один блок. Не объединять.
- Если у пользователя уже стоит принятый подход — ничего не выводить (это шум).
- Контекстный стандарт — без давления, нейтрально оба варианта.
- Project-specific конвенции имеют приоритет над общеиндустриальными.
- Для свежих/эволюционирующих стандартов (OAuth 2.1 vs 2.0) — отметить дату и при необходимости WebSearch.
1.3.1 Режим «объясни варианты»
Триггеры активации:
- Прямая просьба: «я не разбираюсь», «объясни», «какой вариант лучше», «не понимаю», «расшифруй».
- Пользователь не ответил на блок-вопрос за 2 итерации диалога.
Определение итерации без ответа:
- Явный выбор 1/2/3 (с обоснованием или без) → это ответ, счётчик сбрасывается.
- Уточняющий вопрос по блоку → итерация без ответа, +1.
- Смена темы / другие вопросы / молчание по предмету → итерация без ответа, +1.
После 2-й итерации без ответа — авто-активация explain mode для текущего блока.
Формат explain mode:
🔍 Best-practice check: <название области>
📖 Простыми словами:
<2–4 предложения объяснения проблемы. Без терминов API, FK, schema, cursor,
OAuth, idempotency — заменять на «способ хранения», «связь», «как обновляется»,
«вход в аккаунт», «защита от двойного клика». До 1 бытовой аналогии на блок.>
⚖️ Плюсы и минусы:
Вариант 1 — <принятый подход одним словом>
+ <2–3 человеческих плюса, что хорошо в реальной жизни>
− <1–2 человеческих минуса, что неудобно>
Вариант 2 — <как у пользователя>
+ ...
− ...
Вариант 3 — <гибрид/другое, если применимо>
+ ...
− ...
🔧 Технически (для финального ТЗ, пойдёт разработчику):
<тот же блок «Принятый подход / В предложении / Варианты», что в стандартном
формате 1.3, БЕЗ повторного вопроса в конце>
Выбор? (1 / 2 / 3 с обоснованием — обоснование тоже попадёт в ТЗ)
Правила режима:
- Запрещённые термины в блоке «Простыми словами»: API, endpoint, FK, foreign key, schema, cursor, offset, OAuth, token, hash, idempotency, race condition, transaction. Заменять на человеческие эквиваленты.
- Разрешено: «база данных», «настройка», «пользователь», «вход», «связь между», «хранится отдельно».
- Бытовые аналогии — да, но не больше одной на блок и без растягивания.
- Технический блок остаётся обязательным — он попадёт в ТЗ как обоснование выбора.
- После выбора пользователя в explain mode — следующий блок-вопрос (если есть) выдаётся в обычном формате. Explain mode не «прилипает» — активируется заново по триггерам.
1.4 Как искать (методология)
-
Декомпозиция на тематические блоки. Выделить блоки ТЗ по смысловой принадлежности (финансовый, бэк-сервис, фронт, математический, защита данных, архитектурный, интеграционный). Вывести список явно. Запросить подтверждение пользователя.
-
Параллельный запуск агентов (если объём большой). Триггер: входной материал > 10k токенов ИЛИ существующий код для анализа > 3000 строк. Использовать
general-purposeагентов — по одному на тематический блок. Явно предупреждать о запуске и количестве. -
Полный список проблем под анализ. Перед началом — вывести список категорий из чек-листа 1.1 + домены из 1.2 + области из 1.3, по которым будет вестись анализ. Запросить: «что ещё добавить?». Не запускать молча.
1.5 Глубина и формат отчёта
- Не более 15 пунктов в финальном отчёте (отдельно от best-practice блоков-вопросов — их сколько найдётся, в пределах разумного).
- Ранжировать:
- Critical — ломает фундаментальный инвариант / создаёт юридический или финансовый риск / делает систему уязвимой для манипуляций одной стороной. Обычно 1–3.
- Important — нарушает справедливость / создаёт нелогичные edge cases / требует существенной переработки. Обычно 3–7.
- Minor — стилистическое / эргономическое / низковероятное. До кэпа.
- По каждому: конкретный сценарий или формула. Не абстрактное «может быть проблема».
- Для критичных — обязательно альтернативы (Вариант A / B / C).
- Best-practice блоки идут отдельной секцией после ранжированного списка проблем.
1.6 Условие выхода из Фазы 1
Пользователь:
- зафиксировал архитектурный путь по всем critical/important пунктам;
- ответил (1 / 2 / 3 с обоснованием) на каждый best-practice блок-вопрос.
Не переходить в Фазу 2, пока оба условия не выполнены.
Фаза 2: Декомпозиция данных
Запускать если входная задача содержит хотя бы одно из:
- ≥ 2 новых сущности (модели, таблицы);
- ≥ 2 существующих сущности модифицируются и связаны инвариантами;
- есть состояние, эволюционирующее через несколько типов событий (state machine, ledger, очередь);
- введён новый инвариант, связывающий несколько сущностей.
Условие пропуска: одна новая таблица без связей, или модификация одного столбца, или чистый алгоритм без состояния. В этом случае структуру данных формализовать сразу в Фазе 3 / разделе 1 ТЗ.
Алгоритм
-
Перечислить все участвующие сущности — существующие (затрагиваемые), новые (создаваемые), модифицируемые. Включая на первый взгляд нелогичные (audit_log, news, system_flags, observer-точки).
-
Декомпозировать каждую до атомарной модели.
Атомарная = все поля являются одним из:
- примитивы (int, string, decimal, bool, datetime, json со схемой);
- коллекции примитивов (массив строк, JSON-список с описанной структурой);
- foreign key с явной семантикой связи.
Если поле — составной объект, который сам по себе имеет жизненный цикл/инварианты → выделить в отдельную сущность, продолжить декомпозицию.
Стоп-условие: все поля атомарны.
-
Re-check самодостаточности. Для каждой атомарной модели — вопрос:
«Достаточно ли этой модели одной для полного описания доменного смысла, или нужны данные извне?»
Если самодостаточна → отметить явно «доменный смысл полный».
Если нужны данные извне → обязательно указать достраивающую зависимость одним из:
- Поглощение/денормализация: «копируем поле X из сущности Y в момент Z, потому что …»
- Явная FK с семантикой: «
field_id→OtherEntity. Семантика: <зачем эта связь, не просто "связан с">» - Документированный путь резолвции: «доступ только через
Service::method()/Model::scope()— обходные пути запрещены» - Контракт со-существования: «сущности X, Y, Z создаются/удаляются вместе, инвариант проверяется в
<место>(validateFond / observer / DB::transaction)»
Без явного выбора — модель помечена «архитектурно недозавершена», переход в Фазу 3 невозможен.
Decision helper для самодостаточности. Если пользователь подтверждает несамодостаточность, но не понимает какой из 4 типов выбрать — активируй вопросник:
Помогу выбрать тип достраивающей зависимости. Ответь на 1–2 вопроса: Q1: Нужна ли историческая фиксация значения (snapshot, актуального на момент создания связи)? — Да → Поглощение/денормализация. Копия живёт независимо от источника, защищена от будущих изменений (пример: commission_percent в заявке на вывод хранится как копия из настроек, чтобы редактирование настроек не меняло задним числом сумму комиссии). — Нет → переход к Q2. Q2: В каком отношении сущности с зависимостью? — Зависимость существует независимо, может быть удалена/изменена → Явная FK с семантикой (типовой случай user → resource). — Сущности создаются всегда вместе в одной транзакции, по отдельности невалидны → Контракт со-существования (пример: 3 fond_situation при processWithdraw). — Зависимость не хранится напрямую, резолвится через бизнес-логику (scope / service / computed property) → Документированный путь резолвции (пример: hedge.balance через ledger SUM).Триггеры активации helper'а: явная просьба пользователя («не понимаю», «помоги выбрать», «какой подходит») ИЛИ повторное «несамодостаточна, не знаю» подряд.
Auto-выбор зависимости запрещён даже после helper'а — пользователь обязан явно ответить Q1/Q2.
-
Re-check реестровой модели. Для каждой сущности с коллекцией экземпляров — вопрос:
«Несёт ли коллекция собственный доменный смысл помимо хранилища?»
Реестр выделяется в отдельную сущность (свой контроллер, scope'ы, бизнес-методы), если выполнено хотя бы одно:
- собственное состояние коллекции (текущий активный, версия, счётчик, метаданные коллекции);
- доменные операции над коллекцией, не сводимые к стандартному Eloquent API («синхронизировать все», «выбрать тот, что подходит по правилу»);
- несколько потребителей с единообразным API/контрактом.
Если нет — это просто
hasManyот владельца, без отдельной модели управления. -
Cross-cutting инварианты. Формулы и правила, связывающие несколько атомарных моделей. Например:
fond_situation.summ + hedge_ledger.balance + open_options = real_Bybit_total- «Любая
WithdrawalRequestимеет ровно 3 связанныхfond_situationс конкретными source-значениями».
Для каждого инварианта: где проверяется (
validateFond/ observer / тест / DB constraint). -
Анализ пробелов. По каждому полю/связи:
- Кто отвечает за заполнение? (если никто — пробел)
- Что произойдёт при NULL?
- Что произойдёт при удалении связанной сущности (CASCADE / RESTRICT / SET NULL)?
- Как мигрируются существующие записи при добавлении нового поля?
Формат карточки атомарной модели
### <Имя сущности>
- **Назначение:** одна строка.
- **Поля:** список с типами и обоснованием (зачем нужно, кто пишет, кто читает).
- **Жизненный цикл:** создание, переходы, удаление/архивация.
- **Самодостаточность:** ✅ полный доменный смысл ИЛИ
⚠️ Достраивающая зависимость — <тип>: <конкретное описание>
- **Реестровая обёртка:** не нужна ИЛИ
Выделена как `<RegistryModel>` с обоснованием: <какой критерий сработал>
- **Источники мутации:** контроллер/сервис/observer/миграция/admin-UI.
- **Источники чтения:** UI/API/отчёт/другой сервис.
- **Участие в инвариантах:** список cross-cutting инвариантов (раздел 5).
- **Поведение при NULL ключевых полей:** конкретно.
- **CASCADE при удалении связанных:** RESTRICT / SET NULL / CASCADE и почему.
Формат output
Вывести карточки атомарных моделей блоками. Между блоками — вопросы по каждому:
- «Декомпозиция до атомарного уровня — корректна? Есть ли поля, которые я не разбил, хотя надо было?»
- «Самодостаточность блока X — выбранный способ выражения зависимости (поглощение/FK/путь/контракт) — правильный?»
- «Реестровая обёртка для коллекции Y — нужна или избыточна?»
Не вываливать все блоки разом без вопросов. Получать подтверждение по каждому.
Условие выхода из Фазы 2
Пользователь подтвердил состав, самодостаточность, реестровый статус, инварианты и lifecycle по всем блокам. Ни одной модели в статусе «архитектурно недозавершена».
Фаза 3: Структурированное оформление
Когда подход (Фаза 1) и данные (Фаза 2) согласованы — оформляй документ по канонической структуре. Артефакты предыдущих фаз:
- Раздел 1 (Структура данных) = формализация output'а Фазы 2 (карточки + cross-cutting инварианты). Если Фаза 2 не запускалась — описать схему данных кратко здесь.
- Разделы 2–3 (Логика, Конфигурация) опираются на тематические блоки Фазы 1 (если выделялись).
- Раздел 7 (Открытые вопросы) включает:
- unresolved из Фаз 1 и 2 (с явной отметкой);
- всплывшее уже в процессе оформления.
- Раздел 8 (Порядок реализации):
- если Фаза 1 нашла упрощение scope → первым шагом «зафиксировать упрощённый scope»;
- если в Фазе 1 были best-practice отклонения → их обоснования зафиксировать комментариями в соответствующих разделах ТЗ (раздел 1/2/3) с пометкой «выбрано отклонение от стандарта, причина: <…>».
Если Фазы 1 и 2 пропущены (тривиальная задача — фильтр в существующем списке, изменение одной строки конфига, чистая UI-правка):
- Фаза 3 работает от голого запроса пользователя.
- Разделы 2–3 ТЗ выводятся напрямую без артефактов предыдущих фаз.
- Разделы 1 (структура данных, даже если это «без изменений в схеме — пометить явно») и 7 (открытые вопросы) — обязательны несмотря на тривиальность задачи. Минимальный sanity-check для тривиальной задачи: «что может пойти не так на проде?», «какие крайние случаи?», «нужны ли тесты?».
Каноническая структура ТЗ
# ТЗ: <название>
## Зачем это нужно (для нетехнаря)
— описание проблемы простым языком, без терминов кодовой базы
— почему текущее состояние плохо
— нумерованный список «идея решения» (5–7 пунктов, начинаются с жирного key term)
— абзац-итог «что это даёт»
## Алгоритм работы (концептуально, без технических деталей)
### Постоянно действующие сущности
— список с жирными названиями
### Что происходит при <ключевом событии 1>
— нумерованный пошаговый сценарий
### Что происходит при <ключевом событии 2>
…
### Что не меняется
— гарантии для существующего поведения
### Что обеспечивает доверие
— механизмы прозрачности и защиты от манипуляций
## 1. Структура данных / аккаунтов / сущностей
— миграции / новые модели / поля (формализация output'а Фазы 2)
— карточки атомарных моделей с пометкой самодостаточности
— инварианты системы (формула + место проверки)
## 2. Логика основных операций
— подразделы по типам событий (рост/просадка/ошибка/специальный кейс)
— псевдокод или пошаговые алгоритмы
— ссылки на код проекта (Class::method, route name)
## 3. Конфигурация
— SystemFlag/таблицы настроек
— уровень доступа на запись/чтение (явные permission ID)
— governance: AdminLock + Audit + автопост в новости (если есть)
## 4. UI / дашборд (если применимо)
— страницы, эндпоинты, права доступа
— содержание каждого экрана
— кнопки и формы
## 5. Изменения в существующем коде
### Миграции
— нумерованный список
### Код
— нумерованный список с конкретными классами/методами
## 6. Прозрачность и документация
— что пишется в audit_log
— что публикуется в новостях
— документы для клиентов, если нужны
## 7. Открытые вопросы для согласования ДО старта работ
— нумерованный список, каждый пункт — вопрос с подвариантами
— включает unresolved из Фаз 1 и 2 + новое из оформления
## 8. Порядок реализации
— нумерованные шаги, оптимальный путь от миграций к UI
— первым шагом — фиксация упрощённого scope (если Фаза 1 его сузила)
— обязательно «тесты на каждый блок» отдельным пунктом
Структура — не догма. Адаптируй под скоуп:
- если новая фича не имеет UI → секцию 4 пропустить;
- если изменений в коде минимум → секция 5 одной строкой;
- если фича изолированная → секции 6 может не быть.
Стилистические правила
- Язык: русский, если контекст проекта на русском (по умолчанию — русский).
- Имена сущностей: код-стайл моноширинно (
fond_situation.summ,BybitService::fetchSnapshot). - Цифры: конкретные с обоснованием. «Не 5–10 минут», а «5 минут, потому что Bybit retry-window 3 минуты + safety».
- Списки: нумерованные для последовательных шагов, маркированные для перечисления равноправных пунктов.
- Запреты:
- не использовать «возможно», «вероятно», «как-то» — формулируй конкретно;
- не использовать эмодзи в технических разделах (только в client-facing разделах при явной просьбе);
- не дублировать содержимое (если уже описано в разделе 2 — в разделе 5 короткая ссылка).
Открытые вопросы — обязательная секция
Любой ТЗ обязан содержать раздел «Открытые вопросы». Минимум 1 пункт, обычно 3–5. Если кажется что вопросов нет — копай глубже:
- стартовые значения настроек?
- поведение при отказе внешней системы?
- миграция существующих данных?
- крайние случаи (пустой фонд, нулевой клиент, отказ всех аккаунтов)?
- доступ для гостей vs только auth?
Не передавай ТЗ в реализацию с нерешёнными открытыми вопросами. В порядке реализации (раздел 8) первым шагом должна стоять фиксация ответов на них.
Output mode
- Сначала markdown в чате. Это итерационная среда — пользователь будет править, возражать, добавлять. Markdown быстро правится.
- После согласования предложить упаковку в .docx. Не делать самостоятельно — спросить «упаковать в .docx?». Использовать
docx-skill для генерации. - Сохранять build-скрипт (
build_<topic>_tz_doc.cjs) в корне проекта или указанной папке для последующей пересборки. - Решения по best-practice отклонениям документируй в финальном ТЗ. В разделе 1/2/3 (где описывается соответствующая область) — пометка «выбрано отклонение от стандарта по причине: <…>». Это спасёт code review через 6 месяцев от вопроса «почему не использован X?».
Итерация после возражений
-
Подтверди понимание короткой фразой («Понял: <суть правки>»).
-
Внеси изменения точечно — не переписывай весь документ. Покажи только diff/изменённые секции в чате.
-
После 2–3 итераций спроси: «Готов к упаковке в .docx, или ещё правки?»
-
Если правка ломает результат предыдущей фазы — явно вернуться в соответствующую фазу для перепроверки, а не молча подкручивать ТЗ.
Правила частичного возврата:
- Если всплыла одна новая сущность во время оформления → обработать её только через карточку Фазы 2 (атомарность → самодостаточность → реестр → инварианты), полную Фазу 2 не повторять.
- Если всплыли ≥ 2 связанные новые сущности или меняется уже зафиксированный инвариант → перезапустить Фазу 2 целиком (старые карточки остаются как baseline, перепроверяются связи).
- Если новая сущность касается области, не покрытой прошлой best-practice проверкой → обязательно запустить best-practice check на эту область из Фазы 1.3.
- Любой возврат явно объявляется пользователю: «Эта правка тянет за собой пересмотр Фазы N для <причина>. Согласен?»
Антипаттерны
- Не пропускать Фазу 1, если предложение содержит финансовую логику или дизайн с возможностью манипуляций.
- Не пропускать Фазу 2, если задача затрагивает > 1 сущности с инвариантами.
- Не запускать best-practice check молча. Если идёшь по стандарту по умолчанию — не пиши «использую такой-то подход». Это решение пользователя.
- Не предлагать «как принято», если так уже и предложено. Это шум.
- Не давить предпочтением, когда стандарт контекстен.
- Не вываливать все карточки сущностей разом в Фазе 2 без вопросов.
- Не использовать готовый шаблон механически. Если разделы не подходят — адаптируй структуру.
- Не оставлять "TODO"/"FIXME" в финальном документе. Все нерешённые вопросы → раздел «Открытые вопросы».
- Не упаковывать в .docx до согласования.
- Не отвечать «принято, делаю». Сначала зеркально подтверди правку.
- Не врать про охват. Если что-то не покрыл — явно в открытых вопросах.
- Не запускать skill молча. Первое сообщение после срабатывания обязательно содержит объявление активации (см. секцию «Объявление активации»). Без объявления пользователь не знает, что включился структурированный процесс.
- Не диктовать implementation choices. ТЗ — мост между менеджером и разработчиком: фиксирует «что» и «зачем», не «как именно реализовать». Конкретные имена методов, выбор cache TTL, способ декомпозиции сервисов, выбор между SELECT-then-INSERT vs INSERT-and-catch — это территория разработчика, не ТЗ.
Self-audit готового ТЗ (по запросу пользователя)
Когда пользователь просит «проанализируй ТЗ», «оцени его на полноту/избыточность/оверинжиниринг», «прогони ревью» — это отдельный режим работы skill'а. Правила:
Перед началом self-audit'а — обязательно уточнить контекст
Без знания целевой зрелости ТЗ (см. Шаг 0) невозможно адекватно оценить:
- что считать gap'ом (для прототипа — никаких gap'ов; для production-scaling — каждый edge case критичен);
- что считать оверинжинирингом (для MVP — почти всё лишнее; для релиза 1.0 — foundation для роста ОК; для prototype — overspec).
Если уровень зрелости НЕ зафиксирован в самом ТЗ или предыдущем диалоге — первое действие self-audit'а: задать вопрос Шага 0. Не начинать анализ до ответа.
Что проверять при self-audit'е
Прохожу по 5 осям, ранжируя findings по серьёзности и отделяя TZ-level concerns от implementation details:
| Ось | Что искать |
|---|---|
| Полнота | Чего не хватает с учётом целевой зрелости. Для 1.0 — функциональные требования; для production — edge cases и failure modes |
| Избыточность | Что дублируется, что специфицировано без необходимости |
| Оверинжиниринг | Решения, не оправданные текущим уровнем зрелости (например, distributed cache для системы с 50 пользователями) |
| Понятность | Раздел «Зачем нужно» — для нетехнаря, остальное — для разработчика. Терминология единая |
| Адекватность логики | Внутренние противоречия, нарушения собственных инвариантов, undefined семантика в base flow |
Обязательное разделение findings
Каждое замечание классифицировать:
- TZ-level concern — реально требует решения в ТЗ (бизнес-решение, архитектурное требование, влияет на разработчика).
- Implementation detail — это «как», не «что». Если такое нашёл — не давать как замечание ТЗ, явно отметить «это implementation choice разработчика, не ТЗ-уровень».
Анти-паттерн self-audit'а: критиковать ТЗ за implementation choices. Например:
- ❌ «Стоит использовать
DB::afterCommitвместоNewsObserver::created» — это implementation, не ТЗ-уровень. - ✅ «Inv-3 должен формулировать требование "cleanup не нарушает consistency при rollback", без диктовки HOW» — это ТЗ-уровень (формулировка инварианта).
Калибровка по уровню зрелости
При оценке каждого finding'а — спрашивать «релевантно ли это для целевого уровня?»:
| Уровень | Что отбрасывать как «не нужно для этого уровня» |
|---|---|
| Прототип | Performance, observability, security beyond basics, scaling, audit-trails |
| MVP | Performance optimization, future-scaling foundation, exotic edge cases |
| Релиз 1.0 | Hyper-scale performance, exotic edge cases с низкой вероятностью, premature pivot-points |
| Production scaling | Ничего не отбрасываем — всё в скоупе |
Формат финального отчёта self-audit'а
## Полнота: N/10
## Избыточность: N/10
## Оверинжиниринг: N/10
## Понятность: N/10
## Адекватность логики: N/10
## Общая: N/10
### Реально TZ-level findings (требуют действия)
1. Critical: <концерн> — <обоснование>
2. Important: <концерн> — <обоснование>
3. Minor: <концерн> — <обоснование>
### Implementation details (НЕ замечания к ТЗ — упоминаются для прозрачности)
- <находка>: это implementation territory, не ТЗ-уровень
### Не релевантно для уровня зрелости <X>
- <находка>: applicable для уровня <Y>+, не для текущего
### Самокритика анализа
Если значительная часть findings оказалась implementation details или edge cases для более высокого уровня зрелости — явно отметить «X% моих findings были вне scope ТЗ для этого уровня».
После self-audit'а
Пользователь может попросить «внеси правки». Тогда:
- TZ-level findings — внести точечно в markdown ТЗ + предложить пересборку .docx.
- Implementation details — НЕ вносить в ТЗ. Если пользователь настаивает — переспросить «уверен, что это в ТЗ нужно? Это обычно решает разработчик».
Минимальный sanity-check перед выдачей
Эти проверки — последний фильтр, дублирующий часть exit-условий фаз специально. Exit-условия блокируют переход между фазами, sanity-check блокирует выдачу финального markdown'а пользователю. Дубль намеренный.
- [ ] Введение читается человеком без знания кодовой базы?
- [ ] Алгоритм описан без упоминания таблиц БД и классов?
- [ ] Все названия инвариантов / переменных одинаковы во всех секциях (нет drift)?
- [ ] Permissions указаны конкретно (
permission:writeFinance= 9, не «нужны админ-права»)? - [ ] В разделе «Изменения в коде» нет фразы «нужно переписать X» без конкретики?
- [ ] Раздел «Открытые вопросы» не пустой?
- [ ] Раздел «Порядок реализации» содержит шаг «тесты»?
- [ ] Если Фаза 2 запускалась — раздел 1 ТЗ корректно отражает карточки моделей и cross-cutting инварианты?
- [ ] Если Фаза 1 нашла упрощение scope — раздел 8 это отражает в шаге 1?
- [ ] Если Фаза 1 нашла best-practice отклонения — все они закрыты явным выбором + обоснования в ТЗ?
- [ ] Ни одна модель не помечена «архитектурно недозавершена»?
- [ ] Если Фазы 1 и 2 были пропущены (по триггерам или пользовательским override) — раздел 7 всё равно не пустой?
- [ ] Активация skill'а была объявлена в первом сообщении сессии (формат «🔧 Активирован skill: tz-design ...»)? Если нет — это уже не починить, но зафиксируй для следующих сессий.
- [ ] Целевая зрелость зафиксирована в самом ТЗ (метаданные / начало раздела «Зачем нужно»)?
- [ ] ТЗ не диктует implementation choices: имена методов, способ декомпозиции сервисов, выбор cache TTL, race condition handling strategies — оставлены на разработчика (или явно обоснованы как требование уровня, скажем, performance/security)?
Если хоть один чек-бокс не закрывается — доработать перед выдачей.