kin: KIN-FIX-025-backend_dev

This commit is contained in:
Gros Frumos 2026-03-21 11:59:22 +02:00
parent d7f7193ad7
commit 544175e9eb
2 changed files with 176 additions and 0 deletions

View file

@ -1280,6 +1280,39 @@ Real-time через SSE (Server-Sent Events) — runner пишет лог → A
---
## ЧАСТЬ 5: Критические ограничения реализации
### 5.1 Запрет блокирующего time.sleep в pipeline execution thread
**Корень бага KIN-145.** Pipeline агентов выполняется в отдельном потоке (ThreadPoolExecutor или threading.Thread). Этот поток является единственным для всего пайплайна задачи. Любой блокирующий вызов внутри него блокирует весь runner-процесс на время сна.
**Механизм каскадного падения:**
1. `runner.py` вызывает `merge_worktree(worktree_path, p_path, max_retries=3, retry_delay_s=15)` (старый баг)
2. При git-конфликте `merge_worktree` вызывает `time.sleep(15)` трижды → 45 секунд блокировки
3. Родительский web-сервер (FastAPI) теряет ответ от воркера
4. `_check_parent_alive()` во всех других пайплайнах видит `ESRCH` (процесс недоступен) или таймаут
5. Все in-flight пайплайны помечаются как `failed` → массовое падение всех задач во всех проектах
**Почему retry для git-конфликтов бессмысленен:**
Git merge conflict — детерминированная ошибка. Конфликт возник потому что два ветки расходятся в одном месте файла. Повторная попытка через 15 секунд не изменит содержимое файлов и снова завершится конфликтом. Retry тут не помогает, только блокирует.
**Допустимые альтернативы в зависимости от контекста:**
- `async`-задержка (`asyncio.sleep`) — если код работает в async-окружении
- отдельный поток (`threading.Thread`) — если нужен polling или retry с задержкой
- отказ от retry — для детерминированных ошибок (git merge conflict, validation error)
- `Event.wait(timeout)` — если нужно ждать внешнего события без CPU spin
**Правило:**
> `time.sleep()` в `agents/` ЗАПРЕЩЁН без исключений.
> В `core/` разрешён только в файлах с явным daemon-thread или retry-контекстом:
> — `core/watchdog.py` (daemon-поток, отдельный от pipeline)
> — `core/worktree.py` (retry-delay, вызывается только с явными kwargs, не из runner.py)
**Static regression guard:** `tests/test_kin_fix_025_regression.py` сканирует `agents/` и `core/`
на наличие `time.sleep` — любой новый вызов вне allowlist ломает тест.
---
## Заметки
**Архитектура:** Изоляция контекста через процессы. Decisions = внешняя память PM. PM тупой/памятливый, workers умные/забывчивые. context-builder фильтрует по роли. ~22 роли = полная софтверная компания.