memorix 1.1.7 → 1.1.8

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 (174) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/CLAUDE.md +6 -1
  3. package/README.md +21 -0
  4. package/README.zh-CN.md +21 -0
  5. package/TEAM.md +86 -86
  6. package/dist/cli/index.js +730 -150
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/dashboard/static/index.html +201 -201
  9. package/dist/dashboard/static/style.css +3584 -3584
  10. package/dist/index.js +15 -8
  11. package/dist/index.js.map +1 -1
  12. package/dist/memcode-runtime/CHANGELOG.md +13 -0
  13. package/dist/memcode-runtime/package.json +4 -4
  14. package/dist/sdk.js +15 -8
  15. package/dist/sdk.js.map +1 -1
  16. package/docs/AGENT_OPERATOR_PLAYBOOK.md +18 -0
  17. package/docs/DESIGN_DECISIONS.md +357 -357
  18. package/docs/SETUP.md +10 -0
  19. package/docs/dev-log/progress.txt +35 -26
  20. package/package.json +1 -1
  21. package/src/audit/index.ts +156 -156
  22. package/src/cli/commands/agent-integrations.ts +623 -0
  23. package/src/cli/commands/audit-list.ts +89 -89
  24. package/src/cli/commands/background.ts +659 -659
  25. package/src/cli/commands/cleanup.ts +255 -255
  26. package/src/cli/commands/doctor.ts +23 -0
  27. package/src/cli/commands/formation.ts +48 -48
  28. package/src/cli/commands/git-hook-install.ts +111 -111
  29. package/src/cli/commands/handoff.ts +66 -66
  30. package/src/cli/commands/hooks-status.ts +63 -63
  31. package/src/cli/commands/ingest-commit.ts +153 -153
  32. package/src/cli/commands/ingest-image.ts +73 -73
  33. package/src/cli/commands/ingest-log.ts +180 -180
  34. package/src/cli/commands/ingest.ts +44 -44
  35. package/src/cli/commands/integrate-shared.ts +15 -15
  36. package/src/cli/commands/lock.ts +96 -96
  37. package/src/cli/commands/message.ts +121 -121
  38. package/src/cli/commands/poll.ts +70 -70
  39. package/src/cli/commands/purge-all-memory.ts +85 -85
  40. package/src/cli/commands/purge-project-memory.ts +83 -83
  41. package/src/cli/commands/reasoning.ts +132 -132
  42. package/src/cli/commands/repair.ts +60 -0
  43. package/src/cli/commands/retention.ts +108 -108
  44. package/src/cli/commands/serve-shared.ts +118 -118
  45. package/src/cli/commands/setup.ts +3 -3
  46. package/src/cli/commands/skills.ts +123 -123
  47. package/src/cli/commands/task.ts +192 -192
  48. package/src/cli/commands/transfer.ts +73 -73
  49. package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
  50. package/src/cli/index.ts +3 -1
  51. package/src/cli/tui/ChatView.tsx +234 -234
  52. package/src/cli/tui/CommandBar.tsx +312 -312
  53. package/src/cli/tui/ContextRail.tsx +118 -118
  54. package/src/cli/tui/HeaderBar.tsx +72 -72
  55. package/src/cli/tui/LogoBanner.tsx +51 -51
  56. package/src/cli/tui/Panels.tsx +632 -632
  57. package/src/cli/tui/Sidebar.tsx +179 -179
  58. package/src/cli/tui/chat-service.ts +742 -742
  59. package/src/cli/tui/data.ts +547 -547
  60. package/src/cli/tui/index.ts +41 -41
  61. package/src/cli/tui/markdown-render.tsx +371 -371
  62. package/src/cli/tui/theme.ts +178 -178
  63. package/src/cli/tui/use-mouse.ts +157 -157
  64. package/src/cli/tui/useNavigation.ts +56 -56
  65. package/src/cli/update-checker.ts +211 -211
  66. package/src/cli/version.ts +7 -7
  67. package/src/cli/workbench.ts +1 -1
  68. package/src/codegraph/context-pack.ts +5 -1
  69. package/src/codegraph/lite-provider.ts +5 -1
  70. package/src/codegraph/project-context.ts +5 -1
  71. package/src/compact/token-budget.ts +74 -74
  72. package/src/config/behavior.ts +59 -59
  73. package/src/dashboard/project-classification.ts +64 -64
  74. package/src/dashboard/static/index.html +201 -201
  75. package/src/dashboard/static/style.css +3584 -3584
  76. package/src/embedding/fastembed-provider.ts +142 -142
  77. package/src/embedding/transformers-provider.ts +111 -111
  78. package/src/git/extractor.ts +209 -209
  79. package/src/git/hooks-path.ts +85 -85
  80. package/src/git/noise-filter.ts +210 -210
  81. package/src/hooks/installers/index.ts +4 -4
  82. package/src/hooks/official-skills.ts +1 -1
  83. package/src/hooks/pattern-detector.ts +173 -173
  84. package/src/hooks/rules/memorix-agent-rules.md +2 -2
  85. package/src/hooks/significance-filter.ts +250 -250
  86. package/src/llm/memory-manager.ts +328 -328
  87. package/src/llm/provider.ts +885 -885
  88. package/src/llm/quality.ts +248 -248
  89. package/src/memory/attribution-guard.ts +249 -249
  90. package/src/memory/auto-relations.ts +107 -107
  91. package/src/memory/consolidation.ts +302 -302
  92. package/src/memory/disclosure-policy.ts +141 -141
  93. package/src/memory/entity-extractor.ts +197 -197
  94. package/src/memory/formation/evaluate.ts +217 -217
  95. package/src/memory/formation/extract.ts +361 -361
  96. package/src/memory/formation/index.ts +417 -417
  97. package/src/memory/formation/resolve.ts +344 -344
  98. package/src/memory/formation/types.ts +315 -315
  99. package/src/memory/freshness.ts +122 -122
  100. package/src/memory/graph.ts +197 -197
  101. package/src/memory/refs.ts +94 -94
  102. package/src/memory/retention.ts +433 -433
  103. package/src/memory/secret-filter.ts +79 -79
  104. package/src/memory/session.ts +523 -523
  105. package/src/multimodal/image-loader.ts +143 -143
  106. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  107. package/src/orchestrate/adapters/claude.ts +111 -111
  108. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  109. package/src/orchestrate/adapters/codex.ts +41 -41
  110. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  111. package/src/orchestrate/adapters/gemini.ts +42 -42
  112. package/src/orchestrate/adapters/index.ts +73 -73
  113. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  114. package/src/orchestrate/adapters/opencode.ts +47 -47
  115. package/src/orchestrate/adapters/spawn-helper.ts +286 -286
  116. package/src/orchestrate/adapters/types.ts +77 -77
  117. package/src/orchestrate/capability-router.ts +284 -284
  118. package/src/orchestrate/context-compact.ts +188 -188
  119. package/src/orchestrate/cost-tracker.ts +219 -219
  120. package/src/orchestrate/error-recovery.ts +191 -191
  121. package/src/orchestrate/evidence.ts +140 -140
  122. package/src/orchestrate/ledger.ts +110 -110
  123. package/src/orchestrate/memorix-bridge.ts +380 -380
  124. package/src/orchestrate/output-budget.ts +80 -80
  125. package/src/orchestrate/permission.ts +152 -152
  126. package/src/orchestrate/pipeline-trace.ts +131 -131
  127. package/src/orchestrate/prompt-builder.ts +155 -155
  128. package/src/orchestrate/ring-buffer.ts +37 -37
  129. package/src/orchestrate/task-graph.ts +389 -389
  130. package/src/orchestrate/verify-gate.ts +219 -219
  131. package/src/orchestrate/worktree.ts +232 -232
  132. package/src/project/aliases.ts +374 -374
  133. package/src/project/detector.ts +268 -268
  134. package/src/rules/adapters/claude-code.ts +99 -99
  135. package/src/rules/adapters/codex.ts +97 -97
  136. package/src/rules/adapters/copilot.ts +124 -124
  137. package/src/rules/adapters/cursor.ts +114 -114
  138. package/src/rules/adapters/kiro.ts +126 -126
  139. package/src/rules/adapters/trae.ts +56 -56
  140. package/src/rules/adapters/windsurf.ts +83 -83
  141. package/src/rules/syncer.ts +235 -235
  142. package/src/sdk.ts +327 -327
  143. package/src/search/intent-detector.ts +289 -289
  144. package/src/search/query-expansion.ts +52 -52
  145. package/src/server/formation-timeout.ts +27 -27
  146. package/src/skills/mini-skills.ts +386 -386
  147. package/src/store/chat-store.ts +119 -119
  148. package/src/store/file-lock.ts +100 -100
  149. package/src/store/graph-store.ts +249 -249
  150. package/src/store/mini-skill-store.ts +349 -349
  151. package/src/store/obs-store.ts +255 -255
  152. package/src/store/persistence-json.ts +212 -212
  153. package/src/store/persistence.ts +291 -291
  154. package/src/store/project-affinity.ts +195 -195
  155. package/src/store/session-store.ts +259 -259
  156. package/src/store/sqlite-store.ts +339 -339
  157. package/src/team/event-bus.ts +76 -76
  158. package/src/team/file-locks.ts +173 -173
  159. package/src/team/handoff.ts +167 -167
  160. package/src/team/messages.ts +203 -203
  161. package/src/team/poll.ts +132 -132
  162. package/src/team/tasks.ts +211 -211
  163. package/src/wiki/generator.ts +237 -237
  164. package/src/wiki/knowledge-graph.ts +334 -334
  165. package/src/wiki/types.ts +85 -85
  166. package/src/workspace/mcp-adapters/codex.ts +191 -191
  167. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  168. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  169. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  170. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  171. package/src/workspace/mcp-adapters/trae.ts +134 -134
  172. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  173. package/src/workspace/sanitizer.ts +60 -60
  174. package/src/workspace/workflow-sync.ts +131 -131
@@ -1,315 +1,315 @@
1
- /**
2
- * Memory Formation Pipeline — Type Definitions
3
- *
4
- * The Formation Pipeline is a middleware layer that processes raw memory input
5
- * before it reaches storeObservation(). It transforms raw data into high-quality,
6
- * structured memories through three stages: Extract → Resolve → Evaluate.
7
- *
8
- * Design principles:
9
- * - Each stage has typed input/output
10
- * - Pipeline produces FormedMemory as its intermediate representation
11
- * - Supports dual-mode: rules-based (free) + LLM-powered (premium)
12
- * - Shadow mode: can run alongside existing compact-on-write without side effects
13
- */
14
-
15
- import type { ObservationType } from '../../types.js';
16
-
17
- // ============================================================
18
- // Pipeline Input (what comes in from memorix_store or hooks)
19
- // ============================================================
20
-
21
- /** Raw input to the Formation Pipeline */
22
- export interface FormationInput {
23
- entityName: string;
24
- type: ObservationType;
25
- title: string;
26
- narrative: string;
27
- facts?: string[];
28
- filesModified?: string[];
29
- concepts?: string[];
30
- projectId: string;
31
- /** Source of this input */
32
- source: 'explicit' | 'hook';
33
- /** Topic key for upsert (bypasses resolve stage) */
34
- topicKey?: string;
35
- }
36
-
37
- // ============================================================
38
- // Stage 1: Extract
39
- // ============================================================
40
-
41
- /** Output of the Extract stage */
42
- export interface ExtractResult {
43
- /** Enriched title (may be improved from generic titles) */
44
- title: string;
45
- /** Whether title was auto-improved */
46
- titleImproved: boolean;
47
-
48
- /** Enriched narrative */
49
- narrative: string;
50
-
51
- /** All facts: caller-provided + system-extracted */
52
- facts: string[];
53
- /** Facts extracted by the system (not provided by caller) */
54
- extractedFacts: string[];
55
-
56
- /** Resolved entity name (may differ from input if matched to existing KG entity) */
57
- entityName: string;
58
- /** Whether entity was resolved from Knowledge Graph */
59
- entityResolved: boolean;
60
-
61
- /** Verified or corrected observation type */
62
- type: ObservationType;
63
- /** Whether type was auto-corrected */
64
- typeCorrected: boolean;
65
- }
66
-
67
- // ============================================================
68
- // Stage 2: Resolve
69
- // ============================================================
70
-
71
- /** Resolution action — what to do with this memory */
72
- export type ResolutionAction = 'new' | 'merge' | 'evolve' | 'discard';
73
-
74
- /** Output of the Resolve stage */
75
- export interface ResolveResult {
76
- action: ResolutionAction;
77
- /** ID of existing observation to merge into or evolve from */
78
- targetId?: number;
79
- /** Explanation of why this action was chosen */
80
- reason: string;
81
- /** Merged narrative (for merge/evolve actions) */
82
- mergedNarrative?: string;
83
- /** Merged facts (for merge/evolve actions) */
84
- mergedFacts?: string[];
85
- }
86
-
87
- // ============================================================
88
- // Stage 3: Evaluate
89
- // ============================================================
90
-
91
- /** Knowledge value category */
92
- export type ValueCategory = 'core' | 'contextual' | 'ephemeral';
93
-
94
- /** Output of the Evaluate stage */
95
- export interface EvaluateResult {
96
- /** Value score 0-1 */
97
- score: number;
98
- /** Classified category */
99
- category: ValueCategory;
100
- /** Explanation of assessment */
101
- reason: string;
102
- }
103
-
104
- /** Named Formation pipeline stage. */
105
- export type FormationStage = 'extract' | 'resolve' | 'evaluate';
106
-
107
- /** Per-stage diagnostics emitted during pipeline execution. */
108
- export interface FormationStageEvent {
109
- /** Stage that emitted the event */
110
- stage: FormationStage;
111
- /** Lifecycle status for the stage */
112
- status: 'start' | 'success' | 'skipped';
113
- /** Duration of the stage when available */
114
- stageDurationMs?: number;
115
- /** Total elapsed time for the pipeline at emission time */
116
- totalElapsedMs: number;
117
- }
118
-
119
- // ============================================================
120
- // Pipeline Output: FormedMemory
121
- // ============================================================
122
-
123
- /** The complete output of the Formation Pipeline */
124
- export interface FormedMemory {
125
- // ── Final enriched data (ready for storeObservation) ──
126
- entityName: string;
127
- type: ObservationType;
128
- title: string;
129
- narrative: string;
130
- facts: string[];
131
-
132
- // ── Stage results ──
133
- extraction: ExtractResult;
134
- resolution: ResolveResult;
135
- evaluation: EvaluateResult;
136
-
137
- // ── Pipeline metadata ──
138
- pipeline: {
139
- /** Which mode was used */
140
- mode: 'rules' | 'llm';
141
- /** Total pipeline duration in ms */
142
- durationMs: number;
143
- /** Number of stages completed (0-3) */
144
- stagesCompleted: number;
145
- /** Whether this was run in shadow mode (no side effects) */
146
- shadow: boolean;
147
- /** Per-stage durations in ms for diagnostics */
148
- stageDurationsMs: Partial<Record<FormationStage, number>>;
149
- };
150
-
151
- // ── Governance fields (enterprise-grade metadata) ──
152
- governance?: {
153
- /** Provenance: source tracking */
154
- provenance: {
155
- /** Who created this memory (agent ID, user ID, or system) */
156
- creator: string;
157
- /** When this memory was created (ISO 8601 timestamp) */
158
- createdAt: string;
159
- /** Source of the memory (explicit, hook, auto, etc.) */
160
- source: 'explicit' | 'hook' | 'auto' | 'import';
161
- /** Raw input reference (if applicable) */
162
- rawInputRef?: string;
163
- };
164
- /** Confidence: decision reliability score (0-1) */
165
- confidence: {
166
- /** Overall confidence score */
167
- score: number;
168
- /** Breakdown by stage */
169
- breakdown: {
170
- extractionConfidence: number;
171
- resolutionConfidence: number;
172
- evaluationConfidence: number;
173
- };
174
- /** Reason for confidence score */
175
- reason: string;
176
- };
177
- /** Supersession: memory replacement relationships */
178
- supersession?: {
179
- /** IDs of memories this one replaces */
180
- replacedIds: number[];
181
- /** Reason for replacement */
182
- reason: string;
183
- /** Whether this is a soft replacement (archived) or hard replacement (deleted) */
184
- replacementType: 'soft' | 'hard';
185
- };
186
- };
187
- }
188
-
189
- // ============================================================
190
- // Pipeline Configuration
191
- // ============================================================
192
-
193
- /** Formation Pipeline operating mode */
194
- export type FormationMode = 'shadow' | 'active' | 'fallback';
195
-
196
- /** Configuration for the Formation Pipeline */
197
- export interface FormationConfig {
198
- /** Operating mode: shadow (observe only), active (affects storage), fallback (old compact primary) */
199
- mode: FormationMode;
200
- /** Run in shadow mode: compute FormedMemory but don't affect storage (deprecated, use mode instead) */
201
- shadow?: boolean;
202
- /** Enable LLM-powered stages (requires LLM API key) */
203
- useLLM: boolean;
204
- /** Minimum value score to proceed with storage (default: 0.3) */
205
- minValueScore: number;
206
- /** Sampling rate for hooks path (0-1). 0 = always shadow, 1 = always full resolve */
207
- hooksSamplingRate?: number;
208
- /** Function to search existing memories (injected dependency) */
209
- searchMemories: (query: string, limit: number, projectId: string) => Promise<SearchHit[]>;
210
- /** Function to get observation by ID (injected dependency) */
211
- getObservation: (id: number) => ExistingMemoryRef | null;
212
- /** Function to list existing entity names (injected dependency) */
213
- getEntityNames: () => string[];
214
- /** Optional stage callback for diagnostics/logging */
215
- onStageEvent?: (event: FormationStageEvent) => void;
216
- }
217
-
218
- /** A search hit from existing memories (used by Resolve stage) */
219
- export interface SearchHit {
220
- id: number;
221
- observationId: number;
222
- title: string;
223
- narrative: string;
224
- facts: string;
225
- entityName: string;
226
- type: string;
227
- score: number;
228
- }
229
-
230
- /** Minimal reference to an existing observation (used by Resolve stage) */
231
- export interface ExistingMemoryRef {
232
- id: number;
233
- entityName: string;
234
- type: ObservationType;
235
- title: string;
236
- narrative: string;
237
- facts: string[];
238
- topicKey?: string;
239
- }
240
-
241
- // ============================================================
242
- // Pipeline Metrics (for shadow mode comparison)
243
- // ============================================================
244
-
245
- /** Metrics collected during pipeline execution */
246
- export interface FormationMetrics {
247
- /** Number of facts extracted by system */
248
- systemExtractedFacts: number;
249
- /** Whether title was improved */
250
- titleImproved: boolean;
251
- /** Whether entity was resolved to existing KG entity */
252
- entityResolved: boolean;
253
- /** Whether type was corrected */
254
- typeCorrected: boolean;
255
- /** Resolution action taken */
256
- resolutionAction: ResolutionAction;
257
- /** Value score */
258
- valueScore: number;
259
- /** Value category */
260
- valueCategory: ValueCategory;
261
- /** Total duration ms */
262
- durationMs: number;
263
- /** Pipeline mode */
264
- mode: 'rules' | 'llm';
265
-
266
- // ── Before/After Comparison Metrics ─────────────────────────────
267
- /** What old compact-on-write would have done (for comparison) */
268
- oldCompactAction?: 'ADD' | 'UPDATE' | 'NONE' | 'DELETE';
269
- /** ID of target observation old compact would have merged into */
270
- oldCompactTargetId?: number;
271
- /** Reason old compact would have given */
272
- oldCompactReason?: string;
273
- /** Whether Formation decision differs from old compact */
274
- decisionDiffers?: boolean;
275
- /** Which decision is better (formation | compact | equal | unknown) */
276
- betterDecision?: 'formation' | 'compact' | 'equal' | 'unknown';
277
- }
278
-
279
- /** Aggregated before/after comparison metrics */
280
- export interface BeforeAfterMetrics {
281
- /** Total observations processed */
282
- totalProcessed: number;
283
- /** Number where Formation and old compact agreed */
284
- agreements: number;
285
- /** Number where Formation and old compact disagreed */
286
- disagreements: number;
287
- /** Disagreement breakdown */
288
- disagreementBreakdown: {
289
- formationDiscardedCompactAdded: number;
290
- formationMergedCompactAdded: number;
291
- formationAddedCompactDiscarded: number;
292
- formationAddedCompactMerged: number;
293
- formationEvolvedCompactAdded: number;
294
- other: number;
295
- };
296
- /** Quality metrics */
297
- quality: {
298
- /** Formation discarded low-value memories */
299
- formationDiscardedLowValue: number;
300
- /** Formation merged duplicates */
301
- formationMergedDuplicates: number;
302
- /** Formation evolved outdated memories */
303
- formationEvolvedOutdated: number;
304
- /** Old compact missed duplicates */
305
- compactMissedDuplicates: number;
306
- /** Old compact kept low-value */
307
- compactKeptLowValue: number;
308
- };
309
- /** Average duration comparison */
310
- duration: {
311
- formationAvgMs: number;
312
- compactAvgMs: number;
313
- diffMs: number;
314
- };
315
- }
1
+ /**
2
+ * Memory Formation Pipeline — Type Definitions
3
+ *
4
+ * The Formation Pipeline is a middleware layer that processes raw memory input
5
+ * before it reaches storeObservation(). It transforms raw data into high-quality,
6
+ * structured memories through three stages: Extract → Resolve → Evaluate.
7
+ *
8
+ * Design principles:
9
+ * - Each stage has typed input/output
10
+ * - Pipeline produces FormedMemory as its intermediate representation
11
+ * - Supports dual-mode: rules-based (free) + LLM-powered (premium)
12
+ * - Shadow mode: can run alongside existing compact-on-write without side effects
13
+ */
14
+
15
+ import type { ObservationType } from '../../types.js';
16
+
17
+ // ============================================================
18
+ // Pipeline Input (what comes in from memorix_store or hooks)
19
+ // ============================================================
20
+
21
+ /** Raw input to the Formation Pipeline */
22
+ export interface FormationInput {
23
+ entityName: string;
24
+ type: ObservationType;
25
+ title: string;
26
+ narrative: string;
27
+ facts?: string[];
28
+ filesModified?: string[];
29
+ concepts?: string[];
30
+ projectId: string;
31
+ /** Source of this input */
32
+ source: 'explicit' | 'hook';
33
+ /** Topic key for upsert (bypasses resolve stage) */
34
+ topicKey?: string;
35
+ }
36
+
37
+ // ============================================================
38
+ // Stage 1: Extract
39
+ // ============================================================
40
+
41
+ /** Output of the Extract stage */
42
+ export interface ExtractResult {
43
+ /** Enriched title (may be improved from generic titles) */
44
+ title: string;
45
+ /** Whether title was auto-improved */
46
+ titleImproved: boolean;
47
+
48
+ /** Enriched narrative */
49
+ narrative: string;
50
+
51
+ /** All facts: caller-provided + system-extracted */
52
+ facts: string[];
53
+ /** Facts extracted by the system (not provided by caller) */
54
+ extractedFacts: string[];
55
+
56
+ /** Resolved entity name (may differ from input if matched to existing KG entity) */
57
+ entityName: string;
58
+ /** Whether entity was resolved from Knowledge Graph */
59
+ entityResolved: boolean;
60
+
61
+ /** Verified or corrected observation type */
62
+ type: ObservationType;
63
+ /** Whether type was auto-corrected */
64
+ typeCorrected: boolean;
65
+ }
66
+
67
+ // ============================================================
68
+ // Stage 2: Resolve
69
+ // ============================================================
70
+
71
+ /** Resolution action — what to do with this memory */
72
+ export type ResolutionAction = 'new' | 'merge' | 'evolve' | 'discard';
73
+
74
+ /** Output of the Resolve stage */
75
+ export interface ResolveResult {
76
+ action: ResolutionAction;
77
+ /** ID of existing observation to merge into or evolve from */
78
+ targetId?: number;
79
+ /** Explanation of why this action was chosen */
80
+ reason: string;
81
+ /** Merged narrative (for merge/evolve actions) */
82
+ mergedNarrative?: string;
83
+ /** Merged facts (for merge/evolve actions) */
84
+ mergedFacts?: string[];
85
+ }
86
+
87
+ // ============================================================
88
+ // Stage 3: Evaluate
89
+ // ============================================================
90
+
91
+ /** Knowledge value category */
92
+ export type ValueCategory = 'core' | 'contextual' | 'ephemeral';
93
+
94
+ /** Output of the Evaluate stage */
95
+ export interface EvaluateResult {
96
+ /** Value score 0-1 */
97
+ score: number;
98
+ /** Classified category */
99
+ category: ValueCategory;
100
+ /** Explanation of assessment */
101
+ reason: string;
102
+ }
103
+
104
+ /** Named Formation pipeline stage. */
105
+ export type FormationStage = 'extract' | 'resolve' | 'evaluate';
106
+
107
+ /** Per-stage diagnostics emitted during pipeline execution. */
108
+ export interface FormationStageEvent {
109
+ /** Stage that emitted the event */
110
+ stage: FormationStage;
111
+ /** Lifecycle status for the stage */
112
+ status: 'start' | 'success' | 'skipped';
113
+ /** Duration of the stage when available */
114
+ stageDurationMs?: number;
115
+ /** Total elapsed time for the pipeline at emission time */
116
+ totalElapsedMs: number;
117
+ }
118
+
119
+ // ============================================================
120
+ // Pipeline Output: FormedMemory
121
+ // ============================================================
122
+
123
+ /** The complete output of the Formation Pipeline */
124
+ export interface FormedMemory {
125
+ // ── Final enriched data (ready for storeObservation) ──
126
+ entityName: string;
127
+ type: ObservationType;
128
+ title: string;
129
+ narrative: string;
130
+ facts: string[];
131
+
132
+ // ── Stage results ──
133
+ extraction: ExtractResult;
134
+ resolution: ResolveResult;
135
+ evaluation: EvaluateResult;
136
+
137
+ // ── Pipeline metadata ──
138
+ pipeline: {
139
+ /** Which mode was used */
140
+ mode: 'rules' | 'llm';
141
+ /** Total pipeline duration in ms */
142
+ durationMs: number;
143
+ /** Number of stages completed (0-3) */
144
+ stagesCompleted: number;
145
+ /** Whether this was run in shadow mode (no side effects) */
146
+ shadow: boolean;
147
+ /** Per-stage durations in ms for diagnostics */
148
+ stageDurationsMs: Partial<Record<FormationStage, number>>;
149
+ };
150
+
151
+ // ── Governance fields (enterprise-grade metadata) ──
152
+ governance?: {
153
+ /** Provenance: source tracking */
154
+ provenance: {
155
+ /** Who created this memory (agent ID, user ID, or system) */
156
+ creator: string;
157
+ /** When this memory was created (ISO 8601 timestamp) */
158
+ createdAt: string;
159
+ /** Source of the memory (explicit, hook, auto, etc.) */
160
+ source: 'explicit' | 'hook' | 'auto' | 'import';
161
+ /** Raw input reference (if applicable) */
162
+ rawInputRef?: string;
163
+ };
164
+ /** Confidence: decision reliability score (0-1) */
165
+ confidence: {
166
+ /** Overall confidence score */
167
+ score: number;
168
+ /** Breakdown by stage */
169
+ breakdown: {
170
+ extractionConfidence: number;
171
+ resolutionConfidence: number;
172
+ evaluationConfidence: number;
173
+ };
174
+ /** Reason for confidence score */
175
+ reason: string;
176
+ };
177
+ /** Supersession: memory replacement relationships */
178
+ supersession?: {
179
+ /** IDs of memories this one replaces */
180
+ replacedIds: number[];
181
+ /** Reason for replacement */
182
+ reason: string;
183
+ /** Whether this is a soft replacement (archived) or hard replacement (deleted) */
184
+ replacementType: 'soft' | 'hard';
185
+ };
186
+ };
187
+ }
188
+
189
+ // ============================================================
190
+ // Pipeline Configuration
191
+ // ============================================================
192
+
193
+ /** Formation Pipeline operating mode */
194
+ export type FormationMode = 'shadow' | 'active' | 'fallback';
195
+
196
+ /** Configuration for the Formation Pipeline */
197
+ export interface FormationConfig {
198
+ /** Operating mode: shadow (observe only), active (affects storage), fallback (old compact primary) */
199
+ mode: FormationMode;
200
+ /** Run in shadow mode: compute FormedMemory but don't affect storage (deprecated, use mode instead) */
201
+ shadow?: boolean;
202
+ /** Enable LLM-powered stages (requires LLM API key) */
203
+ useLLM: boolean;
204
+ /** Minimum value score to proceed with storage (default: 0.3) */
205
+ minValueScore: number;
206
+ /** Sampling rate for hooks path (0-1). 0 = always shadow, 1 = always full resolve */
207
+ hooksSamplingRate?: number;
208
+ /** Function to search existing memories (injected dependency) */
209
+ searchMemories: (query: string, limit: number, projectId: string) => Promise<SearchHit[]>;
210
+ /** Function to get observation by ID (injected dependency) */
211
+ getObservation: (id: number) => ExistingMemoryRef | null;
212
+ /** Function to list existing entity names (injected dependency) */
213
+ getEntityNames: () => string[];
214
+ /** Optional stage callback for diagnostics/logging */
215
+ onStageEvent?: (event: FormationStageEvent) => void;
216
+ }
217
+
218
+ /** A search hit from existing memories (used by Resolve stage) */
219
+ export interface SearchHit {
220
+ id: number;
221
+ observationId: number;
222
+ title: string;
223
+ narrative: string;
224
+ facts: string;
225
+ entityName: string;
226
+ type: string;
227
+ score: number;
228
+ }
229
+
230
+ /** Minimal reference to an existing observation (used by Resolve stage) */
231
+ export interface ExistingMemoryRef {
232
+ id: number;
233
+ entityName: string;
234
+ type: ObservationType;
235
+ title: string;
236
+ narrative: string;
237
+ facts: string[];
238
+ topicKey?: string;
239
+ }
240
+
241
+ // ============================================================
242
+ // Pipeline Metrics (for shadow mode comparison)
243
+ // ============================================================
244
+
245
+ /** Metrics collected during pipeline execution */
246
+ export interface FormationMetrics {
247
+ /** Number of facts extracted by system */
248
+ systemExtractedFacts: number;
249
+ /** Whether title was improved */
250
+ titleImproved: boolean;
251
+ /** Whether entity was resolved to existing KG entity */
252
+ entityResolved: boolean;
253
+ /** Whether type was corrected */
254
+ typeCorrected: boolean;
255
+ /** Resolution action taken */
256
+ resolutionAction: ResolutionAction;
257
+ /** Value score */
258
+ valueScore: number;
259
+ /** Value category */
260
+ valueCategory: ValueCategory;
261
+ /** Total duration ms */
262
+ durationMs: number;
263
+ /** Pipeline mode */
264
+ mode: 'rules' | 'llm';
265
+
266
+ // ── Before/After Comparison Metrics ─────────────────────────────
267
+ /** What old compact-on-write would have done (for comparison) */
268
+ oldCompactAction?: 'ADD' | 'UPDATE' | 'NONE' | 'DELETE';
269
+ /** ID of target observation old compact would have merged into */
270
+ oldCompactTargetId?: number;
271
+ /** Reason old compact would have given */
272
+ oldCompactReason?: string;
273
+ /** Whether Formation decision differs from old compact */
274
+ decisionDiffers?: boolean;
275
+ /** Which decision is better (formation | compact | equal | unknown) */
276
+ betterDecision?: 'formation' | 'compact' | 'equal' | 'unknown';
277
+ }
278
+
279
+ /** Aggregated before/after comparison metrics */
280
+ export interface BeforeAfterMetrics {
281
+ /** Total observations processed */
282
+ totalProcessed: number;
283
+ /** Number where Formation and old compact agreed */
284
+ agreements: number;
285
+ /** Number where Formation and old compact disagreed */
286
+ disagreements: number;
287
+ /** Disagreement breakdown */
288
+ disagreementBreakdown: {
289
+ formationDiscardedCompactAdded: number;
290
+ formationMergedCompactAdded: number;
291
+ formationAddedCompactDiscarded: number;
292
+ formationAddedCompactMerged: number;
293
+ formationEvolvedCompactAdded: number;
294
+ other: number;
295
+ };
296
+ /** Quality metrics */
297
+ quality: {
298
+ /** Formation discarded low-value memories */
299
+ formationDiscardedLowValue: number;
300
+ /** Formation merged duplicates */
301
+ formationMergedDuplicates: number;
302
+ /** Formation evolved outdated memories */
303
+ formationEvolvedOutdated: number;
304
+ /** Old compact missed duplicates */
305
+ compactMissedDuplicates: number;
306
+ /** Old compact kept low-value */
307
+ compactKeptLowValue: number;
308
+ };
309
+ /** Average duration comparison */
310
+ duration: {
311
+ formationAvgMs: number;
312
+ compactAvgMs: number;
313
+ diffMs: number;
314
+ };
315
+ }