diff --git a/AGENTS.md b/AGENTS.md index 3e64fd7e..b4de11de 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -237,6 +237,21 @@ const PostgresMessageRepository = Layer.effect( - Память: `O(n)` для буферизации сообщений ``` +При исправлении проблемы PR **всегда** содержит краткое доказательство фикса: + +```markdown +## Proof of fix + +- Причина: <корневая причина, кратко> +- Решение: <что изменено и почему это устраняет причину> +- Доказательство: <тест/прогон, который падал до и проходит после> +``` + +Фикс без воспроизводящего теста считается неполным. Дублирование кода и смысла +недопустимо: перед новым кодом — Deep Research по существующим реализациям, +одна единица смысла — одно место определения. Полный цикл разработки — в +[`docs/process.md`](docs/process.md). + 7. **CONVENTIONAL COMMITS С ОБЛАСТЯМИ**: ```bash diff --git a/CLAUDE.md b/CLAUDE.md index 02b9ade9..61c0f50e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -151,6 +151,21 @@ const PostgresMessageRepository = Layer.effect( - Память: `O(n)` для буферизации сообщений ``` +При исправлении проблемы PR **всегда** содержит краткое доказательство фикса: + +```markdown +## Proof of fix + +- Причина: <корневая причина, кратко> +- Решение: <что изменено и почему это устраняет причину> +- Доказательство: <тест/прогон, который падал до и проходит после> +``` + +Фикс без воспроизводящего теста считается неполным. Дублирование кода и смысла +недопустимо: перед новым кодом — Deep Research по существующим реализациям, +одна единица смысла — одно место определения. Полный цикл разработки — в +[`docs/process.md`](docs/process.md). + 7. **CONVENTIONAL COMMITS С ОБЛАСТЯМИ**: ```bash diff --git a/README.md b/README.md index e7b057c1..251094fb 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,11 @@ bun run docker-git apply-all --active - `apply` применяет конфиг к одному проекту. `--no-up` только обновляет файлы без `docker compose up`. - `apply-all` применяет конфиг ко всем проектам. `--active` только к запущенным контейнерам. +## Процесс разработки + +Канонический цикл разработки (SDD: Spec-Driven Development) — от issue до +проверяемого PR — описан в [docs/process.md](docs/process.md). + ## Подробности ```bash diff --git a/docs/process.md b/docs/process.md new file mode 100644 index 00000000..6836471e --- /dev/null +++ b/docs/process.md @@ -0,0 +1,181 @@ +# Процесс разработки (SDD: Spec-Driven Development) + +Этот документ описывает канонический цикл разработки в `docker-git`: от issue до +проверяемого PR. Он отвечает на вопрос «как должна проходить разработка» из +[issue #390](https://github.com/ProverCoderAI/docker-git/issues/390) и связывает +шаги процесса с уже существующими инструментами репозитория. + +Базовая философия задана в [`AGENTS.md`](../AGENTS.md) и [`CLAUDE.md`](../CLAUDE.md): + +> «Если это нельзя доказать — это нельзя доверить продакшену.» +> Каждая функция — теорема, каждый тест — доказательство, каждый тип — утверждение. + +SDD означает, что **сначала формализуем (спецификация + инварианты), потом +программируем**. Спецификация и её инварианты живут вместе с кодом и проверяются +автоматически. + +## Обзор цикла + +```text +issue ──▶ clone (среда) ──▶ /plan ──▶ уточнение ТЗ + Deep Research + │ │ + │ ▼ + │ Story + Prove (инварианты проверяемости) + │ │ + │ апрув плана ──▶ plan-to-git ──▶ PR (память) + │ │ + │ ▼ + └──────────────── разработка (код + тесты + Playwright MCP) + │ + ToDos + subagents (декомпозиция) + │ + ▼ + CI/CD ──▶ сверка с инвариантами плана ──▶ merge +``` + +## 1. Issue — источник истины + +Разработка всегда начинается с issue. Issue фиксирует намерение и становится +точкой привязки для плана, PR и итоговой проверки инвариантов. + +## 2. Среда: клонирование с изоляцией + +Для каждой issue поднимается отдельное Docker-окружение. Браузерная автоматизация +включается флагом `--mcp-playwright` (Playwright MCP + Chromium sidecar): + +```bash +bun run docker-git clone https://github.com/ProverCoderAI/docker-git/issues/390 --force --mcp-playwright +``` + +- `--force` пересоздаёт окружение и удаляет volumes проекта. +- `--mcp-playwright` включает Playwright MCP для проверки кода в реальном браузере. +- `--auto` (или `--auto=codex|claude|gemini|grok`) запускает агента, который сам + выполнит задачу, создаст PR и очистит контейнер после завершения. + +Подробности по флагам — в [`README.md`](../README.md). + +## 3. Планирование: `/plan` + +Агенту передаётся ссылка на issue и команда `/plan`. На этом этапе агент **не +пишет код**, а формализует задачу: + +1. **Задаёт уточняющие вопросы** и фиксирует ТЗ. Неоднозначности проясняются до + начала разработки, а не во время неё. +2. **Ведёт Deep Research.** Внутренняя формулировка из `AGENTS.md`: + «I am looking for code that does ``, is there existing + code that can do this?» Сперва ищем переиспользуемые паттерны в репозитории, + затем — внешние источники. Внешний материал цитируется дословно (`SOURCE:`), + иначе `SOURCE: n/a`. Похожий подход к правилам ресёрча см. + [contract-knowledge/.cursorrules](https://github.com/ton-ai-core/contract-knowledge/blob/main/.cursorrules). +3. **Формирует Story** — итог плана. Story описывает поведение в терминах + пользователя и завершается блоком **Prove**: инвариантами, по которым + проверяется выполнение задачи. + +### Story + Prove (инварианты проверяемости) + +Каждая Story обязана содержать проверяемые инварианты — пред-/постусловия и +свойства, которые можно подтвердить тестом, типом или прогоном CI. Это основной +артефакт SDD: именно по нему сверяется результат разработки. + +```markdown +## Story: <краткое название> + +Как <роль>, я хочу <возможность>, чтобы <ценность>. + +### Prove (инварианты проверяемости) + +- INV-1: ∀ вход ∈ Domain: <предусловие> → <постусловие> +- INV-2: <свойство, проверяемое property-based тестом> +- INV-3: <наблюдаемое поведение, проверяемое через CI / Playwright MCP> + +### Способ проверки каждого инварианта + +- INV-1 → unit/property тест `<имя>` +- INV-2 → `bun test <путь>` +- INV-3 → шаг CI `` / сценарий Playwright +``` + +Формат инвариантов согласован с разделом «PROOF-обязательства в PR» в +[`AGENTS.md`](../AGENTS.md) и [`CLAUDE.md`](../CLAUDE.md). + +## 4. Апрув плана → `plan-to-git` → PR + +Когда план одобрен, он не должен теряться. Инструмент +[`plan-to-git`](https://github.com/ProverCoderAI/plan-to-git) автоматически +выгружает захваченные планы в комментарий PR — так план становится постоянной +памятью разработки и привязывается к ветке. + +В сгенерированных окружениях это уже подключено (см. PR #371, +«feat(shell): sync agent plans to pull requests»): + +- бинарь `plan-to-git` устанавливается в образ проекта; +- managed-хук Codex захватывает явные планы (`plan-to-git hook --source codex`); +- `plan-to-git sync` запускается из git post-push обёртки перед бэкапом сессии. + +Таким образом апрувнутый план фиксируется в PR без ручных действий — память о +намерении сохраняется даже при пересоздании контейнера. + +## 5. Разработка + +После принятия плана начинается реализация (Codex / выбранный агент): + +- агент пишет код, **запускает тесты и проверяет работоспособность**; +- при необходимости использует **Playwright MCP** для проверки написанного кода + в браузере; +- активно ведёт **ToDos** и использует **subagents** для декомпозиции крупной + задачи на независимые проверяемые шаги. + +Код пишется только после формального понимания задачи: типы и инварианты → +архитектура (CORE/SHELL) → код → тесты. Минимальный корректный diff +предпочтительнее переписывания. + +## 6. Верификация и сверка с инвариантами + +После реализации: + +1. Агент проверяет **CI/CD** (сборка, типчек, тесты, линтеры). +2. **Сверяет результат с инвариантами плана** (блок Prove): каждый инвариант + Story должен иметь подтверждение — пройденный тест, проверку типа или зелёный + шаг CI / сценарий Playwright. + +Если любой шаг не проходит — возврат в петлю ресёрча (см. `AGENTS.md`), а не +обход проверки. + +## 7. Доказательство фикса (proof-of-fix) + +При исправлении проблемы агент **всегда** добавляет краткое доказательство в PR: +**почему возникла проблема** и **как она решена**. Кратко, по существу. + +```markdown +## Proof of fix + +- Причина: <корневая причина, кратко> +- Решение: <что изменено и почему это устраняет причину> +- Доказательство: <тест/прогон, который падал до и проходит после> +``` + +Фикс без воспроизводящего теста считается неполным: без воспроизведения нельзя +проверить исправление, и возможна регрессия. + +## 8. Борьба с дублированием + +Нужны инструменты и привычки, устраняющие дублирование кода и дублирование +смысла: + +- перед написанием нового кода — Deep Research по существующим реализациям + (шаг 3.2), чтобы переиспользовать, а не копировать; +- одна единица смысла — одно место определения (типы, инварианты, константы); +- при обнаружении дублирования — выделение общего модуля вместо копии. + +## Чек-лист цикла + +- [ ] Issue зафиксировала намерение. +- [ ] Среда поднята (`clone`, при необходимости `--mcp-playwright`). +- [ ] План уточнён вопросами и Deep Research. +- [ ] Story содержит блок Prove с проверяемыми инвариантами. +- [ ] План одобрен и выгружен в PR через `plan-to-git`. +- [ ] Реализация ведётся через ToDos/subagents, с тестами и (при необходимости) + Playwright MCP. +- [ ] CI/CD зелёный; каждый инвариант Story подтверждён. +- [ ] Для фикса добавлено proof-of-fix. +- [ ] Дублирование кода и смысла исключено.