Бесплатный интерактивный курс · aicoding.space
Страница решений: как объяснить владельцу и получить ответ
Практический курс по @dzhechkov/skills-decision-mockups для инженера, который устал получать «делай как считаешь нужным». Вместе с Ритой ты разберёшь, зачем нужна страница решений, научишься отбраковывать мнимые развилки, писать аналогию раньше термина, называть цену каждого варианта, прогонять страницу через блокирующие ворота check_page.py и доставлять её так, чтобы ответ владельца вернулся в работу текстом, понятным в свежем чате.
Содержание курса
1. Зачем нужна страница решений
Что делает decision-mockups и почему это не «красивый отчёт».
Ключевая мысль: страница решений объясняет положение дел владельцу без инженерного контекста
Рита — тимлид, и третий раз за месяц владелец продукта отвечает ей одинаково: «делай как считаешь нужным». Не потому что ему всё равно. Просто её письмо читается как разбор поломки двигателя для человека, который просто водит машину.
decision-mockups — скилл, который превращает такое письмо в одну самодостаточную HTML-страницу. Страница решений объясняет положение дел владельцу без инженерного контекста: что сделано, какая от этого польза, чем мы рискуем. А если выбор действительно есть — собирает его: развилки кликаются, выбор сохраняется, кнопка «Скопировать ответы» отдаёт текст, который владелец вставляет обратно в чат.
Ставится одной строкой: npx @dzhechkov/skills-decision-mockups — или dz install @dzhechkov/skills-decision-mockups. Пакет живёт на npm, а исходники, шаблон и все справочники — на GitHub.
И сразу неожиданность, из-за которой скилл однажды не включился: развилок может быть ноль. Страница «что сделано → какая польза → какие риски», без единого выбора, — это тоже он.
Три вещи, которые отличают её от обычного письма: она написана словами адресата, она показывает разницу глазами там, где разница видна на экране, и она принимает ответ, а не только просит его.
Компромисс: ты платишь примерно часом работы и дисциплиной чужого словаря, а получаешь подписанное решение вместо «делай как знаешь».
2. Когда применять — и когда не надо
Порога по числу развилок нет: повод — непонимание адресата.
Ключевая мысль: порога по числу развилок нет: повод в непонимании адресата
Рита однажды не применила этот скилл — и зря. В запросе было две развилки, а старое описание требовало «пять и больше», поэтому страницу собрали руками за вечер. Отказ был не в отсутствии инструмента, а в подборе: инструмент лежал рядом и не включился.
Поэтому правило теперь звучит без оговорок: порога по числу развилок нет. Ни «5+», ни «2+», ни «хотя бы одна». Повод — непонимание адресата, а не счёт развилок.
Берись за страницу, когда:
- владелец прямо просит объяснить по-человечески — этого достаточно самого по себе;
- руководитель выбирает между настоящими альтернативами, и цена выбора не видна из кода;
- итог ревью или разбора нужно донести до того, кто не читает изменения в коде;
- разница видна на экране, и пара картинок «как сейчас / после починки» короче трёх абзацев;
- решения расползлись по темам, и их надо собрать одним заходом, а не перепиской на неделю.
И честно не берись, когда собеседник — инженер и ему хватит списка задач; когда решение требует уточняющего разговора (сначала разговор, страница потом); когда объяснять нечего, потому что адресат уже держит картину в голове; когда данные чувствительные или страница выдавала бы себя за чужую систему.
Компромисс: широкий повод означает, что страницу иногда сделают там, где хватило бы двух абзацев. Это дешевле обратной ошибки: непонятое решение возвращается переделкой.
3. Мнимая развилка — и почему она дороже всего
Проверка живости обеих веток: то, что отличает скилл от «сделай красивый отчёт».
Ключевая мысль: мнимая развилка удаляется, а не показывается
Рита выписала четыре развилки — по одной на каждую находку, как в шаблоне. Владелец дошёл до второй и спросил: «А второй вариант тут кто-нибудь вообще согласится делать?» Никто. Так выглядит мнимая развилка.
> «Развилка с одним вариантом — мнимая. Это не выбор, а уже принятое решение, которому пририсовали кнопку.»
Перед тем как что-то рисовать, каждое место выбора проверяют одним вопросом: живы ли обе ветки? Ветка, которая хуже по всем осям, дороже без выигрыша или на которую никто не подпишется, — не выбор. Мнимая развилка удаляется, а не показывается, и удаление называется вслух: владелец должен знать, о чём его не спросили.
Именно это отличает скилл от обычной просьбы «сделай красивый отчёт». Обычная просьба улучшает внешность. Здесь обманчивое взаимодействие падает механически: ворота не пропускают группу с одним вариантом, и страница просто не публикуется.
Цена мнимой развилки не в потраченной минуте. Читатель, один раз обнаруживший, что его спросили о несуществующем выборе, начинает подозревать всю страницу — включая те развилки, которые настоящие.
Отдельный случай: тебя прямо просят «сделай развилку на каждый пункт», а в одном пункте выбора нет. Просьба выполняется не буквально, и об этом пишут прямым текстом — иначе человек останется в уверенности, что его о чём-то спросят.
Компромисс: отбраковка стоит спора с заказчиком страницы и иногда выглядит как неисполнительность. Взамен ты платишь вниманием читателя только за настоящие вопросы.
4. Три вопроса карточки находки
Жёсткая форма карточки: что не так → чем грозит → как чиним.
Ключевая мысль: карточка находки отвечает ровно на три вопроса в одном порядке
Рита пишет находку и уже к третьему абзацу рассказывает историю расследования: как заметили, куда полезли, что оказалось не тем. История честная и совершенно бесполезная — владельцу нужно решение, а не детектив.
Поэтому у карточки жёсткая форма. Карточка находки отвечает ровно на три вопроса, и всегда в одном порядке:
- Что не так — что именно сломано, простыми словами и с одной бытовой картинкой.
- Чем грозит — последствие в единицах адресата: не «запрос на каждую запись», а «три тысячи походов вместо тридцати одного» и «разница между „успели за ночь“ и „каждое утро урезанный отчёт“».
- Как чиним — что делаем, сколько это стоит и что придётся переписать.
Ни больше, ни меньше. Четвёртая строка «как мы это нашли» — материал для команды. А пустая строка хуже отсутствующей: она выглядит как ответ и молча отнимает у читателя вопрос.
Порядок тоже не декоративный. «Чем грозит» до «что не так» звучит как запугивание; «как чиним» первым превращает карточку в наряд на работы, где непонятно, за что платим.
Компромисс: три строки иногда тесны для сложной находки, и хочется дописать четвёртую. Взамен читатель после десятой карточки всё ещё понимает, что читает, — а это и есть цель.
5. Аналогия раньше термина
Главное правило языка страницы: сначала бытовая картинка, потом слово.
Ключевая мысль: бытовая аналогия вводится раньше термина, одна на понятие
Рита говорит «сборщик берёт задачу в аренду на двадцать минут» и видит, как владелец кивает. Кивок не значит ничего: он не спросит, что такое сборщик, он просто согласится со всем подряд — и решение станет формальным. Это худший исход, хуже прямого «не понял».
Отсюда главное правило языка: бытовая аналогия вводится раньше термина, и на одно понятие она ровно одна. Сначала картинка — «берёт задачу в аренду на двадцать минут, как бронь переговорки: пока бронь активна, комната твоя, не продлил — отдают другому», — и только потом, если правда нужно, само слово.
«Одна на понятие» означает: ввёл ленту досмотра — дальше по тексту останавливается лента, а не «падает задача». Две метафоры об одном предмете читатель складывает в кашу и перестаёт различать, где что.
Последствие тоже переводится в единицы адресата. Не «сборка недетерминирована», а «две сборки одного и того же кода в разные дни ведут себя по-разному — классическое „вчера работало“».
Внутренние имена — номер задачи, имя файла, partial — допустимы только в скобках и только после объяснения: «публикуется урезанный отчёт (в коде это называется partial)».
Компромисс: аналогия всегда чуть-чуть врёт — она упрощает механику. Взамен читатель принимает решение осознанно, а неточность правится одной уточняющей фразой.
6. Цена варианта и честная рекомендация
Слово «рекомендуем» ценой не является — и почему у рекомендации три обязательные части.
Ключевая мысль: каждый вариант называет цену, а рекомендация — основание и когда хороша альтернатива
Рита показала два варианта: «A — переписать обработчик, рекомендуем» и «B — оставить как есть». Владелец выбрал A и через неделю узнал, что за этим стояли двадцать шесть существующих проверок в четырёх файлах, которые пришлось переписать. Формально его не обманули. Практически — выбор сделали вслепую.
Каждый вариант называет свою цену. Цена — это дни, объём переделки или явное «нового кода не требуется». Слово «рекомендуем» ценой не является: оно про наш выбор, а не про его стоимость.
И рекомендация — не галочка, а три обязательные вещи сразу:
- один вариант в группе явно помечен как рекомендованный;
- сказано почему именно он — одной фразой с основанием, а не словом «рекомендуем»;
- сказано когда хорош альтернативный — при каких приоритетах владельца выбрать его будет правильно.
Формулировка, проверенная на живом владельце, ставится строкой прямо под вариантами: «Почему A: дёшево и закрывает щель начисто, а тема стратегическая. Когда достаточно B: если хотите двигаться быстро прямо сейчас; риск невелик». Без третьего пункта страница не предлагает выбор, а продавливает один вариант — и это отлично чувствуется.
Форм развилки ровно две, и цена в них живёт по-разному: в развёрнутой она стоит в тексте самого варианта, в компактной чиповой — в строке рекомендации той же карточки вопроса. Третьей формы нет намеренно: она молча выпала бы из проверки цены, а молчаливый пропуск хуже красного.
Компромисс: честная цена иногда пугает и тормозит решение на день. Тормозит она ровно там, где иначе была бы переделка на неделю.
7. Кальки: ворота вместо внимания
Почему список слов переехал из чек-листа в блокирующую проверку.
Ключевая мысль: техническая калька ловится воротами G15, а не вниманием автора
Владелец прочитал готовую страницу и споткнулся трижды: «раны», «рантаймами», «креденшалы». Слова протекли из внутренних сводок, которые Рита пересказывала своими словами — точнее, чужими. Обиднее всего, что пункт чек-листа уже требовал их ловить. Но пункт чек-листа — это внимание, а внимание в три часа ночи заканчивается раньше текста.
Поэтому техническая калька ловится воротами G15, а не вниманием автора. Правило под этим простое: если слово существует только внутри нашего инструментария — на этой странице его нет. Транслитерация английского термина не перевод, а тот же жаргон в русской орфографии.
Ворота держат измеренный список и краснеют адресно, сразу подсказывая замену:
FAIL G15 строка 342, поз. 115: калька «раны» — скажите «запуски»
Чинится это заменой слова, и всё. Спорить можно ровно одним способом — оговоркой с причиной в комментарии на той же строке: <!-- calque: страница про ожоговое отделение, «раны» здесь буквальные -->. Оговорка без причины отклоняется и сама становится находкой: освобождение, которое нельзя объяснить, — это молчаливый список исключений.
Три слова из проверки убраны намеренно, после измерения на настоящей странице: «коммит» и «фича» срабатывали ложно (это собственный словарь владельца), а «воркер» разрешён примером в самом руководстве по языку. Новая калька добавляется одной строкой в таблицу наверху скрипта — это и есть способ научить ворота.
Компромисс: словарь всегда отстаёт от живой речи и ловит только известные слова. Зато известные он ловит всегда, а не тогда, когда автор выспался.
8. Ворота check_page.py
Сначала скрипт, потом глаза: коды возврата, около сорока пяти проверок и встроенный отрицательный контроль.
Ключевая мысль: check_page.py — блокирующие ворота: публикация при коде 1 запрещена
Рита правит страницу шестой раз и на седьмой уже не помнит, закрыла ли она тот div. Глаз этого не видит никогда; скрипт видит всегда.
check_page.py — блокирующие ворота: публикация при коде 1 запрещена. Зависимостей у него нет, только стандартная библиотека Python 3. Порядок работы — сначала скрипт, и только потом глаза:
python3 <путь-до-скилла>/references/check_page.py страница.html
Коды возврата означают разное: 0 — можно публиковать, 1 — блокирующее падение, 2 — команда набрана неправильно (нет аргумента, нет файла). Двойка — ошибка вызова, а не приговор странице: поправь команду и повтори. Путь к скрипту считается от корня скилла, а не от папки проекта, поэтому из чужой директории зови его полным путём.
Ворота ловят около сорока пяти вещей: незакрытый div, цвет мимо токена (в том числе внутри style="…"), токен, объявленный только в светлой теме, тёмный блок со скопированными светлыми значениями, любой внешний адрес, повторяющийся идентификатор развилки, развилку с одним вариантом, счётчик, вписанный руками, оставшуюся заглушку шаблона и лишнюю оболочку документа.
И самое приятное: шаблон намеренно не проходит эти ворота — в нём остались заглушки. Незаполненный скелет не должен считаться готовым к публикации, а ты одним прогоном убеждаешься, что прибор вообще различает годное и негодное. Прибор, который не может показать красное, зелёного тоже не доказывает.
Компромисс: ворота говорят только о форме — они не проверяют, правдива ли названная цена и удачна ли аналогия. Ровно поэтому рядом живёт короткий ручной список: в нём осталось только то, чего регулярное выражение не выражает.
9. Тема, токены и тёмный режим
Три блока палитры, одинаковые имена и разные значения — иначе светлое на светлом.
Ключевая мысль: полная палитра токенов объявляется в трёх темовых блоках
Рита выложила страницу, владелец открыл её вечером на телефоне — и увидел светло-серый текст на светло-сером фоне. Классика жанра, и почти всегда причина одна из двух: цвет объявили только внутри тёмного блока, либо блок скопировали и забыли поменять значения.
Поэтому правило звучит так: полная палитра токенов объявляется в трёх темовых блоках, а значения в тёмных — другие. Токен здесь — это именованная переменная цвета: компоненты читают имя, а конкретный оттенок подставляет тема.
Три блока — это:
- голый
:rootсо всей светлой палитрой; - тот же набор имён в
@media (prefers-color-scheme: dark)под защитой:root:not([data-theme="light"]); - он же ещё раз в
:root[data-theme="dark"], чтобы ручной переключатель побеждал в обе стороны.
Имена во всех трёх одинаковые, значения в тёмных — свои. Ворота проверяют это двумя разными способами: что набор имён совпадает и что значения в тёмных блоках действительно отличаются от светлых. Копия без правки значений — это и есть светлое на светлом у каждого, кто читает в тёмной теме.
Два следствия рядом. Ни один литерал цвета не пишется прямо в style="…" — это тот же цвет мимо токена, только спрятанный. И ширина: широкие блоки (ленты шагов, макеты, таблицы) живут в контейнере с горизонтальной прокруткой, а тело страницы не едет вбок никогда.
Компромисс: сорок с лишним токенов в трёх блоках выглядят избыточно для одностраничного документа. Ровно они и делают документ читаемым у второй половины читателей, которых ты не видишь.
10. Интерактив и экспорт ответов
Как выбор превращается в текст, понятный в свежем чате через два дня.
Ключевая мысль: экспорт понятен сам по себе в свежем чате
Рита получила ответы владельца через два дня — в новом окне переписки, без страницы под рукой: он прошёл развилки, нажал «Скопировать ответы» и вставил текст. Если бы там лежали только короткие пометки вроде «на общие полки», понять их было бы нельзя ни ему, ни ей.
Поэтому экспорт понятен сам по себе в свежем чате. Первая строка называет тему и дату. Дальше — по строке на решение: человеческая подпись развилки и выбранный короткий ответ. В конце — «Без ответа:» и перечень развилок, до которых читатель не дошёл. Частично заполненная страница выгружается честно: неотвеченное перечисляется, а не молча пропадает.
Механика под этим нарочно скромная. Поведение как у радиокнопок — в группе активен один вариант, — но разметка это обычные кнопки с признаком нажатия; повторный клик снимает выбор; результат сохраняется в памяти браузера под ключом, своим для каждой страницы. Общий ключ означал бы, что вторая страница решений подхватит ответы первой, и владелец увидит чужие галочки.
В липкой панели написано «Выбрано N из M», и M считается из разметки, а не вписывается руками: вписанное число расходится с реальностью на первой же правке, причём молча. В самой разметке слот счётчика стоит нулём.
Пресеты вроде «Выбрать рекомендованный (A / A)» — не второй механизм выбора: они кликают те же карточки, поэтому разойтись с панелью и с экспортом не могут. Их два-три, и один из них ровно рекомендованная комбинация: владелец, который согласен, закрывает страницу одним нажатием.
Компромисс: кнопки вместо полноценной радиогруппы — это упрощение доступности, и скилл про это говорит прямо, вместо того чтобы подразумевать обратное.
11. Сборка из шаблона и доставка
Скелет, правки по секциям, зелёный скрипт — и ссылка с пятью строками в чат.
Ключевая мысль: скелет заполняется инкрементальными правками, а доставка — это опубликованный артефакт
Рита один раз попробовала выдать страницу целиком одной большой записью в файл. Агент подвис на середине, и половину пришлось делать заново — не из-за ошибки, а из-за длины.
Скелет заполняется инкрементальными правками, а доставка — это опубликованный артефакт. Порядок такой: скопировать шаблон в целевой файл, потом править его по секциям — шапка, сводка за шестьдесят секунд, кластеры с карточками находок, макеты, вопросы, ключ хранения, тема и дата. Все заглушки обязаны исчезнуть: ворота заваливают страницу, где осталась хоть одна, и это правильно — одна такая строка обесценивает весь документ.
В файле лежит только содержимое страницы. Никаких <!doctype>, <html>, <head>, <body> — оболочку добавляет хост при публикации, он же режет внешние адреса, поэтому все стили встроены, а «скриншоты» нарисованы вёрсткой.
Несколько правил доставки, каждое из которых оплачено чьей-то ошибкой: <title> в самом файле называет вкладку; значок-эмодзи обязателен и не меняется между переизданиями, потому что владелец находит вкладку по значку; повторная публикация того же пути обновляет ту же ссылку, а другой путь заводит вторую страницу — и человек читает не ту.
И последнее: страница не доставлена, пока лежит файлом на диске. Адресат — не инженер, он не откроет HTML с диска. Вместе со ссылкой в чат уходит короткий текст из пяти пунктов: что это; что делать (пройти развилки → «Скопировать ответы» → вставить сюда); какие развилки убраны как мнимые и почему; какие находки остались без макета; чего на странице заведомо нет.
Компромисс: правки по секциям дольше и требуют дисциплины порядка. Взамен работа не теряется целиком, а каждая секция проверяется по мере готовности.
12. Честные границы скилла
Что скилл сам о себе не обещает — и почему это читают до работы, а не после.
Ключевая мысль: скилл честно называет свои границы
Рита дочитала описание до раздела, который встречается редко: автор сам перечисляет, чего его инструмент не умеет. Не в оправдание, а списком.
Скилл честно называет свои границы. Он пишет по-русски — ворота жёстко требуют русские слова экспорта («Решения по», «Без ответа», «Скопировано»), и словарь проверки цены тоже русский; английская страница потребует сначала обобщить ворота. Развилки плоские: вложенные группы сделали бы неоднозначным и подсчёт вариантов, и то, кто обрабатывает нажатие. Взаимодействие кнопочное: ведёт себя как радио, но полной семантики с переходом по стрелкам в шаблоне нет — и обещать её читателю нельзя.
Прибор тоже честен про себя. Часть проверок мягкие и только предупреждают. А проверка цены доказывает, что цена стоит на положенном месте, — но не то, что она правдива. Правдивость остаётся человеку, и короткий ручной список покрывает ровно то, чего регулярное выражение не выражает: мнимые развилки, честность формулировки «частично», качество метафоры, чтение страницы в обеих темах.
Почему такой раздел читают до работы, а не после: названная граница стоит дешевле найденной. Рита узнала про русский язык ворот из описания за минуту. Узнать то же самое от владельца, которому английская страница выдала русскую первую строку экспорта, стоило бы доверия ко всей странице.
И последнее, что стоит унести из курса целиком: страница решений выигрывает не оформлением, а честностью — отбракованной мнимой развилкой, названной ценой, признанной границей. Всё остальное — вёрстка.
Компромисс: честный список ограничений снижает первое впечатление от инструмента. Он же снимает вторую волну разочарования, которая обычно дороже.
Частые вопросы
- Обязательно ли на странице должна быть хотя бы одна развилка?
Нет. Порога нет вообще: повод — непонимание адресата. Страница «что сделано → какая польза → какие риски» без единого выбора — это тот же скилл. Ровно на выдуманном пороге он однажды и не сработал: развилок было две, страницу собрали руками.
- Скрипт красный, но я уверен, что страница хорошая. Можно опубликовать?
Нет: при коде 1 публикация запрещена, спорить с красным нельзя. Единственная законная оговорка — комментарий
calque:с причиной для проверки калек, и он освобождает ровно одну строку. Код 2 — не приговор странице, а ошибка вызова: нет аргумента или файла, поправьте команду и повторите.- Почему шаблон не проходит собственную проверку?
Это встроенный отрицательный контроль: в шаблоне остались заглушки. Незаполненный скелет не должен считаться готовым к публикации — и один прогон на шаблоне показывает, что прибор вообще различает годное и негодное.
- Владелец просит развилку по каждому пункту, а в одном пункте выбора нет.
Просьба выполняется не буквально, и об этом говорят прямым текстом. Мнимая развилка удаляется, находка остаётся полноценной карточкой из трёх строк без выбора, а в сопроводительном тексте перечисляется, какие развилки убраны и почему.
- Можно ли сделать страницу на английском?
Сейчас нет. Проверка жёстко требует русские слова экспорта («Решения по», «Без ответа», «Скопировано»), и словарь проверки цены тоже русский. Английская версия начинается с обобщения ворот, а не со страницы.
- Сколько делать макетов «до / после»?
Только там, где разница видна глазом: экран, пустое состояние, порядок блоков. Для серверной логики, настроек и сборки макет не делают. Практический потолок — пять-семь на страницу, дальше читатель перестаёт их различать, и раздел превращается в галерею.
- Что делать со словом, которого проверка калек ещё не знает?
Добавить одной строкой в таблицу наверху
check_page.py— это и есть способ научить ворота. Обратный случай тоже бывает: три слова из проверки убраны намеренно после измерения на живой странице, потому что срабатывали ложно.