@dikolab/kbdb 0.4.3 → 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.
- package/CLA.md +68 -0
- package/LICENSE +676 -12
- package/LICENSING.md +58 -0
- package/README.md +50 -27
- package/README.md.bak +320 -0
- package/dist/README.md +320 -0
- package/dist/{chunk-BJXEVALU.mjs → chunk-QLJ33C74.mjs} +44 -44
- package/dist/chunk-QLJ33C74.mjs.map +7 -0
- package/dist/cli.cjs +550 -232
- package/dist/cli.cjs.map +4 -4
- package/dist/cli.d.ts +0 -8
- package/dist/cli.mjs +483 -154
- package/dist/cli.mjs.map +4 -4
- package/dist/kbdb-worker.cjs +36 -5
- package/dist/kbdb-worker.cjs.map +3 -3
- package/dist/mod.cjs +89 -30
- package/dist/mod.cjs.map +4 -4
- package/dist/mod.mjs +88 -30
- package/dist/mod.mjs.map +4 -4
- package/dist/src/cli.d.ts +0 -8
- package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
- package/dist/src/shared/cli/constants/recfile-command-field-map.constant.d.ts +8 -0
- package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +21 -0
- package/dist/src/shared/cli/functions/compute-directory-level.function.d.ts +14 -0
- package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -28
- package/dist/src/shared/cli/functions/format-command-output.function.d.ts +14 -0
- package/dist/src/shared/cli/functions/format-db-not-found.function.d.ts +20 -0
- package/dist/src/shared/cli/functions/format-output.function.d.ts +1 -0
- package/dist/src/shared/cli/functions/format-recfile-output.function.d.ts +11 -0
- package/dist/src/shared/cli/functions/render-recfile-value.function.d.ts +11 -0
- package/dist/src/shared/cli/functions/resolve-db-dir.function.d.ts +24 -0
- package/dist/src/shared/cli/functions/resolve-recfile-key.function.d.ts +9 -0
- package/dist/src/shared/cli/functions/run-db-path.function.d.ts +10 -0
- package/dist/src/shared/cli/functions/run-export.function.d.ts +8 -4
- package/dist/src/shared/cli/functions/run-import.function.d.ts +4 -0
- package/dist/src/shared/cli/functions/run-learn.function.d.ts +12 -0
- package/dist/src/shared/cli/index.d.ts +4 -1
- package/dist/src/shared/cli/typings/cli-options.interface.d.ts +9 -2
- package/dist/src/shared/cli/typings/db-resolution.interface.d.ts +9 -0
- package/dist/src/shared/cli/typings/recfile-field-map.type.d.ts +10 -0
- package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
- package/dist/src/shared/wasm-codec/functions/decode-option-u8.function.d.ts +9 -0
- package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
- package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +2 -45
- package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +10 -1
- package/dist/src/shared/wasm-codec/index.d.ts +1 -1
- package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +6 -0
- package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +5 -0
- package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +5 -0
- package/dist/src/shared/worker-client/functions/build-deno-permissions.function.d.ts +11 -0
- package/dist/src/shared/worker-client/functions/read-crash-reason.function.d.ts +9 -0
- package/dist/src/shared/worker-client/functions/resolve-spawn-script.function.d.ts +6 -0
- package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +1 -1
- package/dist/src/shared/worker-client/typings/section.model.d.ts +5 -0
- package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +0 -6
- package/dist/src/shared/worker-daemon/functions/count-files.function.d.ts +12 -0
- package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +2 -0
- package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +8 -0
- package/dist/src/shared/worker-daemon/functions/validate-daemon-path.function.d.ts +15 -0
- package/dist/src/worker.d.ts +0 -7
- package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
- package/dist/wasm/default-embedding/package.json +1 -1
- package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/dist/wasm/fs-database/package.json +1 -1
- package/dist/wasm/fs-migration/kbdb_fs_migration_bg.wasm +0 -0
- package/dist/wasm/fs-migration/package.json +1 -1
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/wasm/kb-worker/package.json +1 -1
- package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
- package/dist/wasm/query-parser/package.json +1 -1
- package/dist/worker.d.ts +0 -7
- package/dist/worker.mjs +37 -6
- package/dist/worker.mjs.map +3 -3
- package/package.json +13 -12
- package/dist/chunk-BJXEVALU.mjs.map +0 -7
- package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +0 -10
- package/docs/details/README.md +0 -30
- package/docs/details/agent-tooling.md +0 -132
- package/docs/details/cli.md +0 -777
- package/docs/details/knowledge-base.md +0 -180
- package/docs/details/library-api.md +0 -495
- package/docs/details/mcp-server.md +0 -482
- package/docs/details/search-and-ranking.md +0 -575
- package/docs/details/storage.md +0 -531
- package/docs/goals/agents.md +0 -751
- package/docs/goals/architecture.svg +0 -198
- package/docs/goals/auto-capture.md +0 -378
- package/docs/goals/benchmarking.md +0 -296
- package/docs/goals/cli.md +0 -2654
- package/docs/goals/concurrency.md +0 -259
- package/docs/goals/content-composer.md +0 -609
- package/docs/goals/content-parser.md +0 -279
- package/docs/goals/database.md +0 -1679
- package/docs/goals/document.md +0 -368
- package/docs/goals/hybrid-search.md +0 -465
- package/docs/goals/mcp.md +0 -1541
- package/docs/goals/overview.md +0 -124
- package/docs/goals/query-parser.md +0 -373
- package/docs/goals/query-result.md +0 -860
- package/docs/goals/semantic-dedup.md +0 -233
- package/docs/goals/skills.md +0 -810
- package/docs/goals/sync.md +0 -217
- package/docs/goals/worker-client.md +0 -1005
- package/docs/goals/worker-daemon.md +0 -1547
- package/docs/modules/overview.md +0 -319
- package/docs/modules/rust/embedding/module.md +0 -91
- package/docs/modules/rust/fs-database/functions/document.md +0 -48
- package/docs/modules/rust/fs-database/functions/integrity.md +0 -79
- package/docs/modules/rust/fs-database/functions/io.md +0 -87
- package/docs/modules/rust/fs-database/functions/module.md +0 -22
- package/docs/modules/rust/fs-database/functions/query-exec.md +0 -44
- package/docs/modules/rust/fs-database/functions/section.md +0 -76
- package/docs/modules/rust/fs-database/indexes/btree.md +0 -35
- package/docs/modules/rust/fs-database/indexes/corpus.md +0 -61
- package/docs/modules/rust/fs-database/indexes/inverted.md +0 -60
- package/docs/modules/rust/fs-database/indexes/module.md +0 -64
- package/docs/modules/rust/fs-database/indexes/positional.md +0 -39
- package/docs/modules/rust/fs-database/indexes/vectors.md +0 -110
- package/docs/modules/rust/fs-database/module.md +0 -150
- package/docs/modules/rust/fs-database/types/catalog.md +0 -53
- package/docs/modules/rust/fs-database/types/module.md +0 -12
- package/docs/modules/rust/fs-database/types/section.md +0 -127
- package/docs/modules/rust/kb-worker/functions/compose.md +0 -57
- package/docs/modules/rust/kb-worker/functions/module.md +0 -20
- package/docs/modules/rust/kb-worker/functions/retrieve.md +0 -194
- package/docs/modules/rust/kb-worker/functions/search.md +0 -173
- package/docs/modules/rust/kb-worker/functions/write.md +0 -172
- package/docs/modules/rust/kb-worker/module.md +0 -171
- package/docs/modules/rust/kb-worker/types/cache.md +0 -90
- package/docs/modules/rust/kb-worker/types/context.md +0 -26
- package/docs/modules/rust/kb-worker/types/module.md +0 -16
- package/docs/modules/rust/kb-worker/types/status.md +0 -29
- package/docs/modules/rust/kb-worker/types/token.md +0 -50
- package/docs/modules/rust/overview.md +0 -531
- package/docs/modules/rust/query-parser/functions/extract.md +0 -56
- package/docs/modules/rust/query-parser/functions/module.md +0 -18
- package/docs/modules/rust/query-parser/functions/parse.md +0 -33
- package/docs/modules/rust/query-parser/functions/pipeline.md +0 -9
- package/docs/modules/rust/query-parser/functions/rank.md +0 -85
- package/docs/modules/rust/query-parser/module.md +0 -131
- package/docs/modules/rust/query-parser/types/cache.md +0 -39
- package/docs/modules/rust/query-parser/types/keyphrase.md +0 -71
- package/docs/modules/rust/query-parser/types/module.md +0 -18
- package/docs/modules/rust/query-parser/types/token.md +0 -46
- package/docs/modules/rust/shared/content-composer/functions.md +0 -114
- package/docs/modules/rust/shared/content-composer/module.md +0 -147
- package/docs/modules/rust/shared/content-composer/types.md +0 -93
- package/docs/modules/rust/shared/content-parser/functions.md +0 -72
- package/docs/modules/rust/shared/content-parser/module.md +0 -99
- package/docs/modules/rust/shared/content-parser/types.md +0 -71
- package/docs/modules/rust/shared/corpus/module.md +0 -24
- package/docs/modules/rust/shared/corpus/types.md +0 -141
- package/docs/modules/rust/shared/document/module.md +0 -25
- package/docs/modules/rust/shared/document/types.md +0 -154
- package/docs/modules/rust/shared/encode/module.md +0 -22
- package/docs/modules/rust/shared/encode/traits.md +0 -304
- package/docs/modules/rust/shared/error/module.md +0 -28
- package/docs/modules/rust/shared/error/types.md +0 -302
- package/docs/modules/rust/shared/kbid/module.md +0 -24
- package/docs/modules/rust/shared/kbid/types.md +0 -147
- package/docs/modules/rust/shared/memory/functions.md +0 -209
- package/docs/modules/rust/shared/memory/module.md +0 -24
- package/docs/modules/rust/shared/module.md +0 -196
- package/docs/modules/rust/shared/pipeline/functions.md +0 -141
- package/docs/modules/rust/shared/pipeline/module.md +0 -62
- package/docs/modules/rust/shared/pipeline/types.md +0 -43
- package/docs/modules/rust/shared/query/module.md +0 -27
- package/docs/modules/rust/shared/query/types.md +0 -236
- package/docs/modules/rust/shared/section/module.md +0 -25
- package/docs/modules/rust/shared/section/types.md +0 -294
- package/docs/modules/rust/shared/term/module.md +0 -25
- package/docs/modules/rust/shared/term/types.md +0 -139
- package/docs/modules/typescript/cli.md +0 -131
- package/docs/modules/typescript/kbdb-worker.md +0 -150
- package/docs/modules/typescript/overview.md +0 -400
- package/docs/modules/typescript/shared/auto-capture/module.md +0 -73
- package/docs/modules/typescript/shared/cli/constants.md +0 -23
- package/docs/modules/typescript/shared/cli/functions.md +0 -809
- package/docs/modules/typescript/shared/cli/module.md +0 -138
- package/docs/modules/typescript/shared/cli/typings.md +0 -197
- package/docs/modules/typescript/shared/embedding/functions.md +0 -200
- package/docs/modules/typescript/shared/embedding/module.md +0 -77
- package/docs/modules/typescript/shared/embedding/typings.md +0 -124
- package/docs/modules/typescript/shared/hash/functions.md +0 -20
- package/docs/modules/typescript/shared/hash/module.md +0 -21
- package/docs/modules/typescript/shared/log/constants.md +0 -82
- package/docs/modules/typescript/shared/log/functions.md +0 -131
- package/docs/modules/typescript/shared/log/module.md +0 -153
- package/docs/modules/typescript/shared/log/typings.md +0 -82
- package/docs/modules/typescript/shared/mcp/classes.md +0 -179
- package/docs/modules/typescript/shared/mcp/functions.md +0 -386
- package/docs/modules/typescript/shared/mcp/module.md +0 -160
- package/docs/modules/typescript/shared/mcp/typings.md +0 -529
- package/docs/modules/typescript/shared/module.md +0 -110
- package/docs/modules/typescript/shared/platform/functions.md +0 -42
- package/docs/modules/typescript/shared/platform/module.md +0 -25
- package/docs/modules/typescript/shared/runtime/functions.md +0 -26
- package/docs/modules/typescript/shared/runtime/module.md +0 -27
- package/docs/modules/typescript/shared/runtime/typings.md +0 -13
- package/docs/modules/typescript/shared/version/module.md +0 -27
- package/docs/modules/typescript/shared/wasm-codec/functions.md +0 -391
- package/docs/modules/typescript/shared/wasm-codec/module.md +0 -98
- package/docs/modules/typescript/shared/worker-client/classes.md +0 -264
- package/docs/modules/typescript/shared/worker-client/functions.md +0 -175
- package/docs/modules/typescript/shared/worker-client/module.md +0 -92
- package/docs/modules/typescript/shared/worker-client/typings.md +0 -511
- package/docs/modules/typescript/shared/worker-daemon/classes.md +0 -239
- package/docs/modules/typescript/shared/worker-daemon/constants.md +0 -37
- package/docs/modules/typescript/shared/worker-daemon/functions.md +0 -234
- package/docs/modules/typescript/shared/worker-daemon/module.md +0 -118
- package/docs/modules/typescript/shared/worker-daemon/typings.md +0 -132
- package/docs/overview.md +0 -191
- package/docs/release-notes/0.1.0.md +0 -189
- package/docs/release-notes/0.1.1.md +0 -46
- package/docs/release-notes/0.1.2.md +0 -38
- package/docs/release-notes/0.1.3.md +0 -42
- package/docs/release-notes/0.2.0.md +0 -147
- package/docs/release-notes/0.3.0.md +0 -89
- package/docs/release-notes/0.3.1.md +0 -121
- package/docs/release-notes/0.3.2.md +0 -64
- package/docs/release-notes/0.4.0.md +0 -80
- package/docs/release-notes/0.4.1.md +0 -149
- package/docs/release-notes/0.4.3.md +0 -60
- package/docs/release-notes/README.md +0 -13
package/docs/details/storage.md
DELETED
|
@@ -1,531 +0,0 @@
|
|
|
1
|
-
# Storage Architecture
|
|
2
|
-
|
|
3
|
-
kbdb stores everything in a `.kbdb` folder inside the
|
|
4
|
-
target directory. There is no external database, no
|
|
5
|
-
cloud dependency, and no running server required for
|
|
6
|
-
data persistence. All metadata files use TOML for
|
|
7
|
-
human inspectability; indexes are binary but derived
|
|
8
|
-
and rebuildable from source data. The entire
|
|
9
|
-
directory is portable -- it can be copied, moved, or
|
|
10
|
-
version-controlled.
|
|
11
|
-
|
|
12
|
-
## Directory Layout
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
.kbdb/
|
|
16
|
-
+-- catalog.toml
|
|
17
|
-
+-- sections/
|
|
18
|
-
| +-- {ab}/
|
|
19
|
-
| | +-- {cdef...}.sec
|
|
20
|
-
| +-- ...
|
|
21
|
-
+-- documents/
|
|
22
|
-
| +-- {docid}.toml
|
|
23
|
-
+-- indexes/
|
|
24
|
-
| +-- meta.toml
|
|
25
|
-
| +-- terms.idx
|
|
26
|
-
| +-- positions.idx
|
|
27
|
-
| +-- references.idx
|
|
28
|
-
| +-- corpus.dat
|
|
29
|
-
+-- worker.toml
|
|
30
|
-
+-- .gitignore
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
| Path | Format | Description |
|
|
34
|
-
|-------------------------------|--------|-------------------------------|
|
|
35
|
-
| `catalog.toml` | TOML | Database table of contents: section count, document count, timestamps, integrity checksums |
|
|
36
|
-
| `sections/{ab}/{cdef...}.sec` | TOML + raw | Section files: TOML header + content body, sharded by first two characters of kbid |
|
|
37
|
-
| `documents/{docid}.toml` | TOML | Document manifests: title + ordered section list |
|
|
38
|
-
| `indexes/meta.toml` | TOML | Index metadata: rebuild timestamp, term count, statistics summary |
|
|
39
|
-
| `indexes/terms.idx` | Binary | Inverted index (B+ tree): maps terms to posting lists with per-field term frequencies |
|
|
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 |
|
|
42
|
-
| `indexes/corpus.dat` | Binary | Corpus statistics: section count, average lengths per field, per-term document frequencies |
|
|
43
|
-
| `worker.toml` | TOML | Cache daemon configuration |
|
|
44
|
-
| `.gitignore` | Text | Excludes `indexes/` from version control |
|
|
45
|
-
|
|
46
|
-
The layout mirrors a PostgreSQL directory-format
|
|
47
|
-
dump: a human-readable catalog at the root, one
|
|
48
|
-
subdirectory per data table, and a separate directory
|
|
49
|
-
for binary indexes.
|
|
50
|
-
|
|
51
|
-
## Content-Addressed IDs (kbid)
|
|
52
|
-
|
|
53
|
-
Every section is identified by a deterministic hash
|
|
54
|
-
of its content. The same content always produces the
|
|
55
|
-
same ID, enabling automatic deduplication.
|
|
56
|
-
|
|
57
|
-
### Hashing Process
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
Input content
|
|
61
|
-
|
|
|
62
|
-
v
|
|
63
|
-
Preprocess (text/code only)
|
|
64
|
-
|
|
|
65
|
-
v
|
|
66
|
-
Construct typed header:
|
|
67
|
-
"section <mime-type> <byte-size>\0<content>"
|
|
68
|
-
|
|
|
69
|
-
v
|
|
70
|
-
SHA-256 hash
|
|
71
|
-
|
|
|
72
|
-
v
|
|
73
|
-
Truncate to first 16 bytes (128 bits)
|
|
74
|
-
|
|
|
75
|
-
v
|
|
76
|
-
Base32 lowercase encoding (no padding)
|
|
77
|
-
|
|
|
78
|
-
v
|
|
79
|
-
26-character alphanumeric kbid
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Hash Input Format
|
|
83
|
-
|
|
84
|
-
The hash input follows the same pattern as Git
|
|
85
|
-
objects (`blob <size>\0<content>`):
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
section <mime-type> <byte-size>\0<preprocessed-content>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
- `section` -- literal string prefix (type tag)
|
|
92
|
-
- `<mime-type>` -- the section's MIME type string
|
|
93
|
-
(e.g. `text/markdown`, `text/typescript`,
|
|
94
|
-
`image/png`)
|
|
95
|
-
- `<byte-size>` -- byte length of the preprocessed
|
|
96
|
-
content, as a decimal ASCII string
|
|
97
|
-
- `\0` -- literal null byte separator
|
|
98
|
-
- `<preprocessed-content>` -- the content after
|
|
99
|
-
preprocessing (text/code) or the base64 string
|
|
100
|
-
as-is (images)
|
|
101
|
-
|
|
102
|
-
### Worked Example
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
Given:
|
|
106
|
-
type = "text/markdown"
|
|
107
|
-
content = "Hello, world!" (13 bytes after preprocessing)
|
|
108
|
-
|
|
109
|
-
Hash input (41 bytes):
|
|
110
|
-
section text/markdown 13\0Hello, world!
|
|
111
|
-
|
|
112
|
-
+-- header: "section text/markdown 13"
|
|
113
|
-
+-- null byte: \0
|
|
114
|
-
+-- content: "Hello, world!"
|
|
115
|
-
|
|
116
|
-
kbid = base32(sha256(hash_input)[..16])
|
|
117
|
-
= 26-character lowercase alphanumeric string
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Properties
|
|
121
|
-
|
|
122
|
-
- **Deterministic** -- identical content with the
|
|
123
|
-
same MIME type always produces the same kbid.
|
|
124
|
-
- **Type-aware** -- the MIME type is part of the hash
|
|
125
|
-
input, so identical raw content stored as different
|
|
126
|
-
types (e.g. `text/markdown` vs `text/typescript`)
|
|
127
|
-
produces different kbids.
|
|
128
|
-
- **Collision-resistant** -- SHA-256 truncated to 128
|
|
129
|
-
bits provides sufficient collision resistance for a
|
|
130
|
-
local knowledge base.
|
|
131
|
-
- **URL-safe** -- base32 lowercase encoding uses only
|
|
132
|
-
alphanumeric characters.
|
|
133
|
-
|
|
134
|
-
## Content Preprocessing
|
|
135
|
-
|
|
136
|
-
Before computing the kbid, text and code sections
|
|
137
|
-
pass through a preprocessing pipeline that
|
|
138
|
-
normalizes encoding artifacts. This ensures that
|
|
139
|
-
semantically identical content -- differing only in
|
|
140
|
-
BOM, line endings, Unicode representation, or
|
|
141
|
-
surrounding whitespace -- produces the same kbid.
|
|
142
|
-
|
|
143
|
-
### Pipeline Steps (Applied in Order)
|
|
144
|
-
|
|
145
|
-
1. **BOM removal** -- Strip the UTF-8 byte order mark
|
|
146
|
-
(U+FEFF) if present at the start of the content.
|
|
147
|
-
The BOM is an encoding artifact, not meaningful
|
|
148
|
-
content.
|
|
149
|
-
|
|
150
|
-
2. **Line ending normalization** -- Convert all
|
|
151
|
-
`\r\n` (Windows) and bare `\r` (old Mac) sequences
|
|
152
|
-
to `\n` (Unix). Content created on different
|
|
153
|
-
platforms produces the same kbid.
|
|
154
|
-
|
|
155
|
-
3. **Unicode NFC normalization** -- Compose decomposed
|
|
156
|
-
Unicode sequences into their canonical form. For
|
|
157
|
-
example, `e` + combining acute accent becomes `e`
|
|
158
|
-
(U+00E9). This is the same normalization used in
|
|
159
|
-
the tokenization pipeline.
|
|
160
|
-
|
|
161
|
-
4. **Whitespace trimming** -- Remove all leading and
|
|
162
|
-
trailing whitespace characters (spaces, tabs,
|
|
163
|
-
newlines, carriage returns, and other Unicode
|
|
164
|
-
whitespace and control characters).
|
|
165
|
-
|
|
166
|
-
### Scope
|
|
167
|
-
|
|
168
|
-
This pipeline applies to **text and code sections
|
|
169
|
-
only**. Image sections use the base64-encoded string
|
|
170
|
-
as-is -- no preprocessing is applied.
|
|
171
|
-
|
|
172
|
-
The preprocessed content is what gets stored on disk.
|
|
173
|
-
The pipeline runs once at ingest time; subsequent
|
|
174
|
-
reads return the already-preprocessed content. The
|
|
175
|
-
`<byte-size>` in the hash header is computed from the
|
|
176
|
-
content after preprocessing.
|
|
177
|
-
|
|
178
|
-
## Section File Format
|
|
179
|
-
|
|
180
|
-
Each section file has a TOML header followed by a
|
|
181
|
-
`---` separator and the raw content body. The header
|
|
182
|
-
is human-readable; the content after the separator is
|
|
183
|
-
stored verbatim.
|
|
184
|
-
|
|
185
|
-
### Header Fields
|
|
186
|
-
|
|
187
|
-
| Field | Type | Required | Description |
|
|
188
|
-
|-----------------------|--------|----------|-----------------------|
|
|
189
|
-
| `kbid` | string | Yes | 26-character content hash |
|
|
190
|
-
| `docids` | array | Yes | Document IDs referencing this section |
|
|
191
|
-
| `type` | string | Yes | MIME type (`text/markdown`, `text/typescript`, `image/png`, etc.) |
|
|
192
|
-
| `title` | string | Images: yes, others: no | Short descriptive title. Indexed with heading weight (2.0x) |
|
|
193
|
-
| `description` | string | No | Longer description. Indexed with body weight (1.0x) |
|
|
194
|
-
| `size` | u32 | Yes | Content byte size |
|
|
195
|
-
| `token_count` | u32 | Yes | Total tokens after tokenization |
|
|
196
|
-
| `heading_token_count` | u32 | Yes | Tokens from `title` |
|
|
197
|
-
| `body_token_count` | u32 | Yes | Tokens from body text + `description` |
|
|
198
|
-
| `code_token_count` | u32 | Yes | Tokens from code content |
|
|
199
|
-
| `created_at` | string | Yes | ISO 8601 timestamp |
|
|
200
|
-
| `checksum` | string | Yes | Integrity checksum |
|
|
201
|
-
|
|
202
|
-
The `title` and `description` fields are not included
|
|
203
|
-
in the kbid hash -- changing them does not change the
|
|
204
|
-
section's identity.
|
|
205
|
-
|
|
206
|
-
Token count fields are pre-computed at insertion time
|
|
207
|
-
by `query-parser.wasm` and stored for reuse at query
|
|
208
|
-
time. This trades a small write-time cost for
|
|
209
|
-
significant search speed.
|
|
210
|
-
|
|
211
|
-
### Example: Text Section
|
|
212
|
-
|
|
213
|
-
File: `sections/ab/cdef1234...sec`
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
kbid = "abcdef1234567890abcdef1234"
|
|
217
|
-
docids = ["doc-5678"]
|
|
218
|
-
type = "text/markdown"
|
|
219
|
-
title = "Architecture Overview"
|
|
220
|
-
description = "High-level overview of the system"
|
|
221
|
-
size = 1234
|
|
222
|
-
token_count = 187
|
|
223
|
-
heading_token_count = 2
|
|
224
|
-
body_token_count = 187
|
|
225
|
-
code_token_count = 0
|
|
226
|
-
created_at = "2026-06-15T10:00:00Z"
|
|
227
|
-
checksum = "sha256:abcdef..."
|
|
228
|
-
---
|
|
229
|
-
Section body text here.
|
|
230
|
-
|
|
231
|
-
$(image: 7fa93b2e4c8d1076a93b2e4c8d)
|
|
232
|
-
|
|
233
|
-
$(code: c4e8a91d3f7b20564e8a91d3f7)
|
|
234
|
-
|
|
235
|
-
This content continues after the embedded sections.
|
|
236
|
-
No escaping or encoding is applied.
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Example: Code Section
|
|
240
|
-
|
|
241
|
-
File: `sections/c4/e8a91d...sec`
|
|
242
|
-
|
|
243
|
-
```
|
|
244
|
-
kbid = "c4e8a91d3f7b20564e8a91d3f7"
|
|
245
|
-
docids = ["doc-5678"]
|
|
246
|
-
type = "text/typescript"
|
|
247
|
-
title = "greet function"
|
|
248
|
-
size = 256
|
|
249
|
-
token_count = 22
|
|
250
|
-
heading_token_count = 2
|
|
251
|
-
body_token_count = 0
|
|
252
|
-
code_token_count = 22
|
|
253
|
-
created_at = "2026-06-15T10:15:00Z"
|
|
254
|
-
checksum = "sha256:1a2b3c..."
|
|
255
|
-
---
|
|
256
|
-
export function greet(name: string): string {
|
|
257
|
-
return `Hello, ${name}!`;
|
|
258
|
-
}
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Example: Image Section
|
|
262
|
-
|
|
263
|
-
File: `sections/7f/a93b2e...sec`
|
|
264
|
-
|
|
265
|
-
```
|
|
266
|
-
kbid = "7fa93b2e4c8d1076a93b2e4c8d"
|
|
267
|
-
docids = ["doc-5678"]
|
|
268
|
-
type = "image/png"
|
|
269
|
-
title = "Architecture diagram"
|
|
270
|
-
description = "Five-layer stack diagram"
|
|
271
|
-
size = 48576
|
|
272
|
-
token_count = 5
|
|
273
|
-
heading_token_count = 2
|
|
274
|
-
body_token_count = 3
|
|
275
|
-
code_token_count = 0
|
|
276
|
-
created_at = "2026-06-15T10:30:00Z"
|
|
277
|
-
checksum = "sha256:fedcba..."
|
|
278
|
-
---
|
|
279
|
-
iVBORw0KGgoAAAANSUhEUgAA...base64 data...
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
The image section has `token_count = 5` from title
|
|
283
|
-
and description tokens only. Binary content produces
|
|
284
|
-
zero tokens.
|
|
285
|
-
|
|
286
|
-
### Section Types
|
|
287
|
-
|
|
288
|
-
| Type | Content after `---` | Indexed? |
|
|
289
|
-
|---------------------|------------------------|----------|
|
|
290
|
-
| `text/markdown` | Raw markdown text | Yes (body field) |
|
|
291
|
-
| `text/*` (code) | Raw source code | Yes (code field) |
|
|
292
|
-
| `application/json` | Raw JSON | Yes (code field) |
|
|
293
|
-
| `image/*` | Base64-encoded binary | No (metadata only) |
|
|
294
|
-
|
|
295
|
-
Code sections are processed through the same
|
|
296
|
-
tokenization pipeline as text, including identifier
|
|
297
|
-
splitting for camelCase and snake_case terms. Image
|
|
298
|
-
binary content is skipped, but `title` (required) and
|
|
299
|
-
`description` (optional) are tokenized and indexed.
|
|
300
|
-
|
|
301
|
-
## Document Manifests
|
|
302
|
-
|
|
303
|
-
A document groups sections under a title with a
|
|
304
|
-
defined order. Documents do not contain content
|
|
305
|
-
directly -- they reference sections by kbid. The
|
|
306
|
-
relationship is many-to-many: a section may appear in
|
|
307
|
-
multiple documents, and a document contains multiple
|
|
308
|
-
sections.
|
|
309
|
-
|
|
310
|
-
### Format
|
|
311
|
-
|
|
312
|
-
```toml
|
|
313
|
-
[document]
|
|
314
|
-
docid = "doc-5678"
|
|
315
|
-
title = "Getting Started Guide"
|
|
316
|
-
created_at = "2026-06-15T10:00:00Z"
|
|
317
|
-
|
|
318
|
-
[[sections]]
|
|
319
|
-
kbid = "abcdef1234567890abcdef1234"
|
|
320
|
-
position = 0
|
|
321
|
-
|
|
322
|
-
[[sections]]
|
|
323
|
-
kbid = "fedcba4321098765fedcba4321"
|
|
324
|
-
position = 1
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Fields
|
|
328
|
-
|
|
329
|
-
| Field | Description |
|
|
330
|
-
|--------------------------|--------------------------|
|
|
331
|
-
| `document.docid` | Document identifier |
|
|
332
|
-
| `document.title` | Human-readable title |
|
|
333
|
-
| `document.created_at` | ISO 8601 timestamp |
|
|
334
|
-
| `sections[].kbid` | Section content hash |
|
|
335
|
-
| `sections[].position` | Zero-based display order |
|
|
336
|
-
|
|
337
|
-
Documents are human-readable and diffable in git.
|
|
338
|
-
When a document is retrieved, its sections are
|
|
339
|
-
returned in position order with full content.
|
|
340
|
-
|
|
341
|
-
## Catalog (`catalog.toml`)
|
|
342
|
-
|
|
343
|
-
The catalog is the database's table of contents --
|
|
344
|
-
the first file read when opening a database. It
|
|
345
|
-
records high-level state without requiring a
|
|
346
|
-
directory scan.
|
|
347
|
-
|
|
348
|
-
```toml
|
|
349
|
-
[database]
|
|
350
|
-
version = 1
|
|
351
|
-
created_at = "2026-06-15T10:00:00Z"
|
|
352
|
-
last_modified = "2026-06-15T12:00:00Z"
|
|
353
|
-
|
|
354
|
-
[counts]
|
|
355
|
-
sections = 42
|
|
356
|
-
documents = 5
|
|
357
|
-
|
|
358
|
-
[integrity]
|
|
359
|
-
checksum = "sha256:abcdef..."
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
Updated on every write operation. If a crash occurs
|
|
363
|
-
mid-write, the catalog remains consistent with the
|
|
364
|
-
last complete state (see Write Safety below).
|
|
365
|
-
|
|
366
|
-
## MIME Types
|
|
367
|
-
|
|
368
|
-
kbdb uses standard MIME type strings to identify
|
|
369
|
-
section content:
|
|
370
|
-
|
|
371
|
-
| Category | MIME types | Canonical |
|
|
372
|
-
|-----------|-------------------------------------|-----------------|
|
|
373
|
-
| Text | `text/markdown` | `text/markdown` |
|
|
374
|
-
| Code | `text/typescript`, `text/javascript`, `text/html`, `text/css`, `text/xml`, `text/plain`, `application/json` | Varies |
|
|
375
|
-
| Image | `image/png`, `image/jpeg`, `image/webp` | Varies |
|
|
376
|
-
|
|
377
|
-
The bare string `"text"` is not used. Text sections
|
|
378
|
-
use `text/markdown` as their canonical type. The MIME
|
|
379
|
-
type is part of the kbid hash, so the same raw
|
|
380
|
-
content stored under different types produces
|
|
381
|
-
different section files.
|
|
382
|
-
|
|
383
|
-
## Write Safety
|
|
384
|
-
|
|
385
|
-
All write operations are designed to be crash-safe:
|
|
386
|
-
|
|
387
|
-
- **Atomic writes** -- New files are written to a
|
|
388
|
-
temporary path and then renamed into place. A crash
|
|
389
|
-
during the write leaves no partial files -- either
|
|
390
|
-
the old file remains or the new file is complete.
|
|
391
|
-
|
|
392
|
-
- **Catalog updated last** -- The catalog is written
|
|
393
|
-
after all data files. A crash mid-write leaves the
|
|
394
|
-
catalog consistent with the last fully committed
|
|
395
|
-
state. The worst case is an unreferenced section
|
|
396
|
-
file on disk, which garbage collection handles.
|
|
397
|
-
|
|
398
|
-
- **Indexes rebuildable** -- Index files are derived
|
|
399
|
-
data. If index files are corrupted or lost, they
|
|
400
|
-
can be rebuilt entirely from sections and document
|
|
401
|
-
manifests. The `.gitignore` excludes indexes from
|
|
402
|
-
version control because they are not source data.
|
|
403
|
-
|
|
404
|
-
### Write Sequence
|
|
405
|
-
|
|
406
|
-
```
|
|
407
|
-
1. Write section file to temp path
|
|
408
|
-
|
|
|
409
|
-
v
|
|
410
|
-
2. Rename temp file into sections/{ab}/{kbid}.sec
|
|
411
|
-
|
|
|
412
|
-
v
|
|
413
|
-
3. Update document manifest (if docid provided)
|
|
414
|
-
|
|
|
415
|
-
v
|
|
416
|
-
4. Update indexes (inverted + positional + corpus)
|
|
417
|
-
|
|
|
418
|
-
v
|
|
419
|
-
5. Update catalog.toml (counts, timestamp, checksum)
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
Each step is atomic. The catalog update in step 5
|
|
423
|
-
commits the entire operation. Steps 1-4 can fail
|
|
424
|
-
without corrupting the database.
|
|
425
|
-
|
|
426
|
-
## Content Markers
|
|
427
|
-
|
|
428
|
-
Text sections can contain markers -- escape sequences
|
|
429
|
-
that embed or link to other sections and documents.
|
|
430
|
-
Markers are stored verbatim in the content body and
|
|
431
|
-
resolved at read time, not at write time.
|
|
432
|
-
|
|
433
|
-
### Marker Types
|
|
434
|
-
|
|
435
|
-
| Marker | Category | Target type | Render behavior |
|
|
436
|
-
|-----------------------------|-----------|--------------------------|------------------------|
|
|
437
|
-
| `$(image: {kbid})` | Embedding | `image/*` section | Inline image |
|
|
438
|
-
| `$(code: {kbid})` | Embedding | `text/*` or `application/json` section | Fenced code block |
|
|
439
|
-
| `$(text: {kbid})` | Embedding | `text/markdown` section | Inline markdown (recursive) |
|
|
440
|
-
| `$(document: {docid})` | Embedding | Document manifest | All sections expanded (recursive) |
|
|
441
|
-
| `$(link: {kbid})` | Link | Any section | Cross-reference |
|
|
442
|
-
| `$(doc-link: {docid})` | Link | Document manifest | Cross-reference |
|
|
443
|
-
|
|
444
|
-
### Syntax
|
|
445
|
-
|
|
446
|
-
Markers use the format `$(type: value)`:
|
|
447
|
-
|
|
448
|
-
```
|
|
449
|
-
$(image: 7fa93b2e4c8d1076a93b2e4c8d)
|
|
450
|
-
$(code: c4e8a91d3f7b20564e8a91d3f7)
|
|
451
|
-
$(text: a1b2c3d4e5f6a1b2c3d4e5f6a1)
|
|
452
|
-
$(document: api-reference-v2)
|
|
453
|
-
$(link: d5e6f7a8b9c0d5e6f7a8b9c0d5)
|
|
454
|
-
$(doc-link: getting-started-guide)
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
Rules:
|
|
458
|
-
- A colon and a space separate type from value.
|
|
459
|
-
- Markers cannot be nested.
|
|
460
|
-
- Unrecognized types pass through unchanged.
|
|
461
|
-
- Unclosed markers are treated as plain text.
|
|
462
|
-
|
|
463
|
-
### Recursive Resolution
|
|
464
|
-
|
|
465
|
-
The `$(text:)` and `$(document:)` markers trigger
|
|
466
|
-
recursive expansion -- the embedded content may
|
|
467
|
-
itself contain markers that must be resolved.
|
|
468
|
-
|
|
469
|
-
Circular references are detected using a visited set:
|
|
470
|
-
|
|
471
|
-
```
|
|
472
|
-
Expand marker $(text: A)
|
|
473
|
-
|
|
|
474
|
-
v
|
|
475
|
-
Add A to visited set: {A}
|
|
476
|
-
|
|
|
477
|
-
v
|
|
478
|
-
Section A contains $(text: B)
|
|
479
|
-
|
|
|
480
|
-
v
|
|
481
|
-
Add B to visited set: {A, B}
|
|
482
|
-
|
|
|
483
|
-
v
|
|
484
|
-
Section B contains $(text: A)
|
|
485
|
-
|
|
|
486
|
-
v
|
|
487
|
-
A is already in visited set -> STOP (circular)
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
Circular references are reported as errors during
|
|
491
|
-
both integrity checks and render-time expansion.
|
|
492
|
-
|
|
493
|
-
### Tokenization
|
|
494
|
-
|
|
495
|
-
All six marker types are stripped from content before
|
|
496
|
-
tokenization and indexing (stage 1 of the
|
|
497
|
-
tokenization pipeline). Markers are structural
|
|
498
|
-
references, not searchable text -- they do not appear
|
|
499
|
-
in the search index.
|
|
500
|
-
|
|
501
|
-
## Deduplication
|
|
502
|
-
|
|
503
|
-
Sections are content-addressable. When identical
|
|
504
|
-
content (after preprocessing) is added with the same
|
|
505
|
-
MIME type:
|
|
506
|
-
|
|
507
|
-
| Scenario | Result |
|
|
508
|
-
|-----------------------|-----------------------------|
|
|
509
|
-
| Different `docid` | Existing section's `docids` array updated to include the new docid. No new file created. |
|
|
510
|
-
| No `docid` | Section skipped entirely. |
|
|
511
|
-
| Same `docid` already present | Idempotent -- no change. |
|
|
512
|
-
|
|
513
|
-
A section can belong to zero or more documents.
|
|
514
|
-
Updating a section's content creates a new file with
|
|
515
|
-
a new kbid; the old file becomes eligible for garbage
|
|
516
|
-
collection.
|
|
517
|
-
|
|
518
|
-
## Storage Performance
|
|
519
|
-
|
|
520
|
-
The directory layout is optimized for read speed:
|
|
521
|
-
|
|
522
|
-
| Operation | Complexity | Mechanism |
|
|
523
|
-
|-------------------|------------|-------------------------|
|
|
524
|
-
| Section lookup | O(1) | Hash-sharded directories allow direct file access by kbid |
|
|
525
|
-
| Term lookup | O(log n) | B+ tree indexes |
|
|
526
|
-
| Catalog discovery | O(1) | `catalog.toml` provides counts without scanning |
|
|
527
|
-
| Document listing | O(1) | Direct file access by docid |
|
|
528
|
-
|
|
529
|
-
Write operations prioritize safety over speed. The
|
|
530
|
-
atomic write + catalog-last pattern ensures no
|
|
531
|
-
partial state is visible after a crash.
|