@dikolab/kbdb 0.1.5 → 0.2.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 (193) 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.mjs +13 -2
  11. package/dist/mod.mjs.map +2 -2
  12. package/dist/src/shared/cli/functions/format-output.function.d.ts +7 -7
  13. package/dist/src/shared/cli/functions/run-search.function.d.ts +25 -16
  14. package/dist/src/shared/cli/index.d.ts +1 -1
  15. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +2 -0
  16. package/dist/src/shared/cli/typings/search-display.model.d.ts +25 -7
  17. package/dist/src/shared/mcp/functions/handle-recall.function.d.ts +29 -0
  18. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +30 -11
  19. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  20. package/dist/src/shared/wasm-codec/functions/decode-recall-result.function.d.ts +28 -0
  21. package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +14 -7
  22. package/dist/src/shared/wasm-codec/functions/encode-recall-params.function.d.ts +21 -0
  23. package/dist/src/shared/wasm-codec/functions/encode-search-params.function.d.ts +1 -1
  24. package/dist/src/shared/wasm-codec/index.d.ts +5 -2
  25. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +13 -3
  26. package/dist/src/shared/worker-client/index.d.ts +2 -1
  27. package/dist/src/shared/worker-client/typings/recall-result.model.d.ts +94 -0
  28. package/dist/src/shared/worker-client/typings/search-params.model.d.ts +2 -0
  29. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +23 -7
  30. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +1 -0
  31. package/dist/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  32. package/dist/wasm/fs-database/kbdb_fs_database.js +30 -0
  33. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  34. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  35. package/dist/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  36. package/dist/wasm/kb-worker/kbdb_worker.js +56 -0
  37. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  38. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
  39. package/dist/worker.mjs +283 -29
  40. package/dist/worker.mjs.map +4 -4
  41. package/docs/details/README.md +26 -0
  42. package/docs/details/cli.md +608 -0
  43. package/docs/details/library-api.md +406 -0
  44. package/docs/details/mcp-server.md +430 -0
  45. package/docs/details/search-and-ranking.md +457 -0
  46. package/docs/details/storage.md +529 -0
  47. package/docs/goals/agents.md +751 -0
  48. package/docs/goals/architecture.svg +198 -0
  49. package/docs/goals/cli.md +2308 -0
  50. package/docs/goals/content-composer.md +609 -0
  51. package/docs/goals/content-parser.md +279 -0
  52. package/docs/goals/database.md +1452 -0
  53. package/docs/goals/document.md +368 -0
  54. package/docs/goals/mcp.md +1467 -0
  55. package/docs/goals/overview.md +124 -0
  56. package/docs/goals/query-parser.md +271 -0
  57. package/docs/goals/query-result.md +693 -0
  58. package/docs/goals/skills.md +738 -0
  59. package/docs/goals/worker-client.md +944 -0
  60. package/docs/goals/worker-daemon.md +1447 -0
  61. package/docs/modules/overview.md +298 -0
  62. package/docs/modules/rust/fs-database/functions/document.md +48 -0
  63. package/docs/modules/rust/fs-database/functions/integrity.md +68 -0
  64. package/docs/modules/rust/fs-database/functions/io.md +87 -0
  65. package/docs/modules/rust/fs-database/functions/module.md +22 -0
  66. package/docs/modules/rust/fs-database/functions/query-exec.md +44 -0
  67. package/docs/modules/rust/fs-database/functions/section.md +59 -0
  68. package/docs/modules/rust/fs-database/indexes/btree.md +35 -0
  69. package/docs/modules/rust/fs-database/indexes/corpus.md +61 -0
  70. package/docs/modules/rust/fs-database/indexes/inverted.md +60 -0
  71. package/docs/modules/rust/fs-database/indexes/module.md +64 -0
  72. package/docs/modules/rust/fs-database/indexes/positional.md +39 -0
  73. package/docs/modules/rust/fs-database/module.md +149 -0
  74. package/docs/modules/rust/fs-database/types/catalog.md +53 -0
  75. package/docs/modules/rust/fs-database/types/module.md +12 -0
  76. package/docs/modules/rust/fs-database/types/section.md +101 -0
  77. package/docs/modules/rust/kb-worker/functions/compose.md +57 -0
  78. package/docs/modules/rust/kb-worker/functions/module.md +20 -0
  79. package/docs/modules/rust/kb-worker/functions/retrieve.md +194 -0
  80. package/docs/modules/rust/kb-worker/functions/search.md +173 -0
  81. package/docs/modules/rust/kb-worker/functions/write.md +172 -0
  82. package/docs/modules/rust/kb-worker/module.md +171 -0
  83. package/docs/modules/rust/kb-worker/types/cache.md +90 -0
  84. package/docs/modules/rust/kb-worker/types/context.md +26 -0
  85. package/docs/modules/rust/kb-worker/types/module.md +16 -0
  86. package/docs/modules/rust/kb-worker/types/status.md +29 -0
  87. package/docs/modules/rust/kb-worker/types/token.md +50 -0
  88. package/docs/modules/rust/overview.md +495 -0
  89. package/docs/modules/rust/query-parser/functions/extract.md +56 -0
  90. package/docs/modules/rust/query-parser/functions/module.md +16 -0
  91. package/docs/modules/rust/query-parser/functions/parse.md +33 -0
  92. package/docs/modules/rust/query-parser/functions/pipeline.md +103 -0
  93. package/docs/modules/rust/query-parser/functions/rank.md +85 -0
  94. package/docs/modules/rust/query-parser/module.md +136 -0
  95. package/docs/modules/rust/query-parser/types/cache.md +39 -0
  96. package/docs/modules/rust/query-parser/types/keyphrase.md +60 -0
  97. package/docs/modules/rust/query-parser/types/module.md +17 -0
  98. package/docs/modules/rust/query-parser/types/token.md +42 -0
  99. package/docs/modules/rust/shared/content-composer/functions.md +114 -0
  100. package/docs/modules/rust/shared/content-composer/module.md +147 -0
  101. package/docs/modules/rust/shared/content-composer/types.md +93 -0
  102. package/docs/modules/rust/shared/content-parser/functions.md +72 -0
  103. package/docs/modules/rust/shared/content-parser/module.md +99 -0
  104. package/docs/modules/rust/shared/content-parser/types.md +71 -0
  105. package/docs/modules/rust/shared/corpus/module.md +24 -0
  106. package/docs/modules/rust/shared/corpus/types.md +141 -0
  107. package/docs/modules/rust/shared/document/module.md +25 -0
  108. package/docs/modules/rust/shared/document/types.md +154 -0
  109. package/docs/modules/rust/shared/encode/module.md +22 -0
  110. package/docs/modules/rust/shared/encode/traits.md +304 -0
  111. package/docs/modules/rust/shared/error/module.md +28 -0
  112. package/docs/modules/rust/shared/error/types.md +302 -0
  113. package/docs/modules/rust/shared/kbid/module.md +24 -0
  114. package/docs/modules/rust/shared/kbid/types.md +147 -0
  115. package/docs/modules/rust/shared/memory/functions.md +209 -0
  116. package/docs/modules/rust/shared/memory/module.md +24 -0
  117. package/docs/modules/rust/shared/module.md +168 -0
  118. package/docs/modules/rust/shared/query/module.md +27 -0
  119. package/docs/modules/rust/shared/query/types.md +236 -0
  120. package/docs/modules/rust/shared/section/module.md +25 -0
  121. package/docs/modules/rust/shared/section/types.md +294 -0
  122. package/docs/modules/rust/shared/term/module.md +25 -0
  123. package/docs/modules/rust/shared/term/types.md +139 -0
  124. package/docs/modules/typescript/cli.md +129 -0
  125. package/docs/modules/typescript/kbdb-worker.md +135 -0
  126. package/docs/modules/typescript/overview.md +378 -0
  127. package/docs/modules/typescript/shared/cli/constants.md +23 -0
  128. package/docs/modules/typescript/shared/cli/functions.md +630 -0
  129. package/docs/modules/typescript/shared/cli/module.md +125 -0
  130. package/docs/modules/typescript/shared/cli/typings.md +172 -0
  131. package/docs/modules/typescript/shared/hash/functions.md +20 -0
  132. package/docs/modules/typescript/shared/hash/module.md +21 -0
  133. package/docs/modules/typescript/shared/mcp/classes.md +179 -0
  134. package/docs/modules/typescript/shared/mcp/functions.md +386 -0
  135. package/docs/modules/typescript/shared/mcp/module.md +160 -0
  136. package/docs/modules/typescript/shared/mcp/typings.md +522 -0
  137. package/docs/modules/typescript/shared/module.md +94 -0
  138. package/docs/modules/typescript/shared/platform/functions.md +42 -0
  139. package/docs/modules/typescript/shared/platform/module.md +25 -0
  140. package/docs/modules/typescript/shared/runtime/functions.md +26 -0
  141. package/docs/modules/typescript/shared/runtime/module.md +27 -0
  142. package/docs/modules/typescript/shared/runtime/typings.md +13 -0
  143. package/docs/modules/typescript/shared/version/module.md +27 -0
  144. package/docs/modules/typescript/shared/wasm-codec/functions.md +391 -0
  145. package/docs/modules/typescript/shared/wasm-codec/module.md +98 -0
  146. package/docs/modules/typescript/shared/worker-client/classes.md +264 -0
  147. package/docs/modules/typescript/shared/worker-client/functions.md +175 -0
  148. package/docs/modules/typescript/shared/worker-client/module.md +84 -0
  149. package/docs/modules/typescript/shared/worker-client/typings.md +508 -0
  150. package/docs/modules/typescript/shared/worker-daemon/classes.md +239 -0
  151. package/docs/modules/typescript/shared/worker-daemon/constants.md +37 -0
  152. package/docs/modules/typescript/shared/worker-daemon/functions.md +221 -0
  153. package/docs/modules/typescript/shared/worker-daemon/module.md +112 -0
  154. package/docs/modules/typescript/shared/worker-daemon/typings.md +126 -0
  155. package/docs/overview.md +188 -0
  156. package/docs/release-notes/0.1.0.md +189 -0
  157. package/docs/release-notes/0.1.1.md +46 -0
  158. package/docs/release-notes/0.1.2.md +38 -0
  159. package/docs/release-notes/0.1.3.md +42 -0
  160. package/docs/release-notes/0.2.0.md +147 -0
  161. package/docs/release-notes/README.md +9 -0
  162. package/package.json +8 -2
  163. package/src/shared/cli/functions/dispatch-command.function.ts +3 -3
  164. package/src/shared/cli/functions/format-output.function.ts +41 -34
  165. package/src/shared/cli/functions/parse-args.function.ts +7 -0
  166. package/src/shared/cli/functions/run-search.function.ts +53 -27
  167. package/src/shared/cli/index.ts +4 -1
  168. package/src/shared/cli/typings/cli-options.interface.ts +2 -0
  169. package/src/shared/cli/typings/search-display.model.ts +26 -7
  170. package/src/shared/mcp/functions/create-tool-definitions.function.ts +64 -4
  171. package/src/shared/mcp/functions/handle-recall.function.ts +66 -0
  172. package/src/shared/mcp/functions/handle-tool-call.function.ts +11 -1
  173. package/src/shared/mcp/typings/mcp-client.interface.ts +33 -15
  174. package/src/shared/version/constants/version.constant.ts +1 -1
  175. package/src/shared/wasm-codec/functions/decode-recall-result.function.ts +267 -0
  176. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +81 -27
  177. package/src/shared/wasm-codec/functions/encode-recall-params.function.ts +68 -0
  178. package/src/shared/wasm-codec/functions/encode-search-params.function.ts +4 -1
  179. package/src/shared/wasm-codec/index.ts +11 -3
  180. package/src/shared/worker-client/classes/worker-client.class.ts +24 -4
  181. package/src/shared/worker-client/index.ts +11 -1
  182. package/src/shared/worker-client/typings/recall-result.model.ts +98 -0
  183. package/src/shared/worker-client/typings/search-params.model.ts +2 -0
  184. package/src/shared/worker-client/typings/search-result.model.ts +24 -7
  185. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +25 -4
  186. package/src/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  187. package/src/wasm/fs-database/kbdb_fs_database.js +30 -0
  188. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  189. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  190. package/src/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  191. package/src/wasm/kb-worker/kbdb_worker.js +56 -0
  192. package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  193. package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
@@ -0,0 +1,302 @@
1
+ # types::error -- Error Types
2
+
3
+ *Hierarchical error enums shared across all three
4
+ WASM modules, mapping to JSON-RPC 2.0 error codes at
5
+ the IPC boundary.*
6
+
7
+ ## File
8
+
9
+ `engine/crates/shared/src/error/error.rs`
10
+
11
+ ## Overview
12
+
13
+ Errors originate in the standalone modules
14
+ (`fs-database`, `query-parser`) and propagate upward
15
+ through `kb-worker` to the TypeScript daemon, which
16
+ translates them into JSON-RPC 2.0 error responses.
17
+ Defining all error types in `kbdb-shared` ensures a
18
+ single hierarchy with consistent `From`
19
+ implementations across crate boundaries.
20
+
21
+ See [Worker Daemon -- Error Responses](
22
+ ../../../../../goals/worker-daemon.md) for the JSON-RPC
23
+ 2.0 error codes at the IPC boundary.
24
+
25
+ ## Error Hierarchy
26
+
27
+ ```
28
+ WorkerError (kb-worker.wasm -> TypeScript)
29
+ ├── Fs(FsError) (from fs-database.wasm)
30
+ ├── Index(IndexError) (from fs-database.wasm)
31
+ ├── Parse(ParseError) (from query-parser.wasm)
32
+ ├── CacheFull
33
+ ├── InvalidToken(String)
34
+ └── ContextMismatch { expected, actual }
35
+ ```
36
+
37
+ `WorkerError` is the top-level error returned by
38
+ `kb-worker.wasm` exports. It wraps lower-level
39
+ errors from the standalone modules.
40
+
41
+ ## Type Definitions
42
+
43
+ ### `FsError`
44
+
45
+ ```rust
46
+ #[derive(Debug)]
47
+ pub enum FsError {
48
+ NotFound(String),
49
+ PermissionDenied(String),
50
+ IoError(String),
51
+ ParseError(String),
52
+ ChecksumMismatch {
53
+ expected: String,
54
+ actual: String,
55
+ },
56
+ }
57
+ ```
58
+
59
+ Errors from `fs-database.wasm` file operations.
60
+
61
+ | Variant | Cause |
62
+ |--------------------|--------------------------------|
63
+ | `NotFound` | Section, document, or file path does not exist |
64
+ | `PermissionDenied` | Host I/O import returned permission error |
65
+ | `IoError` | Host I/O import returned generic error |
66
+ | `ParseError` | TOML header or catalog parsing failed |
67
+ | `ChecksumMismatch` | Section file content does not match its stored checksum |
68
+
69
+ `NotFound` carries the path or kb-id that was
70
+ requested. `ChecksumMismatch` carries both the
71
+ expected and actual checksum strings for diagnostics.
72
+
73
+ ### `IndexError`
74
+
75
+ ```rust
76
+ #[derive(Debug)]
77
+ pub enum IndexError {
78
+ Corrupted(String),
79
+ KeyNotFound(String),
80
+ }
81
+ ```
82
+
83
+ Errors from `fs-database.wasm` index operations.
84
+
85
+ | Variant | Cause |
86
+ |--------------|-----------------------------------|
87
+ | `Corrupted` | B+ tree structure is invalid, page size mismatch, or binary data is unreadable |
88
+ | `KeyNotFound`| Term not found in the inverted index (not necessarily an error -- a query for a term with no matches) |
89
+
90
+ `Corrupted` indicates the index files need a
91
+ rebuild. The daemon can recover by calling
92
+ `worker_rebuild_indexes`.
93
+
94
+ ### `ParseError`
95
+
96
+ ```rust
97
+ #[derive(Debug)]
98
+ pub enum ParseError {
99
+ InvalidSyntax(String),
100
+ EmptyQuery,
101
+ UnmatchedQuote(usize),
102
+ }
103
+ ```
104
+
105
+ Errors from `query-parser.wasm` query parsing.
106
+
107
+ | Variant | Cause |
108
+ |------------------|--------------------------------|
109
+ | `InvalidSyntax` | Unrecognized query operator or malformed expression |
110
+ | `EmptyQuery` | Query string is empty or contains only stop words |
111
+ | `UnmatchedQuote` | Opening `"` without a closing `"` -- carries the character position |
112
+
113
+ ### `WorkerError`
114
+
115
+ ```rust
116
+ #[derive(Debug)]
117
+ pub enum WorkerError {
118
+ Fs(FsError),
119
+ Index(IndexError),
120
+ Parse(ParseError),
121
+ CacheFull,
122
+ InvalidToken(String),
123
+ ContextMismatch {
124
+ expected: String,
125
+ actual: String,
126
+ },
127
+ }
128
+ ```
129
+
130
+ Top-level error returned by `kb-worker.wasm` exports.
131
+
132
+ | Variant | Cause |
133
+ |------------------|--------------------------------|
134
+ | `Fs(FsError)` | Storage operation failed |
135
+ | `Index(IndexError)` | Index operation failed |
136
+ | `Parse(ParseError)` | Query parsing failed |
137
+ | `CacheFull` | Cache limit reached and eviction failed (should not happen with LRU, but defensive) |
138
+ | `InvalidToken` | Result token does not exist or has expired |
139
+ | `ContextMismatch`| Request's `ctx` param does not match the daemon's context |
140
+
141
+ ## `From` Implementations
142
+
143
+ ```rust
144
+ impl From<FsError> for WorkerError {
145
+ fn from(e: FsError) -> Self {
146
+ WorkerError::Fs(e)
147
+ }
148
+ }
149
+
150
+ impl From<IndexError> for WorkerError {
151
+ fn from(e: IndexError) -> Self {
152
+ WorkerError::Index(e)
153
+ }
154
+ }
155
+
156
+ impl From<ParseError> for WorkerError {
157
+ fn from(e: ParseError) -> Self {
158
+ WorkerError::Parse(e)
159
+ }
160
+ }
161
+ ```
162
+
163
+ These conversions allow the `?` operator to propagate
164
+ errors naturally across module boundaries:
165
+
166
+ ```rust
167
+ fn search(...) -> Result<SearchResult, WorkerError> {
168
+ let plan = parse_query(query)?; // ParseError -> WorkerError
169
+ let raw = execute_plan(&plan)?; // IndexError -> WorkerError
170
+ let section = read_section(id)?; // FsError -> WorkerError
171
+ // ...
172
+ }
173
+ ```
174
+
175
+ ## JSON-RPC 2.0 Mapping
176
+
177
+ The TypeScript daemon maps `WorkerError` variants to
178
+ JSON-RPC 2.0 error codes:
179
+
180
+ | WorkerError variant | JSON-RPC code | JSON-RPC message |
181
+ |---------------------|---------------|----------------------|
182
+ | `Fs(NotFound)` | `-32000` | `"Not found"` |
183
+ | `Fs(PermissionDenied)` | `-32000` | `"Permission denied"`|
184
+ | `Fs(IoError)` | `-32000` | `"I/O error"` |
185
+ | `Fs(ParseError)` | `-32000` | `"Parse error"` |
186
+ | `Fs(ChecksumMismatch)` | `-32000` | `"Checksum mismatch"`|
187
+ | `Index(Corrupted)` | `-32000` | `"Index corrupted"` |
188
+ | `Index(KeyNotFound)`| `-32000` | `"Key not found"` |
189
+ | `Parse(InvalidSyntax)` | `-32000` | `"Invalid query syntax"` |
190
+ | `Parse(EmptyQuery)` | `-32000` | `"Empty query"` |
191
+ | `Parse(UnmatchedQuote)` | `-32000` | `"Unmatched quote"` |
192
+ | `CacheFull` | `-32000` | `"Cache full"` |
193
+ | `InvalidToken` | `-32002` | `"Invalid token"` |
194
+ | `ContextMismatch` | `-32001` | `"Context mismatch"` |
195
+
196
+ Codes `-32001` (context mismatch) and `-32002`
197
+ (invalid token) are application-specific codes
198
+ defined in the [Worker Daemon](
199
+ ../../../../../goals/worker-daemon.md) specification.
200
+ All other errors use the generic application error
201
+ code `-32000`.
202
+
203
+ ## Error Relay -- WASM to Host
204
+
205
+ WASM errors must reach the TypeScript process's
206
+ stderr before the WASM instance is cleaned up. The
207
+ relay sequence:
208
+
209
+ 1. A WASM export (`worker_init`, `worker_search`,
210
+ etc.) encounters an error and returns a
211
+ `WorkerError` via the shared memory return
212
+ convention (`set_return(ptr, len)` with the
213
+ `Encode`-serialized error).
214
+ 2. The TypeScript daemon **reads the error from
215
+ shared memory immediately** -- before any cleanup,
216
+ cache purge, or WASM teardown.
217
+ 3. The daemon deserializes the `WorkerError`, maps it
218
+ to the appropriate JSON-RPC error code and
219
+ human-readable message.
220
+ 4. **For IPC-connected errors:** The daemon sends the
221
+ JSON-RPC error response to the client over IPC,
222
+ then resumes normal operation (no teardown).
223
+ 5. **For fatal startup errors** (precondition failures
224
+ during `worker_init`): The daemon writes the error
225
+ message to **stderr**, then proceeds with shutdown
226
+ (purge cache -> remove PID file -> remove socket
227
+ -> exit). The WASM modules remain instantiated
228
+ until the error is fully read and relayed.
229
+
230
+ **Key invariant:** the TypeScript host always reads
231
+ and relays the WASM error before the WASM instance
232
+ is purged. No error is lost to premature cleanup.
233
+
234
+ ## Daemon-Level Error Codes
235
+
236
+ Beyond the WASM-origin error codes (`-32000` through
237
+ `-32002`), the daemon defines additional error codes
238
+ for startup and client-side failures:
239
+
240
+ | Code | Meaning | Origin | Relay path |
241
+ |----------|--------------------------------------|--------|------------|
242
+ | `-32001` | Context mismatch | WASM (`WorkerError::ContextMismatch`) | IPC response |
243
+ | `-32002` | Invalid token | WASM (`WorkerError::InvalidToken`) | IPC response |
244
+ | `-32003` | Daemon unavailable | Worker client (spawn failure) | `WorkerClientError` thrown to caller |
245
+ | `-32004` | Database directory not found | WASM `worker_init` or TS precondition | stderr -> `WorkerClientError.daemonStderr` |
246
+ | `-32005` | Database directory not accessible | WASM `worker_init` or TS precondition | stderr -> `WorkerClientError.daemonStderr` |
247
+ | `-32006` | Database version too new | WASM `worker_init` | stderr -> `WorkerClientError.daemonStderr` |
248
+ | `-32007` | Database version too old (needs migration) | WASM `worker_init` | stderr -> `WorkerClientError.daemonStderr` |
249
+
250
+ Codes `-32004` through `-32007` are startup errors.
251
+ They are never returned over IPC because the daemon
252
+ exits before creating the socket. The daemon writes
253
+ the error to stderr; the worker client captures
254
+ stderr during the spawn window and includes it in
255
+ `WorkerClientError.daemonStderr`. This relay ensures
256
+ the user sees the specific failure reason even though
257
+ the daemon runs as a separate detached process.
258
+
259
+ ## `Display` and `Error` Implementations
260
+
261
+ All error types implement `std::fmt::Display` and
262
+ `std::error::Error`:
263
+
264
+ ```rust
265
+ impl fmt::Display for FsError {
266
+ fn fmt(&self, f: &mut fmt::Formatter<'_>)
267
+ -> fmt::Result
268
+ {
269
+ match self {
270
+ Self::NotFound(p) =>
271
+ write!(f, "not found: {p}"),
272
+ Self::PermissionDenied(p) =>
273
+ write!(f, "permission denied: {p}"),
274
+ Self::IoError(msg) =>
275
+ write!(f, "I/O error: {msg}"),
276
+ Self::ParseError(msg) =>
277
+ write!(f, "parse error: {msg}"),
278
+ Self::ChecksumMismatch { expected, actual } =>
279
+ write!(
280
+ f,
281
+ "checksum mismatch: expected {expected}, got {actual}",
282
+ ),
283
+ }
284
+ }
285
+ }
286
+ ```
287
+
288
+ `WorkerError::source()` returns the wrapped inner
289
+ error for `Fs`, `Index`, and `Parse` variants,
290
+ enabling error chain inspection.
291
+
292
+ ## Testing
293
+
294
+ Unit tests:
295
+
296
+ - `From` conversions: each error type converts to
297
+ the correct `WorkerError` variant.
298
+ - `Display` formatting: each variant produces a
299
+ human-readable message.
300
+ - `source()` chain: `WorkerError::Fs(e).source()`
301
+ returns `Some(&e)`.
302
+ - All variants are `Debug`-printable without panic.
@@ -0,0 +1,24 @@
1
+ # kbid -- Content-Addressed Identifier
2
+
3
+ *Content-addressed 26-character section identifier
4
+ derived from SHA-256 hashing.*
5
+
6
+ ## Source
7
+
8
+ `engine/crates/shared/src/kbid/`
9
+
10
+ ## Responsibility
11
+
12
+ Defines the `KbId` newtype and its construction
13
+ methods. Every section in the knowledge base is
14
+ identified by a deterministic, collision-resistant,
15
+ URL-safe string derived from the section's content.
16
+
17
+ See [Database -- Sections](../../../../goals/database.md)
18
+ for the behavioral specification of content-
19
+ addressable storage.
20
+
21
+ ## Exports
22
+
23
+ - **[types.md](types.md)** -- `KbId` newtype,
24
+ `from_content`, `new`, `shard_prefix`, `KbIdError`.
@@ -0,0 +1,147 @@
1
+ # types::kbid -- Knowledge Base Section Identifier
2
+
3
+ *Newtype wrapper around the 26-character,
4
+ content-addressed section identifier used throughout
5
+ the system.*
6
+
7
+ ## File
8
+
9
+ `engine/crates/shared/src/kbid/kbid.rs`
10
+
11
+ ## Overview
12
+
13
+ Every section in the knowledge base is identified by
14
+ a **kb-id** -- a deterministic, collision-resistant,
15
+ URL-safe string derived from the SHA-256 hash of the
16
+ section's content. The `KbId` type encodes these
17
+ invariants at the type level so that raw strings
18
+ cannot be passed where a validated identifier is
19
+ expected.
20
+
21
+ See [Database -- Sections](../../../../../goals/database.md)
22
+ for the behavioral specification of content-
23
+ addressable storage.
24
+
25
+ ## Type Definition
26
+
27
+ ```rust
28
+ #[derive(Clone, Debug, PartialEq, Eq, Hash)]
29
+ pub struct KbId(String);
30
+ ```
31
+
32
+ The inner `String` is private. Construction goes
33
+ through `KbId::new` or `KbId::from_content`, both of
34
+ which validate or derive the identifier. This
35
+ prevents accidental construction from arbitrary
36
+ strings.
37
+
38
+ ## Construction
39
+
40
+ ### `KbId::from_content`
41
+
42
+ ```rust
43
+ impl KbId {
44
+ pub fn from_content(content: &[u8]) -> Self;
45
+ }
46
+ ```
47
+
48
+ Derives the kb-id from raw content bytes:
49
+
50
+ 1. Compute SHA-256 of `content`.
51
+ 2. Truncate the digest to 16 bytes (128 bits).
52
+ 3. Encode with base32 (Crockford variant, lowercase).
53
+ 4. Result: 26 alphanumeric characters.
54
+
55
+ For text and code sections, `content` is the raw
56
+ UTF-8 bytes. For image sections, `content` is the
57
+ base64-encoded string bytes (not raw binary), so
58
+ identical base64 input always produces the same
59
+ kb-id.
60
+
61
+ This function is infallible -- any byte slice
62
+ produces a valid kb-id.
63
+
64
+ ### `KbId::new`
65
+
66
+ ```rust
67
+ impl KbId {
68
+ pub fn new(s: &str) -> Result<Self, KbIdError>;
69
+ }
70
+ ```
71
+
72
+ Validates an existing identifier string:
73
+
74
+ - Must be exactly 26 characters.
75
+ - Must contain only lowercase alphanumeric characters
76
+ (`[a-z0-9]`).
77
+
78
+ Returns `KbIdError::InvalidLength` or
79
+ `KbIdError::InvalidCharacter` on failure.
80
+
81
+ ## Methods
82
+
83
+ ```rust
84
+ impl KbId {
85
+ pub fn as_str(&self) -> &str;
86
+
87
+ pub fn shard_prefix(&self) -> &str;
88
+ }
89
+ ```
90
+
91
+ ### `as_str`
92
+
93
+ Returns the inner string slice. Used when passing
94
+ the kb-id to I/O functions, serializers, or display.
95
+
96
+ ### `shard_prefix`
97
+
98
+ Returns the first two characters of the kb-id. Used
99
+ by `fs-database` to compute the hash-sharded
100
+ directory path: `sections/{prefix}/{kbid}.sec`.
101
+
102
+ ```rust
103
+ let id = KbId::from_content(b"hello");
104
+ assert_eq!(id.shard_prefix().len(), 2);
105
+ ```
106
+
107
+ ## Trait Implementations
108
+
109
+ | Trait | Purpose |
110
+ |--------------|----------------------------------|
111
+ | `Clone` | Cache entries need owned copies |
112
+ | `Debug` | Diagnostic output |
113
+ | `PartialEq` / `Eq` | Identity comparison |
114
+ | `Hash` | HashMap/HashSet keys (cache, index lookups) |
115
+ | `Display` | Formats as the raw 26-char string |
116
+ | `Encode` | Binary serialization for shared memory (see [encode](../encode/traits.md)) |
117
+
118
+ `Ord` / `PartialOrd` are **not** derived. Kb-ids
119
+ have no meaningful ordering -- they are content
120
+ hashes. If sorting is needed (e.g. deterministic
121
+ output), use `as_str()` for lexicographic comparison
122
+ explicitly.
123
+
124
+ ## Error Type
125
+
126
+ ```rust
127
+ #[derive(Debug)]
128
+ pub enum KbIdError {
129
+ InvalidLength(usize),
130
+ InvalidCharacter(char, usize),
131
+ }
132
+ ```
133
+
134
+ ## Testing
135
+
136
+ Unit tests:
137
+
138
+ - `from_content` produces 26-char lowercase
139
+ alphanumeric output for various inputs.
140
+ - Identical content always produces the same kb-id.
141
+ - Different content produces different kb-ids.
142
+ - `shard_prefix` returns the first two characters.
143
+ - `new` accepts valid 26-char strings.
144
+ - `new` rejects strings that are too short, too long,
145
+ or contain uppercase/special characters.
146
+ - `Encode` round-trip: encode then decode produces
147
+ an equal `KbId`.
@@ -0,0 +1,209 @@
1
+ # functions::alloc -- Allocator and Read/Write Helpers
2
+
3
+ *Allocator exports and shared-memory read/write
4
+ helpers for passing data between the TypeScript host
5
+ and WASM modules.*
6
+
7
+ ## File
8
+
9
+ `engine/crates/shared/src/memory/alloc.rs`
10
+
11
+ ## Overview
12
+
13
+ WASM modules and the TypeScript host share a single
14
+ `WebAssembly.Memory` buffer. All data exchange --
15
+ strings, byte slices, structured records -- passes
16
+ through this buffer using `(pointer, length)` pairs.
17
+ This module provides:
18
+
19
+ 1. **Allocator exports** (`kbdb_alloc`, `kbdb_free`)
20
+ that the TypeScript host calls to manage buffers.
21
+ 2. **Read helpers** that safely reconstruct Rust types
22
+ from raw memory pointers.
23
+ 3. **Write helpers** that serialize Rust types into
24
+ the shared buffer and return pointer/length pairs.
25
+
26
+ Every WASM module re-exports `kbdb_alloc` and
27
+ `kbdb_free` from this module so the host can allocate
28
+ memory in any module's address space.
29
+
30
+ ## Allocator Exports
31
+
32
+ ```rust
33
+ use std::alloc::{alloc, dealloc, Layout};
34
+
35
+ #[no_mangle]
36
+ pub extern "C" fn kbdb_alloc(size: u32) -> *mut u8 {
37
+ let layout = Layout::from_size_align(
38
+ size as usize, 1,
39
+ ).unwrap();
40
+ unsafe { alloc(layout) }
41
+ }
42
+
43
+ #[no_mangle]
44
+ pub extern "C" fn kbdb_free(
45
+ ptr: *mut u8, size: u32,
46
+ ) {
47
+ let layout = Layout::from_size_align(
48
+ size as usize, 1,
49
+ ).unwrap();
50
+ unsafe { dealloc(ptr, layout) }
51
+ }
52
+ ```
53
+
54
+ ### Usage from TypeScript
55
+
56
+ The TypeScript daemon uses this protocol to pass
57
+ data into WASM functions:
58
+
59
+ ```
60
+ 1. host calls kbdb_alloc(size) → ptr
61
+ 2. host writes bytes into memory at ptr
62
+ 3. host calls wasm_function(ptr, size)
63
+ 4. wasm reads from ptr
64
+ 5. host calls kbdb_free(ptr, size)
65
+ ```
66
+
67
+ For return values:
68
+
69
+ ```
70
+ 1. wasm calls kbdb_alloc(size) internally → ptr
71
+ 2. wasm writes result into ptr
72
+ 3. wasm returns (ptr, size) to host
73
+ 4. host reads bytes from memory at ptr
74
+ 5. host calls kbdb_free(ptr, size)
75
+ ```
76
+
77
+ ### Alignment
78
+
79
+ Alignment is `1` (byte-aligned). The data exchanged
80
+ is always byte streams (UTF-8 strings, binary
81
+ encoded structs). No multi-byte alignment is needed
82
+ at the allocation level -- the `Encode` trait handles
83
+ field alignment internally.
84
+
85
+ ### Null and Zero
86
+
87
+ `kbdb_alloc(0)` returns a non-null, dangling pointer
88
+ (per Rust's allocator contract). Callers must not
89
+ dereference zero-length allocations. `kbdb_free` with
90
+ size `0` is a no-op.
91
+
92
+ ## Read Helpers
93
+
94
+ Safe functions that reconstruct Rust types from raw
95
+ shared-memory pointers.
96
+
97
+ ```rust
98
+ pub unsafe fn read_str<'a>(
99
+ ptr: *const u8, len: u32,
100
+ ) -> &'a str;
101
+
102
+ pub unsafe fn read_bytes<'a>(
103
+ ptr: *const u8, len: u32,
104
+ ) -> &'a [u8];
105
+ ```
106
+
107
+ ### `read_str`
108
+
109
+ Interprets the byte range `[ptr, ptr + len)` as
110
+ UTF-8. Panics if the bytes are not valid UTF-8.
111
+
112
+ This is used for string arguments from the host
113
+ (file paths, query strings, MIME types). The host
114
+ always writes valid UTF-8 -- a panic here indicates
115
+ a host bug.
116
+
117
+ ### `read_bytes`
118
+
119
+ Returns the byte range `[ptr, ptr + len)` as a
120
+ slice. No UTF-8 validation. Used for binary data
121
+ (section content, encoded structs).
122
+
123
+ ## Write Helpers
124
+
125
+ Functions that serialize Rust types into the shared
126
+ buffer and return `(pointer, length)` pairs for the
127
+ caller to pass back to the host or another module.
128
+
129
+ ```rust
130
+ pub fn write_str(s: &str) -> (*const u8, u32);
131
+
132
+ pub fn write_bytes(data: &[u8]) -> (*const u8, u32);
133
+
134
+ pub fn write_encoded<T: Encode>(
135
+ value: &T,
136
+ ) -> (*const u8, u32);
137
+ ```
138
+
139
+ ### `write_str`
140
+
141
+ Allocates `s.len()` bytes via `kbdb_alloc`, copies
142
+ the UTF-8 bytes, and returns the pointer and length.
143
+ The caller (or host) is responsible for freeing the
144
+ allocation.
145
+
146
+ ### `write_bytes`
147
+
148
+ Same as `write_str` but for arbitrary byte slices.
149
+
150
+ ### `write_encoded`
151
+
152
+ Encodes `value` using the `Encode` trait (see
153
+ [encode](../encode/traits.md)), allocates a
154
+ buffer for the result, copies the encoded bytes, and
155
+ returns the pointer and length. Convenience wrapper
156
+ for returning structured data from WASM exports.
157
+
158
+ ## Return Value Convention
159
+
160
+ WASM functions can only return scalar values. For
161
+ functions that return variable-length data, the
162
+ convention is a **two-slot return buffer**:
163
+
164
+ ```rust
165
+ pub fn set_return(ptr: *const u8, len: u32);
166
+ pub fn get_return_ptr() -> *const u8;
167
+ pub fn get_return_len() -> u32;
168
+ ```
169
+
170
+ A pair of module-global slots holds the most recent
171
+ return value. The WASM export writes `(ptr, len)`
172
+ into the slots via `set_return`, returns a status
173
+ code (`0` for success, negative for error), and the
174
+ host reads the actual data via `get_return_ptr` and
175
+ `get_return_len`.
176
+
177
+ This avoids multi-value returns, which have uneven
178
+ support across WASM runtimes.
179
+
180
+ ## Safety
181
+
182
+ All read functions are `unsafe` because they
183
+ dereference raw pointers. The safety contract:
184
+
185
+ - `ptr` must point into the shared
186
+ `WebAssembly.Memory` buffer.
187
+ - `ptr + len` must not exceed the buffer's current
188
+ size.
189
+ - The memory region must not be freed or
190
+ reallocated while the returned reference is alive.
191
+
192
+ The write functions are safe -- they allocate fresh
193
+ buffers and copy data in.
194
+
195
+ ## Testing
196
+
197
+ Unit tests (native Rust, not WASM):
198
+
199
+ - `kbdb_alloc` + `kbdb_free` round-trip without
200
+ panic for various sizes (1, 256, 65536).
201
+ - `kbdb_alloc(0)` returns non-null.
202
+ - `write_str` + `read_str` round-trip preserves
203
+ content for ASCII, Unicode, and empty strings.
204
+ - `write_bytes` + `read_bytes` round-trip preserves
205
+ arbitrary byte sequences.
206
+ - `write_encoded` + `Encode::decode` round-trip for
207
+ sample types.
208
+ - Return value slots: `set_return` → `get_return_ptr`
209
+ / `get_return_len` retrieves the same values.
@@ -0,0 +1,24 @@
1
+ # memory -- Memory Management
2
+
3
+ *Allocator exports and shared-memory read/write
4
+ helpers for passing data between the TypeScript host
5
+ and WASM modules.*
6
+
7
+ ## Source
8
+
9
+ `engine/crates/shared/src/memory/`
10
+
11
+ ## Responsibility
12
+
13
+ Provides the shared-memory allocation protocol used
14
+ by all three WASM modules. Every WASM export that
15
+ exchanges variable-length data (strings, byte
16
+ slices, encoded structs) goes through this module's
17
+ allocator and read/write helpers.
18
+
19
+ ## Exports
20
+
21
+ - **[functions.md](functions.md)** -- `kbdb_alloc`,
22
+ `kbdb_free`, `read_str`, `read_bytes`, `write_str`,
23
+ `write_bytes`, `write_encoded`, `set_return`,
24
+ `get_return_ptr`, `get_return_len`.