agentic-qe 3.7.21 → 3.8.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 (164) hide show
  1. package/.claude/helpers/brain-checkpoint.cjs +4 -1
  2. package/.claude/helpers/statusline-v3.cjs +3 -1
  3. package/.claude/skills/skills-manifest.json +1 -1
  4. package/CHANGELOG.md +45 -0
  5. package/README.md +2 -14
  6. package/assets/helpers/statusline-v3.cjs +3 -1
  7. package/dist/cli/brain-commands.js +6 -10
  8. package/dist/cli/bundle.js +7441 -4327
  9. package/dist/cli/commands/audit.d.ts +43 -0
  10. package/dist/cli/commands/audit.js +125 -0
  11. package/dist/cli/commands/hooks.js +29 -6
  12. package/dist/cli/commands/init.js +1 -73
  13. package/dist/cli/commands/learning.js +270 -13
  14. package/dist/cli/commands/ruvector-commands.d.ts +15 -0
  15. package/dist/cli/commands/ruvector-commands.js +271 -0
  16. package/dist/cli/handlers/init-handler.d.ts +0 -1
  17. package/dist/cli/handlers/init-handler.js +0 -6
  18. package/dist/cli/index.js +4 -2
  19. package/dist/context/sources/defect-source.js +2 -2
  20. package/dist/context/sources/memory-source.js +2 -2
  21. package/dist/context/sources/requirements-source.js +2 -2
  22. package/dist/coordination/behavior-tree/decorators.d.ts +108 -0
  23. package/dist/coordination/behavior-tree/decorators.js +251 -0
  24. package/dist/coordination/behavior-tree/index.d.ts +12 -0
  25. package/dist/coordination/behavior-tree/index.js +15 -0
  26. package/dist/coordination/behavior-tree/nodes.d.ts +165 -0
  27. package/dist/coordination/behavior-tree/nodes.js +338 -0
  28. package/dist/coordination/behavior-tree/qe-trees.d.ts +105 -0
  29. package/dist/coordination/behavior-tree/qe-trees.js +181 -0
  30. package/dist/coordination/coherence-action-gate.d.ts +284 -0
  31. package/dist/coordination/coherence-action-gate.js +512 -0
  32. package/dist/coordination/index.d.ts +4 -0
  33. package/dist/coordination/index.js +8 -0
  34. package/dist/coordination/reasoning-qec.d.ts +315 -0
  35. package/dist/coordination/reasoning-qec.js +585 -0
  36. package/dist/coordination/task-executor.d.ts +16 -0
  37. package/dist/coordination/task-executor.js +99 -0
  38. package/dist/coordination/workflow-orchestrator.d.ts +29 -0
  39. package/dist/coordination/workflow-orchestrator.js +42 -0
  40. package/dist/domains/visual-accessibility/cnn-visual-regression.d.ts +135 -0
  41. package/dist/domains/visual-accessibility/cnn-visual-regression.js +327 -0
  42. package/dist/domains/visual-accessibility/index.d.ts +1 -0
  43. package/dist/domains/visual-accessibility/index.js +4 -0
  44. package/dist/governance/coherence-validator.d.ts +112 -0
  45. package/dist/governance/coherence-validator.js +180 -0
  46. package/dist/governance/index.d.ts +1 -0
  47. package/dist/governance/index.js +2 -0
  48. package/dist/governance/witness-chain.d.ts +311 -0
  49. package/dist/governance/witness-chain.js +509 -0
  50. package/dist/init/index.d.ts +0 -2
  51. package/dist/init/index.js +0 -1
  52. package/dist/init/init-wizard-steps.d.ts +10 -0
  53. package/dist/init/init-wizard-steps.js +87 -1
  54. package/dist/init/init-wizard.d.ts +1 -9
  55. package/dist/init/init-wizard.js +3 -69
  56. package/dist/init/orchestrator.js +0 -1
  57. package/dist/init/phases/01-detection.js +0 -27
  58. package/dist/init/phases/07-hooks.js +6 -4
  59. package/dist/init/phases/phase-interface.d.ts +0 -1
  60. package/dist/init/settings-merge.js +1 -1
  61. package/dist/integrations/browser/qe-dashboard/clustering.d.ts +48 -0
  62. package/dist/integrations/browser/qe-dashboard/clustering.js +183 -0
  63. package/dist/integrations/browser/qe-dashboard/index.d.ts +12 -0
  64. package/dist/integrations/browser/qe-dashboard/index.js +15 -0
  65. package/dist/integrations/browser/qe-dashboard/pattern-explorer.d.ts +165 -0
  66. package/dist/integrations/browser/qe-dashboard/pattern-explorer.js +260 -0
  67. package/dist/integrations/browser/qe-dashboard/wasm-vector-store.d.ts +144 -0
  68. package/dist/integrations/browser/qe-dashboard/wasm-vector-store.js +277 -0
  69. package/dist/integrations/ruvector/cognitive-container-codec.d.ts +51 -0
  70. package/dist/integrations/ruvector/cognitive-container-codec.js +180 -0
  71. package/dist/integrations/ruvector/cognitive-container.d.ts +125 -0
  72. package/dist/integrations/ruvector/cognitive-container.js +306 -0
  73. package/dist/integrations/ruvector/coherence-gate.d.ts +309 -0
  74. package/dist/integrations/ruvector/coherence-gate.js +631 -0
  75. package/dist/integrations/ruvector/compressed-hnsw-integration.d.ts +176 -0
  76. package/dist/integrations/ruvector/compressed-hnsw-integration.js +301 -0
  77. package/dist/integrations/ruvector/dither-adapter.d.ts +122 -0
  78. package/dist/integrations/ruvector/dither-adapter.js +295 -0
  79. package/dist/integrations/ruvector/domain-transfer.d.ts +129 -0
  80. package/dist/integrations/ruvector/domain-transfer.js +220 -0
  81. package/dist/integrations/ruvector/feature-flags.d.ts +214 -2
  82. package/dist/integrations/ruvector/feature-flags.js +167 -2
  83. package/dist/integrations/ruvector/filter-adapter.d.ts +71 -0
  84. package/dist/integrations/ruvector/filter-adapter.js +285 -0
  85. package/dist/integrations/ruvector/gnn-wrapper.d.ts +20 -0
  86. package/dist/integrations/ruvector/gnn-wrapper.js +40 -0
  87. package/dist/integrations/ruvector/hnsw-health-monitor.d.ts +237 -0
  88. package/dist/integrations/ruvector/hnsw-health-monitor.js +394 -0
  89. package/dist/integrations/ruvector/index.d.ts +8 -2
  90. package/dist/integrations/ruvector/index.js +18 -2
  91. package/dist/integrations/ruvector/interfaces.d.ts +40 -0
  92. package/dist/integrations/ruvector/sona-persistence.d.ts +54 -0
  93. package/dist/integrations/ruvector/sona-persistence.js +162 -0
  94. package/dist/integrations/ruvector/sona-three-loop.d.ts +392 -0
  95. package/dist/integrations/ruvector/sona-three-loop.js +814 -0
  96. package/dist/integrations/ruvector/sona-wrapper.d.ts +97 -0
  97. package/dist/integrations/ruvector/sona-wrapper.js +147 -3
  98. package/dist/integrations/ruvector/spectral-math.d.ts +101 -0
  99. package/dist/integrations/ruvector/spectral-math.js +254 -0
  100. package/dist/integrations/ruvector/temporal-compression.d.ts +163 -0
  101. package/dist/integrations/ruvector/temporal-compression.js +318 -0
  102. package/dist/integrations/ruvector/thompson-sampler.d.ts +61 -0
  103. package/dist/integrations/ruvector/thompson-sampler.js +118 -0
  104. package/dist/integrations/ruvector/transfer-coherence-stub.d.ts +80 -0
  105. package/dist/integrations/ruvector/transfer-coherence-stub.js +63 -0
  106. package/dist/integrations/ruvector/transfer-verification.d.ts +119 -0
  107. package/dist/integrations/ruvector/transfer-verification.js +115 -0
  108. package/dist/kernel/hnsw-adapter.d.ts +52 -1
  109. package/dist/kernel/hnsw-adapter.js +139 -4
  110. package/dist/kernel/hnsw-index-provider.d.ts +5 -0
  111. package/dist/kernel/native-hnsw-backend.d.ts +110 -0
  112. package/dist/kernel/native-hnsw-backend.js +408 -0
  113. package/dist/kernel/unified-memory.js +5 -6
  114. package/dist/learning/aqe-learning-engine.d.ts +2 -0
  115. package/dist/learning/aqe-learning-engine.js +65 -0
  116. package/dist/learning/experience-capture-middleware.js +20 -0
  117. package/dist/learning/experience-capture.d.ts +10 -0
  118. package/dist/learning/experience-capture.js +34 -0
  119. package/dist/learning/index.d.ts +2 -2
  120. package/dist/learning/index.js +4 -4
  121. package/dist/learning/metrics-tracker.d.ts +11 -0
  122. package/dist/learning/metrics-tracker.js +29 -13
  123. package/dist/learning/pattern-lifecycle.d.ts +30 -1
  124. package/dist/learning/pattern-lifecycle.js +92 -20
  125. package/dist/learning/pattern-store.d.ts +8 -0
  126. package/dist/learning/pattern-store.js +8 -2
  127. package/dist/learning/qe-unified-memory.js +1 -28
  128. package/dist/learning/regret-tracker.d.ts +201 -0
  129. package/dist/learning/regret-tracker.js +361 -0
  130. package/dist/mcp/bundle.js +5915 -474
  131. package/dist/routing/index.d.ts +4 -2
  132. package/dist/routing/index.js +3 -1
  133. package/dist/routing/neural-tiny-dancer-router.d.ts +268 -0
  134. package/dist/routing/neural-tiny-dancer-router.js +514 -0
  135. package/dist/routing/queen-integration.js +5 -5
  136. package/dist/routing/routing-config.d.ts +6 -0
  137. package/dist/routing/routing-config.js +1 -0
  138. package/dist/routing/simple-neural-router.d.ts +76 -0
  139. package/dist/routing/simple-neural-router.js +202 -0
  140. package/dist/routing/tiny-dancer-router.d.ts +20 -1
  141. package/dist/routing/tiny-dancer-router.js +21 -2
  142. package/dist/test-scheduling/dag-attention-scheduler.d.ts +81 -0
  143. package/dist/test-scheduling/dag-attention-scheduler.js +358 -0
  144. package/dist/test-scheduling/dag-attention-types.d.ts +81 -0
  145. package/dist/test-scheduling/dag-attention-types.js +10 -0
  146. package/dist/test-scheduling/index.d.ts +1 -0
  147. package/dist/test-scheduling/index.js +4 -0
  148. package/dist/test-scheduling/pipeline.d.ts +8 -0
  149. package/dist/test-scheduling/pipeline.js +28 -0
  150. package/package.json +6 -2
  151. package/dist/cli/commands/migrate.d.ts +0 -9
  152. package/dist/cli/commands/migrate.js +0 -566
  153. package/dist/init/init-wizard-migration.d.ts +0 -52
  154. package/dist/init/init-wizard-migration.js +0 -345
  155. package/dist/init/migration/config-migrator.d.ts +0 -31
  156. package/dist/init/migration/config-migrator.js +0 -149
  157. package/dist/init/migration/data-migrator.d.ts +0 -72
  158. package/dist/init/migration/data-migrator.js +0 -232
  159. package/dist/init/migration/detector.d.ts +0 -44
  160. package/dist/init/migration/detector.js +0 -105
  161. package/dist/init/migration/index.d.ts +0 -8
  162. package/dist/init/migration/index.js +0 -8
  163. package/dist/learning/v2-to-v3-migration.d.ts +0 -86
  164. package/dist/learning/v2-to-v3-migration.js +0 -529
@@ -0,0 +1,631 @@
1
+ /**
2
+ * Coherence Gate (Task 3.1, ADR-083)
3
+ *
4
+ * Validates AI-generated test artifacts using heuristic coherence scoring
5
+ * based on word-level feature similarity. Detects hallucinated or inconsistent
6
+ * test outputs by measuring the energy deviation from expected pattern consistency.
7
+ *
8
+ * Compute ladder:
9
+ * - Reflex (<1ms): Simple heuristic checks (assertion count, coverage overlap)
10
+ * - Retrieval (~10ms): Full word-frequency coherence computation
11
+ *
12
+ * Implements ITransferCoherenceGate for cross-domain transfer validation.
13
+ * Uses Blake3 hash-chained witness records for audit trail.
14
+ *
15
+ * @module integrations/ruvector/coherence-gate
16
+ * @see ADR-083-coherence-gated-agent-actions.md
17
+ */
18
+ import { createHash, randomUUID } from 'crypto';
19
+ import { createRequire } from 'module';
20
+ import { LoggerFactory } from '../../logging/index.js';
21
+ // Use createRequire for native CJS/WASM modules
22
+ const esmRequire = createRequire(import.meta.url);
23
+ import { getRuVectorFeatureFlags } from './feature-flags.js';
24
+ const logger = LoggerFactory.create('coherence-gate');
25
+ let cohomologyEngine = null;
26
+ let cohomologyLoadAttempted = false;
27
+ /**
28
+ * Lazily load the CohomologyEngine from prime-radiant-advanced-wasm.
29
+ * Returns null if the WASM module is unavailable.
30
+ */
31
+ function getCohomologyEngine() {
32
+ if (cohomologyLoadAttempted)
33
+ return cohomologyEngine;
34
+ cohomologyLoadAttempted = true;
35
+ try {
36
+ const pr = esmRequire('prime-radiant-advanced-wasm');
37
+ const fs = esmRequire('fs');
38
+ const path = esmRequire('path');
39
+ const wasmPath = path.join(path.dirname(require.resolve('prime-radiant-advanced-wasm')), 'prime_radiant_advanced_wasm_bg.wasm');
40
+ pr.initSync({ module: fs.readFileSync(wasmPath) });
41
+ cohomologyEngine = new pr.CohomologyEngine();
42
+ logger.info('CohomologyEngine loaded from prime-radiant-advanced-wasm');
43
+ }
44
+ catch (err) {
45
+ logger.debug('CohomologyEngine unavailable, using word-frequency fallback', { error: String(err) });
46
+ cohomologyEngine = null;
47
+ }
48
+ return cohomologyEngine;
49
+ }
50
+ /**
51
+ * Reset the CohomologyEngine loader state (for testing).
52
+ */
53
+ export function resetCohomologyEngineLoader() {
54
+ cohomologyEngine = null;
55
+ cohomologyLoadAttempted = false;
56
+ }
57
+ /** Default coherence threshold (Normal regime) */
58
+ export const DEFAULT_COHERENCE_THRESHOLD = 0.4;
59
+ /** Weights for energy component computation */
60
+ const ENERGY_WEIGHTS = {
61
+ assertionCoverage: 0.4,
62
+ codeCoverage: 0.3,
63
+ confidencePenalty: 0.3,
64
+ contradictionWeight: 0.2,
65
+ laplacianWeight: 0.15,
66
+ };
67
+ /** Reflex tier latency cutoff in ms */
68
+ const REFLEX_LATENCY_BUDGET_MS = 1;
69
+ // ============================================================================
70
+ // Coherence Gate Implementation
71
+ // ============================================================================
72
+ /**
73
+ * Coherence gate for validating AI-generated test artifacts.
74
+ *
75
+ * Uses word-level heuristic coherence scoring to detect hallucinated or
76
+ * inconsistent test outputs. Implements ITransferCoherenceGate for
77
+ * cross-domain transfer validation compatibility.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const gate = new CoherenceGate();
82
+ * const result = gate.validate({
83
+ * assertions: ['expect(result).toBe(true)'],
84
+ * observedBehavior: ['result was true'],
85
+ * coverage: 0.85,
86
+ * domain: 'test-generation',
87
+ * confidence: 0.9,
88
+ * });
89
+ * if (!result.passed) {
90
+ * console.warn('Artifact may be hallucinated:', result.reason);
91
+ * }
92
+ * ```
93
+ */
94
+ export class CoherenceGate {
95
+ threshold;
96
+ decisionLog = [];
97
+ witnessChain = [];
98
+ lastWitnessHash = '0'.repeat(64);
99
+ nativeAvailable = null;
100
+ constructor(threshold = DEFAULT_COHERENCE_THRESHOLD) {
101
+ this.threshold = threshold;
102
+ }
103
+ // ==========================================================================
104
+ // Core API
105
+ // ==========================================================================
106
+ /**
107
+ * Compute coherence energy for a test artifact.
108
+ *
109
+ * Uses a two-tier compute ladder:
110
+ * - Reflex (<1ms): Simple heuristic checks
111
+ * - Retrieval (~10ms): Full sheaf Laplacian computation
112
+ *
113
+ * @param artifact - The test artifact to evaluate
114
+ * @param forceRetrieval - If true, skip reflex and go straight to retrieval
115
+ * @returns Coherence result with energy score and component breakdown
116
+ */
117
+ computeEnergy(artifact, forceRetrieval = false) {
118
+ const startTime = performance.now();
119
+ // Tier 1: Reflex check
120
+ if (!forceRetrieval) {
121
+ const reflexResult = this.computeReflexEnergy(artifact);
122
+ const reflexLatency = performance.now() - startTime;
123
+ if (reflexLatency <= REFLEX_LATENCY_BUDGET_MS) {
124
+ return {
125
+ energy: reflexResult.energy,
126
+ tier: 'reflex',
127
+ components: reflexResult.components,
128
+ latencyMs: reflexLatency,
129
+ };
130
+ }
131
+ }
132
+ // Tier 2: Full retrieval computation
133
+ const retrievalResult = this.computeRetrievalEnergy(artifact);
134
+ const latencyMs = performance.now() - startTime;
135
+ return {
136
+ energy: retrievalResult.energy,
137
+ tier: 'retrieval',
138
+ components: retrievalResult.components,
139
+ latencyMs,
140
+ };
141
+ }
142
+ /**
143
+ * Validate a test artifact against the coherence threshold.
144
+ *
145
+ * @param artifact - The test artifact to validate
146
+ * @param threshold - Optional override for the default threshold
147
+ * @returns Validation result with witness record
148
+ */
149
+ validate(artifact, threshold) {
150
+ const effectiveThreshold = threshold ?? this.threshold;
151
+ const coherenceResult = this.computeEnergy(artifact);
152
+ const passed = coherenceResult.energy <= effectiveThreshold;
153
+ // Build reason for failure
154
+ let reason;
155
+ if (!passed) {
156
+ reason = this.buildFailureReason(coherenceResult, effectiveThreshold);
157
+ }
158
+ // Create witness record
159
+ const witness = this.createWitnessRecord(artifact, coherenceResult.energy, effectiveThreshold, passed);
160
+ // Log decision
161
+ this.logDecision({
162
+ id: witness.id,
163
+ timestamp: witness.timestamp,
164
+ domain: artifact.domain,
165
+ energy: coherenceResult.energy,
166
+ tier: coherenceResult.tier,
167
+ passed,
168
+ threshold: effectiveThreshold,
169
+ });
170
+ return {
171
+ passed,
172
+ energy: coherenceResult.energy,
173
+ threshold: effectiveThreshold,
174
+ reason,
175
+ witness,
176
+ };
177
+ }
178
+ /**
179
+ * Get the decision log for observability.
180
+ */
181
+ getDecisionLog() {
182
+ return [...this.decisionLog];
183
+ }
184
+ /**
185
+ * Get the witness chain for audit purposes.
186
+ */
187
+ getWitnessChain() {
188
+ return [...this.witnessChain];
189
+ }
190
+ /**
191
+ * Get the current threshold.
192
+ */
193
+ getThreshold() {
194
+ return this.threshold;
195
+ }
196
+ /**
197
+ * Clear the decision log (for testing).
198
+ */
199
+ clearDecisionLog() {
200
+ this.decisionLog = [];
201
+ }
202
+ // ==========================================================================
203
+ // ITransferCoherenceGate Implementation
204
+ // ==========================================================================
205
+ /**
206
+ * Validate whether a pattern can be transferred to a target domain
207
+ * without introducing coherence violations.
208
+ *
209
+ * Converts the pattern into a TestArtifact and runs coherence validation.
210
+ */
211
+ validateTransfer(pattern, targetDomain) {
212
+ const flags = getRuVectorFeatureFlags();
213
+ if (!flags.useCoherenceGate) {
214
+ return { approved: true };
215
+ }
216
+ // Convert pattern to test artifact for coherence check
217
+ const artifact = {
218
+ assertions: this.extractAssertions(pattern),
219
+ observedBehavior: this.extractObservedBehavior(pattern),
220
+ coverage: typeof pattern.coverage === 'number' ? pattern.coverage : 0.5,
221
+ domain: targetDomain,
222
+ confidence: pattern.confidence ?? 0.5,
223
+ };
224
+ const result = this.validate(artifact);
225
+ return {
226
+ approved: result.passed,
227
+ energy: result.energy,
228
+ rejectionReason: result.reason,
229
+ };
230
+ }
231
+ // ==========================================================================
232
+ // Private: Reflex Tier (Heuristic Checks)
233
+ // ==========================================================================
234
+ /**
235
+ * Reflex-tier energy computation using simple heuristics.
236
+ * Must complete in <1ms.
237
+ */
238
+ computeReflexEnergy(artifact) {
239
+ const assertionCoverage = this.computeAssertionCoverageEnergy(artifact);
240
+ const codeCoverage = this.computeCodeCoverageEnergy(artifact);
241
+ const confidencePenalty = this.computeConfidencePenalty(artifact);
242
+ const energy = Math.min(assertionCoverage * ENERGY_WEIGHTS.assertionCoverage +
243
+ codeCoverage * ENERGY_WEIGHTS.codeCoverage +
244
+ confidencePenalty * ENERGY_WEIGHTS.confidencePenalty, 1);
245
+ return {
246
+ energy,
247
+ components: {
248
+ assertionCoverage,
249
+ codeCoverage,
250
+ confidencePenalty,
251
+ contradictionScore: 0,
252
+ laplacianDeviation: 0,
253
+ },
254
+ };
255
+ }
256
+ // ==========================================================================
257
+ // Private: Retrieval Tier (Full Sheaf Laplacian)
258
+ // ==========================================================================
259
+ /**
260
+ * Retrieval-tier energy computation using sheaf Laplacian.
261
+ * Includes contradiction detection and Laplacian deviation.
262
+ */
263
+ computeRetrievalEnergy(artifact) {
264
+ const assertionCoverage = this.computeAssertionCoverageEnergy(artifact);
265
+ const codeCoverage = this.computeCodeCoverageEnergy(artifact);
266
+ const confidencePenalty = this.computeConfidencePenalty(artifact);
267
+ const contradictionScore = this.detectContradictions(artifact);
268
+ const laplacianDeviation = this.computeLaplacianDeviation(artifact);
269
+ // Weighted combination including retrieval-only components
270
+ const baseEnergy = assertionCoverage * ENERGY_WEIGHTS.assertionCoverage +
271
+ codeCoverage * ENERGY_WEIGHTS.codeCoverage +
272
+ confidencePenalty * ENERGY_WEIGHTS.confidencePenalty;
273
+ const retrievalEnergy = contradictionScore * ENERGY_WEIGHTS.contradictionWeight +
274
+ laplacianDeviation * ENERGY_WEIGHTS.laplacianWeight;
275
+ // Normalize: base has weight sum 1.0, retrieval adds up to 0.35
276
+ // Scale so total is still in [0, 1]
277
+ const totalWeight = ENERGY_WEIGHTS.assertionCoverage +
278
+ ENERGY_WEIGHTS.codeCoverage +
279
+ ENERGY_WEIGHTS.confidencePenalty +
280
+ ENERGY_WEIGHTS.contradictionWeight +
281
+ ENERGY_WEIGHTS.laplacianWeight;
282
+ const energy = Math.min((baseEnergy + retrievalEnergy) / totalWeight, 1);
283
+ return {
284
+ energy,
285
+ components: {
286
+ assertionCoverage,
287
+ codeCoverage,
288
+ confidencePenalty,
289
+ contradictionScore,
290
+ laplacianDeviation,
291
+ },
292
+ };
293
+ }
294
+ // ==========================================================================
295
+ // Private: Energy Component Functions
296
+ // ==========================================================================
297
+ /**
298
+ * Compute assertion coverage energy.
299
+ * High energy when assertions far exceed observed behavior (hallucination signal).
300
+ */
301
+ computeAssertionCoverageEnergy(artifact) {
302
+ if (artifact.assertions.length === 0) {
303
+ return 0;
304
+ }
305
+ const ratio = artifact.observedBehavior.length / artifact.assertions.length;
306
+ return Math.max(0, Math.min(1 - ratio, 1));
307
+ }
308
+ /**
309
+ * Compute code coverage energy.
310
+ * Higher energy for lower coverage.
311
+ */
312
+ computeCodeCoverageEnergy(artifact) {
313
+ return Math.max(0, Math.min(1 - artifact.coverage, 1));
314
+ }
315
+ /**
316
+ * Compute confidence penalty.
317
+ * Higher energy for lower confidence.
318
+ */
319
+ computeConfidencePenalty(artifact) {
320
+ return Math.max(0, Math.min(1 - artifact.confidence, 1));
321
+ }
322
+ /**
323
+ * Detect contradictions between assertions and observed behavior.
324
+ *
325
+ * Simple heuristic: look for negation patterns and semantic opposites
326
+ * in the assertion/behavior pairing.
327
+ */
328
+ detectContradictions(artifact) {
329
+ if (artifact.assertions.length === 0 || artifact.observedBehavior.length === 0) {
330
+ return 0;
331
+ }
332
+ let contradictions = 0;
333
+ const negationPatterns = ['not', 'never', 'false', 'undefined', 'null', 'error', 'fail'];
334
+ for (const assertion of artifact.assertions) {
335
+ const assertionLower = assertion.toLowerCase();
336
+ for (const behavior of artifact.observedBehavior) {
337
+ const behaviorLower = behavior.toLowerCase();
338
+ // Check if assertion and behavior have opposing sentiment
339
+ for (const neg of negationPatterns) {
340
+ const assertionHasNeg = assertionLower.includes(neg);
341
+ const behaviorHasNeg = behaviorLower.includes(neg);
342
+ // One has negation, the other does not, and they share a common term
343
+ if (assertionHasNeg !== behaviorHasNeg) {
344
+ const assertionWords = new Set(assertionLower.split(/\s+/));
345
+ const behaviorWords = new Set(behaviorLower.split(/\s+/));
346
+ let shared = 0;
347
+ for (const word of assertionWords) {
348
+ if (behaviorWords.has(word) && word.length > 3) {
349
+ shared++;
350
+ }
351
+ }
352
+ if (shared > 0) {
353
+ contradictions++;
354
+ break;
355
+ }
356
+ }
357
+ }
358
+ }
359
+ }
360
+ return Math.min(contradictions / artifact.assertions.length, 1);
361
+ }
362
+ /**
363
+ * Compute coherence deviation using sheaf Laplacian energy.
364
+ *
365
+ * When `prime-radiant-advanced-wasm` CohomologyEngine is available,
366
+ * builds a sheaf graph from assertion vectors and computes real sheaf
367
+ * Laplacian consistency energy. Falls back to pairwise word-frequency
368
+ * cosine similarity when the WASM module is unavailable.
369
+ *
370
+ * Uses 64-dim word-level feature hashing with FNV-1a for bucket assignment
371
+ * and L2-normalized term-frequency vectors.
372
+ */
373
+ computeLaplacianDeviation(artifact) {
374
+ if (artifact.assertions.length < 2) {
375
+ return 0;
376
+ }
377
+ // Build word-level feature vectors from assertions
378
+ const vectors = artifact.assertions.map(a => this.textToWordFeatureVector(a));
379
+ // Try native CohomologyEngine for real sheaf Laplacian
380
+ const engine = getCohomologyEngine();
381
+ if (engine) {
382
+ try {
383
+ return this.computeNativeLaplacianDeviation(engine, artifact, vectors);
384
+ }
385
+ catch (err) {
386
+ logger.debug('CohomologyEngine.consistencyEnergy failed, using fallback', { error: String(err) });
387
+ }
388
+ }
389
+ // Fallback: pairwise cosine similarity
390
+ return this.computeFallbackLaplacianDeviation(vectors);
391
+ }
392
+ /**
393
+ * Compute Laplacian deviation using the native CohomologyEngine.
394
+ * Builds a sheaf graph where each assertion is a node and related
395
+ * assertion pairs form edges with identity restriction maps.
396
+ */
397
+ computeNativeLaplacianDeviation(engine, artifact, vectors) {
398
+ const dim = vectors[0]?.length ?? 64;
399
+ // Build sheaf graph: each assertion is a node
400
+ const nodes = vectors.map((vec, i) => ({
401
+ id: i,
402
+ label: artifact.assertions[i]?.slice(0, 50) ?? `assertion-${i}`,
403
+ section: vec,
404
+ weight: artifact.confidence,
405
+ }));
406
+ // Build edges: connect all pairs with identity restriction maps
407
+ const edges = [];
408
+ for (let i = 0; i < vectors.length; i++) {
409
+ for (let j = i + 1; j < vectors.length; j++) {
410
+ // Identity restriction map (flat dim x dim matrix)
411
+ const identityMap = [];
412
+ for (let r = 0; r < dim; r++) {
413
+ for (let c = 0; c < dim; c++) {
414
+ identityMap.push(r === c ? 1.0 : 0.0);
415
+ }
416
+ }
417
+ edges.push({
418
+ source: i,
419
+ target: j,
420
+ weight: 1.0,
421
+ restriction_map: identityMap,
422
+ source_dim: dim,
423
+ target_dim: dim,
424
+ });
425
+ }
426
+ }
427
+ const rawEnergy = engine.consistencyEnergy({ nodes, edges });
428
+ // Normalize: raw energy can vary widely; map to [0, 1]
429
+ // Use sigmoid-like scaling: energy / (energy + 1)
430
+ const normalizedEnergy = rawEnergy / (rawEnergy + 1);
431
+ return Math.max(0, Math.min(normalizedEnergy, 1));
432
+ }
433
+ /**
434
+ * Fallback: compute pairwise word-frequency cosine consistency score.
435
+ */
436
+ computeFallbackLaplacianDeviation(vectors) {
437
+ let totalSimilarity = 0;
438
+ let pairCount = 0;
439
+ for (let i = 0; i < vectors.length; i++) {
440
+ for (let j = i + 1; j < vectors.length; j++) {
441
+ totalSimilarity += this.cosineSimilarity(vectors[i], vectors[j]);
442
+ pairCount++;
443
+ }
444
+ }
445
+ if (pairCount === 0) {
446
+ return 0;
447
+ }
448
+ // Average similarity -> deviation
449
+ // High similarity = low deviation, low similarity = high deviation
450
+ const avgSimilarity = totalSimilarity / pairCount;
451
+ return Math.max(0, Math.min(1 - avgSimilarity, 1));
452
+ }
453
+ // ==========================================================================
454
+ // Private: Utility Functions
455
+ // ==========================================================================
456
+ /**
457
+ * Hash a word to a bucket index 0-63 using FNV-1a.
458
+ */
459
+ hashWord(word) {
460
+ let h = 0x811c9dc5; // FNV offset basis
461
+ for (let i = 0; i < word.length; i++) {
462
+ h ^= word.charCodeAt(i);
463
+ h = Math.imul(h, 0x01000193); // FNV prime
464
+ }
465
+ return ((h >>> 0) % 64);
466
+ }
467
+ /**
468
+ * Convert text to a 64-dim word-level feature vector using feature hashing.
469
+ *
470
+ * Tokenizes on whitespace and punctuation, hashes each word to one of 64
471
+ * buckets via FNV-1a, builds a term-frequency vector, and L2-normalizes it.
472
+ */
473
+ textToWordFeatureVector(text) {
474
+ const vec = new Array(64).fill(0);
475
+ const words = text.toLowerCase().split(/[\s,;:.!?()[\]{}"']+/).filter(w => w.length > 0);
476
+ for (const word of words) {
477
+ const bucket = this.hashWord(word);
478
+ vec[bucket]++;
479
+ }
480
+ // L2-normalize
481
+ let norm = 0;
482
+ for (let i = 0; i < 64; i++) {
483
+ norm += vec[i] * vec[i];
484
+ }
485
+ norm = Math.sqrt(norm);
486
+ if (norm > 1e-10) {
487
+ for (let i = 0; i < 64; i++) {
488
+ vec[i] /= norm;
489
+ }
490
+ }
491
+ return vec;
492
+ }
493
+ /**
494
+ * Compute cosine similarity between two vectors.
495
+ */
496
+ cosineSimilarity(a, b) {
497
+ let dot = 0;
498
+ let normA = 0;
499
+ let normB = 0;
500
+ const len = Math.min(a.length, b.length);
501
+ for (let i = 0; i < len; i++) {
502
+ dot += a[i] * b[i];
503
+ normA += a[i] * a[i];
504
+ normB += b[i] * b[i];
505
+ }
506
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
507
+ return denom > 1e-10 ? dot / denom : 0;
508
+ }
509
+ /**
510
+ * Build a human-readable failure reason from coherence results.
511
+ */
512
+ buildFailureReason(result, threshold) {
513
+ const parts = [];
514
+ parts.push(`Coherence energy ${result.energy.toFixed(3)} exceeds threshold ${threshold.toFixed(3)}.`);
515
+ const c = result.components;
516
+ if (c.assertionCoverage > 0.5) {
517
+ parts.push('High assertion-observation mismatch (possible hallucination).');
518
+ }
519
+ if (c.codeCoverage > 0.5) {
520
+ parts.push('Low code coverage.');
521
+ }
522
+ if (c.confidencePenalty > 0.5) {
523
+ parts.push('Low generator confidence.');
524
+ }
525
+ if (c.contradictionScore > 0.3) {
526
+ parts.push('Contradictions detected between assertions and observed behavior.');
527
+ }
528
+ if (c.laplacianDeviation > 0.5) {
529
+ parts.push('Inconsistent assertion structure (high Laplacian deviation).');
530
+ }
531
+ return parts.join(' ');
532
+ }
533
+ /**
534
+ * Create a Blake3-style hash-chained witness record.
535
+ * Falls back to SHA-256 when Blake3 is unavailable.
536
+ */
537
+ createWitnessRecord(artifact, energy, threshold, passed) {
538
+ const id = randomUUID();
539
+ const timestamp = Date.now();
540
+ const artifactHash = this.hashContent(JSON.stringify(artifact));
541
+ const record = {
542
+ id,
543
+ timestamp,
544
+ artifactHash,
545
+ energy,
546
+ threshold,
547
+ passed,
548
+ previousHash: this.lastWitnessHash,
549
+ recordHash: '', // Will be computed below
550
+ };
551
+ // Compute record hash (chain link)
552
+ const hashPayload = `${id}|${timestamp}|${artifactHash}|${energy}|${threshold}|${passed}|${this.lastWitnessHash}`;
553
+ record.recordHash = this.hashContent(hashPayload);
554
+ // Update chain
555
+ const flags = getRuVectorFeatureFlags();
556
+ if (flags.useWitnessChain) {
557
+ this.witnessChain.push(record);
558
+ this.lastWitnessHash = record.recordHash;
559
+ }
560
+ return record;
561
+ }
562
+ /**
563
+ * Hash content using SHA-256 (Blake3 fallback).
564
+ */
565
+ hashContent(content) {
566
+ return createHash('sha256').update(content).digest('hex');
567
+ }
568
+ /**
569
+ * Log a coherence decision for observability.
570
+ */
571
+ logDecision(decision) {
572
+ this.decisionLog.push(decision);
573
+ // Keep bounded
574
+ const maxLog = 1000;
575
+ if (this.decisionLog.length > maxLog) {
576
+ this.decisionLog = this.decisionLog.slice(-maxLog);
577
+ }
578
+ logger.debug('Coherence decision', {
579
+ domain: decision.domain,
580
+ energy: decision.energy,
581
+ tier: decision.tier,
582
+ passed: decision.passed,
583
+ });
584
+ }
585
+ /**
586
+ * Extract assertions from a transfer pattern object.
587
+ */
588
+ extractAssertions(pattern) {
589
+ if (Array.isArray(pattern.assertions)) {
590
+ return pattern.assertions.map(String);
591
+ }
592
+ if (typeof pattern.description === 'string') {
593
+ return [pattern.description];
594
+ }
595
+ return ['transfer-pattern'];
596
+ }
597
+ /**
598
+ * Extract observed behaviors from a transfer pattern object.
599
+ */
600
+ extractObservedBehavior(pattern) {
601
+ if (Array.isArray(pattern.observedBehavior)) {
602
+ return pattern.observedBehavior.map(String);
603
+ }
604
+ if (typeof pattern.evidence === 'string') {
605
+ return [pattern.evidence];
606
+ }
607
+ return ['observed'];
608
+ }
609
+ }
610
+ // ============================================================================
611
+ // Factory
612
+ // ============================================================================
613
+ /**
614
+ * Create a coherence gate instance.
615
+ *
616
+ * @param threshold - Coherence energy threshold (default: 0.4)
617
+ * @returns A new CoherenceGate instance
618
+ */
619
+ export function createCoherenceGate(threshold) {
620
+ return new CoherenceGate(threshold);
621
+ }
622
+ /**
623
+ * Create a transfer coherence gate.
624
+ *
625
+ * Returns the real CoherenceGate implementation (replacing the stub).
626
+ * The CoherenceGate implements ITransferCoherenceGate.
627
+ */
628
+ export function createRealTransferCoherenceGate() {
629
+ return new CoherenceGate();
630
+ }
631
+ //# sourceMappingURL=coherence-gate.js.map