@jmtrin/opencode-kevin 0.2.0 → 0.3.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.
@@ -0,0 +1,138 @@
1
+ -- ============================================================
2
+ -- Kevin 0.3.0 — Migration 004: Knowledge + Causality (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: evidence + lifecycle columns.
10
+ -- evidence_count — how many times this fingerprint was confirmed as fixed.
11
+ -- last_verified_at — timestamp of the most recent causal confirmation.
12
+ -- status — lifecycle state; default 'active'. Superseded rows are hidden.
13
+ ALTER TABLE memories ADD COLUMN evidence_count INTEGER NOT NULL DEFAULT 0;
14
+ ALTER TABLE memories ADD COLUMN last_verified_at TEXT;
15
+ ALTER TABLE memories ADD COLUMN status TEXT NOT NULL DEFAULT 'active'
16
+ CHECK (status IN ('active', 'superseded', 'stale', 'archived'));
17
+
18
+ -- 2. tool_calls: causal link + feedback-loop link columns.
19
+ -- fix_for_fingerprint — set when this successful call resolved a prior failure
20
+ -- with the given fingerprint. NULL for tool calls that were not fixes.
21
+ -- error_fingerprint — set by Reflector (via onLinkError callback) when a call
22
+ -- FAILS, to the stderr-based fingerprint the matching error memory uses.
23
+ -- This fixes the v0.2.0/v0.3.0 feedback-loop fingerprint mismatch bug:
24
+ -- tool_calls.fingerprint is hashed from "tool|args|success" by ToolCallObserver,
25
+ -- while memories.fingerprint is hashed from stderr text by Reflector — they
26
+ -- never agreed, so boost/penalize queries silently mismatched. The new column
27
+ -- stores the SAME identity dimension the error memory uses.
28
+ ALTER TABLE tool_calls ADD COLUMN fix_for_fingerprint TEXT;
29
+ ALTER TABLE tool_calls ADD COLUMN error_fingerprint TEXT;
30
+
31
+ -- 3. Index: causal linkage by fingerprint. Used by CausalChain.onSuccess
32
+ -- and kevin_why to materialize traces.
33
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_fix_fp
34
+ ON tool_calls(fix_for_fingerprint)
35
+ WHERE fix_for_fingerprint IS NOT NULL;
36
+
37
+ -- 3b. Index: feedback-loop linkage by error_fingerprint. Used by
38
+ -- boostPositiveReflectors / penalizeRecurringReflectors to count
39
+ -- recurrences by the same identity dimension the error memory uses.
40
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_error_fp
41
+ ON tool_calls(error_fingerprint)
42
+ WHERE error_fingerprint IS NOT NULL;
43
+
44
+ -- 4. Index: memories by fingerprint for promotion + supersede queries.
45
+ CREATE INDEX IF NOT EXISTS idx_memories_fp
46
+ ON memories(fingerprint)
47
+ WHERE fingerprint IS NOT NULL;
48
+
49
+ -- 5. kevin_metrics: seed new v0.3 counters.
50
+ INSERT OR IGNORE INTO kevin_metrics (key, value) VALUES
51
+ ('patterns_causal', 0),
52
+ ('causal_links', 0),
53
+ ('memories_superseded', 0);
54
+
55
+ -- 6. kevin_settings: seed new opt-in flags.
56
+ INSERT OR IGNORE INTO kevin_settings (key, value) VALUES
57
+ ('llm_reflection_enabled', '0'),
58
+ ('cross_project_enabled', '0');
59
+
60
+ -- 7. Seed version 004.
61
+ INSERT OR IGNORE INTO schema_version (version) VALUES ('004');
62
+
63
+ -- ============================================================
64
+ -- 8. Rebuild memories table with expanded CHECK constraints.
65
+ -- v0.3.0 introduces new types (rule, solution) and origins
66
+ -- (causal, imported). SQLite cannot ALTER a CHECK constraint,
67
+ -- so we rebuild via a temporary table. FTS5 external-content
68
+ -- table references the content table by name, so we drop+recreate
69
+ -- the FTS5 triggers after the rebuild.
70
+ -- ============================================================
71
+
72
+ -- Step 1: Create new table with correct constraints
73
+ CREATE TABLE memories_v04 (
74
+ id TEXT PRIMARY KEY,
75
+ type TEXT NOT NULL CHECK(type IN ('error','pattern','decision','context','rule','solution')),
76
+ content TEXT NOT NULL,
77
+ scope TEXT NOT NULL DEFAULT 'project' CHECK(scope IN ('project','session')),
78
+ relevance_score REAL DEFAULT 0.5,
79
+ source_tool TEXT,
80
+ source_session TEXT,
81
+ metadata TEXT,
82
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
83
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
84
+ expires_at TEXT,
85
+ project_id TEXT,
86
+ fingerprint TEXT,
87
+ origin TEXT NOT NULL DEFAULT 'agent'
88
+ CHECK(origin IN ('reflector','agent','pattern','retrospective','causal','imported')),
89
+ evidence_count INTEGER NOT NULL DEFAULT 0,
90
+ last_verified_at TEXT,
91
+ status TEXT NOT NULL DEFAULT 'active'
92
+ CHECK(status IN ('active','superseded','stale','archived'))
93
+ );
94
+
95
+ -- Step 2: Copy data preserving rowids (FTS5 content sync relies on rowid)
96
+ INSERT INTO memories_v04
97
+ (rowid, id, type, content, scope, relevance_score, source_tool,
98
+ source_session, metadata, created_at, updated_at, expires_at,
99
+ project_id, fingerprint, origin, evidence_count, last_verified_at, status)
100
+ SELECT rowid, id, type, content, scope, relevance_score, source_tool,
101
+ source_session, metadata, created_at, updated_at, expires_at,
102
+ project_id, fingerprint, origin, evidence_count, last_verified_at, status
103
+ FROM memories;
104
+
105
+ -- Step 3: Drop old table and FTS triggers
106
+ DROP TRIGGER IF EXISTS memories_ai;
107
+ DROP TRIGGER IF EXISTS memories_ad;
108
+ DROP TRIGGER IF EXISTS memories_au;
109
+ DROP TABLE memories;
110
+
111
+ -- Step 4: Rename new table
112
+ ALTER TABLE memories_v04 RENAME TO memories;
113
+
114
+ -- Step 5: Recreate FTS triggers (memories_fts is content=external, survives DROP of content table)
115
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
116
+ INSERT INTO memories_fts(rowid, content) VALUES (new.rowid, new.content);
117
+ END;
118
+
119
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
120
+ INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
121
+ END;
122
+
123
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
124
+ INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
125
+ INSERT INTO memories_fts(rowid, content) VALUES (new.rowid, new.content);
126
+ END;
127
+
128
+ -- Step 6: Recreate indexes
129
+ CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
130
+ CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope);
131
+ CREATE INDEX IF NOT EXISTS idx_memories_relevance ON memories(relevance_score DESC);
132
+ CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
133
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_memories_error_fp
134
+ ON memories(project_id, fingerprint)
135
+ WHERE type = 'error' AND fingerprint IS NOT NULL AND origin = 'reflector';
136
+ CREATE INDEX IF NOT EXISTS idx_memories_fp
137
+ ON memories(fingerprint)
138
+ WHERE fingerprint IS NOT NULL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmtrin/opencode-kevin",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Kevin — Observa y aprende: capa de aprendizaje para OpenCode",
5
5
  "type": "module",
6
6
  "main": "dist/plugin/index.js",