---
work_item: ORCH-092
stage: architecture
author_agent: architect
status: accepted
created_at: 2026-06-09
model_used: claude-opus-4-8
---

# ADR-001: Ручной rebase developer и язык промпта deployer

Work Item: **ORCH-092** — Промпт-аудит 6 агентов (эпилог эпика ORCH-52)
Стадия: **architecture**
Сквозная регистрация: **N/A — локальное docs/prompts-only решение.** Оба решения уточняют
существующий канон промптов (`docs/architecture/adr/adr-0021-prompt-canon-anthropic.md`,
README §«Слой промптов»), но не вводят ни нового QG, ни стадии, ни компонента, ни смены БД →
нового global ADR не требуют. Долговечность нормативного эффекта обеспечивается анти-регресс-тестом
`tests/test_agent_prompts_canon.py` (FR-11), а не отдельным сквозным ADR.

## Статус
Accepted

## Контекст

ORCH-092 — аудит 6 системных промптов `.openclaw/agents/*.md`. Анализ (BRD §6, TRZ §3) вынес две
развилки, которые analyst **намеренно не решал** (зона архитектора), потребовав ADR ПЕРЕД правкой
соответствующих строк:

**P1-2 / FR-9 — ручной rebase developer.** `developer.md` (`<task>`, шаг 2 алгоритма) предписывает
`git fetch origin && git rebase origin/main`. Сверка кодом (BRD A-2) показала, что движок **уже**
держит свежесть базы детерминированно и автоматически, причём двумя независимыми рубежами:
- **Срез ветки от свежего `origin/main`** — serial-gate (ORCH-088) откладывает создание ветки со
  `start_pipeline` на момент claim analyst-job (`launcher._materialize_deferred_branch`,
  `src/agents/launcher.py:421`), когда `origin/main` уже содержит код предшественника
  (`done` ⇔ SHA-в-main, ORCH-071/073). `ensure_worktree` режет worktree от свежего `origin/main`.
- **Авторитетный pre-merge rebase под merge-lease** — `check_branch_mergeable`
  (`src/qg/checks.py:697-703`) на ребре `deploy-staging → deploy` вызывает
  `merge_gate.auto_rebase_onto_main` (`src/merge_gate.py:113`) **всегда** при
  `premerge_rebase_always=True` (дефолт, ORCH-026). Эта операция завершается
  `git push --force-with-lease origin <branch>` (`src/merge_gate.py:151`).

Важная асимметрия прав: авторитетный rebase движка **обязан** делать `--force-with-lease`, чтобы
переписать уже запушенную историю ветки. Developer-промпту это **прямо запрещено**
(`<constraints>`: «❌ Не используй `--no-verify` / `--force-push`»). Значит ручной
`git rebase origin/main` developer'а либо безопасен-но-бесполезен (в начале стадии ветка только что
срезана от свежего main — rebase no-op), либо опасен (после первого push повторный rebase требует
force-push, который developer'у запрещён) — то есть инструкция шага 2 **дублирует** автоматику и
**конфликтует** с собственным запретом промпта.

**P2-2 / FR-10 — язык deployer.** 5 из 6 промптов на русском; `deployer.md` (~9.6 KB, самый большой
и самый safety-critical: self-hosting, прод-рестарт 8500) — на английском. Нужно решить:
унифицировать на ru ИЛИ зафиксировать исключение (en). Инвариант NFR-1 критичен: machine-verdict
ключи (`staging_status:`/`deploy_status:`/`security_status:` + значения `SUCCESS/FAILED/PASS/FAIL`),
shell-команды и анти-регресс-маркеры (`docker exec orchestrator-staging`, `pr_already_merged`,
`8500`, `INFRA-WAIVED`) — **байт-в-байт неприкосновенны**.

## Решение

### Сводка
**D1:** убрать безусловный ручной `git rebase origin/main` из алгоритма developer; свежесть базы —
инвариант движка (serial-gate + auto_rebase под lease), а не ответственность агента. **D2:** оставить
`deployer.md` на английском как **явно задокументированное исключение** канона; не переводить.

### D1 — Developer НЕ делает ручной rebase (закрывает FR-9 / BR-9)

Шаг 2 алгоритма developer (`git fetch origin && git rebase origin/main`) **удаляется** как
самостоятельная мутирующая операция. Вместо него — короткая нормативная заметка, что:
- ветка уже срезана движком от свежего `origin/main` (serial-gate ORCH-088), поэтому ручная синхра
  на входе не нужна;
- авторитетный догон `main` перед слиянием делает движок (`auto_rebase_onto_main` под merge-lease,
  ORCH-026/043) на ребре `deploy-staging → deploy`;
- developer **не делает** `git rebase` / `git push --force*` сам (это пересекается с запретом
  `<constraints>` и с авторитетной операцией движка, использующей `--force-with-lease`).

Допустимо сохранить **read-only** `git fetch origin` (без rebase) — он не мутирует историю и полезен
для сверки с актуальным `main`; но это не обязательный шаг. Главный инвариант: **из алгоритма
исчезает мутирующий `git rebase origin/main`**.

Привязка: FR-9 (промпт приводится в соответствие с ADR), AC-9 (developer не нарушает no-force-push),
анти-регресс — маркер «не мержи свой PR» и запрет force-push сохраняются.

### D2 — Deployer остаётся на английском (закрывает FR-10 / BR-10)

`deployer.md` **не переводится**; язык остаётся английским как зафиксированное исключение из канона
«остальные промпты на ru». Обоснование (в порядке веса):
1. **Минимизация регресс-поверхности на самом критичном промпте.** Перевод ~9.6 KB плотного
   операционного текста — широкая поверхность для случайного слома verdict-ключа, маркера или
   shell-команды (NFR-1 — критичный инвариант). Deployer управляет прод-рестартом 8500 (групповой
   self-hosting риск) — здесь цена ошибки максимальна, выгода от churn — нулевая.
2. **Нулевая выгода понимания.** Исполняющая модель (`claude-opus-4-8`) двуязычна; критичные
   команды, контракты, exit-code-маппинги и verdict-ключи **англо-нативны** — перевод вокруг них
   лишь добавляет риск рассинхрона «русский текст ↔ английская команда».
3. **Исключение, а не дрейф.** Чтобы будущий агент не «починил» язык вслепую, исключение
   фиксируется нормативно: (а) запись в `CLAUDE.md`/README §«Слой промптов», (б) анти-регресс-тест
   `tests/test_agent_prompts_canon.py` (FR-11) допускает/ожидает EN для deployer.

D2 **не отменяет** FR-6: критичная рамка «NEVER restart prod 8500» поднимается/усиливается в начале
`deployer.md` — на английском, в существующем blockquote-стиле. machine-verdict ключи и команды
остаются байт-в-байт (AC-6).

## Альтернативы

- **D1-альт: оставить ручной rebase «с пояснением».** Отвергнуто: пояснение не снимает конфликт с
  запретом force-push и не устраняет дублирование авторитетной операции движка; «оставить, но
  объяснить почему оно безопасно» сложнее и хрупче, чем «убрать то, что движок делает лучше».
- **D1-альт: оставить как есть.** Отвергнуто: BRD/TRZ явно квалифицируют это как
  нереализуемо-конфликтующую инструкцию (after-push rebase ⇒ нужен запрещённый force-push).
- **D2-альт: унифицировать deployer на русский.** Отвергнуто: максимальный регресс-риск на самом
  опасном промпте при нулевой выгоде понимания; противоречит духу «docs/prompts-only, минимум
  изменений, NFR-1 байт-в-байт».

## Последствия

- **+** Developer-алгоритм перестаёт противоречить собственному запрету force-push; единственный
  владелец догона `main` — движок (один авторитетный путь, меньше гонок).
- **+** Самый safety-critical промпт (deployer) не подвергается рискованному массовому переводу;
  NFR-1 защищён структурно.
- **+** Оба решения — чисто текстовые, ревертируемы одним PR; `src/**` не тронут (NFR-2/NFR-3).
- **−** Языковая неоднородность канона (5 ru + 1 en) остаётся. Митигейшн: явная нормативная запись +
  тест → это документированное исключение, а не необъяснённый дрейф.
- **−** Теоретически developer может захотеть подтянуть `main` во время длинной стадии и теперь не
  имеет шага rebase. Митигейшн: серийность репо (ORCH-088) ограничивает расхождение `main` за время
  одной задачи; авторитетный rebase перед merge закрывает остаточное расхождение детерминированно.
- **Откат:** вернуть строку `git rebase origin/main` в `developer.md` шаг 2 и (при желании) перевести
  `deployer.md` — обе правки текстовые, в одном PR, без изменения кода/схемы.

## Ссылки
- BRD: `docs/work-items/ORCH-092/01-brd.md` (BR-9, BR-10; §6 A-2)
- TRZ: `docs/work-items/ORCH-092/02-trz.md` (FR-9, FR-10)
- Acceptance: `docs/work-items/ORCH-092/03-acceptance-criteria.md` (AC-6, AC-9)
- Канон промптов: `docs/architecture/adr/adr-0021-prompt-canon-anthropic.md`
- Сверено по коду: `src/merge_gate.py:113,151` (`auto_rebase_onto_main` + `--force-with-lease`),
  `src/qg/checks.py:697-703` (`check_branch_mergeable` → авто-rebase при `premerge_rebase_always`),
  `src/agents/launcher.py:421` (`_materialize_deferred_branch`, отложенный срез ветки ORCH-088)
- Риски: `docs/work-items/ORCH-092/10-tech-risks.md`
