crewly 1.20.398 → 1.20.399

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 (35) hide show
  1. package/config/constants.ts +22 -0
  2. package/dist/backend/backend/src/constants.d.ts +5 -0
  3. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  4. package/dist/backend/backend/src/services/memory/agent-memory.service.d.ts +9 -4
  5. package/dist/backend/backend/src/services/memory/agent-memory.service.d.ts.map +1 -1
  6. package/dist/backend/backend/src/services/memory/agent-memory.service.js +47 -23
  7. package/dist/backend/backend/src/services/memory/agent-memory.service.js.map +1 -1
  8. package/dist/backend/backend/src/services/memory/knowledge-similarity.d.ts +206 -0
  9. package/dist/backend/backend/src/services/memory/knowledge-similarity.d.ts.map +1 -0
  10. package/dist/backend/backend/src/services/memory/knowledge-similarity.js +319 -0
  11. package/dist/backend/backend/src/services/memory/knowledge-similarity.js.map +1 -0
  12. package/dist/backend/build-info.json +2 -2
  13. package/dist/backend/config/constants.d.ts +21 -0
  14. package/dist/backend/config/constants.d.ts.map +1 -1
  15. package/dist/backend/config/constants.js +21 -0
  16. package/dist/backend/config/constants.js.map +1 -1
  17. package/dist/backend/config/index.d.ts +5 -0
  18. package/dist/backend/config/index.d.ts.map +1 -1
  19. package/dist/cli/backend/src/constants.d.ts +5 -0
  20. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  21. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts +9 -4
  22. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts.map +1 -1
  23. package/dist/cli/backend/src/services/memory/agent-memory.service.js +47 -23
  24. package/dist/cli/backend/src/services/memory/agent-memory.service.js.map +1 -1
  25. package/dist/cli/backend/src/services/memory/knowledge-similarity.d.ts +206 -0
  26. package/dist/cli/backend/src/services/memory/knowledge-similarity.d.ts.map +1 -0
  27. package/dist/cli/backend/src/services/memory/knowledge-similarity.js +319 -0
  28. package/dist/cli/backend/src/services/memory/knowledge-similarity.js.map +1 -0
  29. package/dist/cli/config/constants.d.ts +21 -0
  30. package/dist/cli/config/constants.d.ts.map +1 -1
  31. package/dist/cli/config/constants.js +21 -0
  32. package/dist/cli/config/constants.js.map +1 -1
  33. package/dist/cli/config/index.d.ts +5 -0
  34. package/dist/cli/config/index.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Near-duplicate detection and evidence merge for role knowledge (#914 P1).
3
+ *
4
+ * `addRoleKnowledge` used to dedupe by exact match or substring containment
5
+ * only, so the same fact written twice with a different id, count or date
6
+ * in it ("Refresh standing answer … (1 newer)" / "… (6 newer)") became two
7
+ * entries, and recall surfaced both. This module replaces that check with
8
+ * a cheap nearest-neighbour over token sets:
9
+ *
10
+ * - `knowledgeTokens` lowercases, splits on non-alphanumerics and drops the
11
+ * tokens that vary between restatements of one fact (uuids, hex ids,
12
+ * long digit runs, single letters);
13
+ * - `jaccard` is the set overlap of two token sets;
14
+ * - `numbersCompatible` keeps two texts apart when they disagree on a
15
+ * number (ticket, count, version): the frame may be identical, the fact
16
+ * is not;
17
+ * - `findNearestKnowledge` returns the best candidate in the same scope
18
+ * (same category; overlapping tags when both sides have tags), an exact
19
+ * or substring match first, else the highest Jaccard at or above the
20
+ * threshold among number-compatible entries. Superseded and expired
21
+ * entries are never candidates, so a new write cannot reinforce a dead
22
+ * fact. Short texts (fewer than `MIN_TOKENS_FOR_NEAR` tokens) match
23
+ * exactly or not at all.
24
+ * - `mergeKnowledgeEvidence` folds the incoming entry's provenance into the
25
+ * existing one (exact match): evidence union, importance max,
26
+ * verification timestamp. The existing content stays.
27
+ * - `restateKnowledge` handles a near match: the newest wording becomes a
28
+ * new entry with the old provenance and reinforcement, the old entry is
29
+ * marked superseded by it and kept for audit. The LLM adjudication the
30
+ * issue describes (keep / modify / supersede by judgment) is a later,
31
+ * possibly Pro, step; this is the deterministic rule.
32
+ * - `evictionIndex` picks what a full store drops: superseded first.
33
+ *
34
+ * Pure functions only; the threshold was set by replaying the owner's
35
+ * 3.7k real entries (see spec `2026-10-25-knowledge-evidence-merge.md`).
36
+ *
37
+ * @module services/memory/knowledge-similarity
38
+ */
39
+ import type { RoleKnowledgeEntry } from '../../types/memory.types.js';
40
+ /** The fields the similarity check reads from an existing entry. */
41
+ export type KnowledgeLike = Pick<RoleKnowledgeEntry, 'content' | 'category' | 'tags' | 'superseded' | 'supersededBy' | 'ttl'>;
42
+ /** The fields the similarity check reads from an incoming entry. */
43
+ export type IncomingKnowledge = Pick<RoleKnowledgeEntry, 'content'> & Partial<Pick<RoleKnowledgeEntry, 'category' | 'tags'>>;
44
+ /** How an existing entry matched the incoming one. */
45
+ export type MatchKind = 'exact' | 'near';
46
+ /** The nearest existing entry and how close it is. */
47
+ export interface NearestMatch<T> {
48
+ /** The existing entry */
49
+ entry: T;
50
+ /** 1 for an exact or substring match, else the Jaccard overlap */
51
+ score: number;
52
+ /** Exact (legacy rule) or near (token overlap at or above the threshold) */
53
+ kind: MatchKind;
54
+ }
55
+ /** Options for {@link findNearestKnowledge}. */
56
+ export interface NearestOptions {
57
+ /** Jaccard at or above which a candidate is a near-duplicate; defaults to the constant */
58
+ threshold?: number;
59
+ /** Reference instant for the expiry check; defaults to now */
60
+ now?: Date;
61
+ }
62
+ /**
63
+ * Tokens of a knowledge text that survive a restatement: lowercase words
64
+ * and numbers up to five digits, without uuids, hex ids, long digit runs or
65
+ * single letters. Single digits stay: "entry 0" and "entry 1" are two
66
+ * facts.
67
+ *
68
+ * @param text - Entry content
69
+ * @returns Distinct tokens
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * knowledgeTokens('Claimed WorkItem X (id: 51851ddb-3e5f-48b4-b73a-fccbc6a79abb) at 2026-10-25, 3 newer')
74
+ * // Set { 'claimed', 'workitem', 'id', 'at', '2026', '10', '25', '3', 'newer' }
75
+ * ```
76
+ */
77
+ export declare function knowledgeTokens(text: string): Set<string>;
78
+ /**
79
+ * Whether two token sets agree on their numbers: one side's numbers must
80
+ * all appear on the other. "verify CE-140" and "verify CE-196" share every
81
+ * word and differ in one number — two facts, however alike the frame.
82
+ * "snapshot 10/13 03:40Z" and "snapshot 10/13" are one fact, the second
83
+ * just shorter. Disagreeing counts ("1 newer" / "6 newer") are kept apart
84
+ * on purpose: a false merge loses knowledge, a missed one only leaves a
85
+ * duplicate.
86
+ *
87
+ * @param a - First token set
88
+ * @param b - Second token set
89
+ * @returns true when the numbers of one set are a subset of the other's
90
+ */
91
+ export declare function numbersCompatible(a: Set<string>, b: Set<string>): boolean;
92
+ /**
93
+ * Jaccard overlap of two token sets: |A ∩ B| / |A ∪ B|.
94
+ *
95
+ * @param a - First set
96
+ * @param b - Second set
97
+ * @returns 0 when either set is empty, else the overlap in [0, 1]
98
+ */
99
+ export declare function jaccard(a: Set<string>, b: Set<string>): number;
100
+ /**
101
+ * Whether an existing entry is in the incoming entry's scope: the same
102
+ * category when the incoming one names a category, and at least one shared
103
+ * tag when both carry tags.
104
+ *
105
+ * @param existing - Existing entry
106
+ * @param incoming - Incoming entry
107
+ * @returns true when the two may be compared
108
+ */
109
+ export declare function sameScope(existing: Partial<Pick<KnowledgeLike, 'category' | 'tags'>>, incoming: Partial<Pick<IncomingKnowledge, 'category' | 'tags'>>): boolean;
110
+ /**
111
+ * Equal after trim and lowercase.
112
+ *
113
+ * @param existing - Existing content
114
+ * @param incoming - Incoming content
115
+ * @returns true when the two texts are the same
116
+ */
117
+ export declare function isSameText(existing: string, incoming: string): boolean;
118
+ /**
119
+ * One text contains the other, when the incoming text is longer than the
120
+ * substring floor (the legacy containment rule).
121
+ *
122
+ * @param existing - Existing content
123
+ * @param incoming - Incoming content
124
+ * @returns true for a containment match
125
+ */
126
+ export declare function containsText(existing: string, incoming: string): boolean;
127
+ /**
128
+ * The legacy rule: {@link isSameText} or {@link containsText}.
129
+ *
130
+ * @param existing - Existing content
131
+ * @param incoming - Incoming content
132
+ * @returns true for an exact or containment match
133
+ */
134
+ export declare function isExactMatch(existing: string, incoming: string): boolean;
135
+ /**
136
+ * The existing entry the incoming one duplicates, if any: an exact match
137
+ * first, else the highest token overlap at or above the threshold, among
138
+ * entries in scope that recall still shows.
139
+ *
140
+ * @param knowledge - Existing entries
141
+ * @param incoming - Entry about to be written
142
+ * @param options - Threshold and reference time
143
+ * @returns The nearest match, or null when nothing is close enough
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const hit = findNearestKnowledge(memory.roleKnowledge, { content, category });
148
+ * if (hit) merge(hit.entry); else append(content);
149
+ * ```
150
+ */
151
+ export declare function findNearestKnowledge<T extends KnowledgeLike>(knowledge: T[], incoming: IncomingKnowledge, options?: NearestOptions): NearestMatch<T> | null;
152
+ /** What {@link mergeKnowledgeEvidence} changed on the existing entry. */
153
+ export interface MergeResult {
154
+ /** Evidence refs added (not already present) */
155
+ addedEvidence: string[];
156
+ /** Whether importance was raised to the incoming value */
157
+ importanceRaised: boolean;
158
+ }
159
+ /**
160
+ * Folds an incoming duplicate's provenance into the existing entry, in
161
+ * place: evidence becomes the union (legacy `learnedFrom` and
162
+ * `sourceTaskId` count as evidence), importance the max, and the entry is
163
+ * marked verified and used now. Content, confidence and ids are left to the
164
+ * caller.
165
+ *
166
+ * @param existing - Entry that stays (mutated)
167
+ * @param incoming - Duplicate that is not written
168
+ * @param now - Timestamp for `lastVerifiedAt` / `lastUsed`
169
+ * @returns What changed
170
+ */
171
+ export declare function mergeKnowledgeEvidence(existing: RoleKnowledgeEntry, incoming: Partial<Pick<RoleKnowledgeEntry, 'evidence' | 'learnedFrom' | 'sourceTaskId' | 'importance'>>, now?: Date): MergeResult;
172
+ /** Prefix of the evidence ref a superseded entry gets when a restatement replaced it. */
173
+ export declare const RESTATEMENT_REASON_PREFIX = "supersession-reason:restated";
174
+ /**
175
+ * A near-duplicate is the same fact said again, often with a correction
176
+ * ("I asserted X is a working symlink" → "X is a DANGLING symlink"), so the
177
+ * newest wording wins: the incoming entry becomes a new entry carrying the
178
+ * old one's provenance and reinforcement, and the old entry is marked
179
+ * superseded by it — hidden from recall, kept for audit, the same way
180
+ * `MemorySupersessionService.supersede` records an explicit supersession.
181
+ *
182
+ * @param old - Existing near-duplicate (mutated: superseded, evidence reason appended)
183
+ * @param incoming - Entry being written
184
+ * @param ids - The new entry's id and timestamp, and the match score for the audit ref
185
+ * @returns The new entry to store
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const fresh = restateKnowledge(match.entry, entry, { id: uuidv4(), now: new Date(), score: match.score });
190
+ * memory.roleKnowledge.push(fresh);
191
+ * ```
192
+ */
193
+ export declare function restateKnowledge(old: RoleKnowledgeEntry, incoming: Omit<RoleKnowledgeEntry, 'id' | 'createdAt'>, ids: {
194
+ id: string;
195
+ now: Date;
196
+ score: number;
197
+ }): RoleKnowledgeEntry;
198
+ /**
199
+ * Which entry to evict when a store is full: the oldest superseded entry
200
+ * first (recall no longer shows it), else the lowest-confidence live one.
201
+ *
202
+ * @param knowledge - Entries
203
+ * @returns Index to remove, or -1 for an empty list
204
+ */
205
+ export declare function evictionIndex(knowledge: RoleKnowledgeEntry[]): number;
206
+ //# sourceMappingURL=knowledge-similarity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-similarity.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/memory/knowledge-similarity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Near-duplicate detection and evidence merge for role knowledge (#914 P1).
3
+ *
4
+ * `addRoleKnowledge` used to dedupe by exact match or substring containment
5
+ * only, so the same fact written twice with a different id, count or date
6
+ * in it ("Refresh standing answer … (1 newer)" / "… (6 newer)") became two
7
+ * entries, and recall surfaced both. This module replaces that check with
8
+ * a cheap nearest-neighbour over token sets:
9
+ *
10
+ * - `knowledgeTokens` lowercases, splits on non-alphanumerics and drops the
11
+ * tokens that vary between restatements of one fact (uuids, hex ids,
12
+ * long digit runs, single letters);
13
+ * - `jaccard` is the set overlap of two token sets;
14
+ * - `numbersCompatible` keeps two texts apart when they disagree on a
15
+ * number (ticket, count, version): the frame may be identical, the fact
16
+ * is not;
17
+ * - `findNearestKnowledge` returns the best candidate in the same scope
18
+ * (same category; overlapping tags when both sides have tags), an exact
19
+ * or substring match first, else the highest Jaccard at or above the
20
+ * threshold among number-compatible entries. Superseded and expired
21
+ * entries are never candidates, so a new write cannot reinforce a dead
22
+ * fact. Short texts (fewer than `MIN_TOKENS_FOR_NEAR` tokens) match
23
+ * exactly or not at all.
24
+ * - `mergeKnowledgeEvidence` folds the incoming entry's provenance into the
25
+ * existing one (exact match): evidence union, importance max,
26
+ * verification timestamp. The existing content stays.
27
+ * - `restateKnowledge` handles a near match: the newest wording becomes a
28
+ * new entry with the old provenance and reinforcement, the old entry is
29
+ * marked superseded by it and kept for audit. The LLM adjudication the
30
+ * issue describes (keep / modify / supersede by judgment) is a later,
31
+ * possibly Pro, step; this is the deterministic rule.
32
+ * - `evictionIndex` picks what a full store drops: superseded first.
33
+ *
34
+ * Pure functions only; the threshold was set by replaying the owner's
35
+ * 3.7k real entries (see spec `2026-10-25-knowledge-evidence-merge.md`).
36
+ *
37
+ * @module services/memory/knowledge-similarity
38
+ */
39
+ import { MEMORY_CONSTANTS } from '../../constants.js';
40
+ import { isHiddenFromDefaultRecall } from './role-knowledge-eligibility.js';
41
+ /** A uuid anywhere in the text (work item, claim and task ids). */
42
+ const UUID = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
43
+ /**
44
+ * Hex runs of four or more characters with at least one digit: partial ids
45
+ * (`WI d3416d29`), commit shas, hashes. Plain words that happen to be hex
46
+ * letters (`face`, `bead`) have no digit and stay.
47
+ */
48
+ const HEX_ID = /^(?=.*\d)[0-9a-f]{4,}$/;
49
+ /** Digit runs of six or more: epoch values, compact dates, random suffixes. */
50
+ const LONG_NUMBER = /^\d{6,}$/;
51
+ /** A number that survived: ticket numbers, counts, versions, years. */
52
+ const NUMBER = /^\d+$/;
53
+ /** Anything that is not a letter or digit splits tokens. */
54
+ const NON_ALNUM = /[^\p{L}\p{N}]+/u;
55
+ /**
56
+ * Tokens of a knowledge text that survive a restatement: lowercase words
57
+ * and numbers up to five digits, without uuids, hex ids, long digit runs or
58
+ * single letters. Single digits stay: "entry 0" and "entry 1" are two
59
+ * facts.
60
+ *
61
+ * @param text - Entry content
62
+ * @returns Distinct tokens
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * knowledgeTokens('Claimed WorkItem X (id: 51851ddb-3e5f-48b4-b73a-fccbc6a79abb) at 2026-10-25, 3 newer')
67
+ * // Set { 'claimed', 'workitem', 'id', 'at', '2026', '10', '25', '3', 'newer' }
68
+ * ```
69
+ */
70
+ export function knowledgeTokens(text) {
71
+ const out = new Set();
72
+ for (const raw of text.toLowerCase().replace(UUID, ' ').split(NON_ALNUM)) {
73
+ if (raw.length === 0)
74
+ continue;
75
+ if (NUMBER.test(raw)) {
76
+ if (!LONG_NUMBER.test(raw))
77
+ out.add(raw);
78
+ continue;
79
+ }
80
+ if (raw.length === 1 || HEX_ID.test(raw))
81
+ continue;
82
+ out.add(raw);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Whether two token sets agree on their numbers: one side's numbers must
88
+ * all appear on the other. "verify CE-140" and "verify CE-196" share every
89
+ * word and differ in one number — two facts, however alike the frame.
90
+ * "snapshot 10/13 03:40Z" and "snapshot 10/13" are one fact, the second
91
+ * just shorter. Disagreeing counts ("1 newer" / "6 newer") are kept apart
92
+ * on purpose: a false merge loses knowledge, a missed one only leaves a
93
+ * duplicate.
94
+ *
95
+ * @param a - First token set
96
+ * @param b - Second token set
97
+ * @returns true when the numbers of one set are a subset of the other's
98
+ */
99
+ export function numbersCompatible(a, b) {
100
+ const na = [...a].filter((t) => NUMBER.test(t));
101
+ const nb = [...b].filter((t) => NUMBER.test(t));
102
+ return na.every((t) => b.has(t)) || nb.every((t) => a.has(t));
103
+ }
104
+ /**
105
+ * Jaccard overlap of two token sets: |A ∩ B| / |A ∪ B|.
106
+ *
107
+ * @param a - First set
108
+ * @param b - Second set
109
+ * @returns 0 when either set is empty, else the overlap in [0, 1]
110
+ */
111
+ export function jaccard(a, b) {
112
+ if (a.size === 0 || b.size === 0)
113
+ return 0;
114
+ let shared = 0;
115
+ for (const t of a)
116
+ if (b.has(t))
117
+ shared++;
118
+ return shared / (a.size + b.size - shared);
119
+ }
120
+ /**
121
+ * Whether an existing entry is in the incoming entry's scope: the same
122
+ * category when the incoming one names a category, and at least one shared
123
+ * tag when both carry tags.
124
+ *
125
+ * @param existing - Existing entry
126
+ * @param incoming - Incoming entry
127
+ * @returns true when the two may be compared
128
+ */
129
+ export function sameScope(existing, incoming) {
130
+ if (incoming.category && existing.category && incoming.category !== existing.category)
131
+ return false;
132
+ const a = incoming.tags ?? [];
133
+ const b = existing.tags ?? [];
134
+ if (a.length > 0 && b.length > 0 && !a.some((t) => b.includes(t)))
135
+ return false;
136
+ return true;
137
+ }
138
+ /**
139
+ * Equal after trim and lowercase.
140
+ *
141
+ * @param existing - Existing content
142
+ * @param incoming - Incoming content
143
+ * @returns true when the two texts are the same
144
+ */
145
+ export function isSameText(existing, incoming) {
146
+ return existing.toLowerCase().trim() === incoming.toLowerCase().trim();
147
+ }
148
+ /**
149
+ * One text contains the other, when the incoming text is longer than the
150
+ * substring floor (the legacy containment rule).
151
+ *
152
+ * @param existing - Existing content
153
+ * @param incoming - Incoming content
154
+ * @returns true for a containment match
155
+ */
156
+ export function containsText(existing, incoming) {
157
+ const a = existing.toLowerCase().trim();
158
+ const b = incoming.toLowerCase().trim();
159
+ return b.length > MEMORY_CONSTANTS.DEDUP.SUBSTRING_MIN_CHARS && (a.includes(b) || b.includes(a));
160
+ }
161
+ /**
162
+ * The legacy rule: {@link isSameText} or {@link containsText}.
163
+ *
164
+ * @param existing - Existing content
165
+ * @param incoming - Incoming content
166
+ * @returns true for an exact or containment match
167
+ */
168
+ export function isExactMatch(existing, incoming) {
169
+ return isSameText(existing, incoming) || containsText(existing, incoming);
170
+ }
171
+ /**
172
+ * The existing entry the incoming one duplicates, if any: an exact match
173
+ * first, else the highest token overlap at or above the threshold, among
174
+ * entries in scope that recall still shows.
175
+ *
176
+ * @param knowledge - Existing entries
177
+ * @param incoming - Entry about to be written
178
+ * @param options - Threshold and reference time
179
+ * @returns The nearest match, or null when nothing is close enough
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * const hit = findNearestKnowledge(memory.roleKnowledge, { content, category });
184
+ * if (hit) merge(hit.entry); else append(content);
185
+ * ```
186
+ */
187
+ export function findNearestKnowledge(knowledge, incoming, options = {}) {
188
+ const threshold = options.threshold ?? MEMORY_CONSTANTS.DEDUP.NEAR_DUPLICATE_JACCARD;
189
+ const now = options.now ?? new Date();
190
+ const incomingTokens = knowledgeTokens(incoming.content);
191
+ const nearAllowed = incomingTokens.size >= MEMORY_CONSTANTS.DEDUP.MIN_TOKENS_FOR_NEAR;
192
+ // Same text wins outright; a containment match beats any near match; among
193
+ // near matches the highest overlap wins.
194
+ let contained = null;
195
+ let near = null;
196
+ for (const entry of knowledge) {
197
+ if (isHiddenFromDefaultRecall(entry, now))
198
+ continue;
199
+ if (!sameScope(entry, incoming))
200
+ continue;
201
+ if (isSameText(entry.content, incoming.content))
202
+ return { entry, score: 1, kind: 'exact' };
203
+ if (contained === null && containsText(entry.content, incoming.content)) {
204
+ contained = { entry, score: 1, kind: 'exact' };
205
+ continue;
206
+ }
207
+ if (!nearAllowed)
208
+ continue;
209
+ const entryTokens = knowledgeTokens(entry.content);
210
+ if (!numbersCompatible(entryTokens, incomingTokens))
211
+ continue;
212
+ const score = jaccard(entryTokens, incomingTokens);
213
+ if (score >= threshold && (near === null || score > near.score))
214
+ near = { entry, score, kind: 'near' };
215
+ }
216
+ return contained ?? near;
217
+ }
218
+ /**
219
+ * Folds an incoming duplicate's provenance into the existing entry, in
220
+ * place: evidence becomes the union (legacy `learnedFrom` and
221
+ * `sourceTaskId` count as evidence), importance the max, and the entry is
222
+ * marked verified and used now. Content, confidence and ids are left to the
223
+ * caller.
224
+ *
225
+ * @param existing - Entry that stays (mutated)
226
+ * @param incoming - Duplicate that is not written
227
+ * @param now - Timestamp for `lastVerifiedAt` / `lastUsed`
228
+ * @returns What changed
229
+ */
230
+ export function mergeKnowledgeEvidence(existing, incoming, now = new Date()) {
231
+ const evidence = [...(existing.evidence ?? (existing.learnedFrom ? [existing.learnedFrom] : []))];
232
+ const addedEvidence = [];
233
+ for (const ref of [...(incoming.evidence ?? []), incoming.learnedFrom, incoming.sourceTaskId]) {
234
+ if (!ref || evidence.includes(ref))
235
+ continue;
236
+ evidence.push(ref);
237
+ addedEvidence.push(ref);
238
+ }
239
+ if (evidence.length > 0)
240
+ existing.evidence = evidence;
241
+ let importanceRaised = false;
242
+ if (incoming.importance !== undefined && incoming.importance > (existing.importance ?? 0)) {
243
+ existing.importance = incoming.importance;
244
+ importanceRaised = true;
245
+ }
246
+ const iso = now.toISOString();
247
+ existing.lastVerifiedAt = iso;
248
+ existing.lastUsed = iso;
249
+ return { addedEvidence, importanceRaised };
250
+ }
251
+ /** Prefix of the evidence ref a superseded entry gets when a restatement replaced it. */
252
+ export const RESTATEMENT_REASON_PREFIX = 'supersession-reason:restated';
253
+ /**
254
+ * A near-duplicate is the same fact said again, often with a correction
255
+ * ("I asserted X is a working symlink" → "X is a DANGLING symlink"), so the
256
+ * newest wording wins: the incoming entry becomes a new entry carrying the
257
+ * old one's provenance and reinforcement, and the old entry is marked
258
+ * superseded by it — hidden from recall, kept for audit, the same way
259
+ * `MemorySupersessionService.supersede` records an explicit supersession.
260
+ *
261
+ * @param old - Existing near-duplicate (mutated: superseded, evidence reason appended)
262
+ * @param incoming - Entry being written
263
+ * @param ids - The new entry's id and timestamp, and the match score for the audit ref
264
+ * @returns The new entry to store
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * const fresh = restateKnowledge(match.entry, entry, { id: uuidv4(), now: new Date(), score: match.score });
269
+ * memory.roleKnowledge.push(fresh);
270
+ * ```
271
+ */
272
+ export function restateKnowledge(old, incoming, ids) {
273
+ const iso = ids.now.toISOString();
274
+ const fresh = {
275
+ ...incoming,
276
+ id: ids.id,
277
+ createdAt: iso,
278
+ confidence: Math.min(Math.max(old.confidence, incoming.confidence ?? MEMORY_CONSTANTS.DEFAULTS.INITIAL_CONFIDENCE) + MEMORY_CONSTANTS.DEFAULTS.CONFIDENCE_REINFORCEMENT, MEMORY_CONSTANTS.DEFAULTS.MAX_CONFIDENCE),
279
+ lastVerifiedAt: iso,
280
+ };
281
+ // The new entry inherits the old provenance, then its own.
282
+ const inherited = { ...fresh, evidence: [...(old.evidence ?? (old.learnedFrom ? [old.learnedFrom] : []))], importance: old.importance };
283
+ mergeKnowledgeEvidence(inherited, incoming, ids.now);
284
+ if (inherited.evidence && inherited.evidence.length > 0)
285
+ fresh.evidence = inherited.evidence;
286
+ if (inherited.importance !== undefined)
287
+ fresh.importance = inherited.importance;
288
+ old.superseded = true;
289
+ old.supersededBy = fresh.id;
290
+ old.evidence = [...(old.evidence ?? (old.learnedFrom ? [old.learnedFrom] : [])), `${RESTATEMENT_REASON_PREFIX} (jaccard ${ids.score.toFixed(2)})`];
291
+ return fresh;
292
+ }
293
+ /**
294
+ * Which entry to evict when a store is full: the oldest superseded entry
295
+ * first (recall no longer shows it), else the lowest-confidence live one.
296
+ *
297
+ * @param knowledge - Entries
298
+ * @returns Index to remove, or -1 for an empty list
299
+ */
300
+ export function evictionIndex(knowledge) {
301
+ if (knowledge.length === 0)
302
+ return -1;
303
+ let pick = -1;
304
+ for (let i = 0; i < knowledge.length; i++) {
305
+ const e = knowledge[i];
306
+ if (!(e.superseded === true || e.supersededBy))
307
+ continue;
308
+ if (pick === -1 || e.createdAt < knowledge[pick].createdAt)
309
+ pick = i;
310
+ }
311
+ if (pick !== -1)
312
+ return pick;
313
+ for (let i = 0; i < knowledge.length; i++) {
314
+ if (pick === -1 || knowledge[i].confidence < knowledge[pick].confidence)
315
+ pick = i;
316
+ }
317
+ return pick;
318
+ }
319
+ //# sourceMappingURL=knowledge-similarity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-similarity.js","sourceRoot":"","sources":["../../../../../../backend/src/services/memory/knowledge-similarity.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  {
2
- "commit": "e29e8d50bfa5f4c82ad29d1e16307a4bb144e6a3",
3
- "builtAt": "2026-10-25T05:06:04.970Z"
2
+ "commit": "81eb60bed08aa5cd04d53cf6b866a2c3318ad327",
3
+ "builtAt": "2026-10-25T05:52:41.631Z"
4
4
  }
@@ -818,6 +818,27 @@ export declare const MEMORY_CONSTANTS: {
818
818
  /** Minimum confidence value */
819
819
  readonly MIN_CONFIDENCE: 0;
820
820
  };
821
+ /**
822
+ * Near-duplicate detection on write (#914 P1): a new role-knowledge entry
823
+ * close enough to an existing one in the same scope merges its evidence
824
+ * into it instead of being added.
825
+ */
826
+ readonly DEDUP: {
827
+ /**
828
+ * Token-set Jaccard at or above which two entries are one fact restated
829
+ * (numbers must agree, see knowledge-similarity). Set by replaying 3.7k
830
+ * real entries (2026-10-25): at 0.8 the matches are the same claim with
831
+ * another id, a re-check of the same item, or a correction of the same
832
+ * assertion (166 entries, 4.5%); from 0.7 down, different items that
833
+ * share a sentence frame ("Schedule X stops after 3 more runs" / "Schedule
834
+ * Y stops …") start to collide.
835
+ */
836
+ readonly NEAR_DUPLICATE_JACCARD: 0.8;
837
+ /** Fewer tokens than this and only an exact match counts (short texts overlap by chance) */
838
+ readonly MIN_TOKENS_FOR_NEAR: 4;
839
+ /** The legacy containment rule applies only to incoming texts longer than this */
840
+ readonly SUBSTRING_MIN_CHARS: 20;
841
+ };
821
842
  /**
822
843
  * Schema versioning for migrations
823
844
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../config/constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../config/constants.ts"],"names":[],"mappings":"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"}
@@ -842,6 +842,27 @@ export const MEMORY_CONSTANTS = {
842
842
  /** Minimum confidence value */
843
843
  MIN_CONFIDENCE: 0.0,
844
844
  },
845
+ /**
846
+ * Near-duplicate detection on write (#914 P1): a new role-knowledge entry
847
+ * close enough to an existing one in the same scope merges its evidence
848
+ * into it instead of being added.
849
+ */
850
+ DEDUP: {
851
+ /**
852
+ * Token-set Jaccard at or above which two entries are one fact restated
853
+ * (numbers must agree, see knowledge-similarity). Set by replaying 3.7k
854
+ * real entries (2026-10-25): at 0.8 the matches are the same claim with
855
+ * another id, a re-check of the same item, or a correction of the same
856
+ * assertion (166 entries, 4.5%); from 0.7 down, different items that
857
+ * share a sentence frame ("Schedule X stops after 3 more runs" / "Schedule
858
+ * Y stops …") start to collide.
859
+ */
860
+ NEAR_DUPLICATE_JACCARD: 0.8,
861
+ /** Fewer tokens than this and only an exact match counts (short texts overlap by chance) */
862
+ MIN_TOKENS_FOR_NEAR: 4,
863
+ /** The legacy containment rule applies only to incoming texts longer than this */
864
+ SUBSTRING_MIN_CHARS: 20,
865
+ },
845
866
  /**
846
867
  * Schema versioning for migrations
847
868
  */