# ADR-064: Bilingual tagline and repo_name validation (PR-151) ## Статус Accepted (2026-07-30) ## Контекст ADR-062 (PR-146) и ADR-063 (PR-149) эволюционировали тулзу `create-readme` вокруг Quick Start. Параметр `tagline` оставался единым английским теглайном с момента ADR-058 (PR-116, README standard v2). Витрина **slaid098.dev** парсит README через delimiter-теги (summary/features), но tagline рендерился вне delimiterов — парсер не мог его надёжно извлечь, и RU tagline отсутствовал вообще. Дополнительно: `repo_name` принимал любой строки (uppercase, underscores, пробелы) — генерировал `git clone` ссылки вида `https://github.com/slaid098/MyRepo.git` (валидные, но не matching actual repo slug); `tagline_en` никто не проверял на отсутствие кириллицы, а `tagline_ru` не существовало. Issue #150 требует: (A) билингвальный tagline EN+RU с delimiter-тегами, (B) валидация английского `repo_name` (lowercase kebab-case) и `tagline_en` (no Cyrillic), `tagline_ru` (require Cyrillic). ## Решение 1. **`CreateArgs` type** — `tagline: string` переименован в `tagline_en: string` + `tagline_ru: string` (оба required, без `?`). Старый параметр удалён (breaking). 2. **Рендер top-блока** — tagline обёрнут в delimiter-пары: ``` # 🚀 {repo_name} > {tagline_en} > {tagline_ru} [English](#-english) | [Русский](#-русский) ``` EN-пара идёт первой, затем RU-пара, подряд без пустых строк между ними; пустая строка перед language switcher. Spacing критичен для парсера. 3. **Content-валидация в `execute()`** — после presence-чеков (required Record, falsy `!v`), ДО Quick Start guard (PR #149), добавлены: - `repo_name`: `^[a-z0-9]+(-[a-z0-9]+)*$` — lowercase kebab-case, только `a-z`/`0-9`, одиночные дефисы (не leading/trailing/consecutive). - `tagline_en`: `/[ЁА-яё]/` reject — если есть кириллица → ошибка. - `tagline_ru`: `/[ЁА-яё]/` require — если нет кириллицы → ошибка (ловит копию английского tagline). Порядок: presence → content (regex) → Quick Start guard. 4. **`validateReadme`** — добавлено 4 delimiter'а в массив (`tagline-en/ru start/end`, итого 12), +2 пары в `pairs` (EN/RU tagline, с empty-content check), +check H1 prefix `# 🚀 ` (substring). repo_name regex в validate НЕ добавлен — legacy README с uppercase repo_name не должны ломаться (валидируется только в create mode). 5. **Schema** — `tagline` переименован в `tagline_en`, обновлён `.describe()` ("Must not contain Cyrillic"); добавлен `tagline_ru` (".describe": "Must contain Cyrillic"). Оба `.optional()` (required-логика в `execute()`). 6. **SKILL.md** — раздел 4 (delimiters): +tagline-en/ru; раздел 5 (шаблон): top-блок с delimiter-тегами; раздел 5 (validate): "6 пар EN/RU разделителей (tagline + summary + features)" + H1 prefix; раздел 7 (параметры): `tagline_en`/`tagline_ru` с правилами, `repo_name` с regex; раздел 8 (пример): `tagline_en`/`tagline_ru`; новый раздел 9 "Breaking change: tagline → tagline_en + tagline_ru" с инструкцией миграции. 7. **Backward compatibility** — BREAKING: `tagline` удалён, старые вызовы падают с `❌ tagline_en is required for create mode`. Существующие README (без tagline delimiter-тегов) станут invalid при `validate` — `Missing delimiter` и тег. Регенерация README отдельный шаг после merge. ## Альтернативы - **Оставить `tagline` как alias к `tagline_en`** — отвергнуто: молчаливый дуализм (то `tagline`, то `tagline_en`) запутывает пользователей и парсер. Явный breaking с понятным сообщением `❌ tagline_en is required` лучше для миграции (одна правка вызова, а не поиск «почему RU tagline пустой»). - **Один `tagline` + авто-перевод** — отвергнуто: перевод tagline — не responsibility тулзы, качество перевода критично для карточки slaid098.dev. Явный `tagline_ru` с require-Cyrillic-чеком гарантирует осмысленный русский. - **Валидировать `repo_name` в `validateReadme`** — отвергнуто: legacy README с uppercase repo_name (например, старые репо до стандарта) не должны ломаться при `validate`. Regex только в `create` (новые README генерируются по стандарту). `validate` проверяет структуру (delimiterы, заголовки), не контент repo_name. - **Строгий H1 check (regex на полный `# 🚀 {repo_name}`)** — отвергнуто: `validate` не знает `repo_name` (работает с произвольным README). Substring-чек `# 🚀 ` ловит отсутствие префикса, не валидирует что после него. Достаточно для regression-детекции. - **Три отдельных tagline-чек (presence + regex EN + regex RU) как один guard** — отвергнуто: три независимых `if return` с разными сообщениями читаемее, чем комбинированный guard. Пользователь видит конкретную ошибку (repo_name / tagline_en / tagline_ru), а не «одна из трёх валидаций не прошла».