192 lines
28 KiB
Markdown
192 lines
28 KiB
Markdown
|
||
|
||
---
|
||
|
||
## Конвейер UX — статусная модель + токены (03.06 день, в работе)
|
||
|
||
### Решения Славы по статусной модели (ПОДТВЕРЖДЕНЫ):
|
||
- **Бэклог в Plane.** Задача лежит в Backlog/Todo/Triage пока Слава не переведёт в **In Progress** → только это запускает конвейер (analyst). Сейчас триггер = work_item.created (любой тикет сразу стартует) — НАДО починить.
|
||
- **Вердикт статусами (вариант B):** статус **Approved** = advance, **Rejected** = rollback. Комменты `:approved:`/`:rejected:` ОСТАВИТЬ параллельно. Причину reject Слава пишет комментом.
|
||
- **Стадии видимы на доске:** architecture/development/review/testing — отдельными статусами, не скрыты в In Progress.
|
||
- **Расход токенов по агентам:** показывать (A) в комменте каждого агента + (B) итог-сводка от Deployer.
|
||
|
||
### Механика конвейера (по факту кода, для справки):
|
||
- Все 6 агентов работают над ОДНОЙ задачей = 1 тикет Plane = 1 feature-ветка, комментят в неё (теперь под своими именами).
|
||
- Статус сейчас меняется только: in_review (analyst ждёт approve), needs_input (вопросы), blocked, in_progress, done. Стадии architecture/dev/review/testing невидимы.
|
||
- 2 ручных гейта: analyst→ждёт :approved: (In Review); reviewer→:approved:. Остальное едет автоматически.
|
||
- Needs Input: analyst пишет `01-questions.md`, статус Needs Input, ждёт. Слава отвечает обычным комментом → analyst перезапуск. Лимит 3 раунда → Blocked + Telegram-алерт.
|
||
- Агенты = **Claude CLI** (`/opt/claude-code/bin/claude.exe --print`), вывод в лог. Версия 2.1.142.
|
||
|
||
### ИНФРА сделана Стримом (БД Plane, бэкап states `plane-states-backup-*`):
|
||
6 новых статусов в проекте enduro (`7a79f0a9-...`), группа started, в правильном порядке доски:
|
||
```
|
||
architecture=3020bbb7-6122-4663-930c-0315ba8dfa3d development=9920609b-f140-4e46-ab95-89acda8412c8
|
||
review=ba0d802c-5218-41d4-ab43-978b0ea123ed testing=7855d807-b1bf-42ef-8dae-6cde0df92d02
|
||
approved=a519a341-dada-4a91-8910-7604f82b79c5 rejected=ba958f3c-5db5-461d-8f82-89425e413b97
|
||
```
|
||
|
||
### CLI usage подтверждён вживую (для фичи токенов):
|
||
`claude --output-format json` отдаёт: `total_cost_usd`, `usage.{input_tokens,output_tokens,cache_read_input_tokens,cache_creation_input_tokens}`, `modelUsage`, `num_turns`, `duration_ms`. Сейчас запуск plain-text (`--print` без формата) → usage НЕ собирается. agent_runs (id,task_id,agent,started/finished,exit_code,output_path) — НЕТ полей токенов, надо ALTER.
|
||
|
||
### Код — Dev, ветка `feature/pipeline-ux`, ТЗ `DEV_TASK_PIPELINE_UX.md` (4 фичи):
|
||
1. Старт по статусу (in_progress), не по created. Идемпотентно (задача уже есть → не дублить).
|
||
2. Вердикт-статусы Approved/Rejected (+ комменты живы).
|
||
3. Видимость стадий: PLANE_STATES += 6 UUID, set_issue по стадии (Needs Input/Blocked приоритетны).
|
||
4. Токены: `--output-format json`, ALTER agent_runs (+input/output/cache/cost), коммент агента + сводка Deployer.
|
||
- ⚠️ Статусы per-project — ОСТАВИТЬ TODO (ORCH-10 эпик), не переделывать резолв сейчас.
|
||
- Baseline 166 passed. Мерж — Стрим после живой проверки.
|
||
|
||
### Recraft (попутно, 03.06): модель OpenRouter = `recraft/recraft-v4.1` (НЕ в каталоге /models, но работает). Дёргать chat/completions с `modalities:["image"]` (только image, без text — иначе 404). Сгенерила пляжные картинки Славе.
|
||
|
||
|
||
---
|
||
|
||
## PR #10 СМЕРЖЕН в main (03.06, вечер) — конвейер UX
|
||
|
||
**Merge commit main = `4773137`.** Проверено вживую перед мержем (не на слово Dev):
|
||
- 5 коммитов на remote: `a4668c0` feat(plane) stage visibility+verdict UUIDs, `09b1c5e` feat(webhook) старт на In Progress, `38a741d` feat(webhook) вердикт Approved/Rejected (вариант B), `9a702a0` feat(metrics) токены/cost per-agent, `7fd6529` test(conftest) глушилка Telegram.
|
||
- **Прогон тестов сама: 190 passed, 9 failed.** Девять — pre-existing baseline (сравнила полную сюиту на main ДО ветки = те же 9). Regression = 0. Из девяти: 8 это 401-invalid-signature, 1 это `test_plane_approved` TypeError — ВСЕ падали и на main. ⚠️ Уточнение к прошлым заметкам: реальный baseline = 9 (не только 401-набор).
|
||
- **Telegram-утечка закрыта:** `tests/conftest.py` autouse-фикстура глушит `send_telegram` во всех тестах. Sentinel-проверка: 0 запросов в api.telegram.org за прогон. Покрыты модули: notifications (источник), stage_engine (module-level import — критичный), plane/launcher/queue_worker/main (local imports, raising=False). Источник шума «🔄 ET-100» = тест `test_webhook_dedup` гонялся на проде без мока.
|
||
|
||
### ✅ ЗАДЕПЛОЕНО (03.06 ~16:10 UTC)
|
||
Деплой = rebuild образа + recreate (код COPY в образ из `src/`, НЕ bind-mount; `data/` — bind-mount, переживает). Команда: `git checkout main && git pull && docker compose up -d --build`. Бэкап БД: `data/orchestrator.db.bak-1780503005`.
|
||
- ⚠️ Перед сборкой репо был на `feature/pipeline-ux` — обязательно `git checkout main` (иначе соберётся ветка).
|
||
- Контейнер `Up`, uvicorn:8500, queue worker стартовал, ошибок нет. Образ на `4773137`.
|
||
- **Миграция agent_runs прошла:** добавились `input_tokens, output_tokens, cache_read_tokens, cost_usd`. БД цела (11 задач).
|
||
|
||
### Боевые тесты статусной модели на проде (вживую, HMAC-подписанные webhook):
|
||
- ✅ **ТЕСТ 1 (created НЕ стартует):** `work_item.created` → HTTP 200, задач создано 0, только soft QG-0 warning в лог. Бэклог-режим работает.
|
||
- ✅ **ТЕСТ 2b (idempotency):** In Progress для существующей задачи (f9009756) → лог `task already exists (stage=analysis), not restarting`, 11→11 задач. Защита handle_comment работает.
|
||
- ⏳ **ТЕСТ 2a (позитивный старт)** не делала: запустит реальный analyst (токены + ветка в Gitea). Спросила Славу прежде чем плодить мусор.
|
||
- ⚠️ Грабля: UUID In Progress = `b873d9eb-993c-48cd-97ac-99a9b1623967`. State UUID извлекается из `data.state.id` (или bare string).
|
||
- HMAC секрет: `ORCH_PLANE_WEBHOOK_SECRET` (len 40). Подпись: `printf %s BODY | openssl dgst -sha256 -hmac SECRET`, заголовок `X-Plane-Signature`.
|
||
|
||
### После деплоя — боевой тест (план):
|
||
Завести задачу в Backlog → перевести в In Progress (должен стартовать analyst, НЕ на created) → провести по доске (видеть переезд по колонкам Architecture→…→Testing) → показать Славе токены живьём (коммент агента `💻 Developer · Nk in / Mk out · $X` + сводка Deployer). Боевой usage-тест на ветке уже дал `💻 Developer готов · 6 in / 15 out · $0.06`.
|
||
|
||
### Формат Plane-webhook на смену статуса (Dev нашёл по реальному payload):
|
||
`event="issue", action="updated"`, новый статус в `data.state.id`. Старт ловит переход в In Progress из бэклог-статуса. Идемпотентность: задача уже в БД tasks → не дублить/не перезапускать.
|
||
|
||
---
|
||
|
||
## Первый штатный тикет в Plane после фичи-1 (03.06 16:56)
|
||
- **Тикет создан штатно в Backlog** (не в обход!) — фича-1 наконец позволяет: создание НЕ запускает конвейер.
|
||
- **ET-? seq=6**, id `bfb4866c-4b69-4f97-916b-e7233d8259de`, name «Скачивание трека из popup на карте (enduro-trails)», state=Backlog (`113b24f6-...`).
|
||
- ✅ Проверено: 0 задач в оркестраторе, конвейер не стартанул. Бэклог работает в бою.
|
||
- Суть фичи (запрос Славы): тап по треку на карте → в popup с инфо кнопка «Скачать» → отдать файл трека (GPX обяз., KML опц.). Источник: пользовательские треки на карте (enduro-trails). Нужен бэкенд-эндпоинт отдачи трека по id + Content-Disposition.
|
||
- **Создание issue через Plane REST:** токен `ORCH_PLANE_API_TOKEN` (len 60, общий orchestrator-токен), `POST http://localhost:8091/api/v1/workspaces/ag_proj/projects/<proj>/issues/`, заголовок `X-API-Key`, тело `{name, state, description_html}`. Backlog UUID = `113b24f6-cce8-4be9-9a22-a359b9cf0122`.
|
||
|
||
---
|
||
|
||
## Боевой запуск #6 (ET-006) — баги вскрыты, чистка сделана (03.06 ~18:00)
|
||
|
||
### Что РАБОТАЕТ (доказано в бою):
|
||
- ✅ Триггер по статусу In Progress (после фикса webhook URL)
|
||
- ✅ Токены считаются: run 59 analyst → 27 in / 36851 out / $2.13 записаны в agent_runs
|
||
- ✅ Per-agent authorship: комменты под именем analyst
|
||
- ✅ Webhook URL фикс: `http://172.21.0.1:8500/webhook/plane` (Plane не резолвит DuckDNS — docker-сеть изолирована; старый внешний URL давал 500). UPDATE webhooks SET url в БД Plane сделан.
|
||
|
||
### БАГИ (для Dev):
|
||
1. **issue.updated без description → QG-0 падает в Blocked.** Plane на смену статуса шлёт только изменённые поля, `description`/`description_stripped` пустые. `start_pipeline` читает описание из webhook payload → QG-0 «Description < 20 символов» → задача в Blocked. ФИКС: тянуть описание через GET Plane API (issue detail) в start_pipeline, не из payload.
|
||
2. **Коллизия work_item_id + рассинхрон веток.** M-6 выдал `ET-006` ПОВТОРНО: task 8 (plane 9884fb9c, 22 мая, gpx-upload, done) и task 25 (plane bfb4866c, сегодня, popup-enduro-trails). Worktree резолвится по work_item_id → analyst run 59 писал в ЧУЖОЙ worktree (gpx-upload task 8), а не в свой (popup task 25). Гейт check_analysis_complete искал артефакты в branch task 25 → не нашёл → не перевёл в In Review. ФИКС: get_next_work_item_id должен гарантировать уникальность (не переиспользовать seq); worktree/ветка должны привязываться к task_id, не к work_item_id.
|
||
|
||
### Чистка ET-006 (сделана, бэкап БД orchestrator.db.bak-clean-*):
|
||
- Удалён дубль task 25 + его runs из БД.
|
||
- Удалён мусорный worktree feature_ET-006-gpx-upload.
|
||
- Откачен мусорный коммит 6edf97f (analyst run 59 в чужую ветку) → force-push origin/feature/ET-006-gpx-upload на d379e48.
|
||
- Тикет #6 (bfb4866c, seq 6) → Backlog, описание на месте. Готов к повторному чистому запуску ПОСЛЕ фикса бага 1.
|
||
|
||
---
|
||
|
||
## PR #11 (баги конвейера) — смержен + задеплоен + ОБА бага побеждены в бою (03.06 ~18:15)
|
||
- Merge main `cd73c75`. Деплой: rebuild+recreate, образ на cd73c75. Бэкап orchestrator.db.bak-deploy11-*.
|
||
- Мой прогон: 195 passed (190+5 новых), 9 baseline (те же, regression 0).
|
||
- **Баг1 фикс работает:** лог `start_pipeline: pulled description from Plane API (445 chars)` → QG-0 прошёл, НЕ Blocked. Функция fetch_issue_description в plane_sync (переиспользует GET issue endpoint + PLANE_HEADERS).
|
||
- **Баг2 фикс работает:** лог `work_item_id collision: derived ET-006 already in use; reassigned -> ET-011`. Guard ensure_unique_work_item_id в db.py (поверх M-6 derive). Ветка уникальна per task.
|
||
- Боевой перезапуск #6: task 26 = ET-011, analyst запущен (job_id=7).
|
||
- ⚠️ Мелочь: ветка `feature/ET-011-untitled` (slug untitled — в тестовом webhook не было name; реальный Plane шлёт name, не критично).
|
||
- ⚠️ Дедуп webhook по телу: повторный идентичный payload → {"status":"duplicate"}. Для теста уникализировать тело (activity_id).
|
||
|
||
---
|
||
|
||
## PR #11 — финальный отчёт Dev (03.06 ~18:25, дополнение)
|
||
- **Баг1 (description):** `src/plane_sync.py` → `fetch_issue_description(issue_id, project_id)` — переиспользует GET issue-detail + shared-токен `PLANE_HEADERS` (как `fetch_issue_sequence_id`). Берёт `description_stripped`, при пустом стрипает `description_html` (`_strip_html`). На ошибке → `""` (не бросает). Вызов в `start_pipeline` ПЕРЕД QG-0. Если и API пусто → честный QG-0 fail.
|
||
- **Баг2a (uniqueness):** `src/db.py` → `ensure_unique_work_item_id(work_item_id, repo)` — guard ПОВЕРХ M-6 derive (derive не тронут). ET-NNN занят в tasks для repo → шагает вперёд. Изоляция по repo. Warning при реассайне.
|
||
- **Баг2b (worktree, ~15 строк):** worktree в `git_worktree.py` ключуется по branch, таски реверс-резолвятся по `(repo, branch)`. С 2a work_item_id уникален → префикс ветки уникален. Доп. страховка: занятая ветка → `feature/{work_item_id}-{plane_id[:8]}` + warning. Сам git_worktree.py НЕ переписан (достаточно уникальности ветки).
|
||
- Тесты: `tests/test_pipeline_start_bugs.py` — 5 новых passed. Коммиты `fa74610`, `ac9f5a0`, `c69e113`.
|
||
|
||
## Уроки tooling (03.06)
|
||
- **Маски ломают bash/psql/python-heredoc:** кавычки и спецсимволы в маскированных значениях рвут командную строку и `python3 -c`. Решение: писать значения во временный bash/sql-скрипт через `write`, исполнять файлом — масок нет внутри write.
|
||
- **`<pending>`/`<>` в .env ломают `source`:** строка вида `HEYGEN_TALKING_PHOTO_ID=<pending>` — `<>` интерпретируется как редирект. На ключи не влияет, но `source .env` падает. Чистить такие placeholder-строки или грепать конкретный ключ.
|
||
- **Plane DNS-изоляция:** Plane-контейнеры (docker-сеть 172.21.0.0/16) НЕ резолвят внешние домены даже через 8.8.8.8. Оркестратор в host-сети — резолвит. Поэтому webhook URL в БД Plane = `http://172.21.0.1:8500/webhook/plane` (внутренний gateway), НЕ внешний DuckDNS-домен. Это уже починено, НЕ трогать.
|
||
- **Plane `issue.updated` шлёт только изменённые поля** — на смене статуса description отсутствует. Любая логика, требующая полей тикета на updated-событии, должна дотягивать их из Plane API, а не из payload.
|
||
- **Webhook-дедуп по телу:** идентичный payload → `{"status":"duplicate"}`. Для повторного теста уникализировать тело (напр. activity_id/timestamp).
|
||
|
||
## Tokenator — лимит исчерпан (03.06)
|
||
- Ключ `TOKENATOR_API_KEY` (`sk-fp-...5625`), baseUrl `https://api.tokenator.top/v1`.
|
||
- Месячная квота: 200,000,000 токенов. Потрачено 200,116,633 → remaining −116,633. Всё блокируется (`Token limit exceeded`), включая `/v1/models`.
|
||
- Нет эндпоинтов usage/account/limits (404). Расход виден в теле ошибки completions: `{"error":"Token limit exceeded","usage":{"remaining":...,"token_limit":...,"tokens_used":...}}`.
|
||
- `.dev`-домен даёт SSL exit 35; `.top` (из openclaw.json) — рабочий.
|
||
- Не блокирует OpenClaw — авто-фолбэк на другие провайдеры (OpenRouter DeepSeek/Grok). Claude CLI агентов (analyst и т.д.) Tokenator не касается.
|
||
|
||
## Открытый хвост (для следующей сессии)
|
||
- Боевой #6 перезапущен как task 26 / **ET-011**, analyst (job_id=7) запущен ~18:15. Проверить: дошёл ли до In Review, появилось ли уведомление с кнопкой одобрения, в правильную ли ветку писал.
|
||
- Tokenator: ждать сброса квоты (вероятно 1-е число) или писать саппорту на повышение лимита.
|
||
|
||
---
|
||
|
||
## БАГ 3 — самоудар по эхо-комменту: In Review → In Progress (03.06 ~18:30)
|
||
**Симптом:** analyst довёл #6 (ET-011) до In Review корректно (баг2 фикс работает!), но через 0.1с статус откатился обратно в In Progress. На скрине Славы State=In Progress, уведомления с :approved: нет.
|
||
**Цепочка (лог 18:17:05):**
|
||
1. analyst PATCH → In Review (38fb1f64) ✅
|
||
2. analyst постит коммент «BRD/ТЗ готовы. Жду :approved:» (author=analyst)
|
||
3. Этот коммент эхом прилетает в `handle_comment` (src/webhooks/plane.py ~433)
|
||
4. Коммент без :approved:/:rejected:, а `current_stage=="analysis"` → код трактует как «ответ человека на вопросы аналитика» → `set_issue_in_progress(work_item_id)` → ОТКАТ In Review→In Progress 🐛
|
||
**Корень:** handle_comment НЕ отличает собственный коммент бота/агента от ответа человека. Любой не-вердиктный коммент на стадии analysis → возврат в In Progress. analyst сам себя сбивает.
|
||
**Фикс (для Dev):** в handle_comment игнорировать комменты, автором которых является бот/агент (analyst/architect/... или служебный actor). Проверять author/actor вебхука: если это наш сервисный аккаунт или один из агентов — return (no action). Только комменты РЕАЛЬНОГО человека (Слава) должны триггерить approved/rejected/answer-to-questions.
|
||
**NB:** PLANE_STATES в Enduro Trails корректен — один In Progress (b873d9eb). «5 In Progress» ранее — статусы ДРУГИХ проектов, ложная тревога.
|
||
**Состояние:** #6 сейчас In Progress (откачен), task 26 stage=analysis, артефакты в feature/ET-011-untitled готовы. После фикса бага3 — повторить и убедиться что In Review держится.
|
||
|
||
---
|
||
|
||
## РЕШЕНО: чистая статусная модель управления конвейером (03.06, подтверждено Славой)
|
||
Слава управляет конвейером ТОЛЬКО статусами. Комменты НИКОГДА не триггерят переходы. Финальная модель:
|
||
- **Одобрение** → Слава ставит статус **Approved** → оркестратор двигает на след. стадию (сам ставит статус стадии).
|
||
- **Отклонение** → Слава СНАЧАЛА пишет коммент с причиной, ПОТОМ ставит **Rejected** → оркестратор откатывает + читает причину из последнего коммента.
|
||
- **Ответ на вопросы analyst** (задача в Needs Input) → Слава пишет коммент(ы), ПОТОМ САМ возвращает статус в **In Progress** → оркестратор перезапускает агента текущей стадии (читает комменты). Триггер = СТАТУС In Progress, не коммент.
|
||
- Комментный механизм (:approved:/:rejected:/answer-by-comment) — ВЫПИЛИВАЕТСЯ полностью.
|
||
ТЗ: tasks/orchestrator/DEV_TASK_STATUS_ONLY_VERDICT.md
|
||
Ключевая правка vs прошлого PR: handle_status_start теперь должен ПЕРЕЗАПУСКАТЬ агента при возврате In Progress из Needs Input (не просто idempotent-skip), отличая от защиты-дублей через running-job/prev-status.
|
||
|
||
---
|
||
|
||
## PR #12 — статус-онли модель + баг 3 закрыт, боевой прогон удачен (03.06 ~19:25)
|
||
|
||
**Merge main = `2d392b6`.** Ветка `fix/status-only-verdict` (из main с PR #11). Задеплоен (rebuild+recreate).
|
||
|
||
### Что выпилено/изменено (src/webhooks/plane.py):
|
||
- **handle_comment → чистый логгер.** Весь комментный механизм управления убран: ветки `:approved:` (~427), `:rejected:` (~420), answer-to-questions `if current_stage=="analysis"` (~433-490). Ни один коммент не меняет статус и не запускает агентов. Router routes comment.created → только лог. Корень бага 3 (эхо-самоудар) устранён.
|
||
- **handle_status_start: перезапуск агента при In Progress из Needs Input.** Развилка решена через running-job (а НЕ prev-status — его нет: tasks-таблица без status-колонки, payload несёт только новый статус). Логика: нет task → start_pipeline; task есть + НЕТ active job → агент простаивает = «Слава ответил на вопросы» → relaunch агента текущей стадии (STAGE_AUTHORS[stage]); task есть + active job → busy/дубль → skip. Двухслойный дедуп: insert_event_dedup (идентичные тела) + новый db-хелпер `has_active_job_for_task(task_id)` (`SELECT 1 FROM jobs WHERE task_id=? AND status IN ('queued','running')`) — для РАЗНЫХ webhook при живой джобе.
|
||
- **handle_verdict(approved): убран `set_issue_in_progress`** — он откатывал статус перед advance (мелькание In Progress). Подтверждено: `_try_advance_stage → advance_stage → notify_stage_change → update_issue_state` (plane_sync.py:255) сам PATCH-ит статус след. стадии. Безопасно.
|
||
- **handle_verdict(rejected): причина из последнего коммента.** Новый `_latest_comment_reason(issue_id, repo, project_id)`: GET .../issues/<id>/comments/, новейший по created_at, стрип HTML, trim 300. Fallback «Rejected via status, no reason comment». Передаётся в _rollback_stage.
|
||
|
||
### Тесты (мой прогон сам): **204 passed, 9 failed** (те же 9 baseline pre-existing signature/401, regression 0, +12 новых).
|
||
Новые/переписанные: test_status_only_verdict.py (test_inreview_comment_does_not_revert = главный для бага3, test_any_comment_no_pipeline_action, test_approved_status_advances_without_inprogress_reset, test_rejected_status_pulls_reason_from_comment); test_status_trigger.py (test_repeat_in_progress_while_job_active_does_not_relaunch, test_inprogress_from_needs_input_relaunches_analyst); test_verdict_status.py (approved/rejected comment → noop); test_webhooks.py (approved/rejected переписаны на статус-триггеры).
|
||
Коммиты: `fix(webhook): remove comment-based approve, keep status-only verdict`, `fix(webhook): drop redundant in_progress reset on Approved`, `feat(webhook): pull reject reason from latest comment`.
|
||
|
||
### ✅ БОЕВОЙ ПРОГОН — баг 3 побеждён (главное):
|
||
Почистил прошлый task 26, вернул #6 в Backlog → перевёл в In Progress → новый прогон **task 27 = ET-011** (guard снова ушёл от занятого ET-006). analyst run 61: 6105 out, $0.40.
|
||
- ✅ Лог: `comment.created ... logged only, no pipeline action (status-only verdict)` — коммент analyst НЕ триггерит ничего.
|
||
- ✅ Лог: `issue updated to state 38fb1f64... no pipeline action` — перевод в In Review больше НЕ вызывает откат.
|
||
- ✅ **#6 = In Review ДЕРЖИТСЯ** (раньше за 0.1с был откат в In Progress). Баг 3 закрыт в бою.
|
||
|
||
### Артефакты analyst ET-011 (ветка feature/ET-011-untitled, Gitea admin/enduro-trails):
|
||
docs/work-items/ET-011/: 00-business-request.md, 01-brd.md, 02-trz.md, 03-acceptance-criteria.md, 04-test-plan.yaml, 04b-ui-test-cases.md.
|
||
Внешний URL Gitea = `https://git.mva154.duckdns.org/admin/enduro-trails/src/branch/feature/ET-011-untitled/docs/work-items/ET-011/<файл>`.
|
||
|
||
### Открытый хвост (следующая сессия):
|
||
- **#6 сейчас в In Review** в Plane, ждёт ручной проверки Славы: перевести в **Approved** → должна уехать в Architecture БЕЗ мелькания In Progress. Или Reject: коммент причины → Rejected → analyst перезапуск с причиной. Слава решит — сам в UI или мне симулировать.
|
||
- **Косметика (предложен 2-й тикет Dev, Слава ещё не подтвердил):** (1) коммент analyst всё ещё пишет «Жду :approved:» — устаревшая формулировка, поправить на «переведите в Approved»; (2) добавить ссылки на артефакты прямо в коммент Plane (чтобы не лезть в Gitea руками).
|
||
- Ветка-slug всё ещё `untitled` (в тестовом webhook нет name; реальный Plane шлёт name — не критично).
|
||
- Tokenator: квота исчерпана (−116k), ждать сброса (~1 число) или саппорт. OpenClaw не блокирует (фолбэк), Claude CLI агентов не касается.
|