@oomkapwn/enquire-mcp 3.11.1 → 3.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
+ ## [3.11.2] — 2026-06-30
6
+
7
+ > **TL;DR:** **v3.11.2 STABLE — promoted `@rc` → `@latest`. A positioning + eval-rigor patch, zero `src/` behavior change.** Born from a study of a 21k★ adjacent-domain competitor (DeusData/codebase-memory-mcp, *code* memory): borrow the **discipline** (lead with one *measured* number, re-narrate constraints as moats, broaden agent-SEO), never the domain or an unmeasured claim. Ships **`bench:context`** (a context-savings harness — our niche analog of "Nx fewer tokens", with **no figure published** until a representative-vault run + sign-off) + **`docs/EVALUATION_PLAN.md`** (a pre-registered, score-free methodology) + a README hero that now **leads with the already-measured reranker delta** (+15.5 NDCG@10 / +24.7 MRR on a reproducible 60-query ablation) and re-frames the on-device model's weight as the privacy/grounded **moat** (zero cloud calls during serve — *enforced* via `setEmbeddingsOffline`, not aspirational). Every positioning claim is substantiated + invariant-pinned; the no-overclaim rule held (the own-diff sweep even caught + reverted a stray synthetic-vault number `git add -A` had committed). **46 tools · 19 prompts · 1439 tests · 0 CodeQL · 0 open dependabot.** No API breaks (additive patch). CI publishes `@latest` + signed provenance (SLSA L2) + OIDC MCP-registry sync. **Per-RC detail: rc.1 below.**
8
+
9
+ ## [3.11.2-rc.1] — 2026-06-29
10
+
11
+ > **TL;DR:** **Competitive-study response (DeusData/codebase-memory-mcp, 21k★) — eval rigor + number-led positioning, all inside the no-overclaim rule.** A study of that project's positioning playbook (which drove its stars via one measured hook + frictionless install) yielded three borrowable, niche-correct moves — and an explicit list of what NOT to copy (its code-domain features, single-binary rewrite, SLSA-3 claim, any borrowed number).
12
+
13
+ ### Added
14
+
15
+ - **`bench:context` — context-savings harness** (`scripts/bench-context.mjs` + `tests/bench-context.test.ts`). Our niche-correct analog of code-memory tools' "Nx fewer tokens" headline: per question, it measures the `obsidian_context_pack` budget-capped bundle vs the full bodies of the top-K hits an agent would otherwise read in full, over the same hybrid retrieval, and reports the token ratio. Deterministic synthetic vault, pure measurement helpers (`estimateTokens` / `savingsRatio`) covered with NEGATIVE controls so an inflated ratio can't ship. **No headline figure is published** — a "Nx less context" claim requires a representative-vault run + maintainer sign-off (same gate as LongMemEval). `docs/benchmarks.md` gains a "Context efficiency" methodology section.
16
+ - **`docs/EVALUATION_PLAN.md`** — a pre-registered evaluation methodology (no scores by design), committed *before* the headline runs so the method is reviewable without front-running a result. Codifies the project's "every claim an auditor can verify" brand: measured-not-asserted, reproducible, reviewed; retrieval-quality-not-QA-accuracy scope; zero-result=FAIL; weakness disclosure; the reference-hardware + sign-off publication gate. Added to `files[]` (parity with `benchmarks.md`).
17
+
18
+ ### Changed (positioning — substantiated claims only)
19
+
20
+ - **README hero leads with a measured number.** A new credibility line cashes out the qualitative hooks with the already-measured, committed reranker delta — **+15.5 NDCG@10 / +24.7 MRR** over plain hybrid on the reproducible 60-query ablation — the way the 21k★ competitor leads with a falsifiable figure instead of a feature wall. The qualitative "most advanced Obsidian MCP" line stays (and the GitHub About lead is unchanged — pinned by `github-metadata-invariant`).
21
+ - **Install weight re-narrated as the privacy/grounded MOAT** (hero point #3): the ~110 MB on-device model is *why* recall is grounded + private with zero cloud calls during serve — "enforced, not aspirational" — instead of an unexplained cost. The honest "When NOT to use it" concession is untouched.
22
+ - **Broader agent-targeting in npm keywords** (windsurf, zed, aider, gemini-cli, opencode, kilocode) — pure discoverability; enquire is client-agnostic by construction over MCP. (GitHub-topic broadening + an OpenSSF Scorecard workflow are tracked as separate follow-ups — the topic set is checked against live GitHub by an invariant, and workflow files need a maintainer web-UI merge.)
23
+
24
+ ### Explicitly NOT copied (niche guard, documented)
25
+
26
+ The 21k★ tool is a **code**-intelligence memory; we are a **notes/PKM** memory. We did NOT adopt: its single-static-binary/zero-dep rewrite (our on-device model is the privacy moat), any code-domain feature (tree-sitter AST, Hybrid LSP, CALLS/INHERITS edges, dead-code, git-diff blast-radius), 3D graph visualization as a hero asset (documented non-goal), its SLSA-3 badge (we are guarded at L2), multi-agent auto-config / hosted team-graph (we are single-user local-first), or any of its metrics restated as ours.
27
+
28
+ **1434 → 1439 source tests.** No `src/` behavior change (script + docs + positioning). Ships `@rc`; promotion maintainer-gated.
29
+
5
30
  ## [3.11.1] — 2026-06-28
6
31
 
7
32
  > **TL;DR:** **v3.11.1 STABLE — promoted `@rc` → `@latest` (maintainer call). A patch line that closes the case-fold-asymmetry class across all three of its instances.** It began as the **v3.11.0-STABLE external-audit response** (2 independent auditors — Cursor 4.3/ship, Goose 4.4/ship — both **0 CRIT / 0 HIGH / 0 MED**, the cleanest external round of the line; both re-verified the rc.17→rc.25 hardening holds through `dist/`). Cursor's 2 LOWs (`SCHEMA-validate-then-write-gap`) were **reasoned-rejected** (a false equivalence — the write-content sink is linear and already double-bounded by the 7.5 MB HTTP cap + 5 MB `maxFileBytes`; a 1 MB cap would reject legitimate large notes), and Goose's NEL/VT/FF finding was a confirmed non-defect. The real value came from internal adversarial lenses: an **anti-anchoring** Workflow caught a Greek word-final-sigma silent under-replace in `replace_in_notes` that *neither* external auditor found (rc.1), and the **mandatory pre-promotion re-sweep** then caught a third, more-severe instance of the same class — `obsidian_search_text` silently dropping notes on a final-Σ query token (rc.2) — before `@latest` flipped. All three instances are now consistent (per-code-point `foldForMatch` for `replace_in_notes` + `search_text`; the `semanticSearch` snippet-centring residual stays documented-accept as it's cosmetic). **46 tools · 19 prompts · 1434 tests · 0 CodeQL · 0 open dependabot.** No API breaks (additive patch). CI publishes `@latest` + signed provenance (SLSA L2) + OIDC MCP-registry sync. **Per-RC detail: rc.1 + rc.2 below.** **Lesson of the line: two strong external auditors with a clean bill of health still left a real correctness bug — the internal anti-anchoring + pre-promotion re-sweep are what found the class; external state-driven re-verification and internal un-enumerated-class hunting are complementary, exactly as the ≥2-auditor gate intends.**
package/README.ar.md CHANGED
@@ -54,7 +54,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
54
54
  > 3. **صفر استدعاءات سحابية أثناء التشغيل.** النماذج مخزّنة محلياً (تنزيل لمرة واحدة من HuggingFace). محتوى مكتبتك لا يغادر جهازك أبداً. آمنة للعمل المعزول (air-gap) افتراضياً.
55
55
  > 4. **استدعاء واعٍ بالحداثة.** تُبلّغ كل نتيجة عن عمر الملاحظة؛ وإعادة الترتيب الاختيارية بالحداثة تتيح للوكيل تفضيل المعرفة الحديثة ووسم الحقائق القديمة لإعادة التحقق — حدود "الوعي بالنسيان"، مبنيّة على `mtime` الذي تملكه ملفاتك أصلاً.
56
56
 
57
- **46 أداة · 19 موجِّه MCP · 1434+ اختبار وحدة · 50+ لغة · إصدار مستقر v3.11.x · مُقيَّد بالـ semver · MIT · إثبات بناء npm (SLSA L2).**
57
+ **46 أداة · 19 موجِّه MCP · 1439+ اختبار وحدة · 50+ لغة · إصدار مستقر v3.11.x · مُقيَّد بالـ semver · MIT · إثبات بناء npm (SLSA L2).**
58
58
 
59
59
  </div>
60
60
 
package/README.es.md CHANGED
@@ -48,7 +48,7 @@ Tu bóveda de Obsidian se convierte en **memoria a largo plazo persistente y con
48
48
  > 3. **Cero llamadas a la nube durante el servicio.** Modelos en caché local (una descarga única desde HuggingFace). El contenido de tu bóveda nunca sale de tu máquina. Seguro para entornos aislados por defecto.
49
49
  > 4. **Recuperación consciente de la frescura.** Cada resultado informa de la antigüedad de la nota; el reordenamiento por recencia opcional permite que un agente prefiera el conocimiento reciente y marque los hechos obsoletos para reverificación: la frontera consciente del olvido, construida sobre el `mtime` que tus archivos ya tienen.
50
50
 
51
- **46 herramientas · 19 prompts MCP · 1434+ pruebas unitarias · 50+ idiomas · v3.11.x estable · ligado a semver · MIT · procedencia de compilación en npm (SLSA L2).**
51
+ **46 herramientas · 19 prompts MCP · 1439+ pruebas unitarias · 50+ idiomas · v3.11.x estable · ligado a semver · MIT · procedencia de compilación en npm (SLSA L2).**
52
52
 
53
53
  ---
54
54
 
package/README.fr.md CHANGED
@@ -15,7 +15,7 @@
15
15
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
16
16
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
17
17
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
18
- [![tests](https://img.shields.io/badge/tests-1434%20passing-brightgreen.svg)](#️-confiance)
18
+ [![tests](https://img.shields.io/badge/tests-1439%20passing-brightgreen.svg)](#️-confiance)
19
19
  [![stable](https://img.shields.io/badge/v3.11.x-stable-brightgreen.svg)](./STABILITY.md)
20
20
  [![build provenance](https://img.shields.io/badge/build_provenance-SLSA_L2-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l2)
21
21
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -53,7 +53,7 @@ Votre coffre Obsidian devient une **mémoire à long terme persistante et interr
53
53
  > 3. **Zéro appel au cloud pendant le service.** Modèles mis en cache localement (téléchargement unique depuis HuggingFace). Le contenu de votre coffre ne quitte jamais votre machine. Sûr en environnement isolé par défaut.
54
54
  > 4. **Rappel conscient de la fraîcheur.** Chaque résultat indique l'âge de la note ; le reclassement par récence optionnel permet à un agent de préférer le savoir frais et de signaler les faits périmés à revérifier — la frontière consciente de l'oubli, bâtie sur le `mtime` que vos fichiers possèdent déjà.
55
55
 
56
- **46 outils · 19 prompts MCP · 1434+ tests unitaires · 50+ langues · v3.11.x stable · lié au semver · MIT · provenance de build npm (SLSA L2).**
56
+ **46 outils · 19 prompts MCP · 1439+ tests unitaires · 50+ langues · v3.11.x stable · lié au semver · MIT · provenance de build npm (SLSA L2).**
57
57
 
58
58
  ---
59
59
 
@@ -81,7 +81,7 @@ Votre coffre Obsidian devient une **mémoire à long terme persistante et interr
81
81
  | **GraphRAG-light** (détection de communautés de wikilinks par modularité de Louvain) | ✅ **uniquement ici** | ❌ | ❌ |
82
82
  | **Exécution autonome de requêtes `.base`** (fonctionne sans Obsidian ouvert) | ✅ **uniquement ici** | ❌ | ❌ délègue à Obsidian |
83
83
  | **Récupération HyDE** (Gao et al. 2023) + décomposition en sous-questions | ✅ **uniquement ici** | ❌ | ❌ |
84
- | **1434 tests unitaires · 9 portes CI requises + 5 indicatives par PR** | ✅ | s.o. | rare |
84
+ | **1439 tests unitaires · 9 portes CI requises + 5 indicatives par PR** | ✅ | s.o. | rare |
85
85
  | **Provenance de build signée** (npm + Sigstore, SLSA Build L2) | ✅ | s.o. | ❌ |
86
86
  | **Surface publique liée au semver** ([STABILITY.md](./STABILITY.md)) | ✅ | s.o. | ❌ |
87
87
  | Autonome (aucun plugin Obsidian requis) | ✅ | ❌ requiert Obsidian | variable |
@@ -320,7 +320,7 @@ Canal : `npm install @oomkapwn/enquire-mcp` → dernière version stable (`@late
320
320
  ```bash
321
321
  git clone https://github.com/oomkapwn/enquire-mcp.git
322
322
  cd enquire-mcp && npm install
323
- npm test # suite complète (1434 tests, ~12 s)
323
+ npm test # suite complète (1439 tests, ~12 s)
324
324
  npm run lint # zéro avertissement
325
325
  npm run build # tsc → dist/
326
326
  ```
package/README.hi.md CHANGED
@@ -48,7 +48,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
48
48
  > 3. **serve के दौरान शून्य क्लाउड कॉल।** मॉडल स्थानीय रूप से कैश्ड (HuggingFace से एक-बार डाउनलोड)। आपके vault की सामग्री कभी आपकी मशीन नहीं छोड़ती। डिफ़ॉल्ट रूप से एयर-गैप-सुरक्षित।
49
49
  > 4. **ताज़गी-सजग recall।** हर परिणाम बताता है कि नोट कितना पुराना है; वैकल्पिक recency re-ranking एजेंट को ताज़ा ज्ञान को प्राथमिकता देने और बासी तथ्यों को पुनः-सत्यापन हेतु चिह्नित करने देता है — भूलने-के-प्रति-सजग सीमांत, जो आपकी फ़ाइलों में पहले से मौजूद `mtime` पर बना है।
50
50
 
51
- **46 टूल · 19 MCP प्रॉम्प्ट · 1434+ यूनिट टेस्ट · 50+ भाषाएँ · v3.11.x स्थिर · semver-बाध्य · MIT · npm बिल्ड प्रोवेनेंस (SLSA L2)।**
51
+ **46 टूल · 19 MCP प्रॉम्प्ट · 1439+ यूनिट टेस्ट · 50+ भाषाएँ · v3.11.x स्थिर · semver-बाध्य · MIT · npm बिल्ड प्रोवेनेंस (SLSA L2)।**
52
52
 
53
53
  ---
54
54
 
package/README.ja.md CHANGED
@@ -48,7 +48,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
48
48
  > 3. **serve 中はクラウド呼び出しがゼロ。** モデルはローカルにキャッシュ(HuggingFace から一度だけダウンロード)。あなたのボールトの内容はマシンから決して出ていきません。デフォルトでエアギャップ安全。
49
49
  > 4. **鮮度を意識した呼び戻し。** すべてのヒットが、そのノートがどれくらい古いかを報告します。オプトインの鮮度リランキングにより、エージェントは新しい知識を優先し、古くなった事実を再検証対象としてフラグ付けできます——これは忘却を意識したフロンティアであり、あなたのファイルがもともと持っている `mtime` の上に構築されています。
50
50
 
51
- **46 ツール · 19 MCP プロンプト · 1434+ ユニットテスト · 50+ 言語 · v3.11.x 安定版 · semver 準拠 · MIT · npm ビルドプロベナンス(SLSA L2)。**
51
+ **46 ツール · 19 MCP プロンプト · 1439+ ユニットテスト · 50+ 言語 · v3.11.x 安定版 · semver 準拠 · MIT · npm ビルドプロベナンス(SLSA L2)。**
52
52
 
53
53
  ---
54
54
 
@@ -76,7 +76,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
76
76
  | **GraphRAG-light**(Louvain モジュラリティによる wikilink コミュニティ検出) | ✅ **ここだけ** | ❌ | ❌ |
77
77
  | **スタンドアロンの `.base` クエリ実行**(Obsidian を起動せずに動作) | ✅ **ここだけ** | ❌ | ❌ Obsidian に委譲 |
78
78
  | **HyDE 検索**(Gao et al 2023)+ サブクエスチョン分解 | ✅ **ここだけ** | ❌ | ❌ |
79
- | **1434 ユニットテスト · PR ごとに 9 個の必須 + 5 個のアドバイザリ CI ゲート** | ✅ | 該当なし | まれ |
79
+ | **1439 ユニットテスト · PR ごとに 9 個の必須 + 5 個のアドバイザリ CI ゲート** | ✅ | 該当なし | まれ |
80
80
  | **署名付きビルドプロベナンス**(npm + Sigstore、SLSA Build L2) | ✅ | 該当なし | ❌ |
81
81
  | **semver 準拠の公開サーフェス**([STABILITY.md](./STABILITY.md)) | ✅ | 該当なし | ❌ |
82
82
  | スタンドアロン(Obsidian プラグイン不要) | ✅ | ❌ Obsidian が必要 | まちまち |
@@ -315,7 +315,7 @@ graph LR
315
315
  ```bash
316
316
  git clone https://github.com/oomkapwn/enquire-mcp.git
317
317
  cd enquire-mcp && npm install
318
- npm test # フルスイート(1434 テスト、約 12 秒)
318
+ npm test # フルスイート(1439 テスト、約 12 秒)
319
319
  npm run lint # 警告ゼロ
320
320
  npm run build # tsc → dist/
321
321
  ```
package/README.md CHANGED
@@ -12,10 +12,12 @@
12
12
 
13
13
  **Stop re-explaining context to Claude, Cursor, ChatGPT, Codex, OpenClaw every session. Your Obsidian notes become shared, searchable memory across every MCP-compatible agent — your knowledge, every model, forever yours.**
14
14
 
15
+ *Measured: the BGE cross-encoder reranker adds **+15.5 NDCG@10 / +24.7 MRR** over plain hybrid on a [reproducible 60-query ablation](./docs/benchmarks.md) — the full modern IR stack, recalling the markdown **you** wrote (cited, editable), never a cloud paraphrase.*
16
+
15
17
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
16
18
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
17
19
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
18
- [![tests](https://img.shields.io/badge/tests-1434%20passing-brightgreen.svg)](#️-trust)
20
+ [![tests](https://img.shields.io/badge/tests-1439%20passing-brightgreen.svg)](#️-trust)
19
21
  [![stable](https://img.shields.io/badge/v3.11.x-stable-brightgreen.svg)](./STABILITY.md)
20
22
  [![build provenance](https://img.shields.io/badge/build_provenance-SLSA_L2-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l2)
21
23
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -48,10 +50,10 @@ Your Obsidian vault becomes **persistent, queryable long-term memory** for any M
48
50
  > **What makes enquire-mcp different**:
49
51
  > 1. **Vendor-neutral.** Your memory lives in `.md` files. Switch from Claude to Cursor — your memory comes with you.
50
52
  > 2. **Best-in-class retrieval.** Hybrid BM25 + multilingual embeddings + BGE cross-encoder reranker fused via RRF, scaled with HNSW + int8 quantization. The same IR stack a search startup would build — open-sourced, in one binary.
51
- > 3. **Zero cloud calls during serve.** Models cached locally (one-time download from HuggingFace). Your vault content never leaves your machine. Air-gap-safe by default.
53
+ > 3. **Zero cloud calls during serve.** The embedding model runs **on your machine** and indexes the markdown **you** wrote — that's why it's a one-time local download (~110 MB), not a cloud API key. Grounded + private isn't free, and we don't pretend it is: your vault content never leaves your machine, air-gap-safe by default ([enforced](./SECURITY.md), not aspirational).
52
54
  > 4. **Freshness-aware recall.** Every hit reports how old the note is; opt-in recency re-ranking lets an agent prefer fresh knowledge and flag stale facts for re-verification — the forgetting-aware frontier, built on the `mtime` your files already have.
53
55
 
54
- **46 tools · 19 MCP prompts · 1434 unit tests · 50+ languages · v3.11.x stable · semver-bound · MIT · npm build provenance (SLSA L2).**
56
+ **46 tools · 19 MCP prompts · 1439 unit tests · 50+ languages · v3.11.x stable · semver-bound · MIT · npm build provenance (SLSA L2).**
55
57
 
56
58
  ---
57
59
 
@@ -79,7 +81,7 @@ Your Obsidian vault becomes **persistent, queryable long-term memory** for any M
79
81
  | **GraphRAG-light** (wikilink community detection via Louvain modularity) | ✅ **only here** | ❌ | ❌ |
80
82
  | **Standalone `.base` query execution** (works without Obsidian running) | ✅ **only here** | ❌ | ❌ delegates to Obsidian |
81
83
  | **HyDE retrieval** (Gao et al 2023) + sub-question decomposition | ✅ **only here** | ❌ | ❌ |
82
- | **1434 unit tests · 9 required + 5 advisory CI gates per PR** | ✅ | n/a | rare |
84
+ | **1439 unit tests · 9 required + 5 advisory CI gates per PR** | ✅ | n/a | rare |
83
85
  | **Signed build provenance** (npm + Sigstore, SLSA Build L2) | ✅ | n/a | ❌ |
84
86
  | **Semver-bound public surface** ([STABILITY.md](./STABILITY.md)) | ✅ | n/a | ❌ |
85
87
  | Standalone (no Obsidian plugin needed) | ✅ | ❌ requires Obsidian | varies |
@@ -318,7 +320,7 @@ Channel: `npm install @oomkapwn/enquire-mcp` → latest stable (`@latest` = v3.1
318
320
  ```bash
319
321
  git clone https://github.com/oomkapwn/enquire-mcp.git
320
322
  cd enquire-mcp && npm install
321
- npm test # full suite (1434 tests, ~12s)
323
+ npm test # full suite (1439 tests, ~12s)
322
324
  npm run lint # zero warnings
323
325
  npm run build # tsc → dist/
324
326
  ```
package/README.pt.md CHANGED
@@ -15,7 +15,7 @@
15
15
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
16
16
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
17
17
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
18
- [![tests](https://img.shields.io/badge/tests-1434%20passing-brightgreen.svg)](#️-confiança)
18
+ [![tests](https://img.shields.io/badge/tests-1439%20passing-brightgreen.svg)](#️-confiança)
19
19
  [![stable](https://img.shields.io/badge/v3.11.x-stable-brightgreen.svg)](./STABILITY.md)
20
20
  [![build provenance](https://img.shields.io/badge/build_provenance-SLSA_L2-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l2)
21
21
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -53,7 +53,7 @@ Seu vault do Obsidian se torna **memória de longo prazo persistente e consultá
53
53
  > 3. **Zero chamadas à nuvem durante o serve.** Modelos em cache local (download único do HuggingFace). O conteúdo do seu vault nunca sai da sua máquina. Seguro para ambientes isolados (air-gap) por padrão.
54
54
  > 4. **Recuperação consciente da atualidade.** Cada resultado informa quão antiga é a nota; o reranqueamento por recência opcional permite que um agente prefira conhecimento recente e sinalize fatos desatualizados para reverificação — a fronteira consciente do esquecimento, construída sobre o `mtime` que seus arquivos já têm.
55
55
 
56
- **46 ferramentas · 19 prompts MCP · 1434+ testes unitários · 50+ idiomas · v3.11.x estável · vinculado a semver · MIT · proveniência de build no npm (SLSA L2).**
56
+ **46 ferramentas · 19 prompts MCP · 1439+ testes unitários · 50+ idiomas · v3.11.x estável · vinculado a semver · MIT · proveniência de build no npm (SLSA L2).**
57
57
 
58
58
  ---
59
59
 
@@ -81,7 +81,7 @@ Seu vault do Obsidian se torna **memória de longo prazo persistente e consultá
81
81
  | **GraphRAG-light** (detecção de comunidades de wikilinks via modularidade de Louvain) | ✅ **só aqui** | ❌ | ❌ |
82
82
  | **Execução autônoma de consultas `.base`** (funciona sem o Obsidian em execução) | ✅ **só aqui** | ❌ | ❌ delega ao Obsidian |
83
83
  | **Recuperação HyDE** (Gao et al. 2023) + decomposição em sub-perguntas | ✅ **só aqui** | ❌ | ❌ |
84
- | **1434 testes unitários · 9 gates obrigatórios + 5 consultivos de CI por PR** | ✅ | n/d | raro |
84
+ | **1439 testes unitários · 9 gates obrigatórios + 5 consultivos de CI por PR** | ✅ | n/d | raro |
85
85
  | **Proveniência de build assinada** (npm + Sigstore, SLSA Build L2) | ✅ | n/d | ❌ |
86
86
  | **Superfície pública vinculada a semver** ([STABILITY.md](./STABILITY.md)) | ✅ | n/d | ❌ |
87
87
  | Autônomo (sem necessidade de plugin do Obsidian) | ✅ | ❌ exige Obsidian | varia |
@@ -320,7 +320,7 @@ Canal: `npm install @oomkapwn/enquire-mcp` → último estável (`@latest` = v3.
320
320
  ```bash
321
321
  git clone https://github.com/oomkapwn/enquire-mcp.git
322
322
  cd enquire-mcp && npm install
323
- npm test # suíte completa (1434 testes, ~12s)
323
+ npm test # suíte completa (1439 testes, ~12s)
324
324
  npm run lint # zero avisos
325
325
  npm run build # tsc → dist/
326
326
  ```
package/README.ru.md CHANGED
@@ -15,7 +15,7 @@
15
15
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
16
16
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
17
17
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
18
- [![tests](https://img.shields.io/badge/tests-1434%20passing-brightgreen.svg)](#️-доверие)
18
+ [![tests](https://img.shields.io/badge/tests-1439%20passing-brightgreen.svg)](#️-доверие)
19
19
  [![stable](https://img.shields.io/badge/v3.11.x-stable-brightgreen.svg)](./STABILITY.md)
20
20
  [![build provenance](https://img.shields.io/badge/build_provenance-SLSA_L2-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l2)
21
21
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -53,7 +53,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
53
53
  > 3. **Ноль обращений в облако в режиме serve.** Модели кешируются локально (однократная загрузка с HuggingFace). Содержимое вашего хранилища никогда не покидает вашу машину. По умолчанию безопасно для изолированных сред.
54
54
  > 4. **Поиск с учётом свежести.** Каждый результат сообщает, насколько стара заметка; опциональное переранжирование по давности позволяет агенту предпочитать свежие знания и помечать устаревшие факты для повторной проверки — рубеж «осознания забывания», построенный на `mtime`, который ваши файлы уже имеют.
55
55
 
56
- **46 инструментов · 19 MCP-промптов · 1434+ модульных тестов · 50+ языков · стабильная ветка v3.11.x · с гарантиями semver · MIT · подтверждённая сборка в npm (SLSA L2).**
56
+ **46 инструментов · 19 MCP-промптов · 1439+ модульных тестов · 50+ языков · стабильная ветка v3.11.x · с гарантиями semver · MIT · подтверждённая сборка в npm (SLSA L2).**
57
57
 
58
58
  ---
59
59
 
@@ -81,7 +81,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
81
81
  | **GraphRAG-light** (детекция сообществ по wikilink-графу через модулярность Лувена) | ✅ **только здесь** | ❌ | ❌ |
82
82
  | **Автономное выполнение `.base`-запросов** (работает без запущенного Obsidian) | ✅ **только здесь** | ❌ | ❌ делегирует Obsidian |
83
83
  | **HyDE-поиск** (Gao et al 2023) + декомпозиция на подвопросы | ✅ **только здесь** | ❌ | ❌ |
84
- | **1434 модульных тестов · 9 обязательных + 5 совещательных CI-гейтов на каждый PR** | ✅ | н/д | редко |
84
+ | **1439 модульных тестов · 9 обязательных + 5 совещательных CI-гейтов на каждый PR** | ✅ | н/д | редко |
85
85
  | **Подтверждённое происхождение сборки** (npm + Sigstore, SLSA Build L2) | ✅ | н/д | ❌ |
86
86
  | **Публичная поверхность с гарантиями semver** ([STABILITY.md](./STABILITY.md)) | ✅ | н/д | ❌ |
87
87
  | Автономность (плагин Obsidian не нужен) | ✅ | ❌ требует Obsidian | по-разному |
@@ -320,7 +320,7 @@ graph LR
320
320
  ```bash
321
321
  git clone https://github.com/oomkapwn/enquire-mcp.git
322
322
  cd enquire-mcp && npm install
323
- npm test # полный набор (1434 тестов, ~12с)
323
+ npm test # полный набор (1439 тестов, ~12с)
324
324
  npm run lint # ноль предупреждений
325
325
  npm run build # tsc → dist/
326
326
  ```
package/README.zh.md CHANGED
@@ -48,7 +48,7 @@ claude mcp add obsidian -- npx -y @oomkapwn/enquire-mcp serve --vault ~/Document
48
48
  > 3. **serve 期间零云端调用。** 模型本地缓存(一次性从 HuggingFace 下载)。你的仓库内容永不离开本机。默认即可离线/隔离运行。
49
49
  > 4. **时效感知召回。** 每条结果都报告笔记有多旧;可选的时效重排让智能体优先采用新知识,并把陈旧事实标记出来等待复核——这是"遗忘感知"前沿,建立在你的文件本就拥有的 `mtime` 之上。
50
50
 
51
- **46 个工具 · 19 个 MCP 提示词 · 1434+ 单元测试 · 50+ 语言 · v3.11.x 稳定版 · 语义化版本约束 · MIT · npm 构建溯源(SLSA L2)。**
51
+ **46 个工具 · 19 个 MCP 提示词 · 1439+ 单元测试 · 50+ 语言 · v3.11.x 稳定版 · 语义化版本约束 · MIT · npm 构建溯源(SLSA L2)。**
52
52
 
53
53
  ---
54
54
 
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * + `McpServer({version})`) and `src/tool-registry.ts` (used in the
8
8
  * `vault-info` resource payload).
9
9
  */
10
- export declare const VERSION = "3.11.1";
10
+ export declare const VERSION = "3.11.2";
11
11
  export { main } from "./cli.js";
12
12
  export { buildEmbedText, buildMcpServer, formatReadyBanner, prepareServerDeps, type ServeOptions, type ServerDeps, startServer } from "./server.js";
13
13
  export { parsePositiveInt, parseQuantizationMode } from "./tool-registry.js";
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ import { main } from "./cli.js";
40
40
  * + `McpServer({version})`) and `src/tool-registry.ts` (used in the
41
41
  * `vault-info` resource payload).
42
42
  */
43
- export const VERSION = "3.11.1";
43
+ export const VERSION = "3.11.2";
44
44
  // Re-exports — preserve the v3.5.x public surface so http-transport.ts and
45
45
  // tests don't need to know about the new module layout. The set below
46
46
  // exactly matches the v3.5.x `export` declarations: `main`,
@@ -44,7 +44,7 @@ The four axes the external audit (#3, 2026-05) called out as decisive — **REST
44
44
  | Zero outbound network calls in serve mode | **Yes** (default) | Local-only (REST)| Local-only (REST)| Yes | Yes |
45
45
  | Signed build provenance on releases (SLSA L2) | **Yes** | No | No | No | No |
46
46
  | Forgetting-aware freshness (`age_days` / recency re-rank) | Yes (v3.10) | No | No | No | No |
47
- | Test count (public) | **1434** | (varies) | (varies) | (varies) | (varies) |
47
+ | Test count (public) | **1439** | (varies) | (varies) | (varies) | (varies) |
48
48
  | Tool count | 46 | ~25 | ~8 | ~10 | 3–5 |
49
49
  | MCP prompt count | 19 | 0 | 0 | 0 | 0 |
50
50
  | License | MIT | Apache-2.0 | MIT | MIT | (varies) |
@@ -0,0 +1,127 @@
1
+ # Evaluation plan — enquire-mcp
2
+
3
+ **Status:** pre-registered methodology · **no scores in this document by design.**
4
+ **Issued:** 2026-06-29 · **Scope:** how we will measure enquire-mcp's quality, what
5
+ counts as a pass/fail, and the bar a number must clear before it appears in the
6
+ README, `docs/benchmarks.md`, or any public claim.
7
+
8
+ This is a *plan*, committed **before** the headline runs, so the method can be
9
+ reviewed without front-running a result. It exists because the project's core
10
+ brand is **"every claim an auditor can verify"** — and a pre-registered protocol
11
+ is how you make a benchmark falsifiable instead of a marketing artifact.
12
+
13
+ ---
14
+
15
+ ## 0. Principles (the bar every number must clear)
16
+
17
+ 1. **Measured — never asserted or estimated.** A figure is published only after it
18
+ is produced by a committed, reproducible harness. No placeholders, no "~", no
19
+ borrowed competitor numbers.
20
+ 2. **Reproducible.** Every reported number ships with the exact command, the
21
+ harness, the dataset pointer (or a synthetic generator), and a determinism
22
+ contract (fixed bodies, fixed mtimes, pinned model alias).
23
+ 3. **Reviewed.** Headline numbers (LongMemEval, context-efficiency, any
24
+ cross-tool comparison) go through a maintainer **reference-hardware run +
25
+ sign-off** before they leave `benchmarks.md` for the README hero.
26
+ 4. **Scoped to what we are.** enquire-mcp is a **retriever / memory layer**, not an
27
+ answer-generating assistant. We report **retrieval quality**, not end-to-end QA
28
+ accuracy — reporting a QA number for a retriever would be an overclaim (the
29
+ answer is the calling agent's job).
30
+ 5. **Zero result = FAIL, not "n/a".** A query that returns nothing for a question
31
+ that has a ground-truth answer scores 0 and is counted, never silently dropped.
32
+ 6. **Disclose weaknesses.** Per-class breakdowns report where recall is *weaker*
33
+ (e.g. OCR'd PDF vs native markdown), because honest failure disclosure raises
34
+ credibility — it does not lower it.
35
+
36
+ ---
37
+
38
+ ## 1. Dimensions we measure
39
+
40
+ | dimension | what it answers | harness | metric |
41
+ |---|---|---|---|
42
+ | **Retrieval quality** | does the right note rank highly? | `scripts/run-benchmarks.mjs` (`bench:retrieval`) | MRR · NDCG@10 · Recall@10 |
43
+ | **Long-term memory** | does recall hold over long, multi-session histories? | `scripts/bench-longmemeval.mjs` (`bench:longmemeval`) | recall@k / MRR / NDCG@k of the answer-bearing session(s) |
44
+ | **Context efficiency** | how much less context vs read-every-hit? | `scripts/bench-context.mjs` (`bench:context`) | token ratio (baseline-read ÷ pack) |
45
+ | **Freshness awareness** | is a stale fact flagged as stale? | `src/staleness.ts` + `age_days`/`stale` on every hit | stale-flag precision/recall (planned) |
46
+ | **Reranker contribution** | does the cross-encoder help? | the ablation in `run-benchmarks.mjs` | Δ NDCG@10 / Δ MRR (fusion → fusion+rerank) |
47
+
48
+ The **single-source-of-truth metric implementations** live in
49
+ [`src/eval.ts`](https://github.com/oomkapwn/enquire-mcp/blob/main/src/eval.ts)
50
+ (`recallAtK` / `ndcgAtK` / `reciprocalRank`, dedup-safe), used identically by
51
+ every harness and the `enquire-mcp eval` CLI subcommand — so a number cannot drift
52
+ between the bench and the shipped tool.
53
+
54
+ ---
55
+
56
+ ## 2. Datasets & conditions
57
+
58
+ - **Synthetic vault** (committed generators) — deterministic, for the ablation +
59
+ the context-efficiency *method* demonstration. Numbers from it are illustrative,
60
+ never the headline (see §4).
61
+ - **LongMemEval** ([arXiv:2410.10813](https://arxiv.org/abs/2410.10813)) — the
62
+ standard long-term-memory benchmark; `longmemeval_s / _m / _oracle`. Not
63
+ committed (size + licensing); downloaded per the `benchmarks.md` instructions.
64
+ Conditions reported separately by `question_type` (single-session, multi-session,
65
+ temporal-reasoning, knowledge-update, abstention).
66
+ - **LoCoMo** (planned) — a second long-conversation memory set, to avoid
67
+ over-fitting the protocol to one benchmark's quirks.
68
+ - **Representative real vault** — for the context-efficiency headline only, run on
69
+ a real (private) vault on reference hardware; only the *ratio* is reported, never
70
+ vault content.
71
+
72
+ ---
73
+
74
+ ## 3. Grading protocol
75
+
76
+ - **Retrieval metrics** are computed directly from the ground-truth relevant set
77
+ (no LLM judge needed) — deterministic and exactly reproducible.
78
+ - **LLM-as-judge** (only where a judgment is unavoidable, e.g. answer-bearing-span
79
+ relevance that isn't in the labels): use a fixed judge model + temperature,
80
+ **swap the position** of the two items being compared and average both orders to
81
+ cancel position bias, and report inter-run agreement. A judgment that flips on
82
+ the swap is recorded as "uncertain", not silently resolved.
83
+ - **Token efficiency** reports **two ratios** — capped-pack vs (a) full-body reads
84
+ of the same hits and (b) a naive whole-folder read baseline — so the number is
85
+ bounded, not a single best-case scenario.
86
+ - **Abstention** (`*_abs`) questions are scored separately: the correct behavior is
87
+ *no confident hit*, so they are not folded into recall.
88
+
89
+ ---
90
+
91
+ ## 4. Publication gate (what reaches the README)
92
+
93
+ A number moves from "the harness can produce it" to "published" only when **all**
94
+ hold:
95
+
96
+ 1. produced by the committed harness with the determinism contract met;
97
+ 2. run on **reference hardware** against a **representative** dataset (not the
98
+ synthetic vault, for any headline);
99
+ 3. method **reviewed** + the figure **signed off** by the maintainer;
100
+ 4. pinned by a structural guard where a count/claim is involved (the
101
+ `docs-consistency` / OIA invariants), so it can't silently drift later.
102
+
103
+ Until then, the harness + its pure-function tests ship, `benchmarks.md` documents
104
+ the **method**, and the README does **not** assert the figure. Current
105
+ maintainer-gated headlines awaiting a reference run: **LongMemEval retrieval** and
106
+ **context-efficiency ("Nx less context")**.
107
+
108
+ ---
109
+
110
+ ## 5. Deliberately out of scope
111
+
112
+ - **End-to-end QA accuracy** — that measures the *generating agent*, not the memory
113
+ layer. We report retrieval, and let the agent's own evals own the answer.
114
+ - **Borrowed metrics** — no competitor's figure is ever restated as ours.
115
+ - **Single best-case scenarios** as the headline — every efficiency claim is
116
+ reported as a bounded ratio with the baseline named.
117
+
118
+ ---
119
+
120
+ ## Related
121
+
122
+ - [`docs/benchmarks.md`](./benchmarks.md) — the live results + full methodology +
123
+ reproducibility contract.
124
+ - [`src/eval.ts`](https://github.com/oomkapwn/enquire-mcp/blob/main/src/eval.ts) —
125
+ the metric implementations shared by every harness.
126
+ - `scripts/run-benchmarks.mjs` · `scripts/bench-longmemeval.mjs` ·
127
+ `scripts/bench-context.mjs` — the harnesses.
@@ -486,6 +486,35 @@ centerpiece, so it goes through the same "measured, reproducible, reviewed"
486
486
  bar as every other number in this document — never a placeholder or an
487
487
  estimate).
488
488
 
489
+ ## Context efficiency (token cost)
490
+
491
+ Code-intelligence memory tools advertise a flagship "Nx fewer tokens" figure —
492
+ the context an agent saves by querying a memory layer instead of reading source
493
+ files one by one. The same lever applies to a **notes** memory: `obsidian_context_pack`
494
+ returns a single budget-capped bundle (`budget_tokens × 4` chars, default 4000)
495
+ instead of the agent's naive *search → `read_note` every top hit in full* loop.
496
+
497
+ **What we measure.** Per question, two paths over the **same** hybrid retrieval:
498
+ (a) the `context_pack` bundle's token count, vs (b) the summed full bodies of the
499
+ top-K hits the agent would otherwise open. Token estimate is `chars / 4` (a rough,
500
+ deterministic heuristic — the same on both sides, so the *ratio* is robust to it).
501
+
502
+ **Harness.** [`scripts/bench-context.mjs`](https://github.com/oomkapwn/enquire-mcp/blob/main/scripts/bench-context.mjs)
503
+ (shipped v3.11.2) builds a deterministic synthetic vault, indexes FTS5 +
504
+ embeddings, and reports `baseline_tokens` / `pack_tokens` / savings ratio per
505
+ question + the mean (pure helpers covered by `tests/bench-context.test.ts` with
506
+ NEGATIVE controls so an inflated ratio can't ship).
507
+
508
+ ```bash
509
+ npm run bench:context
510
+ ```
511
+
512
+ **Status:** the harness ships in v3.11.2; **no headline "Nx less context" figure
513
+ is published** from a synthetic-vault run. A README claim requires a run on a
514
+ **representative vault** + maintainer sign-off — the same "measured, reproducible,
515
+ reviewed" bar as the LongMemEval score above. The synthetic-vault number the
516
+ script prints is an illustration of the *method*, not a claim about real vaults.
517
+
489
518
  ## Future work
490
519
 
491
520
  - Reproduce on **public BEIR / TREC subsets** so numbers can be compared
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@oomkapwn/enquire-mcp",
4
- "version": "3.11.1",
4
+ "version": "3.11.2",
5
5
  "mcpName": "io.github.oomkapwn/enquire-mcp",
6
- "description": "MCP server giving AI agents (Claude Code, Claude Desktop, Cursor, ChatGPT, Codex, OpenClaw) persistent long-term memory backed by your local Obsidian markdown vault. Hybrid retrieval (BM25 + ML embeddings + BGE reranker, RRF-fused), HNSW + int8 quantization, agentic RAG (HyDE + sub-question decomposition), GraphRAG-light (Louvain), standalone Obsidian Bases, PDFs + Tesseract OCR. Vendor-neutral memory layer for any MCP-compatible agent. 46 tools, 19 MCP prompts, 1434 tests, signed npm build provenance (SLSA L2), semver-bound, MIT, zero cloud calls during serve.",
6
+ "description": "MCP server giving AI agents (Claude Code, Claude Desktop, Cursor, ChatGPT, Codex, OpenClaw) persistent long-term memory backed by your local Obsidian markdown vault. Hybrid retrieval (BM25 + ML embeddings + BGE reranker, RRF-fused), HNSW + int8 quantization, agentic RAG (HyDE + sub-question decomposition), GraphRAG-light (Louvain), standalone Obsidian Bases, PDFs + Tesseract OCR. Vendor-neutral memory layer for any MCP-compatible agent. 46 tools, 19 MCP prompts, 1439 tests, signed npm build provenance (SLSA L2), semver-bound, MIT, zero cloud calls during serve.",
7
7
  "type": "module",
8
8
  "bin": {
9
9
  "enquire-mcp": "dist/index.js"
@@ -51,6 +51,7 @@
51
51
  "docs/QUICKSTART.md",
52
52
  "docs/COMPARISON.md",
53
53
  "docs/benchmarks.md",
54
+ "docs/EVALUATION_PLAN.md",
54
55
  "docs/http-transport.md",
55
56
  "examples",
56
57
  "assets/social-preview.png",
@@ -91,6 +92,7 @@
91
92
  "bench:retrieval": "npm run build && node scripts/run-benchmarks.mjs",
92
93
  "bench:peek-cache": "npm run build && node scripts/bench-peek-cache.mjs",
93
94
  "bench:longmemeval": "npm run build && node scripts/bench-longmemeval.mjs",
95
+ "bench:context": "npm run build && node scripts/bench-context.mjs",
94
96
  "docs:api": "typedoc",
95
97
  "check:audit": "node scripts/check-audit.mjs",
96
98
  "prepare": "rm -rf dist && tsc && chmod +x dist/index.js && (husky 2>/dev/null || true)",
@@ -121,6 +123,12 @@
121
123
  "chatgpt",
122
124
  "openclaw",
123
125
  "codex",
126
+ "windsurf",
127
+ "zed",
128
+ "aider",
129
+ "gemini-cli",
130
+ "opencode",
131
+ "kilocode",
124
132
  "ai-agent",
125
133
  "ai-agents",
126
134
  "ai-search",