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,51 @@
1
+ /**
2
+ * Cognitive Container Binary Codec (Task 4.1)
3
+ *
4
+ * Binary pack/unpack helpers for the cognitive container format.
5
+ * Separated from cognitive-container.ts to keep each file under 500 lines.
6
+ *
7
+ * Binary layout:
8
+ * [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
9
+ *
10
+ * @module integrations/ruvector/cognitive-container-codec
11
+ */
12
+ import { Buffer } from 'buffer';
13
+ import Database from 'better-sqlite3';
14
+ import type { ContainerManifest, ContainerSegment } from './cognitive-container.js';
15
+ /** 8-byte magic header: "COGCNTNR" */
16
+ export declare const MAGIC: Buffer<ArrayBuffer>;
17
+ /** Current container format version */
18
+ export declare const FORMAT_VERSION = 2;
19
+ /** Segment names in canonical order */
20
+ export declare const SEGMENT_NAMES: readonly ["patterns", "embeddings", "q-values", "lora-weights", "graph", "witness-chain"];
21
+ export type SegmentName = (typeof SEGMENT_NAMES)[number];
22
+ /** SHA-256 hash of a Buffer, returned as hex. */
23
+ export declare function sha256buf(data: Buffer): string;
24
+ /**
25
+ * Collect all table data from the database, grouped by segment.
26
+ */
27
+ export declare function collectSegmentData(db: Database.Database, domains?: readonly string[]): Record<SegmentName, Record<string, unknown[]>>;
28
+ /**
29
+ * Serialize a segment's data map to a Buffer, optionally compressed.
30
+ */
31
+ export declare function serializeSegment(data: Record<string, unknown[]>, compress: boolean): Buffer;
32
+ /**
33
+ * Deserialize a segment Buffer back to its data map.
34
+ */
35
+ export declare function deserializeSegment(buf: Buffer, compressed: boolean): Record<string, unknown[]>;
36
+ /**
37
+ * Write the container binary from a manifest and segment buffers.
38
+ */
39
+ export declare function packContainer(manifest: ContainerManifest, segmentBuffers: Buffer[]): Buffer;
40
+ /**
41
+ * Parse the header from container data and return manifest + data offset.
42
+ */
43
+ export declare function unpackHeader(data: Buffer): {
44
+ manifest: ContainerManifest;
45
+ dataOffset: number;
46
+ };
47
+ /**
48
+ * Extract segment buffers from container data using manifest offsets.
49
+ */
50
+ export declare function extractSegments(data: Buffer, dataOffset: number, segments: ContainerSegment[]): Map<string, Buffer>;
51
+ //# sourceMappingURL=cognitive-container-codec.d.ts.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Cognitive Container Binary Codec (Task 4.1)
3
+ *
4
+ * Binary pack/unpack helpers for the cognitive container format.
5
+ * Separated from cognitive-container.ts to keep each file under 500 lines.
6
+ *
7
+ * Binary layout:
8
+ * [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
9
+ *
10
+ * @module integrations/ruvector/cognitive-container-codec
11
+ */
12
+ import { createHash } from 'crypto';
13
+ import { Buffer } from 'buffer';
14
+ import { gunzipSync, gzipSync } from 'zlib';
15
+ import { queryAll, domainFilterForColumn, serializeRowBlobs, TABLE_CONFIGS, TABLE_BLOB_COLUMNS, } from './brain-shared.js';
16
+ // ============================================================================
17
+ // Constants
18
+ // ============================================================================
19
+ /** 8-byte magic header: "COGCNTNR" */
20
+ export const MAGIC = Buffer.from('COGCNTNR', 'ascii');
21
+ /** Current container format version */
22
+ export const FORMAT_VERSION = 2;
23
+ /** Segment names in canonical order */
24
+ export const SEGMENT_NAMES = [
25
+ 'patterns',
26
+ 'embeddings',
27
+ 'q-values',
28
+ 'lora-weights',
29
+ 'graph',
30
+ 'witness-chain',
31
+ ];
32
+ // ============================================================================
33
+ // Helpers
34
+ // ============================================================================
35
+ /** SHA-256 hash of a Buffer, returned as hex. */
36
+ export function sha256buf(data) {
37
+ return createHash('sha256').update(data).digest('hex');
38
+ }
39
+ /** Table name to segment name mapping. */
40
+ const TABLE_TO_SEGMENT = {
41
+ qe_patterns: 'patterns',
42
+ qe_pattern_embeddings: 'embeddings',
43
+ captured_experiences: 'embeddings',
44
+ sona_patterns: 'embeddings',
45
+ rl_q_values: 'q-values',
46
+ dream_cycles: 'lora-weights',
47
+ dream_insights: 'lora-weights',
48
+ concept_nodes: 'graph',
49
+ concept_edges: 'graph',
50
+ witness_chain: 'witness-chain',
51
+ };
52
+ /** Assign a segment name for a given table. Defaults to 'patterns'. */
53
+ function segmentForTable(tableName) {
54
+ return TABLE_TO_SEGMENT[tableName] ?? 'patterns';
55
+ }
56
+ // ============================================================================
57
+ // Data Collection
58
+ // ============================================================================
59
+ /**
60
+ * Collect all table data from the database, grouped by segment.
61
+ */
62
+ export function collectSegmentData(db, domains) {
63
+ const segments = {
64
+ 'patterns': {},
65
+ 'embeddings': {},
66
+ 'q-values': {},
67
+ 'lora-weights': {},
68
+ 'graph': {},
69
+ 'witness-chain': {},
70
+ };
71
+ for (const config of TABLE_CONFIGS) {
72
+ const [where, params] = config.domainColumn
73
+ ? domainFilterForColumn(domains, config.domainColumn)
74
+ : [undefined, []];
75
+ let rows = queryAll(db, config.tableName, where, params);
76
+ const blobCols = TABLE_BLOB_COLUMNS[config.tableName];
77
+ if (blobCols && blobCols.length > 0) {
78
+ rows = rows.map(r => serializeRowBlobs(r, blobCols));
79
+ }
80
+ const seg = segmentForTable(config.tableName);
81
+ segments[seg][config.tableName] = rows;
82
+ }
83
+ return segments;
84
+ }
85
+ // ============================================================================
86
+ // Segment Serialization
87
+ // ============================================================================
88
+ /**
89
+ * Serialize a segment's data map to a Buffer, optionally compressed.
90
+ */
91
+ export function serializeSegment(data, compress) {
92
+ const json = JSON.stringify(data);
93
+ const raw = Buffer.from(json, 'utf-8');
94
+ if (compress) {
95
+ return gzipSync(raw);
96
+ }
97
+ return raw;
98
+ }
99
+ /**
100
+ * Deserialize a segment Buffer back to its data map.
101
+ */
102
+ export function deserializeSegment(buf, compressed) {
103
+ const raw = compressed ? gunzipSync(buf) : buf;
104
+ return JSON.parse(raw.toString('utf-8'));
105
+ }
106
+ // ============================================================================
107
+ // Binary Packing
108
+ // ============================================================================
109
+ /**
110
+ * Write the container binary from a manifest and segment buffers.
111
+ */
112
+ export function packContainer(manifest, segmentBuffers) {
113
+ const manifestJson = JSON.stringify(manifest);
114
+ const manifestBuf = Buffer.from(manifestJson, 'utf-8');
115
+ const headerLen = MAGIC.length + 4 + 4; // MAGIC(8) + VERSION(4) + MANIFEST_LEN(4)
116
+ const totalDataLen = segmentBuffers.reduce((sum, b) => sum + b.length, 0);
117
+ const totalLen = headerLen + manifestBuf.length + totalDataLen;
118
+ const out = Buffer.alloc(totalLen);
119
+ let pos = 0;
120
+ MAGIC.copy(out, pos);
121
+ pos += MAGIC.length;
122
+ out.writeUInt32BE(FORMAT_VERSION, pos);
123
+ pos += 4;
124
+ out.writeUInt32BE(manifestBuf.length, pos);
125
+ pos += 4;
126
+ manifestBuf.copy(out, pos);
127
+ pos += manifestBuf.length;
128
+ for (const buf of segmentBuffers) {
129
+ buf.copy(out, pos);
130
+ pos += buf.length;
131
+ }
132
+ return out;
133
+ }
134
+ /**
135
+ * Parse the header from container data and return manifest + data offset.
136
+ */
137
+ export function unpackHeader(data) {
138
+ if (data.length < 16) {
139
+ throw new Error('Container too small: missing header');
140
+ }
141
+ const magic = data.subarray(0, MAGIC.length);
142
+ if (!magic.equals(MAGIC)) {
143
+ throw new Error('Invalid container: bad magic bytes');
144
+ }
145
+ const version = data.readUInt32BE(MAGIC.length);
146
+ if (version !== FORMAT_VERSION) {
147
+ throw new Error(`Unsupported container version: ${version}`);
148
+ }
149
+ const manifestLen = data.readUInt32BE(MAGIC.length + 4);
150
+ const manifestStart = MAGIC.length + 8;
151
+ const manifestEnd = manifestStart + manifestLen;
152
+ if (data.length < manifestEnd) {
153
+ throw new Error('Container truncated: manifest extends beyond data');
154
+ }
155
+ const manifestJson = data.subarray(manifestStart, manifestEnd).toString('utf-8');
156
+ let manifest;
157
+ try {
158
+ manifest = JSON.parse(manifestJson);
159
+ }
160
+ catch {
161
+ throw new Error('Container corrupt: manifest JSON parse failed');
162
+ }
163
+ return { manifest, dataOffset: manifestEnd };
164
+ }
165
+ /**
166
+ * Extract segment buffers from container data using manifest offsets.
167
+ */
168
+ export function extractSegments(data, dataOffset, segments) {
169
+ const result = new Map();
170
+ for (const seg of segments) {
171
+ const start = dataOffset + seg.offset;
172
+ const end = start + seg.length;
173
+ if (end > data.length) {
174
+ throw new Error(`Segment '${seg.name}' extends beyond container data`);
175
+ }
176
+ result.set(seg.name, data.subarray(start, end));
177
+ }
178
+ return result;
179
+ }
180
+ //# sourceMappingURL=cognitive-container-codec.js.map
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Cognitive Container Export/Import (RVF v2, Task 4.1)
3
+ *
4
+ * Produces full cognitive containers that bundle all brain state into a single
5
+ * self-verifying binary format. Each container includes:
6
+ * - Patterns, embeddings, Q-values, LoRA weights, graph state, witness chain
7
+ * - Container manifest with per-segment SHA-256 checksums
8
+ * - Ed25519 signing for container authenticity (Node.js crypto)
9
+ * - COW (copy-on-write) branching for cheap forks
10
+ *
11
+ * Binary layout:
12
+ * [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
13
+ *
14
+ * @module integrations/ruvector/cognitive-container
15
+ */
16
+ import { Buffer } from 'buffer';
17
+ import Database from 'better-sqlite3';
18
+ import { type MergeStrategy } from './brain-shared.js';
19
+ export interface ContainerSegment {
20
+ readonly name: string;
21
+ readonly offset: number;
22
+ readonly length: number;
23
+ readonly checksum: string;
24
+ readonly compressed: boolean;
25
+ }
26
+ export interface ContainerManifest {
27
+ readonly version: string;
28
+ readonly created: string;
29
+ readonly source: string;
30
+ readonly segments: ContainerSegment[];
31
+ readonly checksums: Record<string, string>;
32
+ readonly signature?: string;
33
+ readonly branchOf?: string;
34
+ }
35
+ export interface ExportOptions {
36
+ readonly domains?: readonly string[];
37
+ readonly compress?: boolean;
38
+ readonly sign?: boolean;
39
+ readonly privateKey?: Buffer;
40
+ readonly sourceId?: string;
41
+ }
42
+ export interface ImportOptions {
43
+ readonly mergeStrategy: MergeStrategy;
44
+ readonly dryRun?: boolean;
45
+ readonly verifySignature?: boolean;
46
+ readonly publicKey?: Buffer;
47
+ }
48
+ export interface ImportResult {
49
+ readonly imported: number;
50
+ readonly skipped: number;
51
+ readonly conflicts: number;
52
+ readonly segmentsRestored: number;
53
+ }
54
+ export interface VerificationResult {
55
+ readonly valid: boolean;
56
+ readonly manifestValid: boolean;
57
+ readonly segmentsValid: boolean;
58
+ readonly signatureValid: boolean | null;
59
+ readonly errors: string[];
60
+ }
61
+ export interface ContainerInfo {
62
+ readonly version: string;
63
+ readonly created: string;
64
+ readonly source: string;
65
+ readonly segmentCount: number;
66
+ readonly segmentNames: string[];
67
+ readonly totalDataBytes: number;
68
+ readonly signed: boolean;
69
+ readonly branchOf: string | null;
70
+ }
71
+ export interface Ed25519KeyPair {
72
+ readonly publicKey: Buffer;
73
+ readonly privateKey: Buffer;
74
+ }
75
+ /** Generate an Ed25519 key pair for container signing. */
76
+ export declare function generateSigningKeyPair(): Ed25519KeyPair;
77
+ export declare class CognitiveContainer {
78
+ /**
79
+ * Export a full cognitive container from the database.
80
+ *
81
+ * Produces a self-contained binary Buffer including all brain segments
82
+ * with per-segment checksums and optional Ed25519 signing.
83
+ */
84
+ exportContainer(db: Database.Database, options?: ExportOptions): {
85
+ data: Buffer;
86
+ manifest: ContainerManifest;
87
+ };
88
+ /**
89
+ * Import a cognitive container into the database.
90
+ *
91
+ * Verifies segment checksums before importing. Optionally verifies
92
+ * the Ed25519 signature.
93
+ */
94
+ importContainer(data: Buffer, db: Database.Database, options: ImportOptions): ImportResult;
95
+ /**
96
+ * Verify container integrity without importing.
97
+ *
98
+ * Checks: magic, manifest parse, segment checksums, optional signature.
99
+ */
100
+ verifyContainer(data: Buffer, publicKey?: Buffer): VerificationResult;
101
+ /**
102
+ * Create a COW (copy-on-write) branch of a container.
103
+ *
104
+ * The branch references the parent container by ID and includes only
105
+ * the manifest with updated metadata. The segment data is shared
106
+ * (not duplicated).
107
+ */
108
+ branchContainer(sourceData: Buffer, branchName: string): {
109
+ data: Buffer;
110
+ manifest: ContainerManifest;
111
+ };
112
+ /** Get container info without importing or fully verifying. */
113
+ getContainerInfo(data: Buffer): ContainerInfo;
114
+ private buildSignedPayload;
115
+ private verifySignatureInternal;
116
+ private verifyChecksums;
117
+ private requireValidSignature;
118
+ private dryRunImport;
119
+ private executeImport;
120
+ private verifySegmentChecksums;
121
+ private verifySignatureStatus;
122
+ }
123
+ /** Create a CognitiveContainer instance. */
124
+ export declare function createCognitiveContainer(): CognitiveContainer;
125
+ //# sourceMappingURL=cognitive-container.d.ts.map
@@ -0,0 +1,306 @@
1
+ /**
2
+ * Cognitive Container Export/Import (RVF v2, Task 4.1)
3
+ *
4
+ * Produces full cognitive containers that bundle all brain state into a single
5
+ * self-verifying binary format. Each container includes:
6
+ * - Patterns, embeddings, Q-values, LoRA weights, graph state, witness chain
7
+ * - Container manifest with per-segment SHA-256 checksums
8
+ * - Ed25519 signing for container authenticity (Node.js crypto)
9
+ * - COW (copy-on-write) branching for cheap forks
10
+ *
11
+ * Binary layout:
12
+ * [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
13
+ *
14
+ * @module integrations/ruvector/cognitive-container
15
+ */
16
+ import { generateKeyPairSync, sign, verify, randomUUID } from 'crypto';
17
+ import { Buffer } from 'buffer';
18
+ import { ensureTargetTables, mergeGenericRow, mergeAppendOnlyRow, TABLE_CONFIGS, PK_COLUMNS, CONFIDENCE_COLUMNS, TIMESTAMP_COLUMNS, deserializeRowBlobs, TABLE_BLOB_COLUMNS, } from './brain-shared.js';
19
+ import { SEGMENT_NAMES, sha256buf, collectSegmentData, serializeSegment, deserializeSegment, packContainer, unpackHeader, extractSegments, } from './cognitive-container-codec.js';
20
+ /** Generate an Ed25519 key pair for container signing. */
21
+ export function generateSigningKeyPair() {
22
+ const { publicKey, privateKey } = generateKeyPairSync('ed25519', {
23
+ publicKeyEncoding: { type: 'spki', format: 'der' },
24
+ privateKeyEncoding: { type: 'pkcs8', format: 'der' },
25
+ });
26
+ return {
27
+ publicKey: Buffer.from(publicKey),
28
+ privateKey: Buffer.from(privateKey),
29
+ };
30
+ }
31
+ // ============================================================================
32
+ // CognitiveContainer
33
+ // ============================================================================
34
+ export class CognitiveContainer {
35
+ /**
36
+ * Export a full cognitive container from the database.
37
+ *
38
+ * Produces a self-contained binary Buffer including all brain segments
39
+ * with per-segment checksums and optional Ed25519 signing.
40
+ */
41
+ exportContainer(db, options = {}) {
42
+ const compress = options.compress ?? true;
43
+ const sourceId = options.sourceId ?? randomUUID();
44
+ const segmentData = collectSegmentData(db, options.domains);
45
+ const segmentBuffers = [];
46
+ const segments = [];
47
+ const checksums = {};
48
+ let currentOffset = 0;
49
+ for (const name of SEGMENT_NAMES) {
50
+ const tableData = segmentData[name];
51
+ const buf = serializeSegment(tableData, compress);
52
+ const checksum = sha256buf(buf);
53
+ segments.push({
54
+ name,
55
+ offset: currentOffset,
56
+ length: buf.length,
57
+ checksum,
58
+ compressed: compress,
59
+ });
60
+ checksums[name] = checksum;
61
+ segmentBuffers.push(buf);
62
+ currentOffset += buf.length;
63
+ }
64
+ const manifest = {
65
+ version: '2.0.0',
66
+ created: new Date().toISOString(),
67
+ source: sourceId,
68
+ segments,
69
+ checksums,
70
+ };
71
+ if (options.sign && options.privateKey) {
72
+ const payload = this.buildSignedPayload(manifest);
73
+ const signature = sign(null, Buffer.from(payload, 'utf-8'), { key: options.privateKey, format: 'der', type: 'pkcs8' });
74
+ manifest.signature = signature.toString('hex');
75
+ }
76
+ const data = packContainer(manifest, segmentBuffers);
77
+ return { data, manifest };
78
+ }
79
+ /**
80
+ * Import a cognitive container into the database.
81
+ *
82
+ * Verifies segment checksums before importing. Optionally verifies
83
+ * the Ed25519 signature.
84
+ */
85
+ importContainer(data, db, options) {
86
+ const { manifest, dataOffset } = unpackHeader(data);
87
+ const segmentBuffers = extractSegments(data, dataOffset, manifest.segments);
88
+ this.verifyChecksums(manifest.segments, segmentBuffers);
89
+ if (options.verifySignature) {
90
+ this.requireValidSignature(manifest, options.publicKey);
91
+ }
92
+ if (options.dryRun) {
93
+ return this.dryRunImport(manifest, segmentBuffers);
94
+ }
95
+ ensureTargetTables(db);
96
+ return this.executeImport(db, manifest, segmentBuffers, options.mergeStrategy);
97
+ }
98
+ /**
99
+ * Verify container integrity without importing.
100
+ *
101
+ * Checks: magic, manifest parse, segment checksums, optional signature.
102
+ */
103
+ verifyContainer(data, publicKey) {
104
+ const errors = [];
105
+ let manifestValid = false;
106
+ let segmentsValid = false;
107
+ let signatureValid = null;
108
+ let manifest;
109
+ let dataOffset;
110
+ try {
111
+ const result = unpackHeader(data);
112
+ manifest = result.manifest;
113
+ dataOffset = result.dataOffset;
114
+ manifestValid = true;
115
+ }
116
+ catch (err) {
117
+ errors.push(err instanceof Error ? err.message : String(err));
118
+ return { valid: false, manifestValid, segmentsValid, signatureValid, errors };
119
+ }
120
+ segmentsValid = this.verifySegmentChecksums(data, dataOffset, manifest, errors);
121
+ signatureValid = this.verifySignatureStatus(manifest, publicKey, errors);
122
+ const valid = manifestValid && segmentsValid
123
+ && (signatureValid === null || signatureValid);
124
+ return { valid, manifestValid, segmentsValid, signatureValid, errors };
125
+ }
126
+ /**
127
+ * Create a COW (copy-on-write) branch of a container.
128
+ *
129
+ * The branch references the parent container by ID and includes only
130
+ * the manifest with updated metadata. The segment data is shared
131
+ * (not duplicated).
132
+ */
133
+ branchContainer(sourceData, branchName) {
134
+ const { manifest: src, dataOffset } = unpackHeader(sourceData);
135
+ const segBufs = extractSegments(sourceData, dataOffset, src.segments);
136
+ const branchManifest = {
137
+ version: src.version,
138
+ created: new Date().toISOString(),
139
+ source: branchName,
140
+ segments: src.segments.map(seg => ({ ...seg })),
141
+ checksums: { ...src.checksums },
142
+ branchOf: src.source,
143
+ };
144
+ const buffers = [];
145
+ for (const seg of src.segments) {
146
+ buffers.push(segBufs.get(seg.name));
147
+ }
148
+ const data = packContainer(branchManifest, buffers);
149
+ return { data, manifest: branchManifest };
150
+ }
151
+ /** Get container info without importing or fully verifying. */
152
+ getContainerInfo(data) {
153
+ const { manifest } = unpackHeader(data);
154
+ const totalDataBytes = manifest.segments.reduce((sum, s) => sum + s.length, 0);
155
+ return {
156
+ version: manifest.version,
157
+ created: manifest.created,
158
+ source: manifest.source,
159
+ segmentCount: manifest.segments.length,
160
+ segmentNames: manifest.segments.map(s => s.name),
161
+ totalDataBytes,
162
+ signed: !!manifest.signature,
163
+ branchOf: manifest.branchOf ?? null,
164
+ };
165
+ }
166
+ // --------------------------------------------------------------------------
167
+ // Private helpers
168
+ // --------------------------------------------------------------------------
169
+ buildSignedPayload(manifest) {
170
+ return JSON.stringify({
171
+ version: manifest.version,
172
+ created: manifest.created,
173
+ source: manifest.source,
174
+ checksums: manifest.checksums,
175
+ });
176
+ }
177
+ verifySignatureInternal(manifest, publicKey) {
178
+ if (!manifest.signature)
179
+ return false;
180
+ const payload = this.buildSignedPayload(manifest);
181
+ return verify(null, Buffer.from(payload, 'utf-8'), { key: publicKey, format: 'der', type: 'spki' }, Buffer.from(manifest.signature, 'hex'));
182
+ }
183
+ verifyChecksums(segments, segmentBuffers) {
184
+ for (const seg of segments) {
185
+ const buf = segmentBuffers.get(seg.name);
186
+ if (!buf)
187
+ throw new Error(`Missing segment data: ${seg.name}`);
188
+ const actual = sha256buf(buf);
189
+ if (actual !== seg.checksum) {
190
+ throw new Error(`Checksum mismatch for segment '${seg.name}': ` +
191
+ `expected ${seg.checksum}, got ${actual}`);
192
+ }
193
+ }
194
+ }
195
+ requireValidSignature(manifest, publicKey) {
196
+ if (!manifest.signature) {
197
+ throw new Error('Container is not signed but signature verification was requested');
198
+ }
199
+ if (!publicKey) {
200
+ throw new Error('Public key required for signature verification');
201
+ }
202
+ if (!this.verifySignatureInternal(manifest, publicKey)) {
203
+ throw new Error('Container signature verification failed');
204
+ }
205
+ }
206
+ dryRunImport(manifest, segmentBuffers) {
207
+ let total = 0;
208
+ for (const seg of manifest.segments) {
209
+ const buf = segmentBuffers.get(seg.name);
210
+ const tableData = deserializeSegment(buf, seg.compressed);
211
+ for (const rows of Object.values(tableData)) {
212
+ total += (rows?.length ?? 0);
213
+ }
214
+ }
215
+ return { imported: total, skipped: 0, conflicts: 0, segmentsRestored: manifest.segments.length };
216
+ }
217
+ executeImport(db, manifest, segmentBuffers, mergeStrategy) {
218
+ let imported = 0;
219
+ let skipped = 0;
220
+ let conflicts = 0;
221
+ let segmentsRestored = 0;
222
+ const importAll = db.transaction(() => {
223
+ for (const seg of manifest.segments) {
224
+ const buf = segmentBuffers.get(seg.name);
225
+ const tableData = deserializeSegment(buf, seg.compressed);
226
+ segmentsRestored++;
227
+ for (const [tableName, rows] of Object.entries(tableData)) {
228
+ if (!Array.isArray(rows) || rows.length === 0)
229
+ continue;
230
+ const config = TABLE_CONFIGS.find(c => c.tableName === tableName);
231
+ if (!config)
232
+ continue;
233
+ const blobCols = TABLE_BLOB_COLUMNS[tableName];
234
+ let processedRows = rows;
235
+ if (blobCols && blobCols.length > 0) {
236
+ processedRows = processedRows.map(r => deserializeRowBlobs(r, blobCols));
237
+ }
238
+ for (const row of processedRows) {
239
+ let result;
240
+ if (config.dedupColumns && config.dedupColumns.length > 0) {
241
+ result = mergeAppendOnlyRow(db, config.tableName, row, config.dedupColumns);
242
+ }
243
+ else {
244
+ const idCol = PK_COLUMNS[config.tableName] || 'id';
245
+ const tsCol = TIMESTAMP_COLUMNS[config.tableName];
246
+ const confCol = CONFIDENCE_COLUMNS[config.tableName];
247
+ result = mergeGenericRow(db, config.tableName, row, idCol, mergeStrategy, tsCol, confCol);
248
+ }
249
+ imported += result.imported;
250
+ skipped += result.skipped;
251
+ conflicts += result.conflicts;
252
+ }
253
+ }
254
+ }
255
+ });
256
+ importAll();
257
+ return { imported, skipped, conflicts, segmentsRestored };
258
+ }
259
+ verifySegmentChecksums(data, dataOffset, manifest, errors) {
260
+ try {
261
+ const segBufs = extractSegments(data, dataOffset, manifest.segments);
262
+ let allGood = true;
263
+ for (const seg of manifest.segments) {
264
+ const buf = segBufs.get(seg.name);
265
+ if (!buf) {
266
+ errors.push(`Missing segment: ${seg.name}`);
267
+ allGood = false;
268
+ continue;
269
+ }
270
+ if (sha256buf(buf) !== seg.checksum) {
271
+ errors.push(`Checksum mismatch for '${seg.name}'`);
272
+ allGood = false;
273
+ }
274
+ }
275
+ return allGood;
276
+ }
277
+ catch (err) {
278
+ errors.push(err instanceof Error ? err.message : String(err));
279
+ return false;
280
+ }
281
+ }
282
+ verifySignatureStatus(manifest, publicKey, errors) {
283
+ if (!manifest.signature)
284
+ return null;
285
+ if (!publicKey)
286
+ return null;
287
+ try {
288
+ const valid = this.verifySignatureInternal(manifest, publicKey);
289
+ if (!valid)
290
+ errors.push('Signature verification failed');
291
+ return valid;
292
+ }
293
+ catch (err) {
294
+ errors.push(`Signature error: ${err instanceof Error ? err.message : String(err)}`);
295
+ return false;
296
+ }
297
+ }
298
+ }
299
+ // ============================================================================
300
+ // Convenience factory
301
+ // ============================================================================
302
+ /** Create a CognitiveContainer instance. */
303
+ export function createCognitiveContainer() {
304
+ return new CognitiveContainer();
305
+ }
306
+ //# sourceMappingURL=cognitive-container.js.map