38 KiB
38 KiB
2026-06-06
ORCH-46 запущен конвейером (вариант A) — 04:06 UTC
- Слава выбрал вариант A («вклеить findings», минимальный), велел сделать автономно (вести до конца как ORCH-47, дёргать только если упрётся в его решение).
- ТЗ:
tasks/orchestrator/DEV_TASK_ORCH-046.md(3 варианта дизайна, выбран A). Описание варианта A залито в Plane ORCH-46 (заголовок укорочен 120→77 символов под QG-0). - Суть A: в
src/stage_engine.pyвстраивать ТЕКСТ замечаний в task_desc деву (не только ссылку):- reviewer REQUEST_CHANGES (~стр.419): парсить
## Findingsиз 12-review.md → вынуть P0/P1 дословно - tester FAIL (~стр.455): вынуть reason + фрагмент 13-test-report.md
- новый хелпер-парсер (graceful, never raise, fallback на ссылку)
- reviewer REQUEST_CHANGES (~стр.419): парсить
- НЕ трогать: гейты check_* (ORCH-45/47), QG-реестр, retry/rollback-логику, webhook-пути.
- task 37, ветка
feature/ORCH-046-stage-engine-pass-reviewer-tes, analyst run 139. - ПЛАН (автономно): дать конвейеру пройти analyst→arch→dev→review→testing→deploy-staging.
- Это правка ЯДРА → следить внимательнее. На BRD-апруве задача встанет ждать Approved Славы (by design) — НЕ забыть, что на BRD нужен человек.
- Возможные затыки: (1) BRD-апрув ждёт Славу; (2) staging B6 isolation FAIL (как у ORCH-47 — не блокер кода, но даст FAILED на deploy-staging); (3) если петля dev↔review — теперь должна быть короче, т.к. фикс про передачу findings.
- Финал: ручной merge + ребилд прода (build образа + рестарт + claude-auth check) — по накатанному из LESSONS_2026-06-05.md.
✅ ORCH-46 ЗАКРЫТА (вариант A, автономно по доверию Славы) — 04:50 UTC
- Слава дал «вариант В» = вести совсем без остановок, апрув BRD за него.
- Прошёл конвейером БЕЗ ЕДИНОЙ ПЕТЛИ (иронично — задача про устранение петель): analysis→architecture→development→review (APPROVED с 1 раза)→testing (check_tests_passed принял result:PASS)→deploy-staging. Дев=1 заход.
- BRD-апрув не понадобился: задача стартовала через In Progress (а не Backlog) → это и есть Approved-эквивалент входа, BRD-гейт не застопорил (analysis→architecture auto-advance).
- Реализация (проверила лично): новый
src/review_parse.py(extract_review_findings/extract_test_failures, never raise, graceful fallback на ссылку),stage_engine.py+37/-6 — вклеиваетFindings (P0/P1):дословно деву +Причина: {reason}для tester. Критичная логика (retry/rollback/QG-реестр/гейты) НЕ тронута. ADR-001 «embed-findings-in-task-desc». 50 тестов passed. - Merge PR #43 (
0bc23984), деплой (chown+reset+build+up+health+auth-check) — review_parse активен в /app, claude-auth жив. - Staging FAIL = тот же B6/ORCH-48 (sandbox=NO, prod-ET/ORCH=YES) — деплоер сам в triage-note указал:
ORCH_PROJECTS_JSONstaging смотрит на прод. К коду ORCH-46 отношения НЕТ (9/10 PASS). Решение как с ORCH-47: код в прод, B6 отдельно. - ✅ Plane ORCH-046 → Done; task37 → done в БД.
Состояние прод-гейтов/ядра после ORCH-46:
- ✅ check_ci_green — поллинг (ORCH-45)
- ✅ check_tests_passed — читает result: (ORCH-47)
- ✅ stage_engine — передаёт деву ТЕКСТ findings, не только ссылку (ORCH-46)
- Бэклог high: ORCH-48/B6 (staging registry isolation — теперь стоит поднять приоритет: блокирует автономный deploy-staging у ВСЕХ ORCH-задач!), ORCH-44 (надёжность запуска агента)
ORCH-48 / B6 — ROOT CAUSE найден (05:00 UTC) — баг в ТЕСТЕ, не в инфре
- Деплоер думал: misconfig staging-контейнера (ORCH_PROJECTS_JSON смотрит на прод). НЕВЕРНО.
- Факт (проверено прямым запуском в orchestrator-staging):
known_plane_project_ids()отдаёт count=1, sandbox=True, ET=False, ORCH=False..env.stagingУЖЕ правильно задаёт ORCH_PROJECTS_JSON=только sandbox. Изоляция реестра в staging работает идеально. - Баг — в самом B6-чеке
scripts/staging_check.py(стр.263+): делаетsys.path.insert(0,"/repos/orchestrator")+ importsrc.projectsиз ХОСТ-worktree (где env НЕ staging) →importlib.reloadподхватывает env процесса harness, а не staging-контейнера → читается built-in _DEFAULT_PROJECTS (ET+ORCH) → ложный FAIL. - Решение ORCH-48: B6 должен проверять реестр ВНУТРИ staging-контейнера (его env), а не импортить из host-worktree. Правка кода
scripts/staging_check.py→ подходит для конвейера. - Built-in default registry (
src/projects.py_DEFAULT_PROJECTS) = ET+ORCH — он и подхватывался при пустом env у harness.
Приоритизация ORCH-46 vs ORCH-48 (утро 06.06) — для контекста
- Слава утром спросил «что первым: ORCH-46 или ORCH-48». Рекомендовала ORCH-46 первой (корень ручного пинания задач: «испорченный телефон» dev↔review, нет передачи текста findings, нет памяти между кругами). → Взяли ORCH-46, закрыли (см. выше).
- Следующая по логике — ORCH-48/B6 (root cause уже найден, см. блок выше): правка
scripts/staging_check.py, чтобы B6 проверял реестр ВНУТРИ staging-контейнера, а не импортилsrc.projectsиз host-worktree. Это разблокирует автономный deploy-staging для ВСЕХ ORCH-задач (сейчас у всех ложный FAIL на B6). - Прочий бэклог high: ORCH-44 (надёжность запуска агента).
ORCH-48 переигран на вариант (в) (06:56 UTC) — по решению Славы
- Первый прогон: архитектор выбрал вариант (а) (HTTP-эндпоинт
GET /projects), дев написал код, конвейер прошёл БЕЗ петель (analyst→…→deployer все exit 0) → deploy-staging FAILED → откат на development. - Причина FAIL = курица-яйцо варианта (а): B6 ходит на
/projectsработающего staging-инстанса, а эндпоинт запечён в образ → в текущем образе его НЕТ (404 на 8501 и 8500 проверено) → ложный FAIL. Требует ручного bootstrap-деплоя. Это класс поломки автономности. - Слава выбрал вариант (в) («запуск suite ВНУТРИ контейнера, без HTTP-эндпоинта») — принципиально без курицы-яйца ни сейчас, ни в будущем.
- Переигровка (сделала): (1)
git reset --hard 8b5b1f0ветки до analyst-артефактов (стёрла ADR(а)f77825b+ код(а)2cf873a+ reviewer/tester auto-commits), force-push; (2) встроила в02-trz.md §4блок «РЕШЕНИЕ ПРИНЯТО ВЛАДЕЛЬЦЕМ: вариант (в)» с обоснованием + что обязан зафиксировать архитектор (убрать host-path хак, запуск черезdocker exec, синхронно правитьdeployer.md+STAGING_CHECK.md, чистая_evaluate_b6, НЕ трогать прод-main/projects/.env), коммит7a6c7a0; (3)update_task_stage(38,"architecture")+enqueue_job(architect)через/tmp/replay_arch.pyс guard'ами (agent_running=None, нет активных jobs). job 91, run 151 architect стартовал 06:56. - ⚠️ Существует PR #45 на эту ветку (открыт при работе под (а)) — после переигровки указывает на пересобранную ветку. Не мержить раньше прохождения staging.
- Топология (для архитектора в ADR): Dockerfile НЕ копирует
scripts/в образ →staging_check.pyтолько через mount/repos/orchestrator/scripts/..., путь запуска внутри контейнера учесть. - План автономно: довести arch→dev→review→testing→deploy-staging. Теперь staging должен пройти САМ (в варианте (в) bootstrap не нужен). Финал — merge PR + ребилд прода по LESSONS_2026-06-05.
✅ ORCH-48 ЗАКРЫТА на варианте (в) (07:12 UTC) — идеально, без петель, без касания прода
- Переигровка прошла arch→dev→review→tester (runs 151-154, все exit 0) БЕЗ петель.
- Архитектор зафиксировал (в) (ADR
ADR-001-b6-registry-via-in-container-run.md): host-path хак убран, чистая_evaluate_b6(known)->(bool,str), запуск suite черезdocker exec orchestrator-staging,/projects-эндпоинт НЕ добавлен, прод-src/main.pyНЕ тронут. - deploy-staging:
staging_status: SUCCESS, 10/10 PASS— ГЛАВНОЕ: B6 ✓ PASS[sandbox=YES, prod-ET=NO, prod-ORCH=NO]САМ, без bootstrap. Деплоер запускал suite ВНУТРИ контейнера через docker.sock (CLI в env агента нет) → B6 читает реестр из env staging-инстанса. - Стадия deploy: деплоер
deploy_status: SUCCESS, restart/rebuild не требовался и НЕ делался (изменения только в bind-mountedscripts/+deployer.md+доки,src/и Dockerfile не тронуты). Прод-контейнер 8500 НЕ тронут (zero group-risk для ET). - Финальный merge (сделала вручную): орк сам смержил только логи (PR #47/#48), а сам фикс-код остался в feature-ветке (by design — фичу мержит владелец). Смержила PR #45 (
2a36ed80) feature→main. - Rollout:
git pullhost-репо/home/slin/repos/orchestrator(владелец slin, sudo НЕ нужен — репо чистое) → HEAD2a36ed8. Проверено в живом bind-mount:_evaluate_b6=3, host-path хак=0,deployer.mddocker exec=1. - ✅ Plane ORCH-048 → Done; task38 → done; prod-8500 health=200, staging-8501 health=200.
- УРОК: орк закрывает задачу в done и мержит ТОЛЬКО логи (15-staging/14-deploy) — сам фикс-код в main НЕ вливается автоматически. Финальный merge feature-PR в main + host
git pull— ручной шаг владельца. Проверятьgit log origin/main..featureПЕРЕД тем как считать задачу закрытой.
Состояние прод-гейтов/ядра после ORCH-48 (обновлено):
- ✅ check_ci_green — поллинг (ORCH-45)
- ✅ check_tests_passed — читает result: (ORCH-47)
- ✅ stage_engine — передаёт деву ТЕКСТ findings (ORCH-46)
- ✅ B6 staging-чек — читает реестр ВНУТРИ staging-контейнера, больше НЕ ложный FAIL (ORCH-48) → deploy-staging разблокирован для ВСЕХ ORCH-задач!
- Бэклог: ORCH-44 (надёжность запуска агента)
ORCH-44 запущен конвейером (07:39 UTC) — надёжность запуска агента
- Три проблемы (инцидент ORCH-17 05.06, застряла ~30мин): П1 preflight слеп к auth (
claude --versionотвечает даже при Not logged in); П2--effort+--print+json → пустой stdout; П3 пустой лог трактуется как успех/висит. - Разведка (сделала перед запуском):
preflight.py— только exists+--version(явный коммент «deliberately no prompt ping»). БинарьAgentLauncher.CLAUDE_BIN=/opt/claude-code/bin/claude.exe. Реальные креды/home/slin/.claude/.credentials.json(claudeAiOauth.expiresAt). cmd сборка launcher.py стр.305-307 (--print --output-format json {effort_flag}),_monitor_agentстр.460 (ключ по exit_code, не по содержимому). queue claim-gating стр.154-164. - РЕШЕНИЕ СЛАВЫ: П1 = ОБА (🅾): preflight упреждающе читает cred-файл (exists+читаемо+expiresAt в будущем) +
_monitor_agentпостфактум ловит 'Not logged in' → breaker+failed. П3 = делать (пустой лог/нет result-JSON → job failed, не вечный running). П2 ВНЕ SCOPE — effort НУЖЕН и работает, НЕ убирать как unsupported; хотфиксORCH_AGENT_EFFORT_*=\"\"оставить, полный возврат → отдельная задача. - Создана ORCH-50 (Backlog, не автостарт): «Эффорт агентов: заставить --effort работать с --print/json» — разведка комбинаций флагов, вернуть effort в прод без потери result-JSON.
- Запуск: описание ORCH-44 дополнено блоком «РЕШЕНИЕ ВЛАДЕЛЬЦА» → In Progress (e331bfb3) → webhook
handle_status_start→start_pipeline. task 39 ORCH-044, веткаfeature/ORCH-044-preflight-auth-effort, analyst run 157. - Веду автономно (как 46/48). Грабли на радаре: это правка КРИТИЧНОЙ launcher/preflight-логики — следить внимательно; staging B6 теперь должен пройти (ORCH-48). Финал: merge feature-PR (НЕ только логи! урок ORCH-48) + host git pull; если тронет
src/→ ребилд прода только с ОК Славы (общий ET+ORCH).
Документация сессии 05.06 — финал (подтверждено)
docs/history/LESSONS_2026-06-05.mdв main орка через PR #42 (615a778d), подтвержденоOK-IN-MAIN.- Внутри: постмортем ORCH-17/45/47, уловка-22 ORCH-47 (гейт чинит сам себя), памятка деплоя прода (
/appзапечён в образ → нуженbuild; порты 8500/8501; полная последовательность chown+reset+build+up+health+auth-check), грабли с root-owned файлами (рассинхрон git).
ORCH-44 — диагностика застревания + CI-fix (07:39–08:30 UTC)
- Запущена и заапрувлена от Славы (проверила артефакты, поправила scope: P2/
--effortисключён → вынесен в ORCH-50, оставлены P1 оба подхода + P3). - Застряла на
development— гейтcheck_ci_greenне пропускал: CI в Gitea красный. - Сначала подумала на flaky-раннер (локально 504 passed, CI падал за ~13с), ретриггернула empty-commit
92fc118— упало снова → полезла в лог CI. - 🐞 Корень — регрессия дева: добавил в
preflight.pyauth-gate_check_auth()(читает~/.claude/.credentials.json, default ON — это фикс П1), но не обновил существующий тестtest_resilience.py::TestPreflight::test_ok_when_version_succeeds(мокал толькоclaude --version). У меня локально зелено (креды в контейнере есть), CI-раннер под slin без валидных кред →ok=False→assert Trueпадает. - Нюанс репро (от дева):
_credentials_path()берётAgentLauncher.AGENT_HOME(хардкод/home/slin), игноритHOME-env. Faithful-репро:ORCH_CLAUDE_CREDENTIALS_PATH=/tmp/nope.json. - Передала Dev-агенту (правка кода/тестов — не моя роль). Фикс: class-scoped
@pytest.fixture(autouse=True)вTestPreflightмокаетpreflight._check_auth → (True, ...). Прод-логику НЕ трогал,preflight_check_auth=Trueцел (фикс ORCH-17 не ослаблен). Коммит6fbf7a3, CI → success (runs 134/135 зелёные). Проверила независимо combined=success. - Гейт
check_ci_greenзавязан на Gitea webhook о CI-statussuccess(src/webhooks/gitea.py:201). Webhook о новом зелёном не продвинул (раннер в другой сети / status-webhook не дошёл) → задача висела на development. - Пнула гейт штатным путём (
temp/kick_ci_gate.py— воспроизводит success-ветку webhook с guard'ами: задача найдена по repo+branch, нет активных job,check_ci_green→True):development → review, reviewer в очередь (job 100). НЕ хак БД — вызов штатных функций орка.get_agent_for_stage("development")→reviewer(агент = тот, кого запускают при выходе из стадии). - TODO при следующем заходе: проверить, докуда уехал конвейер после reviewer (job 100) — review→testing→staging.
ORCH-40 ПРИМЕНЁН К ПРОДУ (16:27 UTC) — uid 1000
- Конвейер прошёл (task 41, все агенты exit 0), код качественный (учёл все 3 мины из моего scope + сам нашёл 4-ю: ssh-маунт /root/.ssh -> /home/slin/.ssh).
- Применение к проду (ручной шаг, как ORCH-42):
sudo chown -R 1000:1000 /home/slin/.claude(пароль slinmotoZ@yaz2010черезsudo -S) — мина P-1 (creds были root:root 0600 -> uid 1000 не читал -> убило бы preflight). Теперь slin:slin, читаемо под 1000. ✅- merge PR #53 -> main (
39cb5dd),user:"1000:1000"в main compose. git pull+docker compose up -d --no-build orchestrator(compose подхватил user:1000:1000, образ НЕ пересобирался — менялся только compose, не код).- Проверки: uid=1000 ✅, health 200 ok ✅, preflight True (2.1.142) ✅, docker.sock present (gid 999 жив, для ORCH-36) ✅.
- Скрипт с авто-откатом:
temp/apply_orch40.sh(откат = закомментить user: -> рестарт на root). - Эффект: агенты пишут файлы как slin:slin, git pull при деплоях не сломается. Фундамент эпика ORCH-54.
- ⚠️ Граблю на будущее: при смене uid контейнера ОБЯЗАТЕЛЬНО сначала chown creds (
/home/slin/.claude), иначе preflight (ORCH-044) завернёт весь конвейер.
ORCH-50 — новая задача (effort) — Backlog
- По решению Славы: «effort нужен и работает, надо научиться с ним работать». Вынесен из ORCH-44 как отдельная задача-исследование (НЕ хоронить как unsupported). title_len 74.
ORCH-51 — Автономный ребилд прода — Backlog (id 0db4942e-a7e0-4906-8290-f104b2774bc4)
- Задача-проектирование (дизайн до кода). 8 вопросов: предикат is_safe_to_rebuild(), race/потеря webhook при рестарте (кейс Славы — главный), парадокс само-ребилда (орк рестартит сам себя → внешний хук, связка ORCH-36), maintenance/drain, lock, post-rebuild health+авто-rollback (ORCH-21), уведомления, аварийный флаг
ORCH_AUTO_PROD_REBUILD. - Идея Славы (06.06): blue-green HA — 2 инстанса за балансировщиком. Дописала разделом «Стратегия деплоя A vs B»:
- A = single-instance + maintenance/drain + reconciliation-скан (проще, быстрее).
- B = blue-green HA (целевая, крупнее). Подводные камни: SQLite не шарится → миграция на Postgres, claim через row-lock (FOR UPDATE SKIP LOCKED), общий storage worktree, общий claude-auth, drain активных агентов (3-6 мин), leader-election для queue_worker (иначе двойной клейм).
- Рекомендация Стрим: A и B — этапы, не «или/или». B оформить отдельным крупным эпиком, зависящим от ORCH-51(A) и ORCH-36.
- Связи: ORCH-36/21/48/28/1b/40.
- ⚠️ Пока ORCH-51 не сделана — прод-ребилд под ORCH-44 (трогает src/) спрашивать у Славы вручную.
ORCH-40 применён к проду (uid 1000) + регрессия → ORCH-43 запущена — 16:00-17:00 UTC
Эпик ORCH-54 (автономное внедрение) — порядок: 40 → 43 → 36 → 53(∥) → 51 → approve-политика
ORCH-40 (права, контейнер под host uid 1000) — ПРОВЕРЕНА + ПРИМЕНЕНА В ПРОД ✅
- Проверка качества кода (PR #53): агенты учли ВСЕ 3 мины из моего scope (+4-ю сами доразведали):
user: "1000:1000"на prod+staging;group_add: ["999"]сохранён (МИНА 1 docker.sock=gid999)- SSH-маунт перенесён
/root/.ssh→/home/slin/.ssh(агент сам нашёл, я не указывала) - ADR честно зафиксировал блокер P-1:
chown -R 1000:1000 /home/slin/.claudeПЕРЕД рестартом - тесты
test_orch040_compose.py, ADR, INFRA.md на месте
- Применение к проду (Слава дал «да», деструктивная прод-операция), порядок:
- chown creds:
.credentials.jsonбылroot:root 0600→ не читался под uid 1000 (МИНА P-1).sudo -Sс паролем slin →slin:slin. (.claude.jsonи ssh-ключи уже были slin:slin) - merge PR #53 → main (
39cb5dd),user:"1000:1000"в main compose - рестарт
docker compose up -d --no-build orchestrator(код не менялся — только compose, образ не пересобирать) - проверки ВСЕ зелёные с 1-го захода: uid=1000, health 200 ok, preflight=True (claude 2.1.142 залогинен под 1000), docker.sock present
- chown creds:
- Скрипт с авто-откатом:
temp/apply_orch40.sh(откат = sed comment user: → recreate под root). Откат НЕ понадобился.
🔴 РЕГРЕССИЯ от ORCH-40 (поймана на первом запуске ORCH-43, починена вручную)
- Первый job под uid 1000 упал:
fatal: could not create leading directories ... /repos/_wt/.../.git: Permission denied - Причина: старые worktree-папки в
/repos/_wt/осталисьroot:root(созданы прежним root-контейнером) → uid 1000 не может создать папку рядом. - Пробел ORCH-40: задача сменила compose, но НЕ нормализовала legacy root-файлы (ADR упоминал, deployer не сделал).
- Fix (one-time cleanup, sudo):
chown -R 1000:1000на/repos/_wt,.git-объекты ОБОИХ репо (orchestrator + enduro-trails),data/runs/*.log(37 root-логов). Теперь 0 root-файлов везде. Удалила stale локальную веткуfeature/ORCH-043. - TODO: дописать legacy-чистку как follow-up к ORCH-40 в Plane (на чистой среде грабли повторятся). Слава спрошен — ждёт ответ.
⚠️ УРОК: миграция uid контейнера = нормализовать ВСЕ существующие файлы
- Смена
user:в compose НЕ трогает уже созданные root-файлы в bind-mount. Любой git/worktree/data затык с Permission denied → chown -R на host под новый uid. Проверять/repos/_wt,.git/objects,.git/worktrees,data/runs.
ORCH-43 (merge-gate feature→main) — ЗАПУЩЕНА в конвейер (task 42, analyst бежит после fix)
- Разведка (важно для будущего): сейчас deployer мержит в main ТОЛЬКО docs-артефакты (14-deploy-log, 15-staging-log) отдельным PR (
qg/checks.py:_deploy_log_from_main:431). Сам feature-код (src/) в main НЕ мержится автоматически — я делала руками (PR #52, #53). check_deploy_status пишет «бумажный» SUCCESS. - Дыры: (1) нет реального мержа кода фичи; (2) нет проверки свежести main vs точка ответвления → гонка при max_concurrency>1.
- Scope ORCH-43: реальный мерж feature→main + merge-gate (свежесть main, auto-rebase, re-test, откат на development при конфликте/красном). Файлы:
stage_engine.py,qg/checks.py,git_worktree.py,webhooks/gitea.py. Скрипт запуска:temp/launch_orch43.py. - Точка ответвления:
git worktree add -b branch wt origin/main(git_worktree.py:ensure_worktree).
Баги в бэклог (Слава просил)
- ORCH-55 — Telegram bump не сработал (карточка ORCH-040 #17216 осталась вверху, регресс ORCH-42). Копать
notifications.py— вероятно флаг bump в проде выключен. Код bump В ПРОДЕ ЕСТЬ (4 вхождения в/app/src/notifications.py), но не отрабатывает. - ORCH-56 — я (Стрим) узнаю о завершении задачи только на heartbeat (~30 мин), не в реал-тайм. Рекомендация: вариант B (орк пингует мою сессию sessions_send на done → реагирую сама без вопроса Славы). Скрипт:
temp/create_bugs.py.
Watchdog за конвейером (HEARTBEAT.md) — поставлен ранее этой сессии
- На каждом heartbeat:
docker exec orchestrator python3 /tmp/orch_watch.py→ активные ORCH (stage!=done) + очередь (queued/running) + последние failed/transient. State:memory/heartbeat-state.json. - ⚠️ Ограничение: heartbeat = таймер, НЕ push. Между событием и докладом до 30 мин (это и есть баг ORCH-56).
ORCH-43 (merge-gate feature→main) — В ПРОДЕ ✅ (18:42 UTC)
- Конвейер прошёл (task 42), регрессия прав починена (см. выше ORCH-57). Review APPROVED (0 блокеров), 535 тестов passed.
- Код:
src/merge_gate.py(+340: branch_is_behind_main, auto_rebase_onto_main, retest_branch, file-lease), stage_engine +180, qg/checks +82 (check_branch_mergeable на deploy-staging→deploy edge), db/config/webhooks. +2689/-7, 29 файлов. - Мерж PR #54: ⚠️ ВАЖНО — Gitea merge auth: хедер ДОЛЖЕН быть
Authorization: token <ORCH_GITEA_TOKEN>(форматtoken, как в орке stage_engine.py:118). НЕ маскировать токен***-плейсхолдером — он подставляется буквально → 401! POST/repos/admin/orchestrator/pulls/{N}/mergebody{"Do":"merge"}. Скрипт:temp/merge_pr54.py. - Деплой (ручной, rebuild+restart):
git pull→docker compose build orchestrator→up -d→ health+preflight. Скрипт с авто-откатом:temp/deploy_orch43.sh. Проверки: merge_gate.py в контейнере yes, uid 1000, health ok, preflight True. mainc21a279. - Эффект: конвейер теперь САМ мержит feature→main (свежесть+rebase+re-test). Последний ручной мерж позади.
- ⚠️ Ирония: ORCH-43 чинит «код не вливается в main» — и сама в это упёрлась (deploy SUCCESS бумажный, мерж ручной). Это же — корень ORCH-36.
ORCH-36 (исполняемый деплой) — РАЗВЕДКА + запуск
- Корень: стадия deploy СЕЙЧАС = бумажная. deployer-агент (
.openclaw/agents/deployer.md— промпты агентов В РЕПО!) только пишет 14-deploy-log.md с deploy_status:SUCCESS. Реального build+restart+health НЕТ. - Маркер в коде: deployer.md: «Real docker/SSH deploys are handled by
scripts/orchestrator-deploy-hook.sh(ORCH-36)» — скрипта ЕЩЁ НЕТ. - 🔴 ГЛАВНАЯ МИНА (self-hosting): прод-контейнер orchestrator (8500) — ОДИН на ВСЕ проекты, и В НЁМ сам deployer бежит. НЕЛЬЗЯ
docker compose up -d orchestratorиз контейнера — убьёт себя. Решение: detached-хук на хосте (nohup/systemd-run/at через docker.sock gid 999 или ssh), рестарт ПОСЛЕ выхода агента. - Scope: создать
scripts/orchestrator-deploy-hook.sh(pull→build→up→health→auto-rollback), self-путь detached, deploy_status из реального исхода, для не-self — ssh DEPLOY_SSH_*. Скрипт запуска:temp/launch_orch36.py. - Промпты агентов (ВАЖНО!):
.openclaw/agents/*.mdв репо (analyst/architect/developer/reviewer/tester/deployer) — версионируются, правятся конвейером.
Прод-доступ (закрепить)
slin@82.22.50.71, парольmotoZ@yaz2010, ConnectTimeout=15. Репо/home/slin/repos/orchestrator. docker черезsg docker -c.- Plane In Progress state id =
e331bfb3-e17e-4699-ba48-4abb89c21b7b(flip туда = автозапуск конвейера через webhook). Проект ORCH id8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a. - Health:
http://localhost:8500/health, очередь+resilience:http://localhost:8500/queue. - Gitea API:
http://localhost:3000/api/v1, токен envORCH_GITEA_TOKEN, repoadmin/orchestrator. Merge PR: POST/repos/admin/orchestrator/pulls/{N}/mergebody{"Do":"merge"}.
🏆 ORCH-36 (исполняемый деплой) + ORCH-53 (sweeper/reconciler) — ОБА В ПРОДЕ (21:24 UTC)
- Вечерний марафон: обе задачи прошли конвейер автономно (через рабочий merge-gate ORCH-43), Слава апрувил на гейтах. Эпик ORCH-54: 4 из 6 в проде.
- ORCH-53 (sweeper) — DONE с первого захода: analyst→arch→dev→reviewer→tester→deployer, реворка НЕ было. Файл назван
src/reconciler.py(НЕ sweeper.py!). PR #56 merged первым (чистый). - ORCH-36 (деплой) — через реворк (review отработал!):
- 1-й заход developer упёрся в таймаут 1800с (30 мин) → SIGKILL (exit -9), система сама ушла в attempt 2 (resilience ORCH-1b), наработки в worktree сохранились → 2-й заход добил.
- reviewer завернул REQUEST_CHANGES (2 реальных P1: sentinel-маркеры self-deploy не чистятся на rollback; нет .env.example для новых флагов + процедуры approve в INFRA) → конвейер сам откатил dev→review→fix→APPROVED.
- Код:
src/self_deploy.py(+338),src/stage_engine.py(+247), config.py, launcher.py,scripts/orchestrator-deploy-hook.sh, deployer.md. +2888/-8, 35 файлов. CI green, review APPROVED, tester PASS. - approve-механизм для прод-деплоя 8500 = Telegram-кнопка (решение Славы), флаг
DEPLOY_REQUIRE_MANUAL_APPROVE=true(дефолт).
- 🔴 BOOTSTRAP-ПАРАДОКС (важный урок): ORCH-36 застряла в петле deploy→development. deployer на стадии deploy не писал
14-deploy-log.md(старая логика в проде ≠ новая в ветке) → гейт check_deploy_status FAILED → откат. Self-репо НЕ может задеплоить сам себя через старую логику — нужен ручной разрыв цикла (мерж+деплой один раз, дальше катит своей же логикой). Как с ORCH-40/43. - 🔴 MERGE-CONFLICT при ручном мерже (урок): после мержа PR #56 main ушёл вперёд → PR #55 дал CONFLICT 409 (
.env.example, CHANGELOG, README, INFRA, src/config.py). Разрулила НЕ rebase (9 коммитов = 9 конфликтов), а merge main→ветку (1 разбор). config.py-конфликт был чисто аддитивный: HEAD добавлял self_deploy-настройки, main — reconcile-настройки → нужны ОБА блока, склеить убрав маркеры. Скрипт разрешения на хосте. ⚠️ grep=======в docs/*/13-test-report.md = ЛОЖНОЕ срабатывание (markdown-разделители, не git-маркеры). PR #55 merged после rebase+CI green. - Деплой:
temp/deploy_36_53.sh(pull→build→up→health+preflight+проверка обоих файлов+reconciler в логах, авто-rollback). Откат не понадобился. self_deploy.py yes, reconciler.py yes, uid 1000, health ok, preflight True. - 🔥 RECONCILER ДОКАЗАЛ СЕБЯ СРАЗУ: в первую секунду после старта в логах:
reconciler: ORCH-036 development разблокирована (потерян webhook)+ET-013 development разблокирована. Sweeper нашёл и разблокировал ДВЕ застрявшие задачи, включая саму ORCH-36 из bootstrap-петли. Ручной heartbeat-watchdog больше не нужен — система чинит себя сама.
Уроки вечера (закрепить):
- Заголовки ORCH-задач ≤80 символов — иначе QG-0 (check title length) заворачивает старт. ORCH-53 был 83 → завернул, подрезала до 71.
- Время хоста ≠ UTC: файлы worktree датированы по мск (+3), БД/системное в UTC. Не баг, но путает сверки etime/updated_at.
- Developer-таймаут 1800с мал для мясных задач (деплой-хук+кнопка+callback). Если упрётся — поднять
agent_timeout_secondsoverride или дробить на под-задачи. Пока спас resilience-ретрай (наработки в worktree не теряются между attempt). - Gitea merge auth:
Authorization: token <ORCH_GITEA_TOKEN>(буквально, НЕ маскировать***→ 401). Скрипт:temp/merge_both.py.
Эпик ORCH-54 — статус на конец 06.06:
✅ ORCH-40 — права (uid 1000) → прод
✅ ORCH-43 — merge-gate → прод
✅ ORCH-36 — исполняемый деплой → прод (Telegram-кнопка approve)
✅ ORCH-53 — sweeper/reconciler → прод (уже чинит зависания)
☐ ORCH-51 — окно/HA → бэклог (на свежую голову)
☐ обкатка автономного деплоя → следующая задача поедет через новый деплой сама
- Что конвейер умеет САМ теперь: мержит feature→main (merge-gate+rebase), реально катит в прод (build+restart+health), прод-деплор спросит Telegram-кнопку перед рестартом 8500, чинит застрявшие задачи (reconciler при потере webhook).
- Последний ручной шаг — мой деплой — уходит. Со следующей задачи конвейер катит сам.
- Слава: «Оставим concurrency=1, не рискуем» — НЕ поднимать max_concurrency (одна БД/очередь на все проекты, последовательно надёжнее).