@jmtrin/opencode-kevin 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -6
- package/dist/migrations/005_v04_signal.sql +57 -0
- package/dist/plugin/CausalChain.d.ts +13 -2
- package/dist/plugin/CausalChain.js +83 -13
- package/dist/plugin/CausalChain.js.map +1 -1
- package/dist/plugin/ContextInjector.d.ts +80 -4
- package/dist/plugin/ContextInjector.js +262 -88
- package/dist/plugin/ContextInjector.js.map +1 -1
- package/dist/plugin/InjectionLedger.d.ts +85 -0
- package/dist/plugin/InjectionLedger.js +189 -0
- package/dist/plugin/InjectionLedger.js.map +1 -0
- package/dist/plugin/LessonFixer.d.ts +44 -0
- package/dist/plugin/LessonFixer.js +46 -0
- package/dist/plugin/LessonFixer.js.map +1 -0
- package/dist/plugin/MemoryService.d.ts +62 -1
- package/dist/plugin/MemoryService.js +206 -43
- package/dist/plugin/MemoryService.js.map +1 -1
- package/dist/plugin/Migrate.js +10 -0
- package/dist/plugin/Migrate.js.map +1 -1
- package/dist/plugin/QualityGate.d.ts +71 -0
- package/dist/plugin/QualityGate.js +78 -0
- package/dist/plugin/QualityGate.js.map +1 -0
- package/dist/plugin/Reflector.d.ts +17 -0
- package/dist/plugin/Reflector.js +81 -26
- package/dist/plugin/Reflector.js.map +1 -1
- package/dist/plugin/Retrospective.js +10 -1
- package/dist/plugin/Retrospective.js.map +1 -1
- package/dist/plugin/ToolCallObserver.d.ts +1 -0
- package/dist/plugin/ToolCallObserver.js +15 -8
- package/dist/plugin/ToolCallObserver.js.map +1 -1
- package/dist/plugin/confidence.d.ts +6 -0
- package/dist/plugin/confidence.js +23 -0
- package/dist/plugin/confidence.js.map +1 -0
- package/dist/plugin/index.d.ts +5 -0
- package/dist/plugin/index.js +216 -44
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/kevin_why.d.ts +4 -0
- package/dist/plugin/kevin_why.js +51 -35
- package/dist/plugin/kevin_why.js.map +1 -1
- package/dist/plugin/memory-format.d.ts +12 -0
- package/dist/plugin/memory-format.js +45 -5
- package/dist/plugin/memory-format.js.map +1 -1
- package/dist/plugin/metrics.d.ts +7 -1
- package/dist/plugin/metrics.js +16 -0
- package/dist/plugin/metrics.js.map +1 -1
- package/dist/plugin/okf-export.js +63 -22
- package/dist/plugin/okf-export.js.map +1 -1
- package/dist/plugin/okf-import.d.ts +4 -1
- package/dist/plugin/okf-import.js +45 -12
- package/dist/plugin/okf-import.js.map +1 -1
- package/dist/plugin/query-tokenizer.d.ts +13 -0
- package/dist/plugin/query-tokenizer.js +86 -0
- package/dist/plugin/query-tokenizer.js.map +1 -0
- package/migrations/005_v04_signal.sql +57 -0
- package/package.json +1 -1
|
@@ -3,6 +3,18 @@ export interface MemoryBlockItem {
|
|
|
3
3
|
type: string;
|
|
4
4
|
content: string;
|
|
5
5
|
protect?: boolean;
|
|
6
|
+
/** v0.4.0 (K4-023) — weak lesson admitted in debug mode: the row is
|
|
7
|
+
* rendered with a `(low confidence)` marker line. */
|
|
8
|
+
weak?: boolean;
|
|
6
9
|
}
|
|
7
10
|
export declare function escapeInjectedText(text: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* v0.4.0 (K4-012) — progressive disclosure for injection: a short
|
|
13
|
+
* snippet row instead of the full body. Row = `id:` line + `[type]`
|
|
14
|
+
* prefix + the first 2 non-empty lines of content, wrapped in
|
|
15
|
+
* `<protect>` unless the memory opted out (`protect: false`). The
|
|
16
|
+
* full body stays available via `kevin_get`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatSnippet(m: MemoryBlockItem): string;
|
|
8
19
|
export declare function formatMemories(memories: MemoryBlockItem[], tag: "context" | "memory"): string;
|
|
20
|
+
export declare function formatMemorySnippets(memories: MemoryBlockItem[], tag: "context" | "memory"): string;
|
|
@@ -4,17 +4,57 @@ export function escapeInjectedText(text) {
|
|
|
4
4
|
.replace(/</g, "<")
|
|
5
5
|
.replace(/>/g, ">");
|
|
6
6
|
}
|
|
7
|
+
function typePrefix(m) {
|
|
8
|
+
const t = escapeInjectedText(String(m.type));
|
|
9
|
+
return m.weak ? `[${t}] (low confidence)` : `[${t}]`;
|
|
10
|
+
}
|
|
7
11
|
function formatRow(m) {
|
|
8
12
|
const idLine = m.id ? `id: ${escapeInjectedText(m.id)}\n` : "";
|
|
9
|
-
const body = `${idLine}
|
|
13
|
+
const body = `${idLine}${typePrefix(m)} ${escapeInjectedText(m.content)}`;
|
|
10
14
|
return m.protect === false ? body : `<protect>\n${body}\n</protect>`;
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
/**
|
|
17
|
+
* v0.4.0 (K4-012) — progressive disclosure for injection: a short
|
|
18
|
+
* snippet row instead of the full body. Row = `id:` line + `[type]`
|
|
19
|
+
* prefix + the first 2 non-empty lines of content, wrapped in
|
|
20
|
+
* `<protect>` unless the memory opted out (`protect: false`). The
|
|
21
|
+
* full body stays available via `kevin_get`.
|
|
22
|
+
*/
|
|
23
|
+
export function formatSnippet(m) {
|
|
24
|
+
const lines = m.content
|
|
25
|
+
.split(/\r?\n/)
|
|
26
|
+
.map((l) => l.trim())
|
|
27
|
+
.filter((l) => l.length > 0)
|
|
28
|
+
.slice(0, 2);
|
|
29
|
+
// v0.4.0 (K4-025) — a pattern's `Fixed by:` line is the highest-value
|
|
30
|
+
// payload (plan §5.4 / D4-07); surface it in the snippet even though
|
|
31
|
+
// it sits below the 2-line cut. Only patterns carry the line.
|
|
32
|
+
const fixLine = lines
|
|
33
|
+
.map((l) => l)
|
|
34
|
+
.concat(m.content
|
|
35
|
+
.split(/\r?\n/)
|
|
36
|
+
.map((l) => l.trim())
|
|
37
|
+
.filter((l) => l.startsWith("Fixed by:")))[2];
|
|
38
|
+
const idLine = m.id ? `id: ${escapeInjectedText(m.id)}\n` : "";
|
|
39
|
+
const bodyLines = fixLine ? [...lines, fixLine] : lines;
|
|
40
|
+
const body = bodyLines.length === 0
|
|
41
|
+
? ""
|
|
42
|
+
: `${idLine}${typePrefix(m)} ${escapeInjectedText(bodyLines.join("\n"))}`;
|
|
43
|
+
return m.protect === false ? body : `<protect>\n${body}\n</protect>`;
|
|
44
|
+
}
|
|
45
|
+
function wrapBlock(body, tag) {
|
|
16
46
|
return tag === "context"
|
|
17
47
|
? `<kevin-context>Lecciones relevantes:\n${body}\n</kevin-context>`
|
|
18
48
|
: `<kevin-memory>\n${body}\n</kevin-memory>`;
|
|
19
49
|
}
|
|
50
|
+
export function formatMemories(memories, tag) {
|
|
51
|
+
if (memories.length === 0)
|
|
52
|
+
return "";
|
|
53
|
+
return wrapBlock(memories.map(formatRow).join("\n"), tag);
|
|
54
|
+
}
|
|
55
|
+
export function formatMemorySnippets(memories, tag) {
|
|
56
|
+
if (memories.length === 0)
|
|
57
|
+
return "";
|
|
58
|
+
return wrapBlock(memories.map(formatSnippet).join("\n"), tag);
|
|
59
|
+
}
|
|
20
60
|
//# sourceMappingURL=memory-format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-format.js","sourceRoot":"","sources":["../../plugin/memory-format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-format.js","sourceRoot":"","sources":["../../plugin/memory-format.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin/metrics.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { Store } from "./Store.js";
|
|
|
6
6
|
* underlying table is empty (e.g., before 003 is applied, on a fresh
|
|
7
7
|
* :memory: test DB, or after a manual wipe).
|
|
8
8
|
*/
|
|
9
|
-
export declare const METRIC_KEYS: readonly ["tokens_injected_pre_prompt", "tokens_injected_compacting", "reflections_throttled", "duplicate_suppressions", "tool_calls_deduped", "patterns_mined", "patterns_causal", "causal_links", "memories_superseded"];
|
|
9
|
+
export declare const METRIC_KEYS: readonly ["tokens_injected_pre_prompt", "tokens_injected_compacting", "reflections_throttled", "duplicate_suppressions", "tool_calls_deduped", "patterns_mined", "patterns_causal", "causal_links", "memories_superseded", "injections_total", "injections_effective", "injections_ineffective", "patterns_promoted_new"];
|
|
10
10
|
export type MetricKey = (typeof METRIC_KEYS)[number];
|
|
11
11
|
/**
|
|
12
12
|
* Cheap token estimate used when bumping the `tokens_injected_*` counters.
|
|
@@ -44,6 +44,12 @@ export declare class Metrics {
|
|
|
44
44
|
* Returns the cached value for a single key. Does NOT flush.
|
|
45
45
|
*/
|
|
46
46
|
get(key: MetricKey): number;
|
|
47
|
+
/**
|
|
48
|
+
* v0.4.0 (K4-008): injection precision = effective / total settled
|
|
49
|
+
* injections. 0 when the ledger has no entries yet (no division by zero).
|
|
50
|
+
* Computed from the cached counters — does NOT flush.
|
|
51
|
+
*/
|
|
52
|
+
precisionRate(): number;
|
|
47
53
|
/** True iff a debounced flush is scheduled. Useful for tests. */
|
|
48
54
|
isFlushScheduled(): boolean;
|
|
49
55
|
/**
|
package/dist/plugin/metrics.js
CHANGED
|
@@ -15,6 +15,10 @@ export const METRIC_KEYS = [
|
|
|
15
15
|
"patterns_causal",
|
|
16
16
|
"causal_links",
|
|
17
17
|
"memories_superseded",
|
|
18
|
+
"injections_total",
|
|
19
|
+
"injections_effective",
|
|
20
|
+
"injections_ineffective",
|
|
21
|
+
"patterns_promoted_new",
|
|
18
22
|
];
|
|
19
23
|
const DEFAULT_FLUSH_MS = 1000;
|
|
20
24
|
function zeroCache() {
|
|
@@ -98,6 +102,18 @@ export class Metrics {
|
|
|
98
102
|
get(key) {
|
|
99
103
|
return this.cache.get(key) ?? 0;
|
|
100
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* v0.4.0 (K4-008): injection precision = effective / total settled
|
|
107
|
+
* injections. 0 when the ledger has no entries yet (no division by zero).
|
|
108
|
+
* Computed from the cached counters — does NOT flush.
|
|
109
|
+
*/
|
|
110
|
+
precisionRate() {
|
|
111
|
+
const total = this.cache.get("injections_total") ?? 0;
|
|
112
|
+
if (total <= 0)
|
|
113
|
+
return 0;
|
|
114
|
+
const effective = this.cache.get("injections_effective") ?? 0;
|
|
115
|
+
return Math.min(1, effective / total);
|
|
116
|
+
}
|
|
101
117
|
/** True iff a debounced flush is scheduled. Useful for tests. */
|
|
102
118
|
isFlushScheduled() {
|
|
103
119
|
return this.flushTimer !== null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../plugin/metrics.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,4BAA4B;IAC5B,4BAA4B;IAC5B,uBAAuB;IACvB,wBAAwB;IACxB,oBAAoB;IACpB,gBAAgB;IAChB,iBAAiB;IACjB,cAAc;IACd,qBAAqB;
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../plugin/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,65 @@
|
|
|
1
|
+
import { computeConfidence } from "./confidence.js";
|
|
1
2
|
const EXPORT_TYPES = new Set(["decision", "rule", "pattern"]);
|
|
2
3
|
function formatTimestamp(ts) {
|
|
3
4
|
try {
|
|
4
|
-
|
|
5
|
+
// SQLite `datetime('now')` is UTC without a zone suffix; parse as
|
|
6
|
+
// UTC so a round-trip never shifts the value by the local offset.
|
|
7
|
+
const iso = ts.includes("T") ? ts : `${ts.replace(" ", "T")}Z`;
|
|
8
|
+
return new Date(iso).toISOString().replace("T", " ").slice(0, 19);
|
|
5
9
|
}
|
|
6
10
|
catch {
|
|
7
11
|
return ts;
|
|
8
12
|
}
|
|
9
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* BUG-008 — select export rows including `recurrence_count` (the v0.4.0
|
|
16
|
+
* demotion signal, column from migration 005). DBs that predate 005 have
|
|
17
|
+
* no such column; the SELECT is retried without it and recurrences
|
|
18
|
+
* degrade to 0 (legacy confidence formula applies — see below).
|
|
19
|
+
*/
|
|
20
|
+
function selectExportRows(store) {
|
|
21
|
+
try {
|
|
22
|
+
return {
|
|
23
|
+
hasRecurrence: true,
|
|
24
|
+
rows: store
|
|
25
|
+
.prepare(`SELECT id, type, content, scope, relevance_score, fingerprint,
|
|
26
|
+
evidence_count, recurrence_count, last_verified_at, status,
|
|
27
|
+
source_tool, source_session, created_at, updated_at
|
|
28
|
+
FROM memories
|
|
29
|
+
WHERE status = 'active'
|
|
30
|
+
ORDER BY type, created_at DESC`)
|
|
31
|
+
.all(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
const legacy = store
|
|
36
|
+
.prepare(`SELECT id, type, content, scope, relevance_score, fingerprint,
|
|
37
|
+
evidence_count, last_verified_at, status,
|
|
38
|
+
source_tool, source_session, created_at, updated_at
|
|
39
|
+
FROM memories
|
|
40
|
+
WHERE status = 'active'
|
|
41
|
+
ORDER BY type, created_at DESC`)
|
|
42
|
+
.all();
|
|
43
|
+
return {
|
|
44
|
+
hasRecurrence: false,
|
|
45
|
+
rows: legacy.map((r) => ({ ...r, recurrence_count: 0 })),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* BUG-008 — the exported confidence must match the two-sided v0.4.0
|
|
51
|
+
* formula (K4-010), demoting lessons with recurrences. Pre-005 DBs (no
|
|
52
|
+
* `recurrence_count` column) keep the legacy one-sided formula.
|
|
53
|
+
*/
|
|
54
|
+
function exportConfidence(row, hasRecurrence) {
|
|
55
|
+
const confidence = hasRecurrence
|
|
56
|
+
? computeConfidence(row.evidence_count, row.recurrence_count)
|
|
57
|
+
: Math.min(1, 0.5 + 0.1 * row.evidence_count);
|
|
58
|
+
return confidence.toFixed(2);
|
|
59
|
+
}
|
|
10
60
|
export function exportOkf(store) {
|
|
11
|
-
const rows = store
|
|
12
|
-
|
|
13
|
-
evidence_count, last_verified_at, status,
|
|
14
|
-
source_tool, source_session, created_at, updated_at
|
|
15
|
-
FROM memories
|
|
16
|
-
WHERE status = 'active'
|
|
17
|
-
ORDER BY type, created_at DESC`)
|
|
18
|
-
.all();
|
|
19
|
-
const filtered = rows.filter((r) => EXPORT_TYPES.has(r.type));
|
|
61
|
+
const { rows: allRows, hasRecurrence } = selectExportRows(store);
|
|
62
|
+
const filtered = allRows.filter((r) => EXPORT_TYPES.has(r.type));
|
|
20
63
|
if (filtered.length === 0)
|
|
21
64
|
return "<!-- No exportable memories found. -->\n";
|
|
22
65
|
const blocks = [];
|
|
@@ -25,8 +68,11 @@ export function exportOkf(store) {
|
|
|
25
68
|
fm.push("---");
|
|
26
69
|
fm.push(`id: ${m.id}`);
|
|
27
70
|
fm.push(`type: ${m.type}`);
|
|
28
|
-
fm.push(`confidence: ${
|
|
71
|
+
fm.push(`confidence: ${exportConfidence(m, hasRecurrence)}`);
|
|
29
72
|
fm.push(`evidence_count: ${m.evidence_count}`);
|
|
73
|
+
if (m.recurrence_count > 0) {
|
|
74
|
+
fm.push(`recurrence_count: ${m.recurrence_count}`);
|
|
75
|
+
}
|
|
30
76
|
if (m.last_verified_at) {
|
|
31
77
|
fm.push(`last_verified_at: ${formatTimestamp(m.last_verified_at)}`);
|
|
32
78
|
}
|
|
@@ -43,15 +89,8 @@ export function exportOkf(store) {
|
|
|
43
89
|
return `${blocks.join("\n\n")}\n`;
|
|
44
90
|
}
|
|
45
91
|
export function exportMarkdown(store) {
|
|
46
|
-
const rows = store
|
|
47
|
-
|
|
48
|
-
evidence_count, last_verified_at, status,
|
|
49
|
-
created_at, updated_at
|
|
50
|
-
FROM memories
|
|
51
|
-
WHERE status = 'active'
|
|
52
|
-
ORDER BY type, created_at DESC`)
|
|
53
|
-
.all();
|
|
54
|
-
const filtered = rows.filter((r) => EXPORT_TYPES.has(r.type));
|
|
92
|
+
const { rows: allRows, hasRecurrence } = selectExportRows(store);
|
|
93
|
+
const filtered = allRows.filter((r) => EXPORT_TYPES.has(r.type));
|
|
55
94
|
if (filtered.length === 0)
|
|
56
95
|
return "# Kevin Knowledge Export\n\n_No exportable memories found._\n";
|
|
57
96
|
const lines = [];
|
|
@@ -61,12 +100,14 @@ export function exportMarkdown(store) {
|
|
|
61
100
|
lines.push(`Total entries: ${filtered.length}`);
|
|
62
101
|
lines.push("");
|
|
63
102
|
for (const m of filtered) {
|
|
64
|
-
const conf = Math.min(1, 0.5 + 0.1 * m.evidence_count);
|
|
65
103
|
lines.push(`## ${m.type}: \`${m.fingerprint ?? m.id.slice(0, 8)}\``);
|
|
66
104
|
lines.push("");
|
|
67
105
|
lines.push(`- **ID:** \`${m.id}\``);
|
|
68
|
-
lines.push(`- **Confidence:** ${
|
|
106
|
+
lines.push(`- **Confidence:** ${exportConfidence(m, hasRecurrence)}`);
|
|
69
107
|
lines.push(`- **Evidence count:** ${m.evidence_count}`);
|
|
108
|
+
if (m.recurrence_count > 0) {
|
|
109
|
+
lines.push(`- **Recurrence count:** ${m.recurrence_count}`);
|
|
110
|
+
}
|
|
70
111
|
if (m.last_verified_at) {
|
|
71
112
|
lines.push(`- **Last verified:** ${formatTimestamp(m.last_verified_at)}`);
|
|
72
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"okf-export.js","sourceRoot":"","sources":["../../plugin/okf-export.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"okf-export.js","sourceRoot":"","sources":["../../plugin/okf-export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAE9D,SAAS,eAAe,CAAC,EAAU;IAClC,IAAI,CAAC;QACJ,kEAAkE;QAClE,kEAAkE;QAClE,MAAM,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;QAC/D,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAmBD;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAY;IAIrC,IAAI,CAAC;QACJ,OAAO;YACN,aAAa,EAAE,IAAI;YACnB,IAAI,EAAE,KAAK;iBACT,OAAO,CACP;;;;;qCAKgC,CAChC;iBACA,GAAG,EAAiB;SACtB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,MAAM,GAAG,KAAK;aAClB,OAAO,CACP;;;;;oCAKgC,CAChC;aACA,GAAG,EAAgD,CAAC;QACtD,OAAO;YACN,aAAa,EAAE,KAAK;YACpB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;SACxD,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACxB,GAAyD,EACzD,aAAsB;IAEtB,MAAM,UAAU,GAAG,aAAa;QAC/B,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,gBAAgB,CAAC;QAC7D,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;IAC/C,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAY;IACrC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,0CAA0C,CAAC;IAE7E,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAa,EAAE,CAAC;QACxB,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvB,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3B,EAAE,CAAC,IAAI,CAAC,eAAe,gBAAgB,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QAC7D,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;YACxB,EAAE,CAAC,IAAI,CAAC,qBAAqB,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,EAAE,CAAC,IAAI,CAAC,YAAY,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrD,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7B,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACf,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY;IAC1C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QACxB,OAAO,+DAA+D,CAAC;IAExE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CACT,aAAa,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CACtE,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,qBAAqB,gBAAgB,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QACtE,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,CAAC,gBAAgB,GAAG,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,wBAAwB,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;QACvD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,kBAAkB,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -3,7 +3,8 @@ import type { MemoryService } from "./MemoryService.js";
|
|
|
3
3
|
* v0.3.0 fix — A single parsed bundle entry. `evidence_count` and
|
|
4
4
|
* `last_verified_at` are preserved across round-trips (export → import)
|
|
5
5
|
* so causal confidence is not lost when knowledge is shared between
|
|
6
|
-
* projects.
|
|
6
|
+
* projects. v0.4.0 (BUG-008) — `recurrence_count` too, so the two-sided
|
|
7
|
+
* v0.4.0 confidence demotion survives the round-trip.
|
|
7
8
|
*/
|
|
8
9
|
export interface ParsedEntry {
|
|
9
10
|
id: string;
|
|
@@ -11,6 +12,8 @@ export interface ParsedEntry {
|
|
|
11
12
|
content: string;
|
|
12
13
|
fingerprint: string | null;
|
|
13
14
|
evidence_count: number;
|
|
15
|
+
/** v0.4.0 (BUG-008) — recurrence demotion, 0 when absent. */
|
|
16
|
+
recurrence_count: number;
|
|
14
17
|
last_verified_at: string | null;
|
|
15
18
|
}
|
|
16
19
|
/**
|
|
@@ -101,6 +101,7 @@ export function parseMarkdownBundle(text) {
|
|
|
101
101
|
const id = ID_RE.test(fm.id) ? fm.id : uuidv7();
|
|
102
102
|
const fp = fm.fingerprint ?? null;
|
|
103
103
|
const evidenceCount = Number.parseInt(fm.evidence_count ?? "0", 10) || 0;
|
|
104
|
+
const recurrenceCount = Number.parseInt(fm.recurrence_count ?? "0", 10) || 0;
|
|
104
105
|
const lastVerified = fm.last_verified_at ?? null;
|
|
105
106
|
entries.push({
|
|
106
107
|
id,
|
|
@@ -108,6 +109,7 @@ export function parseMarkdownBundle(text) {
|
|
|
108
109
|
content,
|
|
109
110
|
fingerprint: fp,
|
|
110
111
|
evidence_count: evidenceCount,
|
|
112
|
+
recurrence_count: recurrenceCount,
|
|
111
113
|
last_verified_at: lastVerified,
|
|
112
114
|
});
|
|
113
115
|
}
|
|
@@ -136,25 +138,50 @@ export function parseMarkdownHeadings(text) {
|
|
|
136
138
|
const type = typeMatch ? typeMatch[1].toLowerCase() : "context";
|
|
137
139
|
const fm = {};
|
|
138
140
|
let bodyStart = -1;
|
|
141
|
+
// True once at least one `- **Key:**` bullet was consumed; the
|
|
142
|
+
// body starts at the FIRST blank line AFTER the bullet block.
|
|
143
|
+
// Blank lines before any bullet (e.g. right after the `##` heading)
|
|
144
|
+
// must be skipped, not treated as body delimiters.
|
|
145
|
+
let sawBullet = false;
|
|
139
146
|
for (let k = 1; k < lines.length; k++) {
|
|
140
147
|
const ln = lines[k];
|
|
141
148
|
const bulletId = ln.match(/^- \*\*ID:\*\*\s*`([^`]+)`/);
|
|
142
149
|
const bulletFp = ln.match(/^- \*\*Fingerprint:\*\*\s*`([a-f0-9]+)`/i);
|
|
143
150
|
const bulletEv = ln.match(/^- \*\*Evidence count:\*\*\s*(\d+)/);
|
|
151
|
+
const bulletRec = ln.match(/^- \*\*Recurrence count:\*\*\s*(\d+)/);
|
|
144
152
|
const bulletLv = ln.match(/^- \*\*Last verified:\*\*\s*(.+)$/);
|
|
145
|
-
if (bulletId)
|
|
153
|
+
if (bulletId) {
|
|
146
154
|
fm.id = bulletId[1];
|
|
147
|
-
|
|
155
|
+
sawBullet = true;
|
|
156
|
+
}
|
|
157
|
+
else if (bulletFp) {
|
|
148
158
|
fm.fingerprint = bulletFp[1];
|
|
149
|
-
|
|
159
|
+
sawBullet = true;
|
|
160
|
+
}
|
|
161
|
+
else if (bulletEv) {
|
|
150
162
|
fm.evidence_count = bulletEv[1];
|
|
151
|
-
|
|
163
|
+
sawBullet = true;
|
|
164
|
+
}
|
|
165
|
+
else if (bulletRec) {
|
|
166
|
+
fm.recurrence_count = bulletRec[1];
|
|
167
|
+
sawBullet = true;
|
|
168
|
+
}
|
|
169
|
+
else if (bulletLv) {
|
|
152
170
|
fm.last_verified_at = bulletLv[1].trim();
|
|
171
|
+
sawBullet = true;
|
|
172
|
+
}
|
|
153
173
|
else if (ln.trim() === "") {
|
|
154
174
|
// First blank line after bullet block — body starts here.
|
|
155
|
-
if (
|
|
175
|
+
if (sawBullet) {
|
|
156
176
|
bodyStart = k + 1;
|
|
157
|
-
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
// Leading blank line (right after the heading) — skip.
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Other bullets (e.g. `- **Confidence:**`, `- **Scope:**`)
|
|
183
|
+
// are not captured — skip them; the bullet block ends at
|
|
184
|
+
// the next blank line.
|
|
158
185
|
}
|
|
159
186
|
}
|
|
160
187
|
if (bodyStart < 0)
|
|
@@ -176,6 +203,7 @@ export function parseMarkdownHeadings(text) {
|
|
|
176
203
|
content,
|
|
177
204
|
fingerprint: fm.fingerprint ?? null,
|
|
178
205
|
evidence_count: Number.parseInt(fm.evidence_count ?? "0", 10) || 0,
|
|
206
|
+
recurrence_count: Number.parseInt(fm.recurrence_count ?? "0", 10) || 0,
|
|
179
207
|
last_verified_at: fm.last_verified_at ?? null,
|
|
180
208
|
});
|
|
181
209
|
}
|
|
@@ -213,11 +241,6 @@ export function importOkf(bundle, memoryService) {
|
|
|
213
241
|
if (!IMPORT_ALLOWED_TYPES.has(entry.type))
|
|
214
242
|
continue;
|
|
215
243
|
const fp = entry.fingerprint ?? computeFingerprint(entry.content, undefined);
|
|
216
|
-
const contentWithEvidence = entry.evidence_count > 0
|
|
217
|
-
? `${entry.content}\n\n[imported evidence_count=${entry.evidence_count}${entry.last_verified_at
|
|
218
|
-
? `, last_verified_at=${entry.last_verified_at}`
|
|
219
|
-
: ""}]`
|
|
220
|
-
: entry.content;
|
|
221
244
|
// Count rows that save() will mark as superseded (decision/rule
|
|
222
245
|
// with the same fingerprint). The supersede update itself runs
|
|
223
246
|
// inside MemoryService.save() in a single transaction; we count
|
|
@@ -225,11 +248,21 @@ export function importOkf(bundle, memoryService) {
|
|
|
225
248
|
superseded += memoryService.countSupersedeCandidates(entry.type, fp, null);
|
|
226
249
|
memoryService.save({
|
|
227
250
|
type: entry.type,
|
|
228
|
-
|
|
251
|
+
// BUG-008 — preserve the bundle id so a round-trip (export →
|
|
252
|
+
// import) keeps memory identity and `getById` stays stable.
|
|
253
|
+
id: entry.id,
|
|
254
|
+
// BUG-009 — the content is the bundle body verbatim. The old
|
|
255
|
+
// code appended `[imported evidence_count=N, ...]`, which the
|
|
256
|
+
// ContextInjector later injected verbatim into model prompts;
|
|
257
|
+
// the values travel via the typed fields below instead.
|
|
258
|
+
content: entry.content,
|
|
229
259
|
scope: "project",
|
|
230
260
|
origin: "imported",
|
|
231
261
|
fingerprint: fp,
|
|
232
262
|
evidenceCount: entry.evidence_count > 0 ? entry.evidence_count : undefined,
|
|
263
|
+
// BUG-008 — restore the recurrence demotion so the re-imported
|
|
264
|
+
// copy keeps the v0.4.0 two-sided confidence of the source.
|
|
265
|
+
recurrenceCount: entry.recurrence_count > 0 ? entry.recurrence_count : undefined,
|
|
233
266
|
lastVerifiedAt: entry.last_verified_at ?? undefined,
|
|
234
267
|
});
|
|
235
268
|
imported++;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"okf-import.js","sourceRoot":"","sources":["../../plugin/okf-import.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,MAAM,OAAO,GAAG,sBAAsB,CAAC;AACvC,MAAM,KAAK,GAAG,iEAAiE,CAAC;
|
|
1
|
+
{"version":3,"file":"okf-import.js","sourceRoot":"","sources":["../../plugin/okf-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K4-013 — shared FTS5 query tokenizer.
|
|
3
|
+
*
|
|
4
|
+
* Injection recall ORs the quoted tokens (`"t1" OR "t2"`) while
|
|
5
|
+
* `kevin_why` ANDs them (`"t1" AND "t2"`).
|
|
6
|
+
*/
|
|
7
|
+
export declare const STOP_WORDS: Set<string>;
|
|
8
|
+
/** Lowercase, split on whitespace, drop stopwords. Returns raw tokens. */
|
|
9
|
+
export declare function tokenizeQuery(query: string): string[];
|
|
10
|
+
/** Quote a token for an FTS5 MATCH clause, escaping embedded quotes. */
|
|
11
|
+
export declare function quoteToken(token: string): string;
|
|
12
|
+
/** Join quoted tokens into a MATCH clause with the given separator. */
|
|
13
|
+
export declare function toMatchClause(tokens: string[], separator: " OR " | " AND "): string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K4-013 — shared FTS5 query tokenizer.
|
|
3
|
+
*
|
|
4
|
+
* Injection recall ORs the quoted tokens (`"t1" OR "t2"`) while
|
|
5
|
+
* `kevin_why` ANDs them (`"t1" AND "t2"`).
|
|
6
|
+
*/
|
|
7
|
+
export const STOP_WORDS = new Set([
|
|
8
|
+
"a",
|
|
9
|
+
"an",
|
|
10
|
+
"and",
|
|
11
|
+
"are",
|
|
12
|
+
"at",
|
|
13
|
+
"be",
|
|
14
|
+
"been",
|
|
15
|
+
"but",
|
|
16
|
+
"by",
|
|
17
|
+
"did",
|
|
18
|
+
"do",
|
|
19
|
+
"does",
|
|
20
|
+
"el",
|
|
21
|
+
"eso",
|
|
22
|
+
"for",
|
|
23
|
+
"how",
|
|
24
|
+
"i",
|
|
25
|
+
"if",
|
|
26
|
+
"in",
|
|
27
|
+
"is",
|
|
28
|
+
"it",
|
|
29
|
+
"la",
|
|
30
|
+
"las",
|
|
31
|
+
"los",
|
|
32
|
+
"mi",
|
|
33
|
+
"my",
|
|
34
|
+
"o",
|
|
35
|
+
"of",
|
|
36
|
+
"on",
|
|
37
|
+
"or",
|
|
38
|
+
"para",
|
|
39
|
+
"por",
|
|
40
|
+
"que",
|
|
41
|
+
"she",
|
|
42
|
+
"su",
|
|
43
|
+
"that",
|
|
44
|
+
"the",
|
|
45
|
+
"this",
|
|
46
|
+
"to",
|
|
47
|
+
"tu",
|
|
48
|
+
"un",
|
|
49
|
+
"una",
|
|
50
|
+
"we",
|
|
51
|
+
"were",
|
|
52
|
+
"what",
|
|
53
|
+
"when",
|
|
54
|
+
"where",
|
|
55
|
+
"which",
|
|
56
|
+
"who",
|
|
57
|
+
"why",
|
|
58
|
+
"with",
|
|
59
|
+
"y",
|
|
60
|
+
"you",
|
|
61
|
+
"como",
|
|
62
|
+
"con",
|
|
63
|
+
"de",
|
|
64
|
+
"en",
|
|
65
|
+
"he",
|
|
66
|
+
"they",
|
|
67
|
+
"was",
|
|
68
|
+
"sin",
|
|
69
|
+
]);
|
|
70
|
+
/** Lowercase, split on whitespace, drop stopwords. Returns raw tokens. */
|
|
71
|
+
export function tokenizeQuery(query) {
|
|
72
|
+
return query
|
|
73
|
+
.trim()
|
|
74
|
+
.toLowerCase()
|
|
75
|
+
.split(/\s+/)
|
|
76
|
+
.filter((t) => t.length > 0 && !STOP_WORDS.has(t));
|
|
77
|
+
}
|
|
78
|
+
/** Quote a token for an FTS5 MATCH clause, escaping embedded quotes. */
|
|
79
|
+
export function quoteToken(token) {
|
|
80
|
+
return `"${token.replace(/"/g, '""')}"`;
|
|
81
|
+
}
|
|
82
|
+
/** Join quoted tokens into a MATCH clause with the given separator. */
|
|
83
|
+
export function toMatchClause(tokens, separator) {
|
|
84
|
+
return tokens.map(quoteToken).join(separator);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=query-tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-tokenizer.js","sourceRoot":"","sources":["../../plugin/query-tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS;IACzC,GAAG;IACH,IAAI;IACJ,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,MAAM;IACN,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;IACJ,MAAM;IACN,KAAK;IACL,MAAM;IACN,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,KAAK;IACL,KAAK;IACL,MAAM;IACN,GAAG;IACH,KAAK;IACL,MAAM;IACN,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,MAAM;IACN,KAAK;IACL,KAAK;CACL,CAAC,CAAC;AAEH,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,KAAa;IAC1C,OAAO,KAAK;SACV,IAAI,EAAE;SACN,WAAW,EAAE;SACb,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAC5B,MAAgB,EAChB,SAA2B;IAE3B,OAAO,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
-- ============================================================
|
|
2
|
+
-- Kevin 0.4.0 — Migration 005: Signal over Noise (additive)
|
|
3
|
+
-- ============================================================
|
|
4
|
+
-- Backward-compatible, additive only. All new columns are
|
|
5
|
+
-- nullable or carry a NOT NULL DEFAULT so legacy rows keep
|
|
6
|
+
-- working without a destructive rebuild.
|
|
7
|
+
-- ============================================================
|
|
8
|
+
|
|
9
|
+
-- 1. memories: positive/negative evidence split (D4-03).
|
|
10
|
+
-- recurrence_count — how many times this fingerprint recurred AFTER
|
|
11
|
+
-- injection (negative evidence; lowers confidence).
|
|
12
|
+
-- fix_args — deterministic capture of the linked success call's
|
|
13
|
+
-- args_summary ("Fixed by:" raw material, D4-07).
|
|
14
|
+
-- last_injected_at — timestamp of the most recent injection of this memory.
|
|
15
|
+
ALTER TABLE memories ADD COLUMN recurrence_count INTEGER NOT NULL DEFAULT 0;
|
|
16
|
+
ALTER TABLE memories ADD COLUMN fix_args TEXT;
|
|
17
|
+
ALTER TABLE memories ADD COLUMN last_injected_at TEXT;
|
|
18
|
+
|
|
19
|
+
-- 2. kevin_injections: the injection ledger (D4-04). One row per injected
|
|
20
|
+
-- memory per prompt/compaction, settled at session.idle.
|
|
21
|
+
CREATE TABLE IF NOT EXISTS kevin_injections (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
memory_id TEXT NOT NULL,
|
|
24
|
+
fingerprint TEXT NOT NULL,
|
|
25
|
+
session_id TEXT NOT NULL,
|
|
26
|
+
hook TEXT NOT NULL CHECK (hook IN ('pre_prompt', 'compacting')),
|
|
27
|
+
tokens INTEGER NOT NULL,
|
|
28
|
+
injected_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
29
|
+
outcome TEXT CHECK (outcome IN ('unmeasured', 'effective', 'ineffective'))
|
|
30
|
+
NOT NULL DEFAULT 'unmeasured'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
-- 2b. Indexes: settlement by session, recurrence lookups by fingerprint,
|
|
34
|
+
-- and outcome rollups for precision_rate.
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_injections_fp
|
|
36
|
+
ON kevin_injections(fingerprint);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_injections_session
|
|
38
|
+
ON kevin_injections(session_id);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_injections_outcome
|
|
40
|
+
ON kevin_injections(outcome);
|
|
41
|
+
|
|
42
|
+
-- 3. kevin_metrics: seed new v0.4 counters.
|
|
43
|
+
-- patterns_promoted_new replaces patterns_causal (which was inflated by
|
|
44
|
+
-- idempotent refreshes); the latter stays for compat but is frozen.
|
|
45
|
+
INSERT OR IGNORE INTO kevin_metrics (key, value) VALUES
|
|
46
|
+
('injections_total', 0),
|
|
47
|
+
('injections_effective', 0),
|
|
48
|
+
('injections_ineffective', 0),
|
|
49
|
+
('patterns_promoted_new', 0);
|
|
50
|
+
|
|
51
|
+
-- 4. kevin_settings: seed new v0.4 flags.
|
|
52
|
+
INSERT OR IGNORE INTO kevin_settings (key, value) VALUES
|
|
53
|
+
('quality_gate_enabled', '1'),
|
|
54
|
+
('lesson_snippet_injection','1');
|
|
55
|
+
|
|
56
|
+
-- 5. Seed version 005.
|
|
57
|
+
INSERT OR IGNORE INTO schema_version (version) VALUES ('005');
|