@unrdf/knowledge-engine 5.0.1 → 26.4.3

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 (71) hide show
  1. package/package.json +13 -7
  2. package/src/ai-enhanced-search.mjs +371 -0
  3. package/src/anomaly-detector.mjs +226 -0
  4. package/src/artifact-generator.mjs +251 -0
  5. package/src/browser.mjs +1 -1
  6. package/src/chatman/disruption-arithmetic.mjs +140 -0
  7. package/src/chatman/market-dynamics.mjs +140 -0
  8. package/src/chatman/organizational-dynamics.mjs +140 -0
  9. package/src/chatman/strategic-dynamics.mjs +140 -0
  10. package/src/chatman-config-loader.mjs +282 -0
  11. package/src/chatman-engine.mjs +431 -0
  12. package/src/chatman-operator.mjs +342 -0
  13. package/src/dark-field-detector.mjs +312 -0
  14. package/src/formation-theorems.mjs +345 -0
  15. package/src/index.mjs +20 -2
  16. package/src/knowledge-hook-manager.mjs +1 -1
  17. package/src/lockchain-writer-browser.mjs +2 -2
  18. package/src/observability.mjs +40 -4
  19. package/src/query-optimizer.mjs +1 -1
  20. package/src/resolution-layer.mjs +1 -1
  21. package/src/transaction.mjs +11 -9
  22. package/README.md +0 -84
  23. package/src/browser-shims.mjs +0 -343
  24. package/src/canonicalize.mjs +0 -414
  25. package/src/condition-cache.mjs +0 -109
  26. package/src/condition-evaluator.mjs +0 -722
  27. package/src/dark-matter-core.mjs +0 -742
  28. package/src/define-hook.mjs +0 -213
  29. package/src/effect-sandbox-browser.mjs +0 -283
  30. package/src/effect-sandbox-worker.mjs +0 -170
  31. package/src/effect-sandbox.mjs +0 -517
  32. package/src/engines/index.mjs +0 -11
  33. package/src/engines/rdf-engine.mjs +0 -299
  34. package/src/file-resolver.mjs +0 -387
  35. package/src/hook-executor-batching.mjs +0 -277
  36. package/src/hook-executor.mjs +0 -870
  37. package/src/hook-management.mjs +0 -150
  38. package/src/ken-parliment.mjs +0 -119
  39. package/src/ken.mjs +0 -149
  40. package/src/knowledge-engine/builtin-rules.mjs +0 -190
  41. package/src/knowledge-engine/inference-engine.mjs +0 -418
  42. package/src/knowledge-engine/knowledge-engine.mjs +0 -317
  43. package/src/knowledge-engine/pattern-dsl.mjs +0 -142
  44. package/src/knowledge-engine/pattern-matcher.mjs +0 -215
  45. package/src/knowledge-engine/rules.mjs +0 -184
  46. package/src/knowledge-engine.mjs +0 -319
  47. package/src/knowledge-hook-engine.mjs +0 -360
  48. package/src/knowledge-substrate-core.mjs +0 -927
  49. package/src/lite.mjs +0 -222
  50. package/src/lockchain-writer.mjs +0 -602
  51. package/src/monitoring/andon-signals.mjs +0 -775
  52. package/src/parse.mjs +0 -290
  53. package/src/performance-optimizer.mjs +0 -678
  54. package/src/policy-pack.mjs +0 -572
  55. package/src/query-cache.mjs +0 -116
  56. package/src/query.mjs +0 -306
  57. package/src/reason.mjs +0 -350
  58. package/src/schemas.mjs +0 -1063
  59. package/src/security/error-sanitizer.mjs +0 -257
  60. package/src/security/path-validator.mjs +0 -194
  61. package/src/security/sandbox-restrictions.mjs +0 -331
  62. package/src/security-validator.mjs +0 -389
  63. package/src/store-cache.mjs +0 -137
  64. package/src/telemetry.mjs +0 -167
  65. package/src/utils/adaptive-monitor.mjs +0 -746
  66. package/src/utils/circuit-breaker.mjs +0 -513
  67. package/src/utils/edge-case-handler.mjs +0 -503
  68. package/src/utils/memory-manager.mjs +0 -498
  69. package/src/utils/ring-buffer.mjs +0 -282
  70. package/src/validate.mjs +0 -319
  71. package/src/validators/index.mjs +0 -338
@@ -0,0 +1,342 @@
1
+ /**
2
+ * @file Chatman Operator - μ Closure Operator Implementation
3
+ * @module knowledge-engine/chatman-operator
4
+ *
5
+ * @description
6
+ * Implements the μ (mu) closure operator from the Chatman Equation.
7
+ * The μ operator calculates the closure of observable patterns to reveal
8
+ * the complete artifact space including invisible dark field components.
9
+ *
10
+ * Core Formula: A = μ(O)
11
+ * Where:
12
+ * - A = Complete artifact space (100%)
13
+ * - μ = Closure operator
14
+ * - O = Observable patterns (~5%)
15
+ */
16
+
17
+ import { randomUUID } from 'crypto';
18
+ import { z } from 'zod';
19
+
20
+ /**
21
+ * Observable pattern schema
22
+ */
23
+ export const ObservablePatternSchema = z.object({
24
+ id: z.string().uuid().optional(),
25
+ type: z.enum(['market', 'organizational', 'strategic', 'disruption']),
26
+ patterns: z.array(z.string()).min(1),
27
+ visibility: z.number().min(0).max(1).default(0.05),
28
+ metadata: z.record(z.unknown()).optional(),
29
+ });
30
+
31
+ /**
32
+ * Closure result schema
33
+ */
34
+ export const ClosureResultSchema = z.object({
35
+ observable: ObservablePatternSchema,
36
+ darkField: z.object({
37
+ patterns: z.array(z.string()),
38
+ visibility: z.number(),
39
+ coverage: z.number(),
40
+ }),
41
+ completeness: z.number().min(0).max(1),
42
+ timestamp: z.number(),
43
+ operatorId: z.string().uuid(),
44
+ });
45
+
46
+ /**
47
+ * Chatman μ operator - Calculates closure of observable patterns
48
+ */
49
+ export class ChatmanOperator {
50
+ /**
51
+ * Create a new Chatman operator
52
+ * @param {Object} [options] - Operator options
53
+ * @param {number} [options.observableRatio=0.05] - Observable to dark field ratio (5% default)
54
+ * @param {number} [options.closureThreshold=0.95] - Minimum completeness threshold
55
+ * @param {Function} [options.tracer] - OTEL tracer function
56
+ */
57
+ constructor(options = {}) {
58
+ this.observableRatio = options.observableRatio ?? 0.05;
59
+ this.closureThreshold = options.closureThreshold ?? 0.95;
60
+ this.tracer = options.tracer;
61
+ this.operatorId = randomUUID();
62
+ this.metrics = {
63
+ closureOperations: 0,
64
+ averageCompleteness: 0,
65
+ totalDarkFieldRevealed: 0,
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Apply μ operator to observable patterns to compute closure
71
+ * @param {Object} observable - Observable pattern
72
+ * @returns {Promise<Object>} Closure result
73
+ */
74
+ async apply(observable) {
75
+ const span = this.tracer?.startSpan?.('chatman.operator.apply');
76
+ const startTime = Date.now();
77
+
78
+ try {
79
+ // Validate input
80
+ const validated = ObservablePatternSchema.parse(observable);
81
+ if (!validated.id) {
82
+ validated.id = randomUUID();
83
+ }
84
+
85
+ span?.setAttribute?.('pattern.type', validated.type);
86
+ span?.setAttribute?.('pattern.count', validated.patterns.length);
87
+
88
+ // Calculate dark field using closure operator
89
+ const darkField = this._calculateDarkField(validated);
90
+
91
+ // Compute completeness metric
92
+ const completeness = this._computeCompleteness(validated, darkField);
93
+
94
+ span?.setAttribute?.('completeness', completeness);
95
+ span?.setAttribute?.('dark_field_size', darkField.patterns.length);
96
+
97
+ const result = {
98
+ observable: validated,
99
+ darkField,
100
+ completeness,
101
+ timestamp: Date.now(),
102
+ operatorId: this.operatorId,
103
+ };
104
+
105
+ // Update metrics
106
+ this.metrics.closureOperations++;
107
+ this.metrics.averageCompleteness =
108
+ (this.metrics.averageCompleteness * (this.metrics.closureOperations - 1) + completeness) /
109
+ this.metrics.closureOperations;
110
+ this.metrics.totalDarkFieldRevealed += darkField.patterns.length;
111
+
112
+ span?.addEvent?.('closure_computed', {
113
+ 'closure.completeness': completeness,
114
+ 'closure.duration_ms': Date.now() - startTime,
115
+ });
116
+
117
+ return ClosureResultSchema.parse(result);
118
+ } catch (error) {
119
+ span?.recordException?.(error);
120
+ span?.setStatus?.({ code: 2, message: error.message }); // ERROR
121
+ throw error;
122
+ } finally {
123
+ span?.end?.();
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Calculate dark field patterns from observable patterns
129
+ * @param {Object} observable - Observable pattern
130
+ * @returns {Object} Dark field
131
+ * @private
132
+ */
133
+ _calculateDarkField(observable) {
134
+ const observableCount = observable.patterns.length;
135
+
136
+ // μ(O) = O ∪ DarkField
137
+ // where |DarkField| ≈ |O| * (1/observableRatio - 1)
138
+ const darkFieldMultiplier = 1 / this.observableRatio - 1;
139
+ const darkFieldSize = Math.floor(observableCount * darkFieldMultiplier);
140
+
141
+ // Generate dark field patterns based on observable type
142
+ const darkFieldPatterns = this._generateDarkFieldPatterns(
143
+ observable.type,
144
+ observable.patterns,
145
+ darkFieldSize
146
+ );
147
+
148
+ return {
149
+ patterns: darkFieldPatterns,
150
+ visibility: 1 - this.observableRatio,
151
+ coverage: darkFieldSize / (darkFieldSize + observableCount),
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Generate dark field patterns based on type and observables
157
+ * @param {string} type - Pattern type
158
+ * @param {Array<string>} observablePatterns - Observable patterns
159
+ * @param {number} targetSize - Target dark field size
160
+ * @returns {Array<string>} Dark field patterns
161
+ * @private
162
+ */
163
+ _generateDarkFieldPatterns(type, observablePatterns, targetSize) {
164
+ const darkField = [];
165
+ const generators = {
166
+ market: this._generateMarketDarkField.bind(this),
167
+ organizational: this._generateOrganizationalDarkField.bind(this),
168
+ strategic: this._generateStrategicDarkField.bind(this),
169
+ disruption: this._generateDisruptionDarkField.bind(this),
170
+ };
171
+
172
+ const generator = generators[type] || generators.market;
173
+ return generator(observablePatterns, targetSize);
174
+ }
175
+
176
+ /**
177
+ * Generate market dynamics dark field
178
+ * @param {Array<string>} patterns - Observable patterns
179
+ * @param {number} size - Target size
180
+ * @returns {Array<string>} Dark field patterns
181
+ * @private
182
+ */
183
+ _generateMarketDarkField(patterns, size) {
184
+ const darkField = [];
185
+ const dimensions = [
186
+ 'hidden_customer_needs',
187
+ 'latent_market_segments',
188
+ 'unspoken_value_drivers',
189
+ 'invisible_competition',
190
+ 'emergent_demand_patterns',
191
+ 'tacit_buying_criteria',
192
+ 'underground_distribution_channels',
193
+ 'implicit_price_expectations',
194
+ ];
195
+
196
+ for (let i = 0; i < size; i++) {
197
+ const dimension = dimensions[i % dimensions.length];
198
+ const patternIndex = i % patterns.length;
199
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
200
+ }
201
+
202
+ return darkField;
203
+ }
204
+
205
+ /**
206
+ * Generate organizational dynamics dark field
207
+ * @param {Array<string>} patterns - Observable patterns
208
+ * @param {number} size - Target size
209
+ * @returns {Array<string>} Dark field patterns
210
+ * @private
211
+ */
212
+ _generateOrganizationalDarkField(patterns, size) {
213
+ const darkField = [];
214
+ const dimensions = [
215
+ 'informal_power_structures',
216
+ 'tacit_knowledge_networks',
217
+ 'hidden_resource_flows',
218
+ 'implicit_decision_criteria',
219
+ 'unwritten_cultural_norms',
220
+ 'latent_capability_reserves',
221
+ 'invisible_coordination_mechanisms',
222
+ 'emergent_collaboration_patterns',
223
+ ];
224
+
225
+ for (let i = 0; i < size; i++) {
226
+ const dimension = dimensions[i % dimensions.length];
227
+ const patternIndex = i % patterns.length;
228
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
229
+ }
230
+
231
+ return darkField;
232
+ }
233
+
234
+ /**
235
+ * Generate strategic dynamics dark field
236
+ * @param {Array<string>} patterns - Observable patterns
237
+ * @param {number} size - Target size
238
+ * @returns {Array<string>} Dark field patterns
239
+ * @private
240
+ */
241
+ _generateStrategicDarkField(patterns, size) {
242
+ const darkField = [];
243
+ const dimensions = [
244
+ 'latent_strategic_options',
245
+ 'hidden_competitive_advantages',
246
+ 'implicit_strategic_assumptions',
247
+ 'emergent_industry_shifts',
248
+ 'tacit_success_factors',
249
+ 'invisible_threat_vectors',
250
+ 'unrecognized_opportunities',
251
+ 'hidden_ecosystem_dependencies',
252
+ ];
253
+
254
+ for (let i = 0; i < size; i++) {
255
+ const dimension = dimensions[i % dimensions.length];
256
+ const patternIndex = i % patterns.length;
257
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
258
+ }
259
+
260
+ return darkField;
261
+ }
262
+
263
+ /**
264
+ * Generate disruption arithmetic dark field
265
+ * @param {Array<string>} patterns - Observable patterns
266
+ * @param {number} size - Target size
267
+ * @returns {Array<string>} Dark field patterns
268
+ * @private
269
+ */
270
+ _generateDisruptionDarkField(patterns, size) {
271
+ const darkField = [];
272
+ const dimensions = [
273
+ 'latent_disruption_vectors',
274
+ 'hidden_innovation_barriers',
275
+ 'implicit_adoption_triggers',
276
+ 'emergent_technology_convergence',
277
+ 'tacit_resistance_patterns',
278
+ 'invisible_tipping_points',
279
+ 'unrecognized_substitutes',
280
+ 'hidden_value_chain_vulnerabilities',
281
+ ];
282
+
283
+ for (let i = 0; i < size; i++) {
284
+ const dimension = dimensions[i % dimensions.length];
285
+ const patternIndex = i % patterns.length;
286
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
287
+ }
288
+
289
+ return darkField;
290
+ }
291
+
292
+ /**
293
+ * Compute completeness of closure
294
+ * @param {Object} observable - Observable pattern
295
+ * @param {Object} darkField - Dark field
296
+ * @returns {number} Completeness ratio [0, 1]
297
+ * @private
298
+ */
299
+ _computeCompleteness(observable, darkField) {
300
+ const totalPatterns = observable.patterns.length + darkField.patterns.length;
301
+ const coverageScore = darkField.patterns.length / totalPatterns;
302
+
303
+ // Completeness is high when dark field coverage approaches (1 - observableRatio)
304
+ const targetCoverage = 1 - this.observableRatio;
305
+ const completeness = Math.min(1, coverageScore / targetCoverage);
306
+
307
+ return completeness;
308
+ }
309
+
310
+ /**
311
+ * Get operator metrics
312
+ * @returns {Object} Metrics
313
+ */
314
+ getMetrics() {
315
+ return {
316
+ ...this.metrics,
317
+ operatorId: this.operatorId,
318
+ observableRatio: this.observableRatio,
319
+ closureThreshold: this.closureThreshold,
320
+ };
321
+ }
322
+
323
+ /**
324
+ * Reset operator metrics
325
+ */
326
+ resetMetrics() {
327
+ this.metrics = {
328
+ closureOperations: 0,
329
+ averageCompleteness: 0,
330
+ totalDarkFieldRevealed: 0,
331
+ };
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Create a Chatman operator instance
337
+ * @param {Object} [options] - Operator options
338
+ * @returns {ChatmanOperator} Operator instance
339
+ */
340
+ export function createChatmanOperator(options = {}) {
341
+ return new ChatmanOperator(options);
342
+ }
@@ -0,0 +1,312 @@
1
+ /**
2
+ * @file Dark Field Detector - 95% Invisible Field Detection
3
+ * @module knowledge-engine/dark-field-detector
4
+ *
5
+ * @description
6
+ * Detects and analyzes the dark field (invisible ~95%) of organizational,
7
+ * market, strategic, and disruption patterns using the Chatman Equation.
8
+ */
9
+
10
+ import { randomUUID } from 'crypto';
11
+ import { z } from 'zod';
12
+
13
+ /**
14
+ * Detection result schema
15
+ */
16
+ export const DetectionResultSchema = z.object({
17
+ id: z.string().uuid(),
18
+ type: z.enum(['market', 'organizational', 'strategic', 'disruption']),
19
+ observableSize: z.number().int().nonnegative(),
20
+ darkFieldSize: z.number().int().nonnegative(),
21
+ darkFieldRatio: z.number().min(0).max(1),
22
+ patterns: z.array(
23
+ z.object({
24
+ dimension: z.string(),
25
+ confidence: z.number().min(0).max(1),
26
+ derivedFrom: z.array(z.string()),
27
+ })
28
+ ),
29
+ detectedAt: z.number(),
30
+ });
31
+
32
+ /**
33
+ * Detection options schema
34
+ */
35
+ export const DetectionOptionsSchema = z.object({
36
+ minConfidence: z.number().min(0).max(1).default(0.7),
37
+ maxPatterns: z.number().int().positive().default(100),
38
+ targetRatio: z.number().min(0).max(1).default(0.95),
39
+ });
40
+
41
+ /**
42
+ * Dark field detector for Chatman Equation
43
+ */
44
+ export class DarkFieldDetector {
45
+ /**
46
+ * Create a new dark field detector
47
+ * @param {Object} [options] - Detector options
48
+ * @param {Function} [options.tracer] - OTEL tracer function
49
+ * @param {number} [options.targetRatio=0.95] - Target dark field ratio
50
+ */
51
+ constructor(options = {}) {
52
+ this.tracer = options.tracer;
53
+ this.targetRatio = options.targetRatio ?? 0.95;
54
+ this.metrics = {
55
+ detectionsPerformed: 0,
56
+ averageDarkFieldRatio: 0,
57
+ totalPatternsDetected: 0,
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Detect dark field patterns from observable data
63
+ * @param {Object} observable - Observable pattern data
64
+ * @param {Object} [options] - Detection options
65
+ * @returns {Promise<Object>} Detection result
66
+ */
67
+ async detect(observable, options = {}) {
68
+ const span = this.tracer?.startSpan?.('chatman.darkfield.detect');
69
+ const startTime = Date.now();
70
+
71
+ try {
72
+ const opts = DetectionOptionsSchema.parse(options);
73
+
74
+ span?.setAttribute?.('observable.type', observable.type);
75
+ span?.setAttribute?.('observable.size', observable.patterns.length);
76
+ span?.setAttribute?.('target_ratio', opts.targetRatio);
77
+
78
+ // Calculate expected dark field size
79
+ const observableSize = observable.patterns.length;
80
+ const darkFieldSize = this._calculateDarkFieldSize(observableSize, opts.targetRatio);
81
+
82
+ // Detect dark field patterns
83
+ const patterns = this._detectPatterns(observable, darkFieldSize, opts);
84
+
85
+ const darkFieldRatio = darkFieldSize / (darkFieldSize + observableSize);
86
+
87
+ const result = {
88
+ id: randomUUID(),
89
+ type: observable.type,
90
+ observableSize,
91
+ darkFieldSize,
92
+ darkFieldRatio,
93
+ patterns,
94
+ detectedAt: Date.now(),
95
+ };
96
+
97
+ // Update metrics
98
+ this.metrics.detectionsPerformed++;
99
+ this.metrics.averageDarkFieldRatio =
100
+ (this.metrics.averageDarkFieldRatio * (this.metrics.detectionsPerformed - 1) +
101
+ darkFieldRatio) /
102
+ this.metrics.detectionsPerformed;
103
+ this.metrics.totalPatternsDetected += patterns.length;
104
+
105
+ span?.addEvent?.('detection_completed', {
106
+ 'detection.id': result.id,
107
+ 'detection.dark_field_size': darkFieldSize,
108
+ 'detection.ratio': darkFieldRatio,
109
+ 'detection.pattern_count': patterns.length,
110
+ 'detection.duration_ms': Date.now() - startTime,
111
+ });
112
+
113
+ return DetectionResultSchema.parse(result);
114
+ } catch (error) {
115
+ span?.recordException?.(error);
116
+ span?.setStatus?.({ code: 2, message: error.message });
117
+ throw error;
118
+ } finally {
119
+ span?.end?.();
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Calculate dark field size from observable size and target ratio
125
+ * @param {number} observableSize - Number of observable patterns
126
+ * @param {number} targetRatio - Target dark field ratio
127
+ * @returns {number} Dark field size
128
+ * @private
129
+ */
130
+ _calculateDarkFieldSize(observableSize, targetRatio) {
131
+ // targetRatio = darkField / (darkField + observable)
132
+ // darkField = observable * targetRatio / (1 - targetRatio)
133
+ return Math.floor((observableSize * targetRatio) / (1 - targetRatio));
134
+ }
135
+
136
+ /**
137
+ * Detect dark field patterns
138
+ * @param {Object} observable - Observable pattern
139
+ * @param {number} targetSize - Target dark field size
140
+ * @param {Object} options - Detection options
141
+ * @returns {Array<Object>} Detected patterns
142
+ * @private
143
+ */
144
+ _detectPatterns(observable, targetSize, options) {
145
+ const detectors = {
146
+ market: this._detectMarketDarkField.bind(this),
147
+ organizational: this._detectOrganizationalDarkField.bind(this),
148
+ strategic: this._detectStrategicDarkField.bind(this),
149
+ disruption: this._detectDisruptionDarkField.bind(this),
150
+ };
151
+
152
+ const detector = detectors[observable.type] || detectors.market;
153
+ return detector(observable.patterns, targetSize, options);
154
+ }
155
+
156
+ /**
157
+ * Detect market dark field patterns
158
+ * @param {Array<string>} observablePatterns - Observable patterns
159
+ * @param {number} targetSize - Target size
160
+ * @param {Object} options - Options
161
+ * @returns {Array<Object>} Detected patterns
162
+ * @private
163
+ */
164
+ _detectMarketDarkField(observablePatterns, targetSize, options) {
165
+ const dimensions = [
166
+ 'hidden_customer_needs',
167
+ 'latent_market_segments',
168
+ 'unspoken_value_drivers',
169
+ 'invisible_competition',
170
+ 'emergent_demand_patterns',
171
+ ];
172
+
173
+ return this._generateDetectedPatterns(dimensions, observablePatterns, targetSize, options);
174
+ }
175
+
176
+ /**
177
+ * Detect organizational dark field patterns
178
+ * @param {Array<string>} observablePatterns - Observable patterns
179
+ * @param {number} targetSize - Target size
180
+ * @param {Object} options - Options
181
+ * @returns {Array<Object>} Detected patterns
182
+ * @private
183
+ */
184
+ _detectOrganizationalDarkField(observablePatterns, targetSize, options) {
185
+ const dimensions = [
186
+ 'informal_power_structures',
187
+ 'tacit_knowledge_networks',
188
+ 'hidden_resource_flows',
189
+ 'implicit_decision_criteria',
190
+ 'unwritten_cultural_norms',
191
+ ];
192
+
193
+ return this._generateDetectedPatterns(dimensions, observablePatterns, targetSize, options);
194
+ }
195
+
196
+ /**
197
+ * Detect strategic dark field patterns
198
+ * @param {Array<string>} observablePatterns - Observable patterns
199
+ * @param {number} targetSize - Target size
200
+ * @param {Object} options - Options
201
+ * @returns {Array<Object>} Detected patterns
202
+ * @private
203
+ */
204
+ _detectStrategicDarkField(observablePatterns, targetSize, options) {
205
+ const dimensions = [
206
+ 'latent_strategic_options',
207
+ 'hidden_competitive_advantages',
208
+ 'implicit_strategic_assumptions',
209
+ 'emergent_industry_shifts',
210
+ 'tacit_success_factors',
211
+ ];
212
+
213
+ return this._generateDetectedPatterns(dimensions, observablePatterns, targetSize, options);
214
+ }
215
+
216
+ /**
217
+ * Detect disruption dark field patterns
218
+ * @param {Array<string>} observablePatterns - Observable patterns
219
+ * @param {number} targetSize - Target size
220
+ * @param {Object} options - Options
221
+ * @returns {Array<Object>} Detected patterns
222
+ * @private
223
+ */
224
+ _detectDisruptionDarkField(observablePatterns, targetSize, options) {
225
+ const dimensions = [
226
+ 'latent_disruption_vectors',
227
+ 'hidden_innovation_barriers',
228
+ 'implicit_adoption_triggers',
229
+ 'emergent_technology_convergence',
230
+ 'tacit_resistance_patterns',
231
+ ];
232
+
233
+ return this._generateDetectedPatterns(dimensions, observablePatterns, targetSize, options);
234
+ }
235
+
236
+ /**
237
+ * Generate detected patterns from dimensions
238
+ * @param {Array<string>} dimensions - Pattern dimensions
239
+ * @param {Array<string>} observablePatterns - Observable patterns
240
+ * @param {number} targetSize - Target size
241
+ * @param {Object} options - Options
242
+ * @returns {Array<Object>} Detected patterns
243
+ * @private
244
+ */
245
+ _generateDetectedPatterns(dimensions, observablePatterns, targetSize, options) {
246
+ const patterns = [];
247
+ const maxPatterns = Math.min(targetSize, options.maxPatterns);
248
+
249
+ for (let i = 0; i < maxPatterns; i++) {
250
+ const dimension = dimensions[i % dimensions.length];
251
+ const patternIndex = i % observablePatterns.length;
252
+ const confidence = this._calculateConfidence(i, maxPatterns, options.minConfidence);
253
+
254
+ if (confidence >= options.minConfidence) {
255
+ patterns.push({
256
+ dimension,
257
+ confidence,
258
+ derivedFrom: [observablePatterns[patternIndex]],
259
+ });
260
+ }
261
+ }
262
+
263
+ return patterns;
264
+ }
265
+
266
+ /**
267
+ * Calculate confidence score for pattern
268
+ * @param {number} index - Pattern index
269
+ * @param {number} total - Total patterns
270
+ * @param {number} minConfidence - Minimum confidence
271
+ * @returns {number} Confidence score
272
+ * @private
273
+ */
274
+ _calculateConfidence(index, total, minConfidence) {
275
+ // Confidence decreases slightly as we generate more patterns
276
+ const decay = 0.1;
277
+ const baseConfidence = 0.95;
278
+ const confidence = baseConfidence - (index / total) * decay;
279
+ return Math.max(minConfidence, confidence);
280
+ }
281
+
282
+ /**
283
+ * Get detector metrics
284
+ * @returns {Object} Metrics
285
+ */
286
+ getMetrics() {
287
+ return {
288
+ ...this.metrics,
289
+ targetRatio: this.targetRatio,
290
+ };
291
+ }
292
+
293
+ /**
294
+ * Reset detector metrics
295
+ */
296
+ resetMetrics() {
297
+ this.metrics = {
298
+ detectionsPerformed: 0,
299
+ averageDarkFieldRatio: 0,
300
+ totalPatternsDetected: 0,
301
+ };
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Create a dark field detector instance
307
+ * @param {Object} [options] - Detector options
308
+ * @returns {DarkFieldDetector} Detector instance
309
+ */
310
+ export function createDarkFieldDetector(options = {}) {
311
+ return new DarkFieldDetector(options);
312
+ }