@siduri-x/core 2.0.2 → 2.0.4

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.
package/dist/siduri-db.js CHANGED
@@ -1,10 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SiduriDatabase = void 0;
4
+ exports.normalizeStatus = normalizeStatus;
4
5
  // eslint-disable-next-line @typescript-eslint/no-var-requires
5
6
  const crypto = require('crypto');
6
7
  // eslint-disable-next-line @typescript-eslint/no-var-requires
7
8
  const { DatabaseSync } = require('node:sqlite');
9
+ function normalizeStatus(status, defaultStatus = 'pending') {
10
+ if (!status)
11
+ return defaultStatus;
12
+ return status.toLowerCase().replace(/_/g, '-');
13
+ }
8
14
  class SiduriDatabase {
9
15
  db;
10
16
  constructor(options = {}) {
@@ -20,6 +26,8 @@ class SiduriDatabase {
20
26
  companion_id TEXT PRIMARY KEY,
21
27
  name TEXT NOT NULL,
22
28
  archetype TEXT,
29
+ origin TEXT,
30
+ ethos TEXT,
23
31
  version TEXT NOT NULL,
24
32
  updated_at TEXT DEFAULT (datetime('now'))
25
33
  );
@@ -39,8 +47,9 @@ class SiduriDatabase {
39
47
  companion_id TEXT NOT NULL,
40
48
  priority INTEGER DEFAULT 50,
41
49
  directive TEXT NOT NULL,
42
- status TEXT DEFAULT 'ACTIVE',
50
+ status TEXT DEFAULT 'active',
43
51
  category TEXT DEFAULT 'behavioral',
52
+ scope_actor TEXT,
44
53
  supersedes_id TEXT,
45
54
  created_at TEXT DEFAULT (datetime('now'))
46
55
  );
@@ -48,13 +57,24 @@ class SiduriDatabase {
48
57
  CREATE TABLE IF NOT EXISTS self_relationships (
49
58
  companion_id TEXT NOT NULL,
50
59
  entity_id TEXT NOT NULL,
51
- entity_type TEXT NOT NULL,
60
+ entity_type TEXT NOT NULL DEFAULT 'human',
61
+ role TEXT DEFAULT 'user',
62
+ stance TEXT DEFAULT 'neutral',
52
63
  trust_score REAL DEFAULT 0.5,
53
64
  familiarity REAL DEFAULT 0.5,
54
65
  interaction_conventions TEXT,
66
+ updated_at TEXT DEFAULT (datetime('now')),
55
67
  PRIMARY KEY(companion_id, entity_id)
56
68
  );
57
69
 
70
+ CREATE TABLE IF NOT EXISTS self_exemplars (
71
+ id TEXT PRIMARY KEY,
72
+ companion_id TEXT NOT NULL,
73
+ user_prompt TEXT NOT NULL,
74
+ companion_response TEXT NOT NULL,
75
+ created_at TEXT DEFAULT (datetime('now'))
76
+ );
77
+
58
78
  -- Knowledge Tables
59
79
  CREATE TABLE IF NOT EXISTS life_inventory (
60
80
  id TEXT PRIMARY KEY,
@@ -109,7 +129,7 @@ class SiduriDatabase {
109
129
  subject TEXT NOT NULL,
110
130
  predicate TEXT NOT NULL,
111
131
  value TEXT NOT NULL,
112
- status TEXT DEFAULT 'PENDING',
132
+ status TEXT DEFAULT 'pending',
113
133
  confidence REAL DEFAULT 1.0,
114
134
  valid_from TEXT,
115
135
  valid_until TEXT,
@@ -159,6 +179,42 @@ class SiduriDatabase {
159
179
  catch {
160
180
  // Column already exists
161
181
  }
182
+ try {
183
+ this.db.exec("ALTER TABLE self_identity ADD COLUMN origin TEXT");
184
+ }
185
+ catch {
186
+ // Column already exists
187
+ }
188
+ try {
189
+ this.db.exec("ALTER TABLE self_identity ADD COLUMN ethos TEXT");
190
+ }
191
+ catch {
192
+ // Column already exists
193
+ }
194
+ try {
195
+ this.db.exec("ALTER TABLE self_directives ADD COLUMN scope_actor TEXT");
196
+ }
197
+ catch {
198
+ // Column already exists
199
+ }
200
+ try {
201
+ this.db.exec("ALTER TABLE self_relationships ADD COLUMN role TEXT DEFAULT 'user'");
202
+ }
203
+ catch {
204
+ // Column already exists
205
+ }
206
+ try {
207
+ this.db.exec("ALTER TABLE self_relationships ADD COLUMN stance TEXT DEFAULT 'neutral'");
208
+ }
209
+ catch {
210
+ // Column already exists
211
+ }
212
+ try {
213
+ this.db.exec("ALTER TABLE self_relationships ADD COLUMN updated_at TEXT");
214
+ }
215
+ catch {
216
+ // Column already exists
217
+ }
162
218
  }
163
219
  close() {
164
220
  this.db.close();
@@ -175,21 +231,25 @@ class SiduriDatabase {
175
231
  companionId: row.companion_id,
176
232
  name: row.name,
177
233
  archetype: row.archetype || undefined,
234
+ origin: row.origin || undefined,
235
+ ethos: row.ethos || undefined,
178
236
  version: row.version,
179
237
  updatedAt: row.updated_at
180
238
  };
181
239
  }
182
240
  setIdentity(identity) {
183
241
  const stmt = this.db.prepare(`
184
- INSERT INTO self_identity (companion_id, name, archetype, version, updated_at)
185
- VALUES (?, ?, ?, ?, datetime('now'))
242
+ INSERT INTO self_identity (companion_id, name, archetype, origin, ethos, version, updated_at)
243
+ VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
186
244
  ON CONFLICT(companion_id) DO UPDATE SET
187
245
  name = excluded.name,
188
246
  archetype = excluded.archetype,
247
+ origin = excluded.origin,
248
+ ethos = excluded.ethos,
189
249
  version = excluded.version,
190
250
  updated_at = datetime('now')
191
251
  `);
192
- stmt.run(identity.companionId, identity.name, identity.archetype || null, identity.version);
252
+ stmt.run(identity.companionId, identity.name, identity.archetype || null, identity.origin || null, identity.ethos || null, identity.version);
193
253
  }
194
254
  getPersonality(companionId) {
195
255
  const stmt = this.db.prepare('SELECT * FROM self_personality WHERE companion_id = ?');
@@ -218,29 +278,41 @@ class SiduriDatabase {
218
278
  `);
219
279
  stmt.run(companionId, traits.warmth, traits.formality, traits.sarcasm, traits.verbosity, traits.curiosity);
220
280
  }
221
- getActiveDirectives(companionId) {
222
- const stmt = this.db.prepare(`
223
- SELECT * FROM self_directives
224
- WHERE companion_id = ? AND status = 'ACTIVE'
225
- ORDER BY priority DESC, created_at ASC
226
- `);
227
- return stmt.all(companionId).map((row) => ({
281
+ rowToSelfDirective(row) {
282
+ return {
228
283
  id: row.id,
229
284
  companionId: row.companion_id,
230
285
  priority: row.priority,
231
286
  directive: row.directive,
232
- status: row.status,
287
+ status: normalizeStatus(row.status, 'active'),
233
288
  category: row.category,
289
+ scopeActor: row.scope_actor || undefined,
234
290
  supersedesId: row.supersedes_id || undefined,
235
- createdAt: row.created_at
236
- }));
291
+ createdAt: row.created_at,
292
+ };
293
+ }
294
+ getActiveDirectives(companionId) {
295
+ const stmt = this.db.prepare(`
296
+ SELECT * FROM self_directives
297
+ WHERE companion_id = ? AND LOWER(status) = 'active'
298
+ ORDER BY priority DESC, created_at ASC
299
+ `);
300
+ return stmt.all(companionId).map((row) => this.rowToSelfDirective(row));
301
+ }
302
+ getAllDirectives(companionId) {
303
+ const stmt = this.db.prepare(`
304
+ SELECT * FROM self_directives
305
+ WHERE companion_id = ?
306
+ ORDER BY priority DESC, created_at ASC
307
+ `);
308
+ return stmt.all(companionId).map((row) => this.rowToSelfDirective(row));
237
309
  }
238
310
  commitDirective(directive) {
239
311
  const stmt = this.db.prepare(`
240
- INSERT INTO self_directives (id, companion_id, priority, directive, status, category, supersedes_id, created_at)
241
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
312
+ INSERT INTO self_directives (id, companion_id, priority, directive, status, category, scope_actor, supersedes_id, created_at)
313
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
242
314
  `);
243
- stmt.run(directive.id, directive.companionId, directive.priority, directive.directive, directive.status, directive.category, directive.supersedesId || null, directive.createdAt || new Date().toISOString());
315
+ stmt.run(directive.id, directive.companionId, directive.priority !== undefined ? directive.priority : 50, directive.directive, normalizeStatus(directive.status, 'active'), directive.category || 'behavioral', directive.scopeActor || null, directive.supersedesId || null, directive.createdAt || new Date().toISOString());
244
316
  }
245
317
  getDirective(id, companionId) {
246
318
  const stmt = companionId
@@ -249,16 +321,7 @@ class SiduriDatabase {
249
321
  const row = (companionId ? stmt.get(id, companionId) : stmt.get(id));
250
322
  if (!row)
251
323
  return undefined;
252
- return {
253
- id: row.id,
254
- companionId: row.companion_id,
255
- priority: row.priority,
256
- directive: row.directive,
257
- status: row.status,
258
- category: row.category,
259
- supersedesId: row.supersedes_id || undefined,
260
- createdAt: row.created_at,
261
- };
324
+ return this.rowToSelfDirective(row);
262
325
  }
263
326
  approveDirective(id, companionId) {
264
327
  const findStmt = companionId
@@ -268,28 +331,28 @@ class SiduriDatabase {
268
331
  if (!row) {
269
332
  return;
270
333
  }
271
- if (row.status !== 'PENDING') {
272
- throw new Error(`Cannot approve directive '${id}': invalid transition from status '${row.status}' to 'ACTIVE' (only PENDING directives can be approved)`);
334
+ if (normalizeStatus(row.status) !== 'pending') {
335
+ throw new Error(`Cannot approve directive '${id}': invalid transition from status '${row.status}' to 'active' (only pending directives can be approved)`);
273
336
  }
274
- // If this directive supersedes an earlier directive, transition that prior directive to SUPERSEDED
337
+ // If this directive supersedes an earlier directive, transition that prior directive to superseded
275
338
  if (row.supersedes_id) {
276
339
  const supersededId = row.supersedes_id;
277
340
  const effectiveCompanionId = companionId || row.companion_id;
278
341
  if (effectiveCompanionId) {
279
- const supersedeStmt = this.db.prepare("UPDATE self_directives SET status = 'SUPERSEDED' WHERE id = ? AND companion_id = ?");
342
+ const supersedeStmt = this.db.prepare("UPDATE self_directives SET status = 'superseded' WHERE id = ? AND companion_id = ?");
280
343
  supersedeStmt.run(supersededId, effectiveCompanionId);
281
344
  }
282
345
  else {
283
- const supersedeStmt = this.db.prepare("UPDATE self_directives SET status = 'SUPERSEDED' WHERE id = ?");
346
+ const supersedeStmt = this.db.prepare("UPDATE self_directives SET status = 'superseded' WHERE id = ?");
284
347
  supersedeStmt.run(supersededId);
285
348
  }
286
349
  }
287
350
  if (companionId) {
288
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'ACTIVE' WHERE id = ? AND companion_id = ? AND status = 'PENDING'");
351
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'active' WHERE id = ? AND companion_id = ? AND LOWER(status) = 'pending'");
289
352
  stmt.run(id, companionId);
290
353
  }
291
354
  else {
292
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'ACTIVE' WHERE id = ? AND status = 'PENDING'");
355
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'active' WHERE id = ? AND LOWER(status) = 'pending'");
293
356
  stmt.run(id);
294
357
  }
295
358
  }
@@ -301,45 +364,45 @@ class SiduriDatabase {
301
364
  if (!row) {
302
365
  return;
303
366
  }
304
- if (row.status !== 'PENDING') {
305
- throw new Error(`Cannot reject directive '${id}': invalid transition from status '${row.status}' to 'REJECTED' (only PENDING directives can be rejected)`);
367
+ if (normalizeStatus(row.status) !== 'pending') {
368
+ throw new Error(`Cannot reject directive '${id}': invalid transition from status '${row.status}' to 'rejected' (only pending directives can be rejected)`);
306
369
  }
307
370
  if (companionId) {
308
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'REJECTED' WHERE id = ? AND companion_id = ? AND status = 'PENDING'");
371
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'rejected' WHERE id = ? AND companion_id = ? AND LOWER(status) = 'pending'");
309
372
  stmt.run(id, companionId);
310
373
  }
311
374
  else {
312
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'REJECTED' WHERE id = ? AND status = 'PENDING'");
375
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'rejected' WHERE id = ? AND LOWER(status) = 'pending'");
313
376
  stmt.run(id);
314
377
  }
315
378
  }
316
379
  revokeDirective(id, companionId) {
317
380
  if (companionId) {
318
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'REVOKED' WHERE id = ? AND companion_id = ?");
381
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'revoked' WHERE id = ? AND companion_id = ?");
319
382
  stmt.run(id, companionId);
320
383
  }
321
384
  else {
322
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'REVOKED' WHERE id = ?");
385
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'revoked' WHERE id = ?");
323
386
  stmt.run(id);
324
387
  }
325
388
  }
326
389
  expireDirective(id, companionId) {
327
390
  if (companionId) {
328
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'EXPIRED' WHERE id = ? AND companion_id = ?");
391
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'expired' WHERE id = ? AND companion_id = ?");
329
392
  stmt.run(id, companionId);
330
393
  }
331
394
  else {
332
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'EXPIRED' WHERE id = ?");
395
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'expired' WHERE id = ?");
333
396
  stmt.run(id);
334
397
  }
335
398
  }
336
399
  disableDirective(id, companionId) {
337
400
  if (companionId) {
338
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'DISABLED' WHERE id = ? AND companion_id = ?");
401
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'disabled' WHERE id = ? AND companion_id = ?");
339
402
  stmt.run(id, companionId);
340
403
  }
341
404
  else {
342
- const stmt = this.db.prepare("UPDATE self_directives SET status = 'DISABLED' WHERE id = ?");
405
+ const stmt = this.db.prepare("UPDATE self_directives SET status = 'disabled' WHERE id = ?");
343
406
  stmt.run(id);
344
407
  }
345
408
  }
@@ -351,23 +414,66 @@ class SiduriDatabase {
351
414
  return {
352
415
  companionId: row.companion_id,
353
416
  entityId: row.entity_id,
354
- entityType: row.entity_type,
355
- trustScore: row.trust_score,
356
- familiarity: row.familiarity,
357
- interactionConventions: row.interaction_conventions ? JSON.parse(row.interaction_conventions) : []
417
+ entityType: row.entity_type || 'human',
418
+ role: row.role || 'user',
419
+ stance: row.stance || 'neutral',
420
+ trustScore: row.trust_score !== undefined && row.trust_score !== null ? row.trust_score : 0.5,
421
+ familiarity: row.familiarity !== undefined && row.familiarity !== null ? row.familiarity : 0.5,
422
+ interactionConventions: row.interaction_conventions ? JSON.parse(row.interaction_conventions) : [],
423
+ updatedAt: row.updated_at || undefined,
358
424
  };
359
425
  }
426
+ getRelationships(companionId) {
427
+ const stmt = this.db.prepare('SELECT * FROM self_relationships WHERE companion_id = ? ORDER BY entity_id ASC');
428
+ return stmt.all(companionId).map((row) => ({
429
+ companionId: row.companion_id,
430
+ entityId: row.entity_id,
431
+ entityType: row.entity_type || 'human',
432
+ role: row.role || 'user',
433
+ stance: row.stance || 'neutral',
434
+ trustScore: row.trust_score !== undefined && row.trust_score !== null ? row.trust_score : 0.5,
435
+ familiarity: row.familiarity !== undefined && row.familiarity !== null ? row.familiarity : 0.5,
436
+ interactionConventions: row.interaction_conventions ? JSON.parse(row.interaction_conventions) : [],
437
+ updatedAt: row.updated_at || undefined,
438
+ }));
439
+ }
360
440
  upsertRelationship(rel) {
361
441
  const stmt = this.db.prepare(`
362
- INSERT INTO self_relationships (companion_id, entity_id, entity_type, trust_score, familiarity, interaction_conventions)
363
- VALUES (?, ?, ?, ?, ?, ?)
442
+ INSERT INTO self_relationships (companion_id, entity_id, entity_type, role, stance, trust_score, familiarity, interaction_conventions, updated_at)
443
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))
364
444
  ON CONFLICT(companion_id, entity_id) DO UPDATE SET
365
445
  entity_type = excluded.entity_type,
446
+ role = excluded.role,
447
+ stance = excluded.stance,
366
448
  trust_score = excluded.trust_score,
367
449
  familiarity = excluded.familiarity,
368
- interaction_conventions = excluded.interaction_conventions
450
+ interaction_conventions = excluded.interaction_conventions,
451
+ updated_at = datetime('now')
369
452
  `);
370
- stmt.run(rel.companionId, rel.entityId, rel.entityType, rel.trustScore, rel.familiarity, JSON.stringify(rel.interactionConventions || []));
453
+ stmt.run(rel.companionId, rel.entityId, rel.entityType || 'human', rel.role || 'user', rel.stance || 'neutral', rel.trustScore !== undefined && rel.trustScore !== null ? rel.trustScore : 0.5, rel.familiarity !== undefined && rel.familiarity !== null ? rel.familiarity : 0.5, JSON.stringify(rel.interactionConventions || []));
454
+ }
455
+ getExemplars(companionId) {
456
+ const stmt = this.db.prepare('SELECT * FROM self_exemplars WHERE companion_id = ? ORDER BY created_at ASC');
457
+ return stmt.all(companionId).map((row) => ({
458
+ id: row.id,
459
+ companionId: row.companion_id,
460
+ user: row.user_prompt,
461
+ assistant: row.companion_response,
462
+ createdAt: row.created_at,
463
+ }));
464
+ }
465
+ setExemplars(companionId, exemplars) {
466
+ const delStmt = this.db.prepare('DELETE FROM self_exemplars WHERE companion_id = ?');
467
+ delStmt.run(companionId);
468
+ const insertStmt = this.db.prepare(`
469
+ INSERT INTO self_exemplars (id, companion_id, user_prompt, companion_response, created_at)
470
+ VALUES (?, ?, ?, ?, datetime('now'))
471
+ `);
472
+ for (let i = 0; i < exemplars.length; i++) {
473
+ const ex = exemplars[i];
474
+ const id = ex.id || `ex-${i + 1}-${Date.now()}`;
475
+ insertStmt.run(id, companionId, ex.user, ex.assistant);
476
+ }
371
477
  }
372
478
  // ==========================================
373
479
  // Knowledge / Life DB Methods
@@ -504,9 +610,26 @@ class SiduriDatabase {
504
610
  payload: JSON.parse(row.payload)
505
611
  };
506
612
  }
613
+ rowToMemoryClaim(row) {
614
+ return {
615
+ id: row.id,
616
+ companionId: row.companion_id,
617
+ subject: row.subject,
618
+ predicate: row.predicate,
619
+ value: row.value,
620
+ status: normalizeStatus(row.status, 'pending'),
621
+ confidence: row.confidence,
622
+ validFrom: row.valid_from || undefined,
623
+ validUntil: row.valid_until || undefined,
624
+ evidence: row.evidence ? (typeof row.evidence === 'string' ? JSON.parse(row.evidence) : row.evidence) : undefined,
625
+ assertedAt: row.asserted_at,
626
+ supersedes: row.supersedes || undefined,
627
+ sourceEventId: row.source_event_id || undefined,
628
+ };
629
+ }
507
630
  proposeClaim(claim) {
508
631
  const id = claim.id || crypto.randomUUID();
509
- const status = 'PENDING';
632
+ const status = normalizeStatus(claim.status, 'pending');
510
633
  const confidence = claim.confidence ?? 1.0;
511
634
  const assertedAt = claim.assertedAt || new Date().toISOString();
512
635
  const stmt = this.db.prepare(`
@@ -517,7 +640,7 @@ class SiduriDatabase {
517
640
  return {
518
641
  ...claim,
519
642
  id,
520
- status,
643
+ status: status,
521
644
  confidence,
522
645
  assertedAt,
523
646
  supersedes: claim.supersedes,
@@ -532,67 +655,67 @@ class SiduriDatabase {
532
655
  if (!row) {
533
656
  return;
534
657
  }
535
- if (row.status !== 'PENDING') {
536
- throw new Error(`Cannot approve claim '${id}': invalid transition from status '${row.status}' to 'APPROVED' (only PENDING claims can be approved)`);
658
+ if (normalizeStatus(row.status) !== 'pending') {
659
+ throw new Error(`Cannot approve claim '${id}': invalid transition from status '${row.status}' to 'approved' (only pending claims can be approved)`);
537
660
  }
538
- // If this claim supersedes an earlier claim, transition that prior claim to SUPERSEDED
661
+ // If this claim supersedes an earlier claim, transition that prior claim to superseded
539
662
  if (row.supersedes) {
540
663
  const supersededId = row.supersedes;
541
664
  if (companionId) {
542
- const supersedeStmt = this.db.prepare("UPDATE memory_claims SET status = 'SUPERSEDED' WHERE id = ? AND companion_id = ?");
665
+ const supersedeStmt = this.db.prepare("UPDATE memory_claims SET status = 'superseded' WHERE id = ? AND companion_id = ?");
543
666
  supersedeStmt.run(supersededId, companionId);
544
667
  }
545
668
  else {
546
- const supersedeStmt = this.db.prepare("UPDATE memory_claims SET status = 'SUPERSEDED' WHERE id = ?");
669
+ const supersedeStmt = this.db.prepare("UPDATE memory_claims SET status = 'superseded' WHERE id = ?");
547
670
  supersedeStmt.run(supersededId);
548
671
  }
549
672
  }
550
673
  if (companionId) {
551
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'APPROVED' WHERE id = ? AND companion_id = ? AND status = 'PENDING'");
674
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'approved' WHERE id = ? AND companion_id = ? AND LOWER(status) = 'pending'");
552
675
  stmt.run(id, companionId);
553
676
  }
554
677
  else {
555
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'APPROVED' WHERE id = ? AND status = 'PENDING'");
678
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'approved' WHERE id = ? AND LOWER(status) = 'pending'");
556
679
  stmt.run(id);
557
680
  }
558
681
  }
559
682
  rejectClaim(id, companionId) {
560
683
  if (companionId) {
561
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'REJECTED' WHERE id = ? AND companion_id = ?");
684
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'rejected' WHERE id = ? AND companion_id = ?");
562
685
  stmt.run(id, companionId);
563
686
  }
564
687
  else {
565
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'REJECTED' WHERE id = ?");
688
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'rejected' WHERE id = ?");
566
689
  stmt.run(id);
567
690
  }
568
691
  }
569
692
  revokeClaim(id, companionId) {
570
693
  if (companionId) {
571
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'REVOKED' WHERE id = ? AND companion_id = ?");
694
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'revoked' WHERE id = ? AND companion_id = ?");
572
695
  stmt.run(id, companionId);
573
696
  }
574
697
  else {
575
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'REVOKED' WHERE id = ?");
698
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'revoked' WHERE id = ?");
576
699
  stmt.run(id);
577
700
  }
578
701
  }
579
702
  expireClaim(id, companionId) {
580
703
  if (companionId) {
581
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'EXPIRED' WHERE id = ? AND companion_id = ?");
704
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'expired' WHERE id = ? AND companion_id = ?");
582
705
  stmt.run(id, companionId);
583
706
  }
584
707
  else {
585
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'EXPIRED' WHERE id = ?");
708
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'expired' WHERE id = ?");
586
709
  stmt.run(id);
587
710
  }
588
711
  }
589
712
  markClaimSessionOnly(id, companionId) {
590
713
  if (companionId) {
591
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'SESSION_ONLY' WHERE id = ? AND companion_id = ?");
714
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'session-only' WHERE id = ? AND companion_id = ?");
592
715
  stmt.run(id, companionId);
593
716
  }
594
717
  else {
595
- const stmt = this.db.prepare("UPDATE memory_claims SET status = 'SESSION_ONLY' WHERE id = ?");
718
+ const stmt = this.db.prepare("UPDATE memory_claims SET status = 'session-only' WHERE id = ?");
596
719
  stmt.run(id);
597
720
  }
598
721
  }
@@ -600,82 +723,33 @@ class SiduriDatabase {
600
723
  const stmt = this.db.prepare(`
601
724
  SELECT c.* FROM memory_claims c
602
725
  JOIN memory_search s ON c.rowid = s.rowid
603
- WHERE c.companion_id = ? AND c.status = 'APPROVED' AND memory_search MATCH ?
726
+ WHERE c.companion_id = ? AND LOWER(c.status) = 'approved' AND memory_search MATCH ?
604
727
  ORDER BY rank
605
728
  LIMIT ?
606
729
  `);
607
- return stmt.all(companionId, query, limit).map((row) => ({
608
- id: row.id,
609
- companionId: row.companion_id,
610
- subject: row.subject,
611
- predicate: row.predicate,
612
- value: row.value,
613
- status: row.status,
614
- confidence: row.confidence,
615
- validFrom: row.valid_from || undefined,
616
- validUntil: row.valid_until || undefined,
617
- evidence: row.evidence ? JSON.parse(row.evidence) : undefined,
618
- assertedAt: row.asserted_at,
619
- supersedes: row.supersedes || undefined,
620
- sourceEventId: row.source_event_id || undefined,
621
- }));
730
+ return stmt.all(companionId, query, limit).map((row) => this.rowToMemoryClaim(row));
622
731
  }
623
732
  getPendingClaims(companionId, limit = 50) {
624
- const stmt = this.db.prepare("SELECT * FROM memory_claims WHERE companion_id = ? AND status = 'PENDING' ORDER BY asserted_at DESC LIMIT ?");
625
- return stmt.all(companionId, limit).map((row) => ({
626
- id: row.id,
627
- companionId: row.companion_id,
628
- subject: row.subject,
629
- predicate: row.predicate,
630
- value: row.value,
631
- status: row.status,
632
- confidence: row.confidence,
633
- validFrom: row.valid_from || undefined,
634
- validUntil: row.valid_until || undefined,
635
- evidence: row.evidence ? JSON.parse(row.evidence) : undefined,
636
- assertedAt: row.asserted_at,
637
- supersedes: row.supersedes || undefined,
638
- sourceEventId: row.source_event_id || undefined,
639
- }));
733
+ const stmt = this.db.prepare("SELECT * FROM memory_claims WHERE companion_id = ? AND LOWER(status) = 'pending' ORDER BY asserted_at DESC LIMIT ?");
734
+ return stmt.all(companionId, limit).map((row) => this.rowToMemoryClaim(row));
640
735
  }
641
736
  getApprovedClaims(companionId, limit = 50) {
642
- const stmt = this.db.prepare("SELECT * FROM memory_claims WHERE companion_id = ? AND status = 'APPROVED' ORDER BY asserted_at DESC LIMIT ?");
643
- return stmt.all(companionId, limit).map((row) => ({
644
- id: row.id,
645
- companionId: row.companion_id,
646
- subject: row.subject,
647
- predicate: row.predicate,
648
- value: row.value,
649
- status: row.status,
650
- confidence: row.confidence,
651
- validFrom: row.valid_from || undefined,
652
- validUntil: row.valid_until || undefined,
653
- evidence: row.evidence ? JSON.parse(row.evidence) : undefined,
654
- assertedAt: row.asserted_at,
655
- supersedes: row.supersedes || undefined,
656
- sourceEventId: row.source_event_id || undefined,
657
- }));
737
+ const stmt = this.db.prepare("SELECT * FROM memory_claims WHERE companion_id = ? AND LOWER(status) = 'approved' ORDER BY asserted_at DESC LIMIT ?");
738
+ return stmt.all(companionId, limit).map((row) => this.rowToMemoryClaim(row));
739
+ }
740
+ getAllClaims(companionId, limit = 100) {
741
+ const stmt = companionId
742
+ ? this.db.prepare("SELECT * FROM memory_claims WHERE companion_id = ? ORDER BY asserted_at DESC LIMIT ?")
743
+ : this.db.prepare("SELECT * FROM memory_claims ORDER BY asserted_at DESC LIMIT ?");
744
+ const rows = companionId ? stmt.all(companionId, limit) : stmt.all(limit);
745
+ return rows.map((row) => this.rowToMemoryClaim(row));
658
746
  }
659
747
  getClaim(id) {
660
748
  const stmt = this.db.prepare("SELECT * FROM memory_claims WHERE id = ?");
661
749
  const row = stmt.get(id);
662
750
  if (!row)
663
751
  return undefined;
664
- return {
665
- id: row.id,
666
- companionId: row.companion_id,
667
- subject: row.subject,
668
- predicate: row.predicate,
669
- value: row.value,
670
- status: row.status,
671
- confidence: row.confidence,
672
- validFrom: row.valid_from || undefined,
673
- validUntil: row.valid_until || undefined,
674
- evidence: row.evidence ? JSON.parse(row.evidence) : undefined,
675
- assertedAt: row.asserted_at,
676
- supersedes: row.supersedes || undefined,
677
- sourceEventId: row.source_event_id || undefined,
678
- };
752
+ return this.rowToMemoryClaim(row);
679
753
  }
680
754
  resetMemory(companionId) {
681
755
  const deleteClaims = this.db.prepare("DELETE FROM memory_claims WHERE companion_id = ?");