@unrdf/knowledge-engine 5.0.1 → 26.4.2

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 +23 -17
  2. package/src/ai-enhanced-search.mjs +371 -0
  3. package/src/anomaly-detector.mjs +226 -0
  4. package/src/artifact-generator.mjs +252 -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 +435 -0
  12. package/src/chatman-operator.mjs +343 -0
  13. package/src/dark-field-detector.mjs +332 -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,343 @@
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) +
109
+ completeness) /
110
+ this.metrics.closureOperations;
111
+ this.metrics.totalDarkFieldRevealed += darkField.patterns.length;
112
+
113
+ span?.addEvent?.('closure_computed', {
114
+ 'closure.completeness': completeness,
115
+ 'closure.duration_ms': Date.now() - startTime,
116
+ });
117
+
118
+ return ClosureResultSchema.parse(result);
119
+ } catch (error) {
120
+ span?.recordException?.(error);
121
+ span?.setStatus?.({ code: 2, message: error.message }); // ERROR
122
+ throw error;
123
+ } finally {
124
+ span?.end?.();
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Calculate dark field patterns from observable patterns
130
+ * @param {Object} observable - Observable pattern
131
+ * @returns {Object} Dark field
132
+ * @private
133
+ */
134
+ _calculateDarkField(observable) {
135
+ const observableCount = observable.patterns.length;
136
+
137
+ // μ(O) = O ∪ DarkField
138
+ // where |DarkField| ≈ |O| * (1/observableRatio - 1)
139
+ const darkFieldMultiplier = 1 / this.observableRatio - 1;
140
+ const darkFieldSize = Math.floor(observableCount * darkFieldMultiplier);
141
+
142
+ // Generate dark field patterns based on observable type
143
+ const darkFieldPatterns = this._generateDarkFieldPatterns(
144
+ observable.type,
145
+ observable.patterns,
146
+ darkFieldSize
147
+ );
148
+
149
+ return {
150
+ patterns: darkFieldPatterns,
151
+ visibility: 1 - this.observableRatio,
152
+ coverage: darkFieldSize / (darkFieldSize + observableCount),
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Generate dark field patterns based on type and observables
158
+ * @param {string} type - Pattern type
159
+ * @param {Array<string>} observablePatterns - Observable patterns
160
+ * @param {number} targetSize - Target dark field size
161
+ * @returns {Array<string>} Dark field patterns
162
+ * @private
163
+ */
164
+ _generateDarkFieldPatterns(type, observablePatterns, targetSize) {
165
+ const darkField = [];
166
+ const generators = {
167
+ market: this._generateMarketDarkField.bind(this),
168
+ organizational: this._generateOrganizationalDarkField.bind(this),
169
+ strategic: this._generateStrategicDarkField.bind(this),
170
+ disruption: this._generateDisruptionDarkField.bind(this),
171
+ };
172
+
173
+ const generator = generators[type] || generators.market;
174
+ return generator(observablePatterns, targetSize);
175
+ }
176
+
177
+ /**
178
+ * Generate market dynamics dark field
179
+ * @param {Array<string>} patterns - Observable patterns
180
+ * @param {number} size - Target size
181
+ * @returns {Array<string>} Dark field patterns
182
+ * @private
183
+ */
184
+ _generateMarketDarkField(patterns, size) {
185
+ const darkField = [];
186
+ const dimensions = [
187
+ 'hidden_customer_needs',
188
+ 'latent_market_segments',
189
+ 'unspoken_value_drivers',
190
+ 'invisible_competition',
191
+ 'emergent_demand_patterns',
192
+ 'tacit_buying_criteria',
193
+ 'underground_distribution_channels',
194
+ 'implicit_price_expectations',
195
+ ];
196
+
197
+ for (let i = 0; i < size; i++) {
198
+ const dimension = dimensions[i % dimensions.length];
199
+ const patternIndex = i % patterns.length;
200
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
201
+ }
202
+
203
+ return darkField;
204
+ }
205
+
206
+ /**
207
+ * Generate organizational dynamics dark field
208
+ * @param {Array<string>} patterns - Observable patterns
209
+ * @param {number} size - Target size
210
+ * @returns {Array<string>} Dark field patterns
211
+ * @private
212
+ */
213
+ _generateOrganizationalDarkField(patterns, size) {
214
+ const darkField = [];
215
+ const dimensions = [
216
+ 'informal_power_structures',
217
+ 'tacit_knowledge_networks',
218
+ 'hidden_resource_flows',
219
+ 'implicit_decision_criteria',
220
+ 'unwritten_cultural_norms',
221
+ 'latent_capability_reserves',
222
+ 'invisible_coordination_mechanisms',
223
+ 'emergent_collaboration_patterns',
224
+ ];
225
+
226
+ for (let i = 0; i < size; i++) {
227
+ const dimension = dimensions[i % dimensions.length];
228
+ const patternIndex = i % patterns.length;
229
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
230
+ }
231
+
232
+ return darkField;
233
+ }
234
+
235
+ /**
236
+ * Generate strategic dynamics dark field
237
+ * @param {Array<string>} patterns - Observable patterns
238
+ * @param {number} size - Target size
239
+ * @returns {Array<string>} Dark field patterns
240
+ * @private
241
+ */
242
+ _generateStrategicDarkField(patterns, size) {
243
+ const darkField = [];
244
+ const dimensions = [
245
+ 'latent_strategic_options',
246
+ 'hidden_competitive_advantages',
247
+ 'implicit_strategic_assumptions',
248
+ 'emergent_industry_shifts',
249
+ 'tacit_success_factors',
250
+ 'invisible_threat_vectors',
251
+ 'unrecognized_opportunities',
252
+ 'hidden_ecosystem_dependencies',
253
+ ];
254
+
255
+ for (let i = 0; i < size; i++) {
256
+ const dimension = dimensions[i % dimensions.length];
257
+ const patternIndex = i % patterns.length;
258
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
259
+ }
260
+
261
+ return darkField;
262
+ }
263
+
264
+ /**
265
+ * Generate disruption arithmetic dark field
266
+ * @param {Array<string>} patterns - Observable patterns
267
+ * @param {number} size - Target size
268
+ * @returns {Array<string>} Dark field patterns
269
+ * @private
270
+ */
271
+ _generateDisruptionDarkField(patterns, size) {
272
+ const darkField = [];
273
+ const dimensions = [
274
+ 'latent_disruption_vectors',
275
+ 'hidden_innovation_barriers',
276
+ 'implicit_adoption_triggers',
277
+ 'emergent_technology_convergence',
278
+ 'tacit_resistance_patterns',
279
+ 'invisible_tipping_points',
280
+ 'unrecognized_substitutes',
281
+ 'hidden_value_chain_vulnerabilities',
282
+ ];
283
+
284
+ for (let i = 0; i < size; i++) {
285
+ const dimension = dimensions[i % dimensions.length];
286
+ const patternIndex = i % patterns.length;
287
+ darkField.push(`${dimension}:derived_from:${patterns[patternIndex]}`);
288
+ }
289
+
290
+ return darkField;
291
+ }
292
+
293
+ /**
294
+ * Compute completeness of closure
295
+ * @param {Object} observable - Observable pattern
296
+ * @param {Object} darkField - Dark field
297
+ * @returns {number} Completeness ratio [0, 1]
298
+ * @private
299
+ */
300
+ _computeCompleteness(observable, darkField) {
301
+ const totalPatterns = observable.patterns.length + darkField.patterns.length;
302
+ const coverageScore = darkField.patterns.length / totalPatterns;
303
+
304
+ // Completeness is high when dark field coverage approaches (1 - observableRatio)
305
+ const targetCoverage = 1 - this.observableRatio;
306
+ const completeness = Math.min(1, coverageScore / targetCoverage);
307
+
308
+ return completeness;
309
+ }
310
+
311
+ /**
312
+ * Get operator metrics
313
+ * @returns {Object} Metrics
314
+ */
315
+ getMetrics() {
316
+ return {
317
+ ...this.metrics,
318
+ operatorId: this.operatorId,
319
+ observableRatio: this.observableRatio,
320
+ closureThreshold: this.closureThreshold,
321
+ };
322
+ }
323
+
324
+ /**
325
+ * Reset operator metrics
326
+ */
327
+ resetMetrics() {
328
+ this.metrics = {
329
+ closureOperations: 0,
330
+ averageCompleteness: 0,
331
+ totalDarkFieldRevealed: 0,
332
+ };
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Create a Chatman operator instance
338
+ * @param {Object} [options] - Operator options
339
+ * @returns {ChatmanOperator} Operator instance
340
+ */
341
+ export function createChatmanOperator(options = {}) {
342
+ return new ChatmanOperator(options);
343
+ }
@@ -0,0 +1,332 @@
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(
174
+ dimensions,
175
+ observablePatterns,
176
+ targetSize,
177
+ options
178
+ );
179
+ }
180
+
181
+ /**
182
+ * Detect organizational dark field patterns
183
+ * @param {Array<string>} observablePatterns - Observable patterns
184
+ * @param {number} targetSize - Target size
185
+ * @param {Object} options - Options
186
+ * @returns {Array<Object>} Detected patterns
187
+ * @private
188
+ */
189
+ _detectOrganizationalDarkField(observablePatterns, targetSize, options) {
190
+ const dimensions = [
191
+ 'informal_power_structures',
192
+ 'tacit_knowledge_networks',
193
+ 'hidden_resource_flows',
194
+ 'implicit_decision_criteria',
195
+ 'unwritten_cultural_norms',
196
+ ];
197
+
198
+ return this._generateDetectedPatterns(
199
+ dimensions,
200
+ observablePatterns,
201
+ targetSize,
202
+ options
203
+ );
204
+ }
205
+
206
+ /**
207
+ * Detect strategic dark field patterns
208
+ * @param {Array<string>} observablePatterns - Observable patterns
209
+ * @param {number} targetSize - Target size
210
+ * @param {Object} options - Options
211
+ * @returns {Array<Object>} Detected patterns
212
+ * @private
213
+ */
214
+ _detectStrategicDarkField(observablePatterns, targetSize, options) {
215
+ const dimensions = [
216
+ 'latent_strategic_options',
217
+ 'hidden_competitive_advantages',
218
+ 'implicit_strategic_assumptions',
219
+ 'emergent_industry_shifts',
220
+ 'tacit_success_factors',
221
+ ];
222
+
223
+ return this._generateDetectedPatterns(
224
+ dimensions,
225
+ observablePatterns,
226
+ targetSize,
227
+ options
228
+ );
229
+ }
230
+
231
+ /**
232
+ * Detect disruption dark field patterns
233
+ * @param {Array<string>} observablePatterns - Observable patterns
234
+ * @param {number} targetSize - Target size
235
+ * @param {Object} options - Options
236
+ * @returns {Array<Object>} Detected patterns
237
+ * @private
238
+ */
239
+ _detectDisruptionDarkField(observablePatterns, targetSize, options) {
240
+ const dimensions = [
241
+ 'latent_disruption_vectors',
242
+ 'hidden_innovation_barriers',
243
+ 'implicit_adoption_triggers',
244
+ 'emergent_technology_convergence',
245
+ 'tacit_resistance_patterns',
246
+ ];
247
+
248
+ return this._generateDetectedPatterns(
249
+ dimensions,
250
+ observablePatterns,
251
+ targetSize,
252
+ options
253
+ );
254
+ }
255
+
256
+ /**
257
+ * Generate detected patterns from dimensions
258
+ * @param {Array<string>} dimensions - Pattern dimensions
259
+ * @param {Array<string>} observablePatterns - Observable patterns
260
+ * @param {number} targetSize - Target size
261
+ * @param {Object} options - Options
262
+ * @returns {Array<Object>} Detected patterns
263
+ * @private
264
+ */
265
+ _generateDetectedPatterns(dimensions, observablePatterns, targetSize, options) {
266
+ const patterns = [];
267
+ const maxPatterns = Math.min(targetSize, options.maxPatterns);
268
+
269
+ for (let i = 0; i < maxPatterns; i++) {
270
+ const dimension = dimensions[i % dimensions.length];
271
+ const patternIndex = i % observablePatterns.length;
272
+ const confidence = this._calculateConfidence(i, maxPatterns, options.minConfidence);
273
+
274
+ if (confidence >= options.minConfidence) {
275
+ patterns.push({
276
+ dimension,
277
+ confidence,
278
+ derivedFrom: [observablePatterns[patternIndex]],
279
+ });
280
+ }
281
+ }
282
+
283
+ return patterns;
284
+ }
285
+
286
+ /**
287
+ * Calculate confidence score for pattern
288
+ * @param {number} index - Pattern index
289
+ * @param {number} total - Total patterns
290
+ * @param {number} minConfidence - Minimum confidence
291
+ * @returns {number} Confidence score
292
+ * @private
293
+ */
294
+ _calculateConfidence(index, total, minConfidence) {
295
+ // Confidence decreases slightly as we generate more patterns
296
+ const decay = 0.1;
297
+ const baseConfidence = 0.95;
298
+ const confidence = baseConfidence - (index / total) * decay;
299
+ return Math.max(minConfidence, confidence);
300
+ }
301
+
302
+ /**
303
+ * Get detector metrics
304
+ * @returns {Object} Metrics
305
+ */
306
+ getMetrics() {
307
+ return {
308
+ ...this.metrics,
309
+ targetRatio: this.targetRatio,
310
+ };
311
+ }
312
+
313
+ /**
314
+ * Reset detector metrics
315
+ */
316
+ resetMetrics() {
317
+ this.metrics = {
318
+ detectionsPerformed: 0,
319
+ averageDarkFieldRatio: 0,
320
+ totalPatternsDetected: 0,
321
+ };
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Create a dark field detector instance
327
+ * @param {Object} [options] - Detector options
328
+ * @returns {DarkFieldDetector} Detector instance
329
+ */
330
+ export function createDarkFieldDetector(options = {}) {
331
+ return new DarkFieldDetector(options);
332
+ }