38 KiB
38 KiB
2026-06-02 — Daily Log
ET-009: GPS Sources (EnduroRussia + Wikiloc) — Pipeline Completed 🎉
Pipeline stages (all passed):
- ✅ analysis — analyst (Sonnet), produced BRD, TRZ, acceptance criteria, test plans
- ✅ architecture — architect v2 (Opus 4.7), ADRs + infrastructure requirements
- ✅ development — developer (Opus 4.7 1M), 19 files, 1287 lines. Commit
3577ff3 - ✅ review — reviewer (Opus), found P1 bugs F-01, F-02
- ✅ development fix — developer (Sonnet), commit
fc03746: 159 lines ingps_tracks.js - ✅ review round 2 — reviewer (Opus), APPROVED, only P3 minors remain
- ✅ testing — tester (Sonnet), 25/25 pytest + 24/24 js tests PASS
- ✅ deploy — deployer (Sonnet), PR #16 merged, image rebuilt, collector running
Key results:
- EnduroRussia parser:
enduro_russia.py— scraping + GPX parsing - Wikiloc parser:
wikiloc.py— Wikiloc GPX integration - Dynamic source filters (F-01):
_buildGpsFiltersUIpulls source_id from/api/gps-tracks/health.tracks_by_source - Attribution fix (F-02): attribution set at
addSourcetime via_ensureGpsSources(map, attribution), not by mutatingsrc.attribution(MapLibre AttributionControl issue) - Collector running: 305 EnduroRussia tracks, fetching one per 5s, 34+ already in DB
- Commits:
eaa6b4c(analyst),4be7fbf(architect),3577ff3(dev),fc03746(dev fix) - PR: #16 merged → main at
b5ba7b2
Known issues:
- Nginx 502 on external URL (port 5556 routing) — not ET-009 specific, needs nginx config fix
- gps_sources.yaml — ADR files inside Docker image (not volume), old image had
proposed; fixed by rebuilding image
Orchestrator Issues Discovered
Critical bug: Launcher Popen broken inside container
- All Claude processes (claude.exe) become zombies when launched via orchestrator's Python subprocess
- Root cause:
dockerbinary not available inside container, Popen flags wrong - Workaround established: base64-encode Python launch script → ssh to host → decode → docker cp → docker exec python3
- This pattern avoids shell quoting hell
Other orchestrator bugs:
.task-arch.md,.task-dev.md,.task-review.mdnot regenerated per-stage (carry over from previous task)- Workaround: manually rewrite these files before each stage launch
- No CI configured in Gitea → every commit triggers false "CI failed" webhook alert
- Tokenator API: all 8 models down for maintenance (June 1, still down June 2 morning)
Agent launch manual pattern:
# 1. Base64-encode the Python launch script
cat launch_script.py | base64 -w0
# 2. SSH to host, decode, cp to container, exec
ssh slin@82.22.50.71 "
echo 'BASE64_STRING' | base64 -d > /tmp/launch.py
docker cp /tmp/launch.py orchestrator:/tmp/launch.py
docker exec orchestrator python3 /tmp/launch.py
"
Models Configuration Changes
- DeepSeek V4 models added to openclaw.json:
openrouter/deepseek/deepseek-v4openrouter/deepseek/deepseek-v4-proopenrouter/deepseek/deepseek-v4-flash
- Current model for main agent:
openrouter/deepseek/deepseek-v4-pro
User Preferences (re-confirmed during ET-009)
- User wants visibility at each pipeline stage — frustrated by silent automated advances
- User wants to approve before advancing: analyst →
:approved:→ architect → developer → reviewer → tester → deployer - Only analyst requires manual
:approved:; architect, reviewer, tester should auto-advance but notify - Deployer should ask before deploying
Глубокий аудит оркестратора (мультиагенты) — 2026-06-02
Проведено
- Аудит кода:
tasks/multi-agent/AUDIT_2026-06-02.md— 3 BLOCKER, 5 SERIOUS, 7 MEDIUM, 5 LOW - Аудит документации:
tasks/multi-agent/DOCS_AUDIT_2026-06-02.md - ТЗ для Dev:
tasks/multi-agent/DEV_TASK_ORCHESTRATOR_FIXES.md(9 задач)
Корневые баги (BLOCKER)
- B-1: нет
dockerбинарника в контейнере orchestrator →_write_task_fileчерезdocker runпадает молча → агент читает старый.task-*.md - B-2:
Popen+ PIPE + daemon-поток → claude-зомби,exit_codeтеряется (в БДexit=Noneдля всех ET-009) - B-3:
.task-*.mdтащатся между задачами + коммитятся в git
Ключевая находка по докам
- P1 zombie из
LESSONS_ET006.md(22 мая) = мой B-2. Баг известен 11 дней, не починен → повторился на ET-008/009 - Системная проблема: lessons пишутся, но не конвертируются в задачи
- Расхождение код↔док: README говорит review QG=
check_review_approved, код используетcheck_reviewer_verdict
Dev-агент запущен
- Model: tokenator/claude-opus-4-8 (modelApplied: true)
- taskName:
orch_fixes, runId: 2f18ca88 - Deploy-хук
/home/slin/bin/enduro-deploy-hook.shСУЩЕСТВУЕТ и корректен - В orchestrator были незакоммиченные правки (M launcher/config/notifications/plane_sync) — Dev разберёт в Task 1
ET-009 Artifacts
- Plane issue:
64e98247-509f-4c30-9955-a5531ab7d1ee(sequence #5) - Plane workspace:
ag_proj, project7a79f0a9-5278-49cd-9007-9a338f238f9c - Orchestrator DB: task_id=16
- Repo:
/home/slin/repos/enduro-trailson mva154 - Docs:
docs/work-items/ET-009/— 00 through 14 (BRD, TRZ, acceptance, tests, ADRs, infra, data, risks, review, test report, deploy) - Docker: container
enduro-trails, image rebuilt with new ADR files, collector running
2026-06-02 — Daily Log
ET-009: GPS Sources (EnduroRussia + Wikiloc) — Pipeline Completed 🎉
Pipeline stages (all passed):
- ✅ analysis — analyst (Sonnet), produced BRD, TRZ, acceptance criteria, test plans
- ✅ architecture — architect v2 (Opus 4.7), ADRs + infrastructure requirements
- ✅ development — developer (Opus 4.7 1M), 19 files, 1287 lines. Commit
3577ff3 - ✅ review — reviewer (Opus), found P1 bugs F-01, F-02
- ✅ development fix — developer (Sonnet), commit
fc03746: 159 lines ingps_tracks.js - ✅ review round 2 — reviewer (Opus), APPROVED, only P3 minors remain
- ✅ testing — tester (Sonnet), 25/25 pytest + 24/24 js tests PASS
- ✅ deploy — deployer (Sonnet), PR #16 merged, image rebuilt, collector running
Key results:
- EnduroRussia parser:
enduro_russia.py— scraping + GPX parsing - Wikiloc parser:
wikiloc.py— Wikiloc GPX integration - Dynamic source filters (F-01):
_buildGpsFiltersUIpulls source_id from/api/gps-tracks/health.tracks_by_source - Attribution fix (F-02): attribution set at
addSourcetime via_ensureGpsSources(map, attribution), not by mutatingsrc.attribution(MapLibre AttributionControl issue) - Collector running: 305 EnduroRussia tracks, fetching one per 5s, 34+ already in DB
- Commits:
eaa6b4c(analyst),4be7fbf(architect),3577ff3(dev),fc03746(dev fix) - PR: #16 merged → main at
b5ba7b2
Known issues:
- Nginx 502 on external URL (port 5556 routing) — not ET-009 specific, needs nginx config fix
- gps_sources.yaml — ADR files inside Docker image (not volume), old image had
proposed; fixed by rebuilding image
Orchestrator Issues Discovered
Critical bug: Launcher Popen broken inside container
- All Claude processes (claude.exe) become zombies when launched via orchestrator's Python subprocess
- Root cause:
dockerbinary not available inside container, Popen flags wrong - Workaround established: base64-encode Python launch script → ssh to host → decode → docker cp → docker exec python3
- This pattern avoids shell quoting hell
Other orchestrator bugs:
.task-arch.md,.task-dev.md,.task-review.mdnot regenerated per-stage (carry over from previous task)- Workaround: manually rewrite these files before each stage launch
- No CI configured in Gitea → every commit triggers false "CI failed" webhook alert
- Tokenator API: all 8 models down for maintenance (June 1, still down June 2 morning)
Agent launch manual pattern:
# 1. Base64-encode the Python launch script
cat launch_script.py | base64 -w0
# 2. SSH to host, decode, cp to container, exec
ssh slin@82.22.50.71 "
echo 'BASE64_STRING' | base64 -d > /tmp/launch.py
docker cp /tmp/launch.py orchestrator:/tmp/launch.py
docker exec orchestrator python3 /tmp/launch.py
"
Models Configuration Changes
- DeepSeek V4 models added to openclaw.json:
openrouter/deepseek/deepseek-v4openrouter/deepseek/deepseek-v4-proopenrouter/deepseek/deepseek-v4-flash
- Current model for main agent:
openrouter/deepseek/deepseek-v4-pro
User Preferences (re-confirmed during ET-009)
- User wants visibility at each pipeline stage — frustrated by silent automated advances
- User wants to approve before advancing: analyst →
:approved:→ architect → developer → reviewer → tester → deployer - Only analyst requires manual
:approved:; architect, reviewer, tester should auto-advance but notify - Deployer should ask before deploying
Глубокий аудит оркестратора (мультиагенты) — 2026-06-02
Проведено
- Аудит кода:
tasks/multi-agent/AUDIT_2026-06-02.md— 3 BLOCKER, 5 SERIOUS, 7 MEDIUM, 5 LOW - Аудит документации:
tasks/multi-agent/DOCS_AUDIT_2026-06-02.md - ТЗ для Dev:
tasks/multi-agent/DEV_TASK_ORCHESTRATOR_FIXES.md(9 задач)
Корневые баги (BLOCKER)
- B-1: нет
dockerбинарника в контейнере orchestrator →_write_task_fileчерезdocker runпадает молча → агент читает старый.task-*.md - B-2:
Popen+ PIPE + daemon-поток → claude-зомби,exit_codeтеряется (в БДexit=Noneдля всех ET-009) - B-3:
.task-*.mdтащатся между задачами + коммитятся в git
Ключевая находка по докам
- P1 zombie из
LESSONS_ET006.md(22 мая) = мой B-2. Баг известен 11 дней, не починен → повторился на ET-008/009 - Системная проблема: lessons пишутся, но не конвертируются в задачи
- Расхождение код↔док: README говорит review QG=
check_review_approved, код используетcheck_reviewer_verdict
Dev-агент — РЕЗУЛЬТАТ (ПРИНЯТО ✅)
- Model: tokenator/claude-opus-4-8 (modelApplied: true), taskName
orch_fixes, runId 2f18ca88 - Починено: B-1, B-2, B-3, S-5, S-1, M-1 + 2 доп-фикса найденных в бою:
- git safe.directory в Dockerfile (без него auto-commit падал на «dubious ownership»)
- init:true в compose (tini как PID 1, добивает grandchild-зомби от claude/node)
- 11 коммитов в main orchestrator (Conventional Commits), запушены
- Тесты: 26 passed (launcher + qg) — гонял в контейнере (хостовый .venv сломан, symlinks на py3.10)
- Автономный прогон: через
launcher.launch(), 0 зомби, auto commit+push сработал - Доки обновлены: ARCHITECTURE, README (QG-таблица),
BUGFIXES_2026-06-02.md
Моя независимая проверка (на сервере, не на слово)
- ✅ health
{"status":"ok"}, 0 defunct процессов - ✅ B-1:
_write_task_fileчерезopen()+ raise (код подтверждён) - ✅ S-5: verdict читается только из YAML frontmatter
- ✅ 26 тестов зелёные
- ✅ init:true в compose, PR #19 open+mergeable
⚠️ ТРЕБУЕТ ДЕЙСТВИЯ
- PR #19 (enduro-trails:
.gitignore+reviewer.md) — ветка main защищена, нужен merge человеком. Спросила Славу — ждёт ответа.
Честные расхождения (Dev не скрыл)
- Хостовый
.venvсломан (symlinks py3.10) — тесты в контейнере test_webhooks.py— 9 pre-existing падений (401/signature), были ДО правок, вне scope- Вне scope (отдельные задачи на потом): S-2/S-3 (rollback в shared-репо), S-4 (git worktree per task), M-3 (дубль
_try_advance_stage), F-2b (очередь задач вместо daemon-потоков — главный целевой рефактор), M-7 (идемпотентность webhook)
Открытый вопрос Славе
- Смержить PR #19?
- Завести в Plane оставшиеся задачи (worktree, очередь задач)?
ET-009 Artifacts
- Plane issue:
64e98247-509f-4c30-9955-a5531ab7d1ee(sequence #5) - Plane workspace:
ag_proj, project7a79f0a9-5278-49cd-9007-9a338f238f9c - Orchestrator DB: task_id=16
- Repo:
/home/slin/repos/enduro-trailson mva154 - Docs:
docs/work-items/ET-009/— 00 through 14 (BRD, TRZ, acceptance, tests, ADRs, infra, data, risks, review, test report, deploy) - Docker: container
enduro-trails, image rebuilt with new ADR files, collector running
ORCH-2 [S-4] git worktree — ПРИНЯТО ✅ (2026-06-02)
Dev-агент (Opus 4.8 Tokenator)
- taskName:
orch2_worktree, TЗ:tasks/orchestrator/DEV_TASK_ORCH2_WORKTREE.md - НОВЫЙ файл:
src/git_worktree.py(5 функций:_safe,get_worktree_path,ensure_worktree,remove_worktree,cleanup_orphaned) - Изменены:
src/agents/launcher.py(worktree-пути),src/qg/checks.py(чтение артефактов + тесты из worktree),src/webhooks/gitea.py(git-операция),src/config.py(+worktrees_dir) - Тесты: 37 passed (9 fail = pre-existing webhook 401, baseline — не изменилось)
- Тест изоляции (live): два worktree на независимые ветки → A≠B, shared repo не тронут ✅
- PR #1 в orchestrator: open, mergeable
Замечен побочный эффект (важно!)
В shared /repos/enduro-trails обнаружена ветка ET-012-m-3-stage-engine с авто-коммитом от analyst, run_id=52. Это M-3 (ORCH-4) — оркестратор САМ запустил analyst и тот отработал АВТОНОМНО. Но создал задачу в неправильном репо (enduro-trails вместо orchestrator), потому что default_repo всё ещё enduro-trails. Доказывает: автономность починена, но multi-repo пока не настроено.
Обсуждение self-hosting оркестратора
- Слава заметил: оркестратор пилится Dev-агентом в обход своего конвейера
- Причина: bootstrap-проблема — нельзя чинить сломанную машину, пока едешь на ней
- Цель на будущее: self-hosting (оркестратор берёт свои же задачи через полный конвейер)
- Нужна задача ORCH-6: self-hosting (после ORCH-1 очереди задач + multi-repo)
Нейминг — финальное решение
- Единое имя:
orchestrator - Gitea-репо переименован
agent-dev→orchestrator - Plane-проект
orchestrator(identifierORCH, id8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a) - Workspace
tasks/multi-agent/→tasks/orchestrator/ - Папка/контейнер/compose уже были
orchestrator - Plane задачи: ORCH-1 (F-2b), ORCH-2 (S-4), ORCH-3 (S-2/S-3), ORCH-4 (M-3), ORCH-5 (M-7)
Открытые вопросы Славе
- Смержить PR #19 (enduro-trails)?
- Смержить PR #1 (orchestrator worktree)?
ИНЦИДЕНТ: Plane-webhook авто-запустил конвейер по всем ORCH-1..7 (2026-06-02 19:00)
Что случилось
- Создала в Plane задачи ORCH-1..7 — Plane-webhook поймал каждую и авто-запустил конвейер (analyst→architect, auto-commit)
- Всё ушло в неправильный репо enduro-trails (
plane.py:91hardcoderepo=settings.default_repo), наплодило мусор ET-010..016 - Корень: Plane-webhook (id
93f0c342-a614-4248-9d0f-c107276f5620) срабатывает на ЛЮБ\u041eЕ issue в workspace, без фильтра по проекту - ⚠️ ПОЗИТИВ: автономность реально работает — analyst exit=0, auto-commit, worktree (ORCH-2) сработал
Меры (сделано)
- 🛡️ Plane-webhook ДЕАКТИВИРОВАН в Plane postgres:
UPDATE webhooks SET is_active=false. Проверено:is_active=f- Plane postgres: контейнер
plane-app-plane-db-1,PGPASSWORD=plane, dbplane, userplane, tablewebhooks - Обратно включить после ORCH-6:
UPDATE webhooks SET is_active=true WHERE id=...
- Plane postgres: контейнер
- 🧹 Вычищено: все ветки ET-010..016 (git local+remote, 204), worktree
_wt/enduro-trails/*(root-owned → sudo rm), тестовые iso-A/iso-B, tasks≥19 в БД орка, agent_runs≥19 - Plane чист: orchestrator=7 (ORCH-1..7), enduro=5 (родные). Junk ET-issues в Plane не было (орк генерил ET-номера сам в git+БД)
- Заметка на сервере:
orchestrator/docs/INCIDENT_2026-06-02_webhook_autorun.txt
ROOT FIX = ORCH-6 (multi-repo)
plane.py:91repo=settings.default_repo→ нужен фильтр поplane_project_id+ маппинг repo per project- Пока ORCH-6 не сделан — webhook ДЕРЖАТЬ ВЫКЛЮЧЕННЫМ
Открытые вопросы
- Смержить PR #19 (enduro-trails) + PR #1 (orchestrator worktree)?
Нейминг — финальное решение
- Единое имя:
orchestrator - Gitea-репо переименован
agent-dev→orchestrator - Plane-проект
orchestrator(identifierORCH, id8da6aa25-a60e-44d6-a1e2-d8ae59aa7d6a) - Workspace
tasks/multi-agent/→tasks/orchestrator/ - Папка/контейнер/compose уже были
orchestrator - Plane задачи: ORCH-1 (F-2b), ORCH-2 (S-4), ORCH-3 (S-2/S-3), ORCH-4 (M-3), ORCH-5 (M-7)
Открытые вопросы Славе
- Смержить PR #19 (enduro-trails)?
- Смержить PR #1 (orchestrator worktree)?
ИНЦИДЕНТ: Plane-webhook авто-запустил конвейер по всем ORCH-1..7 (2026-06-02 19:00)
Что случилось
- Создала в Plane задачи ORCH-1..7 — Plane-webhook поймал каждую и авто-запустил конвейер (analyst→architect, auto-commit)
- Всё ушло в неправильный репо enduro-trails (
plane.py:91hardcoderepo=settings.default_repo), наплодило мусор ET-010..016 - Корень: Plane-webhook (id
93f0c342-a614-4248-9d0f-c107276f5620) срабатывает на ЛЮБ\u041eЕ issue в workspace, без фильтра по проекту - ⚠️ ПОЗИТИВ: автономность реально работает — analyst exit=0, auto-commit, worktree (ORCH-2) сработал
Меры (сделано)
- 🛡️ Plane-webhook ДЕАКТИВИРОВАН в Plane postgres:
UPDATE webhooks SET is_active=false. Проверено:is_active=f- Plane postgres: контейнер
plane-app-plane-db-1,PGPASSWORD=plane, dbplane, userplane, tablewebhooks - Обратно включить после ORCH-6:
UPDATE webhooks SET is_active=true WHERE id=...
- Plane postgres: контейнер
- 🧹 Вычищено: все ветки ET-010..016 (git local+remote, 204), worktree
_wt/enduro-trails/*(root-owned → sudo rm), тестовые iso-A/iso-B, tasks≥19 в БД орка, agent_runs≥19 - Plane чист: orchestrator=7 (ORCH-1..7), enduro=5 (родные). Junk ET-issues в Plane не было (орк генерил ET-номера сам в git+БД)
- Заметка на сервере:
orchestrator/docs/INCIDENT_2026-06-02_webhook_autorun.txt
ROOT FIX = ORCH-6 (multi-repo)
plane.py:91repo=settings.default_repo→ нужен фильтр поplane_project_id+ маппинг repo per project- Пока ORCH-6 не сделан — webhook ДЕРЖАТЬ ВЫКЛЮЧЕННЫМ
Открытые вопросы
- Смержить PR #19 (enduro-trails) + PR #1 (orchestrator worktree)?
ORCH-6 (Multi-repo) — Dev-прогон (2026-06-02 ~19:20-19:28)
ТЗ
- Файл:
tasks/orchestrator/DEV_TASK_ORCH6_MULTIREPO.md(снайперское, все точки кода file:line собраны Стрим заранее) - Цель: реестр проектов (Plane id→repo+prefix) + фильтр webhook по проекту + resolve repo + plane_sync в правильный проект + prefix per project. Закрывает корень инцидента, снимает предохранитель.
- Маппинг по умолчанию: enduro
7a79f0a9-...→repo enduro-trails/ET; orchestrator8da6aa25-...→repo orchestrator/ORCH
Прогон 1 (упал по таймауту LLM на Task 2, не вина кода) — но сделал ~75%, ФУНКЦИОНАЛ РАБОТАЕТ
✅ Готово (Task 1-5), проверено вживую:
src/projects.py(4607 байт) — ProjectConfig + 4 резолвера + дефолт-реестр- plane.py — фильтр по проекту (unknown→ignored) + resolve repo
- db.py —
get_next_work_item_id(repo, prefix)per project (ORCH-001 vs ET-010) - plane_sync.py —
_resolve_project_id, параметризация (обратно совместимо) - gitea.py — unknown repo→ignored (3 хэндлера)
- Resolve-тест в контейнере прошёл: orchestrator→orchestrator/ORCH, enduro→enduro-trails/ET, unknown→None ✅
- Все файлы компилируются; тесты 37 passed / 9 failed (те же pre-existing 401/signature, baseline не сломан) ❌ НЕ доделано (Task 6-7): тесты test_projects/test_plane_webhook, коммит, PR, пересборка, доки. Всё в working tree (не закоммичено).
Решение: НЕ начинать заново, дослать Dev добивку (Task 6-7) — рабочие 75% терять глупо из-за инфра-таймаута
- Запущен 2-й прогон (taskName
orch6_finish/добивка), session subagent24ac376a... - ⚠️ Дубль-событие о падении прогона 1 (subagent
080bc9bc...) прилетело позже — уже обработано, NO_REPLY
КРИТИЧНО на потом
- 🚫 Webhook ОСТАЁТСЯ выключенным до моего финального ревью фильтра (иначе риск повторить инцидент)
- Включить webhook (
is_active=true) — мой шаг ПОСЛЕ проверки что фильтр реально режет unknown-проекты - Tokenator API: жив, ключ в
/home/slin/openclaw/data/.env(НЕ в orchestrator/.env). Ключ содержит|— bash sed/grep его режет, брать через Python - Plane API токен (60 симв) в orchestrator/.env РАБОЧИЙ — баг был в bash sed-парсинге, через Python HTTP 200
- Тесты орка — ТОЛЬКО в контейнере через образ (хостовый .venv сломан):
IMG=$(docker inspect orchestrator --format '{{.Config.Image}}'); docker run --rm -v /home/slin/repos/orchestrator:/code -w /code --entrypoint python3 $IMG -m pytest tests/ -q - Workspace
tasks/multi-agent/→tasks/orchestrator/ - Папка/контейнер/compose уже были
orchestrator - Plane задачи: ORCH-1 (F-2b), ORCH-2 (S-4), ORCH-3 (S-2/S-3), ORCH-4 (M-3), ORCH-5 (M-7)
Открытые вопросы Славе
- Смержить PR #19 (enduro-trails)?
- Смержить PR #1 (orchestrator worktree)?
ИНЦИДЕНТ: Plane-webhook авто-запустил конвейер по всем ORCH-1..7 (2026-06-02 19:00)
Что случилось
- Создала в Plane задачи ORCH-1..7 — Plane-webhook поймал каждую и авто-запустил конвейер (analyst→architect, auto-commit)
- Всё ушло в неправильный репо enduro-trails (
plane.py:91hardcoderepo=settings.default_repo), наплодило мусор ET-010..016 - Корень: Plane-webhook (id
93f0c342-a614-4248-9d0f-c107276f5620) срабатывает на ЛЮБ\u041eЕ issue в workspace, без фильтра по проекту - ⚠️ ПОЗИТИВ: автономность реально работает — analyst exit=0, auto-commit, worktree (ORCH-2) сработал
Меры (сделано)
- 🛡️ Plane-webhook ДЕАКТИВИРОВАН в Plane postgres:
UPDATE webhooks SET is_active=false. Проверено:is_active=f- Plane postgres: контейнер
plane-app-plane-db-1,PGPASSWORD=plane, dbplane, userplane, tablewebhooks - Обратно включить после ORCH-6:
UPDATE webhooks SET is_active=true WHERE id=...
- Plane postgres: контейнер
- 🧹 Вычищено: все ветки ET-010..016 (git local+remote, 204), worktree
_wt/enduro-trails/*(root-owned → sudo rm), тестовые iso-A/iso-B, tasks≥19 в БД орка, agent_runs≥19 - Plane чист: orchestrator=7 (ORCH-1..7), enduro=5 (родные). Junk ET-issues в Plane не было (орк генерил ET-номера сам в git+БД)
- Заметка на сервере:
orchestrator/docs/INCIDENT_2026-06-02_webhook_autorun.txt
ROOT FIX = ORCH-6 (multi-repo)
plane.py:91repo=settings.default_repo→ нужен фильтр поplane_project_id+ маппинг repo per project- Пока ORCH-6 не сделан — webhook ДЕРЖАТЬ ВЫКЛЮЧЕННЫМ
Открытые вопросы
- Смержить PR #19 (enduro-trails) + PR #1 (orchestrator worktree)?
ORCH-6 (Multi-repo) — Dev-прогон (2026-06-02 ~19:20-19:28)
ТЗ
- Файл:
tasks/orchestrator/DEV_TASK_ORCH6_MULTIREPO.md(снайперское, все точки кода file:line собраны Стрим заранее) - Цель: реестр проектов (Plane id→repo+prefix) + фильтр webhook по проекту + resolve repo + plane_sync в правильный проект + prefix per project. Закрывает корень инцидента, снимает предохранитель.
- Маппинг по умолчанию: enduro
7a79f0a9-...→repo enduro-trails/ET; orchestrator8da6aa25-...→repo orchestrator/ORCH
Прогон 1 (упал по таймауту LLM на Task 2, не вина кода) — но сделал ~75%, ФУНКЦИОНАЛ РАБОТАЕТ
✅ Готово (Task 1-5), проверено вживую:
src/projects.py(4607 байт) — ProjectConfig + 4 резолвера + дефолт-реестр- plane.py — фильтр по проекту (unknown→ignored) + resolve repo
- db.py —
get_next_work_item_id(repo, prefix)per project (ORCH-001 vs ET-010) - plane_sync.py —
_resolve_project_id, параметризация (обратно совместимо) - gitea.py — unknown repo→ignored (3 хэндлера)
- Resolve-тест в контейнере прошёл: orchestrator→orchestrator/ORCH, enduro→enduro-trails/ET, unknown→None ✅
- Все файлы компилируются; тесты 37 passed / 9 failed (те же pre-existing 401/signature, baseline не сломан) ❌ НЕ доделано (Task 6-7): тесты test_projects/test_plane_webhook, коммит, PR, пересборка, доки. Всё в working tree (не закоммичено).
Решение: НЕ начинать заново, дослать Dev добивку (Task 6-7) — рабочие 75% терять глупо из-за инфра-таймаута
- Запущен 2-й прогон (taskName
orch6_finish/добивка), session subagent24ac376a... - ⚠️ Дубль-событие о падении прогона 1 (subagent
080bc9bc...) прилетело позже — уже обработано, NO_REPLY
КРИТИЧНО на потом
- 🚫 Webhook ОСТАЁТСЯ выключенным до моего финального ревью фильтра (иначе риск повторить инцидент)
- Включить webhook (
is_active=true) — мой шаг ПОСЛЕ проверки что фильтр реально режет unknown-проекты - Tokenator API: жив, ключ в
/home/slin/openclaw/data/.env(НЕ в orchestrator/.env). Ключ содержит|— bash sed/grep его режет, брать через Python - Plane API токен (60 симв) в orchestrator/.env РАБОЧИЙ — баг был в bash sed-парсинге, через Python HTTP 200
- Тесты орка — ТОЛЬКО в контейнере через образ (хостовый .venv сломан):
IMG=$(docker inspect orchestrator --format '{{.Config.Image}}'); docker run --rm -v /home/slin/repos/orchestrator:/code -w /code --entrypoint python3 $IMG -m pytest tests/ -q
✅ ORCH-6 ДОДЕЛАН (прогон 2, ~19:35) — проверено мной вживую, НЕ на слово
- PR #2 (orchestrator, ветка
feature/ORCH-6-multirepo) — open, mergeable:True - 7 коммитов Conventional Commits
- Оба тест-файла созданы (test_projects, test_plane_webhook)
- Тесты: 57 passed (20 новых зелёных), 9 fail — те же pre-existing 401/TypeError, baseline ЦЕЛ
- Контейнер пересобран, health ok
- Resolve вживую: orchestrator→ORCH, enduro→ET, unknown→None ✅
- 🛡️ Webhook ОСТАЁТСЯ выключен (
is_active=f) — Dev не трогал, как и договорено
🔵 ЖДЁТ РЕШЕНИЯ СЛАВЫ (спросила, ОК пока нет)
- Смержить PR #2 (multi-repo) в main orchestrator
- После мержа — включить Plane-webhook (
UPDATE webhooks SET is_active=true) — теперь безопасно, фильтр режет чужие проекты
- Делать без ОК НЕ буду: мерж в main + включение автозапуска = живая автономная система
- Также висят: PR #19 (enduro-trails), PR #1 (orchestrator worktree)
Следующий бэклог ORCH (после ORCH-6 merge+webhook on)
- ORCH-1 (F-2b очередь задач вместо in-process daemon) — следующий приоритет
- ORCH-3 (S-2/S-3 rollback), ORCH-4 (M-3 stage-engine), ORCH-5 (M-7 идемпотентность webhook dedup)
ORCH-6 ЗАМЕРЖЕН + Webhook ВКЛЮЧЁН (2026-06-02 ~21:00) — проверено вживую
Сделано (с ОК Славы «Делай»)
- ✅ PR #2 смержен в main orchestrator (HTTP 200, merge commit
b021ff7) - ✅ Контейнер пересобран из main, health ok
- ✅ В main также прилетел
test_git_worktree.py(ORCH-2 хвост) — норма - ✅ Plane-webhook ВКЛЮЧЁН обратно:
UPDATE webhooks SET is_active=true→is_active=t, UPDATE 1
Боевой тест предохранителя (двойная защита, подтверждено на проде)
- 🛡️ HMAC-подпись: webhook без валидной подписи →
401 Invalid signature(секрет 40 симв настроен) - 🛡️ Фильтр проекта: webhook с ВАЛИДНОЙ подписью от неизвестного проекта →
200 {"status":"ignored","reason":"unknown project"}, логignoring event from unknown project (known: 2) - ✅ Задача НЕ создалась (11→11) — инцидент технически невозможен
Грабли (повтор из инцидента — записать чтоб не наступать)
- Postgres-пароль Plane:
\x27-экранирование кавычек через ssh+docker ЛОМАЕТСЯ. Рабочий способ — писать SQL в файл иpsql -f, пароль брать из env Plane-контейнера (len=5) - Plane postgres: контейнер
plane-app-plane-db-1, db/userplane
ORCH-1 (F-2b) — Персистентная очередь задач (2026-06-02 ~21:00)
Контекст проблемы (in-process архитектура)
launcher.launch()синхронно:subprocess.Popen(claude)+ 2 daemon-thread (_watchdogтаймаут-киллер 1800с +_monitor_agentждёт/коммитит/advance stage)- 8 точек вызова:
plane.py:189,234,308,389+gitea.py:126,203,275,300 - Беды: рестарт орка = агенты-сироты + потеря работы; нет лимита параллелизма; нет ретраев; webhook блокируется на спавне
ТЗ
tasks/orchestrator/DEV_TASK_ORCH1_QUEUE.md(снайперское, все file:line собраны заранее)- Решение: таблица
jobs(queued/running/done/failed) + atomicclaim_next_job+queue_worker.pyпетля +max_concurrency+ ретраи + requeue running на старте (restart-safe) +/queueэндпоинт
✅ Базовая очередь готова (PR #3) — проверено мной вживую
- 76 passed (19 новых тестов очереди, вкл. атомарность claim на 8 потоках/20 jobs), 9 fail — те же pre-existing 401
/queueживой: counts, max_concurrency, recent- PR #3 open, mergeable:True
- Фиксы B-1/B-2/M-1/ORCH-2/ORCH-6 не тронуты
- Живой прогон: queued→running→done, ретрай, restart-safe
⚠️ Resilience-слой Dev в базовый PR #3 НЕ встроил
- Моё уточнение (preflight/429/backoff/breaker) пришло когда Dev уже ушёл в финал T8-T12 → в коде НЕТ ни
preflight.py, ни классификатора 429, ни breaker, ни колонок backoff - Урок: при дослыле уточнения в активную сессию Dev — проверять, что оно реально вошло в код, а не только в отчёт «done»
ORCH-1b (Resilience-слой) — дослан отдельной задачей (2026-06-02 ~21:00)
Идея Славы (отличный вопрос про надёжность claude CLI)
- Два РАЗНЫХ зверя, лечить раздельно:
- CLI недоступен (бинарь/сеть) → дешёвый preflight
claude --version+ TCP, кэш 45с, токены НЕ жжёт. Мёртв → job ждёт в очереди, не падает - Rate limit 429 → предсказать НЕЛЬЗЯ; prompt-ping перед запуском = трата лимита, ТАК НЕ ДЕЛАТЬ. Ловить 429 на ВЫХОДЕ (паттерны в логе:
429/rate limit/overloaded/Retry-After), классифицировать transient vs permanent
- CLI недоступен (бинарь/сеть) → дешёвый preflight
- Backoff для transient: exp +
available_at/next_attempt_atколонка в очереди + уважатьRetry-After. Очередь = идеальное место для backoff - Circuit breaker: 3 фейла подряд → пауза 5 мин (CLI не дёргаем, лимит не выжигаем) + алерт → half-open проба → закрыли
- Ретраи раздельные: transient (429) ≠ code-fault (attempts=2)
Статус
- Задача
orch1b_resilienceзапущена на Dev (Opus 4.8), поверх той же ветки/PR #3 (фокусные коммиты) - Требует: безопасная миграция БД через PRAGMA-проверку (prod-база
jobsуже живая)
⚠️ Урок: тест-алерты дёргают Славу
- Dev гонял retry-тест с синтетическим
repo r-retry/ job 3 → fail-алерт долетел в Telegram, Слава испугался («Ау») - Проверка:
/queueвсё по нулям, в прод-БД никакогоr-retry/job 3 нет — жил только в эфемерной pytest-БД - TODO для ORCH-1b: подавить Telegram-нотификации в тестовых прогонах (нотификации только прод, не pytest)
Следующие шаги
- Дождаться
orch1b_resilience, проверить вживую (preflight без трат токенов, 429-классификатор, backoff, breaker, миграция) - Слить PR #3 (base queue + resilience) ОДНИМ куском после полной проверки
- Дальше бэклог: ORCH-3 (S-2/S-3 rollback), ORCH-4 (M-3 stage-engine), ORCH-5 (M-7 idempotency/webhook dedup)
Висящие вопросы Славе
- PR #19 (enduro-trails), PR #1 (orchestrator worktree) — мержить?
- PR #2 уже смержен (ORCH-6)