|
| 1 | +# main — Adaptive Search Loop (Phase 4) + что дальше |
| 2 | + |
| 3 | +**Дата:** 2026-06-14 | **Статус:** замержено в main (PR #3), фича закрыта; следующая фаза не начата |
| 4 | +**Цель:** Фаза 4 (Search) deep-research-каркаса превращена из одного запланированного залпа в оркестратор-управляемый цикл (раунд → оценка Opus → опц. ограниченное отклонение) с бюджетом, лимитом глубины и аудит-логом `deviations.md`. Реальный веб-поиск — НЕ в этой работе. |
| 5 | + |
| 6 | +## Продолжить работу |
| 7 | + |
| 8 | +**Где мы:** adaptive-search-loop полностью реализован (Tasks 1–11), отревьюен (две стадии на задачу + holistic), смержен в `main` через PR #3 (merge-commit `a6c0c10`). Локальный `main` синхронизирован с origin **кроме одного коммита**: `d77540d docs(pages)…` локально есть, на origin — нет (`main ahead 1`). Если он нужен на origin — `git push`; если это случайный/чужой коммит — разобраться до пуша. |
| 9 | + |
| 10 | +**Самое важное про «что дальше» (Phase 5 — реальный поиск):** |
| 11 | +Сейчас весь цикл работает **только на `DryRunProvider`** — машинерия собрана и проверена end-to-end, но «живых» сигналов нет: источники = плейсхолдеры (`https://example.com/source-N`), саб-агенты возвращают `signals: {}` (пустые), поэтому в проде цикл **всегда выходит после раунда 1** (триггеры не зажигаются). Это честный scaffold, не баг. |
| 12 | + |
| 13 | +Ключевой порядок из спеки (`docs/superpowers/specs/2026-06-13-adaptive-search-loop-design.md:314`): **движок реализует петлю по-настоящему только когда приземлится реальный веб-поиск**. То есть следующая крупная работа — это retrieval (реальные URL + контент), и уже он естественно зажжёт сигналы `empty_result`/`citation_lead`/`unexpected_finding`/`contradiction`. Без retrieval адаптивность мертва. |
| 14 | + |
| 15 | +**Ключевые файлы:** |
| 16 | +- `runner/adaptive.py` — вся логика цикла (signals-парсинг, `Budget`, `Deviation`/`write_deviations`, cross-agent скан, `decide_deviations`, `run_search_loop`). **Здесь `TODO(Phase 5)` на строке 262**: backfill `outcome`/`new_source_ids` после скоринга (сейчас `outcome="(pending scoring)"`, `new_source_ids=[]` навсегда). |
| 17 | +- `runner/orchestrator.py` — `search()` гоняет цикл через `run_round`-замыкание над `provider.fanout`, пишет `deviations.md`. **TODO-плейсхолдеры:** строка 134 (`url = https://example.com/source-N` → реальные URL), строка 117 (`return ... signals: {}` → реальные сигналы), строка 107 (каналы/источники из `references/`). |
| 18 | +- `references/workflow.md` — методология Фазы 4 как цикл (signals-блок, бюджет/глубина, термination), 5-й adversarial-вопрос (Фаза 6), `carry_forward` (Фаза 7). |
| 19 | +- `phases.yaml` — Фаза 4 помечена `loop: "true"` (без новой phase-id; счётчик фаз = 9). |
| 20 | +- `docs/superpowers/plans/2026-06-13-adaptive-search-loop.md` — план (все боксы отмечены `[x]`). |
| 21 | +- `docs/superpowers/specs/2026-06-13-adaptive-search-loop-design.md` — дизайн-спека (источник правды по «почему»). |
| 22 | + |
| 23 | +**Подводные камни:** |
| 24 | +- **vitest/pytest-фильтр здесь — pytest** (Python 3.14 в окружении). Гонять из `/Users/ivanteresenko/Downloads/claude-deep-research`. |
| 25 | +- **Сеть к github.com нестабильна** в этой сессии (`SSL_ERROR_SYSCALL`, `Post …EOF` на `gh`). `gh pr merge` может «упасть» на пост-синке, хотя мерж на стороне GitHub УЖЕ прошёл — проверять через `gh pr view N --json state,mergedAt,mergeCommit`, а не по выводу команды. |
| 26 | +- **Doc-gate:** `python3 scripts/stamp_docs.py --check` должен быть exit 0. Если правишь `references/*.md` или `phases.yaml` — не трогать `<!--gen:…-->` спаны и не менять счётчик фаз (9), иначе gate краснеет. |
| 27 | +- **4 пропущенных теста** в suite — это opt-in `@pytest.mark.live` smoke (нужен `ANTHROPIC_API_KEY`). Норма, не чинить. |
| 28 | +- На машине **нет bare `python`** — только `python3`. |
| 29 | + |
| 30 | +**Следующий шаг (если продолжать проект):** начать Phase 5 / реальный retrieval. Разведать `multi-llm-runner` спеку (она упоминается как место, где живёт реальный поиск), затем `brainstorming` → план → реализация. Это крупная работа, не однофайловая. |
| 31 | + |
| 32 | +## Сделано |
| 33 | +- **Слой A (методология):** `phases.yaml` (Фаза 4 = loop), `references/workflow.md` (цикл раундов + 5-й adversarial-вопрос + carry_forward). Doc-gate зелёный, счётчик фаз неизменён (9). |
| 34 | +- **Слой B (движок, на DryRun + mocks):** `runner/adaptive.py` целиком (Tasks 5–10), `runner/orchestrator.py` (Task 11 — цикл в `search()`, `RunState.deviations`, пишет `deviations.md`), тесты `tests/test_adaptive.py` + `tests/test_adaptive_integration.py`. |
| 35 | +- **Ревью:** каждая из Tasks 9–11 прошла spec-compliance + code-quality (opus-субагенты, читали закоммиченный код, не доверяя отчёту) + финальное holistic-ревью всего инкремента. Находки пофикшены: убран мёртвый `RoundResult`; покрыты ветки default-to-reject / fallback-rationale / depth_limit / budget_exhausted / cross-agent; переименованы unused-параметры `run_round`; добавлен `TODO(Phase 5)`. |
| 36 | +- **Верификация (наблюдённая):** `pytest -q` → 82 passed, 4 skipped; `stamp_docs --check` → exit 0; scaffold deep-run валидируется `--strict` и эмитит `deviations.md`. |
| 37 | +- **Мерж:** PR #3 → main (merge-commit, чтобы сохранить пофазовую TDD-историю), remote-ветка удалена, локальный main выровнен. PR намеренно включал и 16 коммитов предыдущей несвязанной фичи («мульти-LLM runner, фаза 2»), которая отставала в origin/main. |
| 38 | + |
| 39 | +## Осталось |
| 40 | +- [ ] **Решить судьбу локального коммита `d77540d`** (main ahead 1) — запушить или разобраться, откуда он. |
| 41 | +- [ ] **Phase 5 / реальный веб-поиск (крупное):** retrieval с реальными URL+контентом вместо плейсхолдеров (`orchestrator.py:134`). Это разблокирует живые сигналы → цикл начнёт реально отклоняться. |
| 42 | +- [ ] **Живые сигналы саб-агентов** (`orchestrator.py:117`) — наполнить `signals` реальными `empty_result`/`citation_lead`/`unexpected_finding`/`contradiction` вместо `{}`. |
| 43 | +- [ ] **Backfill `outcome`/`new_source_ids`** в `deviations.md` после скоринга (`adaptive.py:262` TODO) — когда Phase 5 (Scoring) приземлится. |
| 44 | +- [ ] **Каналы/источники из `references/`** в plan-выводе (`orchestrator.py:107`). |
| 45 | +- [ ] (опц.) Когда `deviations.md` станет нагруженным — добавить его проверку в `eval/validate_structure.py` (сейчас артефакт не валидируется структурно). |
| 46 | +- [ ] (опц.) Прогнать `-m live` smoke с реальным ключом, чтобы проверить, что провайдер реально отдаёт `JUSTIFIED:`/`CONTRADICTION:`/`NONE`-формы, которые ждут парсеры (сейчас контракт проверен только со стороны харнесса). |
| 47 | + |
| 48 | +## Решения |
| 49 | +- **Approach 2 (Фаза 4 = цикл), не отдельная Фаза 4.5:** концептуальная простота «Фаза 4 это цикл, точка» важнее, чем сэкономить Opus-оценку на спокойных прогонах. Цена принята сознательно: каждый прогон платит за оценку между раундами. |
| 50 | +- **Двухуровневая детекция:** дешёвые саб-агенты сигналят щедро (recall), Opus строго фильтрует (precision) и отдельно сканит cross-agent противоречия, которые один агент структурно не видит. Дорогой интеллект — только на суждение. |
| 51 | +- **`RoundResult` удалён как мёртвый код:** план его перечислял, но ни эталон, ни Task 11 его не потребляли. План-док синхронизирован с пометкой о post-review удалении. |
| 52 | +- **Merge-commit, не squash:** ветка несла две отдельные серии коммитов (adaptive + предыдущий multi-llm-runner) — merge честно сохраняет пофазовую историю обеих. |
| 53 | +- **PR as-is (35 коммитов):** по явному выбору Ивана предыдущая фича поехала вместе с adaptive, вместо пуша main первым. |
| 54 | + |
| 55 | +--- |
| 56 | +## Сессия 2026-06-14 (вечер) — growth + docs-полировка + сборка main |
| 57 | + |
| 58 | +### Продолжить |
| 59 | +**Главное состояние:** `origin/main = aa3b16a`, всё запушено, CI зелёный (`validate` + `pages` оба success). Рабочее дерево чистое, осталась одна ветка `main`. Stage 1 retrieval УЖЕ в main и реализован (это сдвиг относительно секции выше, где он был «не начат»). |
| 60 | + |
| 61 | +**Два незакоммиченных хвоста** (НЕ мои, появились параллельно — НЕ трогал): |
| 62 | +- `?? docs/superpowers/plans/2026-06-14-real-retrieval-search-stage2.md` — похоже, план реализации Stage 2 (рядом с design-доком, что я закоммитил в aa3b16a). Если это твой готовый план — закоммить; если черновик — дорабатывай. |
| 63 | +- `?? .claude/handoffs/main-2026-06-14.md` — этот самый handoff (untracked, авто-хук его создал; закоммить если нужен в истории). |
| 64 | + |
| 65 | +**Следующий шаг по проекту:** Stage 2 — живой `ClaudeProvider.search()` через `web_search`. Дизайн готов и в main: `docs/superpowers/specs/2026-06-14-real-retrieval-search-stage2-design.md` (Status: Approved → ready for plan). Оттуда: `executing-plans` по плану (если plan-файл выше валиден) или `writing-plans` заново. |
| 66 | + |
| 67 | +**КРИТИЧНЫЙ load-bearing факт для Stage 2** (зафиксирован в памяти [[phase5-stage2-design]]): call 2 (structured output) НЕ должен реплеить `messages` call 1 — `web_search` всегда эмитит citations, а citations + `output_config.format` = **HTTP 400**. Поэтому два вызова независимые, call 2 получает текст+источники call 1 как plain user-text. И риск: `model_tier="cheap"` = `claude-haiku-4-5`, которого НЕТ в списке поддержки `web_search_20260209` → `search()` хард-резолвит на `mid` (`claude-sonnet-4-6`). |
| 68 | + |
| 69 | +**Подводные камни (в дополнение к секции выше):** |
| 70 | +- **Ветка переключалась сама дважды за сессию** (main→retrieval, видимо IDE/фон). ВСЕГДА проверяй `git branch --show-current` перед коммитом/пушем. |
| 71 | +- **CI НЕ гонял ruff до этой сессии** — теперь гоняет (шаг `Lint (ruff)` в `validate.yml`, pin `ruff==0.15.1`). Перед пушем локально: `ruff check .` ДОЛЖЕН быть clean, иначе CI покраснеет. |
| 72 | +- **og-image / GitHub-description правятся ВРУЧНУЮ** (не через stamp_docs) — см. [[og-image-manual-numbers]]. Соцсети не рендерят SVG → og:image обязан быть PNG+абсолютный URL. PNG пересоздаётся headless-Chrome (ImageMagick падает на шрифтах). |
| 73 | + |
| 74 | +### Сделано |
| 75 | +- **Growth-ресёрч (наружу, 3 действия):** (1) исправлен GitHub-description репо (числа были занижены: 7→9 фаз, 75→103, 280→460, 30→39); (2) helpful-first коммент в [gpt-researcher#1572](https://github.com/assafelovic/gpt-researcher/issues/1572#issuecomment-4700801937); (3) PR в [alirezarezvani/claude-skills#851](https://github.com/alirezarezvani/claude-skills/pull/851) (на ревью у мейнтейнера). Разбор болей: `docs/growth/github-pain-points-2026-06-14.md`. |
| 76 | +- **Docs-полировка (в main):** og-image числа 9/29/103/460/39 + PNG-версия 1200×630; `index.html` секция фаз выровнена под `phases.yaml` (было 7-8 кривых карточек → 9: добавлены 6.5 Verify, 7 Refresh, объединён Synthesis+adversarial), заголовок Seven→Nine/Семь→Девять (EN+RU+HTML-fallback); favicon (§) + theme-color; OG/Twitter превью → PNG+абсолютный URL; `docs/growth` + `docs/superpowers` исключены из Pages (`_config.yml`). |
| 77 | +- **Ruff-clean + CI-гейт:** 13 ruff-нарушений в существующем коде (F401/E731/E702/E402 в eval/scripts/tests) исправлены (стиль, поведение не менялось); шаг `Lint (ruff)` добавлен в `validate.yml`. |
| 78 | +- **Stage 2 design (в main):** `stage2-design.md` создан, `design.md` (Stage 1) — 3 open questions помечены resolved со ссылкой. |
| 79 | +- **Git-сборка:** 3 ветки (docs/polish-site + feat/retrieval-search-stage1 + локальный main ahead 3) собраны в линейный main через ff-merge + rebase, **с верификацией перед каждым пушем** (ruff + pytest 90/4 + stamp_docs + context_budget — всё зелёным). Слитые ветки удалены. |
| 80 | + |
| 81 | +### Осталось |
| 82 | +- [ ] **Решить судьбу `docs/superpowers/plans/...stage2.md`** (untracked) — закоммитить план или доработать. |
| 83 | +- [ ] **Phase 5 Stage 2 — реализация** `ClaudeProvider.search()` (live web_search) по готовому дизайну. Это разблокирует ЖИВЫЕ сигналы (сейчас цикл всё ещё на DryRun, выходит после раунда 1). |
| 84 | +- [ ] **Submission в awesome-claude-code** (на Иване, вручную): нужно 5★ (сейчас 4), подача только через веб-форму (CLI/боты запрещены). Готовый текст в `docs/growth/github-pain-points-2026-06-14.md`. |
| 85 | +- [ ] **Мониторить PR #851** — ответить мейнтейнеру; риск — могут счесть близким к их `research/research`. |
| 86 | +- [ ] Хвосты Phase 5 из секции выше (backfill `outcome`/`new_source_ids` `adaptive.py:262`, каналы из references) — остаются. |
| 87 | + |
| 88 | +### Решения |
| 89 | +- **Не писать на трекере Anthropic:** главный сигнал спроса — баги штатного `/deep-research` (жгут токены), но самореклама там = риск спам-ярлыка. Выбраны только безопасные площадки (OSS-issues + resource-каталоги). См. [[awesome-catalog-submission-rules]]. |
| 90 | +- **README прав, GitHub-description устарел:** числа авто-стампятся `scripts/stamp_docs.py` из `phases.yaml`+каталога; description правился руками и отстал. Источник правды — стампер. |
| 91 | +- **9 карточек фаз на сайте, не 7:** честнее показать полный pipeline (= phases.yaml), чем держать упрощённую модель, конфликтующую с числом «9» в остальных местах. |
| 92 | +- **ruff отдельным CI-шагом, не в requirements:** линтер — не runtime-зависимость; шаг сам ставит pinned ruff. |
| 93 | +- **docs-коммит вынесен с retrieval-ветки на отдельную ветку от main** (cherry-pick): docs-полировка не связана со Stage 1, не должна затесаться в его историю. |
| 94 | +- **Stage 2 design-доки закоммичены, хотя «не трогал»:** законченный дизайн (Approved), связан ссылкой с design.md (иначе битая ссылка) — по явному ok Ивана. |
0 commit comments