# ADR-063: Allow empty quick_start with steps-only Quick Start (PR-149) ## Статус Accepted (2026-07-30) ## Контекст ADR-062 (PR-146) добавил параметры `quick_start_steps_en/ru` и условный `hasBashBlock` (`include_clone !== false || quick_start !== ""`), чтобы поддержать userscript-README с кликабельными шагами вместо bash-команды. Однако валидация в `execute()` (mode `create`) по-прежнему требовала непустой `quick_start` через falsy-чек `!v` в required-Record — пустая строка `""` считалась отсутствующей, тулза возвращала `quick_start is required for create mode`. Скилл `repo-readme` (раздел 8 «Кейс: userscript / web-app / npm-package») документирует комбинацию `include_clone: false` + `quick_start: ""` + `quick_start_steps_*` как supported — но тулза её отвергала. Дополнительно: `hasBashBlock` использовал `args.quick_start !== ""`, что для `undefined` давало `true` (undefined !== ""), и bash-блок рендерил literal `undefined` в теле code-fence. ADR-062 явно отметил в «Альтернативах», что ослабление required-чек — отдельное решение вне scope того PR. ## Решение 1. **`CreateArgs.quick_start`** — сделан optional (`quick_start?: string`), чтобы отражать реальную опциональность параметра. 2. **Required-валидация в `execute()`** — `quick_start` убран из required-Record. Вместо него добавлен guard после общих required-чеков: - `hasBash = include_clone !== false || (quick_start ?? "") !== ""` - `hasStepsEn = !!quick_start_steps_en && length > 0` - `hasStepsRu = !!quick_start_steps_ru && length > 0` - Если `!hasBash && !hasStepsEn` → ошибка `quick_start or quick_start_steps_en required (Quick Start EN would be empty)` - Если `!hasBash && !hasStepsRu` → аналогичная ошибка для RU. Guard гарантирует, что Quick Start секция не пуста в ОБОИХ языках. Если bash-блок рендерится — steps опциональны (backward compat). 3. **`hasBashBlock` и тела bash-блоков** — `args.quick_start ?? ""` вместо `args.quick_start`: обрабатывает `undefined` (когда параметр не передан вообще), иначе `undefined !== ""` даёт `true` и bash-блок рендерит literal `undefined`. Локальная переменная `qs = args.quick_start ?? ""` переиспользуется в обоих bash-блоках (EN/RU). 4. **Schema `.describe()`** — убрано "Required for create mode.", добавлено пояснение: параметр optional, пустая строка/absent допустимы когда есть `quick_start_steps_*`, bash-блок опускается при пустом AND `include_clone=false`. 5. **`validateReadme`** — без изменений: проверяет наличие строк "Quick Start" / "Быстрый старт" в заголовках (`### ⚡ Quick Start` / `### ⚡ Быстрый старт`), которые рендерятся всегда. README без bash-блока (только steps) проходит валидацию. Подтверждено smoke-тестом (сценарий 1). 6. **Backward compatibility** — все существующие вызовы с непустым `quick_start` и без steps работают идентично (сценарий 2 smoke-теста: git clone + pip install, без шагов, без `undefined`). ## Альтернативы - **Сделать `quick_start` required только когда нет steps** — отвергнуто: сложная условная required-логика в одном Record, тяжело читать. Cleaner — убрать из required и добавить явный guard с понятными сообщениями ошибок для каждого языка отдельно. - **Один общий guard «есть bash ИЛИ (steps EN И steps RU)»** — отвергнуто: это допустило бы пустую RU-секцию когда есть bash + steps EN (но это backward-compat кейс, где bash рендерится в обеих секциях). Текущий guard (`!hasBash && !hasStepsX`) срабатывает ТОЛЬКО когда bash-блока нет — тогда steps нужны в обоих языках. Когда bash есть — steps опциональны. - **Валидировать steps в `validateReadme`** — отвергнуто: validate проверяет структуру delimiter-пар и наличие секций, не содержимое Quick Start. Заголовки рендерятся всегда; проверять пустоту секции — responsibility `execute()`, не `validateReadme`. - **Не вводить `qs` локальную переменную** — отвергнуто: повторение `args.quick_start ?? ""` в трёх местах (hasBashBlock + 2 bash-блока) хуже для читаемости, чем одна переменная.