@dikolab/kbdb 0.5.0 → 0.6.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 (224) hide show
  1. package/CLA.md +68 -0
  2. package/LICENSE +676 -12
  3. package/LICENSING.md +58 -0
  4. package/README.md +47 -24
  5. package/README.md.bak +320 -0
  6. package/dist/README.md +320 -0
  7. package/dist/{chunk-BJXEVALU.mjs → chunk-QLJ33C74.mjs} +44 -44
  8. package/dist/chunk-QLJ33C74.mjs.map +7 -0
  9. package/dist/cli.cjs +550 -232
  10. package/dist/cli.cjs.map +4 -4
  11. package/dist/cli.d.ts +0 -8
  12. package/dist/cli.mjs +483 -154
  13. package/dist/cli.mjs.map +4 -4
  14. package/dist/kbdb-worker.cjs +36 -5
  15. package/dist/kbdb-worker.cjs.map +3 -3
  16. package/dist/mod.cjs +89 -30
  17. package/dist/mod.cjs.map +4 -4
  18. package/dist/mod.mjs +88 -30
  19. package/dist/mod.mjs.map +4 -4
  20. package/dist/src/cli.d.ts +0 -8
  21. package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
  22. package/dist/src/shared/cli/constants/recfile-command-field-map.constant.d.ts +8 -0
  23. package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +21 -0
  24. package/dist/src/shared/cli/functions/compute-directory-level.function.d.ts +14 -0
  25. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -28
  26. package/dist/src/shared/cli/functions/format-command-output.function.d.ts +14 -0
  27. package/dist/src/shared/cli/functions/format-db-not-found.function.d.ts +20 -0
  28. package/dist/src/shared/cli/functions/format-output.function.d.ts +1 -0
  29. package/dist/src/shared/cli/functions/format-recfile-output.function.d.ts +11 -0
  30. package/dist/src/shared/cli/functions/render-recfile-value.function.d.ts +11 -0
  31. package/dist/src/shared/cli/functions/resolve-db-dir.function.d.ts +24 -0
  32. package/dist/src/shared/cli/functions/resolve-recfile-key.function.d.ts +9 -0
  33. package/dist/src/shared/cli/functions/run-db-path.function.d.ts +10 -0
  34. package/dist/src/shared/cli/functions/run-export.function.d.ts +8 -4
  35. package/dist/src/shared/cli/functions/run-import.function.d.ts +4 -0
  36. package/dist/src/shared/cli/functions/run-learn.function.d.ts +12 -0
  37. package/dist/src/shared/cli/index.d.ts +4 -1
  38. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +9 -2
  39. package/dist/src/shared/cli/typings/db-resolution.interface.d.ts +9 -0
  40. package/dist/src/shared/cli/typings/recfile-field-map.type.d.ts +10 -0
  41. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  42. package/dist/src/shared/wasm-codec/functions/decode-option-u8.function.d.ts +9 -0
  43. package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
  44. package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +2 -45
  45. package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +10 -1
  46. package/dist/src/shared/wasm-codec/index.d.ts +1 -1
  47. package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +6 -0
  48. package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +5 -0
  49. package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +5 -0
  50. package/dist/src/shared/worker-client/functions/build-deno-permissions.function.d.ts +11 -0
  51. package/dist/src/shared/worker-client/functions/read-crash-reason.function.d.ts +9 -0
  52. package/dist/src/shared/worker-client/functions/resolve-spawn-script.function.d.ts +6 -0
  53. package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +1 -1
  54. package/dist/src/shared/worker-client/typings/section.model.d.ts +5 -0
  55. package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +0 -6
  56. package/dist/src/shared/worker-daemon/functions/count-files.function.d.ts +12 -0
  57. package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +2 -0
  58. package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +8 -0
  59. package/dist/src/shared/worker-daemon/functions/validate-daemon-path.function.d.ts +15 -0
  60. package/dist/src/worker.d.ts +0 -7
  61. package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
  62. package/dist/wasm/default-embedding/package.json +1 -1
  63. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  64. package/dist/wasm/fs-database/package.json +1 -1
  65. package/dist/wasm/fs-migration/package.json +1 -1
  66. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  67. package/dist/wasm/kb-worker/package.json +1 -1
  68. package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  69. package/dist/wasm/query-parser/package.json +1 -1
  70. package/dist/worker.d.ts +0 -7
  71. package/dist/worker.mjs +37 -6
  72. package/dist/worker.mjs.map +3 -3
  73. package/package.json +10 -9
  74. package/dist/chunk-BJXEVALU.mjs.map +0 -7
  75. package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +0 -10
  76. package/docs/details/README.md +0 -30
  77. package/docs/details/agent-tooling.md +0 -132
  78. package/docs/details/cli.md +0 -777
  79. package/docs/details/knowledge-base.md +0 -180
  80. package/docs/details/library-api.md +0 -495
  81. package/docs/details/mcp-server.md +0 -482
  82. package/docs/details/search-and-ranking.md +0 -575
  83. package/docs/details/storage.md +0 -531
  84. package/docs/goals/agents.md +0 -751
  85. package/docs/goals/architecture.svg +0 -198
  86. package/docs/goals/auto-capture.md +0 -378
  87. package/docs/goals/benchmarking.md +0 -296
  88. package/docs/goals/cli.md +0 -2654
  89. package/docs/goals/concurrency.md +0 -259
  90. package/docs/goals/content-composer.md +0 -609
  91. package/docs/goals/content-parser.md +0 -279
  92. package/docs/goals/database.md +0 -1679
  93. package/docs/goals/document.md +0 -368
  94. package/docs/goals/hybrid-search.md +0 -465
  95. package/docs/goals/mcp.md +0 -1541
  96. package/docs/goals/overview.md +0 -124
  97. package/docs/goals/query-parser.md +0 -373
  98. package/docs/goals/query-result.md +0 -860
  99. package/docs/goals/semantic-dedup.md +0 -233
  100. package/docs/goals/skills.md +0 -810
  101. package/docs/goals/sync.md +0 -217
  102. package/docs/goals/worker-client.md +0 -1005
  103. package/docs/goals/worker-daemon.md +0 -1547
  104. package/docs/modules/overview.md +0 -319
  105. package/docs/modules/rust/embedding/module.md +0 -91
  106. package/docs/modules/rust/fs-database/functions/document.md +0 -48
  107. package/docs/modules/rust/fs-database/functions/integrity.md +0 -79
  108. package/docs/modules/rust/fs-database/functions/io.md +0 -87
  109. package/docs/modules/rust/fs-database/functions/module.md +0 -22
  110. package/docs/modules/rust/fs-database/functions/query-exec.md +0 -44
  111. package/docs/modules/rust/fs-database/functions/section.md +0 -76
  112. package/docs/modules/rust/fs-database/indexes/btree.md +0 -35
  113. package/docs/modules/rust/fs-database/indexes/corpus.md +0 -61
  114. package/docs/modules/rust/fs-database/indexes/inverted.md +0 -60
  115. package/docs/modules/rust/fs-database/indexes/module.md +0 -64
  116. package/docs/modules/rust/fs-database/indexes/positional.md +0 -39
  117. package/docs/modules/rust/fs-database/indexes/vectors.md +0 -110
  118. package/docs/modules/rust/fs-database/module.md +0 -150
  119. package/docs/modules/rust/fs-database/types/catalog.md +0 -53
  120. package/docs/modules/rust/fs-database/types/module.md +0 -12
  121. package/docs/modules/rust/fs-database/types/section.md +0 -127
  122. package/docs/modules/rust/kb-worker/functions/compose.md +0 -57
  123. package/docs/modules/rust/kb-worker/functions/module.md +0 -20
  124. package/docs/modules/rust/kb-worker/functions/retrieve.md +0 -194
  125. package/docs/modules/rust/kb-worker/functions/search.md +0 -173
  126. package/docs/modules/rust/kb-worker/functions/write.md +0 -172
  127. package/docs/modules/rust/kb-worker/module.md +0 -171
  128. package/docs/modules/rust/kb-worker/types/cache.md +0 -90
  129. package/docs/modules/rust/kb-worker/types/context.md +0 -26
  130. package/docs/modules/rust/kb-worker/types/module.md +0 -16
  131. package/docs/modules/rust/kb-worker/types/status.md +0 -29
  132. package/docs/modules/rust/kb-worker/types/token.md +0 -50
  133. package/docs/modules/rust/overview.md +0 -531
  134. package/docs/modules/rust/query-parser/functions/extract.md +0 -56
  135. package/docs/modules/rust/query-parser/functions/module.md +0 -18
  136. package/docs/modules/rust/query-parser/functions/parse.md +0 -33
  137. package/docs/modules/rust/query-parser/functions/pipeline.md +0 -9
  138. package/docs/modules/rust/query-parser/functions/rank.md +0 -85
  139. package/docs/modules/rust/query-parser/module.md +0 -131
  140. package/docs/modules/rust/query-parser/types/cache.md +0 -39
  141. package/docs/modules/rust/query-parser/types/keyphrase.md +0 -71
  142. package/docs/modules/rust/query-parser/types/module.md +0 -18
  143. package/docs/modules/rust/query-parser/types/token.md +0 -46
  144. package/docs/modules/rust/shared/content-composer/functions.md +0 -114
  145. package/docs/modules/rust/shared/content-composer/module.md +0 -147
  146. package/docs/modules/rust/shared/content-composer/types.md +0 -93
  147. package/docs/modules/rust/shared/content-parser/functions.md +0 -72
  148. package/docs/modules/rust/shared/content-parser/module.md +0 -99
  149. package/docs/modules/rust/shared/content-parser/types.md +0 -71
  150. package/docs/modules/rust/shared/corpus/module.md +0 -24
  151. package/docs/modules/rust/shared/corpus/types.md +0 -141
  152. package/docs/modules/rust/shared/document/module.md +0 -25
  153. package/docs/modules/rust/shared/document/types.md +0 -154
  154. package/docs/modules/rust/shared/encode/module.md +0 -22
  155. package/docs/modules/rust/shared/encode/traits.md +0 -304
  156. package/docs/modules/rust/shared/error/module.md +0 -28
  157. package/docs/modules/rust/shared/error/types.md +0 -302
  158. package/docs/modules/rust/shared/kbid/module.md +0 -24
  159. package/docs/modules/rust/shared/kbid/types.md +0 -147
  160. package/docs/modules/rust/shared/memory/functions.md +0 -209
  161. package/docs/modules/rust/shared/memory/module.md +0 -24
  162. package/docs/modules/rust/shared/module.md +0 -196
  163. package/docs/modules/rust/shared/pipeline/functions.md +0 -141
  164. package/docs/modules/rust/shared/pipeline/module.md +0 -62
  165. package/docs/modules/rust/shared/pipeline/types.md +0 -43
  166. package/docs/modules/rust/shared/query/module.md +0 -27
  167. package/docs/modules/rust/shared/query/types.md +0 -236
  168. package/docs/modules/rust/shared/section/module.md +0 -25
  169. package/docs/modules/rust/shared/section/types.md +0 -294
  170. package/docs/modules/rust/shared/term/module.md +0 -25
  171. package/docs/modules/rust/shared/term/types.md +0 -139
  172. package/docs/modules/typescript/cli.md +0 -131
  173. package/docs/modules/typescript/kbdb-worker.md +0 -150
  174. package/docs/modules/typescript/overview.md +0 -400
  175. package/docs/modules/typescript/shared/auto-capture/module.md +0 -73
  176. package/docs/modules/typescript/shared/cli/constants.md +0 -23
  177. package/docs/modules/typescript/shared/cli/functions.md +0 -809
  178. package/docs/modules/typescript/shared/cli/module.md +0 -138
  179. package/docs/modules/typescript/shared/cli/typings.md +0 -197
  180. package/docs/modules/typescript/shared/embedding/functions.md +0 -200
  181. package/docs/modules/typescript/shared/embedding/module.md +0 -77
  182. package/docs/modules/typescript/shared/embedding/typings.md +0 -124
  183. package/docs/modules/typescript/shared/hash/functions.md +0 -20
  184. package/docs/modules/typescript/shared/hash/module.md +0 -21
  185. package/docs/modules/typescript/shared/log/constants.md +0 -82
  186. package/docs/modules/typescript/shared/log/functions.md +0 -131
  187. package/docs/modules/typescript/shared/log/module.md +0 -153
  188. package/docs/modules/typescript/shared/log/typings.md +0 -82
  189. package/docs/modules/typescript/shared/mcp/classes.md +0 -179
  190. package/docs/modules/typescript/shared/mcp/functions.md +0 -386
  191. package/docs/modules/typescript/shared/mcp/module.md +0 -160
  192. package/docs/modules/typescript/shared/mcp/typings.md +0 -529
  193. package/docs/modules/typescript/shared/module.md +0 -110
  194. package/docs/modules/typescript/shared/platform/functions.md +0 -42
  195. package/docs/modules/typescript/shared/platform/module.md +0 -25
  196. package/docs/modules/typescript/shared/runtime/functions.md +0 -26
  197. package/docs/modules/typescript/shared/runtime/module.md +0 -27
  198. package/docs/modules/typescript/shared/runtime/typings.md +0 -13
  199. package/docs/modules/typescript/shared/version/module.md +0 -27
  200. package/docs/modules/typescript/shared/wasm-codec/functions.md +0 -391
  201. package/docs/modules/typescript/shared/wasm-codec/module.md +0 -98
  202. package/docs/modules/typescript/shared/worker-client/classes.md +0 -264
  203. package/docs/modules/typescript/shared/worker-client/functions.md +0 -175
  204. package/docs/modules/typescript/shared/worker-client/module.md +0 -92
  205. package/docs/modules/typescript/shared/worker-client/typings.md +0 -511
  206. package/docs/modules/typescript/shared/worker-daemon/classes.md +0 -239
  207. package/docs/modules/typescript/shared/worker-daemon/constants.md +0 -37
  208. package/docs/modules/typescript/shared/worker-daemon/functions.md +0 -234
  209. package/docs/modules/typescript/shared/worker-daemon/module.md +0 -118
  210. package/docs/modules/typescript/shared/worker-daemon/typings.md +0 -132
  211. package/docs/overview.md +0 -191
  212. package/docs/release-notes/0.1.0.md +0 -189
  213. package/docs/release-notes/0.1.1.md +0 -46
  214. package/docs/release-notes/0.1.2.md +0 -38
  215. package/docs/release-notes/0.1.3.md +0 -42
  216. package/docs/release-notes/0.2.0.md +0 -147
  217. package/docs/release-notes/0.3.0.md +0 -89
  218. package/docs/release-notes/0.3.1.md +0 -121
  219. package/docs/release-notes/0.3.2.md +0 -64
  220. package/docs/release-notes/0.4.0.md +0 -80
  221. package/docs/release-notes/0.4.1.md +0 -149
  222. package/docs/release-notes/0.4.3.md +0 -60
  223. package/docs/release-notes/0.5.0.md +0 -41
  224. package/docs/release-notes/README.md +0 -16
@@ -1,259 +0,0 @@
1
- # Concurrent Write Safety
2
-
3
- *One writer at a time, unlimited concurrent readers --
4
- formalizing the locking model, multi-daemon prevention,
5
- crash recovery, and stress-test methodology.*
6
-
7
- ## Goal
8
-
9
- The worker daemon serializes all write operations
10
- through a single-writer lock. Multiple concurrent
11
- readers proceed without any lock. This document
12
- formalizes the locking model, multi-daemon prevention,
13
- atomic write guarantees, crash recovery, and
14
- stress-test methodology.
15
-
16
- This goal addresses gap #3 from the issue
17
- [2026-06-23 Opus 4.8 Second Brain Review](../issues/2026-06-23-opus-48-second-brain-review.md):
18
- the single-writer lock in the worker daemon must be
19
- validated under concurrent load before concurrent
20
- multi-agent use can be trusted.
21
-
22
- ## Single-Writer Lock
23
-
24
- The daemon acquires an exclusive file lock on
25
- `kbdb-{ctx}.lock` in the OS temporary directory during
26
- write operations. The lock file uses the same context
27
- ID as the PID file and IPC socket (see
28
- [Worker Daemon](worker-daemon.md) for context ID
29
- derivation).
30
-
31
- - **Read operations** -- search, recall, retrieve,
32
- content, dbStatus, and listByType -- proceed without
33
- acquiring the lock. Concurrent read requests from
34
- multiple worker client connections are fully parallel.
35
- - **Write operations** -- addSection, updateSection,
36
- removeSection, groupSections, removeGrouping,
37
- initDirectory, gc, rebuildIndexes, and export --
38
- acquire the exclusive lock before calling the
39
- corresponding WASM export. If another write is
40
- already in progress, the new write queues behind the
41
- lock and waits.
42
- - The lock is held only for the duration of a single
43
- write operation. It is released immediately after
44
- the operation completes. It is never held across
45
- multiple operations or across client connections.
46
- - The locking model is implemented in TypeScript inside
47
- the worker daemon (`src/shared/worker-daemon/`), not
48
- inside any WASM module.
49
-
50
- This model is equivalent to SQLite's default locking:
51
- readers never block, and writers take turns one at a
52
- time.
53
-
54
- ### Write Operations Subject to the Lock
55
-
56
- | IPC Method | WASM Export |
57
- |--------------------------|----------------------------|
58
- | `addSection` | `worker_add_section` |
59
- | `updateSection` | `worker_update_section` |
60
- | `removeSection` | `worker_remove_section` |
61
- | `groupSections` | `worker_group_sections` |
62
- | `removeGrouping` | `worker_remove_grouping` |
63
- | `initDirectory` | `worker_init_directory` |
64
- | `gc` | `worker_garbage_collect` |
65
- | `rebuildIndexes` | `worker_rebuild_indexes` |
66
- | `export` | `db_export` |
67
-
68
- ## Multi-Daemon Prevention
69
-
70
- Each database context gets exactly one daemon process
71
- at a time, enforced by a PID file keyed to the context
72
- ID.
73
-
74
- - The PID file is named `kbdb-{ctx}.pid` and lives in
75
- the OS temporary directory. Its presence means a
76
- daemon for that context is either running or died
77
- without cleaning up.
78
- - Before spawning a new daemon, the worker client reads
79
- the PID file (if present) and checks whether the
80
- recorded process is alive.
81
- - **PID file absent** -- no running daemon; spawn a
82
- new one.
83
- - **PID file present, process alive** -- connect to
84
- the existing daemon; do not spawn.
85
- - **PID file present, process dead** -- stale PID
86
- file from a prior crash; remove the file and spawn
87
- a new daemon.
88
- - The daemon writes its PID file only after all startup
89
- preconditions pass and the WASM module is loaded
90
- successfully. See [Worker Daemon](worker-daemon.md)
91
- for the full startup sequence.
92
- - On graceful shutdown, the daemon removes its PID
93
- file before exiting.
94
-
95
- This protocol ensures that the same database directory
96
- is never served by two concurrent daemon processes.
97
-
98
- ## Atomic Write Guarantees
99
-
100
- All file writes in the database use the atomic
101
- write pattern: content is written to a temporary file
102
- first, then the temporary file is renamed to the final
103
- path. Rename is an atomic operation on all supported
104
- filesystems (POSIX and Windows NTFS).
105
-
106
- - **Section files** (`sections/{prefix}/{kbid}.sec`)
107
- are written to `sections/{prefix}/{kbid}.sec.tmp`
108
- then renamed.
109
- - **Document manifests** (`documents/{docid}.toml`)
110
- are written to `documents/{docid}.toml.tmp` then
111
- renamed.
112
- - **Index files** (`indexes/terms.idx`, etc.) are
113
- rebuilt to temporary paths then renamed into place.
114
- - **Catalog** (`catalog.toml`) is written last,
115
- after all data files are in place. A crash
116
- before the catalog rename leaves the catalog
117
- consistent with the previous complete state.
118
-
119
- If the daemon crashes mid-write, the temporary file
120
- is orphaned but the original file is intact. On next
121
- daemon startup, orphaned temporary files (matching
122
- `*.tmp`) in the database directory are cleaned up.
123
-
124
- The atomic write pattern is specified in
125
- [Database](database.md) under Storage Design.
126
-
127
- ## Crash Recovery
128
-
129
- The table below describes every identified failure
130
- scenario, the resulting disk state, and the recovery
131
- action.
132
-
133
- | Scenario | State After Crash | Recovery |
134
- |---|---|---|
135
- | Crash during section write | `*.sec.tmp` orphaned, original `.sec` intact | Startup cleans `*.tmp` files |
136
- | Crash during index rebuild | Partial `*.idx.tmp`, originals intact | Startup cleans `*.tmp`; next `rebuildIndexes` overwrites |
137
- | Crash during GC | Some unreferenced sections deleted, others not | Re-run `gc`; idempotent |
138
- | Crash during catalog write | `catalog.toml.tmp` orphaned, original intact | Startup cleans `*.tmp` |
139
- | PID file not removed | Stale `kbdb-{ctx}.pid` on disk | Worker client detects dead process, removes PID, spawns new daemon |
140
- | Lock file not released | `kbdb-{ctx}.lock` orphaned | Daemon startup acquires the exclusive lock fresh; OS releases orphaned file locks when the process that held them exits |
141
- | WASM crash inside write | Partial in-memory state, temp file may exist | Daemon exits; startup cleans `*.tmp`; next operation starts clean |
142
-
143
- All recovery actions are automatic. No manual
144
- intervention is required for any scenario in this
145
- table.
146
-
147
- ## Stress Test Specification
148
-
149
- The following test harness validates concurrent write
150
- safety. It must pass on both Deno and Node.js runtimes
151
- before a release can claim concurrent safety.
152
-
153
- ### Setup
154
-
155
- 1. Create a fresh, empty database directory.
156
- 2. Prepare N unique documents (N in the range 10--50).
157
- Each document must have distinct content to avoid
158
- content-address collisions that would make section
159
- count verification meaningless.
160
-
161
- ### Execution
162
-
163
- 3. Launch N concurrent `kbdb learn` invocations, all
164
- targeting the same database directory. Each
165
- invocation learns one of the N unique documents.
166
- 4. Use a process pool or parallel shell to launch all
167
- N invocations simultaneously -- not sequentially.
168
- 5. Wait for all N invocations to complete. Record any
169
- non-zero exit codes as failures.
170
-
171
- ### Verification
172
-
173
- 6. Run `kbdb check` against the database.
174
- The response must have `ok: true`. Any errors in the
175
- response are test failures.
176
- 7. Query the section count. The count must equal the
177
- expected number of sections derived from the N
178
- documents (no duplicates from race conditions, no
179
- losses from interleaved writes).
180
- 8. Verify that no section has a checksum mismatch.
181
- A mismatch indicates a torn write -- the atomic
182
- rename pattern failed or was bypassed.
183
-
184
- ### Pass Criteria
185
-
186
- | Check | Expected Result |
187
- |---|---|
188
- | All `kbdb learn` exit codes | `0` |
189
- | `kbdb check` response | `ok: true`, zero errors |
190
- | Section count | Exactly the expected count |
191
- | Checksum mismatches | Zero |
192
-
193
- ### Runtime Matrix
194
-
195
- Run the full harness on both runtimes:
196
-
197
- | Runtime | Command prefix |
198
- |---|---|
199
- | Node.js >= 20 | `node dist/kbdb.mjs` |
200
- | Deno | `deno run --allow-all src/cli.ts` |
201
-
202
- Both must pass. A failure on one runtime but not the
203
- other indicates a runtime-specific locking bug.
204
-
205
- ## Edge Cases
206
-
207
- ### Two CLI Invocations Through the Same Daemon
208
-
209
- When two `kbdb` CLI processes connect to the same
210
- daemon (same database directory), their write requests
211
- share the single-writer lock automatically. No user
212
- action is required. The second write waits for the
213
- first to complete.
214
-
215
- ### MCP Server Connections
216
-
217
- An MCP server connection routes all requests through
218
- a worker client to the daemon, the same as a CLI
219
- invocation. Multiple MCP client connections routed to
220
- the same daemon share the write lock:
221
-
222
- - Concurrent read requests from multiple MCP clients
223
- are served in parallel.
224
- - Concurrent write requests from multiple MCP clients
225
- are serialized through the lock one at a time.
226
-
227
- There is no per-connection or per-client lock; the
228
- lock is global to the daemon process.
229
-
230
- ### Direct File Access
231
-
232
- Accessing or modifying `.kbdb` files directly -- via
233
- text editor, shell commands, or any process other than
234
- the daemon -- is not supported. Direct writes bypass
235
- the single-writer lock and the atomic write pattern,
236
- and may corrupt the database. All mutations must go
237
- through the daemon's IPC API.
238
-
239
- ## Design Constraints
240
-
241
- - **Per-daemon locking, not per-file** -- The lock
242
- covers all writes to a database context, not writes
243
- to individual files. This means writes to unrelated
244
- sections still serialize behind the same lock. The
245
- simplicity of a single lock outweighs the throughput
246
- cost at current scale. If per-section parallelism
247
- becomes necessary, this constraint is the place to
248
- revisit.
249
- - **Single-machine only** -- The locking model
250
- relies on OS-level file locks and process identity
251
- on a single machine. It provides no guarantees across
252
- network filesystems or multiple machines. Cross-machine
253
- scenarios require an external sync mechanism (see
254
- [Sync](sync.md) when available).
255
- - **Lock implemented in TypeScript** -- The write lock
256
- is managed by the TypeScript worker daemon layer, not
257
- by any WASM module. WASM modules have no knowledge of
258
- concurrent callers; they process one call at a time
259
- through the host.