# Engineering Workflow Область: пять независимых checkout workspace (`main`, `frontend`, `backend`, `docs`, `specs`). Репозиторий `deploy` существует в Gitea отдельно и применяет свои локальные правила. Этот документ — единственный владелец общего процесса; локальные AGENTS и conventions определяют технические проверки и ограничения. ## Issue Management | Переход | Условие входа → действие → условие выхода | | --- | --- | | Request → Issue | До изменения файлов/конфигурации/спецификаций определить затронутые repos, найти по смыслу открытые и закрытые Issues, проверить актуальность и scope. Взять подходящую открытую Issue (закрытую переоткрыть только для действительно незавершённой работы) либо создать одну новую. Чтение, анализ и предложение изменений разрешены без Issue. | | Issue → Analysis | В Issue должны быть результат в title, контекст/проблема и ожидаемое поведение, проверяемые Acceptance Criteria. Уточнить неизвестное до зависимого решения. Выбрать тип и приоритет; назначить исполнителя, если известен; milestone только при реальном плане, dependencies/related Issues только при наличии. | | Analysis → Delivery | Определить область и риски, выбрать lightweight или SDD ниже. Если AC или owner меняются, сначала обновить соответствующую Issue/согласование. | Типы: `feature`, `bug`, `refactor`, `tech-debt`, `docs`, `test`, `ci`, `chore`, `performance`. Существующие org labels отражают их без требования один-к-одному: `Kind/Feature`, `Kind/Bug`, `Kind/Refactor`, `Kind/Documentation`, `Kind/Testing`, `Kind/Enhancement` (performance); repo-local `Kind/Process` подходит для ci, chore и process/tech-debt. Дополнительные `Kind/Security`, `Kind/Investigation`, `Kind/Dependencies` (последние два — repo-local) — по ситуации. Priority: существующие `Priority/Critical|High|Medium|Low`. Gitea assignee, milestone и state не дублируются labels. Для назначаемых Issue и PR выбирай `hermes-agent`; незанятую задачу не назначай формально. Шаблоны ускоряют ввод, но не доказывают качество заполнения. Один координирующий Issue достаточен, если результат и AC едины, одна команда может принять работу целиком и отдельные repos не требуют независимой поставки. Иначе Issue в каждом независимо принимаемом repo; ссылаться друг на друга и указать порядок зависимостей. Номера `#27` локальны: для чужого repo использовать `WealthLedger/main#27` или полный URL. Не заводить дубль только из-за второго PR. ## Git Branching | Переход | Условие входа → действие → условие выхода | | --- | --- | | Analysis → Branch | Issue и AC определены; проверить `git status`, текущую ветку и `origin/develop`. Использовать существующую подходящую ветку либо создать одну от актуального `develop` каждого affected repo. Чужие изменения не переносить. | | Branch → Implementation | `/-`; номер принадлежит указанной в PR Issue (для cross-repo — координатору). Примеры: `feature/123-import-transactions`, `fix/124-invalid-balance`, `refactor/125-simplify-api-client`, `docs/126-update-architecture`. | Префиксы: feature → `feature`, bug → `fix`, refactor/tech-debt → `refactor`, docs → `docs`, test → `test`, ci → `ci`, chore → `chore`, performance → `perf`. Номер обязателен для новых рабочих веток; короткий английский slug в kebab-case. Ветки `main`/`develop` не место для прямой разработки. Release/hotfix, обратная синхронизация, Renovate и исторические ветки подчиняются существующему release/automation процессу, а не переименовываются. ## Commit Conventions | Переход | Условие входа → действие → условие выхода | | --- | --- | | Implementation → Commit | Одна связанная задача на commit, проверить staged paths/diff. Заголовок Conventional Commits с осмысленным subject и ссылкой на Issue: `feat(portfolio): add transaction import (#123)` или `ci: align gates (WealthLedger/main#27)`. Scope только при полезной области. | Commitlint требует распознаваемую conventional-commits-parser ссылку, но не проверяет числовой формат, существование Issue, её смысл или корректный repo. Использовать `#N` только для локальной Issue и `WealthLedger/repo#N` для чужой; это формат команды, проверяемый при review. Не добавлять custom validator ради более строгой регулярной проверки. Без `fixes`, `closes`, `resolves` в сообщении: не закрывать задачу первым коммитом. Ссылка в footer тоже принимается commitlint; размещение в заголовке остаётся правилом команды. Если заголовок PR после squash станет commit title, оставить в нём ссылку. `chore(release): X.Y.Z` освобождён только при точном SemVer заголовке release-it. Стандартные Gitea merge commits освобождаются по точному шаблону merge message; sync PR используют обычный review/merge process. Историю не переписывать ради формата. ## Pull Request Process | Переход | Условие входа → действие → условие выхода | | --- | --- | | Validation → PR | Завершить AC и релевантные локальные проверки; PR в `develop` из рабочей ветки, только связанный diff. В теле: Summary, Linked Issue, Changes, Verification (команда/результат/ограничения), Breaking Changes при наличии. Для cross-repo PR указывать полный reference и связанные PR. | | PR → Review → Merge | Дождаться required checks на финальной ревизии, проверить AC, значимые изменения — review владельца/специалиста. При замечаниях исправить и обновить evidence. Merge только по политике repo. | | Merge → Issue Closed | Закрыть Issue после принятия **всех** связанных delivery areas, документации и при SDD — обязательной verification/archive; multi-PR Issue остаётся открытой до последнего результата. | Перед передачей PR на review перенеси в него тип и приоритет связанной Issue, назначь `hermes-agent`, привяжи к подходящему milestone (если он есть) и к `WealthLedger — Delivery Board`, колонка «На проверке». Для cross-repo PR используй milestone его собственного repo. Колонку меняй вместе со стадией: при блокировке — «Заблокировано», после принятия — «Готово». Не вводи label этапа вместо встроенной колонки проекта. Для SDD отдельные pre-archive checks/semantic review выполняются до archive по локальной schema; порядок merge/archive согласуется с конкретным change, но Issue закрывается только после обоих событий. Не подменять OpenSpec approval обычным PR review. ## SDD Integration Lightweight: локальный bugfix с известным ожидаемым поведением, docs-only, рефакторинг без изменения контрактов/наблюдаемого поведения и малые CI-правки: `Issue → Analysis → Branch → Implementation → Validation → PR`. SDD: новая функциональность, изменение публичного API, бизнес-правил, поведения нескольких компонентов, архитектуры или неоднозначные требования. После Issue уточнить намерение и запросить согласование Change Owner на вход в OpenSpec; OpenSpec lifecycle применяется только по явному запросу/решению владельца. Использовать **только** store `wealth-ledger-specs` и его локальный lifecycle: Proposal → Delta Specs → System Analysis → Design + QA Analysis → Docs Impact → Tasks → Apply (для legacy change — его собственная schema). Явные approvals перед downstream artifacts и Apply не заменяются Issue/PR. Ветка specs может появиться для planning; ветки реализации — когда Apply разрешён, без насильственной общей точки создания всех веток. Связать Issue ↔ change ID ↔ PR текстовыми ссылками; после проверки применить штатные sync/archive и completion evidence согласно локальной schema. Число файлов не определяет SDD. Если владелец не согласовал вход в SDD, не начинать зависящую реализацию контракта/семантики и явно сообщить блокировку. ## AI Agent Responsibilities Перед edit — поиск подходящей Issue, AC, workflow, branch/status каждого repo; затем только согласованный scope. По завершении — итоговый diff, проверенные команды и ограничения, подготовка commit/PR по запросу и статус Issue. Чтение не требует Issue. Если Gitea недоступна, сообщить об этом до edit и запросить issue reference; не выдавать локальную заметку за Issue. Агенты используют локальные инструкции репозитория и его CI inputs, не полагаются на соседние checkout как обязательную build-зависимость. Этот источник доступен в main; при недоступной ссылке самостоятельный checkout сохраняет обязательный минимум в своём AGENTS и не блокирует локальную работу из-за отсутствия root checkout. ## Quality Gates Итерации: узкие проверки по риску; после логического изменения — релевантные тесты; перед передачей результата — локальные обязательные gates данного repo на итоговом diff; CI — независимые полные проверки. Не повторять дорогой verify после каждого файла; повторить при изменении значимых входов. `main`: `commits`; остальные: локальные `verify`, `security`, `commits` согласно фактическим CI. Frontend/backend запускают их как jobs в едином `verify.yml`, docs/specs — как отдельные workflows; второго CI ради одного правила не требуется. Для Markdown-only не запускать application build. Результат lint не заменяет семантическую проверку. Обязательность merge checks зависит от защиты ветки. | Правило | Уровень на момент принятия документа | | --- | --- | | Conventional Commits и parser-recognized Issue reference в PR title/commits | CI-проверка через существующий commitlint; блокировка merge **только если** check обязателен в branch protection. Не гарантирует numeric reference, существование или соответствие Issue. Точный release SemVer title и штатные Gitea merge messages исключены. Локальные hooks не гарантируют server-side. | | PR вместо прямого push; successful checks перед merge | Enforced только в repos/ветках, где Gitea branch protection настроена и проверена владельцем. YAML сам по себе не защищает ветку. | | Поиск актуальной Issue, AC, корректный repo, branch name/source, соответствие ссылки, SDD selection, scope, статус | Agent-guided; templates и текст не могут гарантировать соответствие. | | Значимое review, соответствие AC/контракту, исключения и closure после всех PR | Manual; approval может быть required в Gitea, если есть независимый reviewer. | ## Exceptions and Recovery Срочный hotfix: немедленно завести/найти Issue, затем исправление в `release/hotfix-` от актуального `main` по существующему release process; проверки и PR в `main`, затем вернуть результат в `develop`. Связать Issue в PR и сопровождающем коммите; специальная release-ветка исключена из обычного шаблона имён. Не отменять Issue или проверки из-за срочности. Если CI красный или PR устарел — исправить в той же ветке и перепроверить актуальный HEAD; если AC изменились — обновить Issue и при SDD вернуть change к затронутому approval gate. При недоступной Gitea продолжать только анализ. Изменение PR title после зелёного CI: проверить, что check пересчитан; для docs/specs/frontend/backend `edited` trigger у существующих checks может отсутствовать. До подтверждения настройки/отдельного исправления этих gates reviewer проверяет текущий title вручную. Новые правила не применяются к историческим коммитам и автоматической обратной синхронизации релиза. Примеры: фича с новым поведением — Issue → согласованный OpenSpec change → ветки Apply → PR каждого affected repo → archive → закрытие Issue. Локальный bugfix — Issue → `fix/124-invalid-balance` → регрессия → PR → закрытие. Cross-repo контракт — одна Issue с общими AC, `backend` и `frontend` PR с `WealthLedger/main#27` и взаимными ссылками; если независимые acceptance/owners, отдельные связанные Issues. Рефакторинг без изменения поведения — lightweight `refactor/125-simplify-api-client`. Hotfix — Issue → `release/hotfix-*` от `main` → PR/release → back-merge в `develop` → закрытие.