Files
LegacyHUB/docs/ADR-shared-core.md
Vadim Malanov 4fcec8039b
Some checks failed
CI / Backend (lint + tests + compose) (push) Has been cancelled
CI / Frontend (lint + type-check + build) (push) Has been cancelled
chore: pin document recognition engine
2026-06-25 11:43:29 +03:00

5.7 KiB
Raw Blame History

ADR: Extract OCR / Markdown / Search into a shared teamhub_core engine

Status: accepted (staged, recognition engine extracted) · 2026-06-15 · scope: legacy-knowledge-indexer + TeamHUB/Engines

Контекст

Платформа (08_DECISIONS D10, CONVENTIONS «Shared engines», plans/LegacyHUB.md §4) требует вынести проверенный пайплайн LegacyHUB (OCR → Markdown → hybrid search) в переиспользуемое stateless ядро, чтобы QMS-Hub и MailHUB потребляли его, а не дублировали. LegacyHUB остаётся эталоном и первым потребителем.

Решение

Ядро teamhub_core живёт в C:\Users\manag\TeamHUB\Engines\engines/teamhub_core/ (НЕ в этом репозитории, НЕ в TeamHUB-Platform) и потребляется как pinned versioned dependency / git submodule (D10). Извлечение делается поэтапно, чтобы не дестабилизировать работающий эталон; на каждом шаге тесты зелёные.

Границы ядра (stateless)

Пакет ядра Источник в LegacyHUB Содержимое
ingest app/ingestion/{ocr,docling_extractor,chunker,normalizer,quality,table_processor,figure_processor}.py OCRmyPDF, Docling, chunker, quality-flags, нормализация (сохранение ГОСТ/ID)
search app/indexing/{embeddings,reranker,hybrid_search,opensearch_client,qdrant_client}.py BGE-M3, reranker, run_search=RRF(BM25,dense)+rerank, bootstrap индексов
storage app/storage/{minio_client,artifacts}.py put/get + retry, ensure_artifact
contracts search/citation Pydantic-типы контракт поиска/цитирования
obs app/common/json_logger.py JSON-логи с маскированием (уже app-agnostic)

Персистентность (app/db/*, Alembic), эмиссия событий, имена бакетов/индексов/ коллекций и REST-роуты ОСТАЮТСЯ в модуле.

Что уже сделано для расцепления (этот репозиторий)

  • Имена параметризованы. opensearch_index_chunks, qdrant_collection_chunks, все minio_bucket_* читаются из Settings (env-aliases). Дефолты приведены к платформенному стандарту (teamhub-legacyhub-*); потребитель (QMS/MailHUB) переопределяет их через env, не трогая код. Жёстко вшитых legacyhub-* имён в логике больше нет.
  • run_search не зависит от БД. app/indexing/hybrid_search.py импортирует только контракты (app/api/schemas), Settings и клиентов индексации — слой поиска уже stateless по отношению к Postgres/ORM.
  • obs-ядро готово. app/common/json_logger.py написан без app-specific импортов и переносится в ядро как есть.
  • Плейтменеджмент секретов вынесен из дефолтов (см. _enforce_secret_policy).
  • Первый физический engine вынесен. OCRmyPDF/Tesseract + Docling recognition теперь живут в TeamHUB/Engines/engines/teamhub-document-recognition-engine; LegacyHUB оставляет app/ingestion/ocr.py и app/ingestion/docling_extractor.py как тонкие адаптеры и source metadata в app/ingestion/ENGINE_SOURCE.md.

Остаточные шаги (staged, координируются с QMS/MailHUB)

  1. Поддерживать LegacyHUB pin на teamhub-document-recognition-engine-v0.1.0 до следующего совместимого release.
  2. Перенести contracts (типы поиска/цитирования) из app/api/schemas в teamhub_core.contracts; app/api/schemas ре-экспортирует их для совместимости.
  3. Перенести search/ingest/storage/obs в ядро; run_search принимает имена индекса/коллекции/бакетов аргументами/конфигом, а не глобальным Settings модуля.
  4. Переключить LegacyHUB на ядро как pinned submodule; app/indexing, app/ingestion становятся тонкими адаптерами. Временная vendored-копия — только с задокументированным сроком удаления.
  5. Контракт-тесты ядра единым сьютом (chunker/quality/hybrid/hashing/duplicates).
  6. Подключить QMS-Hub (свои бакеты teamhub-qms-*, индекс qms_chunks, своя PG) и MailHUB (поиск по письмам/вложениям) как вторых потребителей.

Последствия

  • Физический вынос затрагивает три репозитория (LegacyHUB, Engines, потребители) и выполняется отдельной скоординированной работой; в этом проходе закрыта готовность к расцеплению (параметризация имён, stateless run_search, app-agnostic obs-core) и зафиксирован план.
  • Риск регрессий минимизируется поэтапностью и зелёным тест-сьютом на каждом шаге.

См. также docs/ADR-layers.md (маппинг слоёв) и docs/dispatch-contract.md.