mindforge-cc 7.0.0 → 8.0.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.
@@ -46,6 +46,32 @@ class ConfigManager {
46
46
  return value;
47
47
  }
48
48
 
49
+ set(key, value) {
50
+ const keys = key.split('.');
51
+ let target = this.config;
52
+
53
+ for (let i = 0; i < keys.length - 1; i++) {
54
+ const k = keys[i];
55
+ if (!target[k]) target[k] = {};
56
+ target = target[k];
57
+ }
58
+ target[keys[keys.length - 1]] = value;
59
+
60
+ this._save();
61
+ return value;
62
+ }
63
+
64
+ _save() {
65
+ try {
66
+ if (!fs.existsSync(path.dirname(this.configPath))) {
67
+ fs.mkdirSync(path.dirname(this.configPath), { recursive: true });
68
+ }
69
+ fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
70
+ } catch (err) {
71
+ console.error(`[ConfigManager] Failed to save config: ${err.message}`);
72
+ }
73
+ }
74
+
49
75
  getAll() {
50
76
  return this.config;
51
77
  }
@@ -1,77 +1,58 @@
1
1
  /**
2
- * MindForge v7Post-Quantum Agentic Security (PQAS)
3
- * Component: Hardened Policy Gate
2
+ * MindForge v8Orbital Governance (Pillar XVIII)
3
+ * Component: Hardened Policy Gate (Final Evolution)
4
4
  *
5
- * Enforces strict biometric/executive bypasses for high-impact mutations.
5
+ * Enforces hardware-attested bypasses for high-impact system mutations.
6
6
  */
7
7
  'use strict';
8
8
 
9
- const fs = require('node:fs');
10
- const path = require('node:path');
9
+ const orbitalGuardian = require('../engine/orbital-guardian');
10
+ const configManager = require('../governance/config-manager');
11
11
 
12
12
  class PolicyGateHardened {
13
13
  constructor() {
14
- this.bypassStore = path.join(process.cwd(), '.mindforge', 'bypasses.json');
14
+ // bypasses.json deprecated in favor of orbital.attestations table (v8)
15
+ this.criticalThreshold = configManager.get('governance.critical_drift_threshold', 95);
15
16
  }
16
17
 
17
18
  /**
18
- * Evaluates if an intent requires a biometric bypass.
19
- * @param {Object} intent
20
- * @param {number} impactScore
19
+ * Evaluates if an intent requires hardware-bound attestation.
21
20
  */
22
21
  async evaluateBypass(intent, impactScore) {
23
- if (impactScore <= 95) {
22
+ if (impactScore <= this.criticalThreshold) {
24
23
  return { status: 'ALLOWED', reason: 'Impact within standard threshold' };
25
24
  }
26
25
 
27
- console.log(`[PQAS-GATE] Impact Score ${impactScore} exceeds Critical Threshold (95)`);
28
-
29
- // Check if a pre-existing bypass exists for this request
30
- const bypasses = this._loadBypasses();
31
- const existing = bypasses.find(b => b.requestId === intent.requestId && b.status === 'APPROVED');
26
+ console.log(`[ORBITAL-GATE] Impact Score ${impactScore} requires Hardware Attestation`);
32
27
 
33
- if (existing) {
34
- return { status: 'ALLOWED', reason: 'Biometric Bypass Verified via WebAuthn/DEX', signature: existing.signature };
28
+ // 1. Check SQLite via OrbitalGuardian (Unified v8 persistence)
29
+ const attestation = await orbitalGuardian.verify(intent.requestId);
30
+
31
+ if (attestation.verified) {
32
+ return {
33
+ status: 'ALLOWED',
34
+ reason: 'Hardware Attestation Verified via Enclave',
35
+ attestation_id: attestation.id,
36
+ timestamp: attestation.timestamp
37
+ };
35
38
  }
36
39
 
37
- // Trigger a new challenge
40
+ // 2. Trigger Orbital Challenge
38
41
  return {
39
- status: 'WAIT_FOR_BIOMETRIC',
40
- reason: 'Biometric steering required for high-impact mutation',
41
- challenge_id: `ch_${Math.random().toString(36).substr(2, 6)}`,
42
- threshold: 95
42
+ status: 'WAIT_FOR_ORBITAL',
43
+ reason: 'Hardware/Biometric attestation required for orbital-tier mutation',
44
+ challenge_id: `orb_${Math.random().toString(36).substr(2, 6)}`,
45
+ impact: impactScore
43
46
  };
44
47
  }
45
48
 
46
49
  /**
47
- * Records a manual bypass approval (Simulated).
50
+ * Records a hardware-attested approval.
48
51
  */
49
- async recordBypass(requestId, signature) {
50
- const bypasses = this._loadBypasses();
51
- bypasses.push({
52
- requestId,
53
- signature,
54
- status: 'APPROVED',
55
- timestamp: new Date().toISOString()
56
- });
57
- this._saveBypasses(bypasses);
58
- console.log(`[PQAS-GATE] Recorded Biometric Approval for Request: ${requestId}`);
59
- }
60
-
61
- _loadBypasses() {
62
- try {
63
- if (fs.existsSync(this.bypassStore)) {
64
- return JSON.parse(fs.readFileSync(this.bypassStore, 'utf8'));
65
- }
66
- } catch (err) {}
67
- return [];
68
- }
69
-
70
- _saveBypasses(data) {
71
- if (!fs.existsSync(path.dirname(this.bypassStore))) {
72
- fs.mkdirSync(path.dirname(this.bypassStore), { recursive: true });
73
- }
74
- fs.writeFileSync(this.bypassStore, JSON.stringify(data, null, 2));
52
+ async recordBypass(requestId, did, signature_blob = 'MOCK_HARDWARE_SIGN_v8') {
53
+ const report = await orbitalGuardian.attest(requestId, did, signature_blob);
54
+ console.log(`[ORBITAL-GATE] Recorded Hardware Approval for Request: ${requestId}`);
55
+ return report;
75
56
  }
76
57
  }
77
58
 
@@ -6,12 +6,21 @@
6
6
  const fs = require('node:fs/promises');
7
7
  const path = require('node:path');
8
8
  const os = require('node:os');
9
+ const vectorHub = require('./vector-hub'); // v8 Pillar XV
9
10
 
10
11
  class SemanticHub {
11
12
  constructor() {
12
13
  this.localPath = '.mindforge/memory';
13
14
  this.globalPath = path.join(os.homedir(), '.mindforge/memory/global');
14
15
  this.syncManifest = path.join(this.localPath, 'sync-manifest.json');
16
+ this.vhInitialized = false;
17
+ }
18
+
19
+ async ensureInit() {
20
+ if (!this.vhInitialized) {
21
+ await vectorHub.init();
22
+ this.vhInitialized = true;
23
+ }
15
24
  }
16
25
 
17
26
  /**
@@ -85,23 +94,116 @@ class SemanticHub {
85
94
  }
86
95
 
87
96
  /**
88
- * Retrieves all 'golden_trace' types from the global hub.
97
+ * Retrieves all 'golden_trace' types from the global hub and local SQLite.
89
98
  */
90
99
  async getGoldenTraces(skillFilter = null) {
100
+ await this.ensureInit();
101
+
102
+ // v8: Prioritize SQLite search for high-speed retrieval
103
+ let sqliteTraces = [];
104
+ try {
105
+ if (skillFilter) {
106
+ sqliteTraces = await vectorHub.searchTraces(skillFilter);
107
+ } else {
108
+ sqliteTraces = await vectorHub.db.selectFrom('traces')
109
+ .selectAll()
110
+ .where('event', '=', 'reasoning_trace')
111
+ .limit(20)
112
+ .execute();
113
+ }
114
+ } catch (err) {
115
+ console.warn(`[SEMANTIC-HUB] SQLite trace lookup failed: ${err.message}`);
116
+ }
117
+
118
+ // Legacy file-based fallback/global sync
91
119
  const patternFile = path.join(this.globalPath, 'pattern-library.jsonl');
120
+ let fileTraces = [];
92
121
  try {
93
122
  const data = await fs.readFile(patternFile, 'utf8');
94
- const traces = data.split('\n')
123
+ fileTraces = data.split('\n')
95
124
  .filter(Boolean)
96
125
  .map(JSON.parse)
97
126
  .filter(p => p.type === 'golden-trace' || p.tags?.includes('success'));
98
127
 
99
128
  if (skillFilter) {
100
- return traces.filter(t => t.skill === skillFilter || t.tags?.includes(skillFilter));
129
+ fileTraces = fileTraces.filter(t => t.skill === skillFilter || t.tags?.includes(skillFilter));
101
130
  }
102
- return traces;
103
131
  } catch (e) {
104
- return [];
132
+ // Fallback is silent
133
+ }
134
+
135
+ // Merge and deduplicate
136
+ const allTraces = [...sqliteTraces, ...fileTraces];
137
+ const uniqueTraces = Array.from(new Map(allTraces.map(t => [t.id || t.trace_id, t])).values());
138
+
139
+ return uniqueTraces;
140
+ }
141
+
142
+ /**
143
+ * Retrieves all 'ghost_pattern' types for proactive risk detection.
144
+ */
145
+ async getGhostPatterns() {
146
+ await this.ensureInit();
147
+
148
+ // 1. Fetch from legacy file-based global hub
149
+ const patternFile = path.join(this.globalPath, 'pattern-library.jsonl');
150
+ let ghostPatterns = [];
151
+ try {
152
+ const data = await fs.readFile(patternFile, 'utf8');
153
+ ghostPatterns = data.split('\n')
154
+ .filter(Boolean)
155
+ .map(JSON.parse)
156
+ .filter(p => p.type === 'ghost-pattern' || p.tags?.includes('failure'));
157
+ } catch (e) {
158
+ // Missing library is handled gracefully
159
+ }
160
+
161
+ // 2. Fetch from SQLite high-drift traces (v8 specific ghosting)
162
+ try {
163
+ const v8Ghosts = await vectorHub.db.selectFrom('traces')
164
+ .selectAll()
165
+ .where('drift_score', '>', 0.5)
166
+ .limit(20)
167
+ .execute();
168
+
169
+ const v8Mapped = v8Ghosts.map(g => ({
170
+ id: g.id,
171
+ tags: ['v8-drift-risk', 'failure'],
172
+ failureContext: g.content,
173
+ mitigationStrategy: 'Review logic drift in v8 trace logs.'
174
+ }));
175
+
176
+ ghostPatterns = [...ghostPatterns, ...v8Mapped];
177
+ } catch (err) {
178
+ console.warn(`[SEMANTIC-HUB] SQLite ghost lookup failed: ${err.message}`);
179
+ }
180
+
181
+ return ghostPatterns;
182
+ }
183
+
184
+ /**
185
+ * Saves a discovered skill to SQLite.
186
+ */
187
+ async saveSkill(skill) {
188
+ await this.ensureInit();
189
+ await vectorHub.db.insertInto('skills')
190
+ .values({
191
+ skill_id: skill.id || `sk_${Math.random().toString(36).substr(2, 6)}`,
192
+ name: skill.name,
193
+ description: skill.description || '',
194
+ path: skill.path || '',
195
+ success_rate: skill.success_rate || 0.0,
196
+ last_verified: new Date().toISOString()
197
+ })
198
+ .onConflict(oc => oc.column('skill_id').doUpdateSet({
199
+ success_rate: skill.success_rate,
200
+ last_verified: new Date().toISOString()
201
+ }))
202
+ .execute();
203
+
204
+ // v8 Pillar XVII: Metadata provenance for evolved skills
205
+ if (skill.is_autonomous) {
206
+ console.log(`[SEMANTIC-HUB] Persistence acknowledged for ASE evolved skill: ${skill.name}`);
105
207
  }
106
208
  }
107
209
  }
@@ -0,0 +1,170 @@
1
+ const Database = require('better-sqlite3');
2
+ const { Kysely, SqliteDialect, sql } = require('kysely');
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ /**
7
+ * MindForge v8 VectorHub
8
+ * Unified Persistence Layer for Trace, Remediation, and Skill data.
9
+ */
10
+ class VectorHub {
11
+ constructor(dbPath = null) {
12
+ this.dbPath = dbPath || path.join(process.cwd(), '.mindforge', 'celestial.db');
13
+ this._ensureDir();
14
+
15
+ const nativeDb = new Database(this.dbPath);
16
+ this.db = new Kysely({
17
+ dialect: new SqliteDialect({
18
+ database: nativeDb,
19
+ }),
20
+ });
21
+
22
+ this.initialized = false;
23
+ }
24
+
25
+ _ensureDir() {
26
+ const dir = path.dirname(this.dbPath);
27
+ if (!fs.existsSync(dir)) {
28
+ fs.mkdirSync(dir, { recursive: true });
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Initialize tables and FTS5 search.
34
+ */
35
+ async init() {
36
+ if (this.initialized) return;
37
+
38
+ // Traces Table
39
+ await this.db.schema
40
+ .createTable('traces')
41
+ .ifNotExists()
42
+ .addColumn('id', 'text', (col) => col.primaryKey())
43
+ .addColumn('trace_id', 'text', (col) => col.notNull())
44
+ .addColumn('span_id', 'text')
45
+ .addColumn('event', 'text', (col) => col.notNull())
46
+ .addColumn('timestamp', 'text', (col) => col.notNull())
47
+ .addColumn('agent', 'text')
48
+ .addColumn('content', 'text')
49
+ .addColumn('metadata', 'text') // JSON blob
50
+ .addColumn('drift_score', 'real')
51
+ .addColumn('mesh_node_id', 'text') // v8 Pillar XVI
52
+ .execute();
53
+
54
+ // v8 Migration: ensure mesh_node_id exists on existing table
55
+ try {
56
+ await sql`ALTER TABLE traces ADD COLUMN mesh_node_id TEXT`.execute(this.db);
57
+ } catch (e) {
58
+ // Column might already exist, ignore error.
59
+ }
60
+
61
+ // Remediations Table
62
+ await this.db.schema
63
+ .createTable('remediations')
64
+ .ifNotExists()
65
+ .addColumn('id', 'text', (col) => col.primaryKey())
66
+ .addColumn('trace_id', 'text', (col) => col.notNull())
67
+ .addColumn('strategy', 'text', (col) => col.notNull())
68
+ .addColumn('status', 'text', (col) => col.notNull())
69
+ .addColumn('timestamp', 'text', (col) => col.notNull())
70
+ .addColumn('outcome', 'text')
71
+ .execute();
72
+
73
+ // Skills Table
74
+ await this.db.schema
75
+ .createTable('skills')
76
+ .ifNotExists()
77
+ .addColumn('skill_id', 'text', (col) => col.primaryKey())
78
+ .addColumn('name', 'text', (col) => col.notNull())
79
+ .addColumn('description', 'text')
80
+ .addColumn('path', 'text')
81
+ .addColumn('success_rate', 'real', (col) => col.defaultTo(0.0))
82
+ .addColumn('last_verified', 'text')
83
+ .execute();
84
+
85
+ // Attestations Table (v8 Pillar XVIII)
86
+ await this.db.schema
87
+ .createTable('attestations')
88
+ .ifNotExists()
89
+ .addColumn('id', 'text', (col) => col.primaryKey())
90
+ .addColumn('request_id', 'text', (col) => col.notNull())
91
+ .addColumn('status', 'text', (col) => col.notNull()) // APPROVED / REJECTED
92
+ .addColumn('attestation_payload', 'text') // Signed blob from hardware enclave
93
+ .addColumn('timestamp', 'text', (col) => col.notNull())
94
+ .execute();
95
+
96
+ // Config Table
97
+ await this.db.schema
98
+ .createTable('mesh_config')
99
+ .ifNotExists()
100
+ .addColumn('key', 'text', (col) => col.primaryKey())
101
+ .addColumn('value', 'text')
102
+ .execute();
103
+
104
+ // Enable Full-Text Search for traces (FTS5)
105
+ await sql`
106
+ CREATE VIRTUAL TABLE IF NOT EXISTS traces_search
107
+ USING fts5(trace_id, content, agent, tokenize='porter');
108
+ `.execute(this.db);
109
+
110
+ this.initialized = true;
111
+ console.log(`[VectorHub] Initialized SQLite persistence at ${this.dbPath}`);
112
+ }
113
+
114
+ async close() {
115
+ await this.db.destroy();
116
+ }
117
+
118
+ /**
119
+ * Record a trace event.
120
+ */
121
+ async recordTrace(data) {
122
+ const entry = {
123
+ id: data.id || Math.random().toString(36).substr(2, 9),
124
+ trace_id: data.trace_id,
125
+ span_id: data.span_id || null,
126
+ event: data.event,
127
+ timestamp: data.timestamp || new Date().toISOString(),
128
+ agent: data.agent || null,
129
+ content: data.content || null,
130
+ metadata: data.metadata ? JSON.stringify(data.metadata) : null,
131
+ drift_score: data.drift_score || 0,
132
+ mesh_node_id: data.mesh_node_id || null
133
+ };
134
+
135
+ await this.db.insertInto('traces')
136
+ .values(entry)
137
+ .onConflict(oc => oc.column('id').doUpdateSet({
138
+ metadata: entry.metadata,
139
+ mesh_node_id: entry.mesh_node_id,
140
+ drift_score: entry.drift_score
141
+ }))
142
+ .execute();
143
+
144
+ // Update FTS5 index if content exists
145
+ if (entry.content) {
146
+ await sql`INSERT INTO traces_search (trace_id, content, agent) VALUES (${entry.trace_id}, ${entry.content}, ${entry.agent})`
147
+ .execute(this.db);
148
+ }
149
+
150
+ return entry.id;
151
+ }
152
+
153
+ /**
154
+ * Semantic search for previous traces.
155
+ */
156
+ async searchTraces(query) {
157
+ const results = await sql`
158
+ SELECT t.*, ts.rank
159
+ FROM traces t
160
+ JOIN traces_search ts ON t.trace_id = ts.trace_id
161
+ WHERE traces_search MATCH ${query}
162
+ ORDER BY ts.rank
163
+ LIMIT 10
164
+ `.execute(this.db);
165
+ return results.rows;
166
+ }
167
+ }
168
+
169
+ module.exports = new VectorHub();
170
+ module.exports.VectorHub = VectorHub;
@@ -0,0 +1,85 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const vectorHub = require('../memory/vector-hub');
4
+
5
+ /**
6
+ * MindForge v8 SQLite Migration Script
7
+ * Migrates legacy .json and .jsonl state into VectorHub.
8
+ */
9
+ async function runMigration() {
10
+ console.log('[MIGRATION] Starting MindForge v8 (Celestial) SQLite migration...');
11
+
12
+ await vectorHub.init();
13
+
14
+ // 1. Migrate Remediation Queue
15
+ const remPath = path.join(process.cwd(), '.mindforge', 'remediation-queue.json');
16
+ if (fs.existsSync(remPath)) {
17
+ try {
18
+ const data = JSON.parse(fs.readFileSync(remPath, 'utf8'));
19
+ console.log(`[MIGRATION] Migrating ${data.length} remediations...`);
20
+ for (const rem of data) {
21
+ await vectorHub.db.insertInto('remediations')
22
+ .values({
23
+ id: rem.remediation_id,
24
+ trace_id: rem.span_id, // Mapping span_id to trace_id for legacy compatibility
25
+ strategy: rem.strategy,
26
+ status: rem.status,
27
+ timestamp: rem.timestamp || new Date().toISOString(),
28
+ outcome: rem.status === 'SUCCESS' ? 'Legacy Success' : null
29
+ })
30
+ .onConflict(oc => oc.column('id').doNothing())
31
+ .execute();
32
+ }
33
+ } catch (err) {
34
+ console.warn(`[MIGRATION] Failed to migrate remediations: ${err.message}`);
35
+ }
36
+ }
37
+
38
+ // 2. Migrate Audit Traces (AUDIT.jsonl)
39
+ const auditPath = path.join(process.cwd(), '.planning', 'AUDIT.jsonl');
40
+ if (fs.existsSync(auditPath)) {
41
+ try {
42
+ const lines = fs.readFileSync(auditPath, 'utf8').split('\n').filter(Boolean);
43
+ console.log(`[MIGRATION] Migrating ${lines.length} audit trace lines...`);
44
+
45
+ for (const line of lines) {
46
+ const entry = JSON.parse(line);
47
+ if (entry.event === 'reasoning_trace' || entry.event === 'drift_remediation_event') {
48
+ await vectorHub.recordTrace({
49
+ id: entry.id,
50
+ trace_id: entry.trace_id || 'legacy_trace',
51
+ span_id: entry.span_id || null,
52
+ event: entry.event,
53
+ timestamp: entry.timestamp,
54
+ agent: entry.agent || null,
55
+ content: entry.thought || entry.strategy || null,
56
+ metadata: entry,
57
+ drift_score: entry.drift_score || 0
58
+ });
59
+ }
60
+ }
61
+ } catch (err) {
62
+ console.warn(`[MIGRATION] Failed to migrate audit traces: ${err.message}`);
63
+ }
64
+ }
65
+
66
+ // 3. Set Mesh Node Identity
67
+ await vectorHub.db.insertInto('mesh_config')
68
+ .values({ key: 'mesh_node_id', value: `mindforge-node-${Math.random().toString(36).substr(2, 6)}` })
69
+ .onConflict(oc => oc.column('key').doNothing())
70
+ .execute();
71
+
72
+ await vectorHub.db.insertInto('mesh_config')
73
+ .values({ key: 'v8_migration_complete', value: new Date().toISOString() })
74
+ .onConflict(oc => oc.column('key').doNothing())
75
+ .execute();
76
+
77
+ console.log('[MIGRATION] MindForge v8 Migration Successful.');
78
+ await vectorHub.close();
79
+ }
80
+
81
+ if (require.main === module) {
82
+ runMigration().catch(console.error);
83
+ }
84
+
85
+ module.exports = runMigration;
@@ -9,10 +9,18 @@
9
9
  const fs = require('node:fs');
10
10
  const path = require('node:path');
11
11
 
12
+ const vectorHub = require('../memory/vector-hub');
13
+
12
14
  class RemediationQueue {
13
15
  constructor() {
14
- this.queuePath = path.join(process.cwd(), '.mindforge', 'remediation-queue.json');
15
- this.queue = this._loadQueue();
16
+ this.initialized = false;
17
+ }
18
+
19
+ async ensureInit() {
20
+ if (!this.initialized) {
21
+ await vectorHub.init();
22
+ this.initialized = true;
23
+ }
16
24
  }
17
25
 
18
26
  /**
@@ -34,49 +42,65 @@ class RemediationQueue {
34
42
  * Adds a new task to the remediation queue.
35
43
  */
36
44
  async enqueue(task) {
45
+ await this.ensureInit();
37
46
  const entry = {
38
47
  ...task,
39
48
  enqueued_at: new Date().toISOString(),
40
49
  status: 'PENDING'
41
50
  };
42
51
 
43
- this.queue.push(entry);
44
- this._persist();
52
+ await vectorHub.db.insertInto('remediations')
53
+ .values({
54
+ id: entry.remediation_id,
55
+ trace_id: entry.span_id || 'unknown',
56
+ strategy: entry.strategy,
57
+ status: entry.status,
58
+ timestamp: entry.enqueued_at
59
+ })
60
+ .execute();
61
+
45
62
  return entry;
46
63
  }
47
64
 
48
65
  /**
49
66
  * Updates the status of a specific remediation task.
50
67
  */
51
- updateStatus(remediationId, status) {
52
- const task = this.queue.find(t => t.remediation_id === remediationId);
53
- if (task) {
54
- task.status = status;
55
- task.updated_at = new Date().toISOString();
56
- this._persist();
57
- }
68
+ async updateStatus(remediationId, status) {
69
+ await this.ensureInit();
70
+ await vectorHub.db.updateTable('remediations')
71
+ .set({
72
+ status,
73
+ outcome: `Updated at ${new Date().toISOString()}`
74
+ })
75
+ .where('id', '=', remediationId)
76
+ .execute();
58
77
  }
59
78
 
60
79
  /**
61
- * Internal persistence helper.
80
+ * Legacy persistence removed in v8 (SQLite transition).
62
81
  */
63
82
  _persist() {
64
- try {
65
- if (!fs.existsSync(path.dirname(this.queuePath))) {
66
- fs.mkdirSync(path.dirname(this.queuePath), { recursive: true });
67
- }
68
- fs.writeFileSync(this.queuePath, JSON.stringify(this.queue, null, 2));
69
- } catch (err) {
70
- console.error(`[RemediationQueue] Failed to persist queue: ${err.message}`);
71
- }
83
+ // No-op for v8
84
+ }
85
+
86
+ _loadQueue() {
87
+ // No-op for v8
88
+ return [];
72
89
  }
73
90
 
74
- getPending() {
75
- return this.queue.filter(t => t.status === 'PENDING');
91
+ async getPending() {
92
+ await this.ensureInit();
93
+ return await vectorHub.db.selectFrom('remediations')
94
+ .selectAll()
95
+ .where('status', '=', 'PENDING')
96
+ .execute();
76
97
  }
77
98
 
78
- getAll() {
79
- return this.queue;
99
+ async getAll() {
100
+ await this.ensureInit();
101
+ return await vectorHub.db.selectFrom('remediations')
102
+ .selectAll()
103
+ .execute();
80
104
  }
81
105
  }
82
106