# План фазы 3: этап 3 — ИИ ур. 1–3, эвристика (packages/ai) Обновлено: 2026-08-05 | Статус: выполнен (gates зелёные; perf chooseMove 19×19 ≈ 8 мс) ## Критические долги (реестр — в начале, III.5) - Нет. ## Ключевые решения (не пере-решать) - Отдельный пакет packages/ai — core остаётся чистыми правилами (рекомендация отчёта сессии 2, принято). - ИИ — синхронный чистый вычислитель; воркер появится в этапе 4 (MCTS), протокол postMessage фиксируется там же. - Случайность — только seeded Rng из core, передаётся параметром (детерминизм = воспроизводимые партии и тесты). - Легальность — только через applyMove из core; дублирование правил запрещено. - Приоритеты и вероятности уровней — по контракту в docs/INTERFACES.md (зафиксирован 2026-08-05 до кода). - Простая эвристика глаза: все ортогональные соседи — свои камни, без анализа диагоналей; осознанно грубо, ручной игры «подложить себе» бот не имитирует. ## Объём этапа 3 1. packages/ai (@go-learn/ai 0.1.0, зависимость @go-learn/core): chooseMove + LEVEL_ATARI_PROBABILITY + типы по контракту. 2. Внутренние эвристики: поиск групп в атари (groupAt/liberties из core), ходы-спасения (>1 дамэ после хода или контрзахват), ходы-захвата, фильтр своего глаза, кандидаты nearby (Chebyshev ≤ 2), взвешенный выбор. 3. Корневой tsconfig: references += packages/ai (без project reference на core — TS6310, см. PROJECT_STATE; резолв через workspace-симлинк). ## Тесты (гейт приёмки этапа) - Детерминизм: одинаковый seed → идентичная последовательность ходов в полной партии бот-бот (два прогона, сравнение SGF или списка ходов). - Приоритеты: сконструированные позиции — при rng «всегда 0» (ролл < p) бот спасает своё атари / забирает чужое; при rng «всегда 0.99» (ролл ≥ p) приоритет пропускается. - Фильтр глаза: бот не заполняет свой глаз при наличии других ходов. - Легальность: все ходы бота в длинных партиях легальны (property: случайные партии бот-бот до двух пасов, seed запинен; ни одного ok:false). - Завершение: партия бот-бот 9×9 завершается (over) за разумное число ходов; после over вызов chooseMove кидает Error. - Perf-smoke: chooseMove на позиции 19×19 средней игры < 200 мс в CI-среде (критерий приёмки «ур.3 < 50 мс на среднем ноутбуке» — замер фактический, число в отчёте сессии; порог в тесте с запасом, машинно-зависимый). - Wiring: orphan-check по экспортам packages/ai. ## Критерий выхода Все тесты зелёные + `npm run gates` зелёный. Полная партия 9×9 бот-бот завершается корректно (предпосылка критерия приёмки v1 №2 для ур. 5 в этапе 4).