@sidurijs/core 1.0.0 → 1.0.2
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/LICENSE +190 -0
- package/dist/adversarial.test.js +27 -19
- package/dist/chat-contract.d.ts +9 -0
- package/dist/cognition-planner.d.ts +2 -2
- package/dist/container.d.ts +6 -4
- package/dist/container.js +1 -4
- package/dist/context-retriever.d.ts +5 -4
- package/dist/context-retriever.js +43 -25
- package/dist/conversational-teach.test.js +61 -53
- package/dist/evidence.d.ts +3 -3
- package/dist/gating.d.ts +2 -2
- package/dist/gating.js +1 -1
- package/dist/index.d.ts +43 -51
- package/dist/index.js +1 -1
- package/dist/intent-classifier.d.ts +1 -1
- package/dist/intent-classifier.js +4 -4
- package/dist/intent-classifier.test.js +1 -1
- package/dist/{memory-settler.d.ts → interaction-settler.d.ts} +12 -11
- package/dist/interaction-settler.js +173 -0
- package/dist/perception-cycle.test.js +18 -34
- package/dist/perception-pipeline.d.ts +6 -5
- package/dist/perception-pipeline.js +17 -15
- package/dist/prompt-compiler.d.ts +1 -1
- package/dist/prompt-compiler.js +11 -11
- package/dist/prompt-compiler.test.js +5 -5
- package/dist/proposals.d.ts +1 -2
- package/dist/response-envelope.d.ts +3 -3
- package/dist/response-envelope.js +5 -4
- package/dist/runtime-facades.test.js +12 -35
- package/dist/runtime.d.ts +16 -10
- package/dist/runtime.js +85 -107
- package/dist/schema-validator.test.js +3 -3
- package/dist/session-history.d.ts +3 -3
- package/dist/session-history.js +1 -1
- package/dist/siduri-db.d.ts +11 -29
- package/dist/siduri-db.js +159 -445
- package/dist/siduri-db.test.js +113 -281
- package/dist/teaching.d.ts +3 -3
- package/dist/teaching.js +1 -1
- package/package.json +7 -7
- package/dist/memory-settler.js +0 -161
package/dist/siduri-db.test.js
CHANGED
|
@@ -408,10 +408,10 @@ describe('SiduriDatabase', () => {
|
|
|
408
408
|
});
|
|
409
409
|
});
|
|
410
410
|
// ==========================================
|
|
411
|
-
//
|
|
411
|
+
// Archive Domain Tests
|
|
412
412
|
// ==========================================
|
|
413
|
-
describe('
|
|
414
|
-
it('records
|
|
413
|
+
describe('Archive Domain', () => {
|
|
414
|
+
it('records archive events and retrieves in reverse chronological order', () => {
|
|
415
415
|
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
416
416
|
const events = [
|
|
417
417
|
{
|
|
@@ -437,216 +437,58 @@ describe('SiduriDatabase', () => {
|
|
|
437
437
|
},
|
|
438
438
|
];
|
|
439
439
|
for (const e of events) {
|
|
440
|
-
db.
|
|
440
|
+
db.recordArchiveEvent(e);
|
|
441
441
|
}
|
|
442
|
-
const result = db.
|
|
442
|
+
const result = db.getRecentArchiveEvents('siduri-test', 10);
|
|
443
443
|
expect(result).toHaveLength(3);
|
|
444
444
|
// Reverse chronological order
|
|
445
445
|
expect(result[0].occurredAt).toBe('2026-09-11T10:02:00Z');
|
|
446
446
|
expect(result[1].occurredAt).toBe('2026-09-11T10:01:00Z');
|
|
447
447
|
expect(result[2].occurredAt).toBe('2026-09-11T10:00:00Z');
|
|
448
448
|
});
|
|
449
|
-
it('
|
|
449
|
+
it('searches archive events using FTS5 full-text search', () => {
|
|
450
450
|
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
451
|
-
|
|
452
|
-
id:
|
|
453
|
-
companionId: 'siduri-test',
|
|
454
|
-
subject: 'Kur',
|
|
455
|
-
predicate: 'is',
|
|
456
|
-
value: 'a dark entity from the underworld',
|
|
457
|
-
confidence: 0.8,
|
|
458
|
-
evidence: ['lore book chapter 3'],
|
|
459
|
-
assertedAt: new Date().toISOString(),
|
|
460
|
-
});
|
|
461
|
-
expect(claim.status).toBe('pending');
|
|
462
|
-
expect(claim.subject).toBe('Kur');
|
|
463
|
-
expect(claim.predicate).toBe('is');
|
|
464
|
-
expect(claim.value).toBe('a dark entity from the underworld');
|
|
465
|
-
expect(claim.confidence).toBe(0.8);
|
|
466
|
-
});
|
|
467
|
-
it('approves and rejects claims', () => {
|
|
468
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
469
|
-
const claim1 = db.proposeClaim({
|
|
470
|
-
id: crypto.randomUUID(),
|
|
451
|
+
db.recordArchiveEvent({
|
|
452
|
+
id: 'arch-1',
|
|
471
453
|
companionId: 'siduri-test',
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
confidence: 0.9,
|
|
476
|
-
assertedAt: new Date().toISOString(),
|
|
477
|
-
});
|
|
478
|
-
const claim2 = db.proposeClaim({
|
|
479
|
-
id: crypto.randomUUID(),
|
|
480
|
-
companionId: 'siduri-test',
|
|
481
|
-
subject: 'Kur',
|
|
482
|
-
predicate: 'likes',
|
|
483
|
-
value: 'apples',
|
|
484
|
-
confidence: 0.3,
|
|
485
|
-
assertedAt: new Date().toISOString(),
|
|
486
|
-
});
|
|
487
|
-
db.approveClaim(claim1.id);
|
|
488
|
-
db.rejectClaim(claim2.id);
|
|
489
|
-
const approved = db.getApprovedClaims('siduri-test');
|
|
490
|
-
expect(approved).toHaveLength(1);
|
|
491
|
-
expect(approved[0].id).toBe(claim1.id);
|
|
492
|
-
expect(approved[0].status).toBe('approved');
|
|
493
|
-
});
|
|
494
|
-
it('searches claims using FTS5 full-text search', () => {
|
|
495
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
496
|
-
// Insert and approve several claims
|
|
497
|
-
const c1 = db.proposeClaim({
|
|
498
|
-
id: crypto.randomUUID(),
|
|
499
|
-
companionId: 'siduri-test',
|
|
500
|
-
subject: 'Kur',
|
|
501
|
-
predicate: 'rules',
|
|
502
|
-
value: 'the dark underworld realm',
|
|
503
|
-
confidence: 0.9,
|
|
504
|
-
assertedAt: new Date().toISOString(),
|
|
454
|
+
sourceType: 'chat_turn',
|
|
455
|
+
occurredAt: '2026-09-11T10:00:00Z',
|
|
456
|
+
payload: { text: 'Kur rules the dark underworld realm' },
|
|
505
457
|
});
|
|
506
|
-
|
|
507
|
-
id:
|
|
458
|
+
db.recordArchiveEvent({
|
|
459
|
+
id: 'arch-2',
|
|
508
460
|
companionId: 'siduri-test',
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
confidence: 0.95,
|
|
513
|
-
assertedAt: new Date().toISOString(),
|
|
461
|
+
sourceType: 'chat_turn',
|
|
462
|
+
occurredAt: '2026-09-11T10:01:00Z',
|
|
463
|
+
payload: { text: 'Gilgamesh is king of Uruk' },
|
|
514
464
|
});
|
|
515
|
-
const
|
|
516
|
-
id: crypto.randomUUID(),
|
|
517
|
-
companionId: 'siduri-test',
|
|
518
|
-
subject: 'Enkidu',
|
|
519
|
-
predicate: 'wanders',
|
|
520
|
-
value: 'the wild forest',
|
|
521
|
-
confidence: 0.85,
|
|
522
|
-
assertedAt: new Date().toISOString(),
|
|
523
|
-
});
|
|
524
|
-
db.approveClaim(c1.id);
|
|
525
|
-
db.approveClaim(c2.id);
|
|
526
|
-
db.approveClaim(c3.id);
|
|
527
|
-
// Search for "underworld" — should match c1 only
|
|
528
|
-
const results = db.searchClaims('siduri-test', 'underworld');
|
|
465
|
+
const results = db.searchArchiveEvents('siduri-test', 'underworld');
|
|
529
466
|
expect(results.length).toBeGreaterThan(0);
|
|
530
|
-
expect(results.some((
|
|
531
|
-
expect(results.some((
|
|
532
|
-
|
|
533
|
-
const results2 = db.searchClaims('siduri-test', 'Gilgamesh');
|
|
467
|
+
expect(results.some((r) => r.id === 'arch-1')).toBe(true);
|
|
468
|
+
expect(results.some((r) => r.id === 'arch-2')).toBe(false);
|
|
469
|
+
const results2 = db.searchArchiveEvents('siduri-test', 'Gilgamesh');
|
|
534
470
|
expect(results2.length).toBeGreaterThan(0);
|
|
535
|
-
expect(results2.some((
|
|
471
|
+
expect(results2.some((r) => r.id === 'arch-2')).toBe(true);
|
|
536
472
|
});
|
|
537
|
-
it('
|
|
473
|
+
it('resets archive for the specified companion only', () => {
|
|
538
474
|
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
539
|
-
|
|
540
|
-
const c1 = db.proposeClaim({
|
|
541
|
-
id: crypto.randomUUID(),
|
|
542
|
-
companionId: 'siduri-test',
|
|
543
|
-
subject: 'dark forest',
|
|
544
|
-
predicate: 'has',
|
|
545
|
-
value: 'dark trees and dark monsters',
|
|
546
|
-
confidence: 0.8,
|
|
547
|
-
assertedAt: new Date().toISOString(),
|
|
548
|
-
});
|
|
549
|
-
// c2 mentions "dark" once → should rank lower
|
|
550
|
-
const c2 = db.proposeClaim({
|
|
551
|
-
id: crypto.randomUUID(),
|
|
552
|
-
companionId: 'siduri-test',
|
|
553
|
-
subject: 'cave',
|
|
554
|
-
predicate: 'has',
|
|
555
|
-
value: 'a dark entrance',
|
|
556
|
-
confidence: 0.8,
|
|
557
|
-
assertedAt: new Date().toISOString(),
|
|
558
|
-
});
|
|
559
|
-
db.approveClaim(c1.id);
|
|
560
|
-
db.approveClaim(c2.id);
|
|
561
|
-
const results = db.searchClaims('siduri-test', 'dark');
|
|
562
|
-
expect(results).toHaveLength(2);
|
|
563
|
-
// More occurrences of "dark" → better BM25 rank (lower rank value = better match)
|
|
564
|
-
expect(results[0].id).toBe(c1.id);
|
|
565
|
-
});
|
|
566
|
-
it('excludes pending and rejected claims from searchClaims in SiduriDatabase', () => {
|
|
567
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
568
|
-
const pending = db.proposeClaim({
|
|
569
|
-
id: crypto.randomUUID(),
|
|
570
|
-
companionId: 'siduri-test',
|
|
571
|
-
subject: 'SecretProject',
|
|
572
|
-
predicate: 'status',
|
|
573
|
-
value: 'unapproved draft specification',
|
|
574
|
-
confidence: 0.9,
|
|
575
|
-
assertedAt: new Date().toISOString(),
|
|
576
|
-
});
|
|
577
|
-
// Must not match while pending
|
|
578
|
-
let results = db.searchClaims('siduri-test', 'unapproved');
|
|
579
|
-
expect(results.some((r) => r.id === pending.id)).toBe(false);
|
|
580
|
-
// Approve: now it matches
|
|
581
|
-
db.approveClaim(pending.id, 'siduri-test');
|
|
582
|
-
results = db.searchClaims('siduri-test', 'unapproved');
|
|
583
|
-
expect(results.some((r) => r.id === pending.id)).toBe(true);
|
|
584
|
-
// Revoke: must no longer match
|
|
585
|
-
db.revokeClaim(pending.id, 'siduri-test');
|
|
586
|
-
results = db.searchClaims('siduri-test', 'unapproved');
|
|
587
|
-
expect(results.some((r) => r.id === pending.id)).toBe(false);
|
|
588
|
-
// Explicitly rejected claims must also not match
|
|
589
|
-
const rejected = db.proposeClaim({
|
|
590
|
-
id: crypto.randomUUID(),
|
|
591
|
-
companionId: 'siduri-test',
|
|
592
|
-
subject: 'RejectedFact',
|
|
593
|
-
predicate: 'status',
|
|
594
|
-
value: 'unapproved rejection draft',
|
|
595
|
-
confidence: 0.1,
|
|
596
|
-
});
|
|
597
|
-
db.rejectClaim(rejected.id, 'siduri-test');
|
|
598
|
-
results = db.searchClaims('siduri-test', 'rejection');
|
|
599
|
-
expect(results.some((r) => r.id === rejected.id)).toBe(false);
|
|
600
|
-
});
|
|
601
|
-
it('bounds approveClaim to specific companionId when provided', () => {
|
|
602
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
603
|
-
const claim = db.proposeClaim({
|
|
604
|
-
id: crypto.randomUUID(),
|
|
605
|
-
companionId: 'companion-target',
|
|
606
|
-
subject: 'ProtectedFact',
|
|
607
|
-
predicate: 'belongsTo',
|
|
608
|
-
value: 'Target',
|
|
609
|
-
confidence: 1.0,
|
|
610
|
-
assertedAt: new Date().toISOString(),
|
|
611
|
-
});
|
|
612
|
-
// Attempting to approve for a different companion must not affect it
|
|
613
|
-
db.approveClaim(claim.id, 'companion-intruder');
|
|
614
|
-
expect(db.getApprovedClaims('companion-target')).toHaveLength(0);
|
|
615
|
-
// Approving with the correct companionId succeeds
|
|
616
|
-
db.approveClaim(claim.id, 'companion-target');
|
|
617
|
-
expect(db.getApprovedClaims('companion-target')).toHaveLength(1);
|
|
618
|
-
});
|
|
619
|
-
it('resets memory for the specified companion only', () => {
|
|
620
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
621
|
-
const c1 = db.proposeClaim({
|
|
475
|
+
db.recordArchiveEvent({
|
|
622
476
|
id: crypto.randomUUID(),
|
|
623
477
|
companionId: 'comp-1',
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
confidence: 1.0,
|
|
478
|
+
sourceType: 'chat_turn',
|
|
479
|
+
occurredAt: new Date().toISOString(),
|
|
480
|
+
payload: { text: 'Hello 1' },
|
|
628
481
|
});
|
|
629
|
-
|
|
482
|
+
db.recordArchiveEvent({
|
|
630
483
|
id: crypto.randomUUID(),
|
|
631
484
|
companionId: 'comp-2',
|
|
632
|
-
subject: 'Fact2',
|
|
633
|
-
predicate: 'is',
|
|
634
|
-
value: 'Two',
|
|
635
|
-
confidence: 1.0,
|
|
636
|
-
});
|
|
637
|
-
db.approveClaim(c1.id, 'comp-1');
|
|
638
|
-
db.approveClaim(c2.id, 'comp-2');
|
|
639
|
-
db.recordEvent({
|
|
640
|
-
id: crypto.randomUUID(),
|
|
641
|
-
companionId: 'comp-1',
|
|
642
485
|
sourceType: 'chat_turn',
|
|
643
486
|
occurredAt: new Date().toISOString(),
|
|
644
|
-
payload: { text: 'Hello' },
|
|
487
|
+
payload: { text: 'Hello 2' },
|
|
645
488
|
});
|
|
646
|
-
db.
|
|
647
|
-
expect(db.
|
|
648
|
-
expect(db.
|
|
649
|
-
expect(db.getApprovedClaims('comp-2')).toHaveLength(1);
|
|
489
|
+
db.resetArchive('comp-1');
|
|
490
|
+
expect(db.getRecentArchiveEvents('comp-1')).toHaveLength(0);
|
|
491
|
+
expect(db.getRecentArchiveEvents('comp-2')).toHaveLength(1);
|
|
650
492
|
});
|
|
651
493
|
});
|
|
652
494
|
// ==========================================
|
|
@@ -684,17 +526,14 @@ describe('SiduriDatabase', () => {
|
|
|
684
526
|
properties: { vintage: 2020, region: 'Uruk' },
|
|
685
527
|
updatedAt: new Date().toISOString(),
|
|
686
528
|
});
|
|
687
|
-
// Write
|
|
688
|
-
|
|
689
|
-
id:
|
|
529
|
+
// Write Archive data
|
|
530
|
+
db.recordArchiveEvent({
|
|
531
|
+
id: 'arch-cId',
|
|
690
532
|
companionId: cId,
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
confidence: 1.0,
|
|
695
|
-
assertedAt: new Date().toISOString(),
|
|
533
|
+
sourceType: 'chat_turn',
|
|
534
|
+
occurredAt: new Date().toISOString(),
|
|
535
|
+
payload: { text: 'wine is the finest in Mesopotamia' },
|
|
696
536
|
});
|
|
697
|
-
db.approveClaim(claim.id);
|
|
698
537
|
// Close and reopen
|
|
699
538
|
db.close();
|
|
700
539
|
const db2 = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
@@ -704,8 +543,8 @@ describe('SiduriDatabase', () => {
|
|
|
704
543
|
expect(db2.getActiveDirectives(cId)[0].directive).toBe('Serve drinks gracefully');
|
|
705
544
|
expect(db2.getInventory(cId)).toHaveLength(1);
|
|
706
545
|
expect(db2.getInventory(cId)[0].entityName).toBe('Aged Wine');
|
|
707
|
-
const
|
|
708
|
-
expect(
|
|
546
|
+
const archiveEvents = db2.searchArchiveEvents(cId, 'wine');
|
|
547
|
+
expect(archiveEvents.some((e) => e.id === 'arch-cId')).toBe(true);
|
|
709
548
|
db2.close();
|
|
710
549
|
// Prevent afterEach from double-closing
|
|
711
550
|
db = null;
|
|
@@ -715,7 +554,7 @@ describe('SiduriDatabase', () => {
|
|
|
715
554
|
const cId = 'siduri-test';
|
|
716
555
|
expect(() => {
|
|
717
556
|
for (let i = 0; i < 100; i++) {
|
|
718
|
-
db.
|
|
557
|
+
db.recordArchiveEvent({
|
|
719
558
|
id: crypto.randomUUID(),
|
|
720
559
|
companionId: cId,
|
|
721
560
|
sourceType: 'chat_turn',
|
|
@@ -730,18 +569,17 @@ describe('SiduriDatabase', () => {
|
|
|
730
569
|
currency: 'USD',
|
|
731
570
|
timestamp: new Date().toISOString(),
|
|
732
571
|
});
|
|
733
|
-
db.
|
|
572
|
+
db.commitDirective({
|
|
734
573
|
id: crypto.randomUUID(),
|
|
735
574
|
companionId: cId,
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
assertedAt: new Date().toISOString(),
|
|
575
|
+
priority: 50,
|
|
576
|
+
directive: `directive-${i}`,
|
|
577
|
+
category: 'behavioral',
|
|
578
|
+
status: 'active',
|
|
741
579
|
});
|
|
742
580
|
}
|
|
743
581
|
}).not.toThrow();
|
|
744
|
-
expect(db.
|
|
582
|
+
expect(db.getRecentArchiveEvents(cId, 200)).toHaveLength(100);
|
|
745
583
|
expect(db.getFinanceEntries(cId, 200)).toHaveLength(100);
|
|
746
584
|
});
|
|
747
585
|
it('returns undefined/empty for non-existent data', () => {
|
|
@@ -755,9 +593,8 @@ describe('SiduriDatabase', () => {
|
|
|
755
593
|
expect(db.getFinanceEntries(cId)).toHaveLength(0);
|
|
756
594
|
expect(db.getSchedule(cId)).toHaveLength(0);
|
|
757
595
|
expect(db.getPreferences(cId)).toHaveLength(0);
|
|
758
|
-
expect(db.
|
|
759
|
-
expect(db.
|
|
760
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(0);
|
|
596
|
+
expect(db.getRecentArchiveEvents(cId)).toHaveLength(0);
|
|
597
|
+
expect(db.searchArchiveEvents(cId, 'anything')).toHaveLength(0);
|
|
761
598
|
});
|
|
762
599
|
it('enforces directive state transitions (pending -> active -> disabled/rejected/revoked)', () => {
|
|
763
600
|
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
@@ -901,76 +738,6 @@ describe('SiduriDatabase', () => {
|
|
|
901
738
|
db.approveDirective('dir-beta-1', cIdB);
|
|
902
739
|
expect(db.getActiveDirectives(cIdB)).toHaveLength(1);
|
|
903
740
|
});
|
|
904
|
-
it('enforces claim state transitions (pending -> approved -> revoked/expired/session_only)', () => {
|
|
905
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
906
|
-
const cId = 'claim-state-test';
|
|
907
|
-
const claim = db.proposeClaim({
|
|
908
|
-
id: 'claim-1',
|
|
909
|
-
companionId: cId,
|
|
910
|
-
subject: 'user',
|
|
911
|
-
predicate: 'likes',
|
|
912
|
-
value: 'matcha',
|
|
913
|
-
});
|
|
914
|
-
expect(claim.status).toBe('pending');
|
|
915
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(0);
|
|
916
|
-
// Approve
|
|
917
|
-
db.approveClaim('claim-1');
|
|
918
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(1);
|
|
919
|
-
// Revoke
|
|
920
|
-
db.revokeClaim('claim-1');
|
|
921
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(0);
|
|
922
|
-
// Session only
|
|
923
|
-
const claim2 = db.proposeClaim({
|
|
924
|
-
id: 'claim-2',
|
|
925
|
-
companionId: cId,
|
|
926
|
-
subject: 'session',
|
|
927
|
-
predicate: 'topic',
|
|
928
|
-
value: 'investigation',
|
|
929
|
-
});
|
|
930
|
-
db.markClaimSessionOnly('claim-2');
|
|
931
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(0);
|
|
932
|
-
// Expire
|
|
933
|
-
db.expireClaim('claim-2');
|
|
934
|
-
expect(db.getApprovedClaims(cId)).toHaveLength(0);
|
|
935
|
-
});
|
|
936
|
-
it('strictly rejects illegal claim state transitions in approveClaim', () => {
|
|
937
|
-
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
938
|
-
const cId = 'claim-transition-test';
|
|
939
|
-
// 1. Propose and reject claim
|
|
940
|
-
const rejectedClaim = db.proposeClaim({
|
|
941
|
-
id: 'claim-rejected',
|
|
942
|
-
companionId: cId,
|
|
943
|
-
subject: 'fact',
|
|
944
|
-
predicate: 'is',
|
|
945
|
-
value: 'false',
|
|
946
|
-
});
|
|
947
|
-
db.rejectClaim(rejectedClaim.id);
|
|
948
|
-
// Attempting to approve a REJECTED claim must throw
|
|
949
|
-
expect(() => db.approveClaim(rejectedClaim.id)).toThrow(/invalid transition from status 'rejected' to 'approved'/i);
|
|
950
|
-
// 2. Propose and approve claim, then revoke
|
|
951
|
-
const revokedClaim = db.proposeClaim({
|
|
952
|
-
id: 'claim-revoked',
|
|
953
|
-
companionId: cId,
|
|
954
|
-
subject: 'fact',
|
|
955
|
-
predicate: 'is',
|
|
956
|
-
value: 'outdated',
|
|
957
|
-
});
|
|
958
|
-
db.approveClaim(revokedClaim.id);
|
|
959
|
-
db.revokeClaim(revokedClaim.id);
|
|
960
|
-
// Attempting to approve a REVOKED claim must throw
|
|
961
|
-
expect(() => db.approveClaim(revokedClaim.id)).toThrow(/invalid transition from status 'revoked' to 'approved'/i);
|
|
962
|
-
// 3. Propose and expire claim
|
|
963
|
-
const expiredClaim = db.proposeClaim({
|
|
964
|
-
id: 'claim-expired',
|
|
965
|
-
companionId: cId,
|
|
966
|
-
subject: 'fact',
|
|
967
|
-
predicate: 'is',
|
|
968
|
-
value: 'temporary',
|
|
969
|
-
});
|
|
970
|
-
db.expireClaim(expiredClaim.id);
|
|
971
|
-
// Attempting to approve an EXPIRED claim must throw
|
|
972
|
-
expect(() => db.approveClaim(expiredClaim.id)).toThrow(/invalid transition from status 'expired' to 'approved'/i);
|
|
973
|
-
});
|
|
974
741
|
});
|
|
975
742
|
describe('System Logs', () => {
|
|
976
743
|
it('persists structured system logs and queries them with filters', () => {
|
|
@@ -1018,4 +785,69 @@ describe('SiduriDatabase', () => {
|
|
|
1018
785
|
expect(db.queryLogs({ companionId: cId })).toHaveLength(0);
|
|
1019
786
|
});
|
|
1020
787
|
});
|
|
788
|
+
describe('RFC VX-26-13: Deconstructed Archive & Direct Domain Routing', () => {
|
|
789
|
+
it('records and searches cold audit events via archive_events and FTS5', () => {
|
|
790
|
+
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
791
|
+
const cId = 'arch-comp-1';
|
|
792
|
+
db.recordArchiveEvent({
|
|
793
|
+
id: 'arch-evt-1',
|
|
794
|
+
companionId: cId,
|
|
795
|
+
sourceType: 'tool_execution',
|
|
796
|
+
occurredAt: new Date().toISOString(),
|
|
797
|
+
payload: { command: 'git checkout -b feature/archive', exitCode: 0 },
|
|
798
|
+
});
|
|
799
|
+
db.recordArchiveEvent({
|
|
800
|
+
id: 'arch-evt-2',
|
|
801
|
+
companionId: cId,
|
|
802
|
+
sourceType: 'chat_turn',
|
|
803
|
+
occurredAt: new Date().toISOString(),
|
|
804
|
+
payload: { text: 'How do we remove memory and switch to sovereign primitives?' },
|
|
805
|
+
});
|
|
806
|
+
const recent = db.getRecentArchiveEvents(cId);
|
|
807
|
+
expect(recent).toHaveLength(2);
|
|
808
|
+
const single = db.getArchiveEvent('arch-evt-1');
|
|
809
|
+
expect(single).toBeDefined();
|
|
810
|
+
expect(single?.sourceType).toBe('tool_execution');
|
|
811
|
+
expect(single?.payload?.command).toBe('git checkout -b feature/archive');
|
|
812
|
+
const searchResults = db.searchArchiveEvents(cId, 'primitives');
|
|
813
|
+
expect(searchResults.length).toBeGreaterThan(0);
|
|
814
|
+
expect(searchResults[0].id).toBe('arch-evt-2');
|
|
815
|
+
});
|
|
816
|
+
it('directly mutates companion relationships and identity when approving relational directives', () => {
|
|
817
|
+
db = new siduri_db_1.SiduriDatabase({ dbPath });
|
|
818
|
+
const cId = 'direct-self-comp';
|
|
819
|
+
// 1. Relational directive: Recognize creator
|
|
820
|
+
db.commitDirective({
|
|
821
|
+
id: 'dir-creator-1',
|
|
822
|
+
companionId: cId,
|
|
823
|
+
directive: 'Recognize actor:kur-zagin stated relationship as creator',
|
|
824
|
+
category: 'relational',
|
|
825
|
+
status: 'pending',
|
|
826
|
+
});
|
|
827
|
+
// Before approval: relationship does not exist
|
|
828
|
+
expect(db.getRelationship(cId, 'actor:kur-zagin')).toBeUndefined();
|
|
829
|
+
// Approve directive directly in Self
|
|
830
|
+
db.approveDirective('dir-creator-1', cId);
|
|
831
|
+
// Verify relationship is directly updated in Self
|
|
832
|
+
const rel = db.getRelationship(cId, 'actor:kur-zagin');
|
|
833
|
+
expect(rel).toBeDefined();
|
|
834
|
+
expect(rel?.role).toBe('creator');
|
|
835
|
+
expect(rel?.stance).toBe('familiar_loyal');
|
|
836
|
+
expect(rel?.trustScore).toBe(1.0);
|
|
837
|
+
// Verify companion origin is also updated
|
|
838
|
+
const identity = db.getIdentity(cId);
|
|
839
|
+
expect(identity?.origin).toBe('kur-zagin');
|
|
840
|
+
// 2. Relational directive: User name address
|
|
841
|
+
db.commitDirective({
|
|
842
|
+
id: 'dir-name-1',
|
|
843
|
+
companionId: cId,
|
|
844
|
+
directive: 'Address actor:kur-zagin as Kur Zagin',
|
|
845
|
+
category: 'relational',
|
|
846
|
+
status: 'pending',
|
|
847
|
+
});
|
|
848
|
+
db.approveDirective('dir-name-1', cId);
|
|
849
|
+
const relAfterName = db.getRelationship(cId, 'actor:kur-zagin');
|
|
850
|
+
expect(relAfterName?.name).toBe('Kur Zagin');
|
|
851
|
+
});
|
|
852
|
+
});
|
|
1021
853
|
});
|
package/dist/teaching.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { RequestContext,
|
|
1
|
+
import { RequestContext, ClaimProposal, BehaviorProposal } from './index';
|
|
2
2
|
export interface ExtractedTeaching {
|
|
3
|
-
claims:
|
|
3
|
+
claims: ClaimProposal[];
|
|
4
4
|
behaviorProposals: BehaviorProposal[];
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Deterministic teaching extraction placeholder.
|
|
8
8
|
*
|
|
9
|
-
* In Siduri-X, conversational
|
|
9
|
+
* In Siduri-X, conversational claim and behavioral proposals are generated
|
|
10
10
|
* directly by the Brain LLM via structured cognitive planning (e.g. `submitResponsePlan`).
|
|
11
11
|
* Deterministic regex matching has been removed in favor of pure LLM comprehension,
|
|
12
12
|
* as all candidates are quarantined in 'pending' status until explicitly approved by the user.
|
package/dist/teaching.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.extractDeterministicTeaching = extractDeterministicTeaching;
|
|
|
4
4
|
/**
|
|
5
5
|
* Deterministic teaching extraction placeholder.
|
|
6
6
|
*
|
|
7
|
-
* In Siduri-X, conversational
|
|
7
|
+
* In Siduri-X, conversational claim and behavioral proposals are generated
|
|
8
8
|
* directly by the Brain LLM via structured cognitive planning (e.g. `submitResponsePlan`).
|
|
9
9
|
* Deterministic regex matching has been removed in favor of pure LLM comprehension,
|
|
10
10
|
* as all candidates are quarantined in 'pending' status until explicitly approved by the user.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sidurijs/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Core runtime types, evidence protocol, action dispatcher, capability validation, and SiduriRuntime protocol",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -28,16 +28,16 @@
|
|
|
28
28
|
"default": "./dist/index.js"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsc",
|
|
33
|
-
"dev": "tsc -w",
|
|
34
|
-
"test": "jest --config jest.config.json"
|
|
35
|
-
},
|
|
36
31
|
"devDependencies": {
|
|
37
32
|
"@types/jest": "^30.0.0",
|
|
38
33
|
"@types/node": "^26.5.1",
|
|
39
34
|
"jest": "^30.5.1",
|
|
40
35
|
"ts-jest": "^29.4.12",
|
|
41
36
|
"typescript": "^5.9.3"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"dev": "tsc -w",
|
|
41
|
+
"test": "jest --config jest.config.json"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
}
|