From 56dbb49261a60b38b138582d037c2cc3b0b92298 Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Tue, 14 Jul 2026 16:52:43 +0300 Subject: [PATCH] Document evidence-led query discovery architecture --- .../OFFER_MAP_SEARCH_LANGUAGE_ARCHITECTURE.md | 56 ++++++ .../SEO-farm/OPEN_SOURCE_SEMANTIC_AUDIT.md | 30 ++++ seo_mode/seo_mode/SEO-farm/QUERY_DISCOVERY.md | 165 ++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 seo_mode/seo_mode/SEO-farm/OFFER_MAP_SEARCH_LANGUAGE_ARCHITECTURE.md create mode 100644 seo_mode/seo_mode/SEO-farm/OPEN_SOURCE_SEMANTIC_AUDIT.md create mode 100644 seo_mode/seo_mode/SEO-farm/QUERY_DISCOVERY.md diff --git a/seo_mode/seo_mode/SEO-farm/OFFER_MAP_SEARCH_LANGUAGE_ARCHITECTURE.md b/seo_mode/seo_mode/SEO-farm/OFFER_MAP_SEARCH_LANGUAGE_ARCHITECTURE.md new file mode 100644 index 0000000..ae2d698 --- /dev/null +++ b/seo_mode/seo_mode/SEO-farm/OFFER_MAP_SEARCH_LANGUAGE_ARCHITECTURE.md @@ -0,0 +1,56 @@ +# Offer Map и язык рынка + +Этот документ — рабочая архитектурная опора для SEO-модуля. Она применяется к любому сайту и не содержит отраслевых словарей, названий продуктов или зашитых рынков. + +## Принцип + +```text +Site Graph + evidence + → Offer Map + → Market Archetype Router + → Search Scope + → semantic slots + → deterministic query patterns + → human candidate checker + → observed language + → Wordstat + → clustering and strategy +``` + +LLM допускается в `Offer Map`, маршрутизации архетипов и выделении semantic slots. Она не доказывает спрос и не создаёт готовые ключи для Wordstat. + +## Граница объектов + +### Offer Map + +Фактическая модель продукта, составленная из site evidence: + +- core offer простым рыночным языком; +- market categories; +- возможности и дифференциаторы; +- buyer roles и deployment только с evidence; +- `do_not_overweight_terms`; +- правило: внутренние названия модулей, слоёв, экранов и архитектурных сущностей не являются языком рынка без external evidence. + +### Opportunity Portfolio + +Прикладные модули, вертикали и гипотезы расширения. Портфель полезен для исследования стратегии, но не создаёт поисковые направления автоматически и не является блокером для Product Core. + +### Search Scope + +Явно выбранные пользователем направления, которые разрешено отправить в semantic slots и pattern engine. Новый проект начинает с factual core. Модули и возможности добавляются сюда только отдельным человеческим решением. + +## Candidate checker + +Пользователь видит черновые формулировки, а не Topic Cards: + +- vector / intent / page type / pattern; +- источник смысла в сайте; +- статус: draft, kept for collection, excluded или observed; +- решение человека хранится отдельно от внешнего evidence. + +`kept for collection` означает только разрешение собирать observed language. Это не Wordstat input. Wordstat получают лишь explicit base probes или observed queries, прошедшие evidence gate. + +## Универсальность + +Archetypes и patterns являются конфигурацией, а не кодом под конкретную отрасль. Один и тот же конвейер применим к enterprise software, локальной услуге, e-commerce, медиа, образованию, промышленному оборудованию и другим типам сайтов. diff --git a/seo_mode/seo_mode/SEO-farm/OPEN_SOURCE_SEMANTIC_AUDIT.md b/seo_mode/seo_mode/SEO-farm/OPEN_SOURCE_SEMANTIC_AUDIT.md new file mode 100644 index 0000000..c52e059 --- /dev/null +++ b/seo_mode/seo_mode/SEO-farm/OPEN_SOURCE_SEMANTIC_AUDIT.md @@ -0,0 +1,30 @@ +# Open-source mini-audit: search language pipeline + +Дата проверки: 2026-07-12. Критерии: активность, лицензия, открытые issues и комментарии, архитектурная совместимость с TypeScript/PostgreSQL evidence pipeline. + +## Решения + +| Project | Signals | Decision | +| --- | --- | --- | +| `altrr2/yandex-tools-mcp` | MIT, 38 stars, push 2026-07-08, без открытых issues | Использовать как reference-contract и набор интеграционных тест-кейсов. Не импортировать runtime: provider boundaries и credentials должны оставаться нашими. | +| `baltic-tea/yandex-wordstat-mcp` | 1 star, нет явной лицензии, push 2026-04-26 | Не подключать. Можно сверять Wordstat operators, retries и region cache с реализацией. | +| `neonwatty/autocomplete-cli` | архивирован, 1 star | Не подключать. Заимствовать только протокол expansion: seed, alphabet, question modifiers, language/region, raw artifact. | +| `chukhraiartur/seo-keyword-research-tool` | MIT, 158 stars, код не обновлялся с 2023, старые issues без дискуссии | Не подключать: хороший reference flow для autocomplete/PAA/related, но runtime зависит от SerpApi и не закрывает provenance. | +| `PhialsBasement/LibreCrawl` | MIT, 751 stars, активные свежие issues/PR | Не заменять текущий crawler. Брать regression cases для crawler hardening: anti-bot, JS pages, redirects, sitemap/robots. | +| `puneetindersingh/open-seo-crawler` | MIT, 11 stars, один открытый Playwright issue | Только источник идей для Playwright fallback; не dependency. | +| `sethblack/python-seo-analyzer` | большой активный проект, но Python + отдельный AI stack | Не интегрировать. Сверять набор technical-audit checks с нашим scanner. | +| `searchsolved/search-solved-public-seo` | 404 stars, активен, без явной лицензии, issues разного качества | Не импортировать. Использовать как catalogue маленьких проверяемых экспериментов для PAA, related и internal-search. | +| `FassihFayyaz/SEO-Clustering-Tool` | 5 stars, неактивен с 2025, timeout issue | Не dependency. Позже воспроизвести идею SERP URL-overlap clustering в нашем evidence schema. | +| `KeyBERT`, `YAKE` | зрелые библиотеки извлечения фраз | Не считать поисковым evidence. Возможны как offline triage для текста сайта. | +| `Natasha`, `pymorphy3` | зрелые русскоязычные NLP/morphology библиотеки | Кандидаты на отдельный opt-in Python normalizer после появления observed queries. Не тащить Python runtime в первый pre-Wordstat vertical slice. | + +## Принятые заимствования + +1. `autocomplete-cli`: контракт harvester-а — expansion, locale/region, raw artifact, дедупликация. +2. `yandex-tools-mcp`: test matrix для Wordstat/Yandex providers, а не runtime package. +3. `LibreCrawl` и `python-seo-analyzer`: наборы regression checks для сканера. +4. SEO clustering projects: будущий SERP-overlap алгоритм только после появления валидированных observed/Wordstat rows. + +## Почему не подключаем репозитории напрямую + +Прямой импорт смешал бы provider credentials, lifecycle jobs и raw evidence с чужими CLI/MCP/Streamlit/Flask приложениями. Для нашего конвейера ценнее переносить маленькие проверяемые алгоритмы и контракты, сохраняя одну authority chain: page evidence → Offer Map → scope → pattern → observation → decision. diff --git a/seo_mode/seo_mode/SEO-farm/QUERY_DISCOVERY.md b/seo_mode/seo_mode/SEO-farm/QUERY_DISCOVERY.md new file mode 100644 index 0000000..14ecd2a --- /dev/null +++ b/seo_mode/seo_mode/SEO-farm/QUERY_DISCOVERY.md @@ -0,0 +1,165 @@ +# Query Discovery: язык рынка до Wordstat + +## Канонический контракт v4 + +С `seo-demand-research-brief.v3` входом Query Discovery является не +одна product phrase, а `SemanticPortfolioFacet[]`. + +```text +Offer Map + Business Synthesis + Demand Families + approved Opportunity Portfolio + → Semantic Portfolio (evidence, risks, slot bundle, pattern eligibility) + → balanced_auto Search Scope (3–4 safe core facets) + → topic decomposition per facet + → query-surface drafts + → short market seeds + → observed queries + → normalization + relevance gate + → canonical query clusters + → human observed-language review + → bounded Wordstat queue + +Parallel, non-queue branch: + + Semantic Portfolio + Offer Map + Opportunity Portfolio + → DomainAgnosticityClassifier + → ExpansionSurfaceBuilder + ApplicabilityMatrixBuilder + → explicit exploration selection + → ExpansionSeedGenerator + → recursive Suggest (smoke / balanced / deep) + → normalization + expansion surface-fit gate + → human expansion review +``` + +`demandFamilies` — evidence для фасетов. Их фразы никогда не становятся +Wordstat input напрямую. Current applications и expansion hypotheses остаются +в портфеле и требуют явного выбора; default scope их не активирует. + +Каждый topic, probe и candidate несёт `facetId`. Topic decomposition обязан +вернуть для каждого selected facet либо один topic, либо `rejectedFacet` с +причиной и evidence refs. Неудачная попытка выразить фасет рыночным языком не +заменяется общей формулировкой: она фиксируется как quality result. + +## Граница ответственности + +Перед Query Discovery стоят `Offer Map` и `Search Scope`. Карта возможностей, прикладные модули и гипотезы расширения живут в отдельном Opportunity Portfolio и не становятся search scope автоматически. + +Модель не создаёт ключевые запросы и не оценивает спрос. Она создаёт только `seo.topic_decomposition.v1`: для каждого направления, явно разрешённого в Search Scope, возвращает класс оффера, `primaryMarketEntities`, `marketEntityFamily`, категории, сущности, синонимы, действия, процессы, боли, сегменты, интеграции, отдельные интенты и разрешённые группы шаблонов. + +`primaryMarketEntities` — короткая рыночная категория, а не описание продукта. Для одного topic разрешена ровно одна такая сущность: она должна сохранить отличительный смысл самого фасета и не уводить в чужой конкурентный класс. Backend отвергает сущности, которые состоят только из общих модификаторов и классов продукта. + +`marketEntityFamily` — 3–6 коротких внешне узнаваемых формулировок того же смысла. Это semantic slots, а не готовые ключи и не перечень фич. Backend оставляет только те элементы семьи, которые несут лексический маркер главной сущности: так «платформа управляемых ИИ-агентов» может дать близкие agent-specific поверхности, но не превратиться в ERP, CRM, BPM, «операционную платформу» или интеграционный шум. Главная сущность и эта контекстно связанная семья становятся входом pattern engine; остальные categories/coreEntities/marketSynonyms остаются provenance и контекстом. Для русскоязычного surface English-only probes не выпускаются. Интеграции и прикладные модули не порождают default core probes: это отдельные явно выбранные Search Scope направления. + +Каждый внутренний topic обязан хранить исходные `facetId` и `sourceDirectionId`. Это authority chain: Search Scope vector → semantic slots → probe → observed query → Wordstat evidence. Текстовое fuzzy-сопоставление не может отменять выбранный `topicId`. Topic cards — provenance detail, а не основной пользовательский экран. + +Topic decomposition может прийти из `codex_workspace` или из явного `codex_manual` review. В обоих случаях backend проверяет полный набор утверждённых направлений, точное совпадение `topicId/sourceDirectionId`, классы оффера и разрешённые pattern groups. Если remote workspace недоступен, система остаётся blocked; она не подменяет результат старыми model-generated anchors. + +## Универсальный слой + +`queryDiscovery` не содержит отраслевых словарей и не знает ничего о конкретном сайте. Универсальная библиотека применяет только классы оффера, facet kind, delivery model, sales motion и semantic slots: + +- base entity; +- категория или сущность для процесса; +- проблема/автоматизация процесса; +- разработка или внедрение для service-class; +- интеграция с системой; +- информационный и comparison intent. + +Шаблон создаёт `probe`, а не ключ. Pattern eligibility приходит из backend для конкретного фасета; модель не может назначить себе integration, service или transactional паттерн вне разрешённой группы. Pattern-only probe не может попасть в Wordstat; пользователь может оставить его только в очереди Suggest/first-party collection. + +## Market seed и evidence gate + +`MarketSeedGenerator` строит короткие probes из semantic slots и business model +signals. Это не ключи и не спрос. Local, integration, comparison и price +семейства включаются только при соответствующем facet/policy. Suggest seeds +выбираются round-robin между facets, поэтому один lexical family не съедает +весь collector budget. + +Raw observation сначала проходит `ObservedQueryNormalizer`, затем +`ObservedRelevanceGate`. Gate разделяет clean commercial, informational, +integration/local/comparison reroute, brand/domain/free/education/job noise и +raw-only evidence. + +Canonical cluster становится доступен для Wordstat queue только так: + +1. фраза реально наблюдена в suggest, SERP или first-party источнике; +2. observation прошёл normalizer и relevance gate; +3. варианты собраны в canonical cluster внутри одного facet и intent; +4. пользователь явно утверждает cluster либо независимые evidence classes дают + право `auto_wordstat_ready` по policy. + +`auto_wordstat_ready` не запускает провайдера. Он только разрешает построить +queue item. Model-only draft и raw observation не могут войти в очередь ни при +каком score. + +Наблюдения хранят источник, topic, probe/pattern, язык, географию и ссылку на raw artifact. Wordstat сохраняет отдельное raw evidence и не является генератором языка спроса. + +## Core Validation и Market Expansion + +`Core Validation Queue` остаётся коротким evidence-backed batch. Его размер не +интерпретируется как полный SEO-охват. `Market Expansion Backlog` — отдельный +контур потенциальных process, role, industry, asset/object, integration, +problem, use-case и buying-stage surfaces. + +`ExpansionSurface` не является ключом. Он хранит `relationshipToCore`, +structured slot bundle, applicability/evidence score, expansion risk и human +decision. Direct core не дублируется в expansion. Application, adjacent и +speculative surfaces не активируются автоматически. + +`DomainAgnosticityClassifier` использует только абстрактные признаки Offer Map +и portfolio: delivery model, generic processes, buyer-role diversity, +cross-industry objects, integration layer, vertical constraints и current +applications. Названия конкретного проекта и отраслевые словари в production +policy отсутствуют. + +Выбранная surface создаёт только `market_seed` (`isFinalKeyword=false`). +`smoke`, `balanced` и `deep` управляют budget, suffix/alphabet expansion и +depth-2 recursion. Даже clean expansion observation получает только +`human_expansion_review`; `wordstatReady` в этом контуре равен нулю до +отдельного решения и следующего bounded batch. + +После фактического Wordstat запускается `PostWordstatExpansionPlanner`. Он +маршрутизирует top/related результаты в существующие surfaces или предлагает +новые observed proposals. Эти объекты помечены `sourcePhase=post_wordstat` и не +смешиваются с speculative pre-Wordstat backlog. + +`PostWordstatProductFitGate` является обязательным следующим слоем. Он не +использует frequency как product-fit evidence и для каждой уникальной строки +определяет intent, page type, relationship to core, semantic/source affinity, +product-fit score, competitor/category warnings и рекомендуемый маршрут. +Результаты делятся на validated seeds, commercial batch review, content, +adjacent research и reject; дополнительно строятся canonical product-fit +clusters. Широкая related-фраза не становится коммерческим ключом из-за одной +частотности. + +`PostWordstatBatch2Planner` принимает только human decisions. В Wordstat queue +попадают исключительно `approved_for_wordstat` candidates, queue ограничена 12 +фразами и хранит provenance `wordstat_related_product_fit_approved`. Повторно +собранная exact-фраза становится `validated_seed` и автоматически исчезает из +очереди, но её decision сохраняется для SERP trace. SERP-проверка получает +только human-approved batch, а не весь related result set. + +До observed language пользователь работает с экранами «Поисковые направления» +и «Черновики поисковых формулировок»: он может оставить или исключить pattern +candidate. После collector он работает в отдельном `Observed language review`, +а approved clusters отображаются в `Bounded Wordstat queue`. Ни одно из этих +действий не запускает Wordstat. + +В шапке этого экрана и в пяти фильтрах всегда видны числа: всего, на разборе, оставлены, очередь Wordstat и скрытые. Пять правых действий карточки имеют постоянный порядок: оставить для сбора → вернуть на разбор → скрыть → очередь Wordstat → удалить. Решения сначала остаются локальным черновиком и пишутся в backend только отдельной кнопкой сохранения. + +## API + +- `GET /projects/:projectId/query-discovery/latest` +- `POST /projects/:projectId/query-discovery/topic-decomposition/manual` +- `POST /projects/:projectId/query-discovery/observations` +- `POST /projects/:projectId/query-discovery/observed-language/collect` +- `PUT /projects/:projectId/query-discovery/probes/:probeId/decision` +- `PUT /projects/:projectId/query-discovery/clusters/:clusterId/decision` +- `PUT /projects/:projectId/query-discovery/expansion-surfaces/:surfaceId/decision` +- `POST /projects/:projectId/query-discovery/market-expansion/collect` +- `PUT /projects/:projectId/post-wordstat/candidates/:candidateId/decision` +- `POST /projects/:projectId/post-wordstat/decisions/bulk` +- `POST /projects/:projectId/post-wordstat/batch2/collect` +- `GET /projects/:projectId/market-enrichment/probe-preview` +- `POST /projects/:projectId/market-enrichment` + +Модельный task: `seo.topic_decomposition`. До его выполнения market enrichment и Wordstat preview остаются заблокированы; старый путь model-generated anchors не используется как fallback.