@jmtrin/kevin-core 1.5.0 → 2.1.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/dist/RepoTruth.js CHANGED
@@ -393,7 +393,12 @@ export class RepoTruth {
393
393
  for (const file of ["package.json", "tsconfig.json"]) {
394
394
  try {
395
395
  const st = statSync(join(this.projectRoot, file));
396
- out[file] = String(st.mtimeMs);
396
+ // Include size alongside mtime so a same-tick rewrite with
397
+ // different bytes is still detected on Windows where mtime
398
+ // granularity is ~15ms. The stored string is compared as an
399
+ // opaque token, so legacy rows (bare mtime) will mismatch once
400
+ // and trigger a re-parse.
401
+ out[file] = `${String(st.mtimeMs)}:${String(st.size)}`;
397
402
  }
398
403
  catch {
399
404
  out[file] = null;
@@ -1,6 +1,6 @@
1
- import { type KevinEnv } from "./env.js";
2
1
  import type { MemoryService } from "./MemoryService.js";
3
2
  import type { Store } from "./Store.js";
3
+ import { type KevinEnv } from "./env.js";
4
4
  import type { Metrics } from "./metrics.js";
5
5
  export interface RetrospectiveOptions {
6
6
  dir?: string;
@@ -91,6 +91,12 @@ export const METRIC_KEY_LABELS = {
91
91
  skills_emitted_total: "Skills emitidos (total)",
92
92
  mif_exports_total: "Exportaciones MIF totales",
93
93
  mif_imports_total: "Importaciones MIF totales",
94
+ // v2.0.0 (K16-012 / plan §4.4) — Commonwealth metrics
95
+ source_syncs_total: "Sincronizaciones de fuentes (total)",
96
+ source_dedup_skips_total: "Skips por dedup de fuentes (total)",
97
+ okf_v3_files_written: "Archivos OKF v3 escritos",
98
+ // v2.1.0 (K21-005) — Relay deletion metric
99
+ source_deletions_total: "Borrados de fuente sincronizados (total)",
94
100
  };
95
101
  function originLabel(origin) {
96
102
  if (origin === "reflector")
@@ -8,7 +8,54 @@ import { type KevinEnv } from "./env.js";
8
8
  * core file allowed to call process cwd.
9
9
  */
10
10
  export declare function resolveScanRoots(env?: KevinEnv): string[];
11
- export declare const CONTRACT_VERSION = 1;
11
+ export declare const CONTRACT_VERSION = 2;
12
+ export declare const CONTRACT_CORE_EXPORTS: readonly {
13
+ name: string;
14
+ kind: string;
15
+ }[];
16
+ export declare const CONTRACT_MCP_TOOLS: readonly string[];
17
+ export declare const CONTRACT_MCP_REFUSALS: readonly string[];
18
+ export declare const CONTRACT_SKILLS_LAYOUT: {
19
+ readonly canonical_dir: ".agents/skills";
20
+ readonly skill_dir: "kevin-knowledge";
21
+ readonly files: readonly ["SKILL.md", "references/*.md"];
22
+ readonly frontmatter_fields: readonly ["name", "description", "metadata.generator", "metadata.repo_id"];
23
+ readonly mirror_policy: "copy (not symlink) to .claude/skills and .cursor/skills when enabled";
24
+ };
25
+ export declare const CONTRACT_MIF_PROFILE: {
26
+ readonly envelope_version: 1;
27
+ readonly format: "mif";
28
+ readonly field_mapping: {
29
+ readonly entry_id: "id";
30
+ readonly statement: "content";
31
+ readonly type: "type";
32
+ readonly scope: "metadata.scope";
33
+ readonly fingerprint: "metadata.fingerprint";
34
+ readonly confidence: "metadata.confidence";
35
+ readonly created_at: "timestamp";
36
+ };
37
+ readonly redaction: "SECRET_PATTERNS (PII)";
38
+ readonly dedup: "content-hash (fingerprint)";
39
+ readonly vendor_extensions_preserved: true;
40
+ };
41
+ export declare const CONTRACT_MEMORY_SOURCES: {
42
+ readonly sources: readonly [{
43
+ readonly name: "opencode-plugin";
44
+ readonly precedence: 10;
45
+ }, {
46
+ readonly name: "claude-memory";
47
+ readonly precedence: 20;
48
+ }, {
49
+ readonly name: "codex-memories";
50
+ readonly precedence: 30;
51
+ }, {
52
+ readonly name: "opencode-native";
53
+ readonly precedence: 40;
54
+ }];
55
+ readonly dedup_rule: "lower precedence wins attribution; losers counted in source_dedup_skips_total";
56
+ readonly conflict_kind: "source_pair";
57
+ readonly precedence_order: readonly [10, 20, 30, 40];
58
+ };
12
59
  export type Stability = "frozen" | "forward-only";
13
60
  export interface ContractClause {
14
61
  readonly id: string;
@@ -58,6 +105,16 @@ export declare const CONTRACT_CONFIG_ADDITIONS: readonly {
58
105
  name: string;
59
106
  since: string;
60
107
  }[];
108
+ /**
109
+ * v2.0.0 (K16-004 / plan §5.1) — removed settings (retirements)
110
+ * Each entry carries `since` 2.0.0 and optional replacement pointer.
111
+ * Succession test treats these as LEGITIMATE removals via `removed` annotation.
112
+ */
113
+ export declare const CONTRACT_REMOVED_CONFIG_KEYS: readonly {
114
+ name: string;
115
+ since: string;
116
+ replacement?: string;
117
+ }[];
61
118
  /**
62
119
  * v1.0.0 (K10-027 / plan §5.7) — the C-09 boundary addition. Stored is
63
120
  * not trusted: anything reaching an artifact or a prompt is escaped at
package/dist/contract.js CHANGED
@@ -3,8 +3,8 @@ import { existsSync } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
4
  import { dirname, join } from "node:path";
5
5
  import { MARKER_BEGIN, MARKER_END } from "./ArtifactWriter.js";
6
- import { resolveEnv } from "./env.js";
7
6
  import { METRIC_KEY_LABELS } from "./Retrospective.js";
7
+ import { resolveEnv } from "./env.js";
8
8
  import { fnv1a64 } from "./fingerprint.js";
9
9
  import { KEVIN_CONFIG_KEYS } from "./index.js";
10
10
  import { MAX_ENTRIES, MAX_LINE_BYTES } from "./okf.js";
@@ -45,7 +45,120 @@ export function resolveScanRoots(env) {
45
45
  // Fallback to monorepo relative (even if not yet built)
46
46
  return [monorepoPlugin, monorepoCore];
47
47
  }
48
- export const CONTRACT_VERSION = 1;
48
+ export const CONTRACT_VERSION = 2;
49
+ // v2.0.0 (K16-001 / plan §4.1) — C-10 core exports (names + kinds, since 1.3.0)
50
+ // Explicit export list at packages/core/src/index.ts — keep minimal.
51
+ export const CONTRACT_CORE_EXPORTS = [
52
+ { name: "Archiver", kind: "class" },
53
+ { name: "ArtifactWriter", kind: "class" },
54
+ { name: "CausalChain", kind: "class" },
55
+ { name: "ChatBridge", kind: "module" },
56
+ { name: "ConflictDetector", kind: "class" },
57
+ { name: "ContextInjector", kind: "class" },
58
+ { name: "ConventionMiner", kind: "class" },
59
+ { name: "Curator", kind: "class" },
60
+ { name: "DashboardHtml", kind: "module" },
61
+ { name: "Feedback", kind: "class" },
62
+ { name: "HookLiveness", kind: "class" },
63
+ { name: "InjectionLedger", kind: "class" },
64
+ { name: "LessonFixer", kind: "module" },
65
+ { name: "Materializer", kind: "class" },
66
+ { name: "MemoryService", kind: "class" },
67
+ { name: "Migrate", kind: "class" },
68
+ { name: "PatternMiner", kind: "class" },
69
+ { name: "QualityGate", kind: "class" },
70
+ { name: "Reflector", kind: "class" },
71
+ { name: "RepoIdentity", kind: "module" },
72
+ { name: "RepoTruth", kind: "class" },
73
+ { name: "Retrospective", kind: "class" },
74
+ { name: "SharedLayer", kind: "class" },
75
+ { name: "Store", kind: "class" },
76
+ { name: "ToolCallObserver", kind: "class" },
77
+ { name: "TuiSnapshots", kind: "module" },
78
+ { name: "buildAudit", kind: "function" },
79
+ { name: "buildDoctor", kind: "function" },
80
+ { name: "buildKevinContract", kind: "function" },
81
+ { name: "computeConfidence", kind: "function" },
82
+ { name: "describeContract", kind: "function" },
83
+ { name: "escapeForFence", kind: "function" },
84
+ { name: "escapeForMarkerBlock", kind: "function" },
85
+ { name: "fingerprint", kind: "function" },
86
+ { name: "fnv1a64", kind: "function" },
87
+ { name: "kevin_approve", kind: "function" },
88
+ { name: "kevin_bench", kind: "function" },
89
+ { name: "kevin_forget", kind: "function" },
90
+ { name: "kevin_why", kind: "function" },
91
+ { name: "resolveEnv", kind: "function" },
92
+ { name: "uuidv7", kind: "function" },
93
+ ];
94
+ // v2.0.0 (K16-001) — C-11 MCP tool names/shapes + refusal vocabulary, since 1.4.0
95
+ export const CONTRACT_MCP_TOOLS = [
96
+ "approve",
97
+ "feedback",
98
+ "get",
99
+ "ping",
100
+ "query",
101
+ "recall",
102
+ "save",
103
+ "share",
104
+ "status",
105
+ "trace",
106
+ "why",
107
+ ];
108
+ export const CONTRACT_MCP_REFUSALS = [
109
+ "disabled",
110
+ "repo_mismatch",
111
+ "not_okf",
112
+ "version_ahead",
113
+ "unknown_entry",
114
+ "parse_damaged",
115
+ "line_too_long",
116
+ "below_floor",
117
+ "not_curated",
118
+ "too_many_entries",
119
+ ];
120
+ // v2.0.0 (K16-001) — C-12 emitted skills layout, since 1.5.0
121
+ export const CONTRACT_SKILLS_LAYOUT = {
122
+ canonical_dir: ".agents/skills",
123
+ skill_dir: "kevin-knowledge",
124
+ files: ["SKILL.md", "references/*.md"],
125
+ frontmatter_fields: [
126
+ "name",
127
+ "description",
128
+ "metadata.generator",
129
+ "metadata.repo_id",
130
+ ],
131
+ mirror_policy: "copy (not symlink) to .claude/skills and .cursor/skills when enabled",
132
+ };
133
+ // v2.0.0 (K16-001) — C-13 MIF profile, since 1.5.0
134
+ export const CONTRACT_MIF_PROFILE = {
135
+ envelope_version: 1,
136
+ format: "mif",
137
+ field_mapping: {
138
+ entry_id: "id",
139
+ statement: "content",
140
+ type: "type",
141
+ scope: "metadata.scope",
142
+ fingerprint: "metadata.fingerprint",
143
+ confidence: "metadata.confidence",
144
+ created_at: "timestamp",
145
+ },
146
+ redaction: "SECRET_PATTERNS (PII)",
147
+ dedup: "content-hash (fingerprint)",
148
+ vendor_extensions_preserved: true,
149
+ };
150
+ // v2.0.0 (K16-001) — C-14 MemorySources, since 2.0.0
151
+ export const CONTRACT_MEMORY_SOURCES = {
152
+ sources: [
153
+ { name: "opencode-plugin", precedence: 10 },
154
+ { name: "claude-memory", precedence: 20 },
155
+ { name: "codex-memories", precedence: 30 },
156
+ { name: "opencode-native", precedence: 40 },
157
+ ],
158
+ dedup_rule: "lower precedence wins attribution; losers counted in source_dedup_skips_total",
159
+ conflict_kind: "source_pair",
160
+ precedence_order: [10, 20, 30, 40],
161
+ };
49
162
  // Tool names — the live source of truth for C-03. Any rename here must
50
163
  // flow to the contract (K10-006 AC: renaming a tool changes C-03).
51
164
  // Keep this array adjacent to the actual tool registrations in index.ts
@@ -85,6 +198,7 @@ export const CONTRACT_TOOL_ADDITIONS = [
85
198
  { name: "kevin_bench", since: "1.0.0" },
86
199
  { name: "kevin_contract", since: "1.0.0" },
87
200
  { name: "kevin_forget", since: "1.1.0" },
201
+ { name: "kevin_sources", since: "2.0.0" },
88
202
  ];
89
203
  /**
90
204
  * v1.1.0 (K11-007 / plan §5.1, D11-01) — metric keys added after the freeze,
@@ -107,6 +221,11 @@ export const CONTRACT_METRIC_ADDITIONS = [
107
221
  { name: "mif_exports_total", since: "1.5.0" },
108
222
  { name: "mif_imports_total", since: "1.5.0" },
109
223
  { name: "skills_emitted_total", since: "1.5.0" },
224
+ // v2.0.0 (K16-012 / plan §4.4) — Commonwealth metrics
225
+ { name: "source_syncs_total", since: "2.0.0" },
226
+ { name: "source_dedup_skips_total", since: "2.0.0" },
227
+ { name: "okf_v3_files_written", since: "2.0.0" },
228
+ { name: "source_deletions_total", since: "2.1.0" },
110
229
  ];
111
230
  /**
112
231
  * v1.4.0 (K14-006 / plan §4.3) — config keys added after the freeze,
@@ -121,6 +240,25 @@ export const CONTRACT_CONFIG_ADDITIONS = [
121
240
  { name: "skills_canonical_dir", since: "1.5.0" },
122
241
  { name: "skills_mirror_claude", since: "1.5.0" },
123
242
  { name: "skills_mirror_cursor", since: "1.5.0" },
243
+ // v2.0.0 (K16-013 / plan §4.4) — Commonwealth settings (retirement of import_host_memory handled via removals)
244
+ { name: "okf_write_version", since: "2.0.0" },
245
+ { name: "source_claude_memory", since: "2.0.0" },
246
+ { name: "source_codex_memories", since: "2.0.0" },
247
+ { name: "source_opencode_native", since: "2.0.0" },
248
+ { name: "sources_enabled", since: "2.0.0" },
249
+ { name: "source_deletion_sync", since: "2.1.0" },
250
+ ];
251
+ /**
252
+ * v2.0.0 (K16-004 / plan §5.1) — removed settings (retirements)
253
+ * Each entry carries `since` 2.0.0 and optional replacement pointer.
254
+ * Succession test treats these as LEGITIMATE removals via `removed` annotation.
255
+ */
256
+ export const CONTRACT_REMOVED_CONFIG_KEYS = [
257
+ {
258
+ name: "import_host_memory",
259
+ since: "2.0.0",
260
+ replacement: "sources_enabled + source_claude_memory/source_codex_memories",
261
+ },
124
262
  ];
125
263
  /**
126
264
  * v1.0.0 (K10-027 / plan §5.7) — the C-09 boundary addition. Stored is
@@ -166,7 +304,14 @@ export function describeContract(_input) {
166
304
  const baseConfigKeys = [...KEVIN_CONFIG_KEYS]
167
305
  .filter((k) => !configAdditions.some((a) => a.name === k))
168
306
  .sort();
169
- const settingValue = { keys: [...baseConfigKeys, ...configAdditions].flat() };
307
+ // v2.0.0 (K16-004/005) removed keys are filtered from `keys` and surfaced via `removed` annotation with since 2.0.0
308
+ const removedConfig = [...CONTRACT_REMOVED_CONFIG_KEYS].sort((a, b) => a.name.localeCompare(b.name));
309
+ const filteredConfigAdditions = configAdditions.filter((a) => !removedConfig.some((r) => r.name === a.name));
310
+ const settingValue = {
311
+ keys: [...baseConfigKeys, ...filteredConfigAdditions].flat(),
312
+ };
313
+ if (removedConfig.length > 0)
314
+ settingValue.removed = removedConfig;
170
315
  // v1.1.0 — metric keys added after freeze carry `since` (C-05)
171
316
  const metricAdditions = [...CONTRACT_METRIC_ADDITIONS].sort((a, b) => a.name.localeCompare(b.name));
172
317
  const baseMetricKeys = Object.keys(METRIC_KEY_LABELS)
@@ -240,7 +385,7 @@ export function describeContract(_input) {
240
385
  stability: "forward-only",
241
386
  since: "0.1.0",
242
387
  value: {
243
- schema_version: "013",
388
+ schema_version: "015",
244
389
  migrations_forward_only: true,
245
390
  },
246
391
  },
@@ -274,6 +419,46 @@ export function describeContract(_input) {
274
419
  boundary: [{ name: BOUNDARY_INVARIANT, since: "1.0.0" }],
275
420
  },
276
421
  },
422
+ {
423
+ id: "C-10",
424
+ title: "Core public exports",
425
+ stability: "frozen",
426
+ since: "1.3.0",
427
+ value: {
428
+ exports: [...CONTRACT_CORE_EXPORTS].sort((a, b) => a.name.localeCompare(b.name)),
429
+ },
430
+ },
431
+ {
432
+ id: "C-11",
433
+ title: "MCP tool names and refusal vocabulary",
434
+ stability: "frozen",
435
+ since: "1.4.0",
436
+ value: {
437
+ tools: [...CONTRACT_MCP_TOOLS].sort(),
438
+ refusals: [...CONTRACT_MCP_REFUSALS].sort(),
439
+ },
440
+ },
441
+ {
442
+ id: "C-12",
443
+ title: "Emitted skills layout",
444
+ stability: "frozen",
445
+ since: "1.5.0",
446
+ value: CONTRACT_SKILLS_LAYOUT,
447
+ },
448
+ {
449
+ id: "C-13",
450
+ title: "MIF profile",
451
+ stability: "frozen",
452
+ since: "1.5.0",
453
+ value: CONTRACT_MIF_PROFILE,
454
+ },
455
+ {
456
+ id: "C-14",
457
+ title: "MemorySources",
458
+ stability: "frozen",
459
+ since: "2.0.0",
460
+ value: CONTRACT_MEMORY_SOURCES,
461
+ },
277
462
  ];
278
463
  return { contractVersion: CONTRACT_VERSION, clauses };
279
464
  }
@@ -377,6 +562,33 @@ export function diffContract(golden, live) {
377
562
  // Normalize members: for arrays we care about set equality
378
563
  for (const [mem, _gv] of gMembers) {
379
564
  if (!lMembers.has(mem)) {
565
+ // v2.0.0 (K16-005) — allow removals that are annotated via `removed` array with since (e.g. import_host_memory)
566
+ const liveVal = l.value;
567
+ if (Array.isArray(liveVal.removed)) {
568
+ const entry = liveVal.removed.find((e) => {
569
+ if (typeof e === "string")
570
+ return e === mem;
571
+ if (e !== null &&
572
+ typeof e === "object" &&
573
+ "name" in e)
574
+ return e.name === mem;
575
+ return false;
576
+ });
577
+ const hasSince = entry !== null &&
578
+ typeof entry === "object" &&
579
+ typeof entry.since === "string" &&
580
+ entry.since !== "";
581
+ if (entry !== undefined && hasSince) {
582
+ // Annotated removal — treat as allowed (like added_ok). Do not flag as confusing.
583
+ diffs.push({
584
+ clauseId: g.id,
585
+ path: `${g.id}.${mem}`,
586
+ kind: "added_ok",
587
+ remedy: `Member ${mem} in ${g.id} was removed with since. Allowed in 2.0.0.`,
588
+ });
589
+ continue;
590
+ }
591
+ }
380
592
  diffs.push({
381
593
  clauseId: g.id,
382
594
  path: `${g.id}.${mem}`,
@@ -1,6 +1,6 @@
1
- import { type KevinEnv } from "./env.js";
2
1
  import type { MemoryService } from "./MemoryService.js";
3
2
  import type { Store } from "./Store.js";
3
+ import { type KevinEnv } from "./env.js";
4
4
  import type { Metrics } from "./metrics.js";
5
5
  export interface HostImportReport {
6
6
  files_scanned: number;
@@ -1,10 +1,10 @@
1
1
  // K15-011/012/013 — Host importers (plan §4.5)
2
2
  // Defensive markdown parsers, no YAML lib, same naive parser as validator.
3
- import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
3
+ import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
4
4
  import { join } from "node:path";
5
+ import { QualityGate } from "./QualityGate.js";
5
6
  import { resolveEnv } from "./env.js";
6
7
  import { fingerprint as computeFingerprint } from "./fingerprint.js";
7
- import { QualityGate } from "./QualityGate.js";
8
8
  const MAX_FILE_BYTES = 1 * 1024 * 1024;
9
9
  const MAX_CANDIDATES = 5000;
10
10
  const CLAUDE_TYPE_MAP = {
@@ -134,7 +134,9 @@ export function parseClaudeMemory(dataRoot, env) {
134
134
  }
135
135
  // if frontmatter exists but type missing, map to context
136
136
  }
137
- const mapped = rawType ? (CLAUDE_TYPE_MAP[rawType.toLowerCase()] ?? "context") : "context";
137
+ const mapped = rawType
138
+ ? (CLAUDE_TYPE_MAP[rawType.toLowerCase()] ?? "context")
139
+ : "context";
138
140
  // bullets
139
141
  const bullets = extractBullets(content);
140
142
  if (bullets.length === 0) {
@@ -201,18 +203,31 @@ export function parseCodexMemories(dataRoot, env) {
201
203
  }
202
204
  export function importHostMemories(opts) {
203
205
  const dataRoot = opts.dataRoot ?? resolveEnv(opts.env).dataRoot;
204
- // gate
205
- const gate = opts.memoryService.getSetting("import_host_memory", "0");
206
- if (gate !== "1") {
207
- return {
208
- files_scanned: 0,
209
- candidates: 0,
210
- saved: 0,
211
- duplicates: 0,
212
- skipped_weak: 0,
213
- error: "disabled",
214
- hint: "Enable with kevin_config set import_host_memory 1",
215
- };
206
+ // gate — v2.0.0 retired import_host_memory (K16-005); check sources framework.
207
+ // Legacy fallback kept for pre-014 DBs that still carry the key before migration 014 deletes it.
208
+ const legacy = opts.memoryService.getSetting("import_host_memory", "0");
209
+ if (legacy === "1") {
210
+ // translated by 014; allow but hint new path
211
+ }
212
+ else {
213
+ const master = opts.memoryService.getSetting("sources_enabled", "0") === "1";
214
+ const perKey = opts.source === "claude-memory"
215
+ ? "source_claude_memory"
216
+ : "source_codex_memories";
217
+ const per = opts.memoryService.getSetting(perKey, "0") === "1";
218
+ if (!master || !per) {
219
+ return {
220
+ files_scanned: 0,
221
+ candidates: 0,
222
+ saved: 0,
223
+ duplicates: 0,
224
+ skipped_weak: 0,
225
+ error: "disabled",
226
+ hint: opts.source === "claude-memory"
227
+ ? "Enable with kevin_config set sources_enabled 1 and kevin_config set source_claude_memory 1"
228
+ : "Enable with kevin_config set sources_enabled 1 and kevin_config set source_codex_memories 1",
229
+ };
230
+ }
216
231
  }
217
232
  let parsed;
218
233
  if (opts.source === "claude-memory") {
@@ -233,7 +248,9 @@ export function importHostMemories(opts) {
233
248
  // dedup intra-run via fingerprint set
234
249
  const seenFingerprints = new Set();
235
250
  // existing fingerprints from DB
236
- const existingRows = opts.store.prepare("SELECT fingerprint FROM memories WHERE fingerprint IS NOT NULL").all();
251
+ const existingRows = opts.store
252
+ .prepare("SELECT fingerprint FROM memories WHERE fingerprint IS NOT NULL")
253
+ .all();
237
254
  for (const r of existingRows)
238
255
  seenFingerprints.add(r.fingerprint);
239
256
  for (const c of candidates) {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from "./Store.js";
2
2
  export * from "./Migrate.js";
3
- export { MemoryService, DATE_NOW, mapRow, readOriginCallId, countSupersedeCandidates, hasRepoIdColumn } from "./MemoryService.js";
4
- export type { Memory, SlimMemory, SlimMemoryWithEvidence, SaveInput, QueryInput, GetRelevantInput, MemoryType, MemoryScope, MemoryOrigin, MemoryUpdateResult } from "./MemoryService.js";
3
+ export { MemoryService, DATE_NOW, mapRow, readOriginCallId, countSupersedeCandidates, hasRepoIdColumn, } from "./MemoryService.js";
4
+ export type { Memory, SlimMemory, SlimMemoryWithEvidence, SaveInput, QueryInput, GetRelevantInput, MemoryType, MemoryScope, MemoryOrigin, MemoryUpdateResult, } from "./MemoryService.js";
5
5
  export * from "./ToolCallObserver.js";
6
6
  export * from "./Reflector.js";
7
7
  export * from "./ContextInjector.js";
@@ -38,23 +38,23 @@ export * from "./memory-format.js";
38
38
  export * from "./redact.js";
39
39
  export * from "./uuid.js";
40
40
  export * from "./sqlite-adapter.js";
41
- export { hasColumn, hasIgnoredColumn, hasCuratedColumn, hasTruthColumns, hasLayerColumn, hasRecurrenceColumn, hasArchivedColumn, hasFeedbackColumns, hasFeedbackTable } from "./columns.js";
41
+ export { hasColumn, hasIgnoredColumn, hasCuratedColumn, hasTruthColumns, hasLayerColumn, hasRecurrenceColumn, hasArchivedColumn, hasFeedbackColumns, hasFeedbackTable, } from "./columns.js";
42
42
  export * from "./time-ms.js";
43
43
  export * from "./idle-pipeline.js";
44
44
  export * from "./replay.js";
45
45
  export * from "./replay-types.js";
46
46
  export * from "./ChatBridge.js";
47
47
  export * from "./DashboardHtml.js";
48
- export { deleteMailbox, processActions, readMailbox, writeResults, verifyFresh, consumeMailbox } from "./TuiActions.js";
49
- export type { MailboxReadResult, PendingProposal, ProcessDeps, ActionStatus } from "./TuiActions.js";
48
+ export { deleteMailbox, processActions, readMailbox, writeResults, verifyFresh, consumeMailbox, } from "./TuiActions.js";
49
+ export type { MailboxReadResult, PendingProposal, ProcessDeps, ActionStatus, } from "./TuiActions.js";
50
50
  export * from "./TuiSnapshots.js";
51
- export type { ProposalView, ConflictView, HealthView, TuiSnapshotSet, TuiAction, ActionResult } from "./tui-types.js";
51
+ export type { ProposalView, ConflictView, HealthView, TuiSnapshotSet, TuiAction, ActionResult, } from "./tui-types.js";
52
52
  export * from "./capabilities.js";
53
53
  export * from "./host.js";
54
54
  export { V2_SPECIFIER } from "./native.js";
55
- export type { NativeDeps, NativeRegistration, SettingsReader } from "./native.js";
55
+ export type { NativeDeps, NativeRegistration, SettingsReader, } from "./native.js";
56
56
  export * from "./kevin_approve.js";
57
- export { buildAudit, type AuditReport, type ChannelReport, type CurationReport, type TruthReport, type EmissionState } from "./kevin_audit.js";
57
+ export { buildAudit, type AuditReport, type ChannelReport, type CurationReport, type TruthReport, type EmissionState, } from "./kevin_audit.js";
58
58
  export * from "./kevin_bench.js";
59
59
  export * from "./kevin_conflicts.js";
60
60
  export * from "./kevin_contract.js";
@@ -70,7 +70,11 @@ export * from "./skills-validate.js";
70
70
  export * from "./skills-emit.js";
71
71
  export * from "./mif.js";
72
72
  export * from "./import-host.js";
73
+ export * from "./okf-shards.js";
74
+ export * from "./sources/MemorySource.js";
75
+ export * from "./sources/IdleSync.js";
76
+ export * from "./sources/deletion.js";
73
77
  export * from "./env.js";
74
- export declare const KEVIN_CONFIG_KEYS: readonly ["quality_gate_enabled", "lesson_snippet_injection", "patternminer_enabled", "cross_project_enabled", "llm_reflection_enabled", "tool_calls_dedup_enabled", "deterministic_retrieval", "pre_prompt_budget_tokens", "archive_after_days", "curation_enabled", "agents_md_path", "skill_emission_enabled", "reference_emission_enabled", "injection_confidence_floor", "repo_truth_enabled", "convention_mining_enabled", "conflict_detection_enabled", "error_lesson_mode", "shared_layer_enabled", "okf_path", "share_requires_approval", "author_identity_mode", "shared_confidence_floor", "hook_liveness_enabled", "native_registration_enabled", "host_probe_history_enabled", "dead_hook_report_threshold", "perf_enabled", "perf_ring_capacity", "perf_flush_on_idle", "contract_report_enabled", "tui_snapshots_enabled", "mcp_write_enabled", "mcp_approve_enabled", "mcp_repo_override", "skills_canonical_dir", "skills_mirror_claude", "skills_mirror_cursor", "import_host_memory"];
78
+ export declare const KEVIN_CONFIG_KEYS: readonly ["quality_gate_enabled", "lesson_snippet_injection", "patternminer_enabled", "cross_project_enabled", "llm_reflection_enabled", "tool_calls_dedup_enabled", "deterministic_retrieval", "pre_prompt_budget_tokens", "archive_after_days", "curation_enabled", "agents_md_path", "skill_emission_enabled", "reference_emission_enabled", "injection_confidence_floor", "repo_truth_enabled", "convention_mining_enabled", "conflict_detection_enabled", "error_lesson_mode", "shared_layer_enabled", "okf_path", "share_requires_approval", "author_identity_mode", "shared_confidence_floor", "hook_liveness_enabled", "native_registration_enabled", "host_probe_history_enabled", "dead_hook_report_threshold", "perf_enabled", "perf_ring_capacity", "perf_flush_on_idle", "contract_report_enabled", "tui_snapshots_enabled", "mcp_write_enabled", "mcp_approve_enabled", "mcp_repo_override", "skills_canonical_dir", "skills_mirror_claude", "skills_mirror_cursor", "sources_enabled", "source_claude_memory", "source_codex_memories", "source_opencode_native", "okf_write_version", "source_deletion_sync"];
75
79
  export declare const ERROR_LESSON_MODE_VALUES: readonly ["all", "triage_only"];
76
- export declare const KEVIN_VERSION = "1.5.0";
80
+ export declare const KEVIN_VERSION = "2.1.0";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  export * from "./Store.js";
4
4
  export * from "./Migrate.js";
5
5
  // MemoryService has duplicate hasRepoIdColumn with columns.ts — export selectively (keep MemoryService's hasRepoIdColumn, columns provides other helpers)
6
- export { MemoryService, DATE_NOW, mapRow, readOriginCallId, countSupersedeCandidates, hasRepoIdColumn } from "./MemoryService.js";
6
+ export { MemoryService, DATE_NOW, mapRow, readOriginCallId, countSupersedeCandidates, hasRepoIdColumn, } from "./MemoryService.js";
7
7
  export * from "./ToolCallObserver.js";
8
8
  export * from "./Reflector.js";
9
9
  export * from "./ContextInjector.js";
@@ -41,7 +41,7 @@ export * from "./redact.js";
41
41
  export * from "./uuid.js";
42
42
  export * from "./sqlite-adapter.js";
43
43
  // columns has duplicate hasRepoIdColumn with MemoryService — export without that function (MemoryService's version is canonical via index)
44
- export { hasColumn, hasIgnoredColumn, hasCuratedColumn, hasTruthColumns, hasLayerColumn, hasRecurrenceColumn, hasArchivedColumn, hasFeedbackColumns, hasFeedbackTable } from "./columns.js";
44
+ export { hasColumn, hasIgnoredColumn, hasCuratedColumn, hasTruthColumns, hasLayerColumn, hasRecurrenceColumn, hasArchivedColumn, hasFeedbackColumns, hasFeedbackTable, } from "./columns.js";
45
45
  export * from "./time-ms.js";
46
46
  export * from "./idle-pipeline.js";
47
47
  export * from "./replay.js";
@@ -49,7 +49,7 @@ export * from "./replay-types.js";
49
49
  export * from "./ChatBridge.js";
50
50
  export * from "./DashboardHtml.js";
51
51
  // TuiActions duplicates proposalToken with DashboardHtml — export selectively (exclude proposalToken)
52
- export { deleteMailbox, processActions, readMailbox, writeResults, verifyFresh, consumeMailbox } from "./TuiActions.js";
52
+ export { deleteMailbox, processActions, readMailbox, writeResults, verifyFresh, consumeMailbox, } from "./TuiActions.js";
53
53
  export * from "./TuiSnapshots.js";
54
54
  // shims for isolation
55
55
  export * from "./capabilities.js";
@@ -57,7 +57,7 @@ export * from "./host.js";
57
57
  export { V2_SPECIFIER } from "./native.js";
58
58
  // kevin_* handlers — avoid duplicate EmissionState / NativeDeps
59
59
  export * from "./kevin_approve.js";
60
- export { buildAudit } from "./kevin_audit.js";
60
+ export { buildAudit, } from "./kevin_audit.js";
61
61
  export * from "./kevin_bench.js";
62
62
  export * from "./kevin_conflicts.js";
63
63
  export * from "./kevin_contract.js";
@@ -72,6 +72,10 @@ export * from "./skills-validate.js";
72
72
  export * from "./skills-emit.js";
73
73
  export * from "./mif.js";
74
74
  export * from "./import-host.js";
75
+ export * from "./okf-shards.js";
76
+ export * from "./sources/MemorySource.js";
77
+ export * from "./sources/IdleSync.js";
78
+ export * from "./sources/deletion.js";
75
79
  // KEVIN_CONFIG_KEYS and related constants — moved from adapter index so core owns the source of truth (C-04).
76
80
  // Duplicated here to allow adapter to import from core; adapter will re-export them.
77
81
  export * from "./env.js";
@@ -114,7 +118,12 @@ export const KEVIN_CONFIG_KEYS = [
114
118
  "skills_canonical_dir",
115
119
  "skills_mirror_claude",
116
120
  "skills_mirror_cursor",
117
- "import_host_memory",
121
+ "sources_enabled",
122
+ "source_claude_memory",
123
+ "source_codex_memories",
124
+ "source_opencode_native",
125
+ "okf_write_version",
126
+ "source_deletion_sync",
118
127
  ];
119
128
  export const ERROR_LESSON_MODE_VALUES = ["all", "triage_only"];
120
- export const KEVIN_VERSION = "1.5.0";
129
+ export const KEVIN_VERSION = "2.1.0";
package/dist/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", "injections_total", "injections_effective", "injections_ineffective", "patterns_promoted_new", "injections_inconclusive", "injections_blocked_seen", "injections_blocked_weak", "injections_blocked_recurrence", "injections_blocked_stale", "injections_blocked_ignored", "feedback_positive_total", "feedback_negative_total", "memories_archived", "proposals_created", "proposals_approved", "proposals_rejected", "artifact_writes_total", "artifact_writes_noop", "injections_blocked_confidence", "repo_facts_scanned", "memories_contradicted", "conventions_mined", "conflicts_detected", "error_lessons_suppressed", "shared_entries_total", "shared_entries_imported", "shared_entries_exported", "okf_merge_folds", "rekey_events", "injections_from_shared", "bench_regression_failures", "forget_requests_total", "forget_tombstones_published", "tui_snapshots_flushed", "tui_actions_invoked", "mcp_requests_total", "mcp_reads_served", "mcp_writes_accepted", "mcp_writes_refused", "mcp_errors_total", "skills_emitted_total", "mif_exports_total", "mif_imports_total"];
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", "injections_inconclusive", "injections_blocked_seen", "injections_blocked_weak", "injections_blocked_recurrence", "injections_blocked_stale", "injections_blocked_ignored", "feedback_positive_total", "feedback_negative_total", "memories_archived", "proposals_created", "proposals_approved", "proposals_rejected", "artifact_writes_total", "artifact_writes_noop", "injections_blocked_confidence", "repo_facts_scanned", "memories_contradicted", "conventions_mined", "conflicts_detected", "error_lessons_suppressed", "shared_entries_total", "shared_entries_imported", "shared_entries_exported", "okf_merge_folds", "rekey_events", "injections_from_shared", "hook_fires_total", "hook_errors_total", "hooks_dead_total", "injections_suppressed_dead_hook", "native_registrations_total", "native_registration_failures", "perf_samples_recorded", "perf_budget_breaches", "dispose_fires_total", "dispose_misses_total", "contract_digest_changes", "bench_runs_total", "bench_regression_failures", "forget_requests_total", "forget_tombstones_published", "tui_snapshots_flushed", "tui_actions_invoked", "mcp_requests_total", "mcp_reads_served", "mcp_writes_accepted", "mcp_writes_refused", "mcp_errors_total", "skills_emitted_total", "mif_exports_total", "mif_imports_total", "source_syncs_total", "source_dedup_skips_total", "okf_v3_files_written", "source_deletions_total"];
10
10
  export type MetricKey = (typeof METRIC_KEYS)[number];
11
11
  /**
12
12
  * Cheap token estimate used when bumping the `tokens_injected_*` counters.
package/dist/metrics.js CHANGED
@@ -57,6 +57,20 @@ export const METRIC_KEYS = [
57
57
  "okf_merge_folds",
58
58
  "rekey_events",
59
59
  "injections_from_shared",
60
+ // v0.9.0 (K9-003 / plan §8.10) — native metrics; order matches 010 seed (K16-001 fix: was missing)
61
+ "hook_fires_total",
62
+ "hook_errors_total",
63
+ "hooks_dead_total",
64
+ "injections_suppressed_dead_hook",
65
+ "native_registrations_total",
66
+ "native_registration_failures",
67
+ // v1.0.0 (K10-005 / plan §6) — proven metrics; order matches 011 seed (K16-001 fix: was missing)
68
+ "perf_samples_recorded",
69
+ "perf_budget_breaches",
70
+ "dispose_fires_total",
71
+ "dispose_misses_total",
72
+ "contract_digest_changes",
73
+ "bench_runs_total",
60
74
  // v1.1.0 (K11-001 / plan §4, D11-01) — drift metrics; order matches 012 seed.
61
75
  "bench_regression_failures",
62
76
  "forget_requests_total",
@@ -75,6 +89,12 @@ export const METRIC_KEYS = [
75
89
  "skills_emitted_total",
76
90
  "mif_exports_total",
77
91
  "mif_imports_total",
92
+ // v2.0.0 (K16-012 / plan §4.4) — Commonwealth metrics
93
+ "source_syncs_total",
94
+ "source_dedup_skips_total",
95
+ "okf_v3_files_written",
96
+ // v2.1.0 (K21-005 / plan §4.3) — Relay deletion metric (opt-in, default 0)
97
+ "source_deletions_total",
78
98
  ];
79
99
  const DEFAULT_FLUSH_MS = 1000;
80
100
  function zeroCache() {