Commit graph

80 commits

Author SHA1 Message Date
Trevon
db84bb4c8f
Refine README content for clarity and conciseness
Removed redundant phrases and improved clarity in the README.
2026-10-01 14:11:24 -06:00
Trevon
4e6835a04b
Merge pull request #237 from trvon/docs/install-guide
docs: install and setup guide, Why YAMS, and working repo snippets
2026-09-30 18:00:26 -06:00
trvon
8faa5f43c3
docs: describe the graph without code-symbol nodes
README, AGENTS.md, the yams skill guide and the engineering prompt
still promised symbol extraction, calls/defined_in edges, and graph
--impact for callers. Point callers and blast radius at yams grep and
describe the relations the graph still holds.
2026-09-22 13:30:52 -06:00
0xkite
000863e664
docs: replace SourceHut with Forgejo mirror (#91)
Signed-off-by: trvon <me@trevon.dev>
Co-authored-by: trvon <me@trevon.dev>
2026-09-03 17:16:57 -06:00
trvon
cf9e5f6b3b
docs: refresh homepage and contribution guidance 2026-07-29 22:43:06 -04:00
trvon
7a64babc5e
docs: reduce documentation surface
Keep maintained entry points and executable contracts. Remove historical guides and stale references that drift from command help and source.
2026-07-29 13:02:15 -04:00
Trevon
7076e4b283
feat(daemon): shutdown hardening + test helper linkage fixes (#44)
* perf(daemon): coalesce metadata writes

* refactor(metadata): split repository ops

* fix(metadata): harden repository invariants

* feat: test coverage and continued refactor work in metadata code

* fix(graph): handle path-like explore queries

- prefer file path symbol lookup for graph explore\n- sanitize alias FTS queries before MATCH

* fix(daemon): quiesce shutdown background work

- Interrupt pending DB acquires before worker shutdown
- Wait for tracked background coroutines and timers to drain

* fix(daemon): cancel repair work on shutdown

Blocked embed and post-ingest queues could keep salvage and\nstuck-doc repair alive during shutdown. Consume cancellation in\nrepair retry loops and lock the integrated ServiceManager path\nwith regressions so shutdown fails fast instead of drifting.

* perf(metadata): reduce sqlite lock contention

* perf(metadata): flatten batch content retries

* fix(daemon): align shutdown wait budgets

A low shutdown timeout override could expire before ServiceManager\nfinished its 5s+30s WorkCoordinator join path. Share the join\nbudget constants, clamp graceful lifecycle waits to that floor,\nand lock the behavior with a daemon regression.

* perf(metadata): bound feedback write waits

* perf(metadata): prep batch content before tx

* fix(daemon): honor no-embeddings tasks

Post-ingest queue tasks dropped the per-task noEmbeddings flag,\nso focused extraction tests still emitted embed jobs and Windows\nCI exercised extra async paths. Preserve the flag through the bus,\nskip embed dispatch when requested, and wake the extraction poller\nimmediately after successful queueing.

* perf(daemon): batch fallback metadata writes

* feat(perf,docs): optimizations for metadata writes, prompt updates and test improvements

* perf(metadata): flatten insert retries

* fix(metadata): clear CI portability blockers

Use the shared portable ScopedEnvVar in metadata search-query helper tests, add mutators for test reuse, and normalize Statement::bindAll integral dispatch so long long arguments bind consistently across platforms. Add focused regression coverage for the bindAll long long path.

* perf(metadata): batch writes and steady bench

* fix(daemon): skip inactive post-ingest pollers

* perf(metadata): tighten tag and path caches

* perf(metadata): cache small batch upserts

* fix(daemon): harden embedded host teardown

* feat(docs): updating docs policies and language

* perf(metadata): tune doc update retries

* perf(metadata): bound download retries

* perf(metadata): bound download metadata waits

* bench(metadata): scope post-ingest content path

* fix(daemon): export embedded test hooks

* fix(daemon): harden test helper linkage

* fix(build): add missing standard includes
2026-06-08 16:29:44 -04:00
Trevon
b2da0d3a87
Update README.md by removing Simeon research details
Removed detailed explanation about Simeon research and future plans for YAMS.
2026-05-08 05:30:39 -04:00
Trevon
e27d5e3e84
fix: Copilot review feedback and gitignore for artifacts (#26)
* 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

* docs: soften governance and contribution prose

Replace prescriptive language ('must', 'require', 'adjudicates') with
friendlier, more welcoming phrasing across governance docs, PR template,
security policy, and contributing guide.

* feat(extract): add language-agnostic IMRAD section detection, expand entity types

detectDocumentSections(): structural heuristics for title/abstract/body
using line-length, ALL_CAPS, numbering patterns. No word matching.
Works across all languages and scripts.

deriveTitle(): add IMRAD detection step before first-line fallback.
isHighValueGraphType(): use ScientificAdapter suffix detection (40+
biomedical suffixes) instead of hardcoded 11 types.

* feat(ingest): field-weighted FTS5, IMRAD claim segmentation, ScientificAdapter fallback

- FTS5: title tokens repeated 3x, abstract 2x, body 1x in content
  field for BM25 field weighting without schema migration
- IMRAD-aware claim segmentation: buildBodyClaimSegments splits
  each detected section independently, distributes maxSegments
- ScientificAdapter fallback: when GLiNER unavailable, inline
  entity extraction via suffix/pattern detection → direct KG write
- Add abstract field to PreparedMetadataEntry + BatchContentEntry

* refactor(daemon): extract enrichment stages to post_ingest_enrichment.cpp

Split PostIngestQueue.cpp (3145 lines) into:
- PostIngestQueue.cpp (~3084 lines): coordinator, lifecycle, queue
  management, extraction pipeline, gradient limiters
- post_ingest_enrichment.cpp (new, 701 lines): KG/symbol/entity/title
  stage processing with self-contained enrichment utilities

* fix(daemon): restore enrichment utilities to PostIngestQueue.cpp

Processing methods still in PostIngestQueue.cpp reference entity/NL
utilities (isUsefulNlEntity, buildBodyClaimSegments, etc.) that were
removed during decomposition. Restore them to anonymous namespace.

* fix: address PR #25 Copilot review feedback

- Add missing #include <unordered_map> to concept_resolver.cpp
- Batch entity writes per doc in SearchEngineManager (reduces write amp)
- Remove non-existent CorpusAdapter API claims from README
- Replace absolute paths with repo-relative in daemon-download-jobs.md
- Revert plugin-zyp default to false (noisy warnings)
- Fix grammar in extraction-repair-pipeline.md heading
- Add gitignore entries for .wrangler, .claude, .artifacts, papers

* fix: Copilot feedback - IDF passthrough, batch flush, debug gate, IMRAD comment

- Pass IDF map through enrichWithFallbackConcepts for weighted fallback
- Batch entity writes per doc with threshold flush in SearchEngineManager
- Downgrade graph_rerank-gate diagnostic to spdlog::debug
- Add TODO for entity_callback wiring during concept mining
- Fix DocumentSections comment to match language-agnostic implementation

* chore: bump simeon (ScientificAdapter v3)

* fix: resolve merge conflict markers, add missing <random> include

Remove leftover <<<<<<< / ======= / >>>>>>> from earlier merge.
Add #include <random> to ingestion_throughput_bench.cpp.

* chore: trigger CI after simeon submodule push
2026-05-08 05:29:46 -04:00
Trevon
72647bbaf7
chore: stabilize CI, faiss, metadata, docker, and simeon (#25)
- CI warm: ccache dep, continue-on-error, 60min timeout, YAMS_DISABLE_FAISS
- Faiss: YAMS_HAS_FAISS guard, Apple Clang disable, OpenMP detection
- Metadata: retry constraint failures, deduplicate batch UPSERT entries
- Docker: wget for Zig, gfortran, YAMS_DISABLE_FAISS=1
- CI config: free-disk-space v1.3.1, libomp-18-dev, experimental trigger
- Weekly benchmarks: faiss disable, ccache, diagnostics capture
- Simeon: bump to 7763a97, EntropyRouter, concept_count
- CorpusStats: extraction readiness fields
- Remove committed artifacts (.wrangler, .artifacts, dispatcher_external)
- Fix .vscode/settings.json hardcoded path

Signed-off-by: trvon <git@trevon.dev>
2026-05-07 21:07:59 -04:00
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
c55ce54b87
fix: ci fixes and experiment for search / cluster routing 2026-04-28 01:29:48 -04:00
trvon
8772cc8e54
fix(docs,ci): addressing breaking changes in zig v0.16.x in Dockerfile, docs update and code cleanup 2026-04-25 11:27:18 -04:00
trvon
bdcff5b636
fix: HNSW and topology rebuilds are now batched in repair. Cleaning up from previous migration work 2026-04-21 13:58:10 -04:00
trvon
e4a8639ef6
feat: tuning topology system to work better with simeon via configuration 2026-04-19 20:10:46 -04:00
trvon
d7ab4844a1
fix: small fixes for benchmarks and documentation update 2026-04-17 22:32:04 -04:00
trvon
569ffaed8e
feat: further search improvements and daemon sleep fixes. Commit before service manager refactor/cleanup 2026-04-15 21:50:03 -04:00
trvon
f4fffd73a0
feat: instrumentation improvements for benchmarks, shell completition improvements, packaging updates for completions and docs updates 2026-04-13 21:34:18 -04:00
trvon
0c74dcb34e
feat: completitions fixes. Starting topology routing work for semantic clusters 2026-04-13 12:51:59 -04:00
trvon
1526545f79
fix: updating readme and linking benchmark pages 2026-04-09 22:58:23 -04:00
Trevon
bf462eeca0
Remove symbol extraction and snapshots sections
Removed sections on symbol extraction and snapshots from the README.
2026-03-05 09:52:17 -05:00
Trevon
e8caa25b23
Update installation instructions in README
Removed instructions for installing nightly builds.
2026-03-03 14:18:07 -05:00
trvon
5a764ac2cc
feat: updating brew install guide 2026-02-27 22:02:35 -05:00
trvon
f624a23067
build fixes and benchmark improvements 2026-01-17 16:29:28 -05:00
trvon
eb87c8ec40
reducing ingestion bottlenecks with better batch operations 2026-01-16 19:04:11 -05:00
trevon
2e687eef79
docs improvements, tuning manager now scales postingestqueue, stats exposed in yams stats 2025-12-20 13:36:59 -05:00
trevon
b82a3ccd36
grammar and symbol extractor bug fixes 2025-12-13 14:50:44 -05:00
trevon
537d4594f4
docs update and ci improvements for qpdf 2025-11-27 14:25:29 -05:00
trevon
244cf02822
windows build stable on dev machine 2025-11-23 23:22:30 -05:00
trvon
12fc1b8a50
resolved concurrency bugs in daemon. added fuzzing work in progress per issue #8 2025-11-11 10:10:07 -05:00
trvon
f7d559b2a9
docs: update README with Homebrew installation and simplified init
- Add Homebrew installation section with brew link workaround
- Simplify Quick Start to use 'yams init .' for current directory
- Update caveats in formula template with cleaner instructions
- Add links to yamsmemory.ai docs
2025-11-08 15:48:15 -05:00
trvon
4702a345ad
ci fixes, test updates and documentation imrpovements 2025-11-07 13:20:58 -05:00
trvon
1f74c81a76
adding experiemntal clause to readme 2025-10-29 23:38:13 -04:00
trvon
8d23211af2
improvements for ci, setup.sh and updates to new symbol extraction plugin 2025-10-21 19:38:45 -04:00
trvon
692dabe16e
commititing readme and vscode settings fixes 2025-10-20 16:14:57 -04:00
trvon
b6ca31dfb0
adding symbol extraction work, simplying build with ./setup.sh, updated plugin tests with new meson shard and other goodies 2025-10-20 16:11:31 -04:00
trvon
b25a9f690d
v0.7.5 2025-10-13 20:07:48 -04:00
trvon
83fa1ad1ba
v0.7.5 staging and license updates 2025-10-13 17:07:31 -04:00
trvon
b065e6a2c1
v0.7.5 2025-10-11 00:34:31 -04:00
trvon
72d04f66e0
v0.7.2 staging 2025-10-03 04:02:52 -04:00
Trevon
db1aa312d4
docs update 2025-09-27 21:41:48 -04:00
Trevon
db22bd3651
ci fixes 2025-09-21 16:44:57 -04:00
Trevon
43699f99a3
v0.7.0-prerelease 2025-09-20 22:55:34 -04:00
Trevon
d9e07e981f
hotfix v0.6.37 2025-09-17 12:55:10 -04:00
Trevon
6d67ef0f89
v0.6.20 2025-09-13 22:01:36 -04:00
Trevon
31e1aa5b56
v0.6.14 2025-09-12 23:37:14 -04:00
Trevon
461005b00e
build fixes and stabilizations 2025-09-11 11:59:46 -04:00
Trevon
956c43b80b
v0.6.12 experiemental 2025-09-11 11:28:42 -04:00
Trevon
728f255747
v0.6.9 2025-09-06 00:11:43 -04:00