diff --git a/memory/2026-06-03.md b/memory/2026-06-03.md index 9f97bd0..88c3a2c 100644 --- a/memory/2026-06-03.md +++ b/memory/2026-06-03.md @@ -2,29 +2,35 @@ --- -## Plane per-agent authorship (Вариант A) — инфра ГОТОВА, код запущен (03.06 вечер) +## Plane per-agent authorship — ЗАВЕРШЕНО И ПОДТВЕРЖДЕНО (03.06) -**Задача Славы:** видеть в Plane КТО написал комментарий (агенты орка + Стрим), а не единый `mva154`. Выбран Вариант A (честные аккаунты), способ (b) — боты в БД. +### PR #9 `e9fd3052` ЗАМЕРЖЕН + прод пересобран +- Код: `config.py` (7 bot-полей), `plane_sync.py` (`PLANE_BOT_TOKENS`, `STAGE_AUTHORS`, `_headers_for(author)` fallback, `add_comment(author=)` POST под токеном бота), точки вызова прокидывают author. GET/PATCH под общим токеном (не тронуты). 166 passed (158+8), 9 baseline. +- ⚠️ Config-патч ОБЯЗАТЕЛЕН: образ уже содержит `ORCH_PLANE_BOT_*` env → без полей в config pydantic падает `extra_forbidden`. Прод поднялся → патч сработал. -### Инфра (СДЕЛАНО Стримом напрямую — это БД-операция, не код): -- **Plane self-hosted**, Docker (`plane-app-*`), БД `plane-app-plane-db-1`, креды `plane:plane`, db `plane`. -- Workspace `ag_proj` = `903e12e8-65c9-40a0-a7f6-0186f8af42d4`. -- **Ключевой факт:** автор комментария в Plane = владелец токена (`api_tokens.user_id`), НЕ label. Поэтому нужен отдельный user на агента. -- Было: 2 токена (`orchestrator`, `analyst-agent`) — ОБА на mva154 → всё под mva154. -- **Создано 7 сервис-ботов** (`is_bot=t`, role 15 member в ag_proj), email `@orch.local`, каждый со своим 60-симв сервисным токеном: - - 🧠 orch-analyst, 🏗️ orch-architect, 💻 orch-developer, 🔍 orch-reviewer, 🧪 orch-tester, 🚀 orch-deployer, 🌊 orch-stream (я) -- SQL-скрипт: `/tmp/plane_bots.sql` на сервере (идемпотентный, транзакция, ON CONFLICT). Потребовал `CREATE EXTENSION pgcrypto` (gen_random_bytes). -- **Бэкап БД перед записью:** `/home/slin/plane-identity-backup-1780472581.sql` (users+workspace_members+api_tokens). -- Токен Analyst-бота проверен живым GET → HTTP 200, видит 4 проекта. Авторство работает. -- **Токены в `.env`** (merge-append, блок «M-6.5 Plane per-agent»): `ORCH_PLANE_BOT_ANALYST/ARCHITECT/DEVELOPER/REVIEWER/TESTER/DEPLOYER/STREAM`. Бэкап `.env.bak-`. +### 🔑 ГЛАВНЫЙ УРОК: 403 → project_members +- Боты были в **workspace_members**, но комментить можно только **project_members**. POST коммента давал **403 Forbidden** (аутентификация ок, прав нет). +- Фикс: добавила 7 ботов в `project_members` проекта `7a79f0a9-...` (role 15, member). Бэкап `plane-projmembers-backup-*`. +- ⚠️ NOT NULL `member_id` — без него INSERT падал (транзакция откатывалась молча). Правильный INSERT: id, role, **member_id**, project_id, workspace_id, view_props/default_props/preferences='{}', sort_order=65535, is_active, created_at, updated_at. -### Код (Dev, ветка `feature/plane-per-agent-author`, ТЗ `DEV_TASK_PLANE_PER_AGENT_AUTHOR.md`): -- `config.py`: 7 полей bot-токенов. -- `plane_sync.py`: `PLANE_BOT_TOKENS` map + `_headers_for(author)` (fallback на общий токен если роль пуста/токен пуст). `add_comment(..., author=None)` — POST под токеном агента. GET/PATCH НЕ трогать (под общим токеном). -- Точки вызова прокидывают author по роли стадии: stage_engine (284/305/316 analyst, 369 tester, 409 architect), launcher:472 (текущий агент), webhooks/plane (212/255 analyst, 267 целевая стадия), plane_sync stage-уведомления (255 🔄 → stream, 267 ✅ → deployer). Неочевидное → `stream`. -- Baseline 158 passed. Тесты `tests/test_plane_author.py`. -- ⚠️ Мерж — Стрим после живой проверки + реальный тест-комментарий от каждого бота в Plane. +### ✅ БОЕВАЯ ПРОВЕРКА ПРОЙДЕНА (proof из БД) +- Каждый из 7 ботов запостил коммент на живую ET-009 (`64e98247-...`) → **HTTP 201**. +- `issue_comments JOIN users ON actor_id` показал авторов: 🧠 Analyst / 🏗️ Architect / 💻 Developer / 🔍 Reviewer / 🧪 Tester / 🚀 Deployer / 🌊 Стрим — НЕ mva154. +- Тестовые комменты убраны (soft-delete `deleted_at`, UPDATE 7 → 0 живых). -### Закрыто разведкой (НЕ требовало работы): -- Хук enduro-trails swap — УЖЕ применён (live md5 == кандидат `2b60c65b...`). Бэкап `.bak-1780468526` цел. -- `.env` Gitea-токен — УЖЕ синхронизирован (40 симв == контейнер). Заметка Dev устарела. +### ⚠️ ГРАБЛЯ shell/psql (потеряла время — на будущее) +- heredoc через `ssh '...'` с вложенными кавычками/скобками в python/SQL — постоянно ломается (глотает вывод, `(` unexpected, кавычки съедаются). +- psql `-v var=...` без кавычек = идентификатор (column "font" does not exist). +- `scp` в контейнере НЕТ. +- **РАБОЧИЙ способ передать скрипт на сервер:** `write` локально → `base64 -w0` → `echo '' | base64 -d > /tmp/x` на сервере → `docker cp` → `psql -f`. Надёжно, без экранирования. + +### Plane identity — справочник +- БД Plane: контейнер `plane-app-plane-db-1`, user `plane`, пароль = `docker exec plane-app-api-1 printenv POSTGRES_PASSWORD`. +- Workspace `ag_proj` = `903e12e8-65c9-40a0-a7f6-0186f8af42d4`. Главный проект enduro = `7a79f0a9-5278-49cd-9007-9a338f238f9c`. +- 7 ботов: email `@orch.local`, `is_bot=t`, в workspace_members(role 15) И project_members(role 15). Токены 60-симв в `.env` `ORCH_PLANE_BOT_`. +- Автор коммента = `issue_comments.actor_id` = владелец токена. Роли: ANALYST/ARCHITECT/DEVELOPER/REVIEWER/TESTER/DEPLOYER/STREAM. +- ⚠️ При создании НОВЫХ проектов в Plane — ботов надо добавлять в project_members нового проекта, иначе 403. (Кандидат на автоматизацию: при ORCH-6 resolve проекта — авто-добавление ботов.) + +### ИТОГ дня 03.06 +Закрыто: ORCH-1..7, L1L2L3, M-6, Plane per-agent authorship (Вариант A, боты). Всё в проде, проверено вживую. +Открыто (НЕ срочно): авто-добавление ботов в project_members при новом проекте. diff --git a/tasks/orchestrator/reports/dev-2026-06-03-plane-per-agent-author.md b/tasks/orchestrator/reports/dev-2026-06-03-plane-per-agent-author.md new file mode 100644 index 0000000..3423174 --- /dev/null +++ b/tasks/orchestrator/reports/dev-2026-06-03-plane-per-agent-author.md @@ -0,0 +1,83 @@ +# Dev Report: Plane per-agent comment authorship +Дата: 2026-06-03 +Статус: DONE (PR открыт, НЕ смержен — мерж за Стримом) + +## Задача +Комментарии в Plane должны постится под токеном агента-бота, чтобы был виден +реальный автор (analyst/architect/dev/reviewer/tester/deployer/Стрим), а не +единый mva154. Только код — токены/БД Plane/инфра уже готовы. + +## Сделано +- [x] Ветка `feature/plane-per-agent-author` из свежего main +- [x] config.py: 7 полей bot-токенов (env ORCH_PLANE_BOT_*, дефолт "") +- [x] plane_sync.py: PLANE_BOT_TOKENS, STAGE_AUTHORS, _headers_for(), add_comment(author=) +- [x] Прокинут author во все точки вызова +- [x] GET/PATCH НЕ тронуты (под общим токеном) +- [x] tests/test_plane_author.py — 8 тестов, все passed +- [x] Conventional Commits (2 коммита) +- [x] Push + remote проверен + PR #9 + +## Изменённые файлы +- `src/config.py` — +7 полей plane_bot_* +- `src/plane_sync.py` — PLANE_BOT_TOKENS, STAGE_AUTHORS, _headers_for, add_comment(author=), notify_* проброс +- `src/stage_engine.py` — author= в 5 plane_add_comment +- `src/agents/launcher.py` — author= в plane_add_comment (deploy failed) +- `src/webhooks/plane.py` — author= в 5 точках +- `tests/test_plane_author.py` — НОВЫЙ + +## Таблица: точка вызова → выбранный author +| Файл | Строка/контекст | Текст (суть) | author | +|------|-----------------|--------------|--------| +| stage_engine.py | ~284 | BRD/ТЗ/AC/TestPlan готовы, прошу review | analyst | +| stage_engine.py | ~305 | Analyst нуждается в уточнении (вопросы) | analyst | +| stage_engine.py | ~316 | Analyst завершился без артефактов | analyst | +| stage_engine.py | ~369 | Тесты не прошли, Developer перезапущен (QG tester) | tester | +| stage_engine.py | ~409 | Architect нашёл конфликт с ТЗ, возврат в Analysis | architect | +| agents/launcher.py | ~472 | Deploy FAILED, rolled back | deployer (agent=="deployer" в контексте) | +| webhooks/plane.py | ~212 | Analyst запущен | analyst | +| webhooks/plane.py | ~255 | Analyst перезапущен (rejected) | analyst | +| webhooks/plane.py | ~267 | Откат: current→prev | STAGE_AUTHORS[prev_stage] (агент целевой стадии), fallback stream | +| webhooks/plane.py | ~310 | 3 раунда уточнений исчерпаны | analyst | +| webhooks/plane.py | ~329 | Analyst перезапущен с ответами стейкхолдера | analyst | +| plane_sync.notify_stage_change | 🔄 Stage | переход стадий | **stream** | +| plane_sync.notify_qg_failure | ⚠️ QG failed | провал QG | STAGE_AUTHORS[stage], fallback stream | +| plane_sync.notify_done | ✅ Task completed | задача завершена | **deployer** | + +Соответствует ТЗ. Неочевидных точек, потребовавших произвольного "stream", +не возникло — у webhook:267 (откат) использован STAGE_AUTHORS по целевой стадии, +fallback на stream если стадия вне карты. + +## _headers_for / fallback +```python +def _headers_for(author): + tok = PLANE_BOT_TOKENS.get(author or "") if author else None + return {"X-API-Key": tok} if tok else PLANE_HEADERS +``` +None / неизвестная роль / пустой токен → PLANE_HEADERS (общий orchestrator-токен, +автономность). Только POST add_comment использует _headers_for; GET/PATCH — PLANE_HEADERS. + +## Результат тестов +- tests/test_plane_author.py: **8 passed** +- Полный прогон: **166 passed, 9 failed** + - 158 baseline + 8 новых = 166 ✓ + - 9 failed — все в tests/test_webhooks.py (401 invalid signature + 1 каскадный + TypeError от 401). Это документированный pre-existing baseline (9 pre-existing 401), + к моему коду отношения не имеют. +- Контейнер: `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_PLANE_BOT_* env-переменные.** При прогоне + тестов на ЧИСТОМ main (без полей в config.py) pydantic падает с `extra_forbidden` + — то есть мой config.py-патч ОБЯЗАТЕЛЕН для работоспособности на живом хосте. + На моей ветке всё валидно. +- На сервере был отдельный pre-existing `git stash` (WIP ORCH-1) — НЕ трогал, он на месте. +- `.env.bak-1780472695` — pre-existing untracked файл, не мой, не трогал. +- Gitea-токен из env контейнера (c81227...) рабочий, совпадает с origin URL; PR создан им. + +## Git / PR +- Коммиты: + - `30d6dd0 feat(config): add per-agent Plane bot token settings` + - `d305521 feat(plane): per-agent bot authorship for comments` +- `git log origin/main..origin/feature/plane-per-agent-author` → ОБА коммита присутствуют на remote ✓ +- PR: **#9** → https://git.mva154.duckdns.org/admin/orchestrator/pulls/9 (base: main) +- НЕ деплоил, НЕ мержил. Мерж — Стрим, после живой проверки + реального тест-комментария от каждого бота.