Files
wiki/memory/2026-06-06.md
2026-06-07 00:40:01 +03:00

38 KiB
Raw Permalink Blame History

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 на ссылку)
  • НЕ трогать: гейты 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_JSON staging смотрит на прод. К коду 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") + import src.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-mounted scripts/+deployer.md+доки, src/ и Dockerfile не тронуты). Прод-контейнер 8500 НЕ тронут (zero group-risk для ET).
  • Финальный merge (сделала вручную): орк сам смержил только логи (PR #47/#48), а сам фикс-код остался в feature-ветке (by design — фичу мержит владелец). Смержила PR #45 (2a36ed80) feature→main.
  • Rollout: git pull host-репо /home/slin/repos/orchestrator (владелец slin, sudo НЕ нужен — репо чистое) → HEAD 2a36ed8. Проверено в живом bind-mount: _evaluate_b6=3, host-path хак=0, deployer.md docker 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_startstart_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:3908: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.py auth-gate _check_auth() (читает ~/.claude/.credentials.json, default ON — это фикс П1), но не обновил существующий тест test_resilience.py::TestPreflight::test_ok_when_version_succeeds (мокал только claude --version). У меня локально зелено (креды в контейнере есть), CI-раннер под slin без валидных кред → ok=Falseassert 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-status success (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):
    1. sudo chown -R 1000:1000 /home/slin/.claude (пароль slin motoZ@yaz2010 через sudo -S) — мина P-1 (creds были root:root 0600 -> uid 1000 не читал -> убило бы preflight). Теперь slin:slin, читаемо под 1000.
    2. merge PR #53 -> main (39cb5dd), user:"1000:1000" в main compose.
    3. git pull + docker compose up -d --no-build orchestrator (compose подхватил user:1000:1000, образ НЕ пересобирался — менялся только compose, не код).
    4. Проверки: 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 на месте
  • Применение к проду (Слава дал «да», деструктивная прод-операция), порядок:
    1. chown creds: .credentials.json был root:root 0600 → не читался под uid 1000 (МИНА P-1). sudo -S с паролем slin → slin:slin. (.claude.json и ssh-ключи уже были slin:slin)
    2. merge PR #53 → main (39cb5dd), user:"1000:1000" в main compose
    3. рестарт docker compose up -d --no-build orchestrator (код не менялся — только compose, образ не пересобирать)
    4. проверки ВСЕ зелёные с 1-го захода: uid=1000, health 200 ok, preflight=True (claude 2.1.142 залогинен под 1000), docker.sock present
  • Скрипт с авто-откатом: 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}/merge body {"Do":"merge"}. Скрипт: temp/merge_pr54.py.
  • Деплой (ручной, rebuild+restart): git pulldocker compose build orchestratorup -d → health+preflight. Скрипт с авто-откатом: temp/deploy_orch43.sh. Проверки: merge_gate.py в контейнере yes, uid 1000, health ok, preflight True. main c21a279.
  • Эффект: конвейер теперь САМ мержит 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 id 8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a.
  • Health: http://localhost:8500/health, очередь+resilience: http://localhost:8500/queue.
  • Gitea API: http://localhost:3000/api/v1, токен env ORCH_GITEA_TOKEN, repo admin/orchestrator. Merge PR: POST /repos/admin/orchestrator/pulls/{N}/merge body {"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_seconds override или дробить на под-задачи. Пока спас 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 (одна БД/очередь на все проекты, последовательно надёжнее).