Files
wiki/memory/2026-06-02.md
2026-06-03 00:10:01 +03:00

38 KiB
Raw Permalink Blame History

2026-06-02 — Daily Log

ET-009: GPS Sources (EnduroRussia + Wikiloc) — Pipeline Completed 🎉

Pipeline stages (all passed):

  1. analysis — analyst (Sonnet), produced BRD, TRZ, acceptance criteria, test plans
  2. architecture — architect v2 (Opus 4.7), ADRs + infrastructure requirements
  3. development — developer (Opus 4.7 1M), 19 files, 1287 lines. Commit 3577ff3
  4. review — reviewer (Opus), found P1 bugs F-01, F-02
  5. development fix — developer (Sonnet), commit fc03746: 159 lines in gps_tracks.js
  6. review round 2 — reviewer (Opus), APPROVED, only P3 minors remain
  7. testing — tester (Sonnet), 25/25 pytest + 24/24 js tests PASS
  8. 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): _buildGpsFiltersUI pulls source_id from /api/gps-tracks/health.tracks_by_source
  • Attribution fix (F-02): attribution set at addSource time via _ensureGpsSources(map, attribution), not by mutating src.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: docker binary 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.md not 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-v4
    • openrouter/deepseek/deepseek-v4-pro
    • openrouter/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, project 7a79f0a9-5278-49cd-9007-9a338f238f9c
  • Orchestrator DB: task_id=16
  • Repo: /home/slin/repos/enduro-trails on 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):

  1. analysis — analyst (Sonnet), produced BRD, TRZ, acceptance criteria, test plans
  2. architecture — architect v2 (Opus 4.7), ADRs + infrastructure requirements
  3. development — developer (Opus 4.7 1M), 19 files, 1287 lines. Commit 3577ff3
  4. review — reviewer (Opus), found P1 bugs F-01, F-02
  5. development fix — developer (Sonnet), commit fc03746: 159 lines in gps_tracks.js
  6. review round 2 — reviewer (Opus), APPROVED, only P3 minors remain
  7. testing — tester (Sonnet), 25/25 pytest + 24/24 js tests PASS
  8. 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): _buildGpsFiltersUI pulls source_id from /api/gps-tracks/health.tracks_by_source
  • Attribution fix (F-02): attribution set at addSource time via _ensureGpsSources(map, attribution), not by mutating src.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: docker binary 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.md not 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-v4
    • openrouter/deepseek/deepseek-v4-pro
    • openrouter/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, project 7a79f0a9-5278-49cd-9007-9a338f238f9c
  • Orchestrator DB: task_id=16
  • Repo: /home/slin/repos/enduro-trails on 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-devorchestrator
  • Plane-проект orchestrator (identifier ORCH, id 8da6aa25-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)

Открытые вопросы Славе

  1. Смержить PR #19 (enduro-trails)?
  2. Смержить 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:91 hardcode repo=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, db plane, user plane, table webhooks
    • Обратно включить после ORCH-6: UPDATE webhooks SET is_active=true WHERE id=...
  • 🧹 Вычищено: все ветки 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:91 repo=settings.default_repo → нужен фильтр по plane_project_id + маппинг repo per project
  • Пока ORCH-6 не сделан — webhook ДЕРЖАТЬ ВЫКЛЮЧЕННЫМ

Открытые вопросы

  • Смержить PR #19 (enduro-trails) + PR #1 (orchestrator worktree)?

Нейминг — финальное решение

  • Единое имя: orchestrator
  • Gitea-репо переименован agent-devorchestrator
  • Plane-проект orchestrator (identifier ORCH, id 8da6aa25-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)

Открытые вопросы Славе

  1. Смержить PR #19 (enduro-trails)?
  2. Смержить 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:91 hardcode repo=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, db plane, user plane, table webhooks
    • Обратно включить после ORCH-6: UPDATE webhooks SET is_active=true WHERE id=...
  • 🧹 Вычищено: все ветки 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:91 repo=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; orchestrator 8da6aa25-...→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 subagent 24ac376a...
  • ⚠️ Дубль-событие о падении прогона 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)

Открытые вопросы Славе

  1. Смержить PR #19 (enduro-trails)?
  2. Смержить 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:91 hardcode repo=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, db plane, user plane, table webhooks
    • Обратно включить после ORCH-6: UPDATE webhooks SET is_active=true WHERE id=...
  • 🧹 Вычищено: все ветки 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:91 repo=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; orchestrator 8da6aa25-...→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 subagent 24ac376a...
  • ⚠️ Дубль-событие о падении прогона 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 не трогал, как и договорено

🔵 ЖДЁТ РЕШЕНИЯ СЛАВЫ (спросила, ОК пока нет)

  1. Смержить PR #2 (multi-repo) в main orchestrator
  2. После мержа — включить 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=trueis_active=t, UPDATE 1

Боевой тест предохранителя (двойная защита, подтверждено на проде)

  1. 🛡️ HMAC-подпись: webhook без валидной подписи → 401 Invalid signature (секрет 40 симв настроен)
  2. 🛡️ Фильтр проекта: webhook с ВАЛИДНОЙ подписью от неизвестного проекта → 200 {"status":"ignored","reason":"unknown project"}, лог ignoring event from unknown project (known: 2)
  3. Задача НЕ создалась (11→11) — инцидент технически невозможен

Грабли (повтор из инцидента — записать чтоб не наступать)

  • Postgres-пароль Plane: \x27-экранирование кавычек через ssh+docker ЛОМАЕТСЯ. Рабочий способ — писать SQL в файл и psql -f, пароль брать из env Plane-контейнера (len=5)
  • Plane postgres: контейнер plane-app-plane-db-1, db/user plane

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) + atomic claim_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
  • 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)