# Лінтувати специфікації в CI лінтером специфікацій

Canonical: https://specscore.md/uk/articles/lint-specs-in-ci/

Оновлено: 4 листопада 2026

Лінтер специфікацій — це програма, яка перевіряє специфікацію на структурні помилки і завершується кодом збою, коли їх знаходить. [Безперервна інтеграція](https://specscore.md/uk/validators/) (CI, continuous integration) — автоматична перевірка кожної запропонованої зміни. Безперервна інтеграція і безперервна доставка (CI/CD, continuous integration and continuous delivery) — це пайплайн, який виконує цю перевірку і зберігає зміну, що пройшла, готовою до випуску. [Розробка за специфікаціями](https://specscore.md/uk/spec-driven-development/) (SDD, spec-driven development) — практика писати специфікацію до коду і вважати специфікацію джерелом правди. Документ вимог до продукту (PRD, product requirements document) — проза, яка називає проблему і межі. У [SpecScore](https://specscore.md/) вимога (REQ) — іменоване правило всередині функції, а критерій приймання (AC, acceptance criterion) — необов’язкова абстрактна умова, яка вказує на одне або кілька таких правил. Перевірка — команда [інтерфейсу командного рядка](https://specscore.md/uk/cli/) (CLI, command-line interface), `specscore spec lint`, з CLI в [specscore/specscore-cli](https://github.com/specscore/specscore-cli) ([Apache-2.0](https://github.com/specscore/specscore-cli/blob/main/LICENSE)). [Easy Approach to Requirements Syntax](https://specscore.md/uk/articles/ears-requirements/) (EARS) — шаблон речення для вимоги. Цей лінтер перевіряє заголовки, обов’язкові розділи і посилання. Він не оцінює англійську.

## Що означає лінтувати специфікацію

Лінтувати специфікацію — перевірка того самого роду, що й лінтування коду. Детермінована програма читає файли і повідомляє про порушення правил. Вона не вирішує, чи продукт — добра ідея, і не переписує вимогу кращою прозою. [Сторінка валідаторів](https://specscore.md/uk/validators/) відокремлює цю структурну перевірку від ручної перевірки ШІ. `specscore spec lint` — це структурна перевірка.

Опис команди в [internal/cli/spec.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/internal/cli/spec.go) на тегу CLI v0.55.1 і на тегу v0.39.1, який встановлює воркфлоу цього репозиторію, каже, що вона перевіряє дерево специфікацій на порушення структурних конвенцій. Чистий запуск друкує `0 violations found` і завершується з кодом 0. Запуск, який знаходить порушення, друкує один рядок на кожне зауваження і завершується з кодом 1. Цей код виходу і валить job CI. Неправильні аргументи завершуються з кодом 2. Відсутність `specscore.yaml` завершується з кодом 3, і повідомлення велить виконати `specscore init`.

## Що перевіряє лінтер специфікацій

Правила належать CLI, а не окремому хмарному сервісу. Згенерований каталог [docs/lint-rules.md](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md) на тегу v0.55.1 перелічує 183 правила. Воркфлоу цього сайту встановлює v0.39.1, раніший випуск, тож правило, яке є лише в пізнішому тегу, — не те, що виконує цей job. Правила, названі в цьому розділі, є в обох тегах. `--severity` за замовчуванням — `error`. Попередження друкується, лише якщо передати `--severity warning` або `info`, і команда за замовчуванням через попередження не падає. Каталог позначає `dogfood-version-bump` як попередження, тому команда за замовчуванням не падає, коли закріплена у воркфлоу версія відстає від бінарника.

### Обов’язкові файли і розділи

Правило `readme-exists` ([readme_exists.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)) вимагає `README.md` у кожному каталозі специфікації. Правило `oq-section` ([oq_section.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)) вимагає, щоб README функції містив розділ `## Open Questions`. Успадкований заголовок `## Outstanding Questions` — окреме зауваження, і `--fix` переписує цей заголовок на місці. Повідомлення в прикладі нижче, «Open Questions section not found», — зауваження з README функції, з якого розділ прибрали.

### Рядки індексу і дочірні каталоги

Правило `index-entries` ([index_entries.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)) звіряє індекс функцій із дочірніми каталогами на диску. Дочірній каталог, якого немає в списку, — порушення, і рядок, чиє посилання вказує на відсутній дочірній каталог, — теж порушення. `--fix` може видалити фантомний рядок і вставити той, якого бракує. Це цілісність каталогів і індексу. Це не обхід кожного URL у прозі.

### Форма заголовка критеріїв приймання

Правило `ac-heading-format` ([ac_heading.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)) застосовується до README функції, файлу, чий заголовок — `# Feature:`. Рядок, який виглядає як заголовок критерію приймання, має бути точно `### AC: <id>` з одним пробілом після двокрапки та id у kebab-case. Заголовок вигляду `### AC: <id> (verifies ...)` теж приймається. `--fix` лагодить лише пробіли. Id з великими літерами або підкресленнями повідомляється і лишається людині. Правило не вимагає рядка `**Requirements:**`, не оцінює слова на кшталт «graceful» або «fast» і не попереджає, коли проза містить Given, When або Then. Як написати сам критерій — у статті [як писати критерії приймання](https://specscore.md/uk/articles/acceptance-criteria/).

### Посилання плану на ці ідентифікатори

У плані, який називає функцію-джерело, [plan_rules.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go) читає заголовки `### AC:` у README цієї функції. Правило `P-002` повідомляє значення `**Verifies:**` завдання, яке не зводиться до `<feature-slug>#ac:<ac-slug>` для одного з цих заголовків, порожній рядок `**Verifies:**`, відсутній або нерозпізнаний рядок джерела, або функцію-джерело, яка не зводиться до README функції. Правило `P-001` повідомляє заголовок, який не покриває жодне завдання і який не перелічено під `## Deferred AC Coverage`. Плани з джерелом-ідеєю (`**Source:** idea:<slug>`) і плани з `**Source:** none` звільнені, і так само звільнений план у термінальному статусі диспозиції. Однорядковий текст каталогу для `P-002` каже «valid dependency references»; перевіряючий код у цьому файлі — щойно описана перевірка посилань на AC.

### Чим успішний lint не є

Та сама команда не вирішує, чи вимога закриває названу проблему, чи ім’я має сенс і чи дві функції суперечать одна одній за змістом. Сторінка валідаторів відносить це за межі лінтера CLI. Вона також не перевіряє ключові слова кроків сценарію. `specscore rehearse` виконує файли сценаріїв. Воркфлоу цього репозиторію виконує `specscore spec lint` і не викликає rehearse. Каталог називає подальші родини — ідеї, рішення, сутності, властивості, уроки, issues і решту правил планів — і кожне правило застосовується до файлів, які йому відповідають. Каталог і є список. Ця сторінка не повторює всі 183 описи.

## Запуск specscore spec lint у CI

Команда шукає `specscore.yaml` вгору від робочого каталогу. Без цього файлу вона завершується з кодом 3 і називає `specscore init`. Job CI тому потрібен файл конфігурації в checkout. [scripts/install.sh](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh) читає `SPECSCORE_VERSION` і, якщо змінну не задано, бере `latest`. Зафіксуйте тег, якщо хочете ті самі правила на кожному запуску.

Перевірка цього репозиторію — [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml). Він встановлює CLI з `SPECSCORE_VERSION`, рівним `v0.39.1`, і потім виконує `specscore spec lint` без додаткових флагів, на pull requests і на push до main. GitHub Actions позначає крок як неуспішний, коли процес завершується ненульовим кодом. Уривок нижче зберігає ці кроки встановлення і lint. Файл також задає `permissions: contents: read`, групу конкурентності і коментар про те, чому закріплення — не `latest`.

### Кроки встановлення і lint з dogfood.yml

```yaml
name: Dogfood lint

on:
  push:
    branches: [main]
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
      - name: Install specscore CLI (pinned)
        env:
          SPECSCORE_VERSION: v0.39.1
        run: |
          curl -fsSL https://specscore.md/install/get-cli | \
            SPECSCORE_INSTALL_DIR="$HOME/.local/bin" sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
          specscore --version
      - name: Lint spec tree
        run: specscore spec lint
```

### Звіт про помилку (specscore 0.55.0, та сама форма рядка у v0.39.1)

```text
features/apply-discount/README.md:0 [error] oq-section: Open Questions section not found
features/apply-discount/README.md:0 [error] index-entries: Child directory not listed in index: refunds
features/apply-discount/refunds:0 [error] readme-exists: README.md not found

3 violations found (3 errors)
```

### Чистий звіт

```text
0 violations found
```

Кожне зауваження — це `file:line [severity] rule: message`. Підсумок — це `N violations found` плюс лічба в дужках, наприклад `(3 errors)`. Код виходу — це статус процесу, а не рядок звіту. Три рядки вище знято зі specscore 0.55.0 на функції, з якої прибрали розділ Open Questions і чий індекс пропускав порожній дочірній каталог. Це той самий звіт, який показує сторінка CLI. `--format` приймає `text` (типово), `json` або `yaml`. `--rules` і `--ignore` вибирають правила і не поєднуються. `--fix` переписує зауваження, у яких є виправник, включно із заголовком Outstanding Questions. Job dogfood не передає `--fix`.

## Інструменти, які не лінтують цей формат у CI

Перевірка якості вимог у цій CLI — це структурна перевірка вище. Це не оцінка прози. Інші інструменти розробки за специфікаціями публікують інші перевірки. Абзаци нижче використовують лише те, що кажуть власні сторінки цих проєктів. [Огляд інструментів](https://specscore.md/uk/spec-driven-development/tools/) записує ті самі сторінки як прочитані 30 жовтня 2026 року, крім домашньої сторінки документації Spec Kit, яка друкує 28 вересня 2026 року, і сторінки специфікацій функцій Kiro, яка друкує 4 серпня 2026 року.

[GitHub Spec Kit](https://github.github.io/spec-kit/) — це воркфлоу агента, який пише артефакти Markdown. [Довідник агентного SDD](https://github.github.io/spec-kit/reference/agentic-sdd.html) описує `/speckit.analyze` як звіт про неузгодженості між специфікацією, планом і завданнями, без редагування файлів. Його запускають в агенті. Домашня сторінка документації також називає розширення спільноти, включно з одним на ім’я CI Guard, які додають ворота відповідності. Це не команда, яка лінтує README функції SpecScore.

[OpenSpec](https://github.com/Fission-AI/OpenSpec) структурну перевірку таки публікує. `openspec validate`, описаний у [довіднику CLI](https://openspec.dev/docs/cli), перевіряє структуру зміни і специфікації OpenSpec, завершується ненульовим кодом, коли перевірка не минає, і довідник містить фрагмент shell, який може виконати job CI. Ця перевірка — форма OpenSpec, а не заголовки `### AC:` і не індекс SpecScore.

[Сторінка специфікацій функцій Kiro](https://kiro.dev/docs/specs/feature-specs/) описує Analyze Requirements як перевірку всередині Kiro, до проєкту, яка шукає неузгодженості, неоднозначність, конфліктні обмеження і прогалини. Це не команда в `dogfood.yml`. Шаблони речень, які пише Kiro, — у статті [синтаксис вимог EARS](https://specscore.md/uk/articles/ears-requirements/).

README [BMAD Method](https://github.com/bmad-code-org/BMAD-METHOD) описує артефакти методу і воркфлоу агентів. Він не документує команду, яка лінтує фіксовану схему специфікації в CI. README [Task Master](https://github.com/eyaltoledano/claude-task-master) описує розбір PRD на завдання командою `task-master parse-prd`. Він не описує лінтер для цього PRD. PRD і далі може бути входом функції SpecScore, і `specscore spec lint` — це те, що потім перевіряє файл функції.

## Питання й відповіді

### Що таке лінтер специфікацій?

Лінтер специфікацій читає файли специфікації і повідомляє про структурні порушення. `specscore spec lint` — ця команда для дерева SpecScore. Вона завершується з кодом 0, коли нічого не знаходить на обраній серйозності, і з кодом 1, коли знаходить порушення.

### Чи оцінює лінтер якість вимог за формулюванням?

Ні. `ac-heading-format` перевіряє заголовок `### AC:`. Він не оцінює слова на кшталт «graceful» або «fast» і не попереджає, коли критерій містить Given, When або Then. Формулювання — це робота з текстом. Сторінка валідаторів відокремлює цей детермінований lint від ручної перевірки ШІ.

### Як лінтувати специфікації в CI?

Встановіть CLI з `SPECSCORE_VERSION`, закріпленим на тегу випуску, і виконайте `specscore spec lint`. У checkout потрібен `specscore.yaml`. [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml) — робочий приклад GitHub Actions. Він закріплює v0.39.1.

### Що друкує неуспішний запуск?

Один рядок на зауваження, `file:line [severity] rule: message`, потім підсумок на кшталт `3 violations found (3 errors)`. Процес завершується з кодом 1. Чисте дерево друкує `0 violations found` і завершується з кодом 0.

### Чи перевіряють інші інструменти специфікації в CI/CD?

Команда OpenSpec `openspec validate` може звалити job CI, і вона перевіряє власну структуру зміни OpenSpec. `/speckit.analyze` Spec Kit виконується в сесії агента. Analyze Requirements у Kiro виконується всередині Kiro. README BMAD Method і Task Master не документують лінтер формату для CI. Воркфлоу dogfood у SpecScore виконує `specscore spec lint` по дереву SpecScore.

## Джерела

Поведінку CLI перевірено 4 листопада 2026 року за тегами v0.55.1 і v0.39.1 specscore-cli. Сторінки конкурентів — ті, що пов’язані нижче; огляд інструментів записує їх як прочитані 30 жовтня 2026 року, крім сторінок, які друкують власну дату.

- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore-cli — ліцензія Apache-2.0](https://github.com/specscore/specscore-cli/blob/main/LICENSE)
- [specscore/specscore](https://github.com/specscore/specscore)
- [specscore-cli v0.55.1 — каталог правил lint (183 правила)](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md)
- [specscore/specscore — dogfood.yml (CLI v0.39.1)](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)
- [specscore-cli — install.sh (SPECSCORE_VERSION)](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh)
- [specscore-cli v0.55.1 — readme-exists](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)
- [specscore-cli v0.55.1 — oq-section](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)
- [specscore-cli v0.55.1 — index-entries](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)
- [specscore-cli v0.55.1 — ac-heading-format](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)
- [specscore-cli v0.55.1 — правила плану P-001 і P-002](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go)
- [Що перевіряє SpecScore](https://specscore.md/uk/validators/)
- [Як писати критерії приймання, які перевірить ШІ-агент](https://specscore.md/uk/articles/acceptance-criteria/)
- [Синтаксис вимог EARS з поясненням і прикладами](https://specscore.md/uk/articles/ears-requirements/)
- [Документація GitHub Spec Kit (дата сторінки 28 вересня 2026)](https://github.github.io/spec-kit/)
- [GitHub Spec Kit — довідник агентного SDD (/speckit.analyze)](https://github.github.io/spec-kit/reference/agentic-sdd.html)
- [Довідник CLI OpenSpec — openspec validate](https://openspec.dev/docs/cli)
- [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec)
- [Kiro — специфікації функцій (оновлено 4 серпня 2026)](https://kiro.dev/docs/specs/feature-specs/)
- [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD)
- [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master)
- [Інструменти розробки за специфікаціями](https://specscore.md/uk/spec-driven-development/tools/)

## Пов’язане

- [Розробка за специфікаціями з Claude Code і Cursor](https://specscore.md/uk/articles/claude-code-specs/)
- [Шаблон PRD у Markdown для програмування зі ШІ](https://specscore.md/uk/articles/feature-spec-template/)
- [Як писати критерії приймання, які перевірить ШІ-агент](https://specscore.md/uk/articles/acceptance-criteria/)
- [Синтаксис вимог EARS з поясненням і прикладами](https://specscore.md/uk/articles/ears-requirements/)
- [Що перевіряє SpecScore](https://specscore.md/uk/validators/)
- [CLI](https://specscore.md/uk/cli/)
- [Встановити CLI](https://specscore.md/uk/cli/install/)
- [Розробка за специфікаціями](https://specscore.md/uk/spec-driven-development/)
- [Інструменти розробки за специфікаціями](https://specscore.md/uk/spec-driven-development/tools/)
- [Специфікація функції](https://specscore.md/feature-specification)
- [Специфікація критеріїв приймання](https://specscore.md/acceptance-criteria-specification)
