@siduri-x/core 2.0.7 → 2.0.9

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.
@@ -113,7 +113,7 @@ class ActionPolicyEngine {
113
113
  }
114
114
  // Channel check if tool restricts channels
115
115
  if (toolDef.allowedChannels && toolDef.allowedChannels.length > 0) {
116
- const channel = effectiveContext.conversation.channel || 'direct';
116
+ const channel = effectiveContext.conversation?.channel || 'direct';
117
117
  if (!toolDef.allowedChannels.includes(channel)) {
118
118
  const decision = {
119
119
  allowed: false,
@@ -248,10 +248,10 @@ class ActionPolicyEngine {
248
248
  providerId,
249
249
  parametersHash: paramsHash,
250
250
  companionId: effectiveContext.companionId,
251
- actorId: effectiveContext.actor.actorId,
252
- sessionId: effectiveContext.actor.sessionId,
253
- channel: effectiveContext.conversation.channel,
254
- correlationId: effectiveContext.conversation.correlationId,
251
+ actorId: effectiveContext.actor?.actorId || 'owner-user',
252
+ sessionId: effectiveContext.actor?.sessionId || `sess-${effectiveContext.companionId}`,
253
+ channel: effectiveContext.conversation?.channel || 'direct',
254
+ correlationId: effectiveContext.conversation?.correlationId || `corr-${Date.now()}`,
255
255
  riskLevel,
256
256
  issuedAt,
257
257
  expiresAt,
@@ -413,10 +413,10 @@ class ActionPolicyEngine {
413
413
  actionId: action.actionId,
414
414
  toolName: action.toolName,
415
415
  companionId: context?.companionId || 'unknown',
416
- actorId: context?.actor.actorId,
417
- sessionId: context?.actor.sessionId,
418
- channel: context?.conversation.channel,
419
- correlationId: context?.conversation.correlationId,
416
+ actorId: context?.actor?.actorId,
417
+ sessionId: context?.actor?.sessionId,
418
+ channel: context?.conversation?.channel,
419
+ correlationId: context?.conversation?.correlationId,
420
420
  riskLevel: decision?.riskLevel || 'LOW',
421
421
  lifecycle,
422
422
  decision,
@@ -122,6 +122,9 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
122
122
  if (ctx.identity.archetype || ctx.identity.role) {
123
123
  parts.push(`- Role: ${ctx.identity.role || ctx.identity.archetype}`);
124
124
  }
125
+ if (ctx.identity.origin) {
126
+ parts.push(`- Origin/Created By: ${ctx.identity.origin}`);
127
+ }
125
128
  }
126
129
  if (ctx.relationship) {
127
130
  const nameStr = ctx.relationship.name ? ` [Name: ${ctx.relationship.name}]` : '';
@@ -640,4 +643,163 @@ describe('Conversational Teach Mode End-to-End Lifecycle', () => {
640
643
  expect(lastCallCtx.systemPrompt).toContain('Kur Zagin');
641
644
  db.close();
642
645
  });
646
+ // =========================================================================
647
+ // Test I: Benchmark replication (name, creator, new chat turn-1 recognition)
648
+ // =========================================================================
649
+ it('Test I: reproduces benchmark scenario: teaches name, teaches creator relationship, and verifies new session recognizes creator in origin and relationship', async () => {
650
+ const db = new index_1.SiduriDatabase({ dbPath });
651
+ const companionId = 'comp-test-i';
652
+ const self = createSelfRepository(db);
653
+ const memory = createMemoryOrgan(db);
654
+ const behavior = createBehaviorCompiler();
655
+ const mockBrain = {
656
+ generatePlan: jest.fn().mockImplementation(async (brainCtx) => {
657
+ const lastMsg = brainCtx.recentMessages?.[brainCtx.recentMessages.length - 1]?.content || '';
658
+ const memoryProposals = [];
659
+ const behaviorProposals = [];
660
+ if (/your name is Siduri/i.test(lastMsg)) {
661
+ memoryProposals.push({
662
+ subject: 'companion:self',
663
+ predicate: 'name',
664
+ value: 'Siduri',
665
+ });
666
+ behaviorProposals.push({
667
+ directive: 'Address self as Siduri',
668
+ category: 'relational',
669
+ subject: 'companion:self',
670
+ predicate: 'name',
671
+ value: 'Siduri',
672
+ });
673
+ }
674
+ if (/i am Kur Zagin, your creator/i.test(lastMsg)) {
675
+ memoryProposals.push({
676
+ subject: 'actor:kur_zagin',
677
+ predicate: 'name',
678
+ value: 'Kur Zagin',
679
+ });
680
+ memoryProposals.push({
681
+ subject: 'actor:kur_zagin',
682
+ predicate: 'stated_relationship',
683
+ value: 'creator of companion Siduri',
684
+ });
685
+ behaviorProposals.push({
686
+ directive: 'Acknowledge actor:kur_zagin as creator of companion Siduri',
687
+ category: 'relational',
688
+ subject: 'actor:kur_zagin',
689
+ predicate: 'stated_relationship',
690
+ value: 'creator of companion Siduri',
691
+ });
692
+ behaviorProposals.push({
693
+ directive: 'Address actor:kur_zagin as Kur Zagin',
694
+ category: 'behavioral',
695
+ subject: 'actor:kur_zagin',
696
+ predicate: 'name',
697
+ value: 'Kur Zagin',
698
+ });
699
+ }
700
+ return {
701
+ speech: 'I understand and acknowledge.',
702
+ language: 'en',
703
+ memoryProposals: memoryProposals.length > 0 ? memoryProposals : undefined,
704
+ behaviorProposals: behaviorProposals.length > 0 ? behaviorProposals : undefined,
705
+ _receivedSystemPrompt: brainCtx.systemPrompt,
706
+ };
707
+ }),
708
+ };
709
+ const runtime = new index_1.SiduriRuntime(companionId, { name: 'Siduri' }, {
710
+ brain: mockBrain,
711
+ memory,
712
+ self,
713
+ behavior,
714
+ });
715
+ await runtime.initialize();
716
+ // Session 1 - Turn 1: "your name is Siduri"
717
+ const res1 = await runtime.processPerception({
718
+ source: 'text_chat',
719
+ text: 'your name is Siduri',
720
+ context: createRequestContext(companionId, 'teach', 'owner-user'),
721
+ });
722
+ expect(res1.status).toBe('APPROVED');
723
+ const nameProp = res1.metadata?.proposals?.find((p) => p.predicate === 'name');
724
+ expect(nameProp).toBeDefined();
725
+ await runtime.approveProposal(nameProp.id, { companionId });
726
+ // Verify companion name in self_identity
727
+ const idStep1 = await self.getIdentity(companionId);
728
+ expect(idStep1?.name).toBe('Siduri');
729
+ // Session 1 - Turn 2: "i am Kur Zagin, your creator"
730
+ const res2 = await runtime.processPerception({
731
+ source: 'text_chat',
732
+ text: 'i am Kur Zagin, your creator',
733
+ context: createRequestContext(companionId, 'teach', 'owner-user'),
734
+ });
735
+ expect(res2.status).toBe('APPROVED');
736
+ // Approve both proposals (name and creator of companion Siduri)
737
+ const proposals2 = res2.metadata?.proposals || [];
738
+ const creatorProp = proposals2.find((p) => p.predicate === 'stated_relationship');
739
+ const userProp = proposals2.find((p) => p.predicate === 'name');
740
+ expect(creatorProp).toBeDefined();
741
+ expect(userProp).toBeDefined();
742
+ await runtime.approveProposal(creatorProp.id, { companionId });
743
+ await runtime.approveProposal(userProp.id, { companionId });
744
+ // Also approve the behavioral directives
745
+ const dirProps = res2.metadata?.behavioral_proposals || [];
746
+ for (const d of dirProps) {
747
+ if (d.directive_id) {
748
+ await runtime.approveDirective(d.directive_id, { companionId });
749
+ }
750
+ }
751
+ // Verify self_identity.origin has been dual-promoted!
752
+ const idStep2 = await self.getIdentity(companionId);
753
+ expect(idStep2?.name).toBe('Siduri');
754
+ expect(idStep2?.origin).toBe('Kur Zagin');
755
+ // Verify relationship has creator role, loyal stance, and user name
756
+ const relStep2 = await self.getRelationship(companionId, 'actor:kur_zagin');
757
+ expect(relStep2).toBeDefined();
758
+ expect(relStep2?.role).toBe('creator');
759
+ expect(relStep2?.stance).toBe('familiar_loyal');
760
+ expect(relStep2?.trustScore).toBe(1.0);
761
+ expect(relStep2?.name).toBe('Kur Zagin');
762
+ // Verify single-owner fallback: an incoming request with 'owner-user' gets the primary relationship!
763
+ const relOwnerUser = await self.getRelationship(companionId, 'owner-user');
764
+ expect(relOwnerUser).toBeDefined();
765
+ expect(relOwnerUser?.name).toBe('Kur Zagin');
766
+ expect(relOwnerUser?.role).toBe('creator');
767
+ expect(relOwnerUser?.stance).toBe('familiar_loyal');
768
+ // =======================================================================
769
+ // Session 2 ("New Chat"): user opens a fresh session as 'owner-user'
770
+ // =======================================================================
771
+ // Turn 1: "hey, who are you?"
772
+ await runtime.processPerception({
773
+ source: 'text_chat',
774
+ text: 'hey, who are you?',
775
+ context: createRequestContext(companionId, 'hybrid', 'owner-user'),
776
+ });
777
+ const calls = mockBrain.generatePlan.mock.calls;
778
+ const newChatTurn1Ctx = calls[calls.length - 1][0];
779
+ // Identity nucleus has origin
780
+ expect(newChatTurn1Ctx.systemPrompt).toContain('Name: Siduri');
781
+ expect(newChatTurn1Ctx.systemPrompt).toContain('Origin/Created By: Kur Zagin');
782
+ // Relationship stance recognizes Kur Zagin as creator
783
+ expect(newChatTurn1Ctx.systemPrompt).toContain('Kur Zagin');
784
+ expect(newChatTurn1Ctx.systemPrompt).toContain('familiar_loyal');
785
+ // Turn 2: "who is your creator?"
786
+ await runtime.processPerception({
787
+ source: 'text_chat',
788
+ text: 'who is your creator?',
789
+ context: createRequestContext(companionId, 'hybrid', 'owner-user'),
790
+ });
791
+ const newChatTurn2Ctx = calls[calls.length - 1][0];
792
+ expect(newChatTurn2Ctx.systemPrompt).toContain('Origin/Created By: Kur Zagin');
793
+ // Turn 3: From an anonymous guest session:
794
+ // Should NOT get the personal relationship stance, but Identity origin remains!
795
+ await runtime.processPerception({
796
+ source: 'text_chat',
797
+ text: 'who is your creator?',
798
+ context: createRequestContext(companionId, 'hybrid', 'anonymous-session'),
799
+ });
800
+ const guestTurnCtx = calls[calls.length - 1][0];
801
+ expect(guestTurnCtx.systemPrompt).toContain('Origin/Created By: Kur Zagin');
802
+ expect(guestTurnCtx.systemPrompt).not.toContain('Stance toward anonymous-session [Name: Kur Zagin]');
803
+ db.close();
804
+ });
643
805
  });
@@ -20,21 +20,37 @@ async function normalizeUserInput(message, roleOrContext = 'OWNER', history = []
20
20
  ? 'VIEWER'
21
21
  : 'OWNER')
22
22
  : roleOrContext;
23
+ const defaultActor = {
24
+ actorId: role === 'VIEWER' ? 'anonymous-session' : 'owner-user',
25
+ sessionId: `sess-${companionId}`,
26
+ authorizationRole: role === 'VIEWER' ? 'viewer' : 'administrator',
27
+ capabilities: role === 'VIEWER' ? ['chat'] : ['chat', 'memory:approve', 'action:execute'],
28
+ authenticated: role !== 'VIEWER',
29
+ };
30
+ const defaultConversation = {
31
+ channel: 'direct',
32
+ correlationId: `corr-${Date.now()}`,
33
+ };
23
34
  const requestContext = isContextObject
24
- ? roleOrContext
25
- : {
26
- companionId,
35
+ ? {
36
+ companionId: roleOrContext.companionId || companionId,
27
37
  actor: {
28
- actorId: role === 'VIEWER' ? 'anonymous-session' : 'owner-user',
29
- sessionId: `sess-${companionId}`,
30
- authorizationRole: role === 'VIEWER' ? 'viewer' : 'administrator',
31
- capabilities: role === 'VIEWER' ? ['chat'] : ['chat', 'memory:approve', 'action:execute'],
32
- authenticated: role !== 'VIEWER',
38
+ ...defaultActor,
39
+ ...(roleOrContext.actor || {}),
33
40
  },
34
41
  conversation: {
35
- channel: 'direct',
36
- correlationId: `corr-${Date.now()}`,
42
+ ...defaultConversation,
43
+ ...(roleOrContext.conversation || {}),
37
44
  },
45
+ source: roleOrContext.source || 'local',
46
+ ...(roleOrContext.mode ? { mode: roleOrContext.mode } : {}),
47
+ ...(roleOrContext.subject ? { subject: roleOrContext.subject } : {}),
48
+ ...(roleOrContext.metadata ? { metadata: roleOrContext.metadata } : {}),
49
+ }
50
+ : {
51
+ companionId,
52
+ actor: defaultActor,
53
+ conversation: defaultConversation,
38
54
  source: 'local',
39
55
  };
40
56
  // Universal Perception: Route user input through EarOrgan if available
@@ -36,4 +36,13 @@ describe('InputNormalizer', () => {
36
36
  expect(mockEar.listen).toHaveBeenCalledWith('text_chat', 'raw text', expect.anything());
37
37
  expect(result.perceivedText).toBe('transcribed text');
38
38
  });
39
+ test('safely normalizes partial context object (e.g. { mode: "hybrid" }) with default actor and conversation', async () => {
40
+ const result = await (0, input_normalizer_1.normalizeUserInput)('test query', { mode: 'hybrid' }, [], 'comp-2');
41
+ expect(result.requestContext.conversation).toBeDefined();
42
+ expect(result.requestContext.conversation.channel).toBe('direct');
43
+ expect(result.requestContext.conversation.correlationId).toBeDefined();
44
+ expect(result.requestContext.actor).toBeDefined();
45
+ expect(result.requestContext.actor.actorId).toBe('owner-user');
46
+ expect(result.requestContext.mode).toBe('hybrid');
47
+ });
39
48
  });
@@ -32,8 +32,8 @@ async function settleMemoryProposals(params) {
32
32
  message: perceivedText,
33
33
  role,
34
34
  companionId,
35
- actorId: requestContext.actor.actorId,
36
- channel: requestContext.conversation.channel,
35
+ actorId: requestContext.actor?.actorId || 'owner-user',
36
+ channel: requestContext.conversation?.channel || 'direct',
37
37
  },
38
38
  };
39
39
  await memory.addSourceEvent(sourceEvent);
package/dist/runtime.js CHANGED
@@ -273,19 +273,22 @@ async function promoteApprovedClaimToSelf(claim, self, companionId) {
273
273
  predicate === 'preferred_address' ||
274
274
  predicate === 'affiliation') {
275
275
  const rawSubject = (claim.subject || 'actor:user').replace(/^actor:actor:/, 'actor:');
276
- const isCreator = value.toLowerCase() === 'creator';
276
+ const isCreator = value.toLowerCase().includes('creator');
277
277
  const isName = predicate === 'name' || predicate === 'preferred_address';
278
278
  const isAffil = predicate === 'affiliation';
279
279
  const existingRel = typeof self.getRelationship === 'function'
280
280
  ? await self.getRelationship(targetCompanionId, rawSubject)
281
281
  : null;
282
- const role = isCreator ? value : (existingRel?.role || (isName || isAffil ? existingRel?.role : value));
282
+ const isPriorCreator = existingRel?.role === 'creator' || (existingRel?.stance === 'familiar_loyal' && existingRel.trustScore === 1.0);
283
+ const role = isCreator
284
+ ? 'creator'
285
+ : (isPriorCreator ? 'creator' : (existingRel?.role && existingRel.role !== 'user' ? existingRel.role : (isName || isAffil ? existingRel?.role || 'user' : value)));
283
286
  const name = isName ? value : existingRel?.name;
284
287
  const affiliation = isAffil ? value : existingRel?.affiliation;
285
- const stance = isCreator ? 'familiar_loyal' : (existingRel?.stance || 'neutral');
286
- const trustScore = isCreator ? 1.0 : (existingRel?.trustScore ?? 0.8);
287
- const familiarity = isCreator ? 0.9 : (existingRel?.familiarity ?? 0.5);
288
- const interactionConventions = isCreator
288
+ const stance = isCreator || isPriorCreator ? 'familiar_loyal' : (existingRel?.stance || 'neutral');
289
+ const trustScore = isCreator || isPriorCreator ? 1.0 : (existingRel?.trustScore ?? 0.8);
290
+ const familiarity = isCreator || isPriorCreator ? 0.9 : (existingRel?.familiarity ?? 0.5);
291
+ const interactionConventions = isCreator || isPriorCreator
289
292
  ? Array.from(new Set([...(existingRel?.interactionConventions || []), 'Direct communication', 'Highest administrative trust']))
290
293
  : (existingRel?.interactionConventions || []);
291
294
  await self.updateRelationship(targetCompanionId, {
@@ -300,6 +303,19 @@ async function promoteApprovedClaimToSelf(claim, self, companionId) {
300
303
  familiarity,
301
304
  interactionConventions,
302
305
  });
306
+ // Dual promotion: If this actor is established as creator, also populate companion's origin in self_identity
307
+ if (isCreator || (isName && isPriorCreator)) {
308
+ const existingIdentity = (await self.getIdentity(targetCompanionId)) || {
309
+ companionId: targetCompanionId,
310
+ name: 'Siduri',
311
+ version: '1.0.0',
312
+ updatedAt: new Date().toISOString(),
313
+ };
314
+ const creatorName = name || existingRel?.name || (rawSubject.startsWith('actor:') && rawSubject !== 'actor:user' && rawSubject !== 'actor:primary' ? rawSubject.slice(6) : value);
315
+ existingIdentity.origin = creatorName !== 'user' && creatorName !== 'primary' ? creatorName : value;
316
+ existingIdentity.updatedAt = new Date().toISOString();
317
+ await self.setIdentity(existingIdentity);
318
+ }
303
319
  if (isName) {
304
320
  await self.commitDirectives(targetCompanionId, [
305
321
  {
package/dist/siduri-db.js CHANGED
@@ -236,6 +236,34 @@ class SiduriDatabase {
236
236
  catch {
237
237
  // Column already exists
238
238
  }
239
+ try {
240
+ // Reconcile creator claims that may have been recorded before origin dual-promotion
241
+ const creatorClaims = this.db.prepare(`
242
+ SELECT * FROM memory_claims
243
+ WHERE predicate = 'stated_relationship'
244
+ AND LOWER(value) LIKE '%creator%'
245
+ AND LOWER(status) = 'approved'
246
+ `).all();
247
+ for (const claim of creatorClaims) {
248
+ const identity = this.db.prepare(`SELECT * FROM self_identity WHERE companion_id = ?`).get(claim.companion_id);
249
+ if (identity && !identity.origin) {
250
+ const nameClaim = this.db.prepare(`
251
+ SELECT value FROM memory_claims
252
+ WHERE companion_id = ? AND subject = ? AND predicate = 'name' AND LOWER(status) = 'approved'
253
+ ORDER BY asserted_at DESC LIMIT 1
254
+ `).get(claim.companion_id, claim.subject);
255
+ const originName = nameClaim?.value || (claim.subject.startsWith('actor:') ? claim.subject.slice(6) : claim.subject);
256
+ this.db.prepare(`UPDATE self_identity SET origin = ? WHERE companion_id = ?`).run(originName, claim.companion_id);
257
+ }
258
+ const rel = this.db.prepare(`SELECT * FROM self_relationships WHERE companion_id = ? AND entity_id = ?`).get(claim.companion_id, claim.subject);
259
+ if (rel && (rel.role !== 'creator' || rel.stance !== 'familiar_loyal')) {
260
+ this.db.prepare(`UPDATE self_relationships SET role = 'creator', stance = 'familiar_loyal', trust_score = 1.0 WHERE companion_id = ? AND entity_id = ?`).run(claim.companion_id, claim.subject);
261
+ }
262
+ }
263
+ }
264
+ catch {
265
+ // Best-effort auto-reconciliation
266
+ }
239
267
  }
240
268
  close() {
241
269
  this.db.close();
@@ -446,7 +474,11 @@ class SiduriDatabase {
446
474
  const stripped = entityId.startsWith('actor:') ? entityId.slice(6) : entityId;
447
475
  const prefixed = entityId.startsWith('actor:') ? entityId : `actor:${entityId}`;
448
476
  const stmt = this.db.prepare('SELECT * FROM self_relationships WHERE companion_id = ? AND (entity_id = ? OR entity_id = ? OR entity_id = ?)');
449
- const row = stmt.get(companionId, entityId, stripped, prefixed);
477
+ let row = stmt.get(companionId, entityId, stripped, prefixed);
478
+ if (!row && (entityId === 'owner-user' || entityId === 'local-user' || entityId === 'owner' || entityId === 'primary' || entityId === 'user')) {
479
+ const fallbackStmt = this.db.prepare("SELECT * FROM self_relationships WHERE companion_id = ? AND entity_type = 'human' ORDER BY updated_at DESC LIMIT 1");
480
+ row = fallbackStmt.get(companionId);
481
+ }
450
482
  if (!row)
451
483
  return undefined;
452
484
  return {
@@ -789,17 +821,20 @@ class SiduriDatabase {
789
821
  predicate === 'preferred_address' ||
790
822
  predicate === 'affiliation') {
791
823
  const rawSubject = (claim.subject || 'actor:user').replace(/^actor:actor:/, 'actor:');
792
- const isCreator = value.toLowerCase() === 'creator';
824
+ const isCreator = value.toLowerCase().includes('creator');
793
825
  const isName = predicate === 'name' || predicate === 'preferred_address';
794
826
  const isAffil = predicate === 'affiliation';
795
827
  const existingRel = this.getRelationship(companionId, rawSubject);
796
- const role = isCreator ? value : (existingRel?.role || (isName || isAffil ? existingRel?.role : value));
828
+ const isPriorCreator = existingRel?.role === 'creator' || (existingRel?.stance === 'familiar_loyal' && existingRel.trustScore === 1.0);
829
+ const role = isCreator
830
+ ? 'creator'
831
+ : (isPriorCreator ? 'creator' : (existingRel?.role && existingRel.role !== 'user' ? existingRel.role : (isName || isAffil ? existingRel?.role || 'user' : value)));
797
832
  const name = isName ? value : existingRel?.name;
798
833
  const affiliation = isAffil ? value : existingRel?.affiliation;
799
- const stance = isCreator ? 'familiar_loyal' : (existingRel?.stance || 'neutral');
800
- const trustScore = isCreator ? 1.0 : (existingRel?.trustScore ?? 0.8);
801
- const familiarity = isCreator ? 0.9 : (existingRel?.familiarity ?? 0.5);
802
- const interactionConventions = isCreator
834
+ const stance = isCreator || isPriorCreator ? 'familiar_loyal' : (existingRel?.stance || 'neutral');
835
+ const trustScore = isCreator || isPriorCreator ? 1.0 : (existingRel?.trustScore ?? 0.8);
836
+ const familiarity = isCreator || isPriorCreator ? 0.9 : (existingRel?.familiarity ?? 0.5);
837
+ const interactionConventions = isCreator || isPriorCreator
803
838
  ? Array.from(new Set([...(existingRel?.interactionConventions || []), 'Direct communication', 'Highest administrative trust']))
804
839
  : (existingRel?.interactionConventions || []);
805
840
  this.upsertRelationship({
@@ -814,6 +849,19 @@ class SiduriDatabase {
814
849
  familiarity,
815
850
  interactionConventions,
816
851
  });
852
+ // Dual promotion: If this actor is established as creator, also populate companion's origin in self_identity
853
+ if (isCreator || (isName && isPriorCreator)) {
854
+ const existingIdentity = this.getIdentity(companionId) || {
855
+ companionId,
856
+ name: 'Siduri',
857
+ version: '1.0.0',
858
+ updatedAt: new Date().toISOString(),
859
+ };
860
+ const creatorName = name || existingRel?.name || (rawSubject.startsWith('actor:') && rawSubject !== 'actor:user' && rawSubject !== 'actor:primary' ? rawSubject.slice(6) : value);
861
+ existingIdentity.origin = creatorName !== 'user' && creatorName !== 'primary' ? creatorName : value;
862
+ existingIdentity.updatedAt = new Date().toISOString();
863
+ this.setIdentity(existingIdentity);
864
+ }
817
865
  if (isName) {
818
866
  this.commitDirective({
819
867
  id: `dir-name-${claim.id || Date.now()}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siduri-x/core",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "Core runtime types, evidence protocol, action dispatcher, capability validation, and SiduriRuntime protocol",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {