@jmtrin/opencode-kevin 0.7.0 → 0.9.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 (70) hide show
  1. package/README.md +254 -12
  2. package/dist/migrations/009_v08_team.sql +100 -0
  3. package/dist/migrations/010_v09_native.sql +78 -0
  4. package/dist/plugin/ArtifactWriter.d.ts +28 -0
  5. package/dist/plugin/ArtifactWriter.js +35 -2
  6. package/dist/plugin/ArtifactWriter.js.map +1 -1
  7. package/dist/plugin/ContextInjector.d.ts +9 -0
  8. package/dist/plugin/ContextInjector.js +14 -3
  9. package/dist/plugin/ContextInjector.js.map +1 -1
  10. package/dist/plugin/Curator.d.ts +22 -2
  11. package/dist/plugin/Curator.js +56 -14
  12. package/dist/plugin/Curator.js.map +1 -1
  13. package/dist/plugin/HookLiveness.d.ts +81 -0
  14. package/dist/plugin/HookLiveness.js +324 -0
  15. package/dist/plugin/HookLiveness.js.map +1 -0
  16. package/dist/plugin/InjectionLedger.d.ts +6 -0
  17. package/dist/plugin/InjectionLedger.js +6 -0
  18. package/dist/plugin/InjectionLedger.js.map +1 -1
  19. package/dist/plugin/Materializer.d.ts +29 -5
  20. package/dist/plugin/Materializer.js +48 -16
  21. package/dist/plugin/Materializer.js.map +1 -1
  22. package/dist/plugin/MemoryService.d.ts +34 -5
  23. package/dist/plugin/MemoryService.js +215 -7
  24. package/dist/plugin/MemoryService.js.map +1 -1
  25. package/dist/plugin/Migrate.d.ts +1 -0
  26. package/dist/plugin/Migrate.js +74 -3
  27. package/dist/plugin/Migrate.js.map +1 -1
  28. package/dist/plugin/RepoIdentity.d.ts +124 -0
  29. package/dist/plugin/RepoIdentity.js +301 -0
  30. package/dist/plugin/RepoIdentity.js.map +1 -0
  31. package/dist/plugin/Retrospective.js +18 -0
  32. package/dist/plugin/Retrospective.js.map +1 -1
  33. package/dist/plugin/SharedLayer.d.ts +159 -0
  34. package/dist/plugin/SharedLayer.js +463 -0
  35. package/dist/plugin/SharedLayer.js.map +1 -0
  36. package/dist/plugin/host.d.ts +70 -0
  37. package/dist/plugin/host.js +251 -0
  38. package/dist/plugin/host.js.map +1 -0
  39. package/dist/plugin/index.d.ts +30 -1
  40. package/dist/plugin/index.js +582 -12
  41. package/dist/plugin/index.js.map +1 -1
  42. package/dist/plugin/kevin_approve.js +7 -4
  43. package/dist/plugin/kevin_approve.js.map +1 -1
  44. package/dist/plugin/kevin_audit.d.ts +48 -1
  45. package/dist/plugin/kevin_audit.js +179 -3
  46. package/dist/plugin/kevin_audit.js.map +1 -1
  47. package/dist/plugin/kevin_doctor.d.ts +57 -0
  48. package/dist/plugin/kevin_doctor.js +168 -0
  49. package/dist/plugin/kevin_doctor.js.map +1 -0
  50. package/dist/plugin/kevin_native.d.ts +29 -0
  51. package/dist/plugin/kevin_native.js +80 -0
  52. package/dist/plugin/kevin_native.js.map +1 -0
  53. package/dist/plugin/metrics.d.ts +1 -1
  54. package/dist/plugin/metrics.js +9 -0
  55. package/dist/plugin/metrics.js.map +1 -1
  56. package/dist/plugin/native.d.ts +92 -0
  57. package/dist/plugin/native.js +191 -0
  58. package/dist/plugin/native.js.map +1 -0
  59. package/dist/plugin/okf-export.d.ts +2 -2
  60. package/dist/plugin/okf-export.js +15 -7
  61. package/dist/plugin/okf-export.js.map +1 -1
  62. package/dist/plugin/okf.d.ts +107 -0
  63. package/dist/plugin/okf.js +304 -0
  64. package/dist/plugin/okf.js.map +1 -0
  65. package/dist/plugin/replay-types.d.ts +29 -287
  66. package/dist/plugin/replay-types.js +145 -53
  67. package/dist/plugin/replay-types.js.map +1 -1
  68. package/migrations/009_v08_team.sql +100 -0
  69. package/migrations/010_v09_native.sql +78 -0
  70. package/package.json +2 -3
@@ -0,0 +1,324 @@
1
+ import { HOOK_NAMES } from "./Migrate.js";
2
+ const DEFAULT_THRESHOLD = 3;
3
+ /**
4
+ * v0.9.0 (K9-010 / plan §5.3, D9-09) — parse the TEXT setting
5
+ * `dead_hook_report_threshold` into the [1, 1000] clamp. NaN and empty
6
+ * fall back to 3 (never 0: a zero threshold would report every hook dead
7
+ * before a single session completes a checkpoint).
8
+ */
9
+ export function parseThreshold(text) {
10
+ if (text === null || text === undefined || text === "")
11
+ return DEFAULT_THRESHOLD;
12
+ const n = Number.parseInt(text, 10);
13
+ // NaN → default; 0 is not a valid threshold (K9-010 AC: 'abc'/''/'0'
14
+ // all clamp to the default of three — never zero).
15
+ if (Number.isNaN(n) || n === 0)
16
+ return DEFAULT_THRESHOLD;
17
+ return Math.min(1000, Math.max(1, n));
18
+ }
19
+ /**
20
+ * v0.9.0 (K9-009/K9-010 / plan §5.3) — wraps the plugin's hooks with a
21
+ * success-path recorder, dedups per-session checkpoints, and reports each
22
+ * hook's liveness state. Persistence is machine-scoped: the hook_liveness
23
+ * table carries no project_id or repo_id (D9-08).
24
+ */
25
+ export class HookLiveness {
26
+ store;
27
+ options;
28
+ counters;
29
+ seenSessions;
30
+ suppressedSessions = new Set();
31
+ threshold;
32
+ pluginVersion;
33
+ constructor(store, options) {
34
+ this.store = store;
35
+ this.options = options;
36
+ this.threshold = parseThreshold(options.thresholdText);
37
+ this.pluginVersion = options.pluginVersion;
38
+ this.counters = new Map();
39
+ this.seenSessions = new Map();
40
+ for (const hook of HOOK_NAMES) {
41
+ this.counters.set(hook, {
42
+ fireCount: 0,
43
+ errorCount: 0,
44
+ expectedCount: 0,
45
+ firstSeenAt: null,
46
+ lastSeenAt: null,
47
+ deadSince: null,
48
+ });
49
+ this.seenSessions.set(hook, new Set());
50
+ }
51
+ this.loadFromDb();
52
+ }
53
+ /**
54
+ * Returns a new object with the same keys; function values are replaced
55
+ * by delegating wrappers, non-function values (the tool map) pass by
56
+ * reference. When liveness is disabled, returns the argument unchanged —
57
+ * the same object, not a copy.
58
+ */
59
+ wrap(hooks) {
60
+ if (!this.options.enabled)
61
+ return hooks;
62
+ const out = {};
63
+ for (const [key, value] of Object.entries(hooks)) {
64
+ if (typeof value === "function") {
65
+ out[key] = this.makeWrapper(key, value);
66
+ }
67
+ else {
68
+ out[key] = value;
69
+ }
70
+ }
71
+ return out;
72
+ }
73
+ /**
74
+ * v0.9.0 (K9-010 / plan §5.3) — a checkpoint: the session reached a
75
+ * model turn (tool.execute.after fired), so the system prompt was
76
+ * assembled and `experimental.chat.system.transform` MUST have been
77
+ * offered. Deduped per session: 20 tool calls in one session count
78
+ * exactly one expectation.
79
+ */
80
+ expect(hook, sessionID) {
81
+ const seen = this.seenSessions.get(hook);
82
+ if (!seen || seen.has(sessionID))
83
+ return;
84
+ seen.add(sessionID);
85
+ const counters = this.counters.get(hook);
86
+ if (!counters)
87
+ return;
88
+ counters.expectedCount += 1;
89
+ // The dead flag is materialized here (not only in report()) so that
90
+ // flush() persists dead_since even when no report() was ever called:
91
+ // kevin_doctor's PURE-SQL blocks read dead_since from the table.
92
+ if (counters.fireCount === 0 &&
93
+ counters.expectedCount >= this.threshold &&
94
+ counters.deadSince === null) {
95
+ counters.deadSince = counters.lastSeenAt ?? new Date().toISOString();
96
+ }
97
+ // v0.9.0 (K9-011 / plan §5.3) — when the injection hook is dead, the
98
+ // checkpointed session was suppressed: the host stopped offering the
99
+ // transform, so no injection could happen. Counted once per session
100
+ // (same dedup as expected_count) and persisted by flush(). This is
101
+ // the counter that turns "zero injections" from an ambiguous number
102
+ // into a diagnosis.
103
+ if (hook === "experimental.chat.system.transform" &&
104
+ counters.deadSince !== null &&
105
+ !this.suppressedSessions.has(sessionID)) {
106
+ this.suppressedSessions.add(sessionID);
107
+ }
108
+ }
109
+ /**
110
+ * Per-hook liveness verdicts in canonical HOOK_NAMES order.
111
+ * A hook that fired once is live forever; dead requires both zero fires
112
+ * and `expectedCount >= threshold`; everything else is unknown — and
113
+ * unknown is never rounded to healthy (D9-09).
114
+ */
115
+ report() {
116
+ const out = [];
117
+ for (const hook of HOOK_NAMES) {
118
+ const c = this.counters.get(hook);
119
+ if (!c)
120
+ continue;
121
+ let state;
122
+ if (c.fireCount > 0) {
123
+ state = "live";
124
+ }
125
+ else if (c.expectedCount >= this.threshold) {
126
+ // dead_since is set ONCE and never cleared: it documents the
127
+ // historical death even if the hook later recovers.
128
+ if (c.deadSince === null) {
129
+ c.deadSince = c.lastSeenAt ?? new Date().toISOString();
130
+ }
131
+ state = "dead";
132
+ }
133
+ else {
134
+ state = "unknown";
135
+ }
136
+ out.push({
137
+ hook,
138
+ experimental: hook.startsWith("experimental."),
139
+ state,
140
+ firstSeenAt: c.firstSeenAt,
141
+ lastSeenAt: c.lastSeenAt,
142
+ fireCount: c.fireCount,
143
+ expectedCount: c.expectedCount,
144
+ deadSince: c.deadSince,
145
+ });
146
+ }
147
+ return out;
148
+ }
149
+ /** Persists every counter row. Called on the metrics.flush() cadence. */
150
+ flush() {
151
+ const store = this.store;
152
+ store.transaction(() => {
153
+ // Created lazily on first flush, mirroring Metrics.flush(): the
154
+ // migration guarantees the table in production, but unit tests
155
+ // against pre-010 DBs must not explode at dispose.
156
+ store.exec(`CREATE TABLE IF NOT EXISTS hook_liveness (
157
+ hook TEXT PRIMARY KEY,
158
+ experimental INTEGER NOT NULL DEFAULT 0,
159
+ fire_count INTEGER NOT NULL DEFAULT 0,
160
+ error_count INTEGER NOT NULL DEFAULT 0,
161
+ expected_count INTEGER NOT NULL DEFAULT 0,
162
+ first_seen_at TEXT,
163
+ last_seen_at TEXT,
164
+ dead_since TEXT,
165
+ plugin_version TEXT
166
+ )`);
167
+ const upsert = store.prepare(`INSERT INTO hook_liveness (hook, experimental, fire_count, error_count,
168
+ expected_count, first_seen_at, last_seen_at, dead_since, plugin_version)
169
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
170
+ ON CONFLICT(hook) DO UPDATE SET
171
+ experimental = excluded.experimental,
172
+ fire_count = excluded.fire_count,
173
+ error_count = excluded.error_count,
174
+ expected_count = excluded.expected_count,
175
+ first_seen_at = excluded.first_seen_at,
176
+ last_seen_at = excluded.last_seen_at,
177
+ dead_since = excluded.dead_since,
178
+ plugin_version = excluded.plugin_version`);
179
+ for (const [hook, c] of this.counters) {
180
+ upsert.run(hook, hook.startsWith("experimental.") ? 1 : 0, c.fireCount, c.errorCount, c.expectedCount, c.firstSeenAt, c.lastSeenAt, c.deadSince, this.pluginVersion);
181
+ }
182
+ // v0.9.0 (K9-011 / plan §5.3) — the four v0.9.0 counters are
183
+ // re-derived here, on the metrics cadence, exactly like the 009
184
+ // post-apply hook re-derives hooks_dead_total: SUM(fire_count),
185
+ // SUM(error_count), COUNT(dead_since) and the per-session
186
+ // suppression count. No Metrics dependency, no writes in the hot
187
+ // path — flush() is the single persistence point.
188
+ let fireSum = 0;
189
+ let errorSum = 0;
190
+ let deadCount = 0;
191
+ for (const c of this.counters.values()) {
192
+ fireSum += c.fireCount;
193
+ errorSum += c.errorCount;
194
+ if (c.deadSince !== null)
195
+ deadCount += 1;
196
+ }
197
+ store.exec(`CREATE TABLE IF NOT EXISTS kevin_metrics (
198
+ key TEXT PRIMARY KEY,
199
+ value INTEGER NOT NULL DEFAULT 0,
200
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
201
+ )`);
202
+ const derive = store.prepare(`INSERT INTO kevin_metrics (key, value, updated_at)
203
+ VALUES (?, ?, datetime('now'))
204
+ ON CONFLICT(key) DO UPDATE SET
205
+ value = excluded.value,
206
+ updated_at = datetime('now')`);
207
+ derive.run("hook_fires_total", fireSum);
208
+ derive.run("hook_errors_total", errorSum);
209
+ derive.run("hooks_dead_total", deadCount);
210
+ derive.run("injections_suppressed_dead_hook", this.suppressedSessions.size);
211
+ });
212
+ }
213
+ makeWrapper(key, delegate) {
214
+ const record = () => {
215
+ if (HOOK_NAMES.includes(key)) {
216
+ this.recordSuccess(key);
217
+ }
218
+ };
219
+ const recordError = (e) => {
220
+ if (HOOK_NAMES.includes(key)) {
221
+ this.recordError(key);
222
+ }
223
+ throw e;
224
+ };
225
+ const n = delegate.length;
226
+ if (n === 0) {
227
+ return async () => {
228
+ try {
229
+ const result = await delegate();
230
+ record();
231
+ return result;
232
+ }
233
+ catch (e) {
234
+ return recordError(e);
235
+ }
236
+ };
237
+ }
238
+ if (n === 1) {
239
+ return async (a) => {
240
+ try {
241
+ const result = await delegate(a);
242
+ record();
243
+ return result;
244
+ }
245
+ catch (e) {
246
+ return recordError(e);
247
+ }
248
+ };
249
+ }
250
+ return async (a, b) => {
251
+ try {
252
+ const result = await delegate(a, b);
253
+ record();
254
+ return result;
255
+ }
256
+ catch (e) {
257
+ return recordError(e);
258
+ }
259
+ };
260
+ }
261
+ recordSuccess(hook) {
262
+ const c = this.counters.get(hook);
263
+ if (!c)
264
+ return;
265
+ c.fireCount += 1;
266
+ const now = new Date().toISOString();
267
+ if (c.firstSeenAt === null)
268
+ c.firstSeenAt = now;
269
+ c.lastSeenAt = now;
270
+ }
271
+ recordError(hook) {
272
+ const c = this.counters.get(hook);
273
+ if (!c)
274
+ return;
275
+ c.errorCount += 1;
276
+ }
277
+ loadFromDb() {
278
+ let rows = [];
279
+ try {
280
+ rows = this.store
281
+ .prepare("SELECT hook, fire_count, error_count, expected_count, first_seen_at, last_seen_at, dead_since FROM hook_liveness")
282
+ .all();
283
+ }
284
+ catch {
285
+ // Graceful: pre-010 DBs have no hook_liveness table; the seeded
286
+ // zeros remain until the first flush creates rows.
287
+ rows = [];
288
+ }
289
+ for (const row of rows) {
290
+ if (!HOOK_NAMES.includes(row.hook))
291
+ continue;
292
+ const c = this.counters.get(row.hook);
293
+ if (!c)
294
+ continue;
295
+ c.fireCount = row.fire_count;
296
+ c.errorCount = row.error_count;
297
+ c.expectedCount = row.expected_count;
298
+ c.firstSeenAt = row.first_seen_at;
299
+ c.lastSeenAt = row.last_seen_at;
300
+ c.deadSince = row.dead_since;
301
+ }
302
+ }
303
+ }
304
+ export function reduceVerdict(reports) {
305
+ if (reports.length === 0) {
306
+ return { verdict: "unknown", reason: "no hook reports yet" };
307
+ }
308
+ const dead = reports.filter((r) => r.state === "dead");
309
+ if (dead.length > 0) {
310
+ return {
311
+ verdict: "degraded",
312
+ reason: `${dead.map((r) => r.hook).join(", ")} dead since ${dead[0].deadSince ?? "unknown"}; ${dead.length} affected hook(s)`,
313
+ };
314
+ }
315
+ if (reports.every((r) => r.state === "live")) {
316
+ return { verdict: "healthy", reason: "all hooks live" };
317
+ }
318
+ const pending = reports.filter((r) => r.state === "unknown").length;
319
+ return {
320
+ verdict: "unknown",
321
+ reason: `${pending} hook(s) without checkpoint`,
322
+ };
323
+ }
324
+ //# sourceMappingURL=HookLiveness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HookLiveness.js","sourceRoot":"","sources":["../../plugin/HookLiveness.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,12 @@ export interface InjectionRecordInput {
29
29
  sessionId: string;
30
30
  hook: InjectionHook;
31
31
  tokens: number;
32
+ /**
33
+ * v0.8.0 (K8-024 / plan §5.7) — the memory's layer, passed by the
34
+ * caller (the injector already knows it — no lookup on the hot path).
35
+ * Drives the `injections_from_shared` counter.
36
+ */
37
+ layer?: string | null;
32
38
  }
33
39
  interface InjectionRow {
34
40
  id: string;
@@ -17,6 +17,12 @@ export class InjectionLedger {
17
17
  VALUES (?, ?, ?, ?, ?, ?, 'unmeasured')`)
18
18
  .run(uuidv7(), input.memoryId, input.fingerprint, input.sessionId, input.hook, input.tokens);
19
19
  this.metrics?.incr("injections_total", 1);
20
+ // v0.8.0 (K8-024 / plan §5.7) — shared-layer consumption is counted
21
+ // separately so the audit can tell how much of the push channel
22
+ // came from teammates' entries.
23
+ if (input.layer === "shared") {
24
+ this.metrics?.incr("injections_from_shared", 1);
25
+ }
20
26
  }
21
27
  /**
22
28
  * Settles every unmeasured injection of the session: a fingerprint that
@@ -1 +1 @@
1
- {"version":3,"file":"InjectionLedger.js","sourceRoot":"","sources":["../../plugin/InjectionLedger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InjectionLedger.js","sourceRoot":"","sources":["../../plugin/InjectionLedger.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AA0DnC,MAAM,OAAO,eAAe;IACV,KAAK,CAAQ;IACb,OAAO,CAAiB;IAEzC,YAAY,KAAY,EAAE,OAAwB;QACjD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAA2B;QACjC,IAAI,CAAC,KAAK;aACR,OAAO,CACP;;6CAEyC,CACzC;aACA,GAAG,CACH,MAAM,EAAE,EACR,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,MAAM,CACZ,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAC1C,oEAAoE;QACpE,gEAAgE;QAChE,gCAAgC;QAChC,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,SAAiB;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK;aAC3B,OAAO,CACP;;;uCAGmC,CACnC;aACA,GAAG,CAAC,SAAS,CAMZ,CAAC;QAEJ,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC9B,+DAA+D;YAC/D,2DAA2D;YAC3D,sDAAsD;YACtD,8DAA8D;YAC9D,8DAA8D;YAC9D,4DAA4D;YAC5D,cAAc;YACd,EAAE;YACF,6DAA6D;YAC7D,8DAA8D;YAC9D,gEAAgE;YAChE,gEAAgE;YAChE,8DAA8D;YAC9D,8DAA8D;YAC9D,yDAAyD;YACzD,8DAA8D;YAC9D,0DAA0D;YAC1D,8BAA8B;YAC9B,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK;iBACzB,OAAO,CACP;;;;;;cAMS,CACT;iBACA,GAAG,CACH,SAAS,EACT,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,WAAW,EACf,YAAY,EACZ,YAAY,CACK,CAAC;YAEpB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;YAErB,6DAA6D;YAC7D,sEAAsE;YACtE,gEAAgE;YAChE,mEAAmE;YACnE,qEAAqE;YACrE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACZ,IAAI,GAAG,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;oBAClC,IAAI,CAAC,KAAK;yBACR,OAAO,CACP;sBACe,CACf;yBACA,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACd,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAC;gBACjD,CAAC;gBACD,IAAI,CAAC,KAAK;qBACR,OAAO,CACP;;;;;;yCAMmC,CACnC;qBACA,GAAG,CACH,QAAQ,CAAC,CAAC,EACV,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,SAAS,CACb,CAAC;gBACH,yDAAyD;gBACzD,sDAAsD;gBACtD,uDAAuD;gBACvD,mDAAmD;gBACnD,kDAAkD;gBAClD,IAAI,CAAC,KAAK;qBACR,OAAO,CACP;+CACyC,CACzC;qBACA,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtB,CAAC;iBAAM,IAAI,GAAG,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;gBACzC,2DAA2D;gBAC3D,0CAA0C;gBAC1C,6DAA6D;gBAC7D,6DAA6D;gBAC7D,4DAA4D;gBAC5D,2DAA2D;gBAC3D,kCAAkC;gBAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK;qBACvB,OAAO,CACP;;;;;eAKS,CACT;qBACA,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,WAAW,CAEhD,CAAC;gBACF,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnB,IAAI,CAAC,KAAK;yBACR,OAAO,CACP;sBACe,CACf;yBACA,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACd,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;gBAC/C,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,KAAK;yBACR,OAAO,CACP;sBACe,CACf;yBACA,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACd,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;gBAClD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,SAAiB;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;aACrB,OAAO,CACP;;;uEAGmE,CACnE;aACA,GAAG,CAAC,SAAS,CAA4B,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,CAAC,EAAE;gBAAE,SAAS;YACpB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,2BAA2B,CAAC,SAAiB;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;aACrB,OAAO,CACP;;;;;;;;4BAQwB,CACxB;aACA,GAAG,CAAC,SAAS,CAA4B,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,CAAC,EAAE;gBAAE,SAAS;YACpB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,gFAAgF;IAChF,mBAAmB,CAAC,SAAiB;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK;aACpB,OAAO,CACP;sDACkD,CAClD;aACA,GAAG,CAAC,SAAS,CAAkB,CAAC;QAClC,OAAO,GAAG,CAAC,CAAC,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,cAAc,CAAC,SAAiB;QAC/B,OAAO,IAAI,CAAC,KAAK;aACf,OAAO,CACP;;;;uCAImC,CACnC;aACA,GAAG,CAAC,SAAS,CAAmB,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,aAAa;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK;aACrB,OAAO,CACP,sEAAsE,CACtE;aACA,GAAG,EAAgD,CAAC;QACtD,MAAM,GAAG,GAAqC;YAC7C,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,CAAC;SACf,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACtB,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC;IACZ,CAAC;CACD;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,KAAY,EAAE,QAAgB;IACvD,MAAM,GAAG,GAAG,KAAK;SACf,OAAO,CAAC,4CAA4C,CAAC;SACrD,GAAG,CAAC,QAAQ,CAA4C,CAAC;IAC3D,IAAI,CAAC,GAAG,EAAE,QAAQ;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAA4B,CAAC;QACnE,MAAM,EAAE,GAAG,MAAM,EAAE,cAAc,CAAC;QAClC,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC"}
@@ -30,13 +30,32 @@ export interface BundleTarget {
30
30
  readonly path: string;
31
31
  }
32
32
  export declare const SKILL_TOPIC = "project-knowledge";
33
+ /**
34
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — the native registration surfaces.
35
+ * Registration replaces emission; they are never both active.
36
+ */
37
+ export type NativeSurface = "skill" | "reference";
33
38
  export declare class Materializer {
34
39
  private readonly store;
35
40
  /** `root` is injectable for tests; production defaults to ~/.opencode-kevin. */
36
41
  private readonly root;
42
+ /**
43
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — the mutual-exclusion guard.
44
+ * A surface `attachNative()` registered is skipped by `materialize()`
45
+ * for that surface only; the other surface keeps emitting.
46
+ */
47
+ private readonly nativeRegistered;
37
48
  constructor(store: Store, options?: {
38
49
  root?: string;
39
50
  });
51
+ /**
52
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — record whether the surface was
53
+ * registered natively. Called at attach time (index.ts wiring, K9-018)
54
+ * with each `NativeRegistration.registered` flag.
55
+ */
56
+ markNativeRegistered(surface: NativeSurface, registered: boolean): void;
57
+ /** v0.9.0 (K9-016 / plan §5.4, D9-10) — is the surface registered natively? */
58
+ hasNativeRegistration(surface: NativeSurface): boolean;
40
59
  /** The curated, active memories — the knowledge the pull channels publish. */
41
60
  private curatedRows;
42
61
  /** The rendered skill body over all curated memories; "" when empty. */
@@ -49,11 +68,16 @@ export declare class Materializer {
49
68
  */
50
69
  bundleTargets(): BundleTarget[];
51
70
  /**
52
- * Regenerate every bundle through the ArtifactWriter (plan + apply).
53
- * The only call site of `apply()` outside `kevin_approve` D6-01's
54
- * single write FUNCTION with two constrained targets: `kevin_approve`
55
- * reaches `agents_md_path`, this module reaches `~/.opencode-kevin`
56
- * only (D6-07; enforced by K6-020).
71
+ * Regenerate every bundle through the ArtifactWriter (write). This is
72
+ * a call site of `write()` the single write FUNCTION with two
73
+ * constrained targets: `kevin_approve` reaches `agents_md_path`, this
74
+ * module reaches `~/.opencode-kevin` only (D6-07; enforced by K6-020).
75
+ *
76
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — the guard: a surface registered
77
+ * natively by `attachNative()` is skipped here for that surface only.
78
+ * Both active would put the curated skill in front of the model twice
79
+ * from two sources that can disagree; neither active would silently
80
+ * remove the feature on hosts that gained the subpath.
57
81
  */
58
82
  materialize(writer: ArtifactWriter): MaterializedBundle[];
59
83
  }
@@ -141,10 +141,31 @@ export class Materializer {
141
141
  store;
142
142
  /** `root` is injectable for tests; production defaults to ~/.opencode-kevin. */
143
143
  root;
144
+ /**
145
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — the mutual-exclusion guard.
146
+ * A surface `attachNative()` registered is skipped by `materialize()`
147
+ * for that surface only; the other surface keeps emitting.
148
+ */
149
+ nativeRegistered = new Set();
144
150
  constructor(store, options = {}) {
145
151
  this.store = store;
146
152
  this.root = options.root ?? join(homedir(), ".opencode-kevin");
147
153
  }
154
+ /**
155
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — record whether the surface was
156
+ * registered natively. Called at attach time (index.ts wiring, K9-018)
157
+ * with each `NativeRegistration.registered` flag.
158
+ */
159
+ markNativeRegistered(surface, registered) {
160
+ if (registered)
161
+ this.nativeRegistered.add(surface);
162
+ else
163
+ this.nativeRegistered.delete(surface);
164
+ }
165
+ /** v0.9.0 (K9-016 / plan §5.4, D9-10) — is the surface registered natively? */
166
+ hasNativeRegistration(surface) {
167
+ return this.nativeRegistered.has(surface);
168
+ }
148
169
  /** The curated, active memories — the knowledge the pull channels publish. */
149
170
  curatedRows() {
150
171
  return this.store
@@ -200,37 +221,48 @@ export class Materializer {
200
221
  return targets;
201
222
  }
202
223
  /**
203
- * Regenerate every bundle through the ArtifactWriter (plan + apply).
204
- * The only call site of `apply()` outside `kevin_approve` D6-01's
205
- * single write FUNCTION with two constrained targets: `kevin_approve`
206
- * reaches `agents_md_path`, this module reaches `~/.opencode-kevin`
207
- * only (D6-07; enforced by K6-020).
224
+ * Regenerate every bundle through the ArtifactWriter (write). This is
225
+ * a call site of `write()` the single write FUNCTION with two
226
+ * constrained targets: `kevin_approve` reaches `agents_md_path`, this
227
+ * module reaches `~/.opencode-kevin` only (D6-07; enforced by K6-020).
228
+ *
229
+ * v0.9.0 (K9-016 / plan §5.4, D9-10) — the guard: a surface registered
230
+ * natively by `attachNative()` is skipped here for that surface only.
231
+ * Both active would put the curated skill in front of the model twice
232
+ * from two sources that can disagree; neither active would silently
233
+ * remove the feature on hosts that gained the subpath.
208
234
  */
209
235
  materialize(writer) {
210
236
  const pending = [];
211
237
  const rows = this.curatedRows();
212
238
  const skillBody = renderRows(rows);
213
- if (skillBody !== "") {
239
+ if (skillBody !== "" && !this.nativeRegistered.has("skill")) {
214
240
  pending.push({
215
241
  topic: SKILL_TOPIC,
216
242
  path: join(this.root, "skills", "project-knowledge.md"),
217
243
  body: skillBody,
218
244
  });
219
245
  }
220
- for (const group of this.groupByTopic(rows)) {
221
- const body = renderRows(group.rows);
222
- if (body === "")
223
- continue;
224
- pending.push({
225
- topic: group.topic,
226
- path: join(this.root, "refs", `${group.topic}.md`),
227
- body,
228
- });
246
+ if (!this.nativeRegistered.has("reference")) {
247
+ for (const group of this.groupByTopic(rows)) {
248
+ const body = renderRows(group.rows);
249
+ if (body === "")
250
+ continue;
251
+ pending.push({
252
+ topic: group.topic,
253
+ path: join(this.root, "refs", `${group.topic}.md`),
254
+ body,
255
+ });
256
+ }
229
257
  }
230
258
  return pending.map((bundle) => ({
231
259
  topic: bundle.topic,
232
260
  path: bundle.path,
233
- outcome: writer.apply(writer.plan(bundle.path, bundle.body)),
261
+ outcome: writer.write({
262
+ path: bundle.path,
263
+ mode: "markers",
264
+ content: bundle.body,
265
+ }),
234
266
  }));
235
267
  }
236
268
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Materializer.js","sourceRoot":"","sources":["../../plugin/Materializer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Materializer.js","sourceRoot":"","sources":["../../plugin/Materializer.ts"],"names":[],"mappings":"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"}
@@ -57,11 +57,23 @@ export interface Memory {
57
57
  /** v0.7.0 (K7-008 / plan §5.3, D7-03) — de-ranking penalty in
58
58
  * [0, 0.5], clamped by applyTruthPenalty. Multiplies rankScore as
59
59
  * `(1 - truthPenalty)`. Defaults to 0. */
60
- truthPenalty?: number;
61
- /** v0.7.0 (K7-008 / plan §5.3) — when the memory was first contradicted
62
- * (ISO/sqlite time). Null when never contradicted. */
60
+ truthPenalty?: number | null;
61
+ /** v0.7.0 (K7-008 / plan §5.3, D7-03) — first contradiction timestamp. */
63
62
  contradictedAt?: string | null;
63
+ /** v0.8.0 (K8-018 / plan §5.2) — the memory's layer marker: 'local'
64
+ * (default) or 'shared'. */
65
+ layer?: string | null;
64
66
  }
67
+ /**
68
+ * v0.8.0 (K8-018 / plan §5.2) — outcome of `update()`. A refusal is a
69
+ * typed value, never a throw and never a silent no-op.
70
+ */
71
+ export type MemoryUpdateResult = {
72
+ ok: true;
73
+ } | {
74
+ ok: false;
75
+ refused: readonly string[];
76
+ };
65
77
  export interface SaveInput {
66
78
  type: MemoryType;
67
79
  content: string;
@@ -149,15 +161,19 @@ export interface GetRelevantInput {
149
161
  now?: Date;
150
162
  }
151
163
  export declare const DATE_NOW = "2099-01-01T00:00:00.000Z";
164
+ export declare function hasRepoIdColumn(store: Store): boolean;
152
165
  export declare class MemoryService {
153
166
  private readonly metrics;
154
- constructor(store: Store, metrics?: Metrics | null);
167
+ constructor(store: Store, metrics?: Metrics | null, repoId?: string | null);
155
168
  private store;
169
+ private repoId;
170
+ setRepoId(repoId: string | null): void;
156
171
  private hasRecurrenceColumn;
157
172
  private _hasRecurrenceColumn;
158
173
  private hasIgnoredColumn;
159
174
  private hasCuratedColumn;
160
175
  private hasTruthColumns;
176
+ private hasRepoIdColumn;
161
177
  save(input: SaveInput): string;
162
178
  /**
163
179
  * v0.6.0 (K6-011 / plan §5.4) — mark memories as curated. Batch in a
@@ -174,7 +190,20 @@ export declare class MemoryService {
174
190
  * (most-recurred fingerprint → its pattern memory).
175
191
  */
176
192
  getByFingerprint(fingerprint: string, type?: MemoryType): Memory | null;
177
- update(id: string, fields: Partial<Memory>): void;
193
+ /**
194
+ * v0.8.0 (K8-018 / plan §5.2) — result of a memory mutation.
195
+ * `refused` lists the shared-layer columns that were not written.
196
+ */
197
+ update(id: string, fields: Partial<Memory>): MemoryUpdateResult;
198
+ /**
199
+ * v0.8.0 (K8-018 / plan §5.2) — count a refused shared-row write. The
200
+ * key lives OUTSIDE the frozen METRIC_KEYS ladder (K7-004), following
201
+ * the v0.6.0 `incrRegistered` precedent: it persists to the same
202
+ * `kevin_metrics` table and is read back by `kevin_audit` as a bare SQL
203
+ * scalar, so the counter survives across processes without growing the
204
+ * 39-key ladder.
205
+ */
206
+ private countSharedRefusal;
178
207
  /**
179
208
  * v0.7.0 (K7-008 / plan §5.3, D7-03) — apply a bounded truth penalty.
180
209
  * Clamps `penalty` to [0, 0.5], writes `truth_penalty` and `contradicted_at`,