Files
orchestrator/docs/history/LESSONS_ET006.md
Dev Agent 7c68d1d812
All checks were successful
CI / test (pull_request) Successful in 9s
docs(orchestrator): adopt enduro doc canon + CLAUDE.md + ADR (ORCH-9)
2026-06-05 12:33:55 +03:00

8.6 KiB
Raw Blame History

Lessons Learned — ET-006 (GPX Upload & Visualization)

Дата: 2026-05-22

Задача: ET-006 — Загрузка и визуализация GPX-треков


Что сработало хорошо

1. Review bounce — реальный баг найден и исправлен автоматически

Reviewer обнаружил P1: Math.min.apply(null, array) падает с RangeError на массивах >100K элементов. Developer пофиксил за 6 минут (attempt 2), второй review прошёл чисто. Вывод: reviewer в пайплайне оправдывает себя — ловит баги которые unit-тесты пропускают.

2. Auto-advance testing → deploy

Новый _try_advance_stage() в launcher сработал без ручного вмешательства.

3. Качество артефактов агентов

  • Analyst предусмотрел REQ-F-13 (persist GPX layers при map style switch) — предотвратил архитектурный bounce-back
  • Architect обосновал невозможность Web Worker (DOMParser отсутствует в WorkerGlobalScope)
  • Developer: ~1300 строк production + 700 строк тестов, все REQ покрыты
  • Tester: полный e2e с Playwright, 48 pass / 0 fail

4. Полный цикл с bounce

analysis → architecture → development → review (REQUEST_CHANGES)
→ development (fix P1) → review (APPROVED) → testing → deploy → done

Время: ~6.5 часов (включая ожидание API и e2e тесты)


Проблемы найденные

P1. Zombie processes после docker rebuild

Симптом: Monitor threads умирают при docker compose up --build, agent процессы остаются zombie. Влияние: Ручное вмешательство для commit/push и advance stage. Root cause: Daemon threads в Python не переживают restart контейнера, но child processes (claude.exe) наследуются init (PID 1).

P2. Stale reviews блокируют merge

Симптом: Tester пушит коммит после review approval → approval становится stale → merge отклоняется. Влияние: Ручной re-approve перед каждым merge. Root cause: Branch protection dismiss_stale_approvals: true.

P3. Plane sync 404

Симптом: plane_issue_id в orchestrator DB не совпадает с реальным UUID issue в Plane API. Влияние: State updates в Plane не работают (comments работают). Root cause: Webhook payload содержит ID объекта webhook event, не issue ID.

P4. Неполный event routing

Симптом: pull_request_rejected event type не роутился в handle_pr. Влияние: REQUEST_CHANGES от reviewer не откатывал задачу автоматически. Root cause: Gitea использует разные event types: pull_request, pull_request_approved, pull_request_rejected.

P5. Analyst не запускался автоматически

Симптом: После создания задачи через Plane webhook analyst не стартовал. Влияние: Ручной запуск analyst. Root cause: В handle_work_item_created не было вызова launcher.launch("analyst").

P6. Tester долгий (25 мин)

Симптом: Playwright e2e тесты с headless Chromium на GPX-фиче заняли 25 минут. Влияние: Долгое ожидание, watchdog timeout (30 мин) почти сработал. Root cause: Рендеринг 700K точек + установка зависимостей (Playwright, shapely) в runtime.


Решения

P1. Zombie processes → Entrypoint + orphan recovery

Решение A (быстрое): Добавить в Dockerfile:

RUN git config --global --add safe.directory '*'

Решение B (полное): Startup recovery в main.py:

@app.on_event("startup")
async def recover_orphaned_runs():
    """Mark orphaned runs (started but never finished) as failed."""
    conn = get_db()
    orphans = conn.execute(
        "UPDATE agent_runs SET finished_at=datetime('now'), exit_code=-1 "
        "WHERE finished_at IS NULL AND started_at < datetime('now', '-35 minutes')"
    ).rowcount
    conn.commit()
    if orphans:
        logger.warning(f"Recovered {orphans} orphaned agent runs")
    # Re-check tasks stuck in intermediate stages
    stuck = conn.execute(
        "SELECT id, stage, work_item_id, repo, branch FROM tasks "
        "WHERE stage NOT IN ('done', 'created')"
    ).fetchall()
    for task in stuck:
        # Try to advance if QG passes
        ...

Решение C (robust): Использовать tini как PID 1 в контейнере для proper zombie reaping:

RUN apt-get install -y tini
ENTRYPOINT ["tini", "--"]
CMD ["uvicorn", "src.main:app", ...]

P2. Stale reviews → Отключить dismiss или auto-re-approve

Решение A (простое): Отключить dismiss_stale_approvals:

curl -X PATCH '.../branch_protections/main' -d '{"dismiss_stale_approvals": false}'

Решение B (лучше): Auto-re-approve в launcher после tester push:

# В _monitor_agent, после успешного push для tester:
if agent == "tester":
    _reapprove_pr(repo, branch)

Рекомендация: Решение A — проще и безопаснее. В нашем пайплайне reviewer уже проверяет код, stale dismiss не добавляет ценности.

P3. Plane sync → Исправить маппинг ID

Решение: При work_item.created webhook сохранять правильный issue_id:

# В handle_work_item_created:
plane_issue_id = data.get("id")  # Это ID issue, не event
# Проверить через Plane API: GET /issues/{id} — если 404, искать по name

Диагностика: Сравнить plane_issue_id в DB с реальным через:

curl http://localhost:8091/api/v1/workspaces/ag_proj/projects/.../issues/?search=ET-006

P4. Event routing → Wildcard для pull_request_*

Решение:

if event_type == "push":
    await handle_push(payload)
elif event_type.startswith("pull_request"):
    await handle_pr(payload)
elif event_type == "status":
    await handle_ci_status(payload)

P5. Analyst auto-launch → Уже исправлено

Патч применён: launcher.launch("analyst") добавлен в handle_work_item_created.

P6. Tester долгий → Pre-bake dependencies

Решение A: Добавить Playwright и зависимости в Dockerfile:

RUN pip install playwright pytest-playwright shapely mapbox-vector-tile && \
    playwright install chromium --with-deps

Решение B: Разделить unit/integration и e2e тесты. Unit/integration — обязательные (быстрые), e2e — опциональные (по флагу в task description).

Решение C: Увеличить timeout для tester до 45 минут:

AGENT_CONFIGS = {
    "tester": {..., "timeout": 2700},  # 45 min
}

Приоритет исправлений

# Проблема Приоритет Усилие Решение
P1 Zombie processes HIGH Medium tini + startup recovery
P2 Stale reviews HIGH Low Отключить dismiss_stale_approvals
P4 Event routing HIGH Low startswith("pull_request")
P5 Analyst auto-launch DONE Уже исправлено
P6 Tester timeout MEDIUM Medium Pre-bake deps в Dockerfile
P3 Plane sync 404 LOW Medium Исправить маппинг ID

Метрики ET-006

  • Общее время: ~6.5 часов (00:20 → 06:45 UTC)
  • Agent runs: 7 (analyst, architect, developer×2, reviewer×2, tester)
  • Ручные вмешательства: 4 (zombie recovery×2, PR approve, event re-trigger)
  • Код написан агентами: ~2000 строк (1300 production + 700 tests)
  • Баги найдены reviewer: 1×P1, 3×P2, 6×P3
  • Баги исправлены developer: все P1 + все P2 + 3×P3