From 556a5b57eb44c10e1c94ca73e2a65b3355742b3d Mon Sep 17 00:00:00 2001 From: Sergey <93754860+slaid098@users.noreply.github.com> Date: Thu, 30 Jul 2026 19:57:46 +0300 Subject: [PATCH] fix(create-readme): validate EN switcher anchor symmetrically (#155) * fix(create-readme): validate EN switcher anchor symmetrically * docs(handoff): add handoff and ADR for switcher validation * docs(handoff): set PR number --------- Co-authored-by: opencode-agent --- .opencode/tools/create-readme.ts | 8 +++----- .../066-pr-155-validate-switcher-anchor.md | 13 +++++++++++++ .../pr-155-validate-switcher-anchor.md | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 docs/decisions/066-pr-155-validate-switcher-anchor.md create mode 100644 docs/handoff/pr-155-validate-switcher-anchor.md diff --git a/.opencode/tools/create-readme.ts b/.opencode/tools/create-readme.ts index a0b0d70..13d627d 100644 --- a/.opencode/tools/create-readme.ts +++ b/.opencode/tools/create-readme.ts @@ -133,7 +133,7 @@ ${bashBlockRu}${stepsRu}${accessLineRu}${developmentBlockRu} ` } -function validateReadme(content: string): { ok: boolean; issues: string[] } { +export function validateReadme(content: string): { ok: boolean; issues: string[] } { const issues: string[] = [] const delimiters = [ @@ -179,10 +179,8 @@ function validateReadme(content: string): { ok: boolean; issues: string[] } { issues.push("Missing 'Quick Start' section (English)") if (!content.includes("Быстрый старт")) issues.push("Missing 'Быстрый старт' section (Russian)") - if (!content.includes("[English]")) - issues.push("Missing [English] language switcher link") - if (!content.includes("[Русский]")) - issues.push("Missing [Русский] language switcher link") + if (!content.includes("[English](#-english)")) + issues.push("Missing or wrong [English](#-english) switcher link (should be #-english)") if (!content.includes("## 🇷🇺 Русский")) issues.push("Missing '## 🇷🇺 Русский' header (should be 'Русский', not 'Русская версия')") if (!content.includes("## 🇺🇸 English")) diff --git a/docs/decisions/066-pr-155-validate-switcher-anchor.md b/docs/decisions/066-pr-155-validate-switcher-anchor.md new file mode 100644 index 0000000..baa6492 --- /dev/null +++ b/docs/decisions/066-pr-155-validate-switcher-anchor.md @@ -0,0 +1,13 @@ +# ADR-066: Symmetric switcher anchor validation + +## Статус +Accepted (2026-07-30) + +## Контекст +`validateReadme` в `.opencode/tools/create-readme.ts` проверяла language switcher асимметрично: RU-переключатель проверялся строгим full-anchor чеком `[Русский](#-русский)`, а EN — только подстрокой `[English]` без проверки anchor. Template рендерит switcher симметрично: `[English](#-english) | [Русский](#-русский)`, но валидация не зеркалировала это. + +## Решение +Убрать 2 избыточных substring-чека и заменить на 2 строгих симметричных full-anchor чека: `[English](#-english)` и `[Русский](#-русский)`. Substring-чеки были избыточны — строгий чек субсумирует их (`[English](#-english)` содержит `[English]`). + +## Альтернативы +Оставить асимметрию и добавить отдельный regex-чек для EN anchor — отвергнуто как избыточное усложнение. Простой `includes()` достаточен и зеркалирует существующий RU-чек. diff --git a/docs/handoff/pr-155-validate-switcher-anchor.md b/docs/handoff/pr-155-validate-switcher-anchor.md new file mode 100644 index 0000000..3430fc4 --- /dev/null +++ b/docs/handoff/pr-155-validate-switcher-anchor.md @@ -0,0 +1,19 @@ +--- +pr: 155 +title: Symmetric EN/RU switcher anchor validation in validateReadme +--- + +## Что сделано +- Удалены 2 избыточных substring-чека (`[English]` и `[Русский]` как подстроки) — они субсумируются строгими full-anchor чеками. +- Добавлен строгий full-anchor чек для EN: `[English](#-english)` (зеркало существующего RU-чека `[Русский](#-русский)`). +- Добавлен `export` к функции `validateReadme` для возможности импорта в тестах. +- Smoke-тест: 8/8 edge cases passed (валидный switcher, битые EN/RU anchors, отсутствие anchor, битые ссылки, не-markdown текст). + +## Почему +Валидация language switcher была асимметричной: RU проверялся строго (полный anchor `[Русский](#-русский)`), а EN — только подстрокой `[English]` без проверки anchor. 4 класса дефектов EN-switcher пропускались: битый anchor, отсутствие anchor, битая ссылка, не-markdown-ссылка. + +## Pending +— + +## Watch out +Функция `validateReadme` теперь экспортируется — это публичный API. Ранее была module-private.