@dikolab/kbdb 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLA.md +68 -0
- package/LICENSE +676 -12
- package/LICENSING.md +58 -0
- package/README.md +50 -25
- package/README.md.bak +322 -0
- package/dist/README.md +322 -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/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 +11 -10
- 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/0.5.0.md +0 -41
- package/docs/release-notes/README.md +0 -16
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
# Semantic Near-Duplicate Detection
|
|
2
|
-
|
|
3
|
-
*Cosine similarity on embeddings as a complementary
|
|
4
|
-
detection layer alongside Jaccard -- closes the
|
|
5
|
-
vocabulary-gap ceiling identified in gap #6.*
|
|
6
|
-
|
|
7
|
-
## Goal
|
|
8
|
-
|
|
9
|
-
The existing near-duplicate detection computes a Jaccard
|
|
10
|
-
coefficient on stemmed term sets of the incoming section
|
|
11
|
-
versus all indexed sections. Sections that exceed a
|
|
12
|
-
similarity threshold of 0.85 are reported as
|
|
13
|
-
near-duplicates in `AddSectionResult.near_duplicates`.
|
|
14
|
-
|
|
15
|
-
This mechanism catches lexically similar content
|
|
16
|
-
reliably. It does not catch semantically equivalent
|
|
17
|
-
sections that use different vocabulary. Example: a
|
|
18
|
-
section stored as "We selected PostgreSQL for its JSONB
|
|
19
|
-
support" and a later section written as "Chose Postgres
|
|
20
|
-
due to native JSON column type" express the same
|
|
21
|
-
decision. Their stemmed term sets share few tokens --
|
|
22
|
-
Jaccard produces a low score, no duplicate is flagged,
|
|
23
|
-
and the knowledge base silently accumulates redundant
|
|
24
|
-
content.
|
|
25
|
-
|
|
26
|
-
This gap is identified as the semantic dedup ceiling in
|
|
27
|
-
[Opus 4.8 Second Brain Review](../issues/2026-06-23-opus-48-second-brain-review.md)
|
|
28
|
-
(gap #6). Semantic dedup closes it by adding a cosine
|
|
29
|
-
similarity pass on embedding vectors as a complementary
|
|
30
|
-
detection method when an embedding provider is
|
|
31
|
-
configured. The feature is conditional on
|
|
32
|
-
[Hybrid Search](hybrid-search.md) -- if no
|
|
33
|
-
`EmbeddingProvider` is configured, only the Jaccard pass
|
|
34
|
-
runs and behaviour is identical to today.
|
|
35
|
-
|
|
36
|
-
## Two-Pass Detection Algorithm
|
|
37
|
-
|
|
38
|
-
Detection proceeds in two sequential passes on every
|
|
39
|
-
`add_section` call.
|
|
40
|
-
|
|
41
|
-
### Pass 1: Jaccard (always runs)
|
|
42
|
-
|
|
43
|
-
Compute the Jaccard coefficient between the incoming
|
|
44
|
-
section's stemmed term set and each existing section's
|
|
45
|
-
term set. The term sets are derived from the inverted
|
|
46
|
-
index -- no section files are read.
|
|
47
|
-
|
|
48
|
-
Sections whose Jaccard score meets or exceeds 0.85 are
|
|
49
|
-
flagged as lexical near-duplicates and appended to
|
|
50
|
-
`near_duplicates` with `method: "jaccard"`.
|
|
51
|
-
|
|
52
|
-
Sections whose Jaccard score falls in the range
|
|
53
|
-
[0.40, 0.85) -- the gray zone -- are retained as
|
|
54
|
-
candidates for Pass 2.
|
|
55
|
-
|
|
56
|
-
Sections with a Jaccard score below 0.40 are discarded
|
|
57
|
-
with no further processing.
|
|
58
|
-
|
|
59
|
-
### Pass 2: Cosine (when embeddings available)
|
|
60
|
-
|
|
61
|
-
Pass 2 runs when the active `EmbeddingProvider` has
|
|
62
|
-
non-zero dimensions and `vectors.idx` is present and
|
|
63
|
-
not stale. With the built-in `TfidfEmbeddingProvider`
|
|
64
|
-
as the default (256 dimensions), Pass 2 runs
|
|
65
|
-
automatically without configuration. It is skipped
|
|
66
|
-
only when embeddings are explicitly disabled
|
|
67
|
-
(`provider = "none"` in `worker.toml`).
|
|
68
|
-
|
|
69
|
-
For each gray-zone candidate from Pass 1, retrieve the
|
|
70
|
-
candidate's embedding from `vectors.idx`. If the
|
|
71
|
-
candidate's embedding is missing (e.g. the embedding
|
|
72
|
-
provider failed when that section was learned), skip
|
|
73
|
-
that candidate silently. Compute cosine similarity
|
|
74
|
-
between the incoming section's embedding and the
|
|
75
|
-
candidate's embedding.
|
|
76
|
-
|
|
77
|
-
The incoming section's embedding is computed by the
|
|
78
|
-
daemon as part of the same learn operation that triggers
|
|
79
|
-
the add (see the embedding lifecycle in
|
|
80
|
-
[Hybrid Search](hybrid-search.md)). If the embedding
|
|
81
|
-
computation for the incoming section itself failed, Pass
|
|
82
|
-
2 is skipped entirely for that call.
|
|
83
|
-
|
|
84
|
-
Candidates whose cosine similarity meets or exceeds 0.92
|
|
85
|
-
are flagged as semantic near-duplicates and appended to
|
|
86
|
-
`near_duplicates` with `method: "cosine"`.
|
|
87
|
-
|
|
88
|
-
### Efficiency Rationale
|
|
89
|
-
|
|
90
|
-
Jaccard operates on integer set intersections over the
|
|
91
|
-
inverted index -- it is cheap. Cosine operates on
|
|
92
|
-
floating-point vector dot products and requires reading
|
|
93
|
-
from `vectors.idx` -- it is more expensive. Restricting
|
|
94
|
-
cosine to the gray zone (Jaccard >= 0.40) means cosine
|
|
95
|
-
is invoked only for sections that already share moderate
|
|
96
|
-
lexical overlap with the candidate. Sections with very
|
|
97
|
-
low Jaccard scores are unlikely to be semantic
|
|
98
|
-
duplicates, so skipping them avoids unnecessary work
|
|
99
|
-
without meaningful loss in detection coverage.
|
|
100
|
-
|
|
101
|
-
## Detection Thresholds
|
|
102
|
-
|
|
103
|
-
| Method | Threshold | Meaning |
|
|
104
|
-
|------------------|-----------|------------------------------|
|
|
105
|
-
| Jaccard | >= 0.85 | Lexical near-duplicate |
|
|
106
|
-
| Jaccard pre-filter | >= 0.40 | Candidate for cosine pass |
|
|
107
|
-
| Cosine | >= 0.92 | Semantic near-duplicate |
|
|
108
|
-
|
|
109
|
-
Thresholds are not configurable in v1. They are
|
|
110
|
-
hardcoded constants. If operational experience shows
|
|
111
|
-
that the defaults produce excessive false positives or
|
|
112
|
-
false negatives, they can be exposed as `worker.toml`
|
|
113
|
-
configuration keys in a later version.
|
|
114
|
-
|
|
115
|
-
## Response Format
|
|
116
|
-
|
|
117
|
-
The `near_duplicates` array in `AddSectionResult` gains
|
|
118
|
-
a `method` field on every entry. The field identifies
|
|
119
|
-
which detection pass produced the entry.
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
{
|
|
123
|
-
"kbid": "<26-char hash>",
|
|
124
|
-
"near_duplicates": [
|
|
125
|
-
{
|
|
126
|
-
"kbid": "abc123...",
|
|
127
|
-
"similarity": 0.89,
|
|
128
|
-
"method": "jaccard"
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
"kbid": "def456...",
|
|
132
|
-
"similarity": 0.95,
|
|
133
|
-
"method": "cosine"
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
The `method` field is always present on every
|
|
140
|
-
near-duplicate entry, including in responses from
|
|
141
|
-
deployments where only Jaccard runs. Callers can rely
|
|
142
|
-
on the field being present unconditionally.
|
|
143
|
-
|
|
144
|
-
Entries produced by Pass 1 always carry `method:
|
|
145
|
-
"jaccard"`. Entries produced by Pass 2 always carry
|
|
146
|
-
`method: "cosine"`. No entry can carry both methods --
|
|
147
|
-
a section that crosses the Jaccard threshold of 0.85
|
|
148
|
-
is already flagged in Pass 1 and is not re-evaluated
|
|
149
|
-
in Pass 2.
|
|
150
|
-
|
|
151
|
-
## Dependency on Hybrid Search
|
|
152
|
-
|
|
153
|
-
Semantic dedup reuses the infrastructure introduced by
|
|
154
|
-
[Hybrid Search](hybrid-search.md) without adding any
|
|
155
|
-
new infrastructure of its own.
|
|
156
|
-
|
|
157
|
-
- The `EmbeddingProvider` interface defined in Hybrid
|
|
158
|
-
Search provides the embedding computation at learn
|
|
159
|
-
time.
|
|
160
|
-
- `vectors.idx` provides the embedding lookup at
|
|
161
|
-
duplicate-detection time. No second embedding call is
|
|
162
|
-
made -- the stored vectors are read directly.
|
|
163
|
-
- When `NullEmbeddingProvider` is active (no `[embedding]`
|
|
164
|
-
section in `worker.toml`), Pass 2 never runs. The
|
|
165
|
-
`near_duplicates` array may still contain Jaccard
|
|
166
|
-
entries; it will never contain cosine entries.
|
|
167
|
-
- Stale vector index conditions (model name mismatch
|
|
168
|
-
between `vectors-meta.toml` and the configured
|
|
169
|
-
provider) are treated the same as a missing
|
|
170
|
-
`vectors.idx`: Pass 2 is skipped for that call.
|
|
171
|
-
|
|
172
|
-
## Contradiction Detection Enhancement
|
|
173
|
-
|
|
174
|
-
The existing `divergent_content` integrity check
|
|
175
|
-
identifies sections that share the same `source_key`
|
|
176
|
-
but have different content -- contradictory knowledge
|
|
177
|
-
from the same origin that supersession should have
|
|
178
|
-
resolved.
|
|
179
|
-
|
|
180
|
-
With embeddings available, integrity check can extend
|
|
181
|
-
this check to surface potential semantic contradictions
|
|
182
|
-
that lack a shared source key: sections with high cosine
|
|
183
|
-
similarity (>= 0.92) and conflicting content signals.
|
|
184
|
-
This is a secondary, advisory output in the integrity
|
|
185
|
-
check response -- it does not block any operation.
|
|
186
|
-
|
|
187
|
-
The enhancement runs only when the integrity check is
|
|
188
|
-
invoked and `vectors.idx` is present and not stale. It
|
|
189
|
-
adds a new `semantic_contradictions` array to the
|
|
190
|
-
integrity check response, alongside the existing
|
|
191
|
-
`divergent_content` error entries:
|
|
192
|
-
|
|
193
|
-
```json
|
|
194
|
-
{
|
|
195
|
-
"semantic_contradictions": [
|
|
196
|
-
{
|
|
197
|
-
"kbid_a": "abc123...",
|
|
198
|
-
"kbid_b": "def456...",
|
|
199
|
-
"cosine_similarity": 0.94
|
|
200
|
-
}
|
|
201
|
-
]
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
When no embedding provider is configured or
|
|
206
|
-
`vectors.idx` is absent, `semantic_contradictions` is
|
|
207
|
-
an empty array.
|
|
208
|
-
|
|
209
|
-
## Design Constraints
|
|
210
|
-
|
|
211
|
-
- Semantic dedup is additive. It never replaces the
|
|
212
|
-
Jaccard pass. Both passes coexist, and the Jaccard
|
|
213
|
-
pass always runs regardless of embedding configuration.
|
|
214
|
-
- The `method` field is always present on
|
|
215
|
-
`near_duplicates` entries, even in responses from
|
|
216
|
-
deployments where only Jaccard runs.
|
|
217
|
-
- Cosine similarity computation reuses existing
|
|
218
|
-
embedding vectors stored in `vectors.idx`. No
|
|
219
|
-
additional embedding API call is made during
|
|
220
|
-
duplicate detection.
|
|
221
|
-
- If Pass 2 is skipped (no provider, stale index, or
|
|
222
|
-
embedding failure for the incoming section), the
|
|
223
|
-
response omits cosine entries silently. No warning
|
|
224
|
-
field is added for a skipped cosine pass -- the
|
|
225
|
-
absence of cosine entries is not an error condition
|
|
226
|
-
and is expected in lexical-only deployments.
|
|
227
|
-
- Thresholds are hardcoded in v1. Exposure as
|
|
228
|
-
configuration keys is deferred to a later version
|
|
229
|
-
after operational validation.
|
|
230
|
-
- The `semantic_contradictions` enhancement to integrity
|
|
231
|
-
check is advisory. It does not change `ok` to `false`
|
|
232
|
-
on its own -- it provides supplementary information
|
|
233
|
-
for human review.
|