@jmtrin/opencode-kevin 1.2.0 → 1.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.
Files changed (140) hide show
  1. package/README.md +84 -22
  2. package/dist/plugin/index.d.ts +5 -4
  3. package/dist/plugin/index.js +127 -113
  4. package/dist/plugin/native.d.ts +2 -2
  5. package/dist/plugin/native.js +2 -2
  6. package/package.json +56 -68
  7. package/dist/migrations/001_initial.sql +0 -92
  8. package/dist/migrations/002_indexes.sql +0 -14
  9. package/dist/migrations/003_v02_signal.sql +0 -58
  10. package/dist/migrations/004_v03_knowledge.sql +0 -138
  11. package/dist/migrations/005_v04_signal.sql +0 -57
  12. package/dist/migrations/006_v05_glassbox.sql +0 -118
  13. package/dist/migrations/007_v06_pull.sql +0 -145
  14. package/dist/migrations/008_v07_truth.sql +0 -124
  15. package/dist/migrations/009_v08_team.sql +0 -100
  16. package/dist/migrations/010_v09_native.sql +0 -78
  17. package/dist/migrations/011_v10_proven.sql +0 -69
  18. package/dist/migrations/012_v11_drift.sql +0 -24
  19. package/dist/plugin/Archiver.d.ts +0 -42
  20. package/dist/plugin/Archiver.js +0 -83
  21. package/dist/plugin/ArtifactWriter.d.ts +0 -93
  22. package/dist/plugin/ArtifactWriter.js +0 -291
  23. package/dist/plugin/CausalChain.d.ts +0 -22
  24. package/dist/plugin/CausalChain.js +0 -197
  25. package/dist/plugin/ChatBridge.d.ts +0 -41
  26. package/dist/plugin/ChatBridge.js +0 -103
  27. package/dist/plugin/ConflictDetector.d.ts +0 -35
  28. package/dist/plugin/ConflictDetector.js +0 -260
  29. package/dist/plugin/ContextInjector.d.ts +0 -222
  30. package/dist/plugin/ContextInjector.js +0 -533
  31. package/dist/plugin/ConventionMiner.d.ts +0 -35
  32. package/dist/plugin/ConventionMiner.js +0 -242
  33. package/dist/plugin/Curator.d.ts +0 -116
  34. package/dist/plugin/Curator.js +0 -324
  35. package/dist/plugin/DashboardHtml.d.ts +0 -5
  36. package/dist/plugin/DashboardHtml.js +0 -180
  37. package/dist/plugin/Feedback.d.ts +0 -67
  38. package/dist/plugin/Feedback.js +0 -120
  39. package/dist/plugin/HookLiveness.d.ts +0 -88
  40. package/dist/plugin/HookLiveness.js +0 -322
  41. package/dist/plugin/InjectionLedger.d.ts +0 -98
  42. package/dist/plugin/InjectionLedger.js +0 -295
  43. package/dist/plugin/LessonFixer.d.ts +0 -44
  44. package/dist/plugin/LessonFixer.js +0 -45
  45. package/dist/plugin/Materializer.d.ts +0 -83
  46. package/dist/plugin/Materializer.js +0 -181
  47. package/dist/plugin/MemoryService.d.ts +0 -360
  48. package/dist/plugin/MemoryService.js +0 -1242
  49. package/dist/plugin/Migrate.d.ts +0 -17
  50. package/dist/plugin/Migrate.js +0 -271
  51. package/dist/plugin/PatternMiner.d.ts +0 -49
  52. package/dist/plugin/PatternMiner.js +0 -132
  53. package/dist/plugin/QualityGate.d.ts +0 -124
  54. package/dist/plugin/QualityGate.js +0 -119
  55. package/dist/plugin/Reflector.d.ts +0 -91
  56. package/dist/plugin/Reflector.js +0 -307
  57. package/dist/plugin/RepoIdentity.d.ts +0 -124
  58. package/dist/plugin/RepoIdentity.js +0 -300
  59. package/dist/plugin/RepoTruth.d.ts +0 -80
  60. package/dist/plugin/RepoTruth.js +0 -599
  61. package/dist/plugin/Retrospective.d.ts +0 -17
  62. package/dist/plugin/Retrospective.js +0 -216
  63. package/dist/plugin/SharedLayer.d.ts +0 -159
  64. package/dist/plugin/SharedLayer.js +0 -462
  65. package/dist/plugin/Store.d.ts +0 -29
  66. package/dist/plugin/Store.js +0 -50
  67. package/dist/plugin/ToolCallObserver.d.ts +0 -32
  68. package/dist/plugin/ToolCallObserver.js +0 -201
  69. package/dist/plugin/TuiActions.d.ts +0 -43
  70. package/dist/plugin/TuiActions.js +0 -181
  71. package/dist/plugin/TuiSnapshots.d.ts +0 -24
  72. package/dist/plugin/TuiSnapshots.js +0 -158
  73. package/dist/plugin/columns.d.ts +0 -11
  74. package/dist/plugin/columns.js +0 -54
  75. package/dist/plugin/confidence.d.ts +0 -8
  76. package/dist/plugin/confidence.js +0 -34
  77. package/dist/plugin/contract.d.ts +0 -54
  78. package/dist/plugin/contract.js +0 -386
  79. package/dist/plugin/diff.d.ts +0 -8
  80. package/dist/plugin/diff.js +0 -182
  81. package/dist/plugin/escape.d.ts +0 -39
  82. package/dist/plugin/escape.js +0 -60
  83. package/dist/plugin/fingerprint.d.ts +0 -27
  84. package/dist/plugin/fingerprint.js +0 -73
  85. package/dist/plugin/inferability.d.ts +0 -32
  86. package/dist/plugin/inferability.js +0 -88
  87. package/dist/plugin/kevin_approve.d.ts +0 -34
  88. package/dist/plugin/kevin_approve.js +0 -52
  89. package/dist/plugin/kevin_audit.d.ts +0 -229
  90. package/dist/plugin/kevin_audit.js +0 -631
  91. package/dist/plugin/kevin_bench.d.ts +0 -10
  92. package/dist/plugin/kevin_bench.js +0 -82
  93. package/dist/plugin/kevin_conflicts.d.ts +0 -9
  94. package/dist/plugin/kevin_conflicts.js +0 -50
  95. package/dist/plugin/kevin_contract.d.ts +0 -8
  96. package/dist/plugin/kevin_contract.js +0 -59
  97. package/dist/plugin/kevin_doctor.d.ts +0 -62
  98. package/dist/plugin/kevin_doctor.js +0 -196
  99. package/dist/plugin/kevin_facts.d.ts +0 -42
  100. package/dist/plugin/kevin_facts.js +0 -36
  101. package/dist/plugin/kevin_forget.d.ts +0 -33
  102. package/dist/plugin/kevin_forget.js +0 -260
  103. package/dist/plugin/kevin_native.d.ts +0 -29
  104. package/dist/plugin/kevin_native.js +0 -79
  105. package/dist/plugin/kevin_propose.d.ts +0 -23
  106. package/dist/plugin/kevin_propose.js +0 -14
  107. package/dist/plugin/kevin_publish.d.ts +0 -38
  108. package/dist/plugin/kevin_publish.js +0 -18
  109. package/dist/plugin/kevin_why.d.ts +0 -23
  110. package/dist/plugin/kevin_why.js +0 -111
  111. package/dist/plugin/memory-format.d.ts +0 -20
  112. package/dist/plugin/memory-format.js +0 -59
  113. package/dist/plugin/metrics.d.ts +0 -97
  114. package/dist/plugin/metrics.js +0 -288
  115. package/dist/plugin/okf-export.d.ts +0 -3
  116. package/dist/plugin/okf-export.js +0 -134
  117. package/dist/plugin/okf-import.d.ts +0 -76
  118. package/dist/plugin/okf-import.js +0 -271
  119. package/dist/plugin/okf.d.ts +0 -107
  120. package/dist/plugin/okf.js +0 -303
  121. package/dist/plugin/perf.d.ts +0 -35
  122. package/dist/plugin/perf.js +0 -174
  123. package/dist/plugin/query-tokenizer.d.ts +0 -13
  124. package/dist/plugin/query-tokenizer.js +0 -133
  125. package/dist/plugin/redact.d.ts +0 -2
  126. package/dist/plugin/redact.js +0 -18
  127. package/dist/plugin/replay-types.d.ts +0 -69
  128. package/dist/plugin/replay-types.js +0 -156
  129. package/dist/plugin/replay.d.ts +0 -36
  130. package/dist/plugin/replay.js +0 -202
  131. package/dist/plugin/sqlite-adapter.d.ts +0 -12
  132. package/dist/plugin/sqlite-adapter.js +0 -81
  133. package/dist/plugin/time-ms.d.ts +0 -1
  134. package/dist/plugin/time-ms.js +0 -16
  135. package/dist/plugin/tui-types.d.ts +0 -59
  136. package/dist/plugin/tui-types.js +0 -4
  137. package/dist/plugin/tui.d.ts +0 -18
  138. package/dist/plugin/tui.js +0 -198
  139. package/dist/plugin/uuid.d.ts +0 -1
  140. package/dist/plugin/uuid.js +0 -50
package/package.json CHANGED
@@ -1,70 +1,58 @@
1
1
  {
2
- "name": "@jmtrin/opencode-kevin",
3
- "version": "1.2.0",
4
- "description": "Kevin — Observa y aprende: capa de aprendizaje para OpenCode",
5
- "type": "module",
6
- "main": "dist/plugin/index.js",
7
- "types": "./dist/plugin/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/plugin/index.d.ts",
11
- "import": "./dist/plugin/index.js"
12
- },
13
- "./tui": {
14
- "types": "./dist/plugin/tui.d.ts",
15
- "import": "./dist/plugin/tui.js"
16
- }
17
- },
18
- "files": ["dist/plugin", "dist/migrations"],
19
- "scripts": {
20
- "build": "tsc -p tsconfig.build.json && node scripts/copy-migrations.mjs",
21
- "prepublishOnly": "npm run build",
22
- "test": "vitest run",
23
- "test:unit": "vitest run tests/unit",
24
- "test:integration": "vitest run tests/integration",
25
- "test:e2e": "vitest run tests/e2e",
26
- "typecheck": "tsc --noEmit",
27
- "lint": "biome check .",
28
- "format": "biome format --write .",
29
- "verify": "node --import tsx scripts/verify-install.ts && npm run verify:pack",
30
- "verify:pack": "node --import tsx scripts/verify-pack.ts",
31
- "bench": "node --import tsx scripts/bench.ts",
32
- "gen:corpus": "node --import tsx scripts/gen-corpus.ts",
33
- "bench:check": "node --import tsx scripts/bench-check.ts",
34
- "bench:regress": "tsx scripts/bench-regress.ts",
35
- "replay": "node --import tsx scripts/replay.ts",
36
- "measure:mix": "node --import tsx scripts/measure-mix.ts"
37
- },
38
- "dependencies": {
39
- "@opencode-ai/plugin": "^1.18.16"
40
- },
41
- "optionalDependencies": {
42
- "better-sqlite3": "^12.11.0"
43
- },
44
- "devDependencies": {
45
- "@biomejs/biome": "^1.9.4",
46
- "@types/better-sqlite3": "^7.6.12",
47
- "@types/node": "^22.10.0",
48
- "tsx": "^4.19.0",
49
- "typescript": "^5.7.2",
50
- "vitest": "^2.1.8"
51
- },
52
- "engines": {
53
- "node": ">=22.5.0",
54
- "opencode": "^1.18.0"
55
- },
56
- "repository": {
57
- "type": "git",
58
- "url": "https://github.com/jmtrin/opencode-kevin.git"
59
- },
60
- "homepage": "https://github.com/jmtrin/opencode-kevin#readme",
61
- "bugs": {
62
- "url": "https://github.com/jmtrin/opencode-kevin/issues"
63
- },
64
- "keywords": ["opencode", "plugin", "memory", "learning", "ai"],
65
- "author": "jmtrin",
66
- "publishConfig": {
67
- "access": "public"
68
- },
69
- "license": "MIT"
2
+ "name": "@jmtrin/opencode-kevin",
3
+ "version": "1.4.0",
4
+ "description": "Kevin — Observa y aprende: capa de aprendizaje para OpenCode",
5
+ "type": "module",
6
+ "main": "dist/plugin/index.js",
7
+ "types": "dist/plugin/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/plugin/index.d.ts",
11
+ "import": "./dist/plugin/index.js"
12
+ },
13
+ "./tui": {
14
+ "types": "@jmtrin/opencode-kevin-tui/dist/index.d.ts",
15
+ "import": "@jmtrin/opencode-kevin-tui/dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist/plugin"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "prepublishOnly": "npm run build",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "dependencies": {
27
+ "@opencode-ai/plugin": "^1.18.16",
28
+ "@jmtrin/kevin-core": "1.4.0",
29
+ "@jmtrin/opencode-kevin-tui": "1.4.0"
30
+ },
31
+ "optionalDependencies": {
32
+ "better-sqlite3": "^12.11.0"
33
+ },
34
+ "engines": {
35
+ "node": ">=22.5.0",
36
+ "opencode": "^1.18.0"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/jmtrin/opencode-kevin.git"
41
+ },
42
+ "homepage": "https://github.com/jmtrin/opencode-kevin#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/jmtrin/opencode-kevin/issues"
45
+ },
46
+ "keywords": [
47
+ "opencode",
48
+ "plugin",
49
+ "memory",
50
+ "learning",
51
+ "ai"
52
+ ],
53
+ "author": "jmtrin",
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "license": "MIT"
70
58
  }
@@ -1,92 +0,0 @@
1
- -- ============================================================
2
- -- Kevin 0.1.0 — Schema inicial
3
- -- ============================================================
4
-
5
- -- Tabla de versiones para migraciones
6
- CREATE TABLE IF NOT EXISTS schema_version (
7
- version TEXT PRIMARY KEY,
8
- applied_at TEXT NOT NULL DEFAULT (datetime('now'))
9
- );
10
-
11
- -- ============================================================
12
- -- memories: lecciones aprendidas
13
- -- ============================================================
14
- CREATE TABLE IF NOT EXISTS memories (
15
- id TEXT PRIMARY KEY,
16
- type TEXT NOT NULL CHECK(type IN ('error', 'pattern', 'decision', 'context')),
17
- content TEXT NOT NULL,
18
- scope TEXT NOT NULL DEFAULT 'project' CHECK(scope IN ('project', 'session')),
19
- relevance_score REAL DEFAULT 0.5,
20
- source_tool TEXT,
21
- source_session TEXT,
22
- metadata TEXT,
23
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
24
- updated_at TEXT NOT NULL DEFAULT (datetime('now')),
25
- expires_at TEXT
26
- );
27
-
28
- CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
29
- CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope);
30
- CREATE INDEX IF NOT EXISTS idx_memories_relevance ON memories(relevance_score DESC);
31
- CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
32
-
33
- -- FTS5: búsqueda full-text con remoción de diacríticos (mejor para español)
34
- CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
35
- content,
36
- content='memories',
37
- tokenize='unicode61 remove_diacritics 1'
38
- );
39
-
40
- -- Triggers para mantener FTS5 sincronizado (FTS5 external-content se indexa por rowid)
41
- CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
42
- INSERT INTO memories_fts(rowid, content) VALUES (new.rowid, new.content);
43
- END;
44
-
45
- CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
46
- INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
47
- END;
48
-
49
- CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
50
- INSERT INTO memories_fts(memories_fts, rowid, content) VALUES ('delete', old.rowid, old.content);
51
- INSERT INTO memories_fts(rowid, content) VALUES (new.rowid, new.content);
52
- END;
53
-
54
- -- ============================================================
55
- -- tool_calls: observación de tool calls del agente
56
- -- ============================================================
57
- CREATE TABLE IF NOT EXISTS tool_calls (
58
- id TEXT PRIMARY KEY,
59
- session_id TEXT NOT NULL,
60
- ts TEXT NOT NULL DEFAULT (datetime('now')),
61
- tool TEXT NOT NULL,
62
- args_summary TEXT,
63
- success INTEGER NOT NULL CHECK(success IN (0,1)),
64
- duration_ms INTEGER,
65
- agent TEXT,
66
- error_type TEXT,
67
- metadata TEXT
68
- );
69
-
70
- CREATE INDEX IF NOT EXISTS idx_tool_calls_session ON tool_calls(session_id);
71
- CREATE INDEX IF NOT EXISTS idx_tool_calls_tool ON tool_calls(tool);
72
- CREATE INDEX IF NOT EXISTS idx_tool_calls_ts ON tool_calls(ts);
73
- CREATE INDEX IF NOT EXISTS idx_tool_calls_success ON tool_calls(success);
74
-
75
- -- ============================================================
76
- -- retrospectives: resúmenes de sesión
77
- -- ============================================================
78
- CREATE TABLE IF NOT EXISTS retrospectives (
79
- id TEXT PRIMARY KEY,
80
- session_id TEXT NOT NULL,
81
- ts TEXT NOT NULL DEFAULT (datetime('now')),
82
- failure_count INTEGER DEFAULT 0,
83
- success_count INTEGER DEFAULT 0,
84
- lessons_count INTEGER DEFAULT 0,
85
- file_path TEXT,
86
- metadata TEXT
87
- );
88
-
89
- -- ============================================================
90
- -- Seed: versión inicial
91
- -- ============================================================
92
- INSERT OR IGNORE INTO schema_version (version) VALUES ('001');
@@ -1,14 +0,0 @@
1
- -- ============================================================
2
- -- Kevin 0.1.1 — Migration 002: indexes adicionales
3
- -- ============================================================
4
-
5
- -- F#29: uniqueness on retrospectives.session_id
6
- -- Prevents duplicate retrospective rows under concurrent session.idle events.
7
- CREATE UNIQUE INDEX IF NOT EXISTS idx_retrospectives_session
8
- ON retrospectives(session_id);
9
-
10
- -- F#31: index on memories.expires_at
11
- -- Every query/queryRelevant/loadAll filters WHERE (expires_at IS NULL OR expires_at > datetime('now')).
12
- -- Without this index the filter is a linear scan on large tables.
13
- CREATE INDEX IF NOT EXISTS idx_memories_expires
14
- ON memories(expires_at);
@@ -1,58 +0,0 @@
1
- -- ============================================================
2
- -- Kevin 0.2.0 — Migration 003: Signal Quality (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. The partial UNIQUE
7
- -- index excludes NULL fingerprints so legacy error memories
8
- -- do not collide. The schema_version table (created by 001)
9
- -- guarantees this file runs at most once per DB.
10
- -- ============================================================
11
-
12
- -- 1. memories: Signal Quality columns.
13
- -- project_id — first-class scoping dimension (D2-11).
14
- -- fingerprint — stable hash of normalized error content, salted by project_id (D2-14).
15
- -- origin — distinguishes reflector-sourced vs agent-sourced memories (D2-06),
16
- -- with a CHECK enum and DEFAULT 'agent' so legacy rows backfill cleanly.
17
- ALTER TABLE memories ADD COLUMN project_id TEXT;
18
- ALTER TABLE memories ADD COLUMN fingerprint TEXT;
19
- ALTER TABLE memories ADD COLUMN origin TEXT NOT NULL DEFAULT 'agent'
20
- CHECK(origin IN ('reflector', 'agent', 'pattern', 'retrospective'));
21
-
22
- -- 2. tool_calls: same scoping/fingerprint columns for dedup and PatternMiner.
23
- ALTER TABLE tool_calls ADD COLUMN project_id TEXT;
24
- ALTER TABLE tool_calls ADD COLUMN fingerprint TEXT;
25
-
26
- -- 3. Partial UNIQUE: one reflector-sourced error memory per (project_id, fingerprint).
27
- -- NULL fingerprints are excluded (no dedup for non-error memories or legacy rows).
28
- CREATE UNIQUE INDEX IF NOT EXISTS uq_memories_error_fp
29
- ON memories (project_id, fingerprint)
30
- WHERE type = 'error' AND fingerprint IS NOT NULL AND origin = 'reflector';
31
-
32
- -- 4. kevin_metrics: seeded counters surfaced by kevin_status (D2-07 / K2-004).
33
- CREATE TABLE IF NOT EXISTS kevin_metrics (
34
- key TEXT PRIMARY KEY,
35
- value INTEGER NOT NULL DEFAULT 0,
36
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
37
- );
38
-
39
- INSERT OR IGNORE INTO kevin_metrics (key, value) VALUES
40
- ('tokens_injected_pre_prompt', 0),
41
- ('tokens_injected_compacting', 0),
42
- ('reflections_throttled', 0),
43
- ('duplicate_suppressions', 0),
44
- ('tool_calls_deduped', 0),
45
- ('patterns_mined', 0);
46
-
47
- -- 5. kevin_settings: opt-in feature flags (PatternMiner off, tool_calls dedup off).
48
- CREATE TABLE IF NOT EXISTS kevin_settings (
49
- key TEXT PRIMARY KEY,
50
- value TEXT NOT NULL
51
- );
52
-
53
- INSERT OR IGNORE INTO kevin_settings (key, value) VALUES
54
- ('patternminer_enabled', '0'),
55
- ('tool_calls_dedup_enabled', '0');
56
-
57
- -- 6. Seed version 003.
58
- INSERT OR IGNORE INTO schema_version (version) VALUES ('003');
@@ -1,138 +0,0 @@
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;
@@ -1,57 +0,0 @@
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');
@@ -1,118 +0,0 @@
1
- -- ============================================================================
2
- -- 006_v05_glassbox.sql — v0.5.0 "Glass Box"
3
- --
4
- -- Honest measurement, human feedback, lifecycle completion.
5
- --
6
- -- Section 1: rebuild kevin_injections to admit a fourth outcome.
7
- -- Section 2: human feedback storage.
8
- -- Section 3: memory lifecycle columns.
9
- -- Section 4: metric seeds.
10
- -- Section 5: setting seeds.
11
- -- Section 6: schema_version.
12
- -- ============================================================================
13
-
14
- -- ---------------------------------------------------------------------------
15
- -- 1. kevin_injections: add 'inconclusive'.
16
- --
17
- -- SQLite cannot ALTER a CHECK constraint, so the table must be rebuilt.
18
- -- Migration 004 set this precedent. kevin_injections has no FTS5 triggers,
19
- -- so unlike 004 this is a straight four-step rebuild.
20
- --
21
- -- Existing rows with outcome='effective' are remapped to 'inconclusive'.
22
- -- This is not data loss: v0.4's 'effective' meant "the error did not recur",
23
- -- which is the exact definition of the new 'inconclusive' bucket. Rows that
24
- -- genuinely earned the new 'effective' will be re-settled naturally, and the
25
- -- post-apply hook re-derives the counters from the table.
26
- -- ---------------------------------------------------------------------------
27
- CREATE TABLE IF NOT EXISTS kevin_injections_new (
28
- id TEXT PRIMARY KEY,
29
- memory_id TEXT NOT NULL,
30
- fingerprint TEXT NOT NULL,
31
- session_id TEXT NOT NULL,
32
- hook TEXT NOT NULL CHECK (hook IN ('pre_prompt','compacting')),
33
- tokens INTEGER NOT NULL,
34
- injected_at TEXT NOT NULL DEFAULT (datetime('now')),
35
- outcome TEXT NOT NULL DEFAULT 'unmeasured'
36
- CHECK (outcome IN ('unmeasured','effective','ineffective','inconclusive'))
37
- );
38
-
39
- INSERT INTO kevin_injections_new
40
- (id, memory_id, fingerprint, session_id, hook, tokens, injected_at, outcome)
41
- SELECT
42
- id, memory_id, fingerprint, session_id, hook, tokens, injected_at,
43
- CASE WHEN outcome = 'effective' THEN 'inconclusive' ELSE outcome END
44
- FROM kevin_injections;
45
-
46
- DROP TABLE kevin_injections;
47
- ALTER TABLE kevin_injections_new RENAME TO kevin_injections;
48
-
49
- CREATE INDEX IF NOT EXISTS idx_injections_fp ON kevin_injections(fingerprint);
50
- CREATE INDEX IF NOT EXISTS idx_injections_session ON kevin_injections(session_id);
51
- CREATE INDEX IF NOT EXISTS idx_injections_outcome ON kevin_injections(outcome);
52
-
53
- -- ---------------------------------------------------------------------------
54
- -- 2. Human feedback. Append-only audit trail; the hot path reads the
55
- -- denormalized counters on `memories` (section 3), never this table.
56
- -- ---------------------------------------------------------------------------
57
- CREATE TABLE IF NOT EXISTS memory_feedback (
58
- id TEXT PRIMARY KEY,
59
- memory_id TEXT NOT NULL,
60
- verdict TEXT NOT NULL CHECK (verdict IN ('useful','wrong','outdated','ignore')),
61
- session_id TEXT,
62
- note TEXT,
63
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
64
- );
65
-
66
- CREATE INDEX IF NOT EXISTS idx_feedback_memory ON memory_feedback(memory_id);
67
- CREATE INDEX IF NOT EXISTS idx_feedback_created ON memory_feedback(created_at);
68
-
69
- -- ---------------------------------------------------------------------------
70
- -- 3. Memory lifecycle and feedback columns.
71
- --
72
- -- feedback_positive / feedback_negative are SEPARATE from evidence_count
73
- -- and recurrence_count by design: human judgement is evidence about the
74
- -- memory, causal counters are evidence about the world. Mixing them was
75
- -- the confidence-poisoning defect closed in v0.4.0.
76
- --
77
- -- superseded_by has no REFERENCES clause on purpose. Store enables
78
- -- PRAGMA foreign_keys=ON, and a hard FK would block deletion of a memory
79
- -- that superseded another.
80
- -- ---------------------------------------------------------------------------
81
- ALTER TABLE memories ADD COLUMN feedback_positive INTEGER NOT NULL DEFAULT 0;
82
- ALTER TABLE memories ADD COLUMN feedback_negative INTEGER NOT NULL DEFAULT 0;
83
- ALTER TABLE memories ADD COLUMN ignored INTEGER NOT NULL DEFAULT 0;
84
- ALTER TABLE memories ADD COLUMN superseded_by TEXT;
85
- ALTER TABLE memories ADD COLUMN archived_at TEXT;
86
-
87
- CREATE INDEX IF NOT EXISTS idx_memories_ignored ON memories(ignored);
88
- CREATE INDEX IF NOT EXISTS idx_memories_archived ON memories(archived_at);
89
-
90
- -- ---------------------------------------------------------------------------
91
- -- 4. Metric seeds. Order matches the additions to METRIC_KEYS in metrics.ts.
92
- -- ---------------------------------------------------------------------------
93
- INSERT OR IGNORE INTO kevin_metrics (key, value) VALUES
94
- ('injections_inconclusive', 0),
95
- ('injections_blocked_seen', 0),
96
- ('injections_blocked_weak', 0),
97
- ('injections_blocked_recurrence',0),
98
- ('injections_blocked_stale', 0),
99
- ('injections_blocked_ignored', 0),
100
- ('feedback_positive_total', 0),
101
- ('feedback_negative_total', 0),
102
- ('memories_archived', 0);
103
-
104
- -- ---------------------------------------------------------------------------
105
- -- 5. Setting seeds. Values are TEXT, always. Read them with an explicit
106
- -- string comparison or an explicit Number() parse — never `=== 1`.
107
- -- (That exact mistake kept cross_project_enabled unreachable for the
108
- -- whole of v0.3.0.)
109
- -- ---------------------------------------------------------------------------
110
- INSERT OR IGNORE INTO kevin_settings (key, value) VALUES
111
- ('deterministic_retrieval', '0'),
112
- ('pre_prompt_budget_tokens', '900'),
113
- ('archive_after_days', '30');
114
-
115
- -- ---------------------------------------------------------------------------
116
- -- 6. Version marker.
117
- -- ---------------------------------------------------------------------------
118
- INSERT OR IGNORE INTO schema_version (version) VALUES ('006');