@oomkapwn/enquire-mcp 3.9.0-rc.36 → 3.9.0-rc.37

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,38 @@
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.9.0-rc.37] — 2026-06-01
6
+
7
+ > **TL;DR:** **Docs/process-drift batch — the deferred (no-behavioral-risk) half of the rc.36 comprehensive audit — plus the structural gate that closes the gate-GAP the headline finding exposed.** The process/contradiction sub-agent found **F1** (MEDIUM): `ROADMAP.md` carried a stale "Process maturity — **1020 tests**" claim (plus a `1002`/`44 tools` stat-pill in a planning bullet) that **NO gate caught** — ROADMAP was absent from both `scope-completeness-audit.mjs` `AUDIT_FILES` and the `docs-consistency` surfaces, and a `[x]` checkbox even *claimed* ROADMAP had already been added to `AUDIT_FILES` (it hadn't — only `AGENTS.md` was). Closed the number AND the gate-gap: ROADMAP is now in `AUDIT_FILES` + the `test-count`/`ci-gate-count` defense scopes + a new `docs-consistency` "ROADMAP test-count" invariant. Plus **F3** (`AGENTS.md` referenced a phantom `src/search.ts` ×2 — the file is `src/rrf.ts` / `src/tools/search.ts`), **F4** (`COMPARISON` "7 stack configs" → "8: 6 full-60-query + 2 HyDE-subset"), **F2** (`lint` didn't enforce the documented "0 warnings / no `any`" claim — `noExplicitAny:"warn"` + plain `biome check` → set to `"error"`, verified zero stray `any`). Documents the meta-audit's durable lesson as a CLAUDE.md anti-pattern. **1038 → 1039 tests.**
8
+
9
+ **Patch — comprehensive-audit docs/process half + apparatus gate-gap closure.**
10
+
11
+ ### Fixed (verified-real)
12
+
13
+ - **F1 — `ROADMAP.md` stale test count, caught by no gate** (MEDIUM; the headline finding). Line 21 said "1020 tests" (drifted from canonical 1026→1038); a Tier-2 planning bullet embedded a stale "44 tools / 1002 tests" stat-pill (describing a social-card design rc.29 abandoned). Root cause — a **gate gap**: ROADMAP was in neither `scope-completeness-audit.mjs#AUDIT_FILES` nor any `docs-consistency` surface, and OIA Check 7's `DOCS_FILES_TO_SCAN` omits it. Worse, a `[x]` checkbox claimed "add `ROADMAP.md`/`AGENTS.md` to `AUDIT_FILES`" was DONE — but only `AGENTS` had been added (a false-done — the exact scope-too-narrow recursion the project documents). **Fix:** corrected line 21 → canonical; dropped the stat-pill counts (count-agnostic, per rc.29); added `ROADMAP.md` to `AUDIT_FILES` + the `test-count` and `ci-gate-count` defense scopes; new `docs-consistency` invariant "ROADMAP.md test-count claim matches actual it() count" (3-4-digit pattern pins the maturity total while ignoring the "+15 tests"/"+7 tests" per-RC deltas); made the checkbox honest (AGENTS rc.13, ROADMAP rc.37; OpenSSF Scorecard genuinely deferred).
14
+ - **F3 — `AGENTS.md` phantom `src/search.ts`** (LOW; ×2). The architecture diagram + the "fix a retrieval bug" entrypoint both pointed at `src/search.ts`, which doesn't exist (the orchestration is `src/tools/search.ts`; RRF is `src/rrf.ts`). Corrected both.
15
+ - **F4 — `docs/COMPARISON.md` "7 stack configurations"** (LOW). The benchmarks table has 8 rows (6 on the full 60-query set + 2 HyDE-subset at n=25). Reworded to "8 stack configurations (6 … + 2 HyDE-subset)".
16
+ - **F2 — `lint` did not enforce the documented "0 warnings / no `any`" guarantee** (LOW; claimed-guarantee-vs-reality). CLAUDE.md quality-bar #2 says "biome 0 warnings/errors" and AGENTS says "No `any`", but `biome.json` had `noExplicitAny:"warn"` and the `lint` script was a plain `biome check` (exits 0 on warnings) — a stray `: any` would have passed CI silently. Set `noExplicitAny:"error"` (verified the tree has zero real `: any`, so the gate now matches the claim with no active violation).
17
+
18
+ ### Added — durable methodology capture
19
+
20
+ - **CLAUDE.md anti-pattern** documenting the meta-audit conclusion: the internal apparatus is ~85% drift/claim-driven and structurally blind to behavioral/threat classes, so every recent behavioral defect came from an external lens; the rule is to internalize each external lens as an inventory-based invariant (as rc.36 did with erasure + resource-bound + orphan-dist), and the named-but-uncovered dimensions (supply-chain `run:`-download pinning, paired-sink behavior parity, enforcement-verb→code-guard taxonomy) are listed so they're not silently skipped.
21
+
22
+ ### Method note
23
+
24
+ This is the no-behavioral-risk docs/process half of the rc.36 comprehensive audit (rc.36 shipped the behavioral fixes + the erasure/resource-bound invariants). The F1 closure follows the project's own "drift findings demand a full-surface sweep + structural defense, not a per-instance fix" rule — the stale number was the symptom; the gate gap (ROADMAP outside the audit set) was the cause. **Deferred (named, not silently skipped):** OpenSSF Scorecard + `dependency-review-action` workflows + an OIA scan for unpinned `run:` downloads (M-9 class), a paired-sink behavior-parity invariant (H-3 class), and a generalized enforcement-verb→code-guard taxonomy (beyond OIA 4d/4e).
25
+
26
+ ### Tests (1039)
27
+
28
+ `tests/docs-consistency.test.ts` +1 source `it()` (the ROADMAP test-count invariant). 1038 → 1039; claims synced (README ×4, package.json, llms.txt, AGENTS, COMPARISON, ROADMAP).
29
+
30
+ ### Files changed
31
+
32
+ - `ROADMAP.md` (count → 1039, stat-pill dropped, checkbox honesty), `scripts/scope-completeness-audit.mjs` (ROADMAP → AUDIT_FILES + test-count/ci-gate-count scopes), `tests/docs-consistency.test.ts` (+ROADMAP invariant), `AGENTS.md` (rrf.ts/tools/search.ts + count), `docs/COMPARISON.md` (8 configs + count), `biome.json` (`noExplicitAny: error`), `CLAUDE.md` (anti-pattern), test-count claims → 1039.
33
+ - version bump 3.9.0-rc.36 → 3.9.0-rc.37.
34
+
35
+ ---
36
+
5
37
  ## [3.9.0-rc.36] — 2026-06-01
6
38
 
7
39
  > **TL;DR:** **Comprehensive in-house audit (3 parallel sub-agents — sibling-class hunt · process/contradiction · meta-audit — each cross-checked against my own independent grep sweep) + the structural gates that close each finding's CLASS.** The meta-audit's core result: our home-grown apparatus (12 OIA checks + the invariant suite) is ~85% **drift/claim-driven** (does a CLAIM match reality?) and structurally blind to **behavioral/threat-model** failure — so every recent real bug (P-2 erasure, P-3 path-leak, R-5/AS#5 unbounded-graph, L-3 stale-build) was found by an EXTERNAL privacy/STRIDE lens we don't run ourselves. rc.36 fixes the open siblings of those classes **and internalizes the missing lenses as permanent CI gates.** **Fixed: F-1** (HIGH — `tsc` never purged `dist/`, so the pre-split `dist/tools.{js,d.ts}` (~309 KB stale) SHIPPED to npm, confirmed via `npm pack --dry-run`; the rc.35 fix closed the stale-*import*, this closes the stale-*artifact* ROOT CAUSE), **F-2** (MEDIUM privacy — `clear-cache` left the atomic-write `${cacheFile}.tmp` (full note bodies) on disk — P-2 sibling), **F-3** (LOW — `assertParentInsideVault` leaked an absolute server path to MCP clients — P-3 sibling), **F-4/F-5** (MEDIUM DoS — `findSimilar` + `getNoteNeighbors` did uncapped whole-vault `readNote` fan-out — R-5/AS#5 siblings). **3 new structural gates:** OIA **Check 12b** (orphan-`dist` file detector), `tests/erasure-invariant.test.ts` (writers ⊆ erasers), `tests/resource-bound-invariant.test.ts` (every whole-vault scanner must be CAP-or-EXEMPT classified — ends the AS#5→AS#6 recursion). **1026 → 1038 tests.**
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  [![CI](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
14
14
  [![npm](https://img.shields.io/npm/v/@oomkapwn/enquire-mcp.svg?label=npm&color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
15
15
  [![downloads](https://img.shields.io/npm/dm/@oomkapwn/enquire-mcp.svg?color=cb3837)](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
16
- [![tests](https://img.shields.io/badge/tests-1038%20passing-brightgreen.svg)](#trust)
16
+ [![tests](https://img.shields.io/badge/tests-1039%20passing-brightgreen.svg)](#trust)
17
17
  [![stable](https://img.shields.io/badge/v3.8.x-stable-brightgreen.svg)](./STABILITY.md)
18
18
  [![build provenance](https://img.shields.io/badge/build_provenance-SLSA_L2-blue.svg)](https://slsa.dev/spec/v1.0/levels#build-l2)
19
19
  [![MCP](https://img.shields.io/badge/MCP-1.29-8A2BE2.svg)](https://modelcontextprotocol.io/)
@@ -46,7 +46,7 @@ Your Obsidian vault becomes **persistent, queryable long-term memory** for any M
46
46
  > 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.
47
47
  > 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.
48
48
 
49
- **44 tools · 19 MCP prompts · 1038 unit tests · 50+ languages · v3.8.x stable · semver-bound · MIT · npm build provenance (SLSA L2).**
49
+ **44 tools · 19 MCP prompts · 1039 unit tests · 50+ languages · v3.8.x stable · semver-bound · MIT · npm build provenance (SLSA L2).**
50
50
 
51
51
  ---
52
52
 
@@ -184,7 +184,7 @@ Auto-generated **[API reference at oomkapwn.github.io/enquire-mcp](https://oomka
184
184
  | **GraphRAG-light** (wikilink community detection via Louvain modularity) | ✅ **only here** | ❌ | ❌ |
185
185
  | **Standalone `.base` query execution** (works without Obsidian running) | ✅ **only here** | ❌ | ❌ delegates to Obsidian |
186
186
  | **HyDE retrieval** (Gao et al 2023) + sub-question decomposition | ✅ **only here** | ❌ | ❌ |
187
- | **1038 unit tests · 9 required + 4 advisory CI gates per PR** | ✅ | n/a | rare |
187
+ | **1039 unit tests · 9 required + 4 advisory CI gates per PR** | ✅ | n/a | rare |
188
188
  | **Signed build provenance** (npm + Sigstore, SLSA Build L2) | ✅ | n/a | ❌ |
189
189
  | **Semver-bound public surface** ([STABILITY.md](./STABILITY.md)) | ✅ | n/a | ❌ |
190
190
  | Standalone (no Obsidian plugin needed) | ✅ | ❌ requires Obsidian | varies |
@@ -294,7 +294,7 @@ Channel: `npm install @oomkapwn/enquire-mcp` → latest stable (`@latest` = v3.8
294
294
  ```bash
295
295
  git clone https://github.com/oomkapwn/enquire-mcp.git
296
296
  cd enquire-mcp && npm install
297
- npm test # full suite (1038 tests, ~12s)
297
+ npm test # full suite (1039 tests, ~12s)
298
298
  npm run lint # zero warnings
299
299
  npm run build # tsc → dist/
300
300
  ```
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.9.0-rc.36";
10
+ export declare const VERSION = "3.9.0-rc.37";
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.9.0-rc.36";
43
+ export const VERSION = "3.9.0-rc.37";
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`,
@@ -43,7 +43,7 @@ The four axes the external audit (#3, 2026-05) called out as decisive — **REST
43
43
  | Read open editor state, active note, etc. | **No** | **Yes** | Limited | No | No |
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
- | Test count (public) | **1038** | (varies) | (varies) | (varies) | (varies) |
46
+ | Test count (public) | **1039** | (varies) | (varies) | (varies) | (varies) |
47
47
  | Tool count | 44 | ~25 | ~8 | ~10 | 3–5 |
48
48
  | MCP prompt count | 19 | 0 | 0 | 0 | 0 |
49
49
  | License | MIT | Apache-2.0 | MIT | MIT | (varies) |
@@ -233,7 +233,7 @@ This is a rough heuristic, not a verdict. The "when to pick X" sections above ar
233
233
 
234
234
  ## A note on benchmarks
235
235
 
236
- As of v3.6.0-rc.4, **enquire-mcp ships public, reproducible end-to-end retrieval benchmarks** at [`docs/benchmarks.md`](./benchmarks.md): a 60-query ablation across 7 stack configurations on a deterministic synthetic Obsidian vault. Reproducible with `npm run bench:retrieval` (4-decimal precision across runs). Headline: `rerank-bge` adds **+24.7 MRR / +15.5 NDCG@10** over plain hybrid. The other alternatives in this matrix do not (as of 2026-05-15) ship comparable public benchmarks. If retrieval quality is decisive, **run our `bench:retrieval` against your own vault**, then run any equivalent eval (or hand-eval) the alternatives provide.
236
+ As of v3.6.0-rc.4, **enquire-mcp ships public, reproducible end-to-end retrieval benchmarks** at [`docs/benchmarks.md`](./benchmarks.md): a 60-query ablation across 8 stack configurations (6 on the full 60-query set + 2 HyDE-subset rows at n=25) on a deterministic synthetic Obsidian vault. Reproducible with `npm run bench:retrieval` (4-decimal precision across runs). Headline: `rerank-bge` adds **+24.7 MRR / +15.5 NDCG@10** over plain hybrid. The other alternatives in this matrix do not (as of 2026-05-15) ship comparable public benchmarks. If retrieval quality is decisive, **run our `bench:retrieval` against your own vault**, then run any equivalent eval (or hand-eval) the alternatives provide.
237
237
 
238
238
  ---
239
239
 
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.9.0-rc.36",
4
+ "version": "3.9.0-rc.37",
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. 44 tools, 19 MCP prompts, 1038 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. 44 tools, 19 MCP prompts, 1039 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"