513 lines
38 KiB
Markdown
513 lines
38 KiB
Markdown
# 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:
|
||
```bash
|
||
# 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:
|
||
```bash
|
||
# 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-dev` → `orchestrator`
|
||
- 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-dev` → `orchestrator`
|
||
- 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=true` → `is_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)
|