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,509 @@
1
+ /**
2
+ * Witness Chain - Hash-Linked Audit Trail for Quality Gate Decisions
3
+ *
4
+ * Implements an append-only, hash-linked witness log for quality gate decisions.
5
+ * Each receipt is cryptographically chained to its predecessor using SHA-256,
6
+ * creating a tamper-evident audit trail.
7
+ *
8
+ * Features:
9
+ * - Append-only witness log with SHA-256 hash linking
10
+ * - Chain integrity verification with tamper detection
11
+ * - SPRT (Sequential Probability Ratio Test) evidence accumulation
12
+ * - Export/import for brain transfer
13
+ * - Feature-flag gated via useWitnessChain
14
+ *
15
+ * @module governance/witness-chain
16
+ * @see ADR-083-coherence-gated-agent-actions.md
17
+ */
18
+ import { createHash, randomUUID } from 'crypto';
19
+ import { LoggerFactory } from '../logging/index.js';
20
+ import { getRuVectorFeatureFlags } from '../integrations/ruvector/feature-flags.js';
21
+ const logger = LoggerFactory.create('witness-chain');
22
+ // ============================================================================
23
+ // SPRT Accumulator
24
+ // ============================================================================
25
+ /**
26
+ * Sequential Probability Ratio Test accumulator for Pass/Fail decisions.
27
+ *
28
+ * Simplified sequential decision rule with configurable evidence strength.
29
+ * For production use, strength should reflect log-likelihood ratio of the
30
+ * observation under the alternative vs null hypothesis.
31
+ *
32
+ * Accumulates evidence over a sequence of observations to decide between
33
+ * two hypotheses (Pass vs Fail) with controlled error rates.
34
+ *
35
+ * Boundaries:
36
+ * - Upper bound (accept H1 / PASS): ln(1/alpha)
37
+ * - Lower bound (accept H0 / FAIL): ln(beta)
38
+ *
39
+ * Default evidence step: +0.5 for positive, -0.5 for negative.
40
+ * Use addWeightedEvidence() for variable-strength observations.
41
+ */
42
+ export class SPRTAccumulator {
43
+ logLikelihoodRatio = 0;
44
+ upperBound;
45
+ lowerBound;
46
+ observations = 0;
47
+ /**
48
+ * @param alpha - Type I error rate (false positive). Default: 0.05
49
+ * @param beta - Type II error rate (false negative). Default: 0.05
50
+ */
51
+ constructor(alpha = 0.05, beta = 0.05) {
52
+ this.upperBound = Math.log(1 / alpha);
53
+ this.lowerBound = Math.log(beta);
54
+ }
55
+ /**
56
+ * Add a weighted observation and return the current decision.
57
+ *
58
+ * The strength parameter controls the log-likelihood step size.
59
+ * For production use, strength should reflect the log-likelihood ratio
60
+ * of the observation under the alternative vs null hypothesis.
61
+ *
62
+ * @param positive - Whether this observation is positive evidence
63
+ * @param strength - Evidence strength (step size). Default 0.5 for backward compat.
64
+ * @returns Current decision: PASS, FAIL, or INCONCLUSIVE
65
+ */
66
+ addWeightedEvidence(positive, strength) {
67
+ this.logLikelihoodRatio += positive ? strength : -strength;
68
+ this.observations++;
69
+ if (this.logLikelihoodRatio >= this.upperBound)
70
+ return 'PASS';
71
+ if (this.logLikelihoodRatio <= this.lowerBound)
72
+ return 'FAIL';
73
+ return 'INCONCLUSIVE';
74
+ }
75
+ /**
76
+ * Add an observation with default strength (0.5) and return the current decision.
77
+ *
78
+ * @param positive - Whether this observation is positive evidence
79
+ * @returns Current decision: PASS, FAIL, or INCONCLUSIVE
80
+ */
81
+ addEvidence(positive) {
82
+ return this.addWeightedEvidence(positive, 0.5);
83
+ }
84
+ /**
85
+ * Get the current log-likelihood ratio.
86
+ */
87
+ getRatio() {
88
+ return this.logLikelihoodRatio;
89
+ }
90
+ /**
91
+ * Get the total number of observations.
92
+ */
93
+ getObservations() {
94
+ return this.observations;
95
+ }
96
+ /**
97
+ * Get the SPRT boundaries.
98
+ */
99
+ getBounds() {
100
+ return { upper: this.upperBound, lower: this.lowerBound };
101
+ }
102
+ /**
103
+ * Reset the accumulator to its initial state.
104
+ */
105
+ reset() {
106
+ this.logLikelihoodRatio = 0;
107
+ this.observations = 0;
108
+ }
109
+ }
110
+ // ============================================================================
111
+ // Witness Chain
112
+ // ============================================================================
113
+ /** Genesis hash: 64 hex zeros */
114
+ const GENESIS_HASH = '0'.repeat(64);
115
+ /**
116
+ * Append-only, hash-linked witness chain for quality gate decisions.
117
+ *
118
+ * Maintains an ordered sequence of witness receipts where each receipt
119
+ * references the hash of its predecessor, forming a tamper-evident chain.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const chain = new WitnessChain();
124
+ * const receipt = chain.appendWitness({
125
+ * type: 'coherence-gate',
126
+ * decision: 'PASS',
127
+ * context: { energy: 0.23, threshold: 0.4 },
128
+ * });
129
+ * const result = chain.verifyChain();
130
+ * console.log(result.valid); // true
131
+ * ```
132
+ */
133
+ export class WitnessChain {
134
+ receipts = [];
135
+ lastHash = GENESIS_HASH;
136
+ sprtAccumulators = new Map();
137
+ /**
138
+ * Append a witness decision to the chain.
139
+ *
140
+ * Creates a new receipt hash-linked to the previous receipt and appends
141
+ * it to the chain. Optionally updates the SPRT accumulator for the
142
+ * decision type.
143
+ *
144
+ * @param decision - The decision to witness
145
+ * @returns The new witness receipt with its chain hash
146
+ */
147
+ appendWitness(decision) {
148
+ const id = randomUUID();
149
+ const timestamp = Date.now();
150
+ const chainIndex = this.receipts.length;
151
+ // Compute receipt hash: SHA-256(previousHash + JSON(decision) + timestamp)
152
+ const hashPayload = this.lastHash + JSON.stringify(decision) + timestamp;
153
+ const hash = createHash('sha256').update(hashPayload).digest('hex');
154
+ const receipt = {
155
+ id,
156
+ timestamp,
157
+ previousHash: this.lastHash,
158
+ hash,
159
+ decision,
160
+ chainIndex,
161
+ };
162
+ this.receipts.push(receipt);
163
+ this.lastHash = hash;
164
+ // Update SPRT accumulator for this decision type
165
+ this.updateSPRT(decision);
166
+ logger.debug('Witness appended', {
167
+ chainIndex,
168
+ type: decision.type,
169
+ decision: decision.decision,
170
+ hash: hash.slice(0, 16) + '...',
171
+ });
172
+ return receipt;
173
+ }
174
+ /**
175
+ * Verify the integrity of the entire witness chain.
176
+ *
177
+ * Walks the chain from genesis to tip, recomputing each receipt's hash
178
+ * and checking it against the stored value. Reports the first breakage.
179
+ *
180
+ * @returns Verification result with validity, length, and break point
181
+ */
182
+ verifyChain() {
183
+ if (this.receipts.length === 0) {
184
+ return {
185
+ valid: true,
186
+ length: 0,
187
+ brokenAt: -1,
188
+ message: 'Chain is empty (valid)',
189
+ lastHash: GENESIS_HASH,
190
+ };
191
+ }
192
+ let expectedPrevHash = GENESIS_HASH;
193
+ for (let i = 0; i < this.receipts.length; i++) {
194
+ const receipt = this.receipts[i];
195
+ // Check previousHash link
196
+ if (receipt.previousHash !== expectedPrevHash) {
197
+ return {
198
+ valid: false,
199
+ length: this.receipts.length,
200
+ brokenAt: i,
201
+ message: `Chain broken at index ${i}: previousHash mismatch`,
202
+ lastHash: this.lastHash,
203
+ };
204
+ }
205
+ // Recompute hash
206
+ const hashPayload = receipt.previousHash + JSON.stringify(receipt.decision) + receipt.timestamp;
207
+ const expectedHash = createHash('sha256').update(hashPayload).digest('hex');
208
+ if (receipt.hash !== expectedHash) {
209
+ return {
210
+ valid: false,
211
+ length: this.receipts.length,
212
+ brokenAt: i,
213
+ message: `Chain broken at index ${i}: hash mismatch (tamper detected)`,
214
+ lastHash: this.lastHash,
215
+ };
216
+ }
217
+ expectedPrevHash = receipt.hash;
218
+ }
219
+ return {
220
+ valid: true,
221
+ length: this.receipts.length,
222
+ brokenAt: -1,
223
+ message: `Chain valid (${this.receipts.length} receipts)`,
224
+ lastHash: this.lastHash,
225
+ };
226
+ }
227
+ /**
228
+ * Get receipts from the chain.
229
+ *
230
+ * @param limit - Maximum number of receipts to return (from most recent).
231
+ * If omitted, returns the entire chain.
232
+ * @returns Array of witness receipts
233
+ */
234
+ getChain(limit) {
235
+ if (limit !== undefined && limit > 0) {
236
+ return [...this.receipts.slice(-limit)];
237
+ }
238
+ return [...this.receipts];
239
+ }
240
+ /**
241
+ * Get the total number of receipts in the chain.
242
+ */
243
+ getChainLength() {
244
+ return this.receipts.length;
245
+ }
246
+ /**
247
+ * Get the hash of the most recent receipt (chain tip).
248
+ */
249
+ getLastHash() {
250
+ return this.lastHash;
251
+ }
252
+ /**
253
+ * Export the chain as a JSON string for brain transfer.
254
+ *
255
+ * @returns JSON string containing the full chain
256
+ */
257
+ exportChain() {
258
+ const data = {
259
+ version: '1.0.0',
260
+ exportedAt: Date.now(),
261
+ length: this.receipts.length,
262
+ receipts: this.receipts,
263
+ };
264
+ return JSON.stringify(data, null, 2);
265
+ }
266
+ /**
267
+ * Import a chain from a JSON string.
268
+ *
269
+ * Validates the imported chain integrity before accepting it.
270
+ * Replaces the current chain if valid.
271
+ *
272
+ * @param data - JSON string from exportChain()
273
+ * @returns true if import was successful, false if data was invalid
274
+ */
275
+ importChain(data) {
276
+ try {
277
+ const parsed = JSON.parse(data);
278
+ // Validate structure
279
+ if (!parsed || parsed.version !== '1.0.0' || !Array.isArray(parsed.receipts)) {
280
+ logger.warn('Import failed: invalid format');
281
+ return false;
282
+ }
283
+ // Validate chain integrity before accepting
284
+ const savedReceipts = this.receipts;
285
+ const savedLastHash = this.lastHash;
286
+ this.receipts = parsed.receipts;
287
+ this.lastHash =
288
+ parsed.receipts.length > 0
289
+ ? parsed.receipts[parsed.receipts.length - 1].hash
290
+ : GENESIS_HASH;
291
+ const verification = this.verifyChain();
292
+ if (!verification.valid) {
293
+ // Rollback
294
+ this.receipts = savedReceipts;
295
+ this.lastHash = savedLastHash;
296
+ logger.warn('Import failed: chain integrity check failed', {
297
+ message: verification.message,
298
+ });
299
+ return false;
300
+ }
301
+ logger.info('Chain imported successfully', { length: parsed.receipts.length });
302
+ return true;
303
+ }
304
+ catch (error) {
305
+ logger.warn('Import failed: parse error', {
306
+ error: error instanceof Error ? error.message : String(error),
307
+ });
308
+ return false;
309
+ }
310
+ }
311
+ /**
312
+ * Get or create an SPRT accumulator for a decision type.
313
+ *
314
+ * @param type - The decision type (e.g., 'coherence-gate')
315
+ * @param alpha - Type I error rate (default: 0.05)
316
+ * @param beta - Type II error rate (default: 0.05)
317
+ * @returns The SPRT accumulator for the given type
318
+ */
319
+ getSPRT(type, alpha, beta) {
320
+ if (!this.sprtAccumulators.has(type)) {
321
+ this.sprtAccumulators.set(type, new SPRTAccumulator(alpha, beta));
322
+ }
323
+ return this.sprtAccumulators.get(type);
324
+ }
325
+ /**
326
+ * Get a receipt by chain index.
327
+ *
328
+ * @param index - The chain index (0-based)
329
+ * @returns The receipt at the given index, or undefined if out of range
330
+ */
331
+ getReceipt(index) {
332
+ return this.receipts[index];
333
+ }
334
+ // ==========================================================================
335
+ // Private Methods
336
+ // ==========================================================================
337
+ /**
338
+ * Update the SPRT accumulator based on the decision.
339
+ */
340
+ updateSPRT(decision) {
341
+ const positive = decision.decision === 'PASS' || decision.decision === 'PERMIT';
342
+ const accumulator = this.getSPRT(decision.type);
343
+ accumulator.addEvidence(positive);
344
+ }
345
+ }
346
+ /**
347
+ * SQLite-backed WitnessChain that persists receipts to the unified database.
348
+ *
349
+ * Extends WitnessChain with optional SQLite persistence. When a persistence
350
+ * backend is provided, each witness receipt is written to SQLite on append,
351
+ * and the chain can be restored from SQLite on startup.
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * const persistence = createWitnessChainSQLitePersistence(db);
356
+ * const chain = createPersistentWitnessChain(persistence);
357
+ * // Chain is automatically loaded from SQLite on creation
358
+ * ```
359
+ */
360
+ export class PersistentWitnessChain extends WitnessChain {
361
+ persistence;
362
+ constructor(persistence) {
363
+ super();
364
+ this.persistence = persistence;
365
+ // Restore chain from SQLite
366
+ const storedReceipts = persistence.loadAllReceipts();
367
+ if (storedReceipts.length > 0) {
368
+ const exported = {
369
+ version: '1.0.0',
370
+ exportedAt: Date.now(),
371
+ length: storedReceipts.length,
372
+ receipts: storedReceipts,
373
+ };
374
+ const imported = this.importChain(JSON.stringify(exported));
375
+ if (imported) {
376
+ logger.info('Witness chain restored from SQLite', {
377
+ receipts: storedReceipts.length,
378
+ });
379
+ }
380
+ else {
381
+ logger.warn('Failed to restore witness chain from SQLite — starting fresh');
382
+ }
383
+ }
384
+ }
385
+ /**
386
+ * Append a witness and persist it to SQLite.
387
+ */
388
+ appendWitness(decision) {
389
+ const receipt = super.appendWitness(decision);
390
+ try {
391
+ this.persistence.insertReceipt(receipt);
392
+ }
393
+ catch (err) {
394
+ logger.warn('Failed to persist witness receipt to SQLite', {
395
+ chainIndex: receipt.chainIndex,
396
+ error: err instanceof Error ? err.message : String(err),
397
+ });
398
+ }
399
+ return receipt;
400
+ }
401
+ }
402
+ /**
403
+ * Create a SQLite persistence backend using better-sqlite3.
404
+ *
405
+ * Creates the `witness_chain_receipts` table if it doesn't exist
406
+ * and provides insert/load methods.
407
+ *
408
+ * @param db - better-sqlite3 Database instance (from unified persistence)
409
+ * @returns IWitnessChainPersistence implementation
410
+ */
411
+ export function createWitnessChainSQLitePersistence(db) {
412
+ // Create table if not exists
413
+ db.exec(`
414
+ CREATE TABLE IF NOT EXISTS witness_chain_receipts (
415
+ id TEXT PRIMARY KEY,
416
+ chain_index INTEGER NOT NULL,
417
+ timestamp INTEGER NOT NULL,
418
+ previous_hash TEXT NOT NULL,
419
+ hash TEXT NOT NULL,
420
+ decision_type TEXT NOT NULL,
421
+ decision_outcome TEXT NOT NULL,
422
+ decision_context TEXT NOT NULL,
423
+ decision_evidence REAL,
424
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
425
+ )
426
+ `);
427
+ db.exec(`
428
+ CREATE INDEX IF NOT EXISTS idx_witness_chain_index
429
+ ON witness_chain_receipts(chain_index)
430
+ `);
431
+ const insertStmt = db.prepare(`
432
+ INSERT OR REPLACE INTO witness_chain_receipts
433
+ (id, chain_index, timestamp, previous_hash, hash,
434
+ decision_type, decision_outcome, decision_context, decision_evidence)
435
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
436
+ `);
437
+ const loadAllStmt = db.prepare(`
438
+ SELECT * FROM witness_chain_receipts ORDER BY chain_index ASC
439
+ `);
440
+ const countStmt = db.prepare(`
441
+ SELECT COUNT(*) as cnt FROM witness_chain_receipts
442
+ `);
443
+ return {
444
+ insertReceipt(receipt) {
445
+ insertStmt.run(receipt.id, receipt.chainIndex, receipt.timestamp, receipt.previousHash, receipt.hash, receipt.decision.type, receipt.decision.decision, JSON.stringify(receipt.decision.context), receipt.decision.evidence ?? null);
446
+ },
447
+ loadAllReceipts() {
448
+ const rows = loadAllStmt.all();
449
+ return rows.map(row => {
450
+ let context = {};
451
+ try {
452
+ context = JSON.parse(row.decision_context);
453
+ }
454
+ catch {
455
+ logger.warn('Corrupt decision_context in witness receipt, using empty object', {
456
+ receiptId: row.id,
457
+ chainIndex: row.chain_index,
458
+ });
459
+ }
460
+ return {
461
+ id: row.id,
462
+ chainIndex: row.chain_index,
463
+ timestamp: row.timestamp,
464
+ previousHash: row.previous_hash,
465
+ hash: row.hash,
466
+ decision: {
467
+ type: row.decision_type,
468
+ decision: row.decision_outcome,
469
+ context,
470
+ evidence: row.decision_evidence ?? undefined,
471
+ },
472
+ };
473
+ });
474
+ },
475
+ getReceiptCount() {
476
+ const row = countStmt.get();
477
+ return row.cnt;
478
+ },
479
+ };
480
+ }
481
+ // ============================================================================
482
+ // Factory
483
+ // ============================================================================
484
+ /**
485
+ * Create a new WitnessChain instance (in-memory).
486
+ *
487
+ * @returns A new empty WitnessChain
488
+ */
489
+ export function createWitnessChain() {
490
+ return new WitnessChain();
491
+ }
492
+ /**
493
+ * Create a SQLite-backed WitnessChain that persists receipts.
494
+ *
495
+ * @param persistence - SQLite persistence backend
496
+ * @returns A PersistentWitnessChain loaded from SQLite
497
+ */
498
+ export function createPersistentWitnessChain(persistence) {
499
+ return new PersistentWitnessChain(persistence);
500
+ }
501
+ /**
502
+ * Check if the witness chain feature is enabled.
503
+ *
504
+ * @returns true if the useWitnessChain feature flag is on
505
+ */
506
+ export function isWitnessChainFeatureEnabled() {
507
+ return getRuVectorFeatureFlags().useWitnessChain;
508
+ }
509
+ //# sourceMappingURL=witness-chain.js.map
@@ -41,6 +41,4 @@ export type { WindsurfInstallerOptions, WindsurfInstallResult } from './windsurf
41
41
  export { WindsurfInstaller, createWindsurfInstaller } from './windsurf-installer.js';
42
42
  export type { ContinueDevInstallerOptions, ContinueDevInstallResult } from './continuedev-installer.js';
43
43
  export { ContinueDevInstaller, createContinueDevInstaller } from './continuedev-installer.js';
44
- export type { V2DetectionInfo, MigrationResult, } from './migration/index.js';
45
- export { V2Detector, createV2Detector, V2DataMigrator, createV2DataMigrator, V2ConfigMigrator, createV2ConfigMigrator, } from './migration/index.js';
46
44
  //# sourceMappingURL=index.d.ts.map
@@ -24,5 +24,4 @@ export { RooCodeInstaller, createRooCodeInstaller } from './roocode-installer.js
24
24
  export { CodexInstaller, createCodexInstaller } from './codex-installer.js';
25
25
  export { WindsurfInstaller, createWindsurfInstaller } from './windsurf-installer.js';
26
26
  export { ContinueDevInstaller, createContinueDevInstaller } from './continuedev-installer.js';
27
- export { V2Detector, createV2Detector, V2DataMigrator, createV2DataMigrator, V2ConfigMigrator, createV2ConfigMigrator, } from './migration/index.js';
28
27
  //# sourceMappingURL=index.js.map
@@ -6,6 +6,16 @@
6
6
  * Extracted from init-wizard.ts.
7
7
  */
8
8
  import type { AQEInitConfig, PretrainedLibrary } from './types.js';
9
+ /**
10
+ * Read AQE version directly from memory.db without full initialization.
11
+ * Returns undefined if no version is stored.
12
+ */
13
+ export declare function readVersionFromDb(dbPath: string): string | undefined;
14
+ /**
15
+ * Write AQE version to memory.db in _system namespace.
16
+ * Used by init wizard to mark installation version.
17
+ */
18
+ export declare function writeVersionToDb(projectRoot: string, version: string): Promise<boolean>;
9
19
  /**
10
20
  * Initialize the persistence database (REQUIRED).
11
21
  * Creates the SQLite database file with proper schema.
@@ -6,12 +6,98 @@
6
6
  * Extracted from init-wizard.ts.
7
7
  */
8
8
  import { existsSync, mkdirSync, writeFileSync } from 'fs';
9
- import { join } from 'path';
9
+ import { join, dirname } from 'path';
10
10
  import { createSkillsInstaller } from './skills-installer.js';
11
11
  import { createAgentsInstaller } from './agents-installer.js';
12
12
  import { createN8nInstaller } from './n8n-installer.js';
13
13
  import { toErrorMessage } from '../shared/error-utils.js';
14
14
  import { openDatabase } from '../shared/safe-db.js';
15
+ import { safeJsonParse } from '../shared/safe-json.js';
16
+ // ============================================================================
17
+ // Version Management
18
+ // ============================================================================
19
+ /**
20
+ * Read AQE version directly from memory.db without full initialization.
21
+ * Returns undefined if no version is stored.
22
+ */
23
+ export function readVersionFromDb(dbPath) {
24
+ try {
25
+ const db = openDatabase(dbPath, { readonly: true, fileMustExist: true });
26
+ try {
27
+ const tableExists = db.prepare(`
28
+ SELECT name FROM sqlite_master
29
+ WHERE type='table' AND name='kv_store'
30
+ `).get();
31
+ if (!tableExists) {
32
+ db.close();
33
+ return undefined;
34
+ }
35
+ const row = db.prepare(`
36
+ SELECT value FROM kv_store
37
+ WHERE key = 'aqe_version' AND namespace = '_system'
38
+ `).get();
39
+ db.close();
40
+ if (row) {
41
+ return safeJsonParse(row.value);
42
+ }
43
+ return undefined;
44
+ }
45
+ catch {
46
+ db.close();
47
+ return undefined;
48
+ }
49
+ }
50
+ catch {
51
+ return undefined;
52
+ }
53
+ }
54
+ /**
55
+ * Write AQE version to memory.db in _system namespace.
56
+ * Used by init wizard to mark installation version.
57
+ */
58
+ export async function writeVersionToDb(projectRoot, version) {
59
+ const memoryDbPath = join(projectRoot, '.agentic-qe', 'memory.db');
60
+ try {
61
+ const dir = dirname(memoryDbPath);
62
+ if (!existsSync(dir)) {
63
+ mkdirSync(dir, { recursive: true });
64
+ }
65
+ const db = openDatabase(memoryDbPath);
66
+ try {
67
+ db.exec(`
68
+ CREATE TABLE IF NOT EXISTS kv_store (
69
+ key TEXT NOT NULL,
70
+ namespace TEXT NOT NULL,
71
+ value TEXT NOT NULL,
72
+ expires_at INTEGER,
73
+ created_at INTEGER DEFAULT (strftime('%s', 'now') * 1000),
74
+ PRIMARY KEY (namespace, key)
75
+ );
76
+ `);
77
+ const now = Date.now();
78
+ db.prepare(`
79
+ INSERT OR REPLACE INTO kv_store (key, namespace, value, created_at)
80
+ VALUES (?, '_system', ?, ?)
81
+ `).run('aqe_version', JSON.stringify(version), now);
82
+ db.prepare(`
83
+ INSERT OR REPLACE INTO kv_store (key, namespace, value, created_at)
84
+ VALUES (?, '_system', ?, ?)
85
+ `).run('init_timestamp', JSON.stringify(new Date().toISOString()), now);
86
+ db.close();
87
+ console.log(` ✓ Version ${version} written to memory.db`);
88
+ return true;
89
+ }
90
+ catch (err) {
91
+ db.close();
92
+ console.warn(` ⚠ Could not write version: ${toErrorMessage(err)}`);
93
+ return false;
94
+ }
95
+ }
96
+ catch (err) {
97
+ console.warn(` ⚠ Could not open memory.db: ${toErrorMessage(err)}`);
98
+ return false;
99
+ }
100
+ }
15
101
  // ============================================================================
16
102
  // Persistence Database
17
103
  // ============================================================================
@@ -6,11 +6,9 @@
6
6
  *
7
7
  * This is a facade module. Implementation details are extracted to:
8
8
  * - init-wizard-hooks.ts (hook configuration, MCP, CLAUDE.md generation)
9
- * - init-wizard-migration.ts (V2 detection, migration, config conversion)
10
- * - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config)
9
+ * - init-wizard-steps.ts (persistence, learning, workers, skills, agents, config, version)
11
10
  */
12
11
  import type { InitResult, WizardStep, PretrainedLibrary } from './types.js';
13
- export type { V2DetectionResult } from './init-wizard-migration.js';
14
12
  export interface InitOrchestratorOptions {
15
13
  /** Project root directory */
16
14
  projectRoot: string;
@@ -31,8 +29,6 @@ export interface InitOrchestratorOptions {
31
29
  baseUrl?: string;
32
30
  apiKey?: string;
33
31
  };
34
- /** Automatically migrate from v2 if detected */
35
- autoMigrate?: boolean;
36
32
  }
37
33
  export declare class InitOrchestrator {
38
34
  private projectRoot;
@@ -49,10 +45,6 @@ export declare class InitOrchestrator {
49
45
  * Get wizard steps
50
46
  */
51
47
  getWizardSteps(): WizardStep[];
52
- /**
53
- * Handle V2 detection - returns early result if migration not auto, null otherwise.
54
- */
55
- private handleV2Detection;
56
48
  /**
57
49
  * Run a single initialization step with timing and status tracking
58
50
  */