# DEV TASK — ORCH-3 (S-3) + M-5: безопасный rollback деплоя + чистка хардкода инфры **Проект:** enduro-trails (НЕ orchestrator!) | **Сервер:** slin@82.22.50.71 | **Репо:** /home/slin/repos/enduro-trails | **Хук на хосте:** /home/slin/bin/enduro-deploy-hook.sh **Ветка:** `feature/ORCH-3-deploy-rollback` из свежего main репо enduro-trails. ⚠️ **ЭТО ПРОД-ДЕПЛОЙ. Хук трогать ОСТОРОЖНО** — сохранить существующее поведение (pull + restart + gps-collector), только ДОБАВИТЬ rollback. НЕ переписывать файл целиком одной строкой — мержить. ⚠️ **ГРАБЛЯ push (ORCH-7, НЕ повтори):** после push `git log origin/main..origin/feature/ORCH-3-deploy-rollback` ДОЛЖЕН показать твои коммиты. НЕ отчитывайся «PR готов» пока remote реально не содержит коммитов. ## Проблема (верифицировано по живому коду) ### S-3 — опасный rollback в промпте деплойера `.openclaw/agents/deployer.md` стр.100-107, блок «Rollback (если smoke fail)»: ```bash git checkout $LAST_TAG echo "ROLLED BACK to $LAST_TAG" exit 1 ``` **Два бага:** 1. 🔴 `git checkout $LAST_TAG` выполняется в **shared-репо** `/home/slin/repos/enduro-trails` → переводит рабочую копию в detached HEAD на старый тег. Хук `enduro-deploy-hook.sh` делает `cd $REPO && git pull origin main` — следующий деплой получит загаженное состояние/конфликт. 2. 🔴 Это **не откатывает прод вообще** — контейнер крутит уже собранный образ; `git checkout` локального файла прод не меняет. Откат фиктивный. ### M-5 — хардкод инфры в промптах - `.openclaw/agents/architect.md:16` — `82.22.50.71` хардкод. - `.openclaw/agents/tester.md:27,38,39` — `/home/slin/repos/enduro-trails`, `/home/slin/tools/ui-test/...` хардкод путей. - `deployer.md` УЖЕ частично параметризован (`DEPLOY_SSH_USER/HOST/HOOK` через env с дефолтами) — это образец, как делать остальные. ## Что сделать ### Часть А — rollback В ХУК (S-3) Хук `enduro-deploy-hook.sh` сейчас: `set -e` → `cd $REPO` → `git pull origin main` → `docker compose up -d app` → опц. gps-collector. **rollback'а нет.** 1. **Сохранить текущий образ ДО рестарта** (чтобы было к чему откатываться): - Перед `docker compose up -d app` снять id текущего работающего образа app: `PREV_IMG=$(docker compose images -q app 2>/dev/null || docker inspect --format '{{.Image}}' $(docker compose ps -q app) 2>/dev/null)`. - Записать в файл-«предыдущий»: `echo "$PREV_IMG" > $REPO/.deploy-prev-image` (только если непусто). 2. **Добавить режим rollback в хук** (новый флаг, напр. `enduro-deploy-hook.sh --rollback`): - Прочитать `.deploy-prev-image`, если есть и непусто → `docker tag $PREV_IMG :current` ИЛИ перезапустить app на предыдущем образе (выбери надёжный способ под текущий compose; если app собирается из Dockerfile — откат к предыдущему образу через `docker compose up -d` с `image:` override или `docker run` старого образа). Если способ неоднозначен — опиши в отчёте что выбрал и почему, НЕ выдумывай несуществующие compose-поля. - Залогировать в тот же `$LOG`. - **Если откатывать не к чему** (нет prev-image) → честно залогировать «no previous image, rollback skipped» и вернуть ненулевой код. 3. ⚠️ НЕ ломать `set -e` поведение и существующий happy-path. rollback — отдельная ветка флага, не трогает основной поток. ### Часть Б — почистить промпт деплойера (S-3) В `.openclaw/agents/deployer.md` блок 6 «Rollback»: - **Убрать** `git checkout $LAST_TAG`. - **Заменить** на вызов хука с флагом rollback: ```bash ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${DEPLOY_USER}@${DEPLOY_HOST} "bash ${HOOK} --rollback" echo "ROLLBACK requested via deploy hook" exit 1 ``` (используй те же `DEPLOY_USER/DEPLOY_HOST/HOOK` переменные что уже определены в блоке 3). - Убрать из `tools:` строки `docker` если он больше не нужен в промпте (деплой/откат теперь только через SSH+хук). Проверь — упоминается ли docker ещё где-то в промпте; если только в rollback — можно сузить до `Bash (git, curl)`. Если есть другой обоснованный вызов — оставь и отметь в отчёте. ### Часть В — M-5 параметризация хардкода По образцу `deployer.md` (env с дефолтами): - `architect.md:16` — `82.22.50.71` → текстом обобщить (это просто описание инфры в промпте, не исполняемый код): заменить на `${DEPLOY_SSH_HOST:-…}`-стиль ИЛИ обобщённую формулировку «один сервер (Docker Compose)». Не ломать смысл промпта. - `tester.md:27,38,39` — пути `/home/slin/repos/enduro-trails`, `/home/slin/tools/ui-test/...`: - `make test` путь → использовать `${REPO_DIR:-/home/slin/repos/enduro-trails}` или относительный (агент и так в репо — проверь cwd-контекст). - ui-test путь → `${UI_TEST_RUNNER:-/home/slin/tools/ui-test/run_tests.js}`. - Цель M-5: инфра-специфика выносится в env-переменные с разумными дефолтами, промпты переносимы. Где значение — просто описание (не исполняется) и параметризация ломает читаемость — допустимо оставить, но отметь в отчёте. ## Ограничения - 🚫 НЕ трогай: orchestrator (вообще другой репо), nginx, openclaw.json, .env-секреты, src/ и tests/ самого enduro-trails (только `.openclaw/agents/*.md` + хук на хосте). - ⚠️ Хук — прод. Бэкап перед правкой: `cp /home/slin/bin/enduro-deploy-hook.sh /home/slin/bin/enduro-deploy-hook.sh.bak-$(date +%s)`. Merge, не overwrite. - ⚠️ НЕ запускай реальный деплой/rollback на проде для «проверки» — это живой сайт. Проверка хука — `bash -n` (синтаксис) + dry-run логики на тестовом образе, НЕ трогая работающий app. - Conventional Commits: `fix(deploy): move rollback into deploy hook (S-3)`, `refactor(agents): parametrize infra hardcode (M-5)`. ## Проверка (Стрим проверит вживую) | # | Что | Критерий | |---|-----|----------| | 1 | хук backup | `.bak-*` создан перед правкой | | 2 | хук happy-path цел | pull+restart+gps-collector не сломаны, `bash -n` ок | | 3 | хук rollback | `--rollback` читает prev-image, откатывает app ИЛИ честно «skipped» если нечего; логирует | | 4 | deployer.md | нет `git checkout $LAST_TAG`; rollback = вызов хука `--rollback` | | 5 | M-5 | architect/tester хардкод → env-переменные с дефолтами, смысл цел | | 6 | git | PR в main репо enduro-trails, remote содержит коммиты (грабля ORCH-7) | ## Отчёт - НЕ деплоить на прод. После правок — `bash -n` хука, показать diff deployer.md/architect.md/tester.md + новый хук. - Запушь ветку (ПРОВЕРЬ remote!), открой PR в main **репо enduro-trails**. НЕ мержи — мерж и решение про прод-применение хука делает Стрим. - Хук на хосте: после правки покажи финальный `cat` + `bash -n`. Применение на проде (если решим) — отдельный осознанный шаг, согласованный со Славой. - После каждого блока — короткий отчёт. Если ТЗ расходится с кодом — отчитайся, не выдумывай. Один исполнитель, не паникуй про параллельные сессии.