@dikolab/kbdb 0.1.6 → 0.2.1

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 (199) hide show
  1. package/README.md +30 -9
  2. package/dist/cli.cjs +181 -50
  3. package/dist/cli.cjs.map +3 -3
  4. package/dist/cli.mjs +181 -50
  5. package/dist/cli.mjs.map +3 -3
  6. package/dist/kbdb-worker.cjs +283 -29
  7. package/dist/kbdb-worker.cjs.map +4 -4
  8. package/dist/mod.cjs +13 -2
  9. package/dist/mod.cjs.map +2 -2
  10. package/dist/mod.d.ts +25 -0
  11. package/dist/mod.mjs +13 -2
  12. package/dist/mod.mjs.map +2 -2
  13. package/dist/src/cli.d.ts +8 -0
  14. package/dist/src/shared/cli/functions/format-output.function.d.ts +7 -7
  15. package/dist/src/shared/cli/functions/run-search.function.d.ts +25 -16
  16. package/dist/src/shared/cli/index.d.ts +1 -1
  17. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +2 -0
  18. package/dist/src/shared/cli/typings/search-display.model.d.ts +25 -7
  19. package/dist/src/shared/mcp/functions/handle-recall.function.d.ts +29 -0
  20. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +30 -11
  21. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  22. package/dist/src/shared/wasm-codec/functions/decode-recall-result.function.d.ts +28 -0
  23. package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +14 -7
  24. package/dist/src/shared/wasm-codec/functions/encode-recall-params.function.d.ts +21 -0
  25. package/dist/src/shared/wasm-codec/functions/encode-search-params.function.d.ts +1 -1
  26. package/dist/src/shared/wasm-codec/index.d.ts +5 -2
  27. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +13 -3
  28. package/dist/src/shared/worker-client/index.d.ts +2 -1
  29. package/dist/src/shared/worker-client/typings/recall-result.model.d.ts +94 -0
  30. package/dist/src/shared/worker-client/typings/search-params.model.d.ts +2 -0
  31. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +23 -7
  32. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +1 -0
  33. package/dist/src/worker.d.ts +7 -0
  34. package/dist/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  35. package/dist/wasm/fs-database/kbdb_fs_database.js +30 -0
  36. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  37. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  38. package/dist/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  39. package/dist/wasm/kb-worker/kbdb_worker.js +56 -0
  40. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  41. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
  42. package/dist/worker.mjs +283 -29
  43. package/dist/worker.mjs.map +4 -4
  44. package/docs/details/README.md +26 -0
  45. package/docs/details/cli.md +608 -0
  46. package/docs/details/library-api.md +406 -0
  47. package/docs/details/mcp-server.md +430 -0
  48. package/docs/details/search-and-ranking.md +457 -0
  49. package/docs/details/storage.md +529 -0
  50. package/docs/goals/agents.md +751 -0
  51. package/docs/goals/architecture.svg +198 -0
  52. package/docs/goals/cli.md +2308 -0
  53. package/docs/goals/content-composer.md +609 -0
  54. package/docs/goals/content-parser.md +279 -0
  55. package/docs/goals/database.md +1452 -0
  56. package/docs/goals/document.md +368 -0
  57. package/docs/goals/mcp.md +1467 -0
  58. package/docs/goals/overview.md +124 -0
  59. package/docs/goals/query-parser.md +271 -0
  60. package/docs/goals/query-result.md +693 -0
  61. package/docs/goals/skills.md +738 -0
  62. package/docs/goals/worker-client.md +944 -0
  63. package/docs/goals/worker-daemon.md +1447 -0
  64. package/docs/modules/overview.md +298 -0
  65. package/docs/modules/rust/fs-database/functions/document.md +48 -0
  66. package/docs/modules/rust/fs-database/functions/integrity.md +68 -0
  67. package/docs/modules/rust/fs-database/functions/io.md +87 -0
  68. package/docs/modules/rust/fs-database/functions/module.md +22 -0
  69. package/docs/modules/rust/fs-database/functions/query-exec.md +44 -0
  70. package/docs/modules/rust/fs-database/functions/section.md +59 -0
  71. package/docs/modules/rust/fs-database/indexes/btree.md +35 -0
  72. package/docs/modules/rust/fs-database/indexes/corpus.md +61 -0
  73. package/docs/modules/rust/fs-database/indexes/inverted.md +60 -0
  74. package/docs/modules/rust/fs-database/indexes/module.md +64 -0
  75. package/docs/modules/rust/fs-database/indexes/positional.md +39 -0
  76. package/docs/modules/rust/fs-database/module.md +149 -0
  77. package/docs/modules/rust/fs-database/types/catalog.md +53 -0
  78. package/docs/modules/rust/fs-database/types/module.md +12 -0
  79. package/docs/modules/rust/fs-database/types/section.md +101 -0
  80. package/docs/modules/rust/kb-worker/functions/compose.md +57 -0
  81. package/docs/modules/rust/kb-worker/functions/module.md +20 -0
  82. package/docs/modules/rust/kb-worker/functions/retrieve.md +194 -0
  83. package/docs/modules/rust/kb-worker/functions/search.md +173 -0
  84. package/docs/modules/rust/kb-worker/functions/write.md +172 -0
  85. package/docs/modules/rust/kb-worker/module.md +171 -0
  86. package/docs/modules/rust/kb-worker/types/cache.md +90 -0
  87. package/docs/modules/rust/kb-worker/types/context.md +26 -0
  88. package/docs/modules/rust/kb-worker/types/module.md +16 -0
  89. package/docs/modules/rust/kb-worker/types/status.md +29 -0
  90. package/docs/modules/rust/kb-worker/types/token.md +50 -0
  91. package/docs/modules/rust/overview.md +495 -0
  92. package/docs/modules/rust/query-parser/functions/extract.md +56 -0
  93. package/docs/modules/rust/query-parser/functions/module.md +16 -0
  94. package/docs/modules/rust/query-parser/functions/parse.md +33 -0
  95. package/docs/modules/rust/query-parser/functions/pipeline.md +103 -0
  96. package/docs/modules/rust/query-parser/functions/rank.md +85 -0
  97. package/docs/modules/rust/query-parser/module.md +136 -0
  98. package/docs/modules/rust/query-parser/types/cache.md +39 -0
  99. package/docs/modules/rust/query-parser/types/keyphrase.md +60 -0
  100. package/docs/modules/rust/query-parser/types/module.md +17 -0
  101. package/docs/modules/rust/query-parser/types/token.md +42 -0
  102. package/docs/modules/rust/shared/content-composer/functions.md +114 -0
  103. package/docs/modules/rust/shared/content-composer/module.md +147 -0
  104. package/docs/modules/rust/shared/content-composer/types.md +93 -0
  105. package/docs/modules/rust/shared/content-parser/functions.md +72 -0
  106. package/docs/modules/rust/shared/content-parser/module.md +99 -0
  107. package/docs/modules/rust/shared/content-parser/types.md +71 -0
  108. package/docs/modules/rust/shared/corpus/module.md +24 -0
  109. package/docs/modules/rust/shared/corpus/types.md +141 -0
  110. package/docs/modules/rust/shared/document/module.md +25 -0
  111. package/docs/modules/rust/shared/document/types.md +154 -0
  112. package/docs/modules/rust/shared/encode/module.md +22 -0
  113. package/docs/modules/rust/shared/encode/traits.md +304 -0
  114. package/docs/modules/rust/shared/error/module.md +28 -0
  115. package/docs/modules/rust/shared/error/types.md +302 -0
  116. package/docs/modules/rust/shared/kbid/module.md +24 -0
  117. package/docs/modules/rust/shared/kbid/types.md +147 -0
  118. package/docs/modules/rust/shared/memory/functions.md +209 -0
  119. package/docs/modules/rust/shared/memory/module.md +24 -0
  120. package/docs/modules/rust/shared/module.md +168 -0
  121. package/docs/modules/rust/shared/query/module.md +27 -0
  122. package/docs/modules/rust/shared/query/types.md +236 -0
  123. package/docs/modules/rust/shared/section/module.md +25 -0
  124. package/docs/modules/rust/shared/section/types.md +294 -0
  125. package/docs/modules/rust/shared/term/module.md +25 -0
  126. package/docs/modules/rust/shared/term/types.md +139 -0
  127. package/docs/modules/typescript/cli.md +129 -0
  128. package/docs/modules/typescript/kbdb-worker.md +135 -0
  129. package/docs/modules/typescript/overview.md +378 -0
  130. package/docs/modules/typescript/shared/cli/constants.md +23 -0
  131. package/docs/modules/typescript/shared/cli/functions.md +630 -0
  132. package/docs/modules/typescript/shared/cli/module.md +125 -0
  133. package/docs/modules/typescript/shared/cli/typings.md +172 -0
  134. package/docs/modules/typescript/shared/hash/functions.md +20 -0
  135. package/docs/modules/typescript/shared/hash/module.md +21 -0
  136. package/docs/modules/typescript/shared/mcp/classes.md +179 -0
  137. package/docs/modules/typescript/shared/mcp/functions.md +386 -0
  138. package/docs/modules/typescript/shared/mcp/module.md +160 -0
  139. package/docs/modules/typescript/shared/mcp/typings.md +522 -0
  140. package/docs/modules/typescript/shared/module.md +94 -0
  141. package/docs/modules/typescript/shared/platform/functions.md +42 -0
  142. package/docs/modules/typescript/shared/platform/module.md +25 -0
  143. package/docs/modules/typescript/shared/runtime/functions.md +26 -0
  144. package/docs/modules/typescript/shared/runtime/module.md +27 -0
  145. package/docs/modules/typescript/shared/runtime/typings.md +13 -0
  146. package/docs/modules/typescript/shared/version/module.md +27 -0
  147. package/docs/modules/typescript/shared/wasm-codec/functions.md +391 -0
  148. package/docs/modules/typescript/shared/wasm-codec/module.md +98 -0
  149. package/docs/modules/typescript/shared/worker-client/classes.md +264 -0
  150. package/docs/modules/typescript/shared/worker-client/functions.md +175 -0
  151. package/docs/modules/typescript/shared/worker-client/module.md +84 -0
  152. package/docs/modules/typescript/shared/worker-client/typings.md +508 -0
  153. package/docs/modules/typescript/shared/worker-daemon/classes.md +239 -0
  154. package/docs/modules/typescript/shared/worker-daemon/constants.md +37 -0
  155. package/docs/modules/typescript/shared/worker-daemon/functions.md +221 -0
  156. package/docs/modules/typescript/shared/worker-daemon/module.md +112 -0
  157. package/docs/modules/typescript/shared/worker-daemon/typings.md +126 -0
  158. package/docs/overview.md +188 -0
  159. package/docs/release-notes/0.1.0.md +189 -0
  160. package/docs/release-notes/0.1.1.md +46 -0
  161. package/docs/release-notes/0.1.2.md +38 -0
  162. package/docs/release-notes/0.1.3.md +42 -0
  163. package/docs/release-notes/0.2.0.md +147 -0
  164. package/docs/release-notes/README.md +9 -0
  165. package/mod.ts +26 -0
  166. package/package.json +8 -2
  167. package/src/cli.ts +9 -0
  168. package/src/shared/cli/functions/dispatch-command.function.ts +3 -3
  169. package/src/shared/cli/functions/format-output.function.ts +41 -34
  170. package/src/shared/cli/functions/parse-args.function.ts +7 -0
  171. package/src/shared/cli/functions/run-search.function.ts +53 -27
  172. package/src/shared/cli/index.ts +4 -1
  173. package/src/shared/cli/typings/cli-options.interface.ts +2 -0
  174. package/src/shared/cli/typings/search-display.model.ts +26 -7
  175. package/src/shared/mcp/functions/create-tool-definitions.function.ts +64 -4
  176. package/src/shared/mcp/functions/handle-recall.function.ts +66 -0
  177. package/src/shared/mcp/functions/handle-tool-call.function.ts +11 -1
  178. package/src/shared/mcp/typings/mcp-client.interface.ts +33 -15
  179. package/src/shared/version/constants/version.constant.ts +1 -1
  180. package/src/shared/wasm-codec/functions/decode-recall-result.function.ts +267 -0
  181. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +81 -27
  182. package/src/shared/wasm-codec/functions/encode-recall-params.function.ts +68 -0
  183. package/src/shared/wasm-codec/functions/encode-search-params.function.ts +4 -1
  184. package/src/shared/wasm-codec/index.ts +11 -3
  185. package/src/shared/worker-client/classes/worker-client.class.ts +24 -4
  186. package/src/shared/worker-client/index.ts +11 -1
  187. package/src/shared/worker-client/typings/recall-result.model.ts +98 -0
  188. package/src/shared/worker-client/typings/search-params.model.ts +2 -0
  189. package/src/shared/worker-client/typings/search-result.model.ts +24 -7
  190. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +25 -4
  191. package/src/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  192. package/src/wasm/fs-database/kbdb_fs_database.js +30 -0
  193. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  194. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  195. package/src/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  196. package/src/wasm/kb-worker/kbdb_worker.js +56 -0
  197. package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  198. package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
  199. package/src/worker.ts +8 -0
@@ -0,0 +1,124 @@
1
+ # Goals Overview
2
+
3
+ *Design goals and behavioral specifications for every
4
+ major subsystem in @dikolab/kbdb.*
5
+
6
+ ## Purpose
7
+
8
+ The goal documents describe the **intended behavior**
9
+ of each subsystem -- what it should do, how it should
10
+ respond, and what constraints it operates under. They
11
+ serve as implementation specifications, not
12
+ descriptions of current functionality.
13
+
14
+ ## AI-Agent-First Design Principle
15
+
16
+ kbdb exists to provide useful context to AI agents.
17
+ Every interface decision is evaluated by a single
18
+ criterion: can an AI agent, seeing this response
19
+ for the first time, make a relevance judgment and
20
+ answer the user's question without additional
21
+ round trips?
22
+
23
+ This principle drives three concrete rules:
24
+
25
+ 1. **Search results are self-describing.** Every
26
+ result includes a snippet, heading, section type,
27
+ and source document identifiers -- enough for the
28
+ agent to judge relevance from the result list
29
+ alone, without fetching each section individually.
30
+
31
+ 2. **Progressive drill-down over batch fetching.**
32
+ The `recall` tool lets the agent expand context
33
+ incrementally -- first the section, then its
34
+ parent document, then siblings and references --
35
+ rather than forcing a choice between "fetch
36
+ nothing" and "fetch everything."
37
+
38
+ 3. **Rank order is the signal.** Internal scoring
39
+ details (BM25F coefficients, raw term
40
+ frequencies) are implementation concerns, not
41
+ agent-facing data. Results are ordered by
42
+ relevance; the agent reads them in order.
43
+
44
+ ## Architecture
45
+
46
+ The system is organized in five layers. Data flows
47
+ downward from user commands or agent requests through
48
+ the worker client and daemon into the WASM engine,
49
+ which performs heavy processing and manages the file
50
+ database.
51
+
52
+ ![System Architecture](architecture.svg)
53
+
54
+ ## Goal Documents
55
+
56
+ ### WASM Engine
57
+
58
+ - **[Database](database.md)** -- Filesystem storage
59
+ engine (`fs-database.wasm`). The `.kbdb` directory
60
+ structure, section and document CRUD operations,
61
+ index management, and storage design.
62
+ - **[Query Parser](query-parser.md)** -- Query
63
+ processing and tokenization (`query-parser.wasm`).
64
+ Standalone WASM module for tokenization, query
65
+ parsing, keyword extraction, and ranking.
66
+ - **[Document](document.md)** -- Text content format
67
+ specification. Markdown body text with embedding
68
+ markers and cross-reference link markers.
69
+ - **[Content Parser](content-parser.md)** -- Marker
70
+ extraction engine (`kbdb-shared` rlib). Scans
71
+ section content for `$(type: value)` markers and
72
+ returns structured reference lists.
73
+ - **[Content Composer](content-composer.md)** --
74
+ Content composition engine (`kbdb-shared` rlib).
75
+ Resolves sections and markers, produces rendered
76
+ Markdown documents from kbid and docid identifiers.
77
+ - **[Query Result](query-result.md)** -- Ranking and
78
+ result ordering specification. BM25F scoring with
79
+ per-field term frequencies, proximity and zone
80
+ boosts, score combination, result modes, and
81
+ pre-computed indexing data.
82
+
83
+ ### TypeScript Layer
84
+
85
+ - **[CLI](cli.md)** -- The `kbdb` command and its two
86
+ run modes. CLI mode commands (`learn`, `unlearn`,
87
+ `search`, `content`, `check`, `gc`, `rebuild`),
88
+ MCP mode dispatch, output formats, and the
89
+ pass-through execution model.
90
+ - **[MCP](mcp.md)** -- MCP server mode (`kbdb mcp`).
91
+ Invocation, database path configuration, stdio
92
+ transport, MCP tools (search, recall, retrieve,
93
+ content, learn, unlearn, and more), resources,
94
+ agent wiring examples, and relationship to CLI
95
+ mode.
96
+ - **[Worker Daemon](worker-daemon.md)** -- Cache
97
+ daemon (`kb-worker.wasm` + `src/worker.ts`).
98
+ The detached TypeScript daemon, WASM module loading,
99
+ caching, IPC protocol, lifecycle, and configuration.
100
+ - **[Worker Client](worker-client.md)** -- Shared
101
+ TypeScript client module (`src/shared/worker-client/`).
102
+ Daemon discovery, spawning, IPC connection, typed
103
+ API, and the sole entry point used by `src/cli.ts`.
104
+
105
+ ## Implementation Guide
106
+
107
+ The modules documentation describes **how** the goals
108
+ above are implemented -- crate and module structure,
109
+ file layout, build pipeline, and coding conventions
110
+ for both the Rust engine and the TypeScript layer.
111
+
112
+ - **[Modules Overview](../modules/overview.md)** --
113
+ Full build pipeline. How Rust compiles to WASM,
114
+ lands in the TypeScript source tree, and gets
115
+ bundled into `dist/`. Start here.
116
+ - **[Rust/WASM Modules](../modules/rust/overview.md)**
117
+ -- Cargo workspace, 4 crates, module namespaces,
118
+ WASM exports/imports, size optimization, and
119
+ testing.
120
+ - **[TypeScript Modules](../modules/typescript/overview.md)**
121
+ -- 2 entry points (`src/cli.ts`,
122
+ `src/worker.ts`), 8 shared sub-modules, file
123
+ conventions, dual-runtime constraints, and esbuild
124
+ bundling.
@@ -0,0 +1,271 @@
1
+ # Query Parser -- Query Processing and Tokenization
2
+
3
+ *A shared WASM module that provides tokenization, query
4
+ parsing, and term normalization for the knowledge base
5
+ system.*
6
+
7
+ ## Goal
8
+
9
+ The query parser module (`query-parser.wasm`) provides the core text
10
+ processing capabilities shared across the knowledge base
11
+ system. It handles:
12
+
13
+ - Tokenizing input text into normalized terms.
14
+ - Parsing search queries into structured query plans.
15
+ - Normalizing and stemming terms for consistent indexing
16
+ and matching.
17
+ - Maintaining a query-scoped cache for intermediate
18
+ results during query processing.
19
+
20
+ The query parser is a pure computation module with no file I/O
21
+ and no host dependencies beyond shared memory. It is
22
+ imported by `kb-worker.wasm`, which orchestrates query
23
+ processing and content indexing by combining the
24
+ query parser's text analysis with `fs-database.wasm`'s
25
+ storage operations.
26
+
27
+ ## WASM Module: query-parser.wasm
28
+
29
+ ### Dependency Position
30
+
31
+ ```
32
+ query-parser.wasm fs-database.wasm
33
+ (standalone) (standalone)
34
+ ↑ ↑
35
+ └───────┬───────────┘
36
+ |
37
+ kb-worker.wasm
38
+ (imports both, orchestrates)
39
+ ```
40
+
41
+ `query-parser.wasm` is a standalone module. It imports
42
+ nothing from other WASM modules and depends only on
43
+ host-provided memory. `kb-worker.wasm` imports its
44
+ exports to drive tokenization, query parsing, and
45
+ ranking.
46
+
47
+ ### Host Imports
48
+
49
+ | Import | Description |
50
+ |----------|-------------------------------------|
51
+ | `memory` | Shared `WebAssembly.Memory` for passing strings and buffers between modules |
52
+
53
+ No file I/O, no network, no timers. The module is pure
54
+ computation.
55
+
56
+ ### Exports
57
+
58
+ Functions exported by `query-parser.wasm` for use by other
59
+ WASM modules and the TypeScript host:
60
+
61
+ | Export | Description |
62
+ |------------------|------------------------------------|
63
+ | `tokenize` | Tokenize input text into an array of normalized tokens |
64
+ | `parse_query` | Parse a query string into a structured query plan |
65
+ | `normalize_term` | Normalize a single term (case fold, stem) |
66
+ | `stem` | Stem a single term to its root form |
67
+ | `alloc` / `free` | Memory management for shared buffer allocation |
68
+
69
+ All functions operate on the shared
70
+ `WebAssembly.Memory`. String arguments and return values
71
+ are passed as `(pointer, length)` pairs into the shared
72
+ memory buffer.
73
+
74
+ ## Tokenization Pipeline
75
+
76
+ The query parser provides a multi-stage tokenization
77
+ pipeline used for both indexing (when content is added
78
+ via `kbdb learn`) and query processing (when
79
+ searching). Using the same pipeline for both ensures
80
+ that indexed terms match query terms consistently.
81
+
82
+ The pipeline processes **text and code content**.
83
+ Image sections (`image/*` type) have their binary
84
+ content skipped, but their `title` and `description`
85
+ attributes are tokenized through this pipeline.
86
+
87
+ Code sections (`text/*` and `application/json`) are
88
+ processed through the same pipeline as text sections.
89
+ The identifier splitting stage (stage 4) handles
90
+ camelCase and snake_case decomposition common in
91
+ source code.
92
+
93
+ During indexing, the pipeline runs **per field** for
94
+ each section: title content produces heading-field
95
+ terms, body text and description produce body-field
96
+ terms, and code content produces code-field terms.
97
+ Per-field term frequencies are stored separately in
98
+ the inverted index, enabling BM25F field weights to
99
+ be tuned at query time without rebuilding indexes.
100
+
101
+ Stages:
102
+
103
+ 1. **Marker stripping** -- Remove all six marker
104
+ types from the input text before tokenization:
105
+ `$(image:)`, `$(code:)`, `$(text:)`,
106
+ `$(document:)`, `$(link:)`, and `$(doc-link:)`.
107
+ These are structural references, not searchable
108
+ content. The `strip_content_markers()` function is
109
+ imported from `kbdb-shared` (see
110
+ [Content Parser](content-parser.md) and
111
+ [Document](document.md)).
112
+ 2. **Unicode normalization** (NFC).
113
+ 3. **Word boundary detection** (Unicode Segmentation).
114
+ 4. **Identifier splitting** (camelCase, snake_case
115
+ decomposition).
116
+ 5. **Case folding** (lowercase).
117
+ 6. **Stop word removal** (configurable list).
118
+ 7. **Stemming** (Snowball / Porter2 -- stores both
119
+ stemmed and original forms).
120
+ 8. **N-gram extraction** (bigrams, trigrams for phrase
121
+ indexing and multi-word term matching).
122
+
123
+ `kb-worker.wasm` calls the tokenization pipeline for
124
+ both indexing (when content is added via `kbdb learn`)
125
+ and search (when a query is submitted). It feeds the
126
+ tokenized output to `fs-database.wasm` for index
127
+ storage or index lookups as needed.
128
+
129
+ ## Query Parsing
130
+
131
+ Search queries are parsed into a structured query plan
132
+ -- a data retrieval strategy that describes which terms
133
+ to look up, how to combine them, and what to exclude.
134
+ `kb-worker.wasm` feeds this plan to `fs-database.wasm`
135
+ to execute index lookups.
136
+
137
+ Parsing stages:
138
+
139
+ 1. **Tokenize** -- Run the query text through the
140
+ tokenization pipeline.
141
+ 2. **Parse syntax** -- Recognize query operators: exact
142
+ phrases (`"..."`), boolean AND/OR, and term exclusion
143
+ (`-term`).
144
+ 3. **Build query plan** -- Produce a structured plan
145
+ containing: a list of terms to match, phrase groups,
146
+ exclusions, and match mode.
147
+
148
+ The query plan is the query parser's output --
149
+ `kb-worker.wasm` receives it and passes it to
150
+ `fs-database.wasm` for index lookups, then calls the
151
+ query parser's ranking functions to score and order the raw
152
+ results.
153
+
154
+ ## Query Cache
155
+
156
+ During query processing, the query parser maintains a
157
+ short-lived cache scoped to a single query's lifetime.
158
+ This cache holds:
159
+
160
+ - **Tokenized terms** -- Avoids re-tokenizing duplicate
161
+ terms within the same query.
162
+ - **Stemmed forms** -- Avoids re-stemming the same root
163
+ across query terms.
164
+ - **Parsed sub-expressions** -- Reuses parsed structures
165
+ for repeated patterns.
166
+
167
+ The cache exists only for the duration of one query
168
+ processing cycle. It is allocated when query processing
169
+ begins and discarded immediately after the query plan is
170
+ returned. It is not persisted, not shared across
171
+ queries, and not visible to other modules.
172
+
173
+ This prevents redundant computation when a query
174
+ contains repeated terms or when the same term appears in
175
+ different syntactic positions.
176
+
177
+ ## Keyword Extraction
178
+
179
+ When text content is added to the knowledge base, the
180
+ query parser extracts searchable terms from the raw
181
+ text. `kb-worker.wasm` calls the query parser's
182
+ tokenization exports and then applies the statistical
183
+ extraction pipeline to produce terms and weights,
184
+ which it passes to `fs-database.wasm` for index
185
+ storage.
186
+
187
+ Code sections (`text/*` and `application/json`) are
188
+ processed through the keyword extraction pipeline.
189
+ Their content is tokenized and weighted the same way
190
+ as text sections -- the identifier splitting stage
191
+ handles code-specific patterns (camelCase,
192
+ snake_case).
193
+
194
+ Image sections (`image/*` type) have their binary
195
+ content skipped by the keyword extraction pipeline --
196
+ base64-encoded data produces no searchable terms.
197
+ However, their `title` (required) and `description`
198
+ (optional) attributes are tokenized and indexed
199
+ through the same per-field pipeline, making image
200
+ sections searchable via their metadata. See
201
+ [Query Result](query-result.md) for field weight
202
+ details.
203
+
204
+ ### Statistical Keyword Extraction
205
+
206
+ Extract candidate keywords and keyphrases using
207
+ statistical methods that do not require training data or
208
+ external models:
209
+
210
+ - **RAKE** (Rapid Automatic Keyword Extraction) --
211
+ Splits on stop words, scores candidates by word
212
+ degree / frequency ratio.
213
+ - **N-gram scoring** -- Bigrams and trigrams scored by
214
+ co-occurrence frequency.
215
+
216
+ The extraction method is unsupervised and implemented
217
+ in pure Rust without ML dependencies.
218
+
219
+ ### Term Weighting
220
+
221
+ - Compute **per-field term frequency** (TF) -- term
222
+ frequencies are computed separately for each BM25F
223
+ field: heading (from title), body (from body text +
224
+ description), and code (from code content).
225
+ - Compute corpus-wide **term rarity** (IDF -- how
226
+ uncommon a term is across all stored sections).
227
+ - Combine frequency and rarity into per-field weights
228
+ that reflect each term's discriminative value for
229
+ search (TF-IDF).
230
+
231
+ `kb-worker.wasm` passes the per-field term
232
+ frequencies to `fs-database.wasm` for storage in the
233
+ inverted index as separate `heading_tf`, `body_tf`,
234
+ and `code_tf` values per posting entry. It also
235
+ passes per-field token counts for storage in the
236
+ section header. These pre-computed values are
237
+ retrieved during search and fed to the query parser's
238
+ ranking functions. See [Database](database.md) for
239
+ the storage format.
240
+
241
+ ## Ranking
242
+
243
+ The query parser provides ranking functions that
244
+ `kb-worker.wasm` calls after retrieving raw index
245
+ results from `fs-database.wasm` to order results by
246
+ relevance. See [Query Result](query-result.md) for
247
+ the full ranking specification including scoring
248
+ formulas, field weight mapping, and pre-computed data.
249
+
250
+ - **BM25F** (Field-Weighted Okapi BM25) -- Primary
251
+ ranking function. Probabilistic scoring with
252
+ per-field term frequencies and field weights
253
+ (heading 2.0x, body 1.0x, code 1.5x). Field
254
+ weights are applied at query time using the stored
255
+ per-field TFs, making them tunable without index
256
+ rebuilds.
257
+ - **Proximity scoring** -- Supplementary signal. Boosts
258
+ sections where query terms appear close together.
259
+ - **Zone scoring** -- Structural weighting. Terms in
260
+ the first ~20% of a section (heading zone) weighted
261
+ higher than mid-body text. Uses the pre-computed
262
+ `token_count` to determine the zone boundary.
263
+ - **Freshness weighting** -- Optional boost based on
264
+ insertion timestamps.
265
+
266
+ ## Rust Crates
267
+
268
+ | Crate | Role |
269
+ |------------------------|-------------------------------|
270
+ | `unicode-segmentation` | Word boundary detection |
271
+ | `rust-stemmers` | Snowball / Porter2 stemmer |