Меня заставили использовать OpenSpec

За мной пришли. Ещё совсем недавно, где-то год назад, компания, в которой я работаю, начала "мотивировать" всех разработчиков использовать AI, буквально в любом виде. Затем оказалось, что просто использовать AI уже недостаточно, и всех начали "агитировать" использовать coding агентов. Но и на этом дело не закончилось: теперь меня "призывают" стать адептом SDD и начать активно использовать OpenSpec.
При этом я бы не сказал, что отношу себя к консерваторам или луддитам (так называют противников внедрения новых технологий). Я начал использовать AI ещё на этапе выхода GPT-3 (задолго до того, как его стали активно внедрять у нас). Одним из первых перешёл на программирование с помощью агентов, настраивал собственный harness и, кажется, вполне успешно справлялся с задачами.
Но если сверху решили, то сопротивляться бессмысленно.

Поэтому в статье разбираемся как встроить OpenSpec в свой любовно настроенный harness и не сломать то, что уже неплохо работало.
Про OpenSpec и SDD у меня есть отдельная статья: "Что такое OpenSpec? Полный гайд по Spec-Driven Development". Рекомендую ознакомиться с ней тоже, особенно если только начинаете разбираться в разработке по спецификациям.
Немного обо мне
Меня зовут Илья. В IT я работаю с 2008 года: начинал системным администратором, затем занимался DevOps, а позже перешёл в разработку преимущественно на Java и Kotlin. За это время участвовал в создании крупных образовательных порталов, автоматизации процессов университетов и разработке платформы для ERP-систем. Сейчас разрабатываю системы в области финансов.
AI я использую начиная с GPT-3 в браузере. Затем перешёл на GitHub Copilot с интеграцией чатов в IDE, а какое-то время пользовался JetBrains Junie. Сейчас в работе использую в основном Claude Code и Codex в OpenIDE, но иногда эксперементирую в OpenCode с GLM, MiniMax, Kimi и т.д.
Сейчас мы развиваем собственный мультиагентный AI-плагин, и поддержка Spec-Driven Development – это одно из наших приоритетных направлений.
Все примеры и скриншоты ниже сделаны в OpenIDE с нашим AI-плагином. Подробнее о плагине и самой IDE можно прочитать тут.

Мой Harness

На момент, когда ко мне пришли с OpenSpec, мой harness выглядел так: Claude Code и Codex: основные рабочие агенты, OpenCode — для экспериментов, его я иногда использую в связке с OpenRouter. Для всех трёх у меня оплачены подписки. Claude Code и Codex по $100, поэтому основными моделями у меня сейчас являются Opus XHigh и Sol High.
Для взаимодействия с агентами я не использую стандартные терминальные клиенты. Вместо них я использую OpenIDE с плагином AI for OpenIDE. Он повторяет подход Zed: подключает Claude Code, Codex и OpenCode к IDE по протоколу ACP, только делает это на любимой мной IntelliJ Platform.
Мне такой вариант удобен: между агентами можно просто переключаться, а под рукой остаётся полноценная IDE (если потребуется, можно почитать код или посмотреть diff). Плюс никуда не деваются привычные возможности IDE: можно запустить приложение или тесты, иногда подебажить/попрофилировать. Правда, последние два всё реже и реже)
Так как большинство моих приложений — Spring-приложения, во все три агента у меня установлены Spring Skills (набор skill-ов для работы в экосистеме Spring). Из общих skill-ов у меня также подключены Superpowers и grill-me. Думаю, они вам хорошо знакомы, а если нет, то ссылочки я оставил.
Во всех проектах у меня также настроены: Spotless и Checkstyle для форматирования и контроля code style, Gradle JVM Test Suite для разделения тестов на быстрые юнит-тесты и более медленные интеграционные, ArchUnit для контроля соответствия реализации заданной архитектуре, PITest для мутационного тестирования, и JaCoCo для расчёта coverage и проверки, что показатель не падает.
Кроме того, к агентам подключены различные MCP-серверы и утилиты, которые упрощают взаимодействие с внутренними системами проекта: YouTrack, TeamCity, GitLab, Confluence и так далее. Подробно останавливаться на них не будем.
Мой рабочий flow
До OpenSpec моя рабочая сессия с агентом выглядела следующим образом. На входе уже есть проработанная бизнес-аналитиком задача. Работу начинаю с проверки того, насколько подробно она описана. Если постановки хватает, сразу отдаю задачу в планирование. Если нет детализирую.
Для детализации использую skill-ы grill-me и brainstorming. На выходе получаю не просто описание задачи, а системные требования: как именно новая функциональность должна выглядеть в моём приложении или системе. Если задача затрагивает пользовательский интерфейс, прошу агента подготовить несколько UI mockup-ов.

Следующий этап: skill spring-planning. В prompt передаю получившуюся системную постановку и UI mockup-ы, если они есть. В результате агент готовит план изменений, которые ему предстоит выполнить. Провожу review плана и, если уже по тексту вижу, что исходные требования интерпретированы не совсем корректно, оставляю комментарии и прошу доработать документ.
Отдельно обязательно проверяю, что в плане есть задачи, «гарантирующие», что агент не посчитает работу завершённой при упавших тестах, снижении coverage или проблемах Checkstyle. Кроме того, в плане обязательно должна присутствовать отдельная задача на review реализации другим агентом.
Для реализации создаю новую агентскую сессию и обязательно отдельный worktree, в котором агент выполняет задачи согласно подготовленному плану.
Когда все задачи плана выполнены, Checkstyle и тесты проходят, а coverage не снижается, перехожу к review кода. Агент генерирует слишком много кода, чтобы одинаково внимательно читать каждую строку, поэтому изменения приходится ранжировать по степени важности. Модель, сервисы, репозитории, db-миграции и тесты проверяю обязательно, всё остальное в зависимости от исходной задачи.
Для кода, прошедшего мой review, запускаю мутационное тестирование с помощью PITest и анализирую его результаты. Если обнаруживаю важный сценарий, который следовало бы проверить, но существующие тесты его пропускают, генерирую для него отдельный тест.
На финальной стадии обязательно проверяю наличие end-to-end-тестов. Если автоматизировать их невозможно, проверяю работоспособность фичи «руками».

Дальше начинается стандартный процесс: commit, push, PR/MR, review другими участниками команды (если требуется) и merge.
Именно так я работал с агентами последний год. За это время я успел отладить процесс и настроить инструменты, чтобы всё работало так, как мне было нужно. Но тут кто-то в компании решил, что нам пора внедрять OpenSpec. Поэтому давайте разбираться, что такое OpenSpec и как нативно встроить его в уже отлаженное окружение.
OpenSpec
OpenSpec — это открытый фреймворк для Spec-Driven Development. Его основная задача помогать нам работать со спецификациями на всём их жизненном цикле: от момента, когда идея нового функционала только возникла в голове продукта, до момента, когда она реализована в приложении. В моей ситуации, OpenSpec внедряется только на этапе разработки, поэтому сосредоточусь на нем.
Для начала давайте разберёмся, что вообще такое спецификация. Спецификация — это документ (или набор документов), фиксирующий требования к системе и ожидаемый результат разработки. «В идеале» она отвечает на несколько вопросов: какую проблему и для кого мы решаем; какие пользовательские сценарии поддерживаем; как система должна вести себя в штатных и ошибочных ситуациях; какие ограничения необходимо учитывать; по каким критериям поймём, что функциональность реализована правильно.
В OpenSpec есть два вида спецификаций: main specs и delta specs. Main specs хранят описание текущего поведения системы и выступают источником истины (source of truth). Delta specs создаются для конкретного изменения и описывают только разницу между текущим и желаемым состоянием: какие требования нужно добавить, изменить, удалить или переименовать.

Сама спецификация состоит из набора требований (requirements), и у каждого требования должен быть хотя бы один сценарий (scenario). И требования, и сценарии оформляются отдельными заголовками: ### Requirement: и #### Scenario: соответственно. Требование описывает одно наблюдаемое и проверяемое поведение системы, формулируется через SHALL или MUST и не содержит деталей реализации. Например: The system SHALL return the collection of all stored veterinarians.

Сценарий, в свою очередь, задаёт критерии приёмки требования и описывает конкретные условия и ожидаемый результат в формате GIVEN/WHEN/THEN — либо WHEN/THEN, если предусловий нет. Например, сценарий List with existing records определяет, что запрос GET /api/vets при наличии ветеринаров должен вернуть 200 OK и JSON-массив со всеми записями.
На первый взгляд может показаться, что эти требования и сценарии слишком очевидны. Но, во-первых, очевидные вещи тоже нужно где-то зафиксировать. Во-вторых, OpenSpec сгенерировал их самостоятельно — видимо, они ему всё-таки нужны. А поскольку они корректно описывают, как должно работать наше приложение, оставим их как есть.
Естественно, в эпоху AI руками мы пишем разве что промпты — да и те иногда просто наговариваем. Поэтому самое время разобраться, как генерировать спецификации с помощью OpenSpec.
OpenSpec Change
Любая доработка в OpenSpec осуществляется через создание «изменения» (change).

Внутри него OpenSpec хранит delta spec и связанные с доработкой артефакты. По умолчанию это proposal — фиксирует намерение и границы изменения; design — описывает техническое решение; tasks — задаёт последовательность работ, которой будет следовать агент. Этот список не исчерпывающий: при необходимости его можно дополнить артефактами, которые нужны именно вам.
Давайте создадим наше первое изменение. В качестве примера будем разрабатывать типовое приложение — ветеринарную клинику. За основу возьмём чистый проект на Spring Boot 4.1.1 и Java 26 с подключёнными Spring Web MVC, Spring Data JPA, Validation и PostgreSQL. Пока это пустая заготовка без доменной модели и endpoint-ов. Первым изменением добавим хранение информации о ветеринарах и CRUD REST API для работы с ними.
Но прежде чем создавать первое изменение (change), необходимо инициализировать OpenSpec в репозитории.
Для этого нам потребуется OpenSpec CLI. Инструкцию по установке для вашей платформы и ОС можно найти в официальной документации.
Далее выполняем команду openspec init и выбираем агентов, которых будем использовать при разработке приложения.

Что произошло под капотом? openspec init создал в корне репозитория каталог openspec/, в котором будут храниться конфигурация проекта, актуальные спецификации и будущие изменения. Заодно CLI установил для выбранных агентов skill-ы и slash-команды. Спецификаций на этом этапе ещё нет: init только подготовил структуру проекта и инструкции, по которым будут работать агенты.
Дальше пройдём полный цикл изменения, состоящий из трёх этапов: Propose, Apply и Archive. Каждый из них разберём отдельно.

Propose
Чтобы создать первое изменение, воспользуемся командой /opsx:propose и передадим ей промпт с описанием того, что хотим изменить в приложении.

В реальном проекте описание задачи обычно уже есть в тикете или на странице Wiki/Confluence, поэтому в /opsx:propose мне достаточно указать ссылку. Поскольку мой агент подключён к этим корпоративным системам, он сам загрузит исходные требования и уже на их основе создаст изменение (change).

В рамках propose агент сначала смотрит, что уже зафиксировано в main specs. Если спецификации есть, он определяет, какие из них затронет изменение: какие требования нужно добавить, какие уточнить, а какие убрать. Если main specs ещё нет (как в нашем чистом Spring Boot-проекте), то агент описывает новое поведение с нуля. Результат этой работы выливается в delta specs: требования и сценарии, описывающие только разницу между текущим и желаемым поведением системы.
Затем агент разбирает текущую кодовую базу: какие модули и зависимости уже есть, куда логично встроить новую функциональность и какие технические ограничения нельзя игнорировать. На этой основе он готовит design.md — технический дизайн изменения — и tasks.md — план работ, по которому агент будет реализовывать задачу на следующем шаге.
Когда propose завершится, проверяем сгенерированные артефакты. Я читаю их в таком порядке: proposal.md → specs → design.md → tasks.md. Нужно убедиться, что агент верно понял исходную задачу и что предлагаемая реализация соответствует нашим ожиданиям: по интерфейсу, пользовательским сценариям и внутренней архитектуре. В tasks.md отдельно проверяю, что в плане есть задачи, связанные с проверкой барьеров (guardrails): юнит- и интеграционные тесты, Checkstyle, архитектурные проверки ArchUnit, coverage и мутационное тестирование PITest. Кроме того, убеждаюсь, что есть задача на ревью кода другим агентом: если основную разработку вёл Claude Code, ревью делает Codex, и наоборот.
В моей ситуации мне часто приходилось просить агента вносить одни и те же правки от изменения к изменению на этапе propose. Снизить количество правок и скорректировать поведение агента можно несколькими способами:
Добавить «управляющий» prompt в CLAUDE.md или AGENTS.md вашего агента
Положить инструкции в openspec/AGENTS.md — OpenSpec сам поддерживает этот файл
Описать правила в конфигурационном файле OpenSpec — openspec/config.yaml
Создать собственную схему артефактов
Артефакты проверены, правки зафиксированы — можно переходить к непосредственной реализации.
Apply
Чтобы агент начал разрабатывать спецификацию, достаточно вызвать /opsx:apply. Он возьмёт tasks.md выбранного изменения и пойдёт по пунктам плана. Но перед этим я делаю несколько предварительных шагов.

Сначала коммичу change-спецификацию. На этом этапе в репозитории ещё нет кода фичи — только proposal, delta specs, design и tasks. Если во время реализации что-то пойдёт не так, к согласованным артефактам всегда можно вернуться.
Дальше создаю отдельный worktree и веду в нём всю разработку. Так текущая реализация не пересекается с другими незавершёнными изменениями, а при необходимости разработку нескольких спецификаций можно вести параллельно.
Затем очищаю контекст текущей сессии или завожу новую. Сессия propose уже успела обрасти обсуждением, комментариями и промежуточными правками, а для реализации агенту это не нужно и может быть даже вредно: всё необходимое уже лежит в файлах изменения (change).
После этого вызываю /opsx:apply уже с указанием конкретной change-спецификации.

На этом этапе агент уже не планирует, а пишет код. OpenSpec задаёт, что нужно сделать, но не заменяет инструкции о том, как это делать в Spring. Поэтому Spring Skills, которые мы подключали раньше, сохраняют свою актуальность: агент по-прежнему опирается на них, когда создаёт сущности, репозитории, DTO и REST-контроллеры.
Как и раньше, после того как код написан, необходимо сделать его ревью. Агент по-прежнему генерирует слишком много изменений, чтобы читать каждое одинаково внимательно, поэтому смотрю только наиболее значимый код: модель, сервисы, репозитории, db-миграции и тесты.
Обязательно проверяю наличие автоматизированных end-to-end-тестов и их корректность. Если автоматизировать некоторые end-to-end-сценарии по какой-то причине невозможно, прохожу их руками (или прошу пройти QA). Затем запускаю PITest для вновь написанного или изменённого кода, чтобы убедиться, что на этапе разработки агент не упустил какой-нибудь из важных сценариев.
Закончив ревью и все необходимые проверки, хочется сразу закоммитить изменения, создать PR/MR и двинуться по стандартному процессу. Но постойте, постойте: мы ещё не превратили delta спецификации в main спецификации. Поэтому изменения в исходном коде коммитим, а PR/MR пока не создаём. Сначала нужно выполнить синхронизацию спецификаций и архивацию изменения.
Sync & Archive
Зачем вообще синхронизировать спецификации? Пока delta спецификации живут только внутри изменения (change), main спецификации по-прежнему описывают систему до нашей доработки. А ведь именно main спецификации — источник истины, на который агент будет опираться в следующих propose. Если их не обновить, следующее изменение начнётся с устаревшей картины мира: агент не увидит уже добавленные требования и либо опишет их заново, либо спокойно предложит поведение, которое мы только что реализовали иначе. Синхронизация переносит ADDED, MODIFIED и REMOVED из delta спецификаций в main спецификации. Для этого в OpenSpec есть специальная команда /opsx:sync. Но не торопитесь её вызывать.
Дело в том, что синхронизация — только половина работы. Пока изменение лежит в changes/, OpenSpec считает его незавершённым. Чтобы завершить изменение (change), его необходимо заархивировать. Для этого в OpenSpec есть команда /opsx:archive.

В процессе архивации агент, во-первых, выполняет синхронизацию delta спецификаций с main спецификациями, а во-вторых, переносит каталог изменения (change) в changes/archive/ с текущей датой. Proposal, design, tasks и delta спецификации, а также другие артефакты никуда не пропадают: к ним всегда можно будет вернуться позже.
Так же, как и перед apply, я очищаю текущую сессию или завожу новую и вызываю /opsx:archive с указанием названия изменения.

Коммитим результаты синхронизации и архивации, создаём PR/MR, выполняем остальные шаги стандартного процесса разработки и переходим к следующей задаче, начиная с шага propose. Таким образом мы прошли полный цикл внесения изменения с OpenSpec.
Заключение
Подведём итог. В моём случае OpenSpec не стал чем-то революционным, а лишь формализовал то, что я и так делал: сначала уточнял требования, затем проверял план, реализовывал его в отдельном worktree и только после review сливал изменения. Поэтому внедрение «сверху» оказалось не таким болезненным, как я ожидал.
Из плюсов — у меня пропал страх начинать новую сессию посреди работы. Теперь это можно сделать в любой момент, не опасаясь потерять накопленный контекст: всё необходимое уже зафиксировано в proposal, design, specs и tasks. С нынешними контекстными окнами на миллион токенов это не так важно, как во времена 250 тысяч, но всё ещё бывает полезно. Длинная сессия неизбежно обрастает промежуточными решениями и уже неактуальными обсуждениями, а новая получает только то, что действительно нужно для текущего этапа.
Что касается самих main specs, здесь однозначного мнения у меня пока нет. С одной стороны, последовательная доработка приложения через OpenSpec действительно формирует общее описание поведения системы. С другой — сами спецификации читать непросто. Отчасти это связано с тем, что мы привыкли описывать системы иначе. Кроме того, рядом могут соседствовать элементы совершенно разного уровня абстракции. В одной спецификации можно встретить и бизнес-требование, и описание того, какой тип колонки будет использован в базе данных. Отдельный вопрос — формат Gherkin для сценариев. Насколько он уместен здесь, я пока не решил.
Но, кажется, SDD всё увереннее входит в корпоративную разработку. Поэтому рекомендую не откладывать знакомство и не ждать, пока за вами придут, а попробовать самостоятельно.

OpenIDE бесплатна навсегда, а Pro версию можно попробовать в течение 60 дней без регистрации. Часть описанных возможностей доступна и в обычной версии, все возможности без исключения в OpenIDE Pro.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.