forge-openclaw-plugin 0.2.19 → 0.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +133 -2
  2. package/dist/assets/board-_C6oMy5w.js +6 -0
  3. package/dist/assets/{board-8L3uX7_O.js.map → board-_C6oMy5w.js.map} +1 -1
  4. package/dist/assets/index-B4A6TooJ.js +63 -0
  5. package/dist/assets/index-B4A6TooJ.js.map +1 -0
  6. package/dist/assets/index-D6Xs_2mo.css +1 -0
  7. package/dist/assets/{motion-1GAqqi8M.js → motion-D4sZgCHd.js} +2 -2
  8. package/dist/assets/{motion-1GAqqi8M.js.map → motion-D4sZgCHd.js.map} +1 -1
  9. package/dist/assets/{table-DBGlgRjk.js → table-BWzTaky1.js} +2 -2
  10. package/dist/assets/{table-DBGlgRjk.js.map → table-BWzTaky1.js.map} +1 -1
  11. package/dist/assets/{ui-iTluWjC4.js → ui-BzK4azQb.js} +7 -7
  12. package/dist/assets/{ui-iTluWjC4.js.map → ui-BzK4azQb.js.map} +1 -1
  13. package/dist/assets/vendor-DT3pnAKJ.css +1 -0
  14. package/dist/assets/vendor-De38P6YR.js +729 -0
  15. package/dist/assets/vendor-De38P6YR.js.map +1 -0
  16. package/dist/assets/viz-C6hfyqzu.js +34 -0
  17. package/dist/assets/viz-C6hfyqzu.js.map +1 -0
  18. package/dist/index.html +9 -9
  19. package/dist/openclaw/parity.d.ts +1 -1
  20. package/dist/openclaw/parity.js +29 -2
  21. package/dist/openclaw/routes.js +207 -24
  22. package/dist/openclaw/tools.js +324 -35
  23. package/dist/server/app.js +2080 -92
  24. package/dist/server/db.js +3 -0
  25. package/dist/server/health.js +1284 -0
  26. package/dist/server/managers/platform/background-job-manager.js +138 -2
  27. package/dist/server/managers/platform/llm-manager.js +126 -0
  28. package/dist/server/managers/platform/openai-responses-provider.js +773 -0
  29. package/dist/server/managers/runtime.js +6 -1
  30. package/dist/server/openapi.js +718 -0
  31. package/dist/server/preferences-seeds.js +409 -0
  32. package/dist/server/preferences-types.js +368 -0
  33. package/dist/server/psyche-types.js +42 -18
  34. package/dist/server/repositories/activity-events.js +53 -4
  35. package/dist/server/repositories/calendar.js +89 -15
  36. package/dist/server/repositories/collaboration.js +8 -3
  37. package/dist/server/repositories/diagnostic-logs.js +243 -0
  38. package/dist/server/repositories/entity-ownership.js +92 -0
  39. package/dist/server/repositories/goals.js +7 -2
  40. package/dist/server/repositories/habits.js +122 -16
  41. package/dist/server/repositories/notes.js +119 -41
  42. package/dist/server/repositories/preferences.js +1765 -0
  43. package/dist/server/repositories/projects.js +18 -7
  44. package/dist/server/repositories/psyche.js +84 -27
  45. package/dist/server/repositories/rewards.js +112 -4
  46. package/dist/server/repositories/strategies.js +450 -0
  47. package/dist/server/repositories/tags.js +11 -6
  48. package/dist/server/repositories/task-runs.js +10 -2
  49. package/dist/server/repositories/tasks.js +99 -17
  50. package/dist/server/repositories/users.js +417 -0
  51. package/dist/server/repositories/wiki-memory.js +3366 -0
  52. package/dist/server/services/context.js +20 -18
  53. package/dist/server/services/dashboard.js +29 -6
  54. package/dist/server/services/entity-crud.js +21 -3
  55. package/dist/server/services/insights.js +9 -7
  56. package/dist/server/services/projects.js +2 -1
  57. package/dist/server/services/psyche.js +10 -9
  58. package/dist/server/types.js +594 -30
  59. package/openclaw.plugin.json +1 -1
  60. package/package.json +1 -1
  61. package/server/migrations/015_multi_user_and_strategies.sql +244 -0
  62. package/server/migrations/016_health_companion.sql +158 -0
  63. package/server/migrations/016_strategy_contracts_and_user_graph.sql +22 -0
  64. package/server/migrations/017_preferences.sql +131 -0
  65. package/server/migrations/018_preference_catalogs.sql +31 -0
  66. package/server/migrations/019_wiki_memory.sql +255 -0
  67. package/server/migrations/020_wiki_page_hierarchy.sql +11 -0
  68. package/server/migrations/021_hide_evidence_from_wiki_index.sql +3 -0
  69. package/server/migrations/022_wiki_ingest_background.sql +85 -0
  70. package/server/migrations/023_diagnostic_logs.sql +28 -0
  71. package/skills/forge-openclaw/SKILL.md +126 -34
  72. package/skills/forge-openclaw/entity_conversation_playbooks.md +337 -0
  73. package/skills/forge-openclaw/psyche_entity_playbooks.md +404 -0
  74. package/dist/assets/board-8L3uX7_O.js +0 -6
  75. package/dist/assets/index-Cj1IBH_w.js +0 -36
  76. package/dist/assets/index-Cj1IBH_w.js.map +0 -1
  77. package/dist/assets/index-DQT6EbuS.css +0 -1
  78. package/dist/assets/vendor-BvM2F9Dp.js +0 -503
  79. package/dist/assets/vendor-BvM2F9Dp.js.map +0 -1
  80. package/dist/assets/vendor-CRS-psbw.css +0 -1
  81. package/dist/assets/viz-CNeunkfu.js +0 -34
  82. package/dist/assets/viz-CNeunkfu.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { getDatabase, runInTransaction } from "../db.js";
3
3
  import { recordActivityEvent } from "./activity-events.js";
4
+ import { decorateOwnedEntity, inferFirstOwnedUserId, setEntityOwner } from "./entity-ownership.js";
4
5
  import { filterDeletedEntities, isEntityDeleted } from "./deleted-entities.js";
5
6
  import { createLinkedNotes } from "./notes.js";
6
7
  import { assertGoalExists } from "../services/relations.js";
@@ -33,7 +34,7 @@ function getDefaultProjectTemplate(goal) {
33
34
  }
34
35
  }
35
36
  function mapProject(row) {
36
- return projectSchema.parse({
37
+ return projectSchema.parse(decorateOwnedEntity("project", {
37
38
  id: row.id,
38
39
  goalId: row.goal_id,
39
40
  title: row.title,
@@ -44,7 +45,7 @@ function mapProject(row) {
44
45
  schedulingRules: calendarSchedulingRulesSchema.parse(JSON.parse(row.scheduling_rules_json || "{}")),
45
46
  createdAt: row.created_at,
46
47
  updatedAt: row.updated_at
47
- });
48
+ }));
48
49
  }
49
50
  function completeLinkedProjectTasks(projectId, activity) {
50
51
  const openTasks = listTasks({ projectId }).filter((task) => task.status !== "done");
@@ -101,6 +102,8 @@ export function createProject(input, activity) {
101
102
  .prepare(`INSERT INTO projects (id, goal_id, title, description, status, theme_color, target_points, scheduling_rules_json, created_at, updated_at)
102
103
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
103
104
  .run(id, parsed.goalId, parsed.title, parsed.description, parsed.status, parsed.themeColor, parsed.targetPoints, JSON.stringify(parsed.schedulingRules), now, now);
105
+ setEntityOwner("project", id, parsed.userId ??
106
+ inferFirstOwnedUserId([{ entityType: "goal", entityId: parsed.goalId }]));
104
107
  const project = getProjectById(id);
105
108
  createLinkedNotes(parsed.notes, { entityType: "project", entityId: project.id, anchorKey: null }, activity ?? { source: "ui", actor: null });
106
109
  if (activity) {
@@ -150,6 +153,9 @@ export function updateProject(projectId, input, activity) {
150
153
  getDatabase()
151
154
  .prepare(`UPDATE tasks SET goal_id = ?, updated_at = ? WHERE project_id = ?`)
152
155
  .run(next.goalId, next.updatedAt, projectId);
156
+ if (parsed.userId !== undefined) {
157
+ setEntityOwner("project", projectId, parsed.userId);
158
+ }
153
159
  const completedLinkedTaskCount = current.status !== "completed" && next.status === "completed"
154
160
  ? completeLinkedProjectTasks(projectId, activity)
155
161
  : 0;
@@ -160,7 +166,9 @@ export function updateProject(projectId, input, activity) {
160
166
  entityType: "project",
161
167
  entityId: project.id,
162
168
  eventType: statusChanged ? "project_status_changed" : "project_updated",
163
- title: statusChanged ? `Project ${project.status}: ${project.title}` : `Project updated: ${project.title}`,
169
+ title: statusChanged
170
+ ? `Project ${project.status}: ${project.title}`
171
+ : `Project updated: ${project.title}`,
164
172
  description: statusChanged && project.status === "completed"
165
173
  ? `Project finished and auto-completed ${completedLinkedTaskCount} linked unfinished task${completedLinkedTaskCount === 1 ? "" : "s"}.`
166
174
  : statusChanged
@@ -197,7 +205,11 @@ export function ensureDefaultProjectForGoal(goalId) {
197
205
  getDatabase()
198
206
  .prepare(`INSERT INTO projects (id, goal_id, title, description, status, theme_color, target_points, scheduling_rules_json, created_at, updated_at)
199
207
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
200
- .run(id, goalId, template.title, template.description, goal.status === "completed" ? "completed" : goal.status === "paused" ? "paused" : "active", goal.themeColor, Math.max(100, Math.round(goal.targetPoints / 2)), JSON.stringify({
208
+ .run(id, goalId, template.title, template.description, goal.status === "completed"
209
+ ? "completed"
210
+ : goal.status === "paused"
211
+ ? "paused"
212
+ : "active", goal.themeColor, Math.max(100, Math.round(goal.targetPoints / 2)), JSON.stringify({
201
213
  allowWorkBlockKinds: [],
202
214
  blockWorkBlockKinds: [],
203
215
  allowCalendarIds: [],
@@ -209,6 +221,7 @@ export function ensureDefaultProjectForGoal(goalId) {
209
221
  allowAvailability: [],
210
222
  blockAvailability: []
211
223
  }), now, now);
224
+ setEntityOwner("project", id, goal.userId);
212
225
  return getProjectById(id);
213
226
  });
214
227
  }
@@ -219,9 +232,7 @@ export function deleteProject(projectId, activity) {
219
232
  }
220
233
  return runInTransaction(() => {
221
234
  pruneLinkedEntityReferences("project", projectId);
222
- getDatabase()
223
- .prepare(`DELETE FROM projects WHERE id = ?`)
224
- .run(projectId);
235
+ getDatabase().prepare(`DELETE FROM projects WHERE id = ?`).run(projectId);
225
236
  if (activity) {
226
237
  recordActivityEvent({
227
238
  entityType: "project",
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { getDatabase, runInTransaction } from "../db.js";
3
3
  import { recordActivityEvent } from "./activity-events.js";
4
4
  import { filterDeletedEntities, filterDeletedIds, isEntityDeleted } from "./deleted-entities.js";
5
+ import { clearEntityOwner, decorateOwnedEntity, setEntityOwner } from "./entity-ownership.js";
5
6
  import { recordEventLog } from "./event-log.js";
6
7
  import { unlinkNotesForEntity } from "./notes.js";
7
8
  import { recordPsycheClarityReward, recordPsycheReflectionReward } from "./rewards.js";
@@ -13,6 +14,9 @@ function parseJson(value) {
13
14
  function buildId(prefix) {
14
15
  return `${prefix}_${randomUUID().replaceAll("-", "").slice(0, 10)}`;
15
16
  }
17
+ function assignOwnedEntity(entityType, entityId, userId, actor) {
18
+ return setEntityOwner(entityType, entityId, userId, actor ?? null);
19
+ }
16
20
  function enrichTriggerItems(items, prefix) {
17
21
  return items.map((item) => ({
18
22
  ...item,
@@ -388,7 +392,7 @@ export function getEventTypeById(eventTypeId) {
388
392
  const row = getRow(`SELECT id, domain_id, label, description, system, created_at, updated_at
389
393
  FROM event_types
390
394
  WHERE id = ?`, eventTypeId);
391
- return row ? mapEventType(row) : undefined;
395
+ return row ? decorateOwnedEntity("event_type", mapEventType(row)) : undefined;
392
396
  }
393
397
  export function createEventType(input, context) {
394
398
  const parsed = createEventTypeSchema.parse(input);
@@ -406,6 +410,7 @@ export function createEventType(input, context) {
406
410
  .prepare(`INSERT INTO event_types (id, domain_id, label, description, system, created_at, updated_at)
407
411
  VALUES (?, ?, ?, ?, 0, ?, ?)`)
408
412
  .run(eventType.id, eventType.domainId, eventType.label, eventType.description, eventType.createdAt, eventType.updatedAt);
413
+ assignOwnedEntity("event_type", eventType.id, parsed.userId, context.actor);
409
414
  mapCreateUpdateContext({
410
415
  entityType: "event_type",
411
416
  entityId: eventType.id,
@@ -415,7 +420,7 @@ export function createEventType(input, context) {
415
420
  actor: context.actor ?? null,
416
421
  metadata: { domainId: eventType.domainId }
417
422
  });
418
- return eventType;
423
+ return decorateOwnedEntity("event_type", eventType);
419
424
  }
420
425
  export function updateEventType(eventTypeId, patch, context) {
421
426
  const existing = getEventTypeById(eventTypeId);
@@ -433,6 +438,9 @@ export function updateEventType(eventTypeId, patch, context) {
433
438
  SET label = ?, description = ?, updated_at = ?
434
439
  WHERE id = ?`)
435
440
  .run(updated.label, updated.description, updated.updatedAt, eventTypeId);
441
+ if (parsed.userId !== undefined) {
442
+ assignOwnedEntity("event_type", eventTypeId, parsed.userId, context.actor);
443
+ }
436
444
  mapCreateUpdateContext({
437
445
  entityType: "event_type",
438
446
  entityId: eventTypeId,
@@ -442,7 +450,7 @@ export function updateEventType(eventTypeId, patch, context) {
442
450
  actor: context.actor ?? null,
443
451
  metadata: { domainId: updated.domainId }
444
452
  });
445
- return updated;
453
+ return decorateOwnedEntity("event_type", updated);
446
454
  }
447
455
  export function deleteEventType(eventTypeId, context) {
448
456
  const existing = getEventTypeById(eventTypeId);
@@ -451,6 +459,7 @@ export function deleteEventType(eventTypeId, context) {
451
459
  }
452
460
  return runInTransaction(() => {
453
461
  unlinkEntityNotes("event_type", eventTypeId);
462
+ clearEntityOwner("event_type", eventTypeId);
454
463
  getDatabase()
455
464
  .prepare(`DELETE FROM event_types WHERE id = ?`)
456
465
  .run(eventTypeId);
@@ -482,7 +491,9 @@ export function getEmotionDefinitionById(emotionId) {
482
491
  const row = getRow(`SELECT id, domain_id, label, description, category, system, created_at, updated_at
483
492
  FROM emotion_definitions
484
493
  WHERE id = ?`, emotionId);
485
- return row ? mapEmotionDefinition(row) : undefined;
494
+ return row
495
+ ? decorateOwnedEntity("emotion_definition", mapEmotionDefinition(row))
496
+ : undefined;
486
497
  }
487
498
  export function createEmotionDefinition(input, context) {
488
499
  const parsed = createEmotionDefinitionSchema.parse(input);
@@ -501,6 +512,7 @@ export function createEmotionDefinition(input, context) {
501
512
  .prepare(`INSERT INTO emotion_definitions (id, domain_id, label, description, category, system, created_at, updated_at)
502
513
  VALUES (?, ?, ?, ?, ?, 0, ?, ?)`)
503
514
  .run(emotion.id, emotion.domainId, emotion.label, emotion.description, emotion.category, emotion.createdAt, emotion.updatedAt);
515
+ assignOwnedEntity("emotion_definition", emotion.id, parsed.userId, context.actor);
504
516
  mapCreateUpdateContext({
505
517
  entityType: "emotion_definition",
506
518
  entityId: emotion.id,
@@ -510,7 +522,7 @@ export function createEmotionDefinition(input, context) {
510
522
  actor: context.actor ?? null,
511
523
  metadata: { domainId: emotion.domainId }
512
524
  });
513
- return emotion;
525
+ return decorateOwnedEntity("emotion_definition", emotion);
514
526
  }
515
527
  export function updateEmotionDefinition(emotionId, patch, context) {
516
528
  const existing = getEmotionDefinitionById(emotionId);
@@ -528,6 +540,9 @@ export function updateEmotionDefinition(emotionId, patch, context) {
528
540
  SET label = ?, description = ?, category = ?, updated_at = ?
529
541
  WHERE id = ?`)
530
542
  .run(updated.label, updated.description, updated.category, updated.updatedAt, emotionId);
543
+ if (parsed.userId !== undefined) {
544
+ assignOwnedEntity("emotion_definition", emotionId, parsed.userId, context.actor);
545
+ }
531
546
  mapCreateUpdateContext({
532
547
  entityType: "emotion_definition",
533
548
  entityId: emotionId,
@@ -537,7 +552,7 @@ export function updateEmotionDefinition(emotionId, patch, context) {
537
552
  actor: context.actor ?? null,
538
553
  metadata: { domainId: updated.domainId }
539
554
  });
540
- return updated;
555
+ return decorateOwnedEntity("emotion_definition", updated);
541
556
  }
542
557
  export function deleteEmotionDefinition(emotionId, context) {
543
558
  const existing = getEmotionDefinitionById(emotionId);
@@ -547,6 +562,7 @@ export function deleteEmotionDefinition(emotionId, context) {
547
562
  return runInTransaction(() => {
548
563
  nullifyTriggerEmotionReferences(emotionId);
549
564
  unlinkEntityNotes("emotion_definition", emotionId);
565
+ clearEntityOwner("emotion_definition", emotionId);
550
566
  getDatabase()
551
567
  .prepare(`DELETE FROM emotion_definitions WHERE id = ?`)
552
568
  .run(emotionId);
@@ -582,7 +598,7 @@ export function getPsycheValueById(valueId) {
582
598
  linked_goal_ids_json, linked_project_ids_json, linked_task_ids_json, committed_actions_json, created_at, updated_at
583
599
  FROM psyche_values
584
600
  WHERE id = ?`, valueId);
585
- return row ? mapPsycheValue(row) : undefined;
601
+ return row ? decorateOwnedEntity("psyche_value", mapPsycheValue(row)) : undefined;
586
602
  }
587
603
  export function createPsycheValue(input, context) {
588
604
  const parsed = createPsycheValueSchema.parse(input);
@@ -607,6 +623,7 @@ export function createPsycheValue(input, context) {
607
623
  linked_task_ids_json, committed_actions_json, created_at, updated_at
608
624
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
609
625
  .run(value.id, value.domainId, value.title, value.description, value.valuedDirection, value.whyItMatters, JSON.stringify(value.linkedGoalIds), JSON.stringify(value.linkedProjectIds), JSON.stringify(value.linkedTaskIds), JSON.stringify(value.committedActions), value.createdAt, value.updatedAt);
626
+ assignOwnedEntity("psyche_value", value.id, parsed.userId, context.actor);
610
627
  mapCreateUpdateContext({
611
628
  entityType: "psyche_value",
612
629
  entityId: value.id,
@@ -617,7 +634,7 @@ export function createPsycheValue(input, context) {
617
634
  metadata: { domainId: value.domainId }
618
635
  });
619
636
  recordPsycheClarityReward("psyche_value", value.id, value.title, "psyche_value_defined", context);
620
- return value;
637
+ return decorateOwnedEntity("psyche_value", value);
621
638
  }
622
639
  export function updatePsycheValue(valueId, patch, context) {
623
640
  const existing = getPsycheValueById(valueId);
@@ -637,6 +654,9 @@ export function updatePsycheValue(valueId, patch, context) {
637
654
  linked_project_ids_json = ?, linked_task_ids_json = ?, committed_actions_json = ?, updated_at = ?
638
655
  WHERE id = ?`)
639
656
  .run(updated.title, updated.description, updated.valuedDirection, updated.whyItMatters, JSON.stringify(updated.linkedGoalIds), JSON.stringify(updated.linkedProjectIds), JSON.stringify(updated.linkedTaskIds), JSON.stringify(updated.committedActions), updated.updatedAt, valueId);
657
+ if (parsed.userId !== undefined) {
658
+ assignOwnedEntity("psyche_value", valueId, parsed.userId, context.actor);
659
+ }
640
660
  mapCreateUpdateContext({
641
661
  entityType: "psyche_value",
642
662
  entityId: valueId,
@@ -646,7 +666,7 @@ export function updatePsycheValue(valueId, patch, context) {
646
666
  actor: context.actor ?? null,
647
667
  metadata: { domainId: updated.domainId }
648
668
  });
649
- return updated;
669
+ return decorateOwnedEntity("psyche_value", updated);
650
670
  }
651
671
  export function deletePsycheValue(valueId, context) {
652
672
  const existing = getPsycheValueById(valueId);
@@ -660,6 +680,7 @@ export function deletePsycheValue(valueId, context) {
660
680
  removeIdFromStringArrayColumn("mode_profiles", "linked_value_ids_json", valueId);
661
681
  removeIdFromStringArrayColumn("trigger_reports", "linked_value_ids_json", valueId);
662
682
  unlinkEntityNotes("psyche_value", valueId);
683
+ clearEntityOwner("psyche_value", valueId);
663
684
  getDatabase()
664
685
  .prepare(`DELETE FROM psyche_values WHERE id = ?`)
665
686
  .run(valueId);
@@ -697,7 +718,9 @@ export function getBehaviorPatternById(patternId) {
697
718
  linked_belief_ids_json, created_at, updated_at
698
719
  FROM behavior_patterns
699
720
  WHERE id = ?`, patternId);
700
- return row ? mapBehaviorPattern(row) : undefined;
721
+ return row
722
+ ? decorateOwnedEntity("behavior_pattern", mapBehaviorPattern(row))
723
+ : undefined;
701
724
  }
702
725
  export function createBehaviorPattern(input, context) {
703
726
  const parsed = createBehaviorPatternSchema.parse(input);
@@ -727,6 +750,7 @@ export function createBehaviorPattern(input, context) {
727
750
  linked_belief_ids_json, created_at, updated_at
728
751
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
729
752
  .run(pattern.id, pattern.domainId, pattern.title, pattern.description, pattern.targetBehavior, JSON.stringify(pattern.cueContexts), pattern.shortTermPayoff, pattern.longTermCost, pattern.preferredResponse, JSON.stringify(pattern.linkedValueIds), JSON.stringify(pattern.linkedSchemaLabels), JSON.stringify(pattern.linkedModeLabels), JSON.stringify(pattern.linkedModeIds), JSON.stringify(pattern.linkedBeliefIds), pattern.createdAt, pattern.updatedAt);
753
+ assignOwnedEntity("behavior_pattern", pattern.id, parsed.userId, context.actor);
730
754
  mapCreateUpdateContext({
731
755
  entityType: "behavior_pattern",
732
756
  entityId: pattern.id,
@@ -737,7 +761,7 @@ export function createBehaviorPattern(input, context) {
737
761
  metadata: { domainId: pattern.domainId }
738
762
  });
739
763
  recordPsycheClarityReward("behavior_pattern", pattern.id, pattern.title, "psyche_pattern_defined", context);
740
- return pattern;
764
+ return decorateOwnedEntity("behavior_pattern", pattern);
741
765
  }
742
766
  export function updateBehaviorPattern(patternId, patch, context) {
743
767
  const existing = getBehaviorPatternById(patternId);
@@ -757,6 +781,9 @@ export function updateBehaviorPattern(patternId, patch, context) {
757
781
  linked_mode_ids_json = ?, linked_belief_ids_json = ?, updated_at = ?
758
782
  WHERE id = ?`)
759
783
  .run(updated.title, updated.description, updated.targetBehavior, JSON.stringify(updated.cueContexts), updated.shortTermPayoff, updated.longTermCost, updated.preferredResponse, JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedSchemaLabels), JSON.stringify(updated.linkedModeLabels), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.linkedBeliefIds), updated.updatedAt, patternId);
784
+ if (parsed.userId !== undefined) {
785
+ assignOwnedEntity("behavior_pattern", patternId, parsed.userId, context.actor);
786
+ }
760
787
  mapCreateUpdateContext({
761
788
  entityType: "behavior_pattern",
762
789
  entityId: patternId,
@@ -766,7 +793,7 @@ export function updateBehaviorPattern(patternId, patch, context) {
766
793
  actor: context.actor ?? null,
767
794
  metadata: { domainId: updated.domainId }
768
795
  });
769
- return updated;
796
+ return decorateOwnedEntity("behavior_pattern", updated);
770
797
  }
771
798
  export function deleteBehaviorPattern(patternId, context) {
772
799
  const existing = getBehaviorPatternById(patternId);
@@ -778,6 +805,7 @@ export function deleteBehaviorPattern(patternId, context) {
778
805
  removeIdFromStringArrayColumn("mode_profiles", "linked_pattern_ids_json", patternId);
779
806
  removeIdFromStringArrayColumn("trigger_reports", "linked_pattern_ids_json", patternId);
780
807
  unlinkEntityNotes("behavior_pattern", patternId);
808
+ clearEntityOwner("behavior_pattern", patternId);
781
809
  getDatabase()
782
810
  .prepare(`DELETE FROM behavior_patterns WHERE id = ?`)
783
811
  .run(patternId);
@@ -815,7 +843,7 @@ export function getBehaviorById(behaviorId) {
815
843
  linked_mode_ids_json, created_at, updated_at
816
844
  FROM psyche_behaviors
817
845
  WHERE id = ?`, behaviorId);
818
- return row ? mapBehavior(row) : undefined;
846
+ return row ? decorateOwnedEntity("behavior", mapBehavior(row)) : undefined;
819
847
  }
820
848
  export function createBehavior(input, context) {
821
849
  const parsed = createBehaviorSchema.parse(input);
@@ -834,6 +862,7 @@ export function createBehavior(input, context) {
834
862
  created_at, updated_at
835
863
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
836
864
  .run(behavior.id, behavior.domainId, behavior.kind, behavior.title, behavior.description, JSON.stringify(behavior.commonCues), behavior.urgeStory, behavior.shortTermPayoff, behavior.longTermCost, behavior.replacementMove, behavior.repairPlan, JSON.stringify(behavior.linkedPatternIds), JSON.stringify(behavior.linkedValueIds), JSON.stringify(behavior.linkedSchemaIds), JSON.stringify(behavior.linkedModeIds), behavior.createdAt, behavior.updatedAt);
865
+ assignOwnedEntity("behavior", behavior.id, parsed.userId, context.actor);
837
866
  mapCreateUpdateContext({
838
867
  entityType: "behavior",
839
868
  entityId: behavior.id,
@@ -844,7 +873,7 @@ export function createBehavior(input, context) {
844
873
  metadata: { kind: behavior.kind, domainId: behavior.domainId }
845
874
  });
846
875
  recordPsycheClarityReward("behavior", behavior.id, behavior.title, "psyche_behavior_defined", context);
847
- return behavior;
876
+ return decorateOwnedEntity("behavior", behavior);
848
877
  }
849
878
  export function updateBehavior(behaviorId, patch, context) {
850
879
  const existing = getBehaviorById(behaviorId);
@@ -864,6 +893,9 @@ export function updateBehavior(behaviorId, patch, context) {
864
893
  linked_mode_ids_json = ?, updated_at = ?
865
894
  WHERE id = ?`)
866
895
  .run(updated.kind, updated.title, updated.description, JSON.stringify(updated.commonCues), updated.urgeStory, updated.shortTermPayoff, updated.longTermCost, updated.replacementMove, updated.repairPlan, JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedSchemaIds), JSON.stringify(updated.linkedModeIds), updated.updatedAt, behaviorId);
896
+ if (parsed.userId !== undefined) {
897
+ assignOwnedEntity("behavior", behaviorId, parsed.userId, context.actor);
898
+ }
867
899
  mapCreateUpdateContext({
868
900
  entityType: "behavior",
869
901
  entityId: behaviorId,
@@ -873,7 +905,7 @@ export function updateBehavior(behaviorId, patch, context) {
873
905
  actor: context.actor ?? null,
874
906
  metadata: { kind: updated.kind, domainId: updated.domainId }
875
907
  });
876
- return updated;
908
+ return decorateOwnedEntity("behavior", updated);
877
909
  }
878
910
  export function deleteBehavior(behaviorId, context) {
879
911
  const existing = getBehaviorById(behaviorId);
@@ -886,6 +918,7 @@ export function deleteBehavior(behaviorId, context) {
886
918
  removeIdFromStringArrayColumn("trigger_reports", "linked_behavior_ids_json", behaviorId);
887
919
  nullifyTriggerBehaviorReferences(behaviorId);
888
920
  unlinkEntityNotes("behavior", behaviorId);
921
+ clearEntityOwner("behavior", behaviorId);
889
922
  getDatabase()
890
923
  .prepare(`DELETE FROM psyche_behaviors WHERE id = ?`)
891
924
  .run(behaviorId);
@@ -923,7 +956,7 @@ export function getBeliefEntryById(beliefId) {
923
956
  created_at, updated_at
924
957
  FROM belief_entries
925
958
  WHERE id = ?`, beliefId);
926
- return row ? mapBeliefEntry(row) : undefined;
959
+ return row ? decorateOwnedEntity("belief_entry", mapBeliefEntry(row)) : undefined;
927
960
  }
928
961
  export function createBeliefEntry(input, context) {
929
962
  const parsed = createBeliefEntrySchema.parse(input);
@@ -942,6 +975,7 @@ export function createBeliefEntry(input, context) {
942
975
  created_at, updated_at
943
976
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
944
977
  .run(belief.id, belief.domainId, belief.schemaId, belief.statement, belief.beliefType, belief.originNote, belief.confidence, JSON.stringify(belief.evidenceFor), JSON.stringify(belief.evidenceAgainst), belief.flexibleAlternative, JSON.stringify(belief.linkedValueIds), JSON.stringify(belief.linkedBehaviorIds), JSON.stringify(belief.linkedModeIds), JSON.stringify(belief.linkedReportIds), belief.createdAt, belief.updatedAt);
978
+ assignOwnedEntity("belief_entry", belief.id, parsed.userId, context.actor);
945
979
  mapCreateUpdateContext({
946
980
  entityType: "belief_entry",
947
981
  entityId: belief.id,
@@ -952,7 +986,7 @@ export function createBeliefEntry(input, context) {
952
986
  metadata: { schemaId: belief.schemaId ?? "" }
953
987
  });
954
988
  recordPsycheClarityReward("belief_entry", belief.id, belief.statement, "psyche_belief_captured", context);
955
- return belief;
989
+ return decorateOwnedEntity("belief_entry", belief);
956
990
  }
957
991
  export function updateBeliefEntry(beliefId, patch, context) {
958
992
  const existing = getBeliefEntryById(beliefId);
@@ -972,6 +1006,9 @@ export function updateBeliefEntry(beliefId, patch, context) {
972
1006
  linked_mode_ids_json = ?, linked_report_ids_json = ?, updated_at = ?
973
1007
  WHERE id = ?`)
974
1008
  .run(updated.schemaId, updated.statement, updated.beliefType, updated.originNote, updated.confidence, JSON.stringify(updated.evidenceFor), JSON.stringify(updated.evidenceAgainst), updated.flexibleAlternative, JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.linkedReportIds), updated.updatedAt, beliefId);
1009
+ if (parsed.userId !== undefined) {
1010
+ assignOwnedEntity("belief_entry", beliefId, parsed.userId, context.actor);
1011
+ }
975
1012
  mapCreateUpdateContext({
976
1013
  entityType: "belief_entry",
977
1014
  entityId: beliefId,
@@ -981,7 +1018,7 @@ export function updateBeliefEntry(beliefId, patch, context) {
981
1018
  actor: context.actor ?? null,
982
1019
  metadata: { schemaId: updated.schemaId ?? "" }
983
1020
  });
984
- return updated;
1021
+ return decorateOwnedEntity("belief_entry", updated);
985
1022
  }
986
1023
  export function deleteBeliefEntry(beliefId, context) {
987
1024
  const existing = getBeliefEntryById(beliefId);
@@ -993,6 +1030,7 @@ export function deleteBeliefEntry(beliefId, context) {
993
1030
  removeIdFromStringArrayColumn("trigger_reports", "linked_belief_ids_json", beliefId);
994
1031
  nullifyTriggerThoughtBeliefReferences(beliefId);
995
1032
  unlinkEntityNotes("belief_entry", beliefId);
1033
+ clearEntityOwner("belief_entry", beliefId);
996
1034
  getDatabase()
997
1035
  .prepare(`DELETE FROM belief_entries WHERE id = ?`)
998
1036
  .run(beliefId);
@@ -1028,7 +1066,7 @@ export function getModeProfileById(modeId) {
1028
1066
  origin_context, first_appearance_at, linked_pattern_ids_json, linked_behavior_ids_json, linked_value_ids_json, created_at, updated_at
1029
1067
  FROM mode_profiles
1030
1068
  WHERE id = ?`, modeId);
1031
- return row ? mapModeProfile(row) : undefined;
1069
+ return row ? decorateOwnedEntity("mode_profile", mapModeProfile(row)) : undefined;
1032
1070
  }
1033
1071
  export function createModeProfile(input, context) {
1034
1072
  const parsed = createModeProfileSchema.parse(input);
@@ -1046,6 +1084,7 @@ export function createModeProfile(input, context) {
1046
1084
  origin_context, first_appearance_at, linked_pattern_ids_json, linked_behavior_ids_json, linked_value_ids_json, created_at, updated_at
1047
1085
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
1048
1086
  .run(mode.id, mode.domainId, mode.family, mode.archetype, mode.title, mode.persona, mode.imagery, mode.symbolicForm, mode.facialExpression, mode.fear, mode.burden, mode.protectiveJob, mode.originContext, mode.firstAppearanceAt, JSON.stringify(mode.linkedPatternIds), JSON.stringify(mode.linkedBehaviorIds), JSON.stringify(mode.linkedValueIds), mode.createdAt, mode.updatedAt);
1087
+ assignOwnedEntity("mode_profile", mode.id, parsed.userId, context.actor);
1049
1088
  mapCreateUpdateContext({
1050
1089
  entityType: "mode_profile",
1051
1090
  entityId: mode.id,
@@ -1056,7 +1095,7 @@ export function createModeProfile(input, context) {
1056
1095
  metadata: { family: mode.family }
1057
1096
  });
1058
1097
  recordPsycheClarityReward("mode_profile", mode.id, mode.title, "psyche_mode_named", context);
1059
- return mode;
1098
+ return decorateOwnedEntity("mode_profile", mode);
1060
1099
  }
1061
1100
  export function updateModeProfile(modeId, patch, context) {
1062
1101
  const existing = getModeProfileById(modeId);
@@ -1079,6 +1118,9 @@ export function updateModeProfile(modeId, patch, context) {
1079
1118
  linked_behavior_ids_json = ?, linked_value_ids_json = ?, updated_at = ?
1080
1119
  WHERE id = ?`)
1081
1120
  .run(updated.family, updated.archetype, updated.title, updated.persona, updated.imagery, updated.symbolicForm, updated.facialExpression, updated.fear, updated.burden, updated.protectiveJob, updated.originContext, updated.firstAppearanceAt, JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedValueIds), updated.updatedAt, modeId);
1121
+ if (parsed.userId !== undefined) {
1122
+ assignOwnedEntity("mode_profile", modeId, parsed.userId, context.actor);
1123
+ }
1082
1124
  mapCreateUpdateContext({
1083
1125
  entityType: "mode_profile",
1084
1126
  entityId: modeId,
@@ -1088,7 +1130,7 @@ export function updateModeProfile(modeId, patch, context) {
1088
1130
  actor: context.actor ?? null,
1089
1131
  metadata: { family: updated.family }
1090
1132
  });
1091
- return updated;
1133
+ return decorateOwnedEntity("mode_profile", updated);
1092
1134
  }
1093
1135
  export function deleteModeProfile(modeId, context) {
1094
1136
  const existing = getModeProfileById(modeId);
@@ -1102,6 +1144,7 @@ export function deleteModeProfile(modeId, context) {
1102
1144
  removeIdFromStringArrayColumn("trigger_reports", "linked_mode_ids_json", modeId);
1103
1145
  nullifyTriggerTimelineModeReferences(modeId);
1104
1146
  unlinkEntityNotes("mode_profile", modeId);
1147
+ clearEntityOwner("mode_profile", modeId);
1105
1148
  getDatabase()
1106
1149
  .prepare(`DELETE FROM mode_profiles WHERE id = ?`)
1107
1150
  .run(modeId);
@@ -1133,7 +1176,9 @@ export function getModeGuideSessionById(sessionId) {
1133
1176
  const row = getRow(`SELECT id, summary, answers_json, results_json, created_at, updated_at
1134
1177
  FROM mode_guide_sessions
1135
1178
  WHERE id = ?`, sessionId);
1136
- return row ? mapModeGuideSession(row) : undefined;
1179
+ return row
1180
+ ? decorateOwnedEntity("mode_guide_session", mapModeGuideSession(row))
1181
+ : undefined;
1137
1182
  }
1138
1183
  export function createModeGuideSession(input, context) {
1139
1184
  const parsed = createModeGuideSessionSchema.parse(input);
@@ -1150,6 +1195,7 @@ export function createModeGuideSession(input, context) {
1150
1195
  .prepare(`INSERT INTO mode_guide_sessions (id, summary, answers_json, results_json, created_at, updated_at)
1151
1196
  VALUES (?, ?, ?, ?, ?, ?)`)
1152
1197
  .run(session.id, session.summary, JSON.stringify(session.answers), JSON.stringify(session.results), session.createdAt, session.updatedAt);
1198
+ assignOwnedEntity("mode_guide_session", session.id, parsed.userId, context.actor);
1153
1199
  recordEventLog({
1154
1200
  eventKind: "mode_guide_session.created",
1155
1201
  entityType: "system",
@@ -1158,7 +1204,7 @@ export function createModeGuideSession(input, context) {
1158
1204
  source: context.source,
1159
1205
  metadata: { summary: session.summary }
1160
1206
  });
1161
- return session;
1207
+ return decorateOwnedEntity("mode_guide_session", session);
1162
1208
  }
1163
1209
  export function updateModeGuideSession(sessionId, patch, context) {
1164
1210
  const existing = getModeGuideSessionById(sessionId);
@@ -1180,6 +1226,9 @@ export function updateModeGuideSession(sessionId, patch, context) {
1180
1226
  SET summary = ?, answers_json = ?, results_json = ?, updated_at = ?
1181
1227
  WHERE id = ?`)
1182
1228
  .run(updated.summary, JSON.stringify(updated.answers), JSON.stringify(updated.results), updated.updatedAt, sessionId);
1229
+ if (parsed.userId !== undefined) {
1230
+ assignOwnedEntity("mode_guide_session", sessionId, parsed.userId, context.actor);
1231
+ }
1183
1232
  recordEventLog({
1184
1233
  eventKind: "mode_guide_session.updated",
1185
1234
  entityType: "system",
@@ -1188,7 +1237,7 @@ export function updateModeGuideSession(sessionId, patch, context) {
1188
1237
  source: context.source,
1189
1238
  metadata: { summary: updated.summary }
1190
1239
  });
1191
- return updated;
1240
+ return decorateOwnedEntity("mode_guide_session", updated);
1192
1241
  }
1193
1242
  export function deleteModeGuideSession(sessionId, context) {
1194
1243
  const existing = getModeGuideSessionById(sessionId);
@@ -1196,6 +1245,7 @@ export function deleteModeGuideSession(sessionId, context) {
1196
1245
  return undefined;
1197
1246
  }
1198
1247
  return runInTransaction(() => {
1248
+ clearEntityOwner("mode_guide_session", sessionId);
1199
1249
  getDatabase()
1200
1250
  .prepare(`DELETE FROM mode_guide_sessions WHERE id = ?`)
1201
1251
  .run(sessionId);
@@ -1236,7 +1286,9 @@ export function getTriggerReportById(reportId) {
1236
1286
  schema_links_json, mode_timeline_json, next_moves_json, created_at, updated_at
1237
1287
  FROM trigger_reports
1238
1288
  WHERE id = ?`, reportId);
1239
- return row ? mapTriggerReport(row) : undefined;
1289
+ return row
1290
+ ? decorateOwnedEntity("trigger_report", mapTriggerReport(row))
1291
+ : undefined;
1240
1292
  }
1241
1293
  export function createTriggerReport(input, context) {
1242
1294
  const parsed = createTriggerReportSchema.parse(input);
@@ -1277,6 +1329,7 @@ export function createTriggerReport(input, context) {
1277
1329
  next_moves_json, created_at, updated_at
1278
1330
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
1279
1331
  .run(report.id, report.domainId, report.title, report.status, report.eventTypeId, report.customEventType, report.eventSituation, report.occurredAt, JSON.stringify(report.emotions), JSON.stringify(report.thoughts), JSON.stringify(report.behaviors), JSON.stringify(report.consequences), JSON.stringify(report.linkedPatternIds), JSON.stringify(report.linkedValueIds), JSON.stringify(report.linkedGoalIds), JSON.stringify(report.linkedProjectIds), JSON.stringify(report.linkedTaskIds), JSON.stringify(report.linkedBehaviorIds), JSON.stringify(report.linkedBeliefIds), JSON.stringify(report.linkedModeIds), JSON.stringify(report.modeOverlays), JSON.stringify(report.schemaLinks), JSON.stringify(report.modeTimeline), JSON.stringify(report.nextMoves), report.createdAt, report.updatedAt);
1332
+ assignOwnedEntity("trigger_report", report.id, parsed.userId, context.actor);
1280
1333
  mapCreateUpdateContext({
1281
1334
  entityType: "trigger_report",
1282
1335
  entityId: report.id,
@@ -1290,7 +1343,7 @@ export function createTriggerReport(input, context) {
1290
1343
  }
1291
1344
  });
1292
1345
  recordPsycheReflectionReward(report.id, report.title, { actor: context.actor ?? null, source: context.source });
1293
- return report;
1346
+ return decorateOwnedEntity("trigger_report", report);
1294
1347
  }
1295
1348
  export function updateTriggerReport(reportId, patch, context) {
1296
1349
  const existing = getTriggerReportById(reportId);
@@ -1317,6 +1370,9 @@ export function updateTriggerReport(reportId, patch, context) {
1317
1370
  next_moves_json = ?, updated_at = ?
1318
1371
  WHERE id = ?`)
1319
1372
  .run(updated.title, updated.status, updated.eventTypeId, updated.customEventType, updated.eventSituation, updated.occurredAt, JSON.stringify(updated.emotions), JSON.stringify(updated.thoughts), JSON.stringify(updated.behaviors), JSON.stringify(updated.consequences), JSON.stringify(updated.linkedPatternIds), JSON.stringify(updated.linkedValueIds), JSON.stringify(updated.linkedGoalIds), JSON.stringify(updated.linkedProjectIds), JSON.stringify(updated.linkedTaskIds), JSON.stringify(updated.linkedBehaviorIds), JSON.stringify(updated.linkedBeliefIds), JSON.stringify(updated.linkedModeIds), JSON.stringify(updated.modeOverlays), JSON.stringify(updated.schemaLinks), JSON.stringify(updated.modeTimeline), JSON.stringify(updated.nextMoves), updated.updatedAt, reportId);
1373
+ if (parsed.userId !== undefined) {
1374
+ assignOwnedEntity("trigger_report", reportId, parsed.userId, context.actor);
1375
+ }
1320
1376
  mapCreateUpdateContext({
1321
1377
  entityType: "trigger_report",
1322
1378
  entityId: reportId,
@@ -1326,7 +1382,7 @@ export function updateTriggerReport(reportId, patch, context) {
1326
1382
  actor: context.actor ?? null,
1327
1383
  metadata: { status: updated.status }
1328
1384
  });
1329
- return updated;
1385
+ return decorateOwnedEntity("trigger_report", updated);
1330
1386
  }
1331
1387
  export function deleteTriggerReport(reportId, context) {
1332
1388
  const existing = getTriggerReportById(reportId);
@@ -1336,6 +1392,7 @@ export function deleteTriggerReport(reportId, context) {
1336
1392
  return runInTransaction(() => {
1337
1393
  removeIdFromStringArrayColumn("belief_entries", "linked_report_ids_json", reportId);
1338
1394
  unlinkEntityNotes("trigger_report", reportId);
1395
+ clearEntityOwner("trigger_report", reportId);
1339
1396
  getDatabase()
1340
1397
  .prepare(`DELETE FROM trigger_reports WHERE id = ?`)
1341
1398
  .run(reportId);