@kybernesis/brain-core 0.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.
Files changed (129) hide show
  1. package/dist/claude-call.d.ts +37 -0
  2. package/dist/claude-call.d.ts.map +1 -0
  3. package/dist/claude-call.js +55 -0
  4. package/dist/claude-call.js.map +1 -0
  5. package/dist/entity-graph.d.ts +79 -0
  6. package/dist/entity-graph.d.ts.map +1 -0
  7. package/dist/entity-graph.js +611 -0
  8. package/dist/entity-graph.js.map +1 -0
  9. package/dist/fact-contradiction.d.ts +25 -0
  10. package/dist/fact-contradiction.d.ts.map +1 -0
  11. package/dist/fact-contradiction.js +109 -0
  12. package/dist/fact-contradiction.js.map +1 -0
  13. package/dist/fact-extractor.d.ts +26 -0
  14. package/dist/fact-extractor.d.ts.map +1 -0
  15. package/dist/fact-extractor.js +98 -0
  16. package/dist/fact-extractor.js.map +1 -0
  17. package/dist/fact-retrieval.d.ts +51 -0
  18. package/dist/fact-retrieval.d.ts.map +1 -0
  19. package/dist/fact-retrieval.js +401 -0
  20. package/dist/fact-retrieval.js.map +1 -0
  21. package/dist/fact-store.d.ts +26 -0
  22. package/dist/fact-store.d.ts.map +1 -0
  23. package/dist/fact-store.js +181 -0
  24. package/dist/fact-store.js.map +1 -0
  25. package/dist/fact-temporal.d.ts +20 -0
  26. package/dist/fact-temporal.d.ts.map +1 -0
  27. package/dist/fact-temporal.js +79 -0
  28. package/dist/fact-temporal.js.map +1 -0
  29. package/dist/fts-sanitizer.d.ts +32 -0
  30. package/dist/fts-sanitizer.d.ts.map +1 -0
  31. package/dist/fts-sanitizer.js +61 -0
  32. package/dist/fts-sanitizer.js.map +1 -0
  33. package/dist/hybrid-search.d.ts +44 -0
  34. package/dist/hybrid-search.d.ts.map +1 -0
  35. package/dist/hybrid-search.js +410 -0
  36. package/dist/hybrid-search.js.map +1 -0
  37. package/dist/index.d.ts +33 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +19 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/ops.d.ts +28 -0
  42. package/dist/ops.d.ts.map +1 -0
  43. package/dist/ops.js +307 -0
  44. package/dist/ops.js.map +1 -0
  45. package/dist/queue.d.ts +13 -0
  46. package/dist/queue.d.ts.map +1 -0
  47. package/dist/queue.js +28 -0
  48. package/dist/queue.js.map +1 -0
  49. package/dist/relationship-extractor.d.ts +38 -0
  50. package/dist/relationship-extractor.d.ts.map +1 -0
  51. package/dist/relationship-extractor.js +119 -0
  52. package/dist/relationship-extractor.js.map +1 -0
  53. package/dist/sleep/config.d.ts +47 -0
  54. package/dist/sleep/config.d.ts.map +1 -0
  55. package/dist/sleep/config.js +46 -0
  56. package/dist/sleep/config.js.map +1 -0
  57. package/dist/sleep/db.d.ts +16 -0
  58. package/dist/sleep/db.d.ts.map +1 -0
  59. package/dist/sleep/db.js +114 -0
  60. package/dist/sleep/db.js.map +1 -0
  61. package/dist/sleep/index.d.ts +69 -0
  62. package/dist/sleep/index.d.ts.map +1 -0
  63. package/dist/sleep/index.js +99 -0
  64. package/dist/sleep/index.js.map +1 -0
  65. package/dist/sleep/steps/consolidate.d.ts +19 -0
  66. package/dist/sleep/steps/consolidate.d.ts.map +1 -0
  67. package/dist/sleep/steps/consolidate.js +74 -0
  68. package/dist/sleep/steps/consolidate.js.map +1 -0
  69. package/dist/sleep/steps/decay.d.ts +19 -0
  70. package/dist/sleep/steps/decay.d.ts.map +1 -0
  71. package/dist/sleep/steps/decay.js +121 -0
  72. package/dist/sleep/steps/decay.js.map +1 -0
  73. package/dist/sleep/steps/entity-hygiene.d.ts +29 -0
  74. package/dist/sleep/steps/entity-hygiene.d.ts.map +1 -0
  75. package/dist/sleep/steps/entity-hygiene.js +452 -0
  76. package/dist/sleep/steps/entity-hygiene.js.map +1 -0
  77. package/dist/sleep/steps/link.d.ts +20 -0
  78. package/dist/sleep/steps/link.d.ts.map +1 -0
  79. package/dist/sleep/steps/link.js +216 -0
  80. package/dist/sleep/steps/link.js.map +1 -0
  81. package/dist/sleep/steps/observe.d.ts +17 -0
  82. package/dist/sleep/steps/observe.d.ts.map +1 -0
  83. package/dist/sleep/steps/observe.js +192 -0
  84. package/dist/sleep/steps/observe.js.map +1 -0
  85. package/dist/sleep/steps/profile.d.ts +15 -0
  86. package/dist/sleep/steps/profile.d.ts.map +1 -0
  87. package/dist/sleep/steps/profile.js +26 -0
  88. package/dist/sleep/steps/profile.js.map +1 -0
  89. package/dist/sleep/steps/reasoning.d.ts +19 -0
  90. package/dist/sleep/steps/reasoning.d.ts.map +1 -0
  91. package/dist/sleep/steps/reasoning.js +173 -0
  92. package/dist/sleep/steps/reasoning.js.map +1 -0
  93. package/dist/sleep/steps/summarize.d.ts +21 -0
  94. package/dist/sleep/steps/summarize.d.ts.map +1 -0
  95. package/dist/sleep/steps/summarize.js +206 -0
  96. package/dist/sleep/steps/summarize.js.map +1 -0
  97. package/dist/sleep/steps/tag.d.ts +16 -0
  98. package/dist/sleep/steps/tag.d.ts.map +1 -0
  99. package/dist/sleep/steps/tag.js +84 -0
  100. package/dist/sleep/steps/tag.js.map +1 -0
  101. package/dist/sleep/steps/tier.d.ts +18 -0
  102. package/dist/sleep/steps/tier.d.ts.map +1 -0
  103. package/dist/sleep/steps/tier.js +112 -0
  104. package/dist/sleep/steps/tier.js.map +1 -0
  105. package/dist/sleep/utils/checkpoint.d.ts +11 -0
  106. package/dist/sleep/utils/checkpoint.d.ts.map +1 -0
  107. package/dist/sleep/utils/checkpoint.js +26 -0
  108. package/dist/sleep/utils/checkpoint.js.map +1 -0
  109. package/dist/sleep/utils/jaccard.d.ts +7 -0
  110. package/dist/sleep/utils/jaccard.d.ts.map +1 -0
  111. package/dist/sleep/utils/jaccard.js +19 -0
  112. package/dist/sleep/utils/jaccard.js.map +1 -0
  113. package/dist/store-conversation.d.ts +29 -0
  114. package/dist/store-conversation.d.ts.map +1 -0
  115. package/dist/store-conversation.js +227 -0
  116. package/dist/store-conversation.js.map +1 -0
  117. package/dist/timeline.d.ts +50 -0
  118. package/dist/timeline.d.ts.map +1 -0
  119. package/dist/timeline.js +389 -0
  120. package/dist/timeline.js.map +1 -0
  121. package/dist/user-profile.d.ts +30 -0
  122. package/dist/user-profile.d.ts.map +1 -0
  123. package/dist/user-profile.js +147 -0
  124. package/dist/user-profile.js.map +1 -0
  125. package/dist/vectors.d.ts +56 -0
  126. package/dist/vectors.d.ts.map +1 -0
  127. package/dist/vectors.js +132 -0
  128. package/dist/vectors.js.map +1 -0
  129. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/sleep/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0DH,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,CAAC;IAEtB,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,GAAG;IACnB,kBAAkB,EAAE,CAAC;IAErB,gBAAgB,EAAE,KAAK;IACvB,QAAQ,EAAE,GAAG;IAEb,oBAAoB,EAAE,IAAI;IAC1B,iBAAiB,EAAE,CAAC;IAEpB,oBAAoB,EAAE,IAAI;IAC1B,qBAAqB,EAAE,GAAG;IAC1B,iBAAiB,EAAE,IAAI;IACvB,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,CAAC;IACf,aAAa,EAAE,CAAC;IAEhB,YAAY,EAAE,CAAC;IAEf,uBAAuB,EAAE,CAAC;IAC1B,uBAAuB,EAAE,CAAC;IAE1B,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,KAAK;IAEtB,mBAAmB,EAAE,IAAI;IACzB,eAAe,EAAE,EAAE;IACnB,0BAA0B,EAAE,GAAG;IAC/B,eAAe,EAAE,EAAE;IAEnB,mBAAmB,EAAE,IAAI;IACzB,2BAA2B,EAAE,CAAC;IAC9B,yBAAyB,EAAE,GAAG;IAE9B,kBAAkB,EAAE,IAAI;IACxB,qBAAqB,EAAE,EAAE;IAEzB,oBAAoB,EAAE,IAAI;IAC1B,cAAc,EAAE,CAAC;IAEjB,4BAA4B,EAAE,IAAI;IAClC,4BAA4B,EAAE,CAAC;IAE/B,iBAAiB,EAAE,IAAI;IACvB,qBAAqB,EAAE,EAAE;IAEzB,eAAe,EAAE,IAAI;IACrB,kBAAkB,EAAE,CAAC;CACtB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Sleep DB schema initialization — port of KAD's sleep/db.ts.
3
+ *
4
+ * Library version uses the brain-storage-sqlite pool (getDb(t, 'sleep'))
5
+ * instead of opening its own Database directly. Schema is identical to KAD.
6
+ */
7
+ import type Database from 'better-sqlite3';
8
+ import type { TenantContext } from '@kybernesis/brain-contracts';
9
+ export declare function ensureSleepSchema(t: TenantContext): Database.Database;
10
+ export declare function resetSleepSchemaCache(slug?: string): void;
11
+ /**
12
+ * Reap orphaned sleep_runs that died with status='running'. Returns rows updated.
13
+ * Port of KAD's recoverStaleSleepRuns. Useful at daemon startup.
14
+ */
15
+ export declare function recoverStaleSleepRuns(t: TenantContext): number;
16
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/sleep/db.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAmFrE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAGzD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAW9D"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Sleep DB schema initialization — port of KAD's sleep/db.ts.
3
+ *
4
+ * Library version uses the brain-storage-sqlite pool (getDb(t, 'sleep'))
5
+ * instead of opening its own Database directly. Schema is identical to KAD.
6
+ */
7
+ import { getDb } from '@kybernesis/brain-storage-sqlite';
8
+ const initialized = new Set();
9
+ export function ensureSleepSchema(t) {
10
+ const db = getDb(t, 'sleep');
11
+ if (initialized.has(t.slug))
12
+ return db;
13
+ db.exec(`
14
+ CREATE TABLE IF NOT EXISTS sleep_runs (
15
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
16
+ started_at TEXT NOT NULL,
17
+ completed_at TEXT,
18
+ status TEXT NOT NULL DEFAULT 'running' CHECK(status IN ('running', 'completed', 'failed', 'paused')),
19
+ checkpoint_step TEXT,
20
+ checkpoint_data TEXT,
21
+ metrics TEXT,
22
+ error_message TEXT,
23
+ created_at TEXT DEFAULT (datetime('now'))
24
+ );
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_sleep_runs_status ON sleep_runs(status);
27
+ CREATE INDEX IF NOT EXISTS idx_sleep_runs_started ON sleep_runs(started_at DESC);
28
+
29
+ CREATE TABLE IF NOT EXISTS maintenance_queue (
30
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ item_type TEXT NOT NULL CHECK(item_type IN ('timeline', 'entity', 'file')),
32
+ item_id TEXT NOT NULL,
33
+ task TEXT NOT NULL,
34
+ priority INTEGER DEFAULT 0,
35
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
36
+ processed_at TEXT,
37
+ error_message TEXT,
38
+ UNIQUE(item_type, item_id, task)
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_queue_pending ON maintenance_queue(processed_at) WHERE processed_at IS NULL;
42
+ CREATE INDEX IF NOT EXISTS idx_queue_priority ON maintenance_queue(priority DESC);
43
+
44
+ CREATE TABLE IF NOT EXISTS memory_edges (
45
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
46
+ from_path TEXT NOT NULL,
47
+ to_path TEXT NOT NULL,
48
+ relation TEXT NOT NULL DEFAULT 'related',
49
+ weight REAL DEFAULT 1.0,
50
+ confidence REAL DEFAULT 0.5,
51
+ shared_tags TEXT,
52
+ rationale TEXT,
53
+ method TEXT DEFAULT 'sleep-agent',
54
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
55
+ last_verified TEXT,
56
+ UNIQUE(from_path, to_path)
57
+ );
58
+
59
+ CREATE INDEX IF NOT EXISTS idx_edges_from ON memory_edges(from_path);
60
+ CREATE INDEX IF NOT EXISTS idx_edges_to ON memory_edges(to_path);
61
+ CREATE INDEX IF NOT EXISTS idx_edges_confidence ON memory_edges(confidence DESC);
62
+ CREATE INDEX IF NOT EXISTS idx_edges_relation ON memory_edges(relation);
63
+
64
+ CREATE TABLE IF NOT EXISTS sleep_telemetry (
65
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
66
+ run_id INTEGER REFERENCES sleep_runs(id),
67
+ step TEXT NOT NULL,
68
+ event_type TEXT NOT NULL,
69
+ count INTEGER DEFAULT 0,
70
+ duration_ms INTEGER,
71
+ metadata TEXT,
72
+ created_at TEXT DEFAULT (datetime('now'))
73
+ );
74
+
75
+ CREATE INDEX IF NOT EXISTS idx_telemetry_run ON sleep_telemetry(run_id);
76
+ CREATE INDEX IF NOT EXISTS idx_telemetry_step ON sleep_telemetry(step);
77
+
78
+ CREATE TABLE IF NOT EXISTS tier_transitions (
79
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
80
+ item_id INTEGER NOT NULL,
81
+ from_tier TEXT,
82
+ to_tier TEXT NOT NULL,
83
+ reason TEXT,
84
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
85
+ );
86
+
87
+ CREATE INDEX IF NOT EXISTS idx_tier_transitions_item ON tier_transitions(item_id);
88
+ `);
89
+ initialized.add(t.slug);
90
+ return db;
91
+ }
92
+ export function resetSleepSchemaCache(slug) {
93
+ if (slug)
94
+ initialized.delete(slug);
95
+ else
96
+ initialized.clear();
97
+ }
98
+ /**
99
+ * Reap orphaned sleep_runs that died with status='running'. Returns rows updated.
100
+ * Port of KAD's recoverStaleSleepRuns. Useful at daemon startup.
101
+ */
102
+ export function recoverStaleSleepRuns(t) {
103
+ const db = ensureSleepSchema(t);
104
+ const r = db.prepare(`
105
+ UPDATE sleep_runs
106
+ SET status = 'failed',
107
+ completed_at = datetime('now'),
108
+ error_message = COALESCE(error_message, 'aborted by daemon restart')
109
+ WHERE status = 'running'
110
+ AND started_at < datetime('now', '-2 hours')
111
+ `).run();
112
+ return r.changes;
113
+ }
114
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/sleep/db.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AAEzD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;AAEtC,MAAM,UAAU,iBAAiB,CAAC,CAAgB;IAChD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EP,CAAC,CAAC;IAEH,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,IAAI,IAAI;QAAE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;;QAC9B,WAAW,CAAC,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAgB;IACpD,MAAM,EAAE,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;GAOpB,CAAC,CAAC,GAAG,EAAE,CAAC;IACT,OAAO,CAAC,CAAC,OAAO,CAAC;AACnB,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Sleep pipeline orchestrator — library version of KAD's sleep/index.ts.
3
+ *
4
+ * Scheduling (setInterval, initial delay, registry lookup, cloud-skip) is
5
+ * the daemon's concern, not the library's. The library exposes a single
6
+ * `runSleepCycleNow(t, config)` that runs all 10 steps in canonical order
7
+ * (CANONICAL.md §3):
8
+ *
9
+ * decay → tag → consolidate → link → tier → summarize → observe →
10
+ * profile → reasoning → entity-hygiene
11
+ *
12
+ * Per-step results are recorded in sleep_telemetry. The run lifecycle
13
+ * (sleep_runs row, checkpoint, completion/failure status) is managed here.
14
+ */
15
+ import type { TenantContext } from '@kybernesis/brain-contracts';
16
+ import { type DecayResult } from './steps/decay.js';
17
+ import { type TagResult } from './steps/tag.js';
18
+ import { type ConsolidateResult } from './steps/consolidate.js';
19
+ import { type LinkResult } from './steps/link.js';
20
+ import { type TierResult } from './steps/tier.js';
21
+ import { type SummarizeResult } from './steps/summarize.js';
22
+ import { type ObserveResult } from './steps/observe.js';
23
+ import { type ProfileResult } from './steps/profile.js';
24
+ import { type ReasoningResult } from './steps/reasoning.js';
25
+ import { type EntityHygieneResult } from './steps/entity-hygiene.js';
26
+ import { type SleepConfig } from './config.js';
27
+ export interface RunMetrics {
28
+ decay: DecayResult & {
29
+ durationMs: number;
30
+ };
31
+ tag: TagResult & {
32
+ durationMs: number;
33
+ };
34
+ consolidate: ConsolidateResult & {
35
+ durationMs: number;
36
+ };
37
+ link: LinkResult & {
38
+ durationMs: number;
39
+ };
40
+ tier: TierResult & {
41
+ durationMs: number;
42
+ };
43
+ summarize: SummarizeResult & {
44
+ durationMs: number;
45
+ };
46
+ observe: ObserveResult & {
47
+ durationMs: number;
48
+ };
49
+ profile: ProfileResult & {
50
+ durationMs: number;
51
+ };
52
+ reasoning: ReasoningResult & {
53
+ durationMs: number;
54
+ };
55
+ entityHygiene: EntityHygieneResult & {
56
+ durationMs: number;
57
+ };
58
+ totalDurationMs: number;
59
+ }
60
+ /**
61
+ * Run a single sleep cycle synchronously. Returns the full metrics on
62
+ * completion. Throws if the cycle fails mid-step (after marking the
63
+ * sleep_runs row as 'failed').
64
+ */
65
+ export declare function runSleepCycleNow(t: TenantContext, configOverride?: Partial<SleepConfig>): Promise<RunMetrics>;
66
+ export { DEFAULT_CONFIG } from './config.js';
67
+ export type { SleepConfig } from './config.js';
68
+ export { ensureSleepSchema, recoverStaleSleepRuns } from './db.js';
69
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sleep/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,GAAG,EAAE,SAAS,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,WAAW,EAAE,iBAAiB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,IAAI,EAAE,UAAU,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,IAAI,EAAE,UAAU,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,SAAS,EAAE,eAAe,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,EAAE,aAAa,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,OAAO,EAAE,aAAa,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,SAAS,EAAE,eAAe,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,aAAa,EAAE,mBAAmB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,eAAe,EAAE,MAAM,CAAC;CACzB;AAiCD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,CAAC,EAAE,aAAa,EAChB,cAAc,GAAE,OAAO,CAAC,WAAW,CAAM,GACxC,OAAO,CAAC,UAAU,CAAC,CA6CrB;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Sleep pipeline orchestrator — library version of KAD's sleep/index.ts.
3
+ *
4
+ * Scheduling (setInterval, initial delay, registry lookup, cloud-skip) is
5
+ * the daemon's concern, not the library's. The library exposes a single
6
+ * `runSleepCycleNow(t, config)` that runs all 10 steps in canonical order
7
+ * (CANONICAL.md §3):
8
+ *
9
+ * decay → tag → consolidate → link → tier → summarize → observe →
10
+ * profile → reasoning → entity-hygiene
11
+ *
12
+ * Per-step results are recorded in sleep_telemetry. The run lifecycle
13
+ * (sleep_runs row, checkpoint, completion/failure status) is managed here.
14
+ */
15
+ import { ensureSleepSchema } from './db.js';
16
+ import { saveCheckpoint } from './utils/checkpoint.js';
17
+ import { runDecayStep } from './steps/decay.js';
18
+ import { runTagStep } from './steps/tag.js';
19
+ import { runConsolidateStep } from './steps/consolidate.js';
20
+ import { runLinkStep } from './steps/link.js';
21
+ import { runTierStep } from './steps/tier.js';
22
+ import { runSummarizeStep } from './steps/summarize.js';
23
+ import { runObserveStep } from './steps/observe.js';
24
+ import { runProfileStep } from './steps/profile.js';
25
+ import { runReasoningStep } from './steps/reasoning.js';
26
+ import { runEntityHygieneStep } from './steps/entity-hygiene.js';
27
+ import { DEFAULT_CONFIG } from './config.js';
28
+ function recordTelemetry(db, runId, step, result) {
29
+ try {
30
+ const metadata = { count: result.count };
31
+ if (result.processed !== undefined)
32
+ metadata.processed = result.processed;
33
+ if (result.errors)
34
+ metadata.errors = result.errors;
35
+ db.prepare(`
36
+ INSERT INTO sleep_telemetry (run_id, step, event_type, count, duration_ms, metadata)
37
+ VALUES (?, ?, 'step_completed', ?, ?, ?)
38
+ `).run(runId, step, result.count, result.durationMs, JSON.stringify(metadata));
39
+ }
40
+ catch { /* telemetry must never break the cycle */ }
41
+ }
42
+ async function runStep(db, runId, step, fn) {
43
+ saveCheckpoint(db, runId, step);
44
+ const start = Date.now();
45
+ const result = await fn();
46
+ const durationMs = Date.now() - start;
47
+ recordTelemetry(db, runId, step, { ...result, durationMs });
48
+ return { ...result, durationMs };
49
+ }
50
+ /**
51
+ * Run a single sleep cycle synchronously. Returns the full metrics on
52
+ * completion. Throws if the cycle fails mid-step (after marking the
53
+ * sleep_runs row as 'failed').
54
+ */
55
+ export async function runSleepCycleNow(t, configOverride = {}) {
56
+ const cfg = { ...DEFAULT_CONFIG, ...configOverride };
57
+ const db = ensureSleepSchema(t);
58
+ const startTime = Date.now();
59
+ const runResult = db.prepare(`
60
+ INSERT INTO sleep_runs (started_at, status)
61
+ VALUES (datetime('now'), 'running')
62
+ `).run();
63
+ const runId = runResult.lastInsertRowid;
64
+ try {
65
+ const decay = await runStep(db, runId, 'decay', () => runDecayStep(t, cfg));
66
+ const tag = await runStep(db, runId, 'tag', () => runTagStep(t, cfg));
67
+ const consolidate = await runStep(db, runId, 'consolidate', () => runConsolidateStep(t, cfg));
68
+ const link = await runStep(db, runId, 'link', () => runLinkStep(t, cfg));
69
+ const tier = await runStep(db, runId, 'tier', () => runTierStep(t, cfg));
70
+ const summarize = await runStep(db, runId, 'summarize', () => runSummarizeStep(t, cfg));
71
+ const observe = await runStep(db, runId, 'observe', () => runObserveStep(t, cfg));
72
+ const profile = await runStep(db, runId, 'profile', () => runProfileStep(t, cfg));
73
+ const reasoning = await runStep(db, runId, 'reasoning', () => runReasoningStep(t, cfg));
74
+ const entityHygiene = await runStep(db, runId, 'entity-hygiene', () => runEntityHygieneStep(t, cfg));
75
+ const totalDurationMs = Date.now() - startTime;
76
+ const metrics = {
77
+ decay, tag, consolidate, link, tier, summarize, observe,
78
+ profile, reasoning, entityHygiene, totalDurationMs,
79
+ };
80
+ db.prepare(`
81
+ UPDATE sleep_runs
82
+ SET status = 'completed', completed_at = datetime('now'), metrics = ?
83
+ WHERE id = ?
84
+ `).run(JSON.stringify(metrics), runId);
85
+ return metrics;
86
+ }
87
+ catch (err) {
88
+ const errorMessage = err instanceof Error ? err.message : String(err);
89
+ db.prepare(`
90
+ UPDATE sleep_runs
91
+ SET status = 'failed', completed_at = datetime('now'), error_message = ?
92
+ WHERE id = ?
93
+ `).run(errorMessage, runId);
94
+ throw err;
95
+ }
96
+ }
97
+ export { DEFAULT_CONFIG } from './config.js';
98
+ export { ensureSleepSchema, recoverStaleSleepRuns } from './db.js';
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sleep/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Consolidate step — port of KAD's sleep/steps/consolidate.ts.
3
+ *
4
+ * Merges timeline events with identical/near-identical normalized titles
5
+ * (strip channel prefix `[xxx]` and trailing `...`). Keeps the most recent
6
+ * entry; sums access_count from removed entries; deletes duplicates.
7
+ *
8
+ * Threshold: HAVING COUNT(*) >= consolidationTitleThreshold (default 3).
9
+ * Skips pinned items.
10
+ */
11
+ import type { TenantContext } from '@kybernesis/brain-contracts';
12
+ import type { SleepConfig } from '../config.js';
13
+ export interface ConsolidateResult {
14
+ count: number;
15
+ processed: number;
16
+ errors?: string[];
17
+ }
18
+ export declare function runConsolidateStep(t: TenantContext, config: SleepConfig): Promise<ConsolidateResult>;
19
+ //# sourceMappingURL=consolidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/consolidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,kBAAkB,CACtC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAwE5B"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Consolidate step — port of KAD's sleep/steps/consolidate.ts.
3
+ *
4
+ * Merges timeline events with identical/near-identical normalized titles
5
+ * (strip channel prefix `[xxx]` and trailing `...`). Keeps the most recent
6
+ * entry; sums access_count from removed entries; deletes duplicates.
7
+ *
8
+ * Threshold: HAVING COUNT(*) >= consolidationTitleThreshold (default 3).
9
+ * Skips pinned items.
10
+ */
11
+ import { getDb } from '@kybernesis/brain-storage-sqlite';
12
+ export async function runConsolidateStep(t, config) {
13
+ if (!config.enableConsolidation)
14
+ return { count: 0, processed: 0 };
15
+ const db = getDb(t, 'timeline');
16
+ let consolidated = 0;
17
+ let processed = 0;
18
+ const errors = [];
19
+ try {
20
+ const groups = db.prepare(`
21
+ SELECT
22
+ TRIM(REPLACE(
23
+ CASE WHEN INSTR(title, '] ') > 0
24
+ THEN SUBSTR(title, INSTR(title, '] ') + 2)
25
+ ELSE title
26
+ END,
27
+ '...', ''
28
+ )) as normalized_title,
29
+ COUNT(*) as cnt,
30
+ GROUP_CONCAT(id) as ids,
31
+ MIN(timestamp) as first_ts,
32
+ MAX(timestamp) as last_ts
33
+ FROM timeline_events
34
+ WHERE (is_pinned IS NULL OR is_pinned = 0)
35
+ GROUP BY normalized_title
36
+ HAVING COUNT(*) >= ?
37
+ ORDER BY cnt DESC
38
+ LIMIT ?
39
+ `).all(config.consolidationTitleThreshold, config.batchSize || 50);
40
+ for (const group of groups) {
41
+ processed++;
42
+ const ids = group.ids.split(',').map(Number);
43
+ if (ids.length < 2)
44
+ continue;
45
+ try {
46
+ const keepId = ids[ids.length - 1];
47
+ const removeIds = ids.slice(0, -1);
48
+ const placeholders = removeIds.map(() => '?').join(',');
49
+ const totalAccess = db.prepare(`
50
+ SELECT COALESCE(SUM(COALESCE(access_count, 0)), 0) as total
51
+ FROM timeline_events WHERE id IN (${placeholders})
52
+ `).get(...removeIds);
53
+ db.prepare(`
54
+ UPDATE timeline_events
55
+ SET access_count = COALESCE(access_count, 0) + ?,
56
+ last_accessed = datetime('now')
57
+ WHERE id = ?
58
+ `).run(totalAccess.total + removeIds.length, keepId);
59
+ db.prepare(`
60
+ DELETE FROM timeline_events WHERE id IN (${placeholders})
61
+ `).run(...removeIds);
62
+ consolidated += removeIds.length;
63
+ }
64
+ catch (err) {
65
+ errors.push(`consolidate "${group.normalized_title}": ${String(err)}`);
66
+ }
67
+ }
68
+ }
69
+ catch (err) {
70
+ errors.push(`consolidate step: ${String(err)}`);
71
+ }
72
+ return { count: consolidated, processed, errors: errors.length > 0 ? errors : undefined };
73
+ }
74
+ //# sourceMappingURL=consolidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.js","sourceRoot":"","sources":["../../../src/sleep/steps/consolidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AASzD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,CAAgB,EAChB,MAAmB;IAEnB,IAAI,CAAC,MAAM,CAAC,mBAAmB;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAEnE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAChC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;KAmBzB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,2BAA2B,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,CAM/D,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,SAAS,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAE7B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACnC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACnC,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAExD,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC;;8CAEO,YAAY;SACjD,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAsB,CAAC;gBAE1C,EAAE,CAAC,OAAO,CAAC;;;;;SAKV,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAErD,EAAE,CAAC,OAAO,CAAC;qDACkC,YAAY;SACxD,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;gBAErB,YAAY,IAAI,SAAS,CAAC,MAAM,CAAC;YACnC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,gBAAgB,MAAM,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Decay step — port of KAD's sleep/steps/decay.ts.
3
+ *
4
+ * Three subjobs (all present in KAD source; Bug B11C was a v1 port that
5
+ * dropped 2 of 3 — the library carries the full set):
6
+ * 1. Memory decay: age-based priority reduction with access boost
7
+ * 2. Fact expiration: mark facts.is_latest=0 when expires_at < now
8
+ * 3. Weekly fact-confidence decay: confidence *= 0.95 (floor 0.15) for
9
+ * old ai-extraction/chat facts with no reinforcement
10
+ */
11
+ import type { TenantContext } from '@kybernesis/brain-contracts';
12
+ import type { SleepConfig } from '../config.js';
13
+ export interface DecayResult {
14
+ count: number;
15
+ processed: number;
16
+ errors?: string[];
17
+ }
18
+ export declare function runDecayStep(t: TenantContext, config: SleepConfig): Promise<DecayResult>;
19
+ //# sourceMappingURL=decay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decay.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/decay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAWD,wBAAsB,YAAY,CAChC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAuHtB"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Decay step — port of KAD's sleep/steps/decay.ts.
3
+ *
4
+ * Three subjobs (all present in KAD source; Bug B11C was a v1 port that
5
+ * dropped 2 of 3 — the library carries the full set):
6
+ * 1. Memory decay: age-based priority reduction with access boost
7
+ * 2. Fact expiration: mark facts.is_latest=0 when expires_at < now
8
+ * 3. Weekly fact-confidence decay: confidence *= 0.95 (floor 0.15) for
9
+ * old ai-extraction/chat facts with no reinforcement
10
+ */
11
+ import { getDb } from '@kybernesis/brain-storage-sqlite';
12
+ import { ensureFactsTable } from '../../fact-store.js';
13
+ function isRepetitiveContent(title) {
14
+ const REPETITIVE_PATTERNS = [
15
+ /heartbeat\s+task/i,
16
+ /heartbeat-state/i,
17
+ /check\s+posthog/i,
18
+ ];
19
+ return REPETITIVE_PATTERNS.some(p => p.test(title));
20
+ }
21
+ export async function runDecayStep(t, config) {
22
+ const db = getDb(t, 'timeline');
23
+ const now = Date.now();
24
+ let updated = 0;
25
+ let processed = 0;
26
+ const errors = [];
27
+ // ── Subjob 2: Sweep expired temporal facts ──────────────────────────
28
+ try {
29
+ await ensureFactsTable(t);
30
+ const expired = db.prepare(`
31
+ UPDATE facts SET is_latest = 0, updated_at = datetime('now')
32
+ WHERE expires_at IS NOT NULL
33
+ AND expires_at < datetime('now')
34
+ AND is_latest = 1
35
+ `).run();
36
+ if (expired.changes > 0) {
37
+ console.info('[brain-core/sleep/decay] expired temporal facts', { count: expired.changes });
38
+ }
39
+ }
40
+ catch (err) {
41
+ console.warn('[brain-core/sleep/decay] fact expiration failed', { err: String(err) });
42
+ }
43
+ // ── Subjob 1: Memory decay on timeline_events ───────────────────────
44
+ try {
45
+ const items = db.prepare(`
46
+ SELECT id, title, source_path, timestamp, priority, decay_score, access_count, is_pinned
47
+ FROM timeline_events
48
+ WHERE tier != 'archive' OR tier IS NULL
49
+ ORDER BY priority DESC
50
+ LIMIT ?
51
+ `).all(config.batchSize * 2);
52
+ processed = items.length;
53
+ for (const item of items) {
54
+ try {
55
+ if (item.is_pinned)
56
+ continue;
57
+ const timestamp = new Date(item.timestamp).getTime();
58
+ const ageHours = (now - timestamp) / (1000 * 60 * 60);
59
+ const decayBoost = Math.min(config.maxDecay * 0.2, ageHours * config.decayRatePerHour);
60
+ let effectiveDecayBoost = decayBoost;
61
+ if (isRepetitiveContent(item.title || '') && config.repetitiveDecayMultiplier) {
62
+ effectiveDecayBoost *= config.repetitiveDecayMultiplier;
63
+ }
64
+ const newDecay = Math.min(config.maxDecay, (item.decay_score || 0) + effectiveDecayBoost);
65
+ const accessBoost = isRepetitiveContent(item.title || '')
66
+ ? 0
67
+ : Math.min(0.3, (item.access_count || 0) * 0.05);
68
+ const decayPenalty = effectiveDecayBoost / 2;
69
+ const newPriority = Math.max(0, Math.min(1, (item.priority ?? 0.5) - decayPenalty + accessBoost));
70
+ const decayChanged = Math.abs(newDecay - (item.decay_score || 0)) > 0.001;
71
+ const priorityChanged = Math.abs(newPriority - (item.priority ?? 0.5)) > 0.001;
72
+ if (decayChanged || priorityChanged) {
73
+ db.prepare(`
74
+ UPDATE timeline_events
75
+ SET decay_score = ?, priority = ?
76
+ WHERE id = ?
77
+ `).run(newDecay, newPriority, item.id);
78
+ updated++;
79
+ }
80
+ }
81
+ catch (err) {
82
+ errors.push(`decay item ${item.id}: ${String(err)}`);
83
+ }
84
+ }
85
+ }
86
+ catch (err) {
87
+ console.warn('[brain-core/sleep/decay] memory decay failed', { err: String(err) });
88
+ errors.push(`memory decay: ${String(err)}`);
89
+ }
90
+ // ── Subjob 3: Weekly fact-confidence decay ──────────────────────────
91
+ try {
92
+ await ensureFactsTable(t);
93
+ const lastDecay = db.prepare(`
94
+ SELECT MAX(updated_at) as last_decay FROM facts
95
+ WHERE updated_at IS NOT NULL AND confidence < 0.85
96
+ `).get();
97
+ const shouldDecayFacts = !lastDecay?.last_decay ||
98
+ (Date.now() - new Date(lastDecay.last_decay).getTime()) > 7 * 24 * 60 * 60 * 1000;
99
+ if (shouldDecayFacts) {
100
+ const factDecay = db.prepare(`
101
+ UPDATE facts
102
+ SET confidence = MAX(confidence * 0.95, 0.15),
103
+ updated_at = datetime('now')
104
+ WHERE source_type IN ('ai-extraction', 'chat')
105
+ AND created_at < datetime('now', '-90 days')
106
+ AND last_reinforced_at IS NULL
107
+ AND COALESCE(is_retracted, 0) = 0
108
+ AND confidence > 0.15
109
+ AND is_latest = 1
110
+ `).run();
111
+ if (factDecay.changes > 0) {
112
+ console.info('[brain-core/sleep/decay] fact-confidence decayed', { count: factDecay.changes });
113
+ }
114
+ }
115
+ }
116
+ catch (err) {
117
+ console.warn('[brain-core/sleep/decay] fact-confidence decay failed', { err: String(err) });
118
+ }
119
+ return { count: updated, processed, errors: errors.length > 0 ? errors : undefined };
120
+ }
121
+ //# sourceMappingURL=decay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decay.js","sourceRoot":"","sources":["../../../src/sleep/steps/decay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Entity hygiene step — port of KAD's sleep/steps/entity-hygiene.ts.
3
+ *
4
+ * Five phases:
5
+ * 0. Clean orphaned relations + mentions (no AI)
6
+ * 1. Delete pattern-matched artifacts (Speaker N, CLI commands, file paths)
7
+ * 2. AI-merge same-name-different-type duplicates (relaxed 0.6 confidence)
8
+ * 3. AI-merge variant-name candidates (strict 0.8 confidence)
9
+ * 4. Prune low-value noise (port-faithful KAD filters — see B11B note)
10
+ * 5. Generate narrative profiles for high-mention entities
11
+ *
12
+ * Bug B11B regression-watchpoint: Phase 4 prune uses **all of KAD's
13
+ * filters**: mention_count ≤ 1 AND type='topic' AND last_seen older than
14
+ * pruneMinAgeDays AND is_pinned IS NULL/0 AND no entity_relations.
15
+ * A v1 port dropped filter(s) and over-pruned the entity graph.
16
+ */
17
+ import type { TenantContext } from '@kybernesis/brain-contracts';
18
+ import type { SleepConfig } from '../config.js';
19
+ export interface EntityHygieneResult {
20
+ count: number;
21
+ artifactsCleaned: number;
22
+ merged: number;
23
+ pruned: number;
24
+ assessed: number;
25
+ processed: number;
26
+ errors?: string[];
27
+ }
28
+ export declare function runEntityHygieneStep(t: TenantContext, config: SleepConfig): Promise<EntityHygieneResult>;
29
+ //# sourceMappingURL=entity-hygiene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-hygiene.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/entity-hygiene.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAOjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAoUD,wBAAsB,oBAAoB,CACxC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAmK9B"}