@jmtrin/opencode-kevin 0.3.0 → 0.5.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.
Files changed (72) hide show
  1. package/README.md +117 -9
  2. package/dist/migrations/005_v04_signal.sql +57 -0
  3. package/dist/migrations/006_v05_glassbox.sql +118 -0
  4. package/dist/plugin/Archiver.d.ts +42 -0
  5. package/dist/plugin/Archiver.js +98 -0
  6. package/dist/plugin/Archiver.js.map +1 -0
  7. package/dist/plugin/CausalChain.d.ts +13 -2
  8. package/dist/plugin/CausalChain.js +83 -13
  9. package/dist/plugin/CausalChain.js.map +1 -1
  10. package/dist/plugin/ContextInjector.d.ts +152 -4
  11. package/dist/plugin/ContextInjector.js +400 -93
  12. package/dist/plugin/ContextInjector.js.map +1 -1
  13. package/dist/plugin/Feedback.d.ts +67 -0
  14. package/dist/plugin/Feedback.js +137 -0
  15. package/dist/plugin/Feedback.js.map +1 -0
  16. package/dist/plugin/InjectionLedger.d.ts +92 -0
  17. package/dist/plugin/InjectionLedger.js +243 -0
  18. package/dist/plugin/InjectionLedger.js.map +1 -0
  19. package/dist/plugin/LessonFixer.d.ts +44 -0
  20. package/dist/plugin/LessonFixer.js +46 -0
  21. package/dist/plugin/LessonFixer.js.map +1 -0
  22. package/dist/plugin/MemoryService.d.ts +81 -1
  23. package/dist/plugin/MemoryService.js +321 -54
  24. package/dist/plugin/MemoryService.js.map +1 -1
  25. package/dist/plugin/Migrate.js +31 -0
  26. package/dist/plugin/Migrate.js.map +1 -1
  27. package/dist/plugin/QualityGate.d.ts +110 -0
  28. package/dist/plugin/QualityGate.js +108 -0
  29. package/dist/plugin/QualityGate.js.map +1 -0
  30. package/dist/plugin/Reflector.d.ts +17 -0
  31. package/dist/plugin/Reflector.js +81 -26
  32. package/dist/plugin/Reflector.js.map +1 -1
  33. package/dist/plugin/Retrospective.js +22 -1
  34. package/dist/plugin/Retrospective.js.map +1 -1
  35. package/dist/plugin/ToolCallObserver.d.ts +1 -0
  36. package/dist/plugin/ToolCallObserver.js +15 -8
  37. package/dist/plugin/ToolCallObserver.js.map +1 -1
  38. package/dist/plugin/confidence.d.ts +8 -0
  39. package/dist/plugin/confidence.js +35 -0
  40. package/dist/plugin/confidence.js.map +1 -0
  41. package/dist/plugin/index.d.ts +5 -0
  42. package/dist/plugin/index.js +368 -44
  43. package/dist/plugin/index.js.map +1 -1
  44. package/dist/plugin/kevin_audit.d.ts +49 -0
  45. package/dist/plugin/kevin_audit.js +141 -0
  46. package/dist/plugin/kevin_audit.js.map +1 -0
  47. package/dist/plugin/kevin_why.d.ts +4 -0
  48. package/dist/plugin/kevin_why.js +72 -35
  49. package/dist/plugin/kevin_why.js.map +1 -1
  50. package/dist/plugin/memory-format.d.ts +12 -0
  51. package/dist/plugin/memory-format.js +45 -5
  52. package/dist/plugin/memory-format.js.map +1 -1
  53. package/dist/plugin/metrics.d.ts +27 -1
  54. package/dist/plugin/metrics.js +61 -0
  55. package/dist/plugin/metrics.js.map +1 -1
  56. package/dist/plugin/okf-export.js +63 -22
  57. package/dist/plugin/okf-export.js.map +1 -1
  58. package/dist/plugin/okf-import.d.ts +4 -1
  59. package/dist/plugin/okf-import.js +45 -12
  60. package/dist/plugin/okf-import.js.map +1 -1
  61. package/dist/plugin/query-tokenizer.d.ts +13 -0
  62. package/dist/plugin/query-tokenizer.js +86 -0
  63. package/dist/plugin/query-tokenizer.js.map +1 -0
  64. package/dist/plugin/replay-types.d.ts +327 -0
  65. package/dist/plugin/replay-types.js +65 -0
  66. package/dist/plugin/replay-types.js.map +1 -0
  67. package/dist/plugin/replay.d.ts +36 -0
  68. package/dist/plugin/replay.js +193 -0
  69. package/dist/plugin/replay.js.map +1 -0
  70. package/migrations/005_v04_signal.sql +57 -0
  71. package/migrations/006_v05_glassbox.sql +118 -0
  72. package/package.json +3 -2
@@ -15,6 +15,20 @@ 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",
22
+ // v0.5.0 (K5-004 / plan §8.3) — order matches migration 006's seed block.
23
+ "injections_inconclusive",
24
+ "injections_blocked_seen",
25
+ "injections_blocked_weak",
26
+ "injections_blocked_recurrence",
27
+ "injections_blocked_stale",
28
+ "injections_blocked_ignored",
29
+ "feedback_positive_total",
30
+ "feedback_negative_total",
31
+ "memories_archived",
18
32
  ];
19
33
  const DEFAULT_FLUSH_MS = 1000;
20
34
  function zeroCache() {
@@ -98,6 +112,53 @@ export class Metrics {
98
112
  get(key) {
99
113
  return this.cache.get(key) ?? 0;
100
114
  }
115
+ /**
116
+ * v0.4.0 (K4-008): injection precision = effective / total settled
117
+ * injections. 0 when the ledger has no entries yet (no division by zero).
118
+ * Computed from the cached counters — does NOT flush.
119
+ * v0.5.0 (K5-004 / plan §5.1, D5-02) — the denominator is now
120
+ * `effective + ineffective` only. `inconclusive` (the new majority
121
+ * bucket) must not inflate precision: absence of recurrence is not
122
+ * evidence of effect. An idle session therefore no longer drives
123
+ * precision toward 1.0 — expect the reported rate to fall sharply on
124
+ * real databases; that is the intended result.
125
+ */
126
+ precisionRate() {
127
+ const effective = this.cache.get("injections_effective") ?? 0;
128
+ const measured = effective + (this.cache.get("injections_ineffective") ?? 0);
129
+ if (measured <= 0)
130
+ return 0;
131
+ return Math.min(1, effective / measured);
132
+ }
133
+ /**
134
+ * v0.5.0 (K5-004 / plan §5.1, D5-02) — the share of injections that
135
+ * were actually measured (effective + ineffective) of all injections.
136
+ * Reported alongside `precisionRate` so a low measurable fraction is
137
+ * visible rather than hidden behind a large `total`. 0 when the ledger
138
+ * is empty. Computed from the cached counters — does NOT flush.
139
+ */
140
+ coverageRate() {
141
+ const total = this.cache.get("injections_total") ?? 0;
142
+ if (total <= 0)
143
+ return 0;
144
+ const measured = (this.cache.get("injections_effective") ?? 0) +
145
+ (this.cache.get("injections_ineffective") ?? 0);
146
+ return Math.min(1, measured / total);
147
+ }
148
+ /**
149
+ * v0.5.0 (K5-004 / plan §5.2, D5-02) — the five `injections_blocked_*`
150
+ * counters keyed by their short names. Consumed by `kevin_audit`.
151
+ * Computed from the cached counters — does NOT flush.
152
+ */
153
+ blockedSnapshot() {
154
+ return {
155
+ seen: this.cache.get("injections_blocked_seen") ?? 0,
156
+ weak: this.cache.get("injections_blocked_weak") ?? 0,
157
+ recurrence: this.cache.get("injections_blocked_recurrence") ?? 0,
158
+ stale: this.cache.get("injections_blocked_stale") ?? 0,
159
+ ignored: this.cache.get("injections_blocked_ignored") ?? 0,
160
+ };
161
+ }
101
162
  /** True iff a debounced flush is scheduled. Useful for tests. */
102
163
  isFlushScheduled() {
103
164
  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;CACZ,CAAC;AAIX,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,SAAS,SAAS;IACjB,MAAM,CAAC,GAAG,IAAI,GAAG,EAAqB,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,WAAW;QAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,CAAC;AACV,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,OAAO;IAQD;IAPD,KAAK,CAAyB;IAC9B,KAAK,GAAmB,IAAI,GAAG,EAAE,CAAC;IAC3C,UAAU,GAAyC,IAAI,CAAC;IAC/C,OAAO,CAAS;IACzB,MAAM,GAAG,KAAK,CAAC;IAEvB,YACkB,KAAY,EAC7B,UAAkB,gBAAgB;QADjB,UAAK,GAAL,KAAK,CAAO;QAG7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC;IAEO,UAAU;QACjB,uEAAuE;QACvE,qEAAqE;QACrE,+DAA+D;QAC/D,IAAI,IAAI,GAAqC,EAAE,CAAC;QAChD,IAAI,CAAC;YACJ,IAAI,GAAG,IAAI,CAAC,KAAK;iBACf,OAAO,CAAC,sCAAsC,CAAC;iBAC/C,GAAG,EAAsC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,IAAI,GAAG,EAAE,CAAC;QACX,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAgB,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAgB,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,CAAC,GAAc,EAAE,EAAE,GAAG,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,aAAa,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,QAAQ;QACP,MAAM,GAAG,GAAG,EAA+B,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,WAAW;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAc;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,iEAAiE;IACjE,gBAAgB;QACf,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,KAAK;QACJ,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACtB,KAAK,CAAC,IAAI,CACT;;;;eAIW,CACX,CAAC;YACF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC3B;;;;2CAIuC,CACvC,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACvC,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK;QACJ,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC;IAEO,aAAa;QACpB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO;QACrC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACd,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACjB,kEAAkE;QAClE,MAAM,CAAC,GAAG,IAAI,CAAC,UAEd,CAAC;QACF,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IACb,CAAC;IAEO,UAAU;QACjB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC9B,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,CAAC;IACF,CAAC;CACD"}
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
- return new Date(ts).toISOString().replace("T", " ").slice(0, 19);
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
- .prepare(`SELECT id, type, content, scope, relevance_score, fingerprint,
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: ${Math.min(1, 0.5 + 0.1 * m.evidence_count).toFixed(2)}`);
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
- .prepare(`SELECT id, type, content, scope, relevance_score, fingerprint,
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:** ${conf.toFixed(2)}`);
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":"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"}
1
+ {"version":3,"file":"okf-export.js","sourceRoot":"","sources":["../../plugin/okf-export.ts"],"names":[],"mappings":"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"}
@@ -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
- else if (bulletFp)
155
+ sawBullet = true;
156
+ }
157
+ else if (bulletFp) {
148
158
  fm.fingerprint = bulletFp[1];
149
- else if (bulletEv)
159
+ sawBullet = true;
160
+ }
161
+ else if (bulletEv) {
150
162
  fm.evidence_count = bulletEv[1];
151
- else if (bulletLv)
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 (bodyStart < 0)
175
+ if (sawBullet) {
156
176
  bodyStart = k + 1;
157
- break;
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
- content: contentWithEvidence,
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":"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"}
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"}