@oomkapwn/enquire-mcp 3.9.0-rc.21 → 3.9.0-rc.23
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 +60 -0
- package/README.md +4 -4
- package/STABILITY.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/docs/COMPARISON.md +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,66 @@
|
|
|
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.23] — 2026-05-29
|
|
6
|
+
|
|
7
|
+
> **TL;DR:** **Test-infra rigor (full-audit batch 3/3 — closes the audit).** The test auditor found the project's structural-enforcement apparatus was weaker than CLAUDE.md claimed: (HIGH) the META-invariant — the enforcer of the "every invariant has a NEGATIVE control" rule — passed if the token `NEGATIVE` appeared **anywhere, including a TODO comment** (reproduced), and its `*-invariant.test.ts` glob **silently excluded** real structural invariants (`no-internal-imports`, `lint`) and even itself; (MED) `security.test.ts` + `fts5.test.ts` had silent `return`-skips (the exact T1 anti-pattern rc.8 fixed) on security surfaces with no CI-GUARD; (LOW) `vault.ts` — the most security-critical module — had **no per-file coverage floor**, and `ocr.ts` floored only branches while its line coverage rotted to 44%. All closed. **1002 tests** (+5).
|
|
8
|
+
|
|
9
|
+
**Patch — test-infrastructure rigor (full-audit batch 3/3). Tests/scripts only; no `src/` runtime change.**
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **META-invariant comment-bypass (HIGH).** `checkInvariantHasNegativeCoverage` accepted the `NEGATIVE`/`negative-control` token **anywhere in the file** — so `// TODO: add a negative-control later` + a vacuous test satisfied the rule (reproduced by the auditor). Path (a) now requires the token inside an actual **test declaration** (`it`/`test`/`describe` title) — a real inline negative control; a bare comment no longer counts. Files whose coverage lives in siblings or that delegate to a tool use the explicit `META-INVARIANT-EXEMPT` marker (path b).
|
|
14
|
+
- **META-invariant glob-miss (HIGH).** The scan only walked `tests/*-invariant.test.ts`, silently excluding real structural invariants (`no-internal-imports.test.ts`, `lint.test.ts`) and the meta file itself — a dev could dodge the rule by filename. The scan now also covers a curated `EXTRA_STRUCTURAL_FILES` set (`docs-consistency`, `cli-parity`, `lint`, `no-internal-imports`, `meta-invariant-coverage`). `no-internal-imports` got a **real inline NEGATIVE control** (extracted a pure `restrictedImportViolations` matcher; a synthetic restricted-import is flagged, an allowed one isn't); `lint` + `k1-class` carry `META-INVARIANT-EXEMPT` markers (delegation-to-biome / sibling-coverage).
|
|
15
|
+
- **Silent-skip security surfaces (MED).** `security.test.ts` (symlink-escape privacy) + `fts5.test.ts` (FTS5 injection-escaping) `return`ed silently with zero assertions when their precondition (symlink support / better-sqlite3) was absent — green-passing a security surface. Added **CI-GUARD tripwires** (fail loud in CI if the precondition vanishes) + converted the 3 `security.test.ts` symlink skips to visible `ctx.skip()`. Also added a CI-GUARD to `e2e-handlers.test.ts` (the 401-no-bearer auth E2E). Same fix as rc.8's T1.
|
|
16
|
+
- **Per-file FLOORS gaps (LOW).** Added `src/vault.ts` (`branches: 75`; actual 78.03%) — the most security-critical module (path-traversal/symlink/privacy), previously the lone critical module with no per-file gate. Added an `ocr.ts` `lines: 40` floor (actual 44.44%) so the #16 offline-enforcement surface's line coverage can't silently rot under a branches-only floor.
|
|
17
|
+
|
|
18
|
+
### Tests (1002, +5)
|
|
19
|
+
|
|
20
|
+
+1 META-invariant self-test proving the comment/TODO-only bypass is now **rejected** (positive: the EXEMPT path still works); +1 `no-internal-imports` NEGATIVE control; +3 CI-GUARD tripwires (`security`, `fts5`, `e2e-handlers`).
|
|
21
|
+
|
|
22
|
+
### Files changed
|
|
23
|
+
|
|
24
|
+
- `tests/meta-invariant-coverage.test.ts` (tightened path-a check + broadened scan + bypass-rejected self-test), `tests/no-internal-imports.test.ts` (pure matcher + NEGATIVE control), `tests/lint.test.ts` + `tests/k1-class-invariant.test.ts` (EXEMPT markers), `tests/security.test.ts` (CI-GUARD + 3 `ctx.skip()`), `tests/fts5.test.ts` + `tests/e2e-handlers.test.ts` (CI-GUARDs), `scripts/check-per-file-coverage.mjs` (vault.ts + ocr.ts floors).
|
|
25
|
+
- version bump 3.9.0-rc.22 → 3.9.0-rc.23 (7 surfaces); test count 997 → 1002.
|
|
26
|
+
|
|
27
|
+
### Full-audit closure
|
|
28
|
+
|
|
29
|
+
This completes the 3-batch response to the multi-agent state-driven audit: **rc.21** (security — verified ReDoS), **rc.22** (docs drift + structural guards), **rc.23** (test-infra rigor). The automated 10-gate baseline was clean throughout; the `src/` runtime audited exceptionally clean (the only `src/` finding was the rc.21 ReDoS). Net: 4 HIGH + 1 security-MED + several LOW closed, each with a structural defense where one was missing.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## [3.9.0-rc.22] — 2026-05-29
|
|
34
|
+
|
|
35
|
+
> **TL;DR:** **Docs-drift + structural guards (full-audit batch 2/3).** The docs auditor found 2 claim-vs-reality drifts the gates didn't catch: (HIGH) `STABILITY.md` stated the `--reranker-model` default alias is `rerank-multilingual` — but the code default is `rerank-bge` (the **3rd instance** of the exact α-class drift fixed in rc.15 TSDoc + rc.16 CLI help, now in a *packaged semver-contract doc*); (MED) `ROADMAP.md` said "**8** state-driven OIA drift checks" when the canonical count is **10** (Check 9 rc.14, Check 10 rc.20). Both fixed AND each gets a structural guard in `tests/docs-consistency.test.ts` so the class can't recur. **997 tests** (+2 docs-consistency guards).
|
|
36
|
+
|
|
37
|
+
**Patch — docs-drift + structural defense (full-audit batch 2/3). Docs/tests only.**
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **`STABILITY.md` reranker default α-drift (HIGH).** The "Default models" bullet named `rerank-multilingual` as the `--reranker-model` default; `src/embeddings.ts` defines `DEFAULT_RERANKER_ALIAS = "rerank-bge"` (`rerank-multilingual` is a *valid* catalog alias but NOT the default). Same drift rc.15 fixed in `loadReranker`'s TSDoc and rc.16 in the CLI `--enable-reranker` help — this 3rd instance lived on the packaged semver-contract doc. → `rerank-bge`.
|
|
42
|
+
- **`ROADMAP.md` OIA-check undercount (MED).** "8 state-driven OIA drift checks" → **10** (the lone count straggler; AGENTS/CLAUDE/CHANGELOG were already correct).
|
|
43
|
+
|
|
44
|
+
### Changed (structural defenses — close both classes)
|
|
45
|
+
|
|
46
|
+
- **`tests/docs-consistency.test.ts` (+2 invariants):**
|
|
47
|
+
- **reranker-default α-guard** — reads `DEFAULT_RERANKER_ALIAS` from `src/embeddings.ts` and asserts STABILITY's "Default models" bullet names it AND does not present `rerank-multilingual` as the default. Pins the 3rd-instance class structurally.
|
|
48
|
+
- **OIA-count consistency** — derives the canonical count from `scripts/oia-walk.mjs`'s self-declared `canonical count is "N"` (cross-checked it's ≥10) and asserts every count-stating surface (`AGENTS.md` ×2, `ROADMAP.md`) matches it — so adding an OIA check forces a docs sync.
|
|
49
|
+
|
|
50
|
+
### Tests (997)
|
|
51
|
+
|
|
52
|
+
+2 `it()` in `tests/docs-consistency.test.ts` (the two guards above). Test count 995 → 997 across surfaces.
|
|
53
|
+
|
|
54
|
+
### Files changed
|
|
55
|
+
|
|
56
|
+
- `STABILITY.md` (reranker default → rerank-bge), `ROADMAP.md` (OIA 8→10 + test-count 997), `tests/docs-consistency.test.ts` (+2 guards), test-count surfaces (README/COMPARISON/llms.txt/AGENTS/package.json) → 997.
|
|
57
|
+
- version bump 3.9.0-rc.21 → 3.9.0-rc.22 (7 surfaces).
|
|
58
|
+
|
|
59
|
+
### Deferred to rc.23 (same audit, batch 3/3)
|
|
60
|
+
|
|
61
|
+
Test-infra rigor: meta-invariant comment-bypass + glob-miss (HIGH×2), silent-`return`→`ctx.skip()`+CI-GUARD propagation (security.test.ts/fts5.test.ts), `vault.ts`/`ocr.ts` per-file FLOORS.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
5
65
|
## [3.9.0-rc.21] — 2026-05-29
|
|
6
66
|
|
|
7
67
|
> **TL;DR:** **Security — close a verified ReDoS hole the rc.9 guard missed (full-audit response, batch 1/3).** A fresh multi-agent state-driven audit (code + docs + tests, all green on the 10-gate baseline) reproduced ONE genuine exploit: `obsidian_open_questions`'s `isCatastrophicRegex` (rc.9) catches *nested* quantifiers (`(a+)+`) but **not overlapping-alternation** (`(a|a)+`) — the auditor hung V8 >8s with a 200-char-cap-legal pattern, and the tool is always-registered, so any bearer-authenticated `serve-http` client could freeze the event loop (remote DoS). The guard now also rejects **unbounded-quantified AMBIGUOUS alternations** via leading-atom overlap analysis — catching `(a|a)+`, `(a|ab)*`, `(.|a)+`, `((a|a))+`, `(a|)+` while keeping DISJOINT ones like `(a|b|c)+` / `(cat|dog)+` accepted (they match linearly) and the unquantified default-pattern alternation unaffected. **995 tests** (+2 integration; +13 detector cases via the existing data-driven loops). **No CRITICAL/HIGH code findings otherwise — the codebase audited exceptionally clean.**
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
[](https://github.com/oomkapwn/enquire-mcp/actions/workflows/ci.yml)
|
|
14
14
|
[](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
|
|
15
15
|
[](https://www.npmjs.com/package/@oomkapwn/enquire-mcp)
|
|
16
|
-
[](#trust)
|
|
17
17
|
[](./STABILITY.md)
|
|
18
18
|
[](https://slsa.dev/spec/v1.0/levels#build-l2)
|
|
19
19
|
[](https://modelcontextprotocol.io/)
|
|
@@ -38,7 +38,7 @@ Your Obsidian vault becomes **persistent, queryable long-term memory** for any M
|
|
|
38
38
|
> 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.
|
|
39
39
|
> 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.
|
|
40
40
|
|
|
41
|
-
**44 tools · 19 MCP prompts ·
|
|
41
|
+
**44 tools · 19 MCP prompts · 1002 unit tests · 50+ languages · v3.8.x stable · semver-bound · MIT · npm build provenance (SLSA L2).**
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -176,7 +176,7 @@ Auto-generated **[API reference at oomkapwn.github.io/enquire-mcp](https://oomka
|
|
|
176
176
|
| **GraphRAG-light** (wikilink community detection via Louvain modularity) | ✅ **only here** | ❌ | ❌ |
|
|
177
177
|
| **Standalone `.base` query execution** (works without Obsidian running) | ✅ **only here** | ❌ | ❌ delegates to Obsidian |
|
|
178
178
|
| **HyDE retrieval** (Gao et al 2023) + sub-question decomposition | ✅ **only here** | ❌ | ❌ |
|
|
179
|
-
| **
|
|
179
|
+
| **1002 unit tests · 9 required + 4 advisory CI gates per PR** | ✅ | n/a | rare |
|
|
180
180
|
| **Signed build provenance** (npm + Sigstore, SLSA Build L2) | ✅ | n/a | ❌ |
|
|
181
181
|
| **Semver-bound public surface** ([STABILITY.md](./STABILITY.md)) | ✅ | n/a | ❌ |
|
|
182
182
|
| Standalone (no Obsidian plugin needed) | ✅ | ❌ requires Obsidian | varies |
|
|
@@ -286,7 +286,7 @@ Channel: `npm install @oomkapwn/enquire-mcp` → latest stable (`@latest` = v3.8
|
|
|
286
286
|
```bash
|
|
287
287
|
git clone https://github.com/oomkapwn/enquire-mcp.git
|
|
288
288
|
cd enquire-mcp && npm install
|
|
289
|
-
npm test # full suite (
|
|
289
|
+
npm test # full suite (1002 tests, ~12s)
|
|
290
290
|
npm run lint # zero warnings
|
|
291
291
|
npm run build # tsc → dist/
|
|
292
292
|
```
|
package/STABILITY.md
CHANGED
|
@@ -60,7 +60,7 @@ Anything not listed here (private fields, internal helpers, test fixtures) is **
|
|
|
60
60
|
|
|
61
61
|
- **Stderr log format.** We add diagnostic lines, change wording, and adjust verbosity in minor releases. Don't grep stderr for control flow.
|
|
62
62
|
- **On-disk file formats.** SQLite schemas, HNSW sidecar layouts, embedding model versions, and persistent-cache shapes can evolve. v2.17 demonstrated the policy: schema bumps trigger automatic rebuild via the meta-table contamination guard. You don't need to migrate manually.
|
|
63
|
-
- **Default models.** `--embedding-model` and `--reranker-model` default aliases (`multilingual` / `rerank-
|
|
63
|
+
- **Default models.** `--embedding-model` and `--reranker-model` default aliases (`multilingual` / `rerank-bge`) point at the recommended HuggingFace repos for the current release. We may change which underlying repo a default alias resolves to in a minor release if a better one becomes available; the alias name itself is stable.
|
|
64
64
|
- **Internal HTTP routes** other than `/mcp` and `/health` (which are configurable via `--mcp-path` / `--health-path`).
|
|
65
65
|
- **Test infrastructure** under `tests/` and helper scripts under `scripts/`.
|
|
66
66
|
|
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.
|
|
10
|
+
export declare const VERSION = "3.9.0-rc.23";
|
|
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.
|
|
43
|
+
export const VERSION = "3.9.0-rc.23";
|
|
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`,
|
package/docs/COMPARISON.md
CHANGED
|
@@ -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) | **
|
|
46
|
+
| Test count (public) | **1002** | (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) |
|
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.
|
|
4
|
+
"version": "3.9.0-rc.23",
|
|
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,
|
|
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, 1002 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"
|