Commit graph

1,193 commits

Author SHA1 Message Date
trvon
285c6f7607
Revert "Experimental Merge (#23)"
This reverts commit e21de6ff4a.
2026-05-07 20:44:33 -04:00
Trevon
e21de6ff4a
Experimental Merge (#23)
* feat: search work and moving to experimental

* WIP

* feat(search): diagnostic logging pipeline — graph build, concepts, reranker gate

- New [concepts] per-50-query log showing extracted query concepts, type
  distribution, and used_gliner flag.

- New [PIQ-entity] per-1000-dispatch + per-document completion log with
  entity type counts (e.g., 'protein=3, gene=1, chemical=2').

- New [graph_rerank-gate] one-shot log showing why enableGraphRerank
  is zeroed: shows shortQueryBudgeted, corpusWarming, bypassWarmingGate,
  lexicalReady, and post-ingest inflight.

- New [graph_rerank] per-50-query log with window size, matched
  candidates, applied count, concept count, and elapsed time.

- retrieval_quality_bench.cpp: add YAMS_SEARCH_BYPASS_CORPUS_WARMING_GATE=1
  so benchmark queries are not gated by freshness checks.

- resolve merge conflicts from experimental branch.

* fix(search): enable entity extraction for text files via GLiNER fallback

- prepareMetadataEntry: shouldDispatchEntity now also checks hasTitleExtractor()
  so plain-text files (.txt, .md) get entity extraction even when no binary
  entity provider supports their extension.

- processEntityExtractionStage: when no ExternalEntityProvider matches,
  fall back to processTitleExtractionStage which runs GLiNER on text.

- refreshStageAvailability: entity stage is now considered capable when
  hasTitleExtractor() is true, so the entity poller gets concurrency budget
  even if entityProviders_ is empty.

- kCombinedEntityTypes: add biomedical entity types (protein, gene, cell,
  disease, chemical, drug, pathway, biological_process, biomarker, anatomy,
  organism) so GLiNER extracts high-value biomedical entities instead of
  only generic NL types (person, organization, concept).

* perf(bench): add YAMS_POST_ENTITY_CONCURRENT=4 for text entity fallback throughput

* feat(search): fast token-based entity extraction for text documents

- Replace slow GLiNER-based entity extraction (~260ms/doc) with fast
  token-based concept mining (~1ms/doc) via generateFallbackQueryConcepts.
  Uses sub-phrase mining + IDF-weighted token salience — the same function
  already used for query-time concept fallback.

- Store entities with full KG scaffolding: KGNode with entity type/label,
  KGAlias for query-time resolution, DeferredEdge from entity→document,
  and DeferredDocEntity linking entity to document for getDocEntitiesForDocument.

- Add biomedical entity types to kCombinedEntityTypes in title extraction
  (protein, gene, cell, disease, chemical, drug, pathway, etc.) so GLiNER
  can output high-value biomedical entities when used.

- Add include for query_expansion.h to access generateFallbackQueryConcepts.

- bench: add YAMS_POST_ENTITY_CONCURRENT=4 for entity poller throughput.

Benchmark: 22K+ entities extracted across 5183 docs, ~41% high-value
biomedical. MRR 0.4281 (beats 0.4273 baseline by +0.2%).

* feat(diag): add firstDocEntities check to graph_rerank-gate log

- Queries kg_doc_entities for the first candidate document to verify
  whether fast entity writes were committed before queries start.
- Confirmed: firstDocEntities=0 — entities stuck in WriteCoordinator
  async queue when benchmark queries begin.

* fix(search): add periodic write-coordinator flush during entity extraction

Entity writes enqueued via writeCoordinator_ can accumulate since the
writer loop is capped at 8 batches/iteration. For 5K+ documents this
creates a backlog that outlasts the post-ingest drain wait — entities
are not committed to kg_doc_entities before benchmark queries start.

Add a periodic flush (every 128 batches, 500ms timeout) in the entity
extraction batch processor to drain the WC queue incrementally.

Diagnostic confirms firstDocEntities=0 persists — a synchronous
committed flush or batched WC enqueue is needed.

* fix(docker): add gfortran for openblas arm64 build

* fix(search): accumulate entity writes into shared WC batch, flush once

The WriteCoordinator writer loop is capped at 8 batches/iteration. With
5K+ per-doc entity writes, entities outlast the benchmark's post-ingest
drain and firstDocEntities=0 when the graph scorer runs.

- processEntityExtractionStage: add optional DeferredKGBatch* parameter.
  Text-fallback appends entity nodes/aliases/edges/doc-entities to the
  shared batch instead of creating per-doc WC batches.

- processEntityExtractionBatch: creates one DeferredKGBatch, passes it to
  all stage calls in the batch, enqueues to WC once at end.

- Single-shot WC flush: after all stages go idle (totalInFlight==0),
  calls writeCoordinator_->flush(15s) to drain remaining entity writes
  before benchmark queries start.

- DeferredKGBatch forward-declared in PostIngestQueue header.

* ci: fix free-disk-space action ref, sha didnt exist

* fix(search): revert WC accumulation, fix text fallback to per-doc writes

The shared-batch WC accumulation approach worked conceptually but:
- WC flush with totalInFlight==0 fires too early (before last batch)
- generateFallbackQueryConcepts produces empty concepts for 99% of
  document texts (designed for short queries, not abstracts)
- Only 1/5183 docs produced concepts → 1 doc worth of entities in KG

Revert to simple per-doc entity extraction. The enable=/disable=
graph reranker gate is still controlled by shortQueryBudgeted=1
which zeroes the graph reranker on the first query (intent=Code).

firstDocEntities=0 persists — entities need a different creation
strategy for document text (phrase mining too conservative).

* fix(docker): add curl retry for Zig download

* feat(search): per-profile ConceptExtractionBackend (Fallback vs GlinerWithFallback)

- search_engine_config.h: new ConceptExtractionBackend enum with Fallback
  (sub-phrase mining + IDF tokens, <1ms) and GlinerWithFallback (GLiNER
  first, fall back on empty/timeout). Default: GlinerWithFallback.

- search_tuner.h: SCIENTIFIC profile sets Fallback (GLiNER returns empty
  for 99% of short biomedical claims). Other profiles keep default.
  Wired through TunedParams.applyTo().

- search_engine.cpp: gate GLiNER concept extraction on the config backend.
  When Fallback, conceptFuture is never created and concepts come directly
  from generateFallbackQueryConcepts. Added [concept-backend] diagnostic.

- search_engine_builder.cpp: builder log now includes concept_backend
  in the override-state startup message.

- search_tuner_catch2_test.cpp: verify SCIENTIFIC profile uses Fallback.

Note: builder correctly sets Fallback but query-time workingConfig still
shows GlinerWithFallback (int=1). This is a config-sync issue between
builder-time profile application and runtime config snapshot — the
tuner or a post-override config copy may reset the field. To be fixed.

* refactor(search): extract concept resolver, per-profile backend, clean dead code

- New concept_resolver.h/cpp: extract enrichWithFallbackConcepts from the
  search engine monolith into a testable unit. Generates IDF-weighted
  token concepts via generateFallbackQueryConcepts, deduplicates, and
  appends to existing concepts.

- search_engine_config.h: new ConceptExtractionBackend enum (Fallback vs
  GlinerWithFallback). SCIENTIFIC profile sets Fallback since GLiNER
  extracts 0 concepts for 99% of short biomedical claims.

- search_tuner.h: wire conceptExtractionBackend through TunedParams,
  applyTo, seedTunedParamsFromConfig (the one-line fix that resolved
  the config-sync bug where profile Fallback was overridden at query
  policy resolution time).

- search_engine.cpp: materializeConcepts lambda restructured to always
  reach the fallback even when GLiNER future is invalid. Removed
  ~80 lines of diagnostic bloat ([concept-backend], [workingConfig-*],
  per-50 [concepts]). GLiNER gate checks config backend.

- PostIngestQueue.cpp: removed dead fast-token entity extraction
  (~150 lines of concept generation + KG scaffolding that produced
  0 entities for 99% of documents). Reverted entity-stage gating
  (entityCapable || hasTitleExtractor) and shouldDispatchEntity to
  extension-only checks. Removed DeferredKGBatch forward decl.

- gliner_query_extractor: removed unused createGlinerExtractionFunc-
  FromProvider fallback factory (~150 lines).

- ServiceManager.cpp: removed fallback call site for removed factory.

- builder log: removed concept_backend diagnostic line noise.

- search_tuner_catch2_test.cpp: verify SCIENTIFIC uses Fallback.

Net: ~400 lines removed, ~120 lines added (concept_resolver unit +
config wiring). GLiNER concept extraction savings: ~30-80ms/query
× 300 queries = 9-24s total for SCIENTIFIC profiles.

* fix: entity stage only for binaries, title stage for text

entity stage = binary providers (Ghidra/Zyp). title stage = GLiNER for all
text. No overlap — title already stores NL entities to KG.

* fix(docker): add wget for Zig, disable faiss

openblas arm64 build fails in Docker containers. YAMS_DISABLE_FAISS=1
env var skips faiss (and its openblas transitive dep). Zig download
now uses wget -c for resume on flaky ziglang.org connections.

* ci: add experimental branch to tests trigger

* ci: pin free-disk-space to v1.3.1

* feat: Simeon concept mining entity export for graph reranker

- simeon_lexical_backend.h: EntityCallback in Config. Called with
  (docId, entityText, confidence) per concept match per doc.

- simeon_lexical_backend.cpp: after mine_concepts, iterate docs
  via collect_doc_concepts + entity_callback.

- SearchEngineManager.cpp: enable concept_mining_enabled, wire
  entity_callback batch-inserting DocEntity via KG store. Fix
  kgStore capture-before-move race.

Note: simeon submodule has collect_doc_concepts in concept_mining.hpp
+ concept_mining.cpp (must commit to submodule separately).

* ci: disable faiss in warm and test jobs

* ci(bench): add faiss disable, ccache, and failure diagnostics to weekly benchmarks

* fix(metadata): retry constraint failures in executeQueryOnPool

FK race on Linux causes transient constraint failures when metadata
write races ahead of document commit. Previously treated as terminal.
Now retried with backoff like lock errors.

* fix(metadata): deduplicate batch entries before UPSERT

Duplicate (document_id, key) pairs within a single batch cause SQLite
ON CONFLICT DO UPDATE to fail with constraint violation. Dedup keeps
the last write per key.

* chore: bump simeon, add extraction readiness stats

Simeon: 8bf225e -> 6320ab6 (adapter + QPP router framework).
CorpusStats: add contentExtracted*, ftsIndexed*, titleCoverage,
languageCoverage, and KG topology richness fields.

* feat(search): integrate simeon EntropyRouter strategy lane, corpus-state tuning

- Wire EntropyRouter + Keyphrase/LeadField strategies into SimeonLexicalBackend
- Add scoreStrategyRouted(), hasStrategyRouter(), strategy_router_enabled config
- Add YAMS_SIMEON_STRATEGY_ROUTER_ENABLED env wiring
- Add applyCorpusStateAdjustments(): per-corpus-state recall push (vec max,
  rescue slots, weak-query fanout, entity vec expansion, NER damping)
- Extend CorpusStats with extraction/FTS/title/language/KG edge+alias density
- Add hasRichGraphTopology(), nerOnlyNoEdges damping to graph adjustments
- Add 14 new engine-policy benchmark candidates (retrieval lanes, RRF sweep,
  aggressive recall, strategy router)
- Weight miss_pre_fusion_rate in optimization objective (0.25x)
- Add Simeon lexical concept/doc count to IndexFreshnessSnapshot + status
- Bump simeon submodule (retrieval_strategy + corpus_adapter API)

* feat(search): add concept_count and concept_mining_enabled accessors

* feat(search): add ScientificAdapter + RM3 PRF blend

ScientificAdapter: training-free entity extraction for scientific
text via regex/suffix patterns (biomedical suffixes, ALL_CAPS symbols,
capitalized multi-word terms, measurements). Replaces TextAdapter
in strategy router build, providing entity lists for KeyphraseStrategy.

RM3: add score_with_prf blend path to scoreStrategyRouted at 0.30
weight when rm3_enabled=true. New benchmark candidate
scientific_strategy_rm3.

Strategy router + ScientificAdapter: mrr=0.4514 ndcg=0.4789 recall=0.5849
2026-05-07 20:36:10 -04:00
trvon
8fd830e9a9
feat(search): integrate simeon EntropyRouter strategy lane, corpus-state tuning
- Wire EntropyRouter + Keyphrase/LeadField strategies into SimeonLexicalBackend
- Add scoreStrategyRouted(), hasStrategyRouter(), strategy_router_enabled config
- Add YAMS_SIMEON_STRATEGY_ROUTER_ENABLED env wiring
- Add applyCorpusStateAdjustments(): per-corpus-state recall push (vec max,
  rescue slots, weak-query fanout, entity vec expansion, NER damping)
- Extend CorpusStats with extraction/FTS/title/language/KG edge+alias density
- Add hasRichGraphTopology(), nerOnlyNoEdges damping to graph adjustments
- Add 14 new engine-policy benchmark candidates (retrieval lanes, RRF sweep,
  aggressive recall, strategy router)
- Weight miss_pre_fusion_rate in optimization objective (0.25x)
- Add Simeon lexical concept/doc count to IndexFreshnessSnapshot + status
- Bump simeon submodule (retrieval_strategy + corpus_adapter API)
2026-05-07 20:14:59 -04:00
trvon
a61d0fe34e
feat(search): add concept_count and concept_mining_enabled accessors 2026-05-07 20:14:41 -04:00
trvon
342a3f8fae
chore: bump simeon, add extraction readiness stats
Simeon: 8bf225e -> 6320ab6 (adapter + QPP router framework).
CorpusStats: add contentExtracted*, ftsIndexed*, titleCoverage,
languageCoverage, and KG topology richness fields.
2026-05-07 20:14:02 -04:00
trvon
68a49e70dd
fix(metadata): deduplicate batch entries before UPSERT
Duplicate (document_id, key) pairs within a single batch cause SQLite
ON CONFLICT DO UPDATE to fail with constraint violation. Dedup keeps
the last write per key.
2026-05-07 16:22:00 -04:00
trvon
e971b56aa9
fix(metadata): retry constraint failures in executeQueryOnPool
FK race on Linux causes transient constraint failures when metadata
write races ahead of document commit. Previously treated as terminal.
Now retried with backoff like lock errors.
2026-05-07 14:23:57 -04:00
trvon
41276c0375
ci(bench): add faiss disable, ccache, and failure diagnostics to weekly benchmarks 2026-05-07 11:23:16 -04:00
trvon
db778ce72d
ci: disable faiss in warm and test jobs nightly-20260507-db778ce7 2026-05-06 21:27:48 -04:00
trvon
b463a29acc
ci: pin free-disk-space to v1.3.1 2026-05-06 20:23:03 -04:00
trvon
e7c520f41d
ci: add experimental branch to tests trigger 2026-05-06 20:23:03 -04:00
trvon
597aed4fc9
fix(docker): add wget for Zig, disable faiss
openblas arm64 build fails in Docker containers. YAMS_DISABLE_FAISS=1
env var skips faiss (and its openblas transitive dep). Zig download
now uses wget -c for resume on flaky ziglang.org connections.
2026-05-06 15:10:03 -04:00
trvon
ec1e0a6ac2
ci: fix free-disk-space action ref, sha didnt exist 2026-05-06 10:01:37 -04:00
trvon
8f5b0d0eb3
fix(docker): add gfortran for openblas arm64 build 2026-05-06 09:08:44 -04:00
trvon
b4b22e428c
ci(warm): add ccache dep, tolerate populate timeout 2026-05-05 21:09:19 -04:00
trvon
1f9bc767a0
feat(search): reduce graph noise, add edge-creation diagnostics
- PostIngestQueue: halve co-occurrence edge budgets (entities 12→8, edges 36→16),
  skip edges where neither entity is biomedical high-value, raise the
  confidence floor for biomedical pairs (0.10→0.20) and non-biomedical
  pairs (0.05→0.08), bump base multiplier (0.50→0.65). This cuts total
  edge volume by over 50% while retaining signal quality.

- search_tuner.h: raise graphRerankMinSignal to 0.08 (from default 0.01)
  to match the elevated edge-confidence floor.

- New atomic graph-construction counters (gs_processed_, gs_totalEntities_,
  gs_highValueEntities_, gs_totalEdges_, gs_totalPrimaryTopicEdges_) log
  entity → edge pipeline every 100 documents via [PIQ-graph].

- Periodic [graph_rerank] log (every 50 queries) reports reranker
  window size, matched candidates, whether boost was applied, concept
  count, and elapsed time — enabling end-to-end traceability from
  ingestion to retrieval.
2026-05-05 20:56:12 -04:00
trvon
bec8164d4c
fix(vector): guard faiss backend init behind YAMS_HAS_FAISS
Types only declared when YAMS_HAS_FAISS defined. Falls through
to SqliteVec PQ when faiss unavailable.
2026-05-05 20:32:44 -04:00
trvon
6704e0bb76
fix(search): wire GLiNER concept extractor, fix PQ dirty race, add KG NER awareness 2026-05-05 20:06:06 -04:00
trvon
18b10dc444
fix: addressing build regressions where fiass needed openmp installed 2026-05-05 19:50:16 -04:00
trvon
bc100efcdc
feat: updating zyp pdf extractor to use v0.16.0 compat in plugin build 2026-05-05 19:37:50 -04:00
trvon
8433d4f6fc
fix: disable faiss on Apple Clang macOS, remove hardcoded /opt/homebrew paths
faiss recipe validate() rejects apple-clang (no OpenMP). Disable faiss
in configure() when compiler=apple-clang on macOS. The list order is
swapped to [False,True] so False is the default; configure() enables
faiss on all non-apple-clang platforms.

Also removes hardcoded /opt/homebrew/{include,opt/libomp/include} paths
from src/vector/meson.build that broke Linux ARM / Docker builds when
the cmake faiss dep fallback was reached.
2026-05-05 19:11:47 -04:00
trvon
f14c7d64ab
fix: disable faiss on Apple Clang macOS, restore profile cache keys
faiss requires OpenMP which Apple Clang does not ship. Skip faiss
on macOS/apple-clang to prevent conan install failures during warm.

Also restore trailing whitespace in Linux gcc profiles to match
original cache key hash (hashFiles change invalidated all platform
caches, exposing the macOS issue).
2026-05-05 18:50:56 -04:00
trvon
c3127d55c9
fix(ci): restore cache-hit guard for macOS/Windows warm step
The conan install step fails on macOS when run unconditionally (previously
hidden by the cache-hit skip). Restore the guard for non-Linux platforms
while keeping Linux always-running to populate ccache.
2026-05-05 18:41:13 -04:00
trvon
07ad8667ea
fix(ci): revert Conan profile ccache wiring (breaks compiler_executables)
tools.build:compiler_executables requires bare executable names, not
'ccache clang' with a space. setup.sh already wraps CC/CXX with ccache
for Meson builds. The warm step's meson compile (Fix 3) populates
ccache for YAMS source. Conan dep ccache will be addressed separately.
2026-05-05 18:38:20 -04:00
trvon
76c7e9d60f
security,ci: security issues address from codeql and improving cache usage logic in ci 2026-05-05 18:27:43 -04:00
trvon
cbb86506d0
feat: add RM3 pseudo-relevance feedback + adopt research-tuned config 2026-05-05 16:13:18 -04:00
trvon
73fbe4c842
feat: add BM25 variant RRF fusion to lexical backend 2026-05-05 16:13:18 -04:00
trvon
102d5a1e50
feat: integrate simeon concept mining into lexical backend 2026-05-05 16:13:18 -04:00
trvon
2d84e44013
security: addressing codeql security finding and expanding opengrep rules 2026-05-05 15:38:59 -04:00
trvon
dc6aaa13ce
feat: add FAISS HNSW vector backend with ConfigResolver policy 2026-05-05 15:38:22 -04:00
trvon
9cf74ec420
ci: test fixes 2026-05-05 13:38:53 -04:00
trvon
8b7bfe575d
feat: improved search fusion logic and tuning parameters. CI improvements, reverting to push with wrangler in CI. Experimenting with vector rebuild to address additional lost overhead in search 2026-05-05 08:58:20 -04:00
trvon
ea6cd51da3
fix: removed reduant corpus adapter nightly-20260505-ea6cd51d 2026-05-04 16:33:57 -04:00
trvon
7ae52e8b8b
fix: test fixes and search fusion update to correctly expose simeontext fusion so that it does not drop ft5s candidates. Still explore fusion optimizations v0.14.2 2026-05-04 15:54:57 -04:00
trvon
77dad749af
docs: revert CHANGELOG.md to condensed version, update release to fix overwrite attempt in release asset stage 2026-05-04 15:32:02 -04:00
trvon
052258861f
merge 2026-05-04 15:28:29 -04:00
trvon
14e8a17c59
docs: updating changes logs archive 2026-05-04 15:27:58 -04:00
github-actions[bot]
591f664b82
chore(main): release 0.14.1 (#21)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-04 14:04:13 -04:00
trvon
f80013063d
build: windows packaging fixes 2026-05-04 14:02:43 -04:00
trvon
2d5c6625eb
fix: download logic improvements and ci test fixes. Stagging download fixes seperate from search features 2026-05-04 13:29:17 -04:00
github-actions[bot]
ef6c8ade12
chore(main): release 0.14.0 (#19) v0.14.0
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-04 12:29:28 -04:00
trvon
e0b288f4e0
ci: improve release please configuration and CHANGELOG 2026-05-04 11:11:45 -04:00
trvon
7d7f981fb4
ci: patching orphaned boost setting 2026-05-04 08:39:27 -04:00
trvon
a7ea3da82a
updating boost variable exposure 2026-05-03 17:03:34 -04:00
trvon
34e8ede523
build: updating meson.build for windows boost exposure improvements 2026-05-03 13:38:27 -04:00
trvon
75e7dcfa47
ci: windows ci improvements 2026-05-03 05:39:54 -04:00
trvon
ba9030bce8
fix: repair fix in db optimize 2026-05-03 01:31:40 -04:00
trvon
f3ffb92264
security: updates to opengrep rules, repair subsystem scanning logic and windows build logic 2026-05-03 01:06:25 -04:00
trvon
5adb8f153f
security: dev scripts and hooks update, perf update, security fixes for quality issues 2026-05-02 21:40:47 -04:00
Trevon
557f8c1da3
Merge branch 'main' of https://github.com/trvon/yams 2026-05-02 21:34:38 -04:00