agent-recall-core 3.4.31 → 3.4.35
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/README.md +121 -441
- package/dist/digest/store.d.ts.map +1 -1
- package/dist/digest/store.js +4 -3
- package/dist/digest/store.js.map +1 -1
- package/dist/display/board-render.d.ts +61 -0
- package/dist/display/board-render.d.ts.map +1 -0
- package/dist/display/board-render.js +223 -0
- package/dist/display/board-render.js.map +1 -0
- package/dist/helpers/alignment-patterns.d.ts +10 -0
- package/dist/helpers/alignment-patterns.d.ts.map +1 -1
- package/dist/helpers/alignment-patterns.js +5 -1
- package/dist/helpers/alignment-patterns.js.map +1 -1
- package/dist/helpers/blind-spots.d.ts +86 -0
- package/dist/helpers/blind-spots.d.ts.map +1 -0
- package/dist/helpers/blind-spots.js +205 -0
- package/dist/helpers/blind-spots.js.map +1 -0
- package/dist/helpers/conflict-scan.d.ts +10 -0
- package/dist/helpers/conflict-scan.d.ts.map +1 -1
- package/dist/helpers/conflict-scan.js +3 -3
- package/dist/helpers/conflict-scan.js.map +1 -1
- package/dist/helpers/semantic-match.d.ts +82 -0
- package/dist/helpers/semantic-match.d.ts.map +1 -0
- package/dist/helpers/semantic-match.js +229 -0
- package/dist/helpers/semantic-match.js.map +1 -0
- package/dist/index.d.ts +52 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -9
- package/dist/index.js.map +1 -1
- package/dist/palace/awareness.d.ts +30 -0
- package/dist/palace/awareness.d.ts.map +1 -1
- package/dist/palace/awareness.js +65 -2
- package/dist/palace/awareness.js.map +1 -1
- package/dist/palace/consolidate.d.ts.map +1 -1
- package/dist/palace/consolidate.js +17 -0
- package/dist/palace/consolidate.js.map +1 -1
- package/dist/palace/decay-pass.d.ts +46 -0
- package/dist/palace/decay-pass.d.ts.map +1 -0
- package/dist/palace/decay-pass.js +87 -0
- package/dist/palace/decay-pass.js.map +1 -0
- package/dist/palace/insights-index.d.ts.map +1 -1
- package/dist/palace/insights-index.js +4 -2
- package/dist/palace/insights-index.js.map +1 -1
- package/dist/palace/skills.d.ts +41 -2
- package/dist/palace/skills.d.ts.map +1 -1
- package/dist/palace/skills.js +106 -4
- package/dist/palace/skills.js.map +1 -1
- package/dist/prompts/consolidation-prompt.d.ts +25 -0
- package/dist/prompts/consolidation-prompt.d.ts.map +1 -0
- package/dist/prompts/consolidation-prompt.js +91 -0
- package/dist/prompts/consolidation-prompt.js.map +1 -0
- package/dist/storage/archive-prune.d.ts +56 -0
- package/dist/storage/archive-prune.d.ts.map +1 -0
- package/dist/storage/archive-prune.js +118 -0
- package/dist/storage/archive-prune.js.map +1 -0
- package/dist/storage/archive-write.d.ts +38 -0
- package/dist/storage/archive-write.d.ts.map +1 -0
- package/dist/storage/archive-write.js +98 -0
- package/dist/storage/archive-write.js.map +1 -0
- package/dist/storage/blind-spots-store.d.ts +30 -0
- package/dist/storage/blind-spots-store.d.ts.map +1 -0
- package/dist/storage/blind-spots-store.js +91 -0
- package/dist/storage/blind-spots-store.js.map +1 -0
- package/dist/storage/capture-router.d.ts +60 -0
- package/dist/storage/capture-router.d.ts.map +1 -0
- package/dist/storage/capture-router.js +133 -0
- package/dist/storage/capture-router.js.map +1 -0
- package/dist/storage/classification.d.ts +32 -0
- package/dist/storage/classification.d.ts.map +1 -0
- package/dist/storage/classification.js +74 -0
- package/dist/storage/classification.js.map +1 -0
- package/dist/storage/consolidation-queue.d.ts +39 -0
- package/dist/storage/consolidation-queue.d.ts.map +1 -0
- package/dist/storage/consolidation-queue.js +120 -0
- package/dist/storage/consolidation-queue.js.map +1 -0
- package/dist/storage/content-guard.d.ts +74 -0
- package/dist/storage/content-guard.d.ts.map +1 -0
- package/dist/storage/content-guard.js +179 -0
- package/dist/storage/content-guard.js.map +1 -0
- package/dist/storage/corrections.d.ts +246 -21
- package/dist/storage/corrections.d.ts.map +1 -1
- package/dist/storage/corrections.js +605 -56
- package/dist/storage/corrections.js.map +1 -1
- package/dist/storage/durable-intent.d.ts +49 -0
- package/dist/storage/durable-intent.d.ts.map +1 -0
- package/dist/storage/durable-intent.js +124 -0
- package/dist/storage/durable-intent.js.map +1 -0
- package/dist/storage/filelock.d.ts +6 -0
- package/dist/storage/filelock.d.ts.map +1 -1
- package/dist/storage/filelock.js +6 -1
- package/dist/storage/filelock.js.map +1 -1
- package/dist/storage/memory-protocol.d.ts +19 -0
- package/dist/storage/memory-protocol.d.ts.map +1 -0
- package/dist/storage/memory-protocol.js +101 -0
- package/dist/storage/memory-protocol.js.map +1 -0
- package/dist/storage/paths.d.ts +23 -0
- package/dist/storage/paths.d.ts.map +1 -1
- package/dist/storage/paths.js +39 -0
- package/dist/storage/paths.js.map +1 -1
- package/dist/storage/retention.d.ts +23 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/storage/retention.js +48 -0
- package/dist/storage/retention.js.map +1 -0
- package/dist/storage/session.d.ts +2 -2
- package/dist/storage/session.d.ts.map +1 -1
- package/dist/storage/session.js +11 -1
- package/dist/storage/session.js.map +1 -1
- package/dist/supabase/config.d.ts +8 -0
- package/dist/supabase/config.d.ts.map +1 -1
- package/dist/supabase/config.js +5 -0
- package/dist/supabase/config.js.map +1 -1
- package/dist/supabase/recall-backend.d.ts +1 -0
- package/dist/supabase/recall-backend.d.ts.map +1 -1
- package/dist/supabase/recall-backend.js +13 -13
- package/dist/supabase/recall-backend.js.map +1 -1
- package/dist/supabase/sync.d.ts.map +1 -1
- package/dist/supabase/sync.js +30 -3
- package/dist/supabase/sync.js.map +1 -1
- package/dist/tools-logic/bootstrap.d.ts +15 -0
- package/dist/tools-logic/bootstrap.d.ts.map +1 -1
- package/dist/tools-logic/bootstrap.js +238 -47
- package/dist/tools-logic/bootstrap.js.map +1 -1
- package/dist/tools-logic/brief.d.ts +84 -0
- package/dist/tools-logic/brief.d.ts.map +1 -0
- package/dist/tools-logic/brief.js +193 -0
- package/dist/tools-logic/brief.js.map +1 -0
- package/dist/tools-logic/check-action.d.ts +9 -0
- package/dist/tools-logic/check-action.d.ts.map +1 -1
- package/dist/tools-logic/check-action.js +31 -2
- package/dist/tools-logic/check-action.js.map +1 -1
- package/dist/tools-logic/check.d.ts +7 -0
- package/dist/tools-logic/check.d.ts.map +1 -1
- package/dist/tools-logic/check.js +24 -2
- package/dist/tools-logic/check.js.map +1 -1
- package/dist/tools-logic/confidence.d.ts +50 -0
- package/dist/tools-logic/confidence.d.ts.map +1 -0
- package/dist/tools-logic/confidence.js +70 -0
- package/dist/tools-logic/confidence.js.map +1 -0
- package/dist/tools-logic/drill-down.d.ts +37 -0
- package/dist/tools-logic/drill-down.d.ts.map +1 -0
- package/dist/tools-logic/drill-down.js +63 -0
- package/dist/tools-logic/drill-down.js.map +1 -0
- package/dist/tools-logic/export-corrections.d.ts +63 -0
- package/dist/tools-logic/export-corrections.d.ts.map +1 -0
- package/dist/tools-logic/export-corrections.js +124 -0
- package/dist/tools-logic/export-corrections.js.map +1 -0
- package/dist/tools-logic/journal-capture.d.ts.map +1 -1
- package/dist/tools-logic/journal-capture.js +4 -1
- package/dist/tools-logic/journal-capture.js.map +1 -1
- package/dist/tools-logic/journal-write.d.ts.map +1 -1
- package/dist/tools-logic/journal-write.js +3 -2
- package/dist/tools-logic/journal-write.js.map +1 -1
- package/dist/tools-logic/memory-query.d.ts +10 -3
- package/dist/tools-logic/memory-query.d.ts.map +1 -1
- package/dist/tools-logic/memory-query.js +31 -7
- package/dist/tools-logic/memory-query.js.map +1 -1
- package/dist/tools-logic/mirror-builder.d.ts +115 -0
- package/dist/tools-logic/mirror-builder.d.ts.map +1 -0
- package/dist/tools-logic/mirror-builder.js +348 -0
- package/dist/tools-logic/mirror-builder.js.map +1 -0
- package/dist/tools-logic/palace-write.d.ts.map +1 -1
- package/dist/tools-logic/palace-write.js +3 -2
- package/dist/tools-logic/palace-write.js.map +1 -1
- package/dist/tools-logic/pipeline-close.d.ts.map +1 -1
- package/dist/tools-logic/pipeline-close.js +2 -1
- package/dist/tools-logic/pipeline-close.js.map +1 -1
- package/dist/tools-logic/pipeline-open.d.ts.map +1 -1
- package/dist/tools-logic/pipeline-open.js +2 -1
- package/dist/tools-logic/pipeline-open.js.map +1 -1
- package/dist/tools-logic/predict-correction.d.ts +47 -0
- package/dist/tools-logic/predict-correction.d.ts.map +1 -0
- package/dist/tools-logic/predict-correction.js +137 -0
- package/dist/tools-logic/predict-correction.js.map +1 -0
- package/dist/tools-logic/prior-builder.d.ts +27 -0
- package/dist/tools-logic/prior-builder.d.ts.map +1 -0
- package/dist/tools-logic/prior-builder.js +57 -0
- package/dist/tools-logic/prior-builder.js.map +1 -0
- package/dist/tools-logic/recognition-builder.d.ts +116 -0
- package/dist/tools-logic/recognition-builder.d.ts.map +1 -0
- package/dist/tools-logic/recognition-builder.js +289 -0
- package/dist/tools-logic/recognition-builder.js.map +1 -0
- package/dist/tools-logic/safety-consolidation.d.ts +104 -0
- package/dist/tools-logic/safety-consolidation.d.ts.map +1 -0
- package/dist/tools-logic/safety-consolidation.js +256 -0
- package/dist/tools-logic/safety-consolidation.js.map +1 -0
- package/dist/tools-logic/session-end-reflect.d.ts +18 -0
- package/dist/tools-logic/session-end-reflect.d.ts.map +1 -1
- package/dist/tools-logic/session-end-reflect.js +68 -29
- package/dist/tools-logic/session-end-reflect.js.map +1 -1
- package/dist/tools-logic/session-end.d.ts +9 -0
- package/dist/tools-logic/session-end.d.ts.map +1 -1
- package/dist/tools-logic/session-end.js +111 -13
- package/dist/tools-logic/session-end.js.map +1 -1
- package/dist/tools-logic/session-start-lite.d.ts +2 -0
- package/dist/tools-logic/session-start-lite.d.ts.map +1 -1
- package/dist/tools-logic/session-start-lite.js +10 -0
- package/dist/tools-logic/session-start-lite.js.map +1 -1
- package/dist/tools-logic/session-start.d.ts +46 -0
- package/dist/tools-logic/session-start.d.ts.map +1 -1
- package/dist/tools-logic/session-start.js +96 -3
- package/dist/tools-logic/session-start.js.map +1 -1
- package/dist/tools-logic/skill-propose.d.ts +27 -0
- package/dist/tools-logic/skill-propose.d.ts.map +1 -0
- package/dist/tools-logic/skill-propose.js +66 -0
- package/dist/tools-logic/skill-propose.js.map +1 -0
- package/dist/tools-logic/skill-recall.d.ts +5 -0
- package/dist/tools-logic/skill-recall.d.ts.map +1 -1
- package/dist/tools-logic/skill-recall.js +14 -1
- package/dist/tools-logic/skill-recall.js.map +1 -1
- package/dist/tools-logic/smart-recall.d.ts +17 -0
- package/dist/tools-logic/smart-recall.d.ts.map +1 -1
- package/dist/tools-logic/smart-recall.js +51 -16
- package/dist/tools-logic/smart-recall.js.map +1 -1
- package/dist/tools-logic/store-doctor.d.ts +71 -0
- package/dist/tools-logic/store-doctor.d.ts.map +1 -0
- package/dist/tools-logic/store-doctor.js +387 -0
- package/dist/tools-logic/store-doctor.js.map +1 -0
- package/dist/tools-logic/store-repair.d.ts +64 -0
- package/dist/tools-logic/store-repair.d.ts.map +1 -0
- package/dist/tools-logic/store-repair.js +243 -0
- package/dist/tools-logic/store-repair.js.map +1 -0
- package/dist/tools-logic/supersession.d.ts +34 -0
- package/dist/tools-logic/supersession.d.ts.map +1 -0
- package/dist/tools-logic/supersession.js +103 -0
- package/dist/tools-logic/supersession.js.map +1 -0
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/vector/local-vector-backend.d.ts.map +1 -1
- package/dist/vector/local-vector-backend.js +14 -17
- package/dist/vector/local-vector-backend.js.map +1 -1
- package/package.json +1 -1
- package/dist/relevance/injector.d.ts +0 -51
- package/dist/relevance/injector.d.ts.map +0 -1
- package/dist/relevance/injector.js +0 -121
- package/dist/relevance/injector.js.map +0 -1
- package/dist/relevance/precision.d.ts +0 -109
- package/dist/relevance/precision.d.ts.map +0 -1
- package/dist/relevance/precision.js +0 -279
- package/dist/relevance/precision.js.map +0 -1
- package/dist/relevance/promoter.d.ts +0 -60
- package/dist/relevance/promoter.d.ts.map +0 -1
- package/dist/relevance/promoter.js +0 -336
- package/dist/relevance/promoter.js.map +0 -1
- package/dist/relevance/stager.d.ts +0 -61
- package/dist/relevance/stager.d.ts.map +0 -1
- package/dist/relevance/stager.js +0 -251
- package/dist/relevance/stager.js.map +0 -1
- package/dist/relevance/surfacer.d.ts +0 -34
- package/dist/relevance/surfacer.d.ts.map +0 -1
- package/dist/relevance/surfacer.js +0 -333
- package/dist/relevance/surfacer.js.map +0 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* blind-spots.ts — auto-derive the user's behavioral profile from accumulated
|
|
3
|
+
* corrections (Wave 5, Decision #8).
|
|
4
|
+
*
|
|
5
|
+
* Memory becoming understanding: corrections are not one input among many —
|
|
6
|
+
* their ACCUMULATION reveals recurring tendencies ("Blind Spots") the system can
|
|
7
|
+
* warn about BEFORE the user has to correct again. This module is the pure
|
|
8
|
+
* derivation step; persistence lives in storage/blind-spots-store.ts and the
|
|
9
|
+
* prediction lives in tools-logic/predict-correction.ts.
|
|
10
|
+
*
|
|
11
|
+
* Reuses `extractKeywords` + `cleanRule` from the alignment-patterns grammar —
|
|
12
|
+
* does NOT fork the matching grammar (clustering must agree with watch_for).
|
|
13
|
+
* Pure, no LLM, no IO.
|
|
14
|
+
*/
|
|
15
|
+
import { extractKeywords } from "./auto-name.js";
|
|
16
|
+
import { cleanRule } from "./alignment-patterns.js";
|
|
17
|
+
import { tokenize, overlap } from "../tools-logic/check-action.js";
|
|
18
|
+
import { semanticSimilarity, blindSpotConcepts } from "./semantic-match.js";
|
|
19
|
+
const P0_RE = /\bnever\b|\balways\b|\bdon'?t\b|\bdo not\b|\bmust not\b|\bforbid\b|\bprohibit\b/i;
|
|
20
|
+
/** Default exact trigger-keyword overlap floor for a blind spot to fire (Loop 3 path). */
|
|
21
|
+
export const BLIND_SPOT_MIN_OVERLAP = 2;
|
|
22
|
+
/**
|
|
23
|
+
* Default LOCAL semantic-similarity floor (Loop 5). When exact keyword overlap is
|
|
24
|
+
* below {@link BLIND_SPOT_MIN_OVERLAP}, a blind spot still fires if the situation
|
|
25
|
+
* is semantically similar to its concept text at or above this threshold.
|
|
26
|
+
*
|
|
27
|
+
* TUNED on the real ~/.agent-recall corpus (scripts/eval/predict-loo.mjs --both):
|
|
28
|
+
* the keyword baseline fires 0/13 (0% recall). The local semantic path lifts that
|
|
29
|
+
* to 2/13 (15.4% recall) at this threshold while the false-positive rate on
|
|
30
|
+
* unrelated NEGATIVE pairs stays exactly 0% (0/22). This is the HIGHEST-recall
|
|
31
|
+
* point with zero FP — the conservative choice. The next step down (0.19) reaches
|
|
32
|
+
* 3/13 (23.1%) but at 4.5% FP, and FP climbs to 22.7% by 0.14; recall gains that
|
|
33
|
+
* also fire on unrelated pairs are noise, so we hold the zero-FP line. On the
|
|
34
|
+
* controlled zero-overlap paraphrase instrument (scripts/eval/paraphrase-
|
|
35
|
+
* robustness.mjs) this threshold fires 100% (vs 0% for the keyword path), proving
|
|
36
|
+
* the path is genuinely semantic, not lexical luck.
|
|
37
|
+
*/
|
|
38
|
+
export const BLIND_SPOT_SEMANTIC_THRESHOLD = 0.20;
|
|
39
|
+
/**
|
|
40
|
+
* Decide whether a free-text SITUATION resembles a blind spot — the single
|
|
41
|
+
* matching grammar shared by predict-correction.ts and the LOO eval, so both
|
|
42
|
+
* score identically (no fork).
|
|
43
|
+
*
|
|
44
|
+
* FLOOR: exact trigger-keyword overlap >= minOverlap (the Loop 3 path, unchanged).
|
|
45
|
+
* WIDEN: when the floor fails, a LOCAL semantic-similarity score (stemming +
|
|
46
|
+
* concept map + char-trigram cosine over the blind spot's tendency/example/triggers)
|
|
47
|
+
* at or above semanticThreshold fires the risk. NO API key, NO network.
|
|
48
|
+
*/
|
|
49
|
+
export function matchesBlindSpot(situation, bs, minOverlap = BLIND_SPOT_MIN_OVERLAP, semanticThreshold = BLIND_SPOT_SEMANTIC_THRESHOLD) {
|
|
50
|
+
const sitTokens = tokenize(situation);
|
|
51
|
+
const triggerSet = new Set((bs.trigger_keywords ?? []).map((k) => k.toLowerCase()));
|
|
52
|
+
const matched = overlap(sitTokens, triggerSet);
|
|
53
|
+
if (matched.length >= minOverlap) {
|
|
54
|
+
return { fired: true, via: "keyword", matched, semanticScore: 0 };
|
|
55
|
+
}
|
|
56
|
+
const semanticScore = semanticSimilarity(situation, blindSpotConcepts(bs));
|
|
57
|
+
if (semanticScore >= semanticThreshold) {
|
|
58
|
+
return { fired: true, via: "semantic", matched, semanticScore };
|
|
59
|
+
}
|
|
60
|
+
return { fired: false, via: null, matched, semanticScore };
|
|
61
|
+
}
|
|
62
|
+
/** Number of cleaned keywords to extract per signal for clustering. */
|
|
63
|
+
const KW_PER_SIGNAL = 4;
|
|
64
|
+
/** A non-P0 cluster needs this much keyword overlap to bind. */
|
|
65
|
+
const MIN_SHARED_KEYWORDS = 2;
|
|
66
|
+
function normalizeCorrection(c) {
|
|
67
|
+
const rule = cleanRule(c.rule ?? "");
|
|
68
|
+
return {
|
|
69
|
+
rule,
|
|
70
|
+
severity: c.severity === "p0" ? "p0" : "p1",
|
|
71
|
+
keywords: extractKeywords(rule, KW_PER_SIGNAL),
|
|
72
|
+
date: c.date ?? "",
|
|
73
|
+
recurrence: c.recurrence_count ?? 0,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Alignment-log entries carry the raw correction in `corrections: string[]`
|
|
78
|
+
* and/or `delta` (Was:/Correction: format). Both flow through `cleanRule`.
|
|
79
|
+
*/
|
|
80
|
+
function normalizeAlignment(a) {
|
|
81
|
+
const out = [];
|
|
82
|
+
const raws = [...(a.corrections ?? [])];
|
|
83
|
+
if (a.delta)
|
|
84
|
+
raws.push(a.delta);
|
|
85
|
+
for (const raw of raws) {
|
|
86
|
+
const rule = cleanRule(raw);
|
|
87
|
+
if (!rule || rule.length < 4)
|
|
88
|
+
continue;
|
|
89
|
+
out.push({
|
|
90
|
+
rule,
|
|
91
|
+
severity: P0_RE.test(rule) ? "p0" : "p1",
|
|
92
|
+
keywords: extractKeywords(rule, KW_PER_SIGNAL),
|
|
93
|
+
date: a.date ?? "",
|
|
94
|
+
recurrence: 0,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/** Count how many keywords two signals share (substring-tolerant, mirrors check.ts). */
|
|
100
|
+
function sharedKeywords(a, b) {
|
|
101
|
+
const hits = new Set();
|
|
102
|
+
for (const k of a) {
|
|
103
|
+
if (b.some((bk) => bk === k || bk.includes(k) || k.includes(bk)))
|
|
104
|
+
hits.add(k);
|
|
105
|
+
}
|
|
106
|
+
return [...hits];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Cluster correction + alignment signals into Blind Spots.
|
|
110
|
+
*
|
|
111
|
+
* Clustering rule: greedily seed clusters from the strongest signals; a signal
|
|
112
|
+
* joins a cluster when it shares ≥2 keywords with the seed (≥1 if either is P0).
|
|
113
|
+
* A lone P0 signal still produces a Blind Spot (the >=1-if-P0 rule) — P0
|
|
114
|
+
* corrections are too important to need three repetitions before warning.
|
|
115
|
+
*/
|
|
116
|
+
export function deriveBlindSpots(corrections, alignmentLog) {
|
|
117
|
+
const signals = [];
|
|
118
|
+
for (const c of corrections ?? []) {
|
|
119
|
+
if (c.active === false)
|
|
120
|
+
continue;
|
|
121
|
+
const s = normalizeCorrection(c);
|
|
122
|
+
if (s.keywords.length === 0)
|
|
123
|
+
continue;
|
|
124
|
+
signals.push(s);
|
|
125
|
+
}
|
|
126
|
+
for (const a of alignmentLog ?? []) {
|
|
127
|
+
for (const s of normalizeAlignment(a)) {
|
|
128
|
+
if (s.keywords.length === 0)
|
|
129
|
+
continue;
|
|
130
|
+
signals.push(s);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Seed order: P0 first, then by recurrence, then by keyword richness — so the
|
|
134
|
+
// strongest tendency anchors its cluster's signature.
|
|
135
|
+
const ordered = [...signals].sort((x, y) => {
|
|
136
|
+
if (x.severity !== y.severity)
|
|
137
|
+
return x.severity === "p0" ? -1 : 1;
|
|
138
|
+
if (y.recurrence !== x.recurrence)
|
|
139
|
+
return y.recurrence - x.recurrence;
|
|
140
|
+
return y.keywords.length - x.keywords.length;
|
|
141
|
+
});
|
|
142
|
+
const used = new Set();
|
|
143
|
+
const clusters = [];
|
|
144
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
145
|
+
if (used.has(i))
|
|
146
|
+
continue;
|
|
147
|
+
const seed = ordered[i];
|
|
148
|
+
const cluster = [seed];
|
|
149
|
+
used.add(i);
|
|
150
|
+
for (let j = i + 1; j < ordered.length; j++) {
|
|
151
|
+
if (used.has(j))
|
|
152
|
+
continue;
|
|
153
|
+
const cand = ordered[j];
|
|
154
|
+
const shared = sharedKeywords(seed.keywords, cand.keywords);
|
|
155
|
+
const threshold = seed.severity === "p0" || cand.severity === "p0" ? 1 : MIN_SHARED_KEYWORDS;
|
|
156
|
+
if (shared.length >= threshold) {
|
|
157
|
+
cluster.push(cand);
|
|
158
|
+
used.add(j);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
clusters.push(cluster);
|
|
162
|
+
}
|
|
163
|
+
const blindSpots = [];
|
|
164
|
+
for (const cluster of clusters) {
|
|
165
|
+
const seed = cluster[0];
|
|
166
|
+
const isP0 = cluster.some((s) => s.severity === "p0");
|
|
167
|
+
// Non-P0 clusters need ≥2 members to count as a tendency; a single P0 counts.
|
|
168
|
+
if (!isP0 && cluster.length < 2)
|
|
169
|
+
continue;
|
|
170
|
+
// Trigger keywords = keywords shared by the largest share of the cluster.
|
|
171
|
+
const kwCount = new Map();
|
|
172
|
+
for (const s of cluster) {
|
|
173
|
+
for (const k of new Set(s.keywords))
|
|
174
|
+
kwCount.set(k, (kwCount.get(k) ?? 0) + 1);
|
|
175
|
+
}
|
|
176
|
+
const triggerKeywords = [...kwCount.entries()]
|
|
177
|
+
.filter(([, n]) => n >= 2 || cluster.length === 1)
|
|
178
|
+
.sort((a, b) => b[1] - a[1])
|
|
179
|
+
.map(([k]) => k)
|
|
180
|
+
.slice(0, 5);
|
|
181
|
+
// Fall back to the seed's own keywords if nothing was shared by ≥2 members
|
|
182
|
+
// (happens for a lone P0). Guarantee at least the seed keywords surface.
|
|
183
|
+
const finalKeywords = triggerKeywords.length > 0 ? triggerKeywords : seed.keywords.slice(0, 3);
|
|
184
|
+
const lastSeen = cluster.reduce((acc, s) => (s.date > acc ? s.date : acc), "");
|
|
185
|
+
blindSpots.push({
|
|
186
|
+
tendency: seed.rule,
|
|
187
|
+
evidence_count: cluster.length,
|
|
188
|
+
severity: isP0 ? "p0" : "p1",
|
|
189
|
+
trigger_keywords: finalKeywords,
|
|
190
|
+
example_rule: seed.rule,
|
|
191
|
+
last_seen: lastSeen,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
// Strongest evidence first; P0 outranks P1 on a tie.
|
|
195
|
+
blindSpots.sort((a, b) => {
|
|
196
|
+
if (a.severity !== b.severity)
|
|
197
|
+
return a.severity === "p0" ? -1 : 1;
|
|
198
|
+
return b.evidence_count - a.evidence_count;
|
|
199
|
+
});
|
|
200
|
+
return {
|
|
201
|
+
derived_at: new Date().toISOString(),
|
|
202
|
+
blind_spots: blindSpots,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=blind-spots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blind-spots.js","sourceRoot":"","sources":["../../src/helpers/blind-spots.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,16 @@ export interface ConflictScanResult {
|
|
|
23
23
|
hasConflict: boolean;
|
|
24
24
|
matches: ConflictMatch[];
|
|
25
25
|
}
|
|
26
|
+
/** Extract semver-style version tokens: "1.2.3", "v1.2.3", "version 1.2.3" */
|
|
27
|
+
export declare function extractVersionTokens(text: string): Map<string, string>;
|
|
28
|
+
/** Return [statusWord, category] pairs found in text. */
|
|
29
|
+
export declare function extractStatusTokens(text: string): Map<string, string>;
|
|
30
|
+
/**
|
|
31
|
+
* Extract key-value pairs from patterns like:
|
|
32
|
+
* "status: blocked", "version is 3.4.1", "env = production"
|
|
33
|
+
* Returns a Map<normalised_key, value>.
|
|
34
|
+
*/
|
|
35
|
+
export declare function extractKVTokens(text: string): Map<string, string>;
|
|
26
36
|
/**
|
|
27
37
|
* Scan existing memories for conflicts with newContent.
|
|
28
38
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-scan.d.ts","sourceRoot":"","sources":["../../src/helpers/conflict-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"conflict-scan.d.ts","sourceRoot":"","sources":["../../src/helpers/conflict-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAMD,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYtE;AAWD,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBjE;AAMD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CA6F7B;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,CAeR"}
|
|
@@ -14,7 +14,7 @@ import { smartRecall } from "../tools-logic/smart-recall.js";
|
|
|
14
14
|
// Token extractors
|
|
15
15
|
// ---------------------------------------------------------------------------
|
|
16
16
|
/** Extract semver-style version tokens: "1.2.3", "v1.2.3", "version 1.2.3" */
|
|
17
|
-
function extractVersionTokens(text) {
|
|
17
|
+
export function extractVersionTokens(text) {
|
|
18
18
|
const result = new Map();
|
|
19
19
|
// Capture the word/context before the version number as the key
|
|
20
20
|
const pattern = /(\w[\w.-]{0,30})\s*(?:v|@|version\s+)?(\d+\.\d+\.\d+)/gi;
|
|
@@ -36,7 +36,7 @@ const STATUS_WORD_MAP = {
|
|
|
36
36
|
pending: "pending",
|
|
37
37
|
};
|
|
38
38
|
/** Return [statusWord, category] pairs found in text. */
|
|
39
|
-
function extractStatusTokens(text) {
|
|
39
|
+
export function extractStatusTokens(text) {
|
|
40
40
|
const result = new Map();
|
|
41
41
|
const lower = text.toLowerCase();
|
|
42
42
|
for (const [word, category] of Object.entries(STATUS_WORD_MAP)) {
|
|
@@ -52,7 +52,7 @@ function extractStatusTokens(text) {
|
|
|
52
52
|
* "status: blocked", "version is 3.4.1", "env = production"
|
|
53
53
|
* Returns a Map<normalised_key, value>.
|
|
54
54
|
*/
|
|
55
|
-
function extractKVTokens(text) {
|
|
55
|
+
export function extractKVTokens(text) {
|
|
56
56
|
const result = new Map();
|
|
57
57
|
// "key: value" or "key = value"
|
|
58
58
|
const colonEq = /\b([\w][\w -]{0,30})\s*[:=]\s*([^\s,;.!?\n]{1,50})/g;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-scan.js","sourceRoot":"","sources":["../../src/helpers/conflict-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAmB7D,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"conflict-scan.js","sourceRoot":"","sources":["../../src/helpers/conflict-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* semantic-match.ts — LOCAL, zero-key, zero-network semantic similarity (Loop 5).
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS — Loop 3 measured the keyword predictor at an honest 0/13 on
|
|
5
|
+
* the real corpus: of the 13 predictable corrections, 11 had ZERO lead-in↔trigger
|
|
6
|
+
* token overlap and the other 2 maxed at 1 (below the MIN_OVERLAP=2 floor). The
|
|
7
|
+
* relationship between a situation ("renaming the npm package and the README")
|
|
8
|
+
* and the resolution it will provoke ("Rename everything to Novada Proxy") is
|
|
9
|
+
* SEMANTIC, not lexical — different surface words, same concept.
|
|
10
|
+
*
|
|
11
|
+
* This module restores AgentRecall's local-by-default identity: NO OPENAI_API_KEY,
|
|
12
|
+
* NO network, NO per-call LLM. It bridges vocabularies with three cheap, pure
|
|
13
|
+
* signals over the situation text vs a blind-spot's trigger keywords:
|
|
14
|
+
*
|
|
15
|
+
* 1. LIGHT STEMMING — collapse morphology (publish/published/publishing,
|
|
16
|
+
* rename/renaming, customer/customers) so inflected forms match.
|
|
17
|
+
* 2. SYNONYM / CONCEPT EXPANSION — a small built-in map keyed to the recurring
|
|
18
|
+
* AgentRecall domains (publish↔ship↔release, secret↔key↔token↔credential,
|
|
19
|
+
* name↔rename↔naming, approval↔permission, codex↔sonnet↔agent). This is the
|
|
20
|
+
* actual bridge between a situation's verbs and a resolution's nouns.
|
|
21
|
+
* 3. CHARACTER-TRIGRAM COSINE — fuzzy overlap that catches shared roots and
|
|
22
|
+
* near-spellings even when whole stems differ.
|
|
23
|
+
*
|
|
24
|
+
* The combined score is `max(stemmed token-set cosine, char-trigram cosine)`
|
|
25
|
+
* over the SYNONYM-EXPANDED stem sets — a value in [0,1]. Callers compare it to a
|
|
26
|
+
* threshold to decide whether a risk fires.
|
|
27
|
+
*
|
|
28
|
+
* Pure, deterministic, no IO. The heavy lifting (set construction) is O(tokens);
|
|
29
|
+
* any precompute a caller wants belongs at write/consolidation time, not here.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Stem a single lowercased token. Applies the first matching suffix rule, then a
|
|
33
|
+
* light "double consonant" fixup so e.g. `renam` (from `renaming`) collapses with
|
|
34
|
+
* `rename` by re-adding a trailing `e` when the stem ends in a consonant cluster
|
|
35
|
+
* that commonly drops an `e`. Deterministic and dependency-free.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stem(token: string): string;
|
|
38
|
+
/** Stem every token in a set, returning a new stemmed set. */
|
|
39
|
+
export declare function stemSet(tokens: Set<string>): Set<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Canonicalize a stemmed token set into CONCEPT space: every token that belongs
|
|
42
|
+
* to a synonym group is REPLACED by its shared concept token (`__concept_<g>`);
|
|
43
|
+
* tokens with no concept pass through unchanged. Collapsing synonyms onto one
|
|
44
|
+
* shared dimension (rather than appending a marker alongside the surface stems)
|
|
45
|
+
* is what lets "publish package npm" and "ship release registry" overlap
|
|
46
|
+
* meaningfully — both reduce to the same `__concept_0`, so the cosine sees a real
|
|
47
|
+
* shared term instead of a diluted one. That is the semantic bridge.
|
|
48
|
+
*/
|
|
49
|
+
export declare function expandConcepts(stems: Set<string>): Set<string>;
|
|
50
|
+
/** Set-cosine over two token sets (binary term vectors): |A∩B| / sqrt(|A|·|B|). */
|
|
51
|
+
export declare function setCosine(a: Set<string>, b: Set<string>): number;
|
|
52
|
+
/** Character trigrams of a token set's joined text (fuzzy root/near-spelling overlap). */
|
|
53
|
+
export declare function charTrigrams(tokens: Set<string>): Set<string>;
|
|
54
|
+
/**
|
|
55
|
+
* The local semantic similarity in [0,1] between a SITUATION text and a
|
|
56
|
+
* blind-spot's matching MATERIAL (free text: its tendency / example rule and its
|
|
57
|
+
* trigger keywords joined together). Both sides are tokenized with the production
|
|
58
|
+
* grammar, stemmed, and concept-expanded; the score is the MAX of the expanded
|
|
59
|
+
* token-set cosine and the character-trigram cosine. Pure and deterministic.
|
|
60
|
+
*
|
|
61
|
+
* Passing the blind spot's full text (not just its sparse trigger_keywords) is
|
|
62
|
+
* what gives the semantic path material to work with — Loop 3's diagnostic showed
|
|
63
|
+
* trigger_keywords are frequently EMPTY for the predictable cases, so matching on
|
|
64
|
+
* keywords alone reproduces the 0/13. The richer text is the seed rule the
|
|
65
|
+
* correction was about, which DOES carry concept-bearing words.
|
|
66
|
+
*
|
|
67
|
+
* @param situation free-text plan / lead-in (the situation the agent is in)
|
|
68
|
+
* @param blindSpotText the blind spot's tendency / example_rule + trigger keywords
|
|
69
|
+
*/
|
|
70
|
+
export declare function semanticSimilarity(situation: string, blindSpotText: string): number;
|
|
71
|
+
/**
|
|
72
|
+
* Build the semantic matching MATERIAL for a blind spot: its concept-bearing
|
|
73
|
+
* tendency / example rule text plus its trigger keywords, joined into one string.
|
|
74
|
+
* Centralizes what "the blind spot's text" means so production code and the LOO
|
|
75
|
+
* harness score the SAME way (no fork — the harness imports this).
|
|
76
|
+
*/
|
|
77
|
+
export declare function blindSpotConcepts(bs: {
|
|
78
|
+
tendency?: string;
|
|
79
|
+
example_rule?: string;
|
|
80
|
+
trigger_keywords?: string[];
|
|
81
|
+
}): string;
|
|
82
|
+
//# sourceMappingURL=semantic-match.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-match.d.ts","sourceRoot":"","sources":["../../src/helpers/semantic-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAsCH;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAqB1C;AAED,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAIxD;AAmDD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAO9D;AAMD,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAMhE;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAO7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAenF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG,MAAM,CAGT"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* semantic-match.ts — LOCAL, zero-key, zero-network semantic similarity (Loop 5).
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS — Loop 3 measured the keyword predictor at an honest 0/13 on
|
|
5
|
+
* the real corpus: of the 13 predictable corrections, 11 had ZERO lead-in↔trigger
|
|
6
|
+
* token overlap and the other 2 maxed at 1 (below the MIN_OVERLAP=2 floor). The
|
|
7
|
+
* relationship between a situation ("renaming the npm package and the README")
|
|
8
|
+
* and the resolution it will provoke ("Rename everything to Novada Proxy") is
|
|
9
|
+
* SEMANTIC, not lexical — different surface words, same concept.
|
|
10
|
+
*
|
|
11
|
+
* This module restores AgentRecall's local-by-default identity: NO OPENAI_API_KEY,
|
|
12
|
+
* NO network, NO per-call LLM. It bridges vocabularies with three cheap, pure
|
|
13
|
+
* signals over the situation text vs a blind-spot's trigger keywords:
|
|
14
|
+
*
|
|
15
|
+
* 1. LIGHT STEMMING — collapse morphology (publish/published/publishing,
|
|
16
|
+
* rename/renaming, customer/customers) so inflected forms match.
|
|
17
|
+
* 2. SYNONYM / CONCEPT EXPANSION — a small built-in map keyed to the recurring
|
|
18
|
+
* AgentRecall domains (publish↔ship↔release, secret↔key↔token↔credential,
|
|
19
|
+
* name↔rename↔naming, approval↔permission, codex↔sonnet↔agent). This is the
|
|
20
|
+
* actual bridge between a situation's verbs and a resolution's nouns.
|
|
21
|
+
* 3. CHARACTER-TRIGRAM COSINE — fuzzy overlap that catches shared roots and
|
|
22
|
+
* near-spellings even when whole stems differ.
|
|
23
|
+
*
|
|
24
|
+
* The combined score is `max(stemmed token-set cosine, char-trigram cosine)`
|
|
25
|
+
* over the SYNONYM-EXPANDED stem sets — a value in [0,1]. Callers compare it to a
|
|
26
|
+
* threshold to decide whether a risk fires.
|
|
27
|
+
*
|
|
28
|
+
* Pure, deterministic, no IO. The heavy lifting (set construction) is O(tokens);
|
|
29
|
+
* any precompute a caller wants belongs at write/consolidation time, not here.
|
|
30
|
+
*/
|
|
31
|
+
import { tokenize } from "../tools-logic/check-action.js";
|
|
32
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
33
|
+
// Light Porter-ish stemming — strips common English suffixes. NOT a full Porter
|
|
34
|
+
// stemmer (no library dependency); just enough to collapse the inflections that
|
|
35
|
+
// actually appear in corrections. Order matters: longest/most-specific first.
|
|
36
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
37
|
+
/** Suffix rules applied in order; first match wins. Each only fires above a min stem length. */
|
|
38
|
+
const STEM_RULES = [
|
|
39
|
+
{ suffix: "ization", minLen: 9, replace: "ize" }, // tokenization -> tokenize
|
|
40
|
+
{ suffix: "iveness", minLen: 9 },
|
|
41
|
+
{ suffix: "fulness", minLen: 9 },
|
|
42
|
+
{ suffix: "ousness", minLen: 9 },
|
|
43
|
+
{ suffix: " ", minLen: 99 }, // (never; placeholder kept out of hot path)
|
|
44
|
+
{ suffix: " ", minLen: 99 },
|
|
45
|
+
{ suffix: "ements", minLen: 8 },
|
|
46
|
+
{ suffix: "ables", minLen: 7 },
|
|
47
|
+
{ suffix: " ", minLen: 99 },
|
|
48
|
+
{ suffix: "ement", minLen: 7 },
|
|
49
|
+
{ suffix: "ation", minLen: 7, replace: "ate" }, // deprecation -> deprecate
|
|
50
|
+
{ suffix: "ingly", minLen: 7 },
|
|
51
|
+
{ suffix: "edly", minLen: 6 },
|
|
52
|
+
{ suffix: "ings", minLen: 6 }, // renamings -> renam (then -> rename via 'e' add below) — handled by 'ing'
|
|
53
|
+
{ suffix: "ies", minLen: 5, replace: "y" }, // dependencies -> dependency
|
|
54
|
+
{ suffix: "ied", minLen: 5, replace: "y" },
|
|
55
|
+
{ suffix: "ing", minLen: 5 }, // renaming -> renam ; publishing -> publish
|
|
56
|
+
{ suffix: "ers", minLen: 5 }, // builders -> build
|
|
57
|
+
{ suffix: "er", minLen: 5 }, // builder -> build (guarded by len so 'user' stays)
|
|
58
|
+
{ suffix: "ses", minLen: 5 }, // accesses -> acces -> (handled)
|
|
59
|
+
{ suffix: "es", minLen: 4 }, // changes -> chang ; aliases -> alias (len-guarded)
|
|
60
|
+
{ suffix: "ed", minLen: 4 }, // renamed -> renam ; changed -> chang
|
|
61
|
+
{ suffix: "ly", minLen: 5 }, // explicitly -> explicit
|
|
62
|
+
{ suffix: "s", minLen: 4 }, // customers -> customer ; tokens -> token
|
|
63
|
+
];
|
|
64
|
+
/**
|
|
65
|
+
* Stem a single lowercased token. Applies the first matching suffix rule, then a
|
|
66
|
+
* light "double consonant" fixup so e.g. `renam` (from `renaming`) collapses with
|
|
67
|
+
* `rename` by re-adding a trailing `e` when the stem ends in a consonant cluster
|
|
68
|
+
* that commonly drops an `e`. Deterministic and dependency-free.
|
|
69
|
+
*/
|
|
70
|
+
export function stem(token) {
|
|
71
|
+
let t = token;
|
|
72
|
+
for (const rule of STEM_RULES) {
|
|
73
|
+
if (rule.minLen >= 99)
|
|
74
|
+
continue;
|
|
75
|
+
if (t.length >= rule.minLen && t.endsWith(rule.suffix)) {
|
|
76
|
+
t = t.slice(0, t.length - rule.suffix.length) + (rule.replace ?? "");
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Collapse a doubled trailing consonant (running -> runn -> run).
|
|
81
|
+
if (t.length > 3 && /([^aeiou])\1$/.test(t))
|
|
82
|
+
t = t.slice(0, -1);
|
|
83
|
+
// Re-add a dropped silent 'e' for common verb stems so the -ing/-ed form and the
|
|
84
|
+
// bare form converge (renam->rename, declar->declare). Only when the stem ends in
|
|
85
|
+
// a consonant preceded by a vowel-consonant and is a plausible verb root length.
|
|
86
|
+
if (t.length >= 4 && /[bcdfgklmnprstvz]$/.test(t) && /[aeiou][^aeiou]$/.test(t)) {
|
|
87
|
+
// heuristic: nam->name, renam->rename, declar->declare. Add 'e' to canonicalize.
|
|
88
|
+
// Guarded against words that should stay bare by only firing for endings that
|
|
89
|
+
// frequently dropped an 'e' before -ing/-ed (a small, deterministic allowlist).
|
|
90
|
+
if (/(?:am|ar|at|iz|ut|os|us|iv|ac|ic|ag|ap|ip|op|ur)$/.test(t))
|
|
91
|
+
t = t + "e";
|
|
92
|
+
}
|
|
93
|
+
return t;
|
|
94
|
+
}
|
|
95
|
+
/** Stem every token in a set, returning a new stemmed set. */
|
|
96
|
+
export function stemSet(tokens) {
|
|
97
|
+
const out = new Set();
|
|
98
|
+
for (const t of tokens)
|
|
99
|
+
out.add(stem(t));
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
103
|
+
// Synonym / concept groups — the bridge between situation verbs and resolution
|
|
104
|
+
// nouns. Each group is a set of STEMS that should be treated as the same concept.
|
|
105
|
+
// Kept small and domain-grounded (the AgentRecall correction corpus): publishing,
|
|
106
|
+
// naming, secrets, approval, agents, products/memory. Adding a group widens
|
|
107
|
+
// recall; a too-broad group risks false positives, so groups stay tight.
|
|
108
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
109
|
+
const SYNONYM_GROUPS = [
|
|
110
|
+
// ship / release / deploy / publish — the most common situation→correction bridge.
|
|
111
|
+
["publish", "ship", "release", "deploy", "push", "launch", "npm", "version",
|
|
112
|
+
"bump", "registry", "rollout", "roll", "artifact"],
|
|
113
|
+
// naming / rename / identity-of-a-thing.
|
|
114
|
+
["name", "rename", "naming", "title", "label", "brand", "rebrand", "heading",
|
|
115
|
+
"docs", "readme"],
|
|
116
|
+
// secrets / credentials / keys.
|
|
117
|
+
["secret", "key", "token", "credential", "api-key", "apikey", "auth",
|
|
118
|
+
"password", "vault"],
|
|
119
|
+
// permission / approval / gating.
|
|
120
|
+
["approval", "approve", "permission", "permit", "gate", "consent", "confirm",
|
|
121
|
+
"explicit"],
|
|
122
|
+
// agents / models / orchestration (codex/sonnet/opus context).
|
|
123
|
+
["codex", "sonnet", "opus", "agent", "subagent", "sub-agent", "orchestrate",
|
|
124
|
+
"model", "prompt", "instruction"],
|
|
125
|
+
// customer / user / buyer.
|
|
126
|
+
["customer", "user", "buyer", "client", "visitor"],
|
|
127
|
+
// memory / understanding / recall (the product itself).
|
|
128
|
+
["memory", "understand", "recall", "remember", "knowledge", "context"],
|
|
129
|
+
// compliance / safety / risk.
|
|
130
|
+
["compliance", "compliant", "safety", "safe", "risk", "secure", "security"],
|
|
131
|
+
// build / scratch / reuse.
|
|
132
|
+
["build", "create", "make", "implement", "scratch", "reuse", "port", "offer",
|
|
133
|
+
"product"],
|
|
134
|
+
// email / contact / inbox.
|
|
135
|
+
["email", "inbox", "contact", "mail", "alias"],
|
|
136
|
+
// price / cost / margin / economics.
|
|
137
|
+
["cost", "margin", "price", "pricing", "economics", "spread", "basis", "expose"],
|
|
138
|
+
// config / settings / store / environment.
|
|
139
|
+
["config", "settings", "store", "environment", "env", "live", "production"],
|
|
140
|
+
// detail / thorough / explicit-text.
|
|
141
|
+
["detailed", "thorough", "detail", "explicit", "verbose"],
|
|
142
|
+
];
|
|
143
|
+
/** stem -> canonical concept id (index into SYNONYM_GROUPS). Built once at module load. */
|
|
144
|
+
const CONCEPT_OF = new Map();
|
|
145
|
+
for (let g = 0; g < SYNONYM_GROUPS.length; g++) {
|
|
146
|
+
for (const w of SYNONYM_GROUPS[g])
|
|
147
|
+
CONCEPT_OF.set(stem(w), g);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Canonicalize a stemmed token set into CONCEPT space: every token that belongs
|
|
151
|
+
* to a synonym group is REPLACED by its shared concept token (`__concept_<g>`);
|
|
152
|
+
* tokens with no concept pass through unchanged. Collapsing synonyms onto one
|
|
153
|
+
* shared dimension (rather than appending a marker alongside the surface stems)
|
|
154
|
+
* is what lets "publish package npm" and "ship release registry" overlap
|
|
155
|
+
* meaningfully — both reduce to the same `__concept_0`, so the cosine sees a real
|
|
156
|
+
* shared term instead of a diluted one. That is the semantic bridge.
|
|
157
|
+
*/
|
|
158
|
+
export function expandConcepts(stems) {
|
|
159
|
+
const out = new Set();
|
|
160
|
+
for (const t of stems) {
|
|
161
|
+
const g = CONCEPT_OF.get(t);
|
|
162
|
+
out.add(g !== undefined ? `__concept_${g}` : t);
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
167
|
+
// Cosine similarities
|
|
168
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
169
|
+
/** Set-cosine over two token sets (binary term vectors): |A∩B| / sqrt(|A|·|B|). */
|
|
170
|
+
export function setCosine(a, b) {
|
|
171
|
+
if (a.size === 0 || b.size === 0)
|
|
172
|
+
return 0;
|
|
173
|
+
let inter = 0;
|
|
174
|
+
const [small, large] = a.size <= b.size ? [a, b] : [b, a];
|
|
175
|
+
for (const t of small)
|
|
176
|
+
if (large.has(t))
|
|
177
|
+
inter++;
|
|
178
|
+
return inter / Math.sqrt(a.size * b.size);
|
|
179
|
+
}
|
|
180
|
+
/** Character trigrams of a token set's joined text (fuzzy root/near-spelling overlap). */
|
|
181
|
+
export function charTrigrams(tokens) {
|
|
182
|
+
const out = new Set();
|
|
183
|
+
for (const tok of tokens) {
|
|
184
|
+
const s = ` ${tok} `;
|
|
185
|
+
for (let i = 0; i + 3 <= s.length; i++)
|
|
186
|
+
out.add(s.slice(i, i + 3));
|
|
187
|
+
}
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The local semantic similarity in [0,1] between a SITUATION text and a
|
|
192
|
+
* blind-spot's matching MATERIAL (free text: its tendency / example rule and its
|
|
193
|
+
* trigger keywords joined together). Both sides are tokenized with the production
|
|
194
|
+
* grammar, stemmed, and concept-expanded; the score is the MAX of the expanded
|
|
195
|
+
* token-set cosine and the character-trigram cosine. Pure and deterministic.
|
|
196
|
+
*
|
|
197
|
+
* Passing the blind spot's full text (not just its sparse trigger_keywords) is
|
|
198
|
+
* what gives the semantic path material to work with — Loop 3's diagnostic showed
|
|
199
|
+
* trigger_keywords are frequently EMPTY for the predictable cases, so matching on
|
|
200
|
+
* keywords alone reproduces the 0/13. The richer text is the seed rule the
|
|
201
|
+
* correction was about, which DOES carry concept-bearing words.
|
|
202
|
+
*
|
|
203
|
+
* @param situation free-text plan / lead-in (the situation the agent is in)
|
|
204
|
+
* @param blindSpotText the blind spot's tendency / example_rule + trigger keywords
|
|
205
|
+
*/
|
|
206
|
+
export function semanticSimilarity(situation, blindSpotText) {
|
|
207
|
+
const sitTokens = tokenize(situation);
|
|
208
|
+
const bsTokens = tokenize(blindSpotText);
|
|
209
|
+
if (sitTokens.size === 0 || bsTokens.size === 0)
|
|
210
|
+
return 0;
|
|
211
|
+
const sitStem = stemSet(sitTokens);
|
|
212
|
+
const bsStem = stemSet(bsTokens);
|
|
213
|
+
const sitExp = expandConcepts(sitStem);
|
|
214
|
+
const bsExp = expandConcepts(bsStem);
|
|
215
|
+
const tokenCos = setCosine(sitExp, bsExp);
|
|
216
|
+
const triCos = setCosine(charTrigrams(sitStem), charTrigrams(bsStem));
|
|
217
|
+
return Math.max(tokenCos, triCos);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Build the semantic matching MATERIAL for a blind spot: its concept-bearing
|
|
221
|
+
* tendency / example rule text plus its trigger keywords, joined into one string.
|
|
222
|
+
* Centralizes what "the blind spot's text" means so production code and the LOO
|
|
223
|
+
* harness score the SAME way (no fork — the harness imports this).
|
|
224
|
+
*/
|
|
225
|
+
export function blindSpotConcepts(bs) {
|
|
226
|
+
const parts = [bs.tendency ?? "", bs.example_rule ?? "", ...(bs.trigger_keywords ?? [])];
|
|
227
|
+
return parts.filter(Boolean).join(" ");
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=semantic-match.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-match.js","sourceRoot":"","sources":["../../src/helpers/semantic-match.ts"],"names":[],"mappings":"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"}
|