agentic-qe 3.8.11 → 3.8.13

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 (98) hide show
  1. package/.claude/skills/qe-code-intelligence/SKILL.md +29 -20
  2. package/.claude/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  3. package/.claude/skills/qe-quality-assessment/SKILL.md +1 -1
  4. package/.claude/skills/qe-test-generation/SKILL.md +1 -1
  5. package/.claude/skills/skills-manifest.json +1 -1
  6. package/CHANGELOG.md +45 -0
  7. package/README.md +9 -0
  8. package/assets/skills/qe-code-intelligence/SKILL.md +29 -20
  9. package/assets/skills/qe-code-intelligence/evals/qe-code-intelligence.yaml +3 -3
  10. package/assets/skills/qe-quality-assessment/SKILL.md +1 -1
  11. package/assets/skills/qe-test-generation/SKILL.md +1 -1
  12. package/dist/cli/bundle.js +1162 -1046
  13. package/dist/cli/commands/code.js +149 -11
  14. package/dist/cli/commands/init.js +3 -2
  15. package/dist/cli/commands/ruvector-commands.js +17 -0
  16. package/dist/cli/handlers/init-handler.d.ts +1 -0
  17. package/dist/cli/handlers/init-handler.js +15 -10
  18. package/dist/cli/utils/file-discovery.d.ts +1 -0
  19. package/dist/cli/utils/file-discovery.js +1 -1
  20. package/dist/domains/code-intelligence/coordinator-gnn.d.ts +21 -0
  21. package/dist/domains/code-intelligence/coordinator-gnn.js +102 -0
  22. package/dist/domains/contract-testing/coordinator.js +13 -0
  23. package/dist/domains/coverage-analysis/coordinator.js +5 -0
  24. package/dist/domains/defect-intelligence/coordinator.d.ts +1 -0
  25. package/dist/domains/defect-intelligence/coordinator.js +43 -0
  26. package/dist/domains/quality-assessment/coordinator.js +26 -0
  27. package/dist/domains/test-generation/coordinator.js +14 -0
  28. package/dist/init/orchestrator.js +1 -0
  29. package/dist/init/phases/08-mcp.js +4 -4
  30. package/dist/init/phases/phase-interface.d.ts +3 -1
  31. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +11 -0
  32. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +44 -1
  33. package/dist/integrations/rl-suite/algorithms/eprop.d.ts +79 -0
  34. package/dist/integrations/rl-suite/algorithms/eprop.js +284 -0
  35. package/dist/integrations/rl-suite/algorithms/index.d.ts +2 -1
  36. package/dist/integrations/rl-suite/algorithms/index.js +2 -1
  37. package/dist/integrations/rl-suite/index.d.ts +2 -2
  38. package/dist/integrations/rl-suite/index.js +2 -2
  39. package/dist/integrations/rl-suite/interfaces.d.ts +3 -3
  40. package/dist/integrations/rl-suite/interfaces.js +1 -1
  41. package/dist/integrations/rl-suite/orchestrator.d.ts +2 -2
  42. package/dist/integrations/rl-suite/orchestrator.js +3 -2
  43. package/dist/integrations/rl-suite/reward-signals.d.ts +1 -1
  44. package/dist/integrations/rl-suite/reward-signals.js +1 -1
  45. package/dist/integrations/ruvector/coherence-gate-cohomology.d.ts +41 -0
  46. package/dist/integrations/ruvector/coherence-gate-cohomology.js +47 -0
  47. package/dist/integrations/ruvector/coherence-gate-core.d.ts +200 -0
  48. package/dist/integrations/ruvector/coherence-gate-core.js +294 -0
  49. package/dist/integrations/ruvector/coherence-gate-energy.d.ts +136 -0
  50. package/dist/integrations/ruvector/coherence-gate-energy.js +373 -0
  51. package/dist/integrations/ruvector/coherence-gate-vector.d.ts +38 -0
  52. package/dist/integrations/ruvector/coherence-gate-vector.js +76 -0
  53. package/dist/integrations/ruvector/coherence-gate.d.ts +10 -311
  54. package/dist/integrations/ruvector/coherence-gate.js +10 -652
  55. package/dist/integrations/ruvector/cold-tier-trainer.d.ts +103 -0
  56. package/dist/integrations/ruvector/cold-tier-trainer.js +377 -0
  57. package/dist/integrations/ruvector/cusum-detector.d.ts +70 -0
  58. package/dist/integrations/ruvector/cusum-detector.js +142 -0
  59. package/dist/integrations/ruvector/delta-tracker.d.ts +122 -0
  60. package/dist/integrations/ruvector/delta-tracker.js +311 -0
  61. package/dist/integrations/ruvector/domain-transfer.d.ts +79 -1
  62. package/dist/integrations/ruvector/domain-transfer.js +158 -2
  63. package/dist/integrations/ruvector/eprop-learner.d.ts +135 -0
  64. package/dist/integrations/ruvector/eprop-learner.js +351 -0
  65. package/dist/integrations/ruvector/feature-flags.d.ts +177 -0
  66. package/dist/integrations/ruvector/feature-flags.js +145 -0
  67. package/dist/integrations/ruvector/graphmae-encoder.d.ts +88 -0
  68. package/dist/integrations/ruvector/graphmae-encoder.js +360 -0
  69. package/dist/integrations/ruvector/hdc-fingerprint.d.ts +127 -0
  70. package/dist/integrations/ruvector/hdc-fingerprint.js +222 -0
  71. package/dist/integrations/ruvector/hopfield-memory.d.ts +97 -0
  72. package/dist/integrations/ruvector/hopfield-memory.js +238 -0
  73. package/dist/integrations/ruvector/index.d.ts +13 -2
  74. package/dist/integrations/ruvector/index.js +46 -2
  75. package/dist/integrations/ruvector/mincut-wrapper.d.ts +7 -0
  76. package/dist/integrations/ruvector/mincut-wrapper.js +54 -2
  77. package/dist/integrations/ruvector/reservoir-replay.d.ts +172 -0
  78. package/dist/integrations/ruvector/reservoir-replay.js +335 -0
  79. package/dist/integrations/ruvector/solver-adapter.d.ts +93 -0
  80. package/dist/integrations/ruvector/solver-adapter.js +299 -0
  81. package/dist/integrations/ruvector/sona-persistence.d.ts +33 -0
  82. package/dist/integrations/ruvector/sona-persistence.js +47 -0
  83. package/dist/integrations/ruvector/spectral-sparsifier.d.ts +154 -0
  84. package/dist/integrations/ruvector/spectral-sparsifier.js +389 -0
  85. package/dist/integrations/ruvector/temporal-causality.d.ts +63 -0
  86. package/dist/integrations/ruvector/temporal-causality.js +317 -0
  87. package/dist/learning/pattern-promotion.d.ts +63 -0
  88. package/dist/learning/pattern-promotion.js +235 -1
  89. package/dist/learning/pattern-store.d.ts +2 -0
  90. package/dist/learning/pattern-store.js +187 -1
  91. package/dist/learning/sqlite-persistence.d.ts +2 -0
  92. package/dist/learning/sqlite-persistence.js +4 -0
  93. package/dist/mcp/bundle.js +506 -427
  94. package/dist/shared/utils/index.d.ts +1 -0
  95. package/dist/shared/utils/index.js +1 -0
  96. package/dist/shared/utils/xorshift128.d.ts +24 -0
  97. package/dist/shared/utils/xorshift128.js +50 -0
  98. package/package.json +1 -1
@@ -2,18 +2,18 @@
2
2
  * Agentic QE v3 - RL Suite Interfaces
3
3
  *
4
4
  * Reinforcement Learning algorithms for Quality Engineering.
5
- * Per ADR-040, implements 9 RL algorithms for QE-specific applications.
5
+ * Per ADR-040 + ADR-087 R11, implements 10 RL algorithms for QE-specific applications.
6
6
  */
7
7
  import type { DomainName, Priority, AgentType } from '../../shared/types';
8
8
  export type { DomainName } from '../../shared/types';
9
9
  /**
10
10
  * All supported RL algorithms
11
11
  */
12
- export type RLAlgorithmType = 'decision-transformer' | 'q-learning' | 'sarsa' | 'actor-critic' | 'policy-gradient' | 'dqn' | 'ppo' | 'a2c' | 'ddpg';
12
+ export type RLAlgorithmType = 'decision-transformer' | 'q-learning' | 'sarsa' | 'actor-critic' | 'policy-gradient' | 'dqn' | 'ppo' | 'a2c' | 'ddpg' | 'eprop';
13
13
  /**
14
14
  * RL algorithm categories
15
15
  */
16
- export type RLAlgorithmCategory = 'value-based' | 'policy-based' | 'actor-critic' | 'offline-rl' | 'deterministic-policy';
16
+ export type RLAlgorithmCategory = 'value-based' | 'policy-based' | 'actor-critic' | 'offline-rl' | 'deterministic-policy' | 'online-learning';
17
17
  /**
18
18
  * QE domain application for RL algorithms
19
19
  */
@@ -2,7 +2,7 @@
2
2
  * Agentic QE v3 - RL Suite Interfaces
3
3
  *
4
4
  * Reinforcement Learning algorithms for Quality Engineering.
5
- * Per ADR-040, implements 9 RL algorithms for QE-specific applications.
5
+ * Per ADR-040 + ADR-087 R11, implements 10 RL algorithms for QE-specific applications.
6
6
  */
7
7
  // ============================================================================
8
8
  // QE Reward Signal Presets
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Agentic QE v3 - QE RL Suite Orchestrator
3
3
  *
4
- * Main orchestrator for all 9 RL algorithms in QE.
4
+ * Main orchestrator for all 10 RL algorithms in QE.
5
5
  * Provides unified interface for algorithm selection, training, and inference.
6
6
  */
7
7
  import type { RLAlgorithm, RLAlgorithmType, RLState, RLAction, RLPrediction, RLExperience, RLTrainingStats, RLSuiteConfig, DomainName, RewardContext, RewardCalculation } from './interfaces';
@@ -16,7 +16,7 @@ export interface RLSuiteStats {
16
16
  /**
17
17
  * Main orchestrator for QE RL Suite
18
18
  *
19
- * Manages all 9 RL algorithms and provides:
19
+ * Manages all 10 RL algorithms and provides:
20
20
  * - Algorithm selection based on domain/task
21
21
  * - Unified training interface
22
22
  * - Prediction with automatic algorithm routing
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Agentic QE v3 - QE RL Suite Orchestrator
3
3
  *
4
- * Main orchestrator for all 9 RL algorithms in QE.
4
+ * Main orchestrator for all 10 RL algorithms in QE.
5
5
  * Provides unified interface for algorithm selection, training, and inference.
6
6
  */
7
7
  import { QLearningAlgorithm } from './algorithms/q-learning';
@@ -21,7 +21,7 @@ import { getRewardSignalsForDomain, calculateReward } from './reward-signals';
21
21
  /**
22
22
  * Main orchestrator for QE RL Suite
23
23
  *
24
- * Manages all 9 RL algorithms and provides:
24
+ * Manages all 10 RL algorithms and provides:
25
25
  * - Algorithm selection based on domain/task
26
26
  * - Unified training interface
27
27
  * - Prediction with automatic algorithm routing
@@ -347,6 +347,7 @@ export class QERLSuite {
347
347
  'ppo': 0,
348
348
  'a2c': 0,
349
349
  'ddpg': 0,
350
+ 'eprop': 0,
350
351
  },
351
352
  domainUsage: {},
352
353
  lastUpdated: new Date(),
@@ -2,7 +2,7 @@
2
2
  * Agentic QE v3 - QE-Specific Reward Signals
3
3
  *
4
4
  * Domain-specific reward functions for RL algorithms in QE.
5
- * Per ADR-040, implements reward signals for all 9 algorithms.
5
+ * Per ADR-040, implements reward signals for all 10 algorithms.
6
6
  */
7
7
  import type { RewardSignal, RewardContext, RewardCalculation, DomainName } from './interfaces';
8
8
  /**
@@ -2,7 +2,7 @@
2
2
  * Agentic QE v3 - QE-Specific Reward Signals
3
3
  *
4
4
  * Domain-specific reward functions for RL algorithms in QE.
5
- * Per ADR-040, implements reward signals for all 9 algorithms.
5
+ * Per ADR-040, implements reward signals for all 10 algorithms.
6
6
  */
7
7
  // ============================================================================
8
8
  // Test Execution Rewards (for Decision Transformer, DQN, PPO)
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Coherence Gate - CohomologyEngine WASM Lazy Loader
3
+ *
4
+ * Lazily loads the CohomologyEngine from prime-radiant-advanced-wasm.
5
+ * Returns null when the WASM module is unavailable, allowing fallback
6
+ * to word-frequency cosine similarity.
7
+ *
8
+ * @module integrations/ruvector/coherence-gate-cohomology
9
+ * @see ADR-083-coherence-gated-agent-actions.md
10
+ */
11
+ /**
12
+ * Minimal interface for the CohomologyEngine from prime-radiant-advanced-wasm.
13
+ */
14
+ export interface ICohomologyEngine {
15
+ consistencyEnergy(graph: {
16
+ nodes: Array<{
17
+ id: number;
18
+ label: string;
19
+ section: number[];
20
+ weight: number;
21
+ }>;
22
+ edges: Array<{
23
+ source: number;
24
+ target: number;
25
+ weight: number;
26
+ restriction_map: number[];
27
+ source_dim: number;
28
+ target_dim: number;
29
+ }>;
30
+ }): number;
31
+ }
32
+ /**
33
+ * Lazily load the CohomologyEngine from prime-radiant-advanced-wasm.
34
+ * Returns null if the WASM module is unavailable.
35
+ */
36
+ export declare function getCohomologyEngine(): ICohomologyEngine | null;
37
+ /**
38
+ * Reset the CohomologyEngine loader state (for testing).
39
+ */
40
+ export declare function resetCohomologyEngineLoader(): void;
41
+ //# sourceMappingURL=coherence-gate-cohomology.d.ts.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Coherence Gate - CohomologyEngine WASM Lazy Loader
3
+ *
4
+ * Lazily loads the CohomologyEngine from prime-radiant-advanced-wasm.
5
+ * Returns null when the WASM module is unavailable, allowing fallback
6
+ * to word-frequency cosine similarity.
7
+ *
8
+ * @module integrations/ruvector/coherence-gate-cohomology
9
+ * @see ADR-083-coherence-gated-agent-actions.md
10
+ */
11
+ import { createRequire } from 'module';
12
+ import { LoggerFactory } from '../../logging/index.js';
13
+ const esmRequire = createRequire(import.meta.url);
14
+ const logger = LoggerFactory.create('coherence-gate-cohomology');
15
+ let cohomologyEngine = null;
16
+ let cohomologyLoadAttempted = false;
17
+ /**
18
+ * Lazily load the CohomologyEngine from prime-radiant-advanced-wasm.
19
+ * Returns null if the WASM module is unavailable.
20
+ */
21
+ export function getCohomologyEngine() {
22
+ if (cohomologyLoadAttempted)
23
+ return cohomologyEngine;
24
+ cohomologyLoadAttempted = true;
25
+ try {
26
+ const pr = esmRequire('prime-radiant-advanced-wasm');
27
+ const fs = esmRequire('fs');
28
+ const path = esmRequire('path');
29
+ const wasmPath = path.join(path.dirname(require.resolve('prime-radiant-advanced-wasm')), 'prime_radiant_advanced_wasm_bg.wasm');
30
+ pr.initSync({ module: fs.readFileSync(wasmPath) });
31
+ cohomologyEngine = new pr.CohomologyEngine();
32
+ logger.info('CohomologyEngine loaded from prime-radiant-advanced-wasm');
33
+ }
34
+ catch (err) {
35
+ logger.debug('CohomologyEngine unavailable, using word-frequency fallback', { error: String(err) });
36
+ cohomologyEngine = null;
37
+ }
38
+ return cohomologyEngine;
39
+ }
40
+ /**
41
+ * Reset the CohomologyEngine loader state (for testing).
42
+ */
43
+ export function resetCohomologyEngineLoader() {
44
+ cohomologyEngine = null;
45
+ cohomologyLoadAttempted = false;
46
+ }
47
+ //# sourceMappingURL=coherence-gate-cohomology.js.map
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Coherence Gate - Core Module (Task 3.1, ADR-083)
3
+ *
4
+ * CoherenceGate class, public API, types, and factory functions.
5
+ * Validates AI-generated test artifacts using heuristic coherence scoring
6
+ * based on word-level feature similarity.
7
+ *
8
+ * @module integrations/ruvector/coherence-gate-core
9
+ * @see ADR-083-coherence-gated-agent-actions.md
10
+ */
11
+ import type { ITransferCoherenceGate, CoherenceValidation } from './transfer-coherence-stub.js';
12
+ import type { WitnessChain as GovernanceWitnessChain } from '../../governance/witness-chain.js';
13
+ import type { GateType } from './cusum-detector.js';
14
+ /**
15
+ * Test artifact to validate for coherence.
16
+ */
17
+ export interface TestArtifact {
18
+ /** Assertions made by the generated test */
19
+ assertions: string[];
20
+ /** Observed behaviors from actual execution */
21
+ observedBehavior: string[];
22
+ /** Code coverage ratio (0-1) */
23
+ coverage: number;
24
+ /** Domain the test belongs to */
25
+ domain: string;
26
+ /** Confidence score of the generator (0-1) */
27
+ confidence: number;
28
+ }
29
+ /**
30
+ * Result of coherence energy computation.
31
+ */
32
+ export interface CoherenceResult {
33
+ /** Coherence energy score (0-1, lower = more coherent) */
34
+ energy: number;
35
+ /** Which compute tier was used */
36
+ tier: 'reflex' | 'retrieval';
37
+ /** Breakdown of energy components */
38
+ components: EnergyComponents;
39
+ /** Computation latency in milliseconds */
40
+ latencyMs: number;
41
+ }
42
+ /**
43
+ * Breakdown of energy components for explainability.
44
+ */
45
+ export interface EnergyComponents {
46
+ /** Energy from assertion-observation mismatch (0-1) */
47
+ assertionCoverage: number;
48
+ /** Energy from low code coverage (0-1) */
49
+ codeCoverage: number;
50
+ /** Energy from low confidence (0-1) */
51
+ confidencePenalty: number;
52
+ /** Energy from contradiction detection (0-1, retrieval only) */
53
+ contradictionScore: number;
54
+ /** Energy from sheaf Laplacian deviation (0-1, retrieval only) */
55
+ laplacianDeviation: number;
56
+ }
57
+ /**
58
+ * Result of validation against a threshold.
59
+ */
60
+ export interface ValidationResult {
61
+ /** Whether the artifact passes coherence validation */
62
+ passed: boolean;
63
+ /** The coherence energy score */
64
+ energy: number;
65
+ /** The threshold used for validation */
66
+ threshold: number;
67
+ /** Human-readable reason if validation failed */
68
+ reason?: string;
69
+ /** The witness record for this decision */
70
+ witness: WitnessRecord;
71
+ }
72
+ /**
73
+ * Hash-chained witness record for audit trail.
74
+ */
75
+ export interface WitnessRecord {
76
+ /** Unique record identifier */
77
+ id: string;
78
+ /** Timestamp of the decision */
79
+ timestamp: number;
80
+ /** Hash of the artifact that was validated */
81
+ artifactHash: string;
82
+ /** The coherence energy computed */
83
+ energy: number;
84
+ /** The threshold applied */
85
+ threshold: number;
86
+ /** Whether validation passed */
87
+ passed: boolean;
88
+ /** Hash of the previous witness record */
89
+ previousHash: string;
90
+ /** Hash of this record (chained) */
91
+ recordHash: string;
92
+ }
93
+ /**
94
+ * Decision log entry for observability.
95
+ */
96
+ export interface CoherenceDecision {
97
+ /** Unique decision identifier */
98
+ id: string;
99
+ /** Timestamp */
100
+ timestamp: number;
101
+ /** Domain of the artifact */
102
+ domain: string;
103
+ /** Computed energy */
104
+ energy: number;
105
+ /** Compute tier used */
106
+ tier: 'reflex' | 'retrieval';
107
+ /** Whether validation passed */
108
+ passed: boolean;
109
+ /** Threshold used */
110
+ threshold: number;
111
+ }
112
+ /** Default coherence threshold (Normal regime) */
113
+ export declare const DEFAULT_COHERENCE_THRESHOLD = 0.4;
114
+ /**
115
+ * Coherence gate for validating AI-generated test artifacts.
116
+ *
117
+ * Uses word-level heuristic coherence scoring to detect hallucinated or
118
+ * inconsistent test outputs. Implements ITransferCoherenceGate for
119
+ * cross-domain transfer validation compatibility.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const gate = new CoherenceGate();
124
+ * const result = gate.validate({
125
+ * assertions: ['expect(result).toBe(true)'],
126
+ * observedBehavior: ['result was true'],
127
+ * coverage: 0.85,
128
+ * domain: 'test-generation',
129
+ * confidence: 0.9,
130
+ * });
131
+ * if (!result.passed) {
132
+ * console.warn('Artifact may be hallucinated:', result.reason);
133
+ * }
134
+ * ```
135
+ */
136
+ export declare class CoherenceGate implements ITransferCoherenceGate {
137
+ private readonly threshold;
138
+ private decisionLog;
139
+ private witnessChain;
140
+ private lastWitnessHash;
141
+ private nativeAvailable;
142
+ /** Optional governance witness chain for SQLite persistence */
143
+ private governanceChain;
144
+ constructor(threshold?: number);
145
+ /**
146
+ * Attach a governance WitnessChain (or PersistentWitnessChain) for
147
+ * durable persistence of coherence decisions.
148
+ */
149
+ setGovernanceChain(chain: GovernanceWitnessChain): void;
150
+ /**
151
+ * Compute coherence energy for a test artifact.
152
+ *
153
+ * Uses a two-tier compute ladder:
154
+ * - Reflex (<1ms): Simple heuristic checks
155
+ * - Retrieval (~10ms): Full sheaf Laplacian computation
156
+ *
157
+ * @param artifact - Test artifact to evaluate
158
+ * @param forceRetrieval - Skip reflex tier and go straight to retrieval
159
+ * @param gateType - Gate action type for CUSUM drift tracking (default: 'retrieve')
160
+ */
161
+ computeEnergy(artifact: TestArtifact, forceRetrieval?: boolean, gateType?: GateType): CoherenceResult;
162
+ /**
163
+ * Validate a test artifact against the coherence threshold.
164
+ *
165
+ * @param artifact - Test artifact to validate
166
+ * @param threshold - Optional override threshold (default: constructor threshold)
167
+ * @param gateType - Gate action type for CUSUM drift tracking (default: 'retrieve')
168
+ */
169
+ validate(artifact: TestArtifact, threshold?: number, gateType?: GateType): ValidationResult;
170
+ /** Get the decision log for observability. */
171
+ getDecisionLog(): CoherenceDecision[];
172
+ /** Get the witness chain for audit purposes. */
173
+ getWitnessChain(): WitnessRecord[];
174
+ /** Get the current threshold. */
175
+ getThreshold(): number;
176
+ /** Clear the decision log (for testing). */
177
+ clearDecisionLog(): void;
178
+ validateTransfer(pattern: {
179
+ id?: string;
180
+ domain?: string;
181
+ confidence?: number;
182
+ [key: string]: unknown;
183
+ }, targetDomain: string): CoherenceValidation;
184
+ private buildFailureReason;
185
+ private createWitnessRecord;
186
+ private hashContent;
187
+ private logDecision;
188
+ private extractAssertions;
189
+ private extractObservedBehavior;
190
+ }
191
+ /**
192
+ * Create a coherence gate instance.
193
+ */
194
+ export declare function createCoherenceGate(threshold?: number, governanceChain?: GovernanceWitnessChain): CoherenceGate;
195
+ /**
196
+ * Create a transfer coherence gate.
197
+ * Returns the real CoherenceGate implementation (replacing the stub).
198
+ */
199
+ export declare function createRealTransferCoherenceGate(): ITransferCoherenceGate;
200
+ //# sourceMappingURL=coherence-gate-core.d.ts.map
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Coherence Gate - Core Module (Task 3.1, ADR-083)
3
+ *
4
+ * CoherenceGate class, public API, types, and factory functions.
5
+ * Validates AI-generated test artifacts using heuristic coherence scoring
6
+ * based on word-level feature similarity.
7
+ *
8
+ * @module integrations/ruvector/coherence-gate-core
9
+ * @see ADR-083-coherence-gated-agent-actions.md
10
+ */
11
+ import { createHash, randomUUID } from 'crypto';
12
+ import { LoggerFactory } from '../../logging/index.js';
13
+ import { getRuVectorFeatureFlags } from './feature-flags.js';
14
+ import { computeReflexEnergy, computeRetrievalEnergy, REFLEX_LATENCY_BUDGET_MS, } from './coherence-gate-energy.js';
15
+ const logger = LoggerFactory.create('coherence-gate');
16
+ /** Default coherence threshold (Normal regime) */
17
+ export const DEFAULT_COHERENCE_THRESHOLD = 0.4;
18
+ // ============================================================================
19
+ // Coherence Gate Implementation
20
+ // ============================================================================
21
+ /**
22
+ * Coherence gate for validating AI-generated test artifacts.
23
+ *
24
+ * Uses word-level heuristic coherence scoring to detect hallucinated or
25
+ * inconsistent test outputs. Implements ITransferCoherenceGate for
26
+ * cross-domain transfer validation compatibility.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const gate = new CoherenceGate();
31
+ * const result = gate.validate({
32
+ * assertions: ['expect(result).toBe(true)'],
33
+ * observedBehavior: ['result was true'],
34
+ * coverage: 0.85,
35
+ * domain: 'test-generation',
36
+ * confidence: 0.9,
37
+ * });
38
+ * if (!result.passed) {
39
+ * console.warn('Artifact may be hallucinated:', result.reason);
40
+ * }
41
+ * ```
42
+ */
43
+ export class CoherenceGate {
44
+ threshold;
45
+ decisionLog = [];
46
+ witnessChain = [];
47
+ lastWitnessHash = '0'.repeat(64);
48
+ nativeAvailable = null;
49
+ /** Optional governance witness chain for SQLite persistence */
50
+ governanceChain = null;
51
+ constructor(threshold = DEFAULT_COHERENCE_THRESHOLD) {
52
+ this.threshold = threshold;
53
+ }
54
+ /**
55
+ * Attach a governance WitnessChain (or PersistentWitnessChain) for
56
+ * durable persistence of coherence decisions.
57
+ */
58
+ setGovernanceChain(chain) {
59
+ this.governanceChain = chain;
60
+ }
61
+ // ==========================================================================
62
+ // Core API
63
+ // ==========================================================================
64
+ /**
65
+ * Compute coherence energy for a test artifact.
66
+ *
67
+ * Uses a two-tier compute ladder:
68
+ * - Reflex (<1ms): Simple heuristic checks
69
+ * - Retrieval (~10ms): Full sheaf Laplacian computation
70
+ *
71
+ * @param artifact - Test artifact to evaluate
72
+ * @param forceRetrieval - Skip reflex tier and go straight to retrieval
73
+ * @param gateType - Gate action type for CUSUM drift tracking (default: 'retrieve')
74
+ */
75
+ computeEnergy(artifact, forceRetrieval = false, gateType = 'retrieve') {
76
+ const startTime = performance.now();
77
+ // Tier 1: Reflex check
78
+ if (!forceRetrieval) {
79
+ const reflexResult = computeReflexEnergy(artifact, gateType);
80
+ const reflexLatency = performance.now() - startTime;
81
+ if (reflexLatency <= REFLEX_LATENCY_BUDGET_MS) {
82
+ return {
83
+ energy: reflexResult.energy,
84
+ tier: 'reflex',
85
+ components: reflexResult.components,
86
+ latencyMs: reflexLatency,
87
+ };
88
+ }
89
+ }
90
+ // Tier 2: Full retrieval computation
91
+ const retrievalResult = computeRetrievalEnergy(artifact, gateType);
92
+ const latencyMs = performance.now() - startTime;
93
+ return {
94
+ energy: retrievalResult.energy,
95
+ tier: 'retrieval',
96
+ components: retrievalResult.components,
97
+ latencyMs,
98
+ };
99
+ }
100
+ /**
101
+ * Validate a test artifact against the coherence threshold.
102
+ *
103
+ * @param artifact - Test artifact to validate
104
+ * @param threshold - Optional override threshold (default: constructor threshold)
105
+ * @param gateType - Gate action type for CUSUM drift tracking (default: 'retrieve')
106
+ */
107
+ validate(artifact, threshold, gateType = 'retrieve') {
108
+ const effectiveThreshold = threshold ?? this.threshold;
109
+ const coherenceResult = this.computeEnergy(artifact, false, gateType);
110
+ const passed = coherenceResult.energy <= effectiveThreshold;
111
+ // Build reason for failure
112
+ let reason;
113
+ if (!passed) {
114
+ reason = this.buildFailureReason(coherenceResult, effectiveThreshold);
115
+ }
116
+ // Create witness record
117
+ const witness = this.createWitnessRecord(artifact, coherenceResult.energy, effectiveThreshold, passed);
118
+ // Log decision
119
+ this.logDecision({
120
+ id: witness.id,
121
+ timestamp: witness.timestamp,
122
+ domain: artifact.domain,
123
+ energy: coherenceResult.energy,
124
+ tier: coherenceResult.tier,
125
+ passed,
126
+ threshold: effectiveThreshold,
127
+ });
128
+ return {
129
+ passed,
130
+ energy: coherenceResult.energy,
131
+ threshold: effectiveThreshold,
132
+ reason,
133
+ witness,
134
+ };
135
+ }
136
+ /** Get the decision log for observability. */
137
+ getDecisionLog() {
138
+ return [...this.decisionLog];
139
+ }
140
+ /** Get the witness chain for audit purposes. */
141
+ getWitnessChain() {
142
+ return [...this.witnessChain];
143
+ }
144
+ /** Get the current threshold. */
145
+ getThreshold() {
146
+ return this.threshold;
147
+ }
148
+ /** Clear the decision log (for testing). */
149
+ clearDecisionLog() {
150
+ this.decisionLog = [];
151
+ }
152
+ // ==========================================================================
153
+ // ITransferCoherenceGate Implementation
154
+ // ==========================================================================
155
+ validateTransfer(pattern, targetDomain) {
156
+ const flags = getRuVectorFeatureFlags();
157
+ if (!flags.useCoherenceGate) {
158
+ return { approved: true };
159
+ }
160
+ const artifact = {
161
+ assertions: this.extractAssertions(pattern),
162
+ observedBehavior: this.extractObservedBehavior(pattern),
163
+ coverage: typeof pattern.coverage === 'number' ? pattern.coverage : 0.5,
164
+ domain: targetDomain,
165
+ confidence: pattern.confidence ?? 0.5,
166
+ };
167
+ // Transfer validation uses 'write' gate type for CUSUM tracking
168
+ const result = this.validate(artifact, undefined, 'write');
169
+ return {
170
+ approved: result.passed,
171
+ energy: result.energy,
172
+ rejectionReason: result.reason,
173
+ };
174
+ }
175
+ // ==========================================================================
176
+ // Private Helpers
177
+ // ==========================================================================
178
+ buildFailureReason(result, threshold) {
179
+ const parts = [];
180
+ parts.push(`Coherence energy ${result.energy.toFixed(3)} exceeds threshold ${threshold.toFixed(3)}.`);
181
+ const c = result.components;
182
+ if (c.assertionCoverage > 0.5) {
183
+ parts.push('High assertion-observation mismatch (possible hallucination).');
184
+ }
185
+ if (c.codeCoverage > 0.5) {
186
+ parts.push('Low code coverage.');
187
+ }
188
+ if (c.confidencePenalty > 0.5) {
189
+ parts.push('Low generator confidence.');
190
+ }
191
+ if (c.contradictionScore > 0.3) {
192
+ parts.push('Contradictions detected between assertions and observed behavior.');
193
+ }
194
+ if (c.laplacianDeviation > 0.5) {
195
+ parts.push('Inconsistent assertion structure (high Laplacian deviation).');
196
+ }
197
+ return parts.join(' ');
198
+ }
199
+ createWitnessRecord(artifact, energy, threshold, passed) {
200
+ const id = randomUUID();
201
+ const timestamp = Date.now();
202
+ const artifactHash = this.hashContent(JSON.stringify(artifact));
203
+ const record = {
204
+ id,
205
+ timestamp,
206
+ artifactHash,
207
+ energy,
208
+ threshold,
209
+ passed,
210
+ previousHash: this.lastWitnessHash,
211
+ recordHash: '',
212
+ };
213
+ // Compute record hash (chain link)
214
+ const hashPayload = `${id}|${timestamp}|${artifactHash}|${energy}|${threshold}|${passed}|${this.lastWitnessHash}`;
215
+ record.recordHash = this.hashContent(hashPayload);
216
+ // Update chain
217
+ const flags = getRuVectorFeatureFlags();
218
+ if (flags.useWitnessChain) {
219
+ this.witnessChain.push(record);
220
+ this.lastWitnessHash = record.recordHash;
221
+ // Persist to governance chain if attached
222
+ if (this.governanceChain) {
223
+ try {
224
+ const governanceDecision = {
225
+ type: 'coherence-gate',
226
+ decision: passed ? 'PASS' : 'FAIL',
227
+ context: { energy, threshold, artifactHash: record.artifactHash },
228
+ };
229
+ this.governanceChain.appendWitness(governanceDecision);
230
+ }
231
+ catch (err) {
232
+ logger.debug('Failed to persist to governance chain', { error: String(err) });
233
+ }
234
+ }
235
+ }
236
+ return record;
237
+ }
238
+ hashContent(content) {
239
+ return createHash('sha256').update(content).digest('hex');
240
+ }
241
+ logDecision(decision) {
242
+ this.decisionLog.push(decision);
243
+ // Keep bounded
244
+ const maxLog = 1000;
245
+ if (this.decisionLog.length > maxLog) {
246
+ this.decisionLog = this.decisionLog.slice(-maxLog);
247
+ }
248
+ logger.debug('Coherence decision', {
249
+ domain: decision.domain,
250
+ energy: decision.energy,
251
+ tier: decision.tier,
252
+ passed: decision.passed,
253
+ });
254
+ }
255
+ extractAssertions(pattern) {
256
+ if (Array.isArray(pattern.assertions)) {
257
+ return pattern.assertions.map(String);
258
+ }
259
+ if (typeof pattern.description === 'string') {
260
+ return [pattern.description];
261
+ }
262
+ return ['transfer-pattern'];
263
+ }
264
+ extractObservedBehavior(pattern) {
265
+ if (Array.isArray(pattern.observedBehavior)) {
266
+ return pattern.observedBehavior.map(String);
267
+ }
268
+ if (typeof pattern.evidence === 'string') {
269
+ return [pattern.evidence];
270
+ }
271
+ return ['observed'];
272
+ }
273
+ }
274
+ // ============================================================================
275
+ // Factory
276
+ // ============================================================================
277
+ /**
278
+ * Create a coherence gate instance.
279
+ */
280
+ export function createCoherenceGate(threshold, governanceChain) {
281
+ const gate = new CoherenceGate(threshold);
282
+ if (governanceChain) {
283
+ gate.setGovernanceChain(governanceChain);
284
+ }
285
+ return gate;
286
+ }
287
+ /**
288
+ * Create a transfer coherence gate.
289
+ * Returns the real CoherenceGate implementation (replacing the stub).
290
+ */
291
+ export function createRealTransferCoherenceGate() {
292
+ return new CoherenceGate();
293
+ }
294
+ //# sourceMappingURL=coherence-gate-core.js.map