@dikolab/kbdb 0.2.1 → 0.3.0

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.
Files changed (120) hide show
  1. package/README.md +59 -24
  2. package/dist/cli.cjs +462 -73
  3. package/dist/cli.cjs.map +4 -4
  4. package/dist/cli.mjs +454 -65
  5. package/dist/cli.mjs.map +4 -4
  6. package/dist/kbdb-worker.cjs +395 -60
  7. package/dist/kbdb-worker.cjs.map +4 -4
  8. package/dist/mod.cjs +18 -1
  9. package/dist/mod.cjs.map +2 -2
  10. package/dist/mod.mjs +18 -1
  11. package/dist/mod.mjs.map +2 -2
  12. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +3 -1
  13. package/dist/src/shared/cli/functions/install-default-skills.function.d.ts +12 -0
  14. package/dist/src/shared/cli/functions/run-check.function.d.ts +47 -5
  15. package/dist/src/shared/cli/functions/run-export.function.d.ts +34 -0
  16. package/dist/src/shared/cli/functions/run-gc.function.d.ts +6 -0
  17. package/dist/src/shared/cli/functions/run-learn.function.d.ts +35 -6
  18. package/dist/src/shared/cli/functions/run-recall.function.d.ts +45 -0
  19. package/dist/src/shared/cli/functions/run-search.function.d.ts +52 -15
  20. package/dist/src/shared/cli/index.d.ts +4 -0
  21. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +13 -0
  22. package/dist/src/shared/cli/typings/learn-result.model.d.ts +19 -0
  23. package/dist/src/shared/cli/typings/search-display.model.d.ts +18 -0
  24. package/dist/src/shared/mcp/classes/mcp-server.class.d.ts +8 -0
  25. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +43 -0
  26. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  27. package/dist/src/shared/wasm-codec/functions/decode-add-section-result.function.d.ts +48 -0
  28. package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +58 -0
  29. package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +33 -0
  30. package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +52 -0
  31. package/dist/src/shared/wasm-codec/index.d.ts +2 -0
  32. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +16 -0
  33. package/dist/src/shared/worker-client/index.d.ts +1 -1
  34. package/dist/src/shared/worker-client/typings/add-section-result.model.d.ts +29 -15
  35. package/dist/src/shared/worker-client/typings/export-result.model.d.ts +14 -0
  36. package/dist/src/shared/worker-client/typings/gc-result.model.d.ts +6 -0
  37. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +12 -0
  38. package/dist/src/shared/worker-client/typings/section.model.d.ts +16 -0
  39. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +35 -0
  40. package/dist/wasm/fs-database/kbdb_fs_database.d.ts +22 -1
  41. package/dist/wasm/fs-database/kbdb_fs_database.js +28 -1
  42. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  43. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +1 -0
  44. package/dist/wasm/kb-worker/kbdb_worker.d.ts +48 -1
  45. package/dist/wasm/kb-worker/kbdb_worker.js +60 -1
  46. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  47. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +2 -0
  48. package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  49. package/dist/worker.mjs +396 -60
  50. package/dist/worker.mjs.map +4 -4
  51. package/docs/details/cli.md +102 -15
  52. package/docs/details/library-api.md +55 -6
  53. package/docs/details/mcp-server.md +8 -4
  54. package/docs/details/search-and-ranking.md +63 -5
  55. package/docs/details/storage.md +2 -0
  56. package/docs/goals/cli.md +255 -14
  57. package/docs/goals/database.md +244 -17
  58. package/docs/goals/document.md +1 -1
  59. package/docs/goals/mcp.md +83 -14
  60. package/docs/goals/query-parser.md +98 -4
  61. package/docs/goals/query-result.md +177 -10
  62. package/docs/goals/skills.md +72 -0
  63. package/docs/goals/worker-daemon.md +54 -7
  64. package/docs/modules/rust/fs-database/functions/integrity.md +11 -0
  65. package/docs/modules/rust/fs-database/functions/section.md +23 -6
  66. package/docs/modules/rust/fs-database/module.md +1 -0
  67. package/docs/modules/rust/fs-database/types/section.md +27 -1
  68. package/docs/modules/rust/overview.md +2 -1
  69. package/docs/modules/rust/query-parser/functions/module.md +2 -2
  70. package/docs/modules/rust/query-parser/functions/pipeline.md +44 -6
  71. package/docs/modules/rust/query-parser/module.md +5 -4
  72. package/docs/modules/rust/query-parser/types/keyphrase.md +11 -0
  73. package/docs/modules/rust/query-parser/types/module.md +3 -3
  74. package/docs/modules/typescript/shared/cli/functions.md +68 -3
  75. package/package.json +1 -1
  76. package/src/shared/cli/functions/dispatch-command.function.ts +53 -1
  77. package/src/shared/cli/functions/format-output.function.ts +36 -12
  78. package/src/shared/cli/functions/generate-help.function.ts +56 -1
  79. package/src/shared/cli/functions/install-default-skills.function.ts +296 -0
  80. package/src/shared/cli/functions/parse-args.function.ts +13 -0
  81. package/src/shared/cli/functions/run-check.function.ts +87 -6
  82. package/src/shared/cli/functions/run-export.function.ts +40 -0
  83. package/src/shared/cli/functions/run-gc.function.ts +6 -0
  84. package/src/shared/cli/functions/run-init.function.ts +2 -0
  85. package/src/shared/cli/functions/run-learn.function.ts +68 -16
  86. package/src/shared/cli/functions/run-recall.function.ts +66 -0
  87. package/src/shared/cli/functions/run-search.function.ts +58 -15
  88. package/src/shared/cli/index.ts +4 -0
  89. package/src/shared/cli/typings/cli-options.interface.ts +13 -0
  90. package/src/shared/cli/typings/learn-result.model.ts +16 -0
  91. package/src/shared/cli/typings/search-display.model.ts +18 -0
  92. package/src/shared/mcp/classes/mcp-server.class.ts +30 -1
  93. package/src/shared/mcp/functions/create-tool-definitions.function.ts +46 -5
  94. package/src/shared/mcp/functions/handle-tool-call.function.ts +70 -2
  95. package/src/shared/mcp/typings/mcp-client.interface.ts +45 -0
  96. package/src/shared/version/constants/version.constant.ts +1 -1
  97. package/src/shared/wasm-codec/functions/decode-add-section-result.function.ts +112 -0
  98. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +86 -0
  99. package/src/shared/wasm-codec/functions/decode-section-records.function.ts +87 -0
  100. package/src/shared/wasm-codec/functions/encode-add-section-params.function.ts +68 -0
  101. package/src/shared/wasm-codec/index.ts +5 -0
  102. package/src/shared/worker-client/classes/worker-client.class.ts +19 -0
  103. package/src/shared/worker-client/index.ts +4 -1
  104. package/src/shared/worker-client/typings/add-section-result.model.ts +30 -15
  105. package/src/shared/worker-client/typings/export-result.model.ts +14 -0
  106. package/src/shared/worker-client/typings/gc-result.model.ts +6 -0
  107. package/src/shared/worker-client/typings/search-result.model.ts +12 -0
  108. package/src/shared/worker-client/typings/section.model.ts +16 -0
  109. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +315 -46
  110. package/src/shared/worker-daemon/functions/create-host-imports.function.ts +19 -4
  111. package/src/shared/worker-daemon/functions/create-ipc-server.function.ts +5 -1
  112. package/src/wasm/fs-database/kbdb_fs_database.d.ts +22 -1
  113. package/src/wasm/fs-database/kbdb_fs_database.js +28 -1
  114. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  115. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +1 -0
  116. package/src/wasm/kb-worker/kbdb_worker.d.ts +48 -1
  117. package/src/wasm/kb-worker/kbdb_worker.js +60 -1
  118. package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  119. package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +2 -0
  120. package/src/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
@@ -30,12 +30,14 @@ kbdb <command> <subcommand> [options] ...[parameters]
30
30
  | Knowledge Base | `learn` | Import content from files or stdin |
31
31
  | Knowledge Base | `unlearn` | Remove sections by kbid |
32
32
  | Knowledge Base | `search` | Query the knowledge base |
33
+ | Knowledge Base | `recall` | Recall full context for sections |
33
34
  | Knowledge Base | `content` | Compose rendered content from ids |
34
35
  | Database | `db init` | Initialise a new `.kbdb` directory |
35
36
  | Database | `db migrate` | Migrate database to current format |
36
37
  | Maintenance | `status` | Show database status |
37
38
  | Maintenance | `check` | Verify knowledge base integrity |
38
39
  | Maintenance | `gc` | Garbage collect unreferenced sections |
40
+ | Maintenance | `export` | Export database snapshot |
39
41
  | Maintenance | `rebuild` | Reconstruct all index files |
40
42
  | Skills | `skill learn` | Create a new skill definition |
41
43
  | Skills | `skill list` | List all skills |
@@ -76,6 +78,7 @@ These options apply to the `search` command.
76
78
  |--------|-------|---------|--------|-------------|
77
79
  | `--mode <mode>` | `-m` | `sections` | `sections`, `documents`, `stats` | Result granularity |
78
80
  | `--limit <n>` | `-l` | `20` | positive integer | Maximum results returned |
81
+ | `--offset <n>` | | `0` | non-negative integer | Zero-based result offset for pagination |
79
82
  | `--format <fmt>` | `-f` | `json` | `json`, `text`, `mcp` | Output format |
80
83
  | `--content` | `-c` | off | boolean flag | Hydrate results with section content |
81
84
 
@@ -115,6 +118,8 @@ or `-` for stdin.
115
118
  | `--title <title>` | Section title (applies to all sections) |
116
119
  | `--description <d>` | Section description |
117
120
  | `--docid <docid>` | Attach sections to this document ID |
121
+ | `--tags <t,...>` | Comma-separated tags for scoping and filtering |
122
+ | `--replace` | Enable supersession by source key |
118
123
 
119
124
  **Output:** JSON array of `LearnResult` objects:
120
125
 
@@ -124,7 +129,10 @@ or `-` for stdin.
124
129
  "kbid": "abcdef1234567890abcdef1234",
125
130
  "path": "/absolute/path/to/file.md",
126
131
  "size": 1234,
127
- "skipped": false
132
+ "skipped": false,
133
+ "superseded": null,
134
+ "warnings": [],
135
+ "near_duplicates": []
128
136
  }
129
137
  ]
130
138
  ```
@@ -162,26 +170,77 @@ are joined into a single query string.
162
170
  **Output (json):**
163
171
 
164
172
  ```json
165
- [
166
- {
167
- "kbid": "abcdef1234567890abcdef1234",
168
- "score": 8.7432,
169
- "preview": "",
170
- "matches": [
171
- { "term": "machine", "frequency": 3 },
172
- { "term": "learning", "frequency": 1 }
173
- ]
174
- }
175
- ]
173
+ {
174
+ "items": [
175
+ {
176
+ "kbid": "abcdef1234567890abcdef1234",
177
+ "heading": "Machine Learning Overview",
178
+ "type": "text/markdown",
179
+ "docids": ["doc-5678"],
180
+ "snippet": "...applies machine learning...",
181
+ "matched_terms": ["machine", "learning"],
182
+ "matched_fields": ["heading", "body"],
183
+ "confidence": 1.0,
184
+ "created_at": "2026-06-15T10:00:00Z"
185
+ }
186
+ ],
187
+ "total": 42,
188
+ "offset": 0,
189
+ "limit": 20,
190
+ "has_more": true,
191
+ "relaxed": false
192
+ }
176
193
  ```
177
194
 
178
195
  **Output (text):**
179
196
 
180
197
  ```
181
- 1. [abcdef1234567890abcdef1234] (score: 8.7432)
198
+ 1. [abcdef1234567890abcdef1234] (confidence: 1.00)
199
+ Machine Learning Overview
200
+ ...applies machine learning...
201
+ matches: machine, learning (heading, body)
202
+ ```
203
+
204
+ ### `recall` -- Recall Context
182
205
 
183
- matches: machine, learning
184
206
  ```
207
+ kbdb recall [options] <kbid>...
208
+ ```
209
+
210
+ Retrieve full content and progressive context for
211
+ one or more sections. Use after `search` to read
212
+ relevant results.
213
+
214
+ **Options:**
215
+
216
+ | Option | Default | Description |
217
+ |--------|---------|-------------|
218
+ | `--depth <n>` | `0` | Context expansion level (0--3) |
219
+
220
+ **Expansion levels:**
221
+
222
+ | Depth | Returns |
223
+ |-------|---------|
224
+ | 0 | Full section content with heading, type, docids |
225
+ | 1 | Depth 0 + parent documents + back-references |
226
+ | 2 | Depth 1 + sibling sections + forward references |
227
+ | 3 | Depth 2 + full text of referenced sections |
228
+
229
+ **Output:**
230
+
231
+ ```json
232
+ {
233
+ "kbid": "abcdef1234567890abcdef1234",
234
+ "heading": "Architecture Overview",
235
+ "type": "text/markdown",
236
+ "content": "Full section text...",
237
+ "docids": ["doc-5678"]
238
+ }
239
+ ```
240
+
241
+ When multiple kbids are provided, output is a JSON
242
+ array. The `--depth` parameter applies to all
243
+ sections.
185
244
 
186
245
  ### `content` -- Compose Rendered Content
187
246
 
@@ -229,6 +288,11 @@ document references, and type consistency.
229
288
  "type": "orphan_section",
230
289
  "entity": "x9y8z7w6v5u4t3s2r1q0p9o8n7",
231
290
  "detail": "Section not referenced by any document"
291
+ },
292
+ {
293
+ "type": "divergent_content",
294
+ "entity": "a1b2c3d4e5f67890",
295
+ "detail": "Sections sharing source key have different content"
232
296
  }
233
297
  ]
234
298
  }
@@ -251,7 +315,8 @@ document manifest references).
251
315
  ```json
252
316
  {
253
317
  "removed_sections": 3,
254
- "removed_bytes": 15360
318
+ "removed_bytes": 15360,
319
+ "stale_sources": 1
255
320
  }
256
321
  ```
257
322
 
@@ -273,6 +338,28 @@ and document manifests on disk.
273
338
  }
274
339
  ```
275
340
 
341
+ ### `export` -- Export Database
342
+
343
+ ```
344
+ kbdb export [options] [<path>]
345
+ ```
346
+
347
+ Export the knowledge base as a self-contained
348
+ directory snapshot for backup or versioning. Copies
349
+ sections, documents, and catalog (no indexes -- they
350
+ are rebuildable via `rebuild`). Defaults to
351
+ `./kbdb-export/`.
352
+
353
+ **Output:**
354
+
355
+ ```json
356
+ {
357
+ "path": "/absolute/path/to/export",
358
+ "sections_exported": 39,
359
+ "documents_exported": 5
360
+ }
361
+ ```
362
+
276
363
  ### `db init` -- Initialise Database
277
364
 
278
365
  ```
@@ -69,7 +69,9 @@ Queries the knowledge base and returns ranked
69
69
  results.
70
70
 
71
71
  ```typescript
72
- search(params: SearchParams): Promise<SearchResult[]>
72
+ search(
73
+ params: SearchParams,
74
+ ): Promise<PagedSearchResult>
73
75
  ```
74
76
 
75
77
  | Param | Type | Description |
@@ -188,6 +190,36 @@ listDocumentsByType(
188
190
 
189
191
  ---
190
192
 
193
+ ### Recall
194
+
195
+ #### `recall(params)`
196
+
197
+ Retrieves full content and progressive context for
198
+ one or more sections. Use after `search()` to read
199
+ relevant results.
200
+
201
+ ```typescript
202
+ recall(
203
+ params: RecallParams,
204
+ ): Promise<RecallResult | RecallResult[]>
205
+ ```
206
+
207
+ | Param | Type | Description |
208
+ |-------|------|-------------|
209
+ | `params.kbid` | `string?` | Single section identifier. |
210
+ | `params.kbids` | `string[]?` | Batch section identifiers. |
211
+ | `params.depth` | `number?` | Expansion depth (0--3). Default `0`. |
212
+
213
+ At least one of `kbid` or `kbids` is required.
214
+ Returns a single `RecallResult` for `kbid`, or an
215
+ array for `kbids`. Depth controls progressive
216
+ context expansion: 0 = section content, 1 = adds
217
+ parent documents and back-references, 2 = adds
218
+ siblings and forward references, 3 = adds full text
219
+ of referenced sections.
220
+
221
+ ---
222
+
191
223
  ### Content
192
224
 
193
225
  #### `content(ids)`
@@ -339,6 +371,21 @@ interface SearchParams {
339
371
  readonly query: string;
340
372
  readonly mode?: 'sections' | 'documents' | 'stats';
341
373
  readonly limit?: number;
374
+ readonly offset?: number;
375
+ readonly content?: boolean;
376
+ }
377
+ ```
378
+
379
+ ### `PagedSearchResult`
380
+
381
+ ```typescript
382
+ interface PagedSearchResult {
383
+ readonly items: readonly SearchResult[];
384
+ readonly total: number;
385
+ readonly offset: number;
386
+ readonly limit: number;
387
+ readonly has_more: boolean;
388
+ readonly relaxed: boolean;
342
389
  }
343
390
  ```
344
391
 
@@ -347,11 +394,13 @@ interface SearchParams {
347
394
  ```typescript
348
395
  interface SearchResult {
349
396
  readonly kbid: string;
350
- readonly score: number;
351
- readonly matches: readonly {
352
- readonly term: string;
353
- readonly frequency: number;
354
- }[];
397
+ readonly heading: string | null;
398
+ readonly type: string;
399
+ readonly docids: readonly string[];
400
+ readonly snippet: string;
401
+ readonly matched_terms: readonly string[];
402
+ readonly matched_fields: readonly string[];
403
+ readonly created_at: string;
355
404
  }
356
405
  ```
357
406
 
@@ -188,7 +188,7 @@ own worker client connection.
188
188
 
189
189
  ## Tools Reference
190
190
 
191
- The MCP server exposes 17 tools grouped by
191
+ The MCP server exposes 19 tools grouped by
192
192
  function. All tools communicate with the worker
193
193
  daemon via JSON-RPC 2.0 over IPC.
194
194
 
@@ -196,15 +196,17 @@ daemon via JSON-RPC 2.0 over IPC.
196
196
 
197
197
  | Tool | Parameters | Description | Read-only | Destructive |
198
198
  |------|-----------|-------------|-----------|-------------|
199
- | `search` | `query` (string, required), `mode` (string), `limit` (number) | Query the knowledge base by keywords. Returns ranked results with kbid, score, and matched terms. | yes | no |
200
- | `learn` | `content` (string, required), `type` (string), `title` (string), `description` (string), `docid` (string) | Import content into the knowledge base. Extracts keywords and builds indexes. | no | no |
199
+ | `search` | `query` (string, required), `mode` (string), `limit` (number), `offset` (number), `content` (boolean) | Query the knowledge base by keywords. Returns ranked results with heading, snippet, and matched terms. Use multiple short keyword queries for best coverage. | yes | no |
200
+ | `learn` | `content` (string, required), `type` (string), `title` (string), `description` (string), `docid` (string), `tags` (string[]), `replace` (boolean) | Import content into the knowledge base. Use for durable facts, decisions, and corrections. Use `replace` when updating existing knowledge. Attach `tags` for scoping. | no | no |
201
201
  | `unlearn` | `kbid` (string, required) | Remove a section by kb-id. Cascades deletion to index entries and ranking data. | no | yes |
202
202
  | `retrieve` | `kbid` (string), `docid` (string) | Fetch a specific section or document by identifier. At least one of `kbid` or `docid` required. | yes | no |
203
+ | `recall` | `kbid` (string), `kbids` (string[]), `depth` (number) | Retrieve full content and progressive context for sections. Use after `search` to read relevant results. Depth 0-3 controls context expansion. | yes | no |
203
204
  | `content` | `ids` (string[], required) | Compose a rendered Markdown document from one or more kbid or docid identifiers. | yes | no |
204
205
  | `status` | (none) | Return database status and cache statistics. | yes | no |
205
206
  | `check` | (none) | Verify knowledge base integrity. Reports checksum mismatches, orphan sections, broken references. | yes | no |
206
207
  | `gc` | (none) | Remove unreferenced sections (no document manifest references). | no | yes |
207
208
  | `rebuild` | (none) | Reconstruct all index files from section files and document manifests on disk. | no | no |
209
+ | `export` | `path` (string) | Export the knowledge base as a self-contained directory snapshot for backup or versioning. Copies sections, documents, and catalog (no indexes). | no | no |
208
210
 
209
211
  ### Skills Tools
210
212
 
@@ -236,7 +238,9 @@ daemon via JSON-RPC 2.0 over IPC.
236
238
  | `status` | yes |
237
239
  | `check` | yes |
238
240
  | `gc` | no |
241
+ | `recall` | yes |
239
242
  | `rebuild` | no |
243
+ | `export` | yes |
240
244
  | `skill-learn` | yes |
241
245
  | `skill-list` | yes |
242
246
  | `skill-get` | yes |
@@ -336,7 +340,7 @@ Protocol version **2025-11-25** and advertises the
336
340
  following capabilities:
337
341
 
338
342
  - **tools** -- `tools/list` and `tools/call` for
339
- all 17 tools.
343
+ all 19 tools.
340
344
  - **resources** -- `resources/list`,
341
345
  `resources/read`, and
342
346
  `resources/templates/list` for URI-based content
@@ -43,7 +43,7 @@ sections containing both "auth" and "flow".
43
43
  ## Tokenization Pipeline
44
44
 
45
45
  Both indexing and search queries pass through the
46
- same eight-stage pipeline. Using identical processing
46
+ same nine-stage pipeline. Using identical processing
47
47
  for both sides guarantees that stored terms match
48
48
  query terms.
49
49
 
@@ -69,10 +69,13 @@ query terms.
69
69
  6. Stop word removal
70
70
  |
71
71
  v
72
- 7. Stemming
72
+ 7. Synonym expansion
73
73
  |
74
74
  v
75
- 8. N-gram extraction
75
+ 8. Stemming
76
+ |
77
+ v
78
+ 9. N-gram extraction
76
79
  |
77
80
  v
78
81
  Normalized tokens
@@ -111,13 +114,24 @@ query terms.
111
114
  no discriminative value (`the`, `is`, `and`,
112
115
  etc.). The stop word list is configurable.
113
116
 
114
- 7. **Stemming** -- Reduce words to root forms using
117
+ 7. **Synonym expansion** -- Look up each token in a
118
+ built-in bidirectional synonym map and insert
119
+ synonym tokens alongside the original. Bridges
120
+ vocabulary gaps: a document using "sign-in" becomes
121
+ findable via "login". The map covers common
122
+ IT/development vocabulary (~30-50 entries:
123
+ login/sign-in, auth/authentication,
124
+ remove/delete, config/configuration, etc.).
125
+ Applied symmetrically during both indexing and
126
+ querying.
127
+
128
+ 8. **Stemming** -- Reduce words to root forms using
115
129
  the Snowball/Porter2 stemmer. `running` and `runs`
116
130
  both stem to `run`. Both the stemmed form and the
117
131
  original are stored so exact-match queries still
118
132
  work.
119
133
 
120
- 8. **N-gram extraction** -- Generate bigrams and
134
+ 9. **N-gram extraction** -- Generate bigrams and
121
135
  trigrams for phrase indexing and multi-word term
122
136
  matching. Supports phrase queries without requiring
123
137
  a separate phrase index.
@@ -291,6 +305,35 @@ and freshness are additive boosts with configurable
291
305
  weights. Results are sorted by `final_score`
292
306
  descending; ties broken by kbid lexicographic order.
293
307
 
308
+ ### Score Normalization
309
+
310
+ Raw BM25F scores are normalized to a 0.0--1.0
311
+ `confidence` value within each result set. Each
312
+ score is divided by the maximum score in the result
313
+ set, so the top result always has confidence 1.0.
314
+ This lets agents distinguish strong matches from
315
+ weak tail results without interpreting raw score
316
+ magnitudes.
317
+
318
+ Confidence is exposed in CLI output but omitted from
319
+ MCP results (ordering is the signal for agents).
320
+
321
+ ## Relaxed-Match Fallback
322
+
323
+ When a multi-term AND query returns zero results,
324
+ the engine automatically retries with OR semantics
325
+ -- any term matches instead of all required. This
326
+ prevents silent misses when the query is too
327
+ specific for the corpus.
328
+
329
+ The fallback is transparent: no special syntax
330
+ needed. Results from relaxed matching are flagged
331
+ with `relaxed: true` in the response envelope so
332
+ the caller knows the match is weaker. Single-term
333
+ queries are unaffected (AND and OR are equivalent
334
+ for one term). Phrase queries and exclusions are
335
+ preserved in both modes.
336
+
294
337
  ## Keyword Extraction
295
338
 
296
339
  When content is added to the knowledge base, the
@@ -347,6 +390,7 @@ indexes/
347
390
  +-- meta.toml human-readable metadata
348
391
  +-- terms.idx inverted index (B+ tree)
349
392
  +-- positions.idx positional index (B+ tree)
393
+ +-- references.idx reference graph (B+ tree)
350
394
  +-- corpus.dat corpus statistics (binary)
351
395
  ```
352
396
 
@@ -378,6 +422,20 @@ zero-based token offsets. Supports three functions:
378
422
  - **Zone scoring** -- Determine whether a term falls
379
423
  in the heading zone (first 20% of the section).
380
424
 
425
+ ### `references.idx` -- Reference Graph Index
426
+
427
+ B+ tree mapping section kbids to their content
428
+ marker cross-references. Stores bidirectional
429
+ edges: for each `$(text:)`, `$(code:)`, `$(image:)`,
430
+ `$(link:)`, `$(document:)`, and `$(doc-link:)`
431
+ marker, both a forward entry (source -> target) and
432
+ a back entry (target -> source) are recorded. This
433
+ enables the `recall` command's progressive context
434
+ expansion -- depth 1+ retrieves back-references
435
+ (sections that point to this one) and depth 2+
436
+ retrieves forward references (sections this one
437
+ points to).
438
+
381
439
  ### `corpus.dat` -- Corpus Statistics
382
440
 
383
441
  Binary file storing corpus-wide aggregates:
@@ -24,6 +24,7 @@ version-controlled.
24
24
  | +-- meta.toml
25
25
  | +-- terms.idx
26
26
  | +-- positions.idx
27
+ | +-- references.idx
27
28
  | +-- corpus.dat
28
29
  +-- worker.toml
29
30
  +-- .gitignore
@@ -37,6 +38,7 @@ version-controlled.
37
38
  | `indexes/meta.toml` | TOML | Index metadata: rebuild timestamp, term count, statistics summary |
38
39
  | `indexes/terms.idx` | Binary | Inverted index (B+ tree): maps terms to posting lists with per-field term frequencies |
39
40
  | `indexes/positions.idx` | Binary | Positional index (B+ tree): maps (term, kbid) to token offset arrays |
41
+ | `indexes/references.idx` | Binary | Reference graph index (B+ tree): bidirectional content marker cross-references between sections |
40
42
  | `indexes/corpus.dat` | Binary | Corpus statistics: section count, average lengths per field, per-term document frequencies |
41
43
  | `worker.toml` | TOML | Cache daemon configuration |
42
44
  | `.gitignore` | Text | Excludes `indexes/` from version control |