opencode-swarm 7.107.3 → 7.107.4

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 (61) hide show
  1. package/.opencode/skills/consult/SKILL.md +10 -0
  2. package/.opencode/skills/council/SKILL.md +10 -0
  3. package/.opencode/skills/engineering-conventions/SKILL.md +20 -0
  4. package/README.md +2 -2
  5. package/dist/agents/agent-output-schema.d.ts +1 -1
  6. package/dist/cli/{config-doctor-cntnpyvj.js → config-doctor-kdq3vae4.js} +3 -2
  7. package/dist/cli/{curator-llm-factory-x9tk7e6m.js → curator-llm-factory-abw56kg0.js} +16 -11
  8. package/dist/cli/{curator-1nr4qszq.js → curator-rb05fjjk.js} +16 -11
  9. package/dist/cli/{dispatch-e4ejrsz8.js → dispatch-anmxxhen.js} +56 -13
  10. package/dist/cli/{evidence-summary-service-9r28ds8t.js → evidence-summary-service-nwdfnbz1.js} +2 -2
  11. package/dist/cli/gate-evidence-ywys9vfs.js +1 -1
  12. package/dist/cli/{guardrail-explain-etdrhd4d.js → guardrail-explain-dayy7zw4.js} +17 -12
  13. package/dist/cli/{guardrail-log-2rns4g6d.js → guardrail-log-fjypsmek.js} +4 -3
  14. package/dist/cli/{hive-promoter-j4e6rfa6.js → hive-promoter-34bdmw1w.js} +16 -11
  15. package/dist/cli/{index-502f6np6.js → index-19vxtwa6.js} +21 -16
  16. package/dist/cli/{index-tgtmbf3r.js → index-4vsgp5a8.js} +1 -1
  17. package/dist/cli/index-bfwt3abw.js +14 -0
  18. package/dist/cli/{index-9wstcavp.js → index-bpgqbwmf.js} +115 -1019
  19. package/dist/cli/index-bq8kd9r9.js +199 -0
  20. package/dist/cli/index-dfdg4ws5.js +741 -0
  21. package/dist/cli/{index-w15984gg.js → index-f45hbd5x.js} +2 -2
  22. package/dist/cli/{index-cyzzdbvw.js → index-gyzxeza3.js} +354 -116
  23. package/dist/cli/index-kxm3bdjh.js +631 -0
  24. package/dist/cli/index-n1sptn1w.js +147 -0
  25. package/dist/cli/{index-2560cctg.js → index-pchpahdf.js} +11 -0
  26. package/dist/cli/{index-esg1554h.js → index-wvxhynxq.js} +1 -1
  27. package/dist/cli/{index-8w4d325g.js → index-xg18az81.js} +61 -22
  28. package/dist/cli/{index-f7nma02k.js → index-xmarctsf.js} +137 -175
  29. package/dist/cli/{index-m1xjr58n.js → index-zej8cy0j.js} +1 -1
  30. package/dist/cli/index.js +17 -12
  31. package/dist/cli/knowledge-escalator-3sgwrgy9.js +32 -0
  32. package/dist/cli/knowledge-events-kfc6xmkw.js +62 -0
  33. package/dist/cli/{knowledge-store-tsa8ezka.js → knowledge-store-kyacem71.js} +3 -1
  34. package/dist/cli/knowledge-validator-ez3ws8ef.js +57 -0
  35. package/dist/cli/{pr-subscriptions-0dpn4epk.js → pr-subscriptions-bpvazmsw.js} +2 -2
  36. package/dist/cli/{schema-vw2ffhe9.js → schema-x0ekqzvs.js} +2 -1
  37. package/dist/cli/{skill-generator-y6mmq8n5.js → skill-generator-x83re96d.js} +6 -2
  38. package/dist/commands/knowledge.d.ts +5 -1
  39. package/dist/commands/registry.d.ts +2 -2
  40. package/dist/config/evidence-schema.d.ts +9 -9
  41. package/dist/config/schema.d.ts +42 -12
  42. package/dist/hooks/knowledge-curator.d.ts +27 -0
  43. package/dist/hooks/knowledge-escalator.d.ts +16 -0
  44. package/dist/hooks/knowledge-events.d.ts +11 -0
  45. package/dist/hooks/knowledge-reader.d.ts +0 -17
  46. package/dist/hooks/knowledge-store.d.ts +16 -1
  47. package/dist/hooks/knowledge-types.d.ts +85 -0
  48. package/dist/hooks/knowledge-validator.d.ts +15 -0
  49. package/dist/hooks/skill-usage-log.d.ts +3 -0
  50. package/dist/index.js +307 -305
  51. package/dist/memory/consolidation.d.ts +1 -1
  52. package/dist/memory/schema.d.ts +4 -4
  53. package/dist/sast/rules/rust.d.ts +6 -0
  54. package/dist/tools/knowledge-archive.d.ts +6 -2
  55. package/dist/tools/lint.d.ts +2 -2
  56. package/dist/tools/secretscan.d.ts +16 -0
  57. package/dist/tools/test-runner.d.ts +1 -1
  58. package/package.json +1 -1
  59. package/dist/cli/{index-hkpw4wwa.js → index-4r5z8sgw.js} +3 -3
  60. package/dist/cli/{index-kzfkggjx.js → index-9b7a6agd.js} +3 -3
  61. package/dist/cli/{pending-delegations-ws51m1e1.js → pending-delegations-vfnpm8zt.js} +3 -3
@@ -0,0 +1,631 @@
1
+ // @bun
2
+ import {
3
+ resolveKnowledgeStoreDir
4
+ } from "./index-n1sptn1w.js";
5
+ import {
6
+ atomicWriteFile
7
+ } from "./index-9b7qp18e.js";
8
+ import {
9
+ init_logger,
10
+ warn
11
+ } from "./index-zgwm4ryv.js";
12
+ import {
13
+ require_proper_lockfile
14
+ } from "./index-3naa2ajc.js";
15
+ import {
16
+ __require,
17
+ __toESM
18
+ } from "./index-a76rekgs.js";
19
+
20
+ // src/hooks/knowledge-events.ts
21
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
22
+ import { randomUUID } from "crypto";
23
+ import { existsSync } from "fs";
24
+ import { appendFile, mkdir, readFile, stat } from "fs/promises";
25
+ import * as os from "os";
26
+ import * as path from "path";
27
+ init_logger();
28
+ var KNOWLEDGE_EVENT_SCHEMA_VERSION = 1;
29
+ var MAX_EVENT_LOG_ENTRIES = 5000;
30
+ var counterRollupCache = new Map;
31
+ var MAX_COUNTER_ROLLUP_CACHE_DIRS = 32;
32
+ var RECEIPT_EVENT_TYPES = new Set([
33
+ "acknowledged",
34
+ "applied",
35
+ "ignored",
36
+ "contradicted",
37
+ "violated",
38
+ "n_a",
39
+ "override"
40
+ ]);
41
+ function resolveKnowledgeEventsPath(directory) {
42
+ return path.join(resolveKnowledgeStoreDir(directory), "knowledge-events.jsonl");
43
+ }
44
+ function resolveKnowledgeCounterBaselinePath(directory) {
45
+ return path.join(resolveKnowledgeStoreDir(directory), "knowledge-counter-baseline.json");
46
+ }
47
+ function resolveHiveEventsPath() {
48
+ const platform = process.platform;
49
+ const home = process.env.HOME || os.homedir();
50
+ let dir;
51
+ if (platform === "win32") {
52
+ dir = path.join(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"), "opencode-swarm", "Data");
53
+ } else if (platform === "darwin") {
54
+ dir = path.join(home, "Library", "Application Support", "opencode-swarm");
55
+ } else {
56
+ dir = path.join(process.env.XDG_DATA_HOME || path.join(home, ".local", "share"), "opencode-swarm");
57
+ }
58
+ return path.join(dir, "shared-knowledge-events.jsonl");
59
+ }
60
+ function resolveLegacyApplicationLogPath(directory) {
61
+ return path.join(resolveKnowledgeStoreDir(directory), "knowledge-application.jsonl");
62
+ }
63
+ function newTraceId() {
64
+ return randomUUID();
65
+ }
66
+ function newEventId() {
67
+ return randomUUID();
68
+ }
69
+ function withDefaults(event) {
70
+ return {
71
+ schema_version: KNOWLEDGE_EVENT_SCHEMA_VERSION,
72
+ ...event,
73
+ event_id: event.event_id || newEventId(),
74
+ timestamp: event.timestamp || new Date().toISOString()
75
+ };
76
+ }
77
+ async function appendKnowledgeEvent(directory, event) {
78
+ const populated = withDefaults(event);
79
+ const filePath = resolveKnowledgeEventsPath(directory);
80
+ const dirPath = path.dirname(filePath);
81
+ await mkdir(dirPath, { recursive: true });
82
+ let release;
83
+ try {
84
+ release = await import_proper_lockfile.default.lock(dirPath, {
85
+ retries: { retries: 200, minTimeout: 10, maxTimeout: 100 }
86
+ });
87
+ await appendFile(filePath, `${JSON.stringify(populated)}
88
+ `, "utf-8");
89
+ try {
90
+ const content = await readFile(filePath, "utf-8");
91
+ const lines = content.split(`
92
+ `).filter((line) => line.trim().length > 0);
93
+ if (lines.length > MAX_EVENT_LOG_ENTRIES) {
94
+ const evicted = lines.slice(0, lines.length - MAX_EVENT_LOG_ENTRIES);
95
+ const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
96
+ await foldEvictedEventsIntoBaseline(directory, evicted, filePath);
97
+ await atomicWriteFile(filePath, `${trimmed.join(`
98
+ `)}
99
+ `);
100
+ }
101
+ } catch (err) {
102
+ warn(`[knowledge-events] local cap trim failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
103
+ }
104
+ } finally {
105
+ if (release)
106
+ await release().catch(() => {});
107
+ }
108
+ return populated;
109
+ }
110
+ async function recordKnowledgeEvent(directory, event) {
111
+ try {
112
+ return await appendKnowledgeEvent(directory, event);
113
+ } catch (err) {
114
+ warn(`[knowledge-events] recordKnowledgeEvent failed: ${err instanceof Error ? err.message : String(err)}`);
115
+ return null;
116
+ }
117
+ }
118
+ async function appendHiveKnowledgeEvent(event) {
119
+ const populated = withDefaults(event);
120
+ const filePath = resolveHiveEventsPath();
121
+ const dirPath = path.dirname(filePath);
122
+ await mkdir(dirPath, { recursive: true });
123
+ let release;
124
+ try {
125
+ release = await import_proper_lockfile.default.lock(dirPath, {
126
+ retries: { retries: 200, minTimeout: 10, maxTimeout: 100 }
127
+ });
128
+ await appendFile(filePath, `${JSON.stringify(populated)}
129
+ `, "utf-8");
130
+ try {
131
+ const content = await readFile(filePath, "utf-8");
132
+ const lines = content.split(`
133
+ `).filter((line) => line.trim().length > 0);
134
+ if (lines.length > MAX_EVENT_LOG_ENTRIES) {
135
+ const trimmed = lines.slice(lines.length - MAX_EVENT_LOG_ENTRIES);
136
+ await atomicWriteFile(filePath, `${trimmed.join(`
137
+ `)}
138
+ `);
139
+ }
140
+ } catch (err) {
141
+ warn(`[knowledge-events] hive cap trim failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
142
+ }
143
+ } finally {
144
+ if (release)
145
+ await release().catch(() => {});
146
+ }
147
+ return populated;
148
+ }
149
+ async function recordHiveKnowledgeEvent(event) {
150
+ try {
151
+ return await appendHiveKnowledgeEvent(event);
152
+ } catch (err) {
153
+ warn(`[knowledge-events] recordHiveKnowledgeEvent failed: ${err instanceof Error ? err.message : String(err)}`);
154
+ return null;
155
+ }
156
+ }
157
+ async function readKnowledgeEvents(directory, maxEvents) {
158
+ const filePath = resolveKnowledgeEventsPath(directory);
159
+ if (!existsSync(filePath))
160
+ return [];
161
+ const content = await readFile(filePath, "utf-8");
162
+ const out = [];
163
+ const max = maxEvents !== undefined && maxEvents > 0 ? maxEvents : Infinity;
164
+ for (const line of content.split(`
165
+ `)) {
166
+ if (out.length >= max)
167
+ break;
168
+ const trimmed = line.trim();
169
+ if (!trimmed)
170
+ continue;
171
+ try {
172
+ out.push(JSON.parse(trimmed));
173
+ } catch {
174
+ warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
175
+ }
176
+ }
177
+ return out;
178
+ }
179
+ async function readHiveKnowledgeEvents() {
180
+ const filePath = resolveHiveEventsPath();
181
+ if (!existsSync(filePath))
182
+ return [];
183
+ const content = await readFile(filePath, "utf-8");
184
+ return parseEventLines(content.split(`
185
+ `), filePath);
186
+ }
187
+ async function readLegacyApplicationRecords(directory) {
188
+ const filePath = resolveLegacyApplicationLogPath(directory);
189
+ if (!existsSync(filePath))
190
+ return [];
191
+ const content = await readFile(filePath, "utf-8");
192
+ const out = [];
193
+ for (const line of content.split(`
194
+ `)) {
195
+ const trimmed = line.trim();
196
+ if (!trimmed)
197
+ continue;
198
+ try {
199
+ out.push(JSON.parse(trimmed));
200
+ } catch {
201
+ warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
202
+ }
203
+ }
204
+ return out;
205
+ }
206
+ var MAX_VIOLATION_TIMESTAMPS = 10;
207
+ function emptyRollup() {
208
+ return {
209
+ shown_count: 0,
210
+ acknowledged_count: 0,
211
+ applied_explicit_count: 0,
212
+ ignored_count: 0,
213
+ violated_count: 0,
214
+ contradicted_count: 0,
215
+ n_a_count: 0,
216
+ succeeded_after_shown_count: 0,
217
+ failed_after_shown_count: 0,
218
+ partial_after_shown_count: 0,
219
+ violation_timestamps: []
220
+ };
221
+ }
222
+ function cloneRollup(input) {
223
+ return {
224
+ ...emptyRollup(),
225
+ ...input,
226
+ violation_timestamps: [...input.violation_timestamps ?? []]
227
+ };
228
+ }
229
+ function cloneRollupMap(input) {
230
+ const out = new Map;
231
+ for (const [id, rollup] of input) {
232
+ out.set(id, cloneRollup(rollup));
233
+ }
234
+ return out;
235
+ }
236
+ function normalizeRollupTimestamps(rollup) {
237
+ if (rollup.violation_timestamps.length > 1) {
238
+ rollup.violation_timestamps.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
239
+ }
240
+ if (rollup.violation_timestamps.length > MAX_VIOLATION_TIMESTAMPS) {
241
+ rollup.violation_timestamps = rollup.violation_timestamps.slice(0, MAX_VIOLATION_TIMESTAMPS);
242
+ }
243
+ return rollup;
244
+ }
245
+ function mergeRollupInto(target, source) {
246
+ target.shown_count += source.shown_count ?? 0;
247
+ target.acknowledged_count += source.acknowledged_count ?? 0;
248
+ target.applied_explicit_count += source.applied_explicit_count ?? 0;
249
+ target.ignored_count += source.ignored_count ?? 0;
250
+ target.violated_count += source.violated_count ?? 0;
251
+ target.contradicted_count += source.contradicted_count ?? 0;
252
+ target.n_a_count += source.n_a_count ?? 0;
253
+ target.succeeded_after_shown_count += source.succeeded_after_shown_count ?? 0;
254
+ target.failed_after_shown_count += source.failed_after_shown_count ?? 0;
255
+ target.partial_after_shown_count += source.partial_after_shown_count ?? 0;
256
+ if (source.last_applied_at) {
257
+ target.last_applied_at = maxIso(target.last_applied_at, source.last_applied_at);
258
+ }
259
+ if (source.last_acknowledged_at) {
260
+ target.last_acknowledged_at = maxIso(target.last_acknowledged_at, source.last_acknowledged_at);
261
+ }
262
+ target.violation_timestamps.push(...source.violation_timestamps ?? []);
263
+ normalizeRollupTimestamps(target);
264
+ }
265
+ function get(map, id) {
266
+ let r = map.get(id);
267
+ if (!r) {
268
+ r = emptyRollup();
269
+ map.set(id, r);
270
+ }
271
+ return r;
272
+ }
273
+ function maxIso(current, candidate) {
274
+ if (!current)
275
+ return candidate;
276
+ return candidate > current ? candidate : current;
277
+ }
278
+ async function readCounterBaseline(directory) {
279
+ const filePath = resolveKnowledgeCounterBaselinePath(directory);
280
+ if (!existsSync(filePath))
281
+ return new Map;
282
+ let raw;
283
+ try {
284
+ raw = JSON.parse(await readFile(filePath, "utf-8"));
285
+ } catch (err) {
286
+ warn(`[knowledge-events] corrupted counter baseline at ${filePath}; ignoring folded baseline and replaying live events only: ${err instanceof Error ? err.message : String(err)}`);
287
+ return new Map;
288
+ }
289
+ const map = new Map;
290
+ for (const [id, rollup] of Object.entries(raw)) {
291
+ map.set(id, normalizeRollupTimestamps(cloneRollup(rollup)));
292
+ }
293
+ return map;
294
+ }
295
+ async function writeCounterBaseline(directory, baseline) {
296
+ const filePath = resolveKnowledgeCounterBaselinePath(directory);
297
+ const out = {};
298
+ for (const [id, rollup] of [...baseline.entries()].sort(([a], [b]) => a.localeCompare(b))) {
299
+ out[id] = normalizeRollupTimestamps(cloneRollup(rollup));
300
+ }
301
+ await atomicWriteFile(filePath, `${JSON.stringify(out, null, 2)}
302
+ `);
303
+ }
304
+ async function statCacheKey(filePath) {
305
+ try {
306
+ const fileStat = await stat(filePath);
307
+ return `${fileStat.mtimeMs}:${fileStat.ctimeMs}:${fileStat.size}`;
308
+ } catch (err) {
309
+ if (err?.code === "ENOENT")
310
+ return "missing";
311
+ throw err;
312
+ }
313
+ }
314
+ async function buildCounterRollupCacheKey(directory) {
315
+ const [eventsKey, legacyKey, baselineKey] = await Promise.all([
316
+ statCacheKey(resolveKnowledgeEventsPath(directory)),
317
+ statCacheKey(resolveLegacyApplicationLogPath(directory)),
318
+ statCacheKey(resolveKnowledgeCounterBaselinePath(directory))
319
+ ]);
320
+ return `${eventsKey}|${legacyKey}|${baselineKey}`;
321
+ }
322
+ function setCounterRollupCache(directory, key, rollups) {
323
+ if (counterRollupCache.has(directory)) {
324
+ counterRollupCache.delete(directory);
325
+ }
326
+ counterRollupCache.set(directory, {
327
+ key,
328
+ rollups: cloneRollupMap(rollups)
329
+ });
330
+ while (counterRollupCache.size > MAX_COUNTER_ROLLUP_CACHE_DIRS) {
331
+ const oldestKey = counterRollupCache.keys().next().value;
332
+ if (oldestKey === undefined)
333
+ break;
334
+ counterRollupCache.delete(oldestKey);
335
+ }
336
+ }
337
+ function parseEventLines(lines, filePath) {
338
+ const out = [];
339
+ for (const line of lines) {
340
+ const trimmed = line.trim();
341
+ if (!trimmed)
342
+ continue;
343
+ try {
344
+ out.push(JSON.parse(trimmed));
345
+ } catch {
346
+ warn(`[knowledge-events] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
347
+ }
348
+ }
349
+ return out;
350
+ }
351
+ async function foldEvictedEventsIntoBaseline(directory, evictedLines, filePath) {
352
+ const evictedEvents = parseEventLines(evictedLines, filePath);
353
+ if (evictedEvents.length === 0)
354
+ return;
355
+ const baseline = await readCounterBaseline(directory);
356
+ for (const [id, rollup] of recomputeCounters(evictedEvents)) {
357
+ mergeRollupInto(get(baseline, id), rollup);
358
+ }
359
+ await writeCounterBaseline(directory, baseline);
360
+ }
361
+ function recomputeCounters(events, legacyRecords = [], baseline = new Map) {
362
+ const map = new Map;
363
+ const retrievedIds = new Set;
364
+ for (const [id, rollup] of baseline) {
365
+ map.set(id, cloneRollup(rollup));
366
+ if ((rollup.shown_count ?? 0) > 0)
367
+ retrievedIds.add(id);
368
+ }
369
+ for (const e of events) {
370
+ switch (e.type) {
371
+ case "retrieved": {
372
+ for (const id of e.result_ids) {
373
+ retrievedIds.add(id);
374
+ get(map, id).shown_count += 1;
375
+ }
376
+ break;
377
+ }
378
+ case "acknowledged": {
379
+ const r = get(map, e.knowledge_id);
380
+ r.acknowledged_count += 1;
381
+ r.last_acknowledged_at = maxIso(r.last_acknowledged_at, e.timestamp);
382
+ break;
383
+ }
384
+ case "applied": {
385
+ const r = get(map, e.knowledge_id);
386
+ r.applied_explicit_count += 1;
387
+ r.last_applied_at = maxIso(r.last_applied_at, e.timestamp);
388
+ break;
389
+ }
390
+ case "ignored":
391
+ get(map, e.knowledge_id).ignored_count += 1;
392
+ break;
393
+ case "violated": {
394
+ const r = get(map, e.knowledge_id);
395
+ r.violated_count += 1;
396
+ r.violation_timestamps.push(e.timestamp);
397
+ break;
398
+ }
399
+ case "contradicted":
400
+ get(map, e.knowledge_id).contradicted_count += 1;
401
+ break;
402
+ case "n_a":
403
+ get(map, e.knowledge_id).n_a_count += 1;
404
+ break;
405
+ case "outcome": {
406
+ if (!e.knowledge_id)
407
+ break;
408
+ const r = get(map, e.knowledge_id);
409
+ if (e.outcome === "success")
410
+ r.succeeded_after_shown_count += 1;
411
+ else if (e.outcome === "failure")
412
+ r.failed_after_shown_count += 1;
413
+ else if (e.outcome === "partial")
414
+ r.partial_after_shown_count += 1;
415
+ break;
416
+ }
417
+ }
418
+ }
419
+ for (const rec of legacyRecords) {
420
+ const r = get(map, rec.knowledgeId);
421
+ switch (rec.result) {
422
+ case "shown":
423
+ if (!retrievedIds.has(rec.knowledgeId))
424
+ r.shown_count += 1;
425
+ break;
426
+ case "acknowledged":
427
+ r.acknowledged_count += 1;
428
+ r.last_acknowledged_at = maxIso(r.last_acknowledged_at, rec.timestamp);
429
+ break;
430
+ case "applied":
431
+ r.applied_explicit_count += 1;
432
+ r.last_applied_at = maxIso(r.last_applied_at, rec.timestamp);
433
+ break;
434
+ case "ignored":
435
+ r.ignored_count += 1;
436
+ break;
437
+ case "violated":
438
+ r.violated_count += 1;
439
+ r.violation_timestamps.push(rec.timestamp);
440
+ break;
441
+ }
442
+ }
443
+ for (const r of map.values()) {
444
+ normalizeRollupTimestamps(r);
445
+ }
446
+ return map;
447
+ }
448
+ function countViolationsInWindow(timestamps, windowDays, now = new Date) {
449
+ const cutoff = now.getTime() - windowDays * 24 * 60 * 60 * 1000;
450
+ let count = 0;
451
+ for (const ts of timestamps) {
452
+ const t = Date.parse(ts);
453
+ if (!Number.isNaN(t) && t >= cutoff)
454
+ count += 1;
455
+ }
456
+ return count;
457
+ }
458
+ async function countEntryViolationsInWindow(directory, entryId, windowDays, now = new Date) {
459
+ try {
460
+ const cutoff = now.getTime() - windowDays * 24 * 60 * 60 * 1000;
461
+ const [events, legacyRecords] = await Promise.all([
462
+ readKnowledgeEvents(directory),
463
+ readLegacyApplicationRecords(directory)
464
+ ]);
465
+ let count = 0;
466
+ for (const e of events) {
467
+ if (e.type !== "violated" || e.knowledge_id !== entryId)
468
+ continue;
469
+ const t = Date.parse(e.timestamp);
470
+ if (!Number.isNaN(t) && t >= cutoff)
471
+ count += 1;
472
+ }
473
+ for (const rec of legacyRecords) {
474
+ if (rec.result !== "violated" || rec.knowledgeId !== entryId)
475
+ continue;
476
+ const t = Date.parse(rec.timestamp);
477
+ if (!Number.isNaN(t) && t >= cutoff)
478
+ count += 1;
479
+ }
480
+ return count;
481
+ } catch {
482
+ return 0;
483
+ }
484
+ }
485
+ async function countEntryContradictionsInWindow(directory, entryId, windowDays, now = new Date) {
486
+ try {
487
+ const cutoff = now.getTime() - windowDays * 24 * 60 * 60 * 1000;
488
+ const events = await readKnowledgeEvents(directory);
489
+ let count = 0;
490
+ for (const e of events) {
491
+ if (e.type !== "contradicted" || e.knowledge_id !== entryId)
492
+ continue;
493
+ const t = Date.parse(e.timestamp);
494
+ if (!Number.isNaN(t) && t >= cutoff)
495
+ count += 1;
496
+ }
497
+ return count;
498
+ } catch {
499
+ return 0;
500
+ }
501
+ }
502
+ async function readKnowledgeCounterRollups(directory) {
503
+ try {
504
+ const cacheKey = await buildCounterRollupCacheKey(directory);
505
+ const cached = counterRollupCache.get(directory);
506
+ if (cached?.key === cacheKey) {
507
+ counterRollupCache.delete(directory);
508
+ counterRollupCache.set(directory, cached);
509
+ return cloneRollupMap(cached.rollups);
510
+ }
511
+ const [events, legacyRecords, baseline] = await Promise.all([
512
+ readKnowledgeEvents(directory),
513
+ readLegacyApplicationRecords(directory),
514
+ readCounterBaseline(directory)
515
+ ]);
516
+ const rollups = recomputeCounters(events, legacyRecords, baseline);
517
+ setCounterRollupCache(directory, cacheKey, rollups);
518
+ return cloneRollupMap(rollups);
519
+ } catch (err) {
520
+ warn(`[knowledge-events] readKnowledgeCounterRollups failed: ${err instanceof Error ? err.message : String(err)}`);
521
+ return new Map;
522
+ }
523
+ }
524
+ function effectiveRetrievalOutcomes(stored, rollup) {
525
+ const base = stored ?? {
526
+ applied_count: 0,
527
+ succeeded_after_count: 0,
528
+ failed_after_count: 0
529
+ };
530
+ if (!rollup)
531
+ return base;
532
+ const { n_a_count: _na, ...rollupWithoutNa } = rollup;
533
+ return {
534
+ ...base,
535
+ ...rollupWithoutNa,
536
+ succeeded_after_shown_count: (base.succeeded_after_shown_count ?? 0) + (rollup.succeeded_after_shown_count ?? 0),
537
+ failed_after_shown_count: (base.failed_after_shown_count ?? 0) + (rollup.failed_after_shown_count ?? 0)
538
+ };
539
+ }
540
+ var VERDICT_CONFIDENCE_BOOST = 0.03;
541
+ var VERDICT_CONFIDENCE_DECAY = 0.05;
542
+ async function applyKnowledgeVerdictFeedback(directory, options) {
543
+ try {
544
+ const events = await readKnowledgeEvents(directory);
545
+ const markerIndex = options?.sinceTimestamp && options.sinceEventId ? events.findIndex((e) => e.timestamp === options.sinceTimestamp && e.event_id === options.sinceEventId) : -1;
546
+ const actionable = events.filter((e, index) => {
547
+ if (e.type !== "applied" && e.type !== "violated" && e.type !== "ignored") {
548
+ return false;
549
+ }
550
+ if (options?.sinceTimestamp && e.timestamp < options.sinceTimestamp) {
551
+ return false;
552
+ }
553
+ if (options?.sinceTimestamp && e.timestamp === options.sinceTimestamp) {
554
+ if (!options.sinceEventId) {
555
+ return false;
556
+ }
557
+ if (markerIndex < 0) {
558
+ return false;
559
+ }
560
+ return index > markerIndex;
561
+ }
562
+ return true;
563
+ });
564
+ if (actionable.length === 0) {
565
+ return { processed: 0, bumps: 0 };
566
+ }
567
+ const groups = new Map;
568
+ let lastProcessedTimestamp;
569
+ let lastProcessedEventId;
570
+ for (const event of actionable) {
571
+ if (typeof event.timestamp === "string" && (!lastProcessedTimestamp || event.timestamp >= lastProcessedTimestamp)) {
572
+ lastProcessedTimestamp = event.timestamp;
573
+ lastProcessedEventId = event.event_id;
574
+ }
575
+ const kid = event.knowledge_id;
576
+ if (!kid)
577
+ continue;
578
+ const g = groups.get(kid) ?? { applied: 0, violated: 0, ignored: 0 };
579
+ if (event.type === "applied")
580
+ g.applied++;
581
+ else if (event.type === "violated")
582
+ g.violated++;
583
+ else if (event.type === "ignored")
584
+ g.ignored++;
585
+ groups.set(kid, g);
586
+ }
587
+ const deltas = [];
588
+ for (const [id, counts] of groups) {
589
+ const positives = counts.applied;
590
+ const negatives = counts.violated + counts.ignored;
591
+ if (positives === 0 && negatives === 0)
592
+ continue;
593
+ const delta = positives > negatives ? VERDICT_CONFIDENCE_BOOST : -VERDICT_CONFIDENCE_DECAY;
594
+ deltas.push({ id, delta });
595
+ }
596
+ if (deltas.length > 0) {
597
+ const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-kyacem71.js");
598
+ await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
599
+ }
600
+ return {
601
+ processed: groups.size,
602
+ bumps: deltas.length,
603
+ lastProcessedTimestamp,
604
+ lastProcessedEventId
605
+ };
606
+ } catch (err) {
607
+ warn(`[knowledge-events] applyKnowledgeVerdictFeedback failed (fail-open): ${err instanceof Error ? err.message : String(err)}`);
608
+ return { processed: 0, bumps: 0 };
609
+ }
610
+ }
611
+ var _internals = {
612
+ resolveKnowledgeEventsPath,
613
+ resolveKnowledgeCounterBaselinePath,
614
+ appendKnowledgeEvent,
615
+ recordKnowledgeEvent,
616
+ readKnowledgeEvents,
617
+ readCounterBaseline,
618
+ readLegacyApplicationRecords,
619
+ readKnowledgeCounterRollups,
620
+ effectiveRetrievalOutcomes,
621
+ recomputeCounters,
622
+ applyKnowledgeVerdictFeedback,
623
+ newTraceId,
624
+ newEventId,
625
+ resolveHiveEventsPath,
626
+ appendHiveKnowledgeEvent,
627
+ recordHiveKnowledgeEvent,
628
+ readHiveKnowledgeEvents
629
+ };
630
+
631
+ export { KNOWLEDGE_EVENT_SCHEMA_VERSION, MAX_EVENT_LOG_ENTRIES, RECEIPT_EVENT_TYPES, resolveKnowledgeEventsPath, resolveKnowledgeCounterBaselinePath, resolveHiveEventsPath, resolveLegacyApplicationLogPath, newTraceId, newEventId, appendKnowledgeEvent, recordKnowledgeEvent, appendHiveKnowledgeEvent, recordHiveKnowledgeEvent, readKnowledgeEvents, readHiveKnowledgeEvents, readLegacyApplicationRecords, MAX_VIOLATION_TIMESTAMPS, recomputeCounters, countViolationsInWindow, countEntryViolationsInWindow, countEntryContradictionsInWindow, readKnowledgeCounterRollups, effectiveRetrievalOutcomes, applyKnowledgeVerdictFeedback, _internals };