@xopcai/xopc 0.0.255 → 0.0.256

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 (164) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-DvjK5FEm.js → activity-store-DYb6xFC3.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Cqspzbf_.js → agent-avatar-dicebear-BZJZvmYw.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Bq7GNF1L.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-1vtaw07m.js +1 -0
  7. package/dist/gateway/static/root/assets/{api-CsYi3heY.js → api-NADZ8X8B.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-Gd4a5hdE.js → app-management-settings-panel-DG64SQsx.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-CZ6KOnbd.js → appearance-settings-BRWQdIIy.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-D3ziBisx.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-y82Rwhjm.js → archive-plugin-D3FQ9VzV.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-D46SGNpv.js → attachment-load-Cid3dBaW.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-wilciIZ1.js → automations-page-BUTNaZtj.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-D4NJSE8l.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-CuMkNNCe.js → binary-plugins-BSYMCuaB.js} +1 -1
  16. package/dist/gateway/static/root/assets/block-editor-qDlC3t7b.js +159 -0
  17. package/dist/gateway/static/root/assets/{browser-automation-inputs-hlmcSp4p.js → browser-automation-inputs-rA2QROKe.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-automations-page-OjZvbARU.js → browser-automations-page-Du1KVE01.js} +2 -2
  19. package/dist/gateway/static/root/assets/browser-settings-page-WZ0Jt5Hp.js +8 -0
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-D1AYoRx4.js +7 -0
  21. package/dist/gateway/static/root/assets/channels-settings-CZnlYu2L.js +1 -0
  22. package/dist/gateway/static/root/assets/{channels-status-swr-D1HHFzkE.js → channels-status-swr-B2aMPOSM.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-Ce_T9BPq.js → chat-terminal-dock-CY-I_bCe.js} +2 -2
  24. package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BaASWQor.js → chunk-KS7C4IRE-Cq1tE_3b.js} +2 -2
  25. package/dist/gateway/static/root/assets/code-editor-CXIH8jQw.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-CkH3gaqs.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BRrCwYyD.js → cron-expression-z4WOWyBU.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-C35RuuWW.js → date-picker-vKUcJeQZ.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-4pNXVcRM.js → dependency-picker-BpZ9A2gi.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-z91GYnPf.js → desktop-pet-ClrAMqgn.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-BvV1UA5g.js → desktop-pet-settings-DKNKGiEG.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-CkVF5HvV.js → extension-debug-page-C39hFkJm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-DW0zQGaB.js → extension-page-DkqVsWB7.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-settings-page-BLQhizZ3.js → extension-settings-page-Be4lFw8f.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-config-swr-02BBC1mK.js → gateway-config-swr-DEKSw3d-.js} +1 -1
  36. package/dist/gateway/static/root/assets/gateway-settings-HIHGY-0Y.js +1 -0
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-XZnY6621.js → gateway-startup-retry-Dlyt2VhF.js} +1 -1
  38. package/dist/gateway/static/root/assets/heartbeat-settings-DiYjWa1F.js +1 -0
  39. package/dist/gateway/static/root/assets/home-page-BLZNEVmk.js +1 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-CIcKz4Xs.js → image-generation-api-CJIPVk_d.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-50Kr6L6C.css +2 -0
  42. package/dist/gateway/static/root/assets/{index-PksHo9hS.js → index-BWdn9NaX.js} +49 -47
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-yfaGz6SE.js → keyboard-shortcuts-settings-ge76J038.js} +1 -1
  44. package/dist/gateway/static/root/assets/languages-BFe8nIOO.js +2 -0
  45. package/dist/gateway/static/root/assets/local-app-workbench-page-E47xrPDI.js +2 -0
  46. package/dist/gateway/static/root/assets/{local-apps-page-Cp-nEtgV.js → local-apps-page-gkw7VRL4.js} +1 -1
  47. package/dist/gateway/static/root/assets/{locale-store-VsboRLD7.js → locale-store-DJPCr2mb.js} +1 -1
  48. package/dist/gateway/static/root/assets/{logs-page-DkqsRCri.js → logs-page-HHtDMSUW.js} +2 -2
  49. package/dist/gateway/static/root/assets/{management-settings-24_JyDPk.js → management-settings-DOfCSojd.js} +1 -1
  50. package/dist/gateway/static/root/assets/markdown-editor-BhBJANcx.js +1 -0
  51. package/dist/gateway/static/root/assets/{markdown-view-CPXhy6nh.js → markdown-view-k_PJsY2C.js} +2 -2
  52. package/dist/gateway/static/root/assets/{media-plugins-CwLvIb9r.js → media-plugins-D8wMcUtB.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-BeIiRpmk.js +3 -0
  54. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-BbJCDv57.js → mobile-pairing-wizard-B4Ewewwr.js} +1 -1
  55. package/dist/gateway/static/root/assets/note-detail-panel-DPd5L2A9.js +5 -0
  56. package/dist/gateway/static/root/assets/notes-page-CE_De-iQ.js +8 -0
  57. package/dist/gateway/static/root/assets/{page-tabs-0YXn9Gkl.js → page-tabs-DoxnT3X4.js} +1 -1
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-2jVV5kfZ.js → preview-open-alternatives-D4oL1yua.js} +1 -1
  59. package/dist/gateway/static/root/assets/product-open-page-CeStuxSl.js +1 -0
  60. package/dist/gateway/static/root/assets/project-detail-page-DXhBJzJy.js +1 -0
  61. package/dist/gateway/static/root/assets/{projects-page-D6jY2ZWl.js → projects-page-CcqhmZoX.js} +1 -1
  62. package/dist/gateway/static/root/assets/{registry-api-DlTWbXQA.js → registry-api-Dalzf2w0.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-ulmJT_Ac.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-B-NDgmJ4.js → runtime-tools-settings-panel-CrOpchy5.js} +2 -2
  65. package/dist/gateway/static/root/assets/{schema-form-DZYeBS1v.js → schema-form-Dk52v4cQ.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-RM0kAsNa.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-BfLbu67w.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-zy5UMvPk.js → settings-form-section-dvGi1APN.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-CTuipbJq.js → settings-page-CEYjEm2D.js} +1 -1
  70. package/dist/gateway/static/root/assets/setup-status-panel-BZ4i0CYX.js +1 -0
  71. package/dist/gateway/static/root/assets/{share-preview-page-D3Uawo_h.js → share-preview-page-DP4Qgsv6.js} +1 -1
  72. package/dist/gateway/static/root/assets/shares-settings-B5yHTrGO.js +1 -0
  73. package/dist/gateway/static/root/assets/skill-reload-api-BicZK04u.js +1 -0
  74. package/dist/gateway/static/root/assets/{skills-page-DDbabz7p.js → skills-page-Dlr1Ue1w.js} +1 -1
  75. package/dist/gateway/static/root/assets/{skills-page.utils-DkGhbiMa.js → skills-page.utils-I1wcnceD.js} +1 -1
  76. package/dist/gateway/static/root/assets/source-workspace-editor-DunRD1gY.js +1 -0
  77. package/dist/gateway/static/root/assets/{system-settings-panel-Fc-WbX6-.js → system-settings-panel-DIaFAHT0.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-4_5g-V8B.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-vdB57bTn.js → theme-store-DYDrhfnD.js} +1 -1
  80. package/dist/gateway/static/root/assets/{tunnel-api-DZ0evABj.js → tunnel-api-DAXx1rHF.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-autosave-Ckof_m7e.js → use-autosave-BwEFbveP.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-model-page-CQnXw4ba.js +2 -0
  83. package/dist/gateway/static/root/assets/{vendor-codemirror-Qdcjid65.js → vendor-codemirror-DFxP3B9T.js} +16 -16
  84. package/dist/gateway/static/root/assets/{voice-api-key-field-CnmtpWlq.js → voice-api-key-field-C-WbC2fM.js} +1 -1
  85. package/dist/gateway/static/root/assets/{voice-config-api-OA04c71t.js → voice-config-api-Ds0z9O11.js} +1 -1
  86. package/dist/gateway/static/root/assets/{work-discovery-overlay-sxvsDIC3.js → work-discovery-overlay-DiGw5KKj.js} +1 -1
  87. package/dist/gateway/static/root/assets/workflow-run-setup-panel-BIU2wg99.js +3 -0
  88. package/dist/gateway/static/root/assets/workflows-page-D3Z7JVHH.js +6 -0
  89. package/dist/gateway/static/root/index.html +11 -11
  90. package/dist/package.js +1 -1
  91. package/dist/packages/gateway-contract/src/user-message-display.js +0 -18
  92. package/dist/src/agent/context/execution-context.js +34 -21
  93. package/dist/src/agent/context/execution-context.types.d.ts +2 -0
  94. package/dist/src/agent/inbound/attachment-pipeline.d.ts +1 -0
  95. package/dist/src/agent/inbound/attachment-pipeline.js +6 -1
  96. package/dist/src/agent/prompt/sections/memory-skills.js +2 -1
  97. package/dist/src/agent/prompt/sections/tooling.js +2 -0
  98. package/dist/src/agent/tools/delegate-tool.js +1 -0
  99. package/dist/src/agent/tools/factory.js +14 -1
  100. package/dist/src/agent/tools/index.d.ts +1 -1
  101. package/dist/src/agent/tools/index.js +2 -2
  102. package/dist/src/agent/tools/user-context-tool.d.ts +3 -0
  103. package/dist/src/agent/tools/user-context-tool.js +147 -4
  104. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  105. package/dist/src/agent/workflow/catalog.js +6 -2
  106. package/dist/src/chat-commands/builtins/workflow.js +1 -1
  107. package/dist/src/connectors/connected-source-understanding.js +4 -4
  108. package/dist/src/gateway/agent-builtin-tools.d.ts +7 -1
  109. package/dist/src/gateway/agent-builtin-tools.js +7 -0
  110. package/dist/src/gateway/hono/routes/user-model.js +35 -102
  111. package/dist/src/gateway/hono/routes/workflows.js +7 -4
  112. package/dist/src/gateway/service.js +9 -9
  113. package/dist/src/tasks/home-query-service.js +2 -2
  114. package/dist/src/tui/tui-workflow-slash.d.ts +3 -6
  115. package/dist/src/tui/tui-workflow-slash.js +3 -6
  116. package/dist/src/user-model/bootstrap.d.ts +17 -0
  117. package/dist/src/user-model/bootstrap.js +118 -0
  118. package/dist/src/user-model/index.d.ts +3 -0
  119. package/dist/src/user-model/index.js +4 -1
  120. package/dist/src/user-model/profile.d.ts +5 -0
  121. package/dist/src/user-model/profile.js +98 -0
  122. package/dist/src/user-model/usage-policy.d.ts +2 -0
  123. package/dist/src/user-model/usage-policy.js +6 -0
  124. package/dist/src/work-discovery/analyzer.js +8 -6
  125. package/dist/src/work-discovery/service.d.ts +1 -1
  126. package/dist/src/work-discovery/service.js +4 -4
  127. package/dist/src/work-discovery/types.d.ts +1 -1
  128. package/dist/src/workflows/domain/run.d.ts +8 -1
  129. package/dist/src/workflows/domain/validation.d.ts +3 -4
  130. package/dist/src/workflows/domain/validation.js +119 -8
  131. package/dist/src/workflows/service/workflow-run-service.js +9 -2
  132. package/package.json +5 -5
  133. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CL3Mi-uM.js +0 -1
  134. package/dist/gateway/static/root/assets/agents-odqXmGhA.js +0 -1
  135. package/dist/gateway/static/root/assets/apps-page-DyBDoCam.js +0 -1
  136. package/dist/gateway/static/root/assets/automations-workspace-8U86Umig.js +0 -6
  137. package/dist/gateway/static/root/assets/block-editor-DFnPsrxI.js +0 -185
  138. package/dist/gateway/static/root/assets/browser-settings-page-DOUG84qV.js +0 -8
  139. package/dist/gateway/static/root/assets/capabilities-settings-panel-CG73Mwi8.js +0 -7
  140. package/dist/gateway/static/root/assets/channels-settings-MDywEWWM.js +0 -1
  141. package/dist/gateway/static/root/assets/connectors-page-D29p6Zvm.js +0 -2
  142. package/dist/gateway/static/root/assets/gateway-settings-rAXx8FGP.js +0 -1
  143. package/dist/gateway/static/root/assets/heartbeat-settings-BaW_r1t9.js +0 -1
  144. package/dist/gateway/static/root/assets/home-page-BoTS8-Z9.js +0 -1
  145. package/dist/gateway/static/root/assets/index-DsonmRCH.css +0 -2
  146. package/dist/gateway/static/root/assets/languages-5WaOu0Lf.js +0 -2
  147. package/dist/gateway/static/root/assets/local-app-workbench-page-B3flRQH1.js +0 -2
  148. package/dist/gateway/static/root/assets/markdown-editor-BjMTIM-m.js +0 -1
  149. package/dist/gateway/static/root/assets/messages-DngsF_Kx.js +0 -3
  150. package/dist/gateway/static/root/assets/note-detail-panel-OklYXK7y.js +0 -5
  151. package/dist/gateway/static/root/assets/notes-page-BjfgJIQw.js +0 -8
  152. package/dist/gateway/static/root/assets/product-open-page-D7p0NfTK.js +0 -1
  153. package/dist/gateway/static/root/assets/project-detail-page-rLNM2mP0.js +0 -1
  154. package/dist/gateway/static/root/assets/remote-access-hub-CZZg0kXc.js +0 -1
  155. package/dist/gateway/static/root/assets/sessions-page-BvuxJegi.js +0 -1
  156. package/dist/gateway/static/root/assets/settings-advanced-gate-BAQHP4mB.js +0 -1
  157. package/dist/gateway/static/root/assets/setup-status-panel-BkWoc5j5.js +0 -1
  158. package/dist/gateway/static/root/assets/shares-settings-B2doziIn.js +0 -1
  159. package/dist/gateway/static/root/assets/skill-reload-api-D2ymjqG5.js +0 -1
  160. package/dist/gateway/static/root/assets/source-workspace-editor-CVWzt0oT.js +0 -1
  161. package/dist/gateway/static/root/assets/task-detail-page-7w7eB9nB.js +0 -1
  162. package/dist/gateway/static/root/assets/user-model-page-CcNCyrXZ.js +0 -2
  163. package/dist/gateway/static/root/assets/workflow-run-setup-panel-CUCfBpPF.js +0 -3
  164. package/dist/gateway/static/root/assets/workflows-page-Bp-nvnLa.js +0 -5
@@ -174,6 +174,12 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
174
174
  readonly en: "Read a typed user assertion.";
175
175
  readonly zh: "读取一条结构化用户事实。";
176
176
  };
177
+ }, {
178
+ readonly id: "user_context_update";
179
+ readonly description: {
180
+ readonly en: "Apply an explicit user correction to an existing assertion.";
181
+ readonly zh: "根据用户明确表达修正已有用户理解。";
182
+ };
177
183
  }, {
178
184
  readonly id: "knowledge_search";
179
185
  readonly description: {
@@ -265,4 +271,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
265
271
  readonly zh: "使用已验证的参数执行选定的外部工具。";
266
272
  };
267
273
  }];
268
- export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "user_context_search" | "user_context_get" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
274
+ export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "user_context_search" | "user_context_get" | "user_context_update" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
@@ -199,6 +199,13 @@ const GATEWAY_BUILTIN_TOOLS = [
199
199
  zh: "读取一条结构化用户事实。"
200
200
  }
201
201
  },
202
+ {
203
+ id: "user_context_update",
204
+ description: {
205
+ en: "Apply an explicit user correction to an existing assertion.",
206
+ zh: "根据用户明确表达修正已有用户理解。"
207
+ }
208
+ },
202
209
  {
203
210
  id: "knowledge_search",
204
211
  description: {
@@ -2,7 +2,9 @@ import { createCollaborationRule, getCollaborationRule, listCollaborationRules,
2
2
  import { getKnowledgeItem, listKnowledgeItems, searchKnowledgeItems, setKnowledgeStatus } from "../../../knowledge-memory/repository.js";
3
3
  import "../../../knowledge-memory/index.js";
4
4
  import { createPriorityWindow, createUserGoal, listPriorityWindows, listUserGoals, setUserGoalStatus } from "../../../user-model/goals.js";
5
- import { getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../../user-model/repository.js";
5
+ import { getAssertionSlot, getUserAssertion, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../../user-model/repository.js";
6
+ import { applyUserProfilePatch, getUserProfileSnapshot } from "../../../user-model/profile.js";
7
+ import { bootstrapUserModel } from "../../../user-model/bootstrap.js";
6
8
  import "../../../user-model/index.js";
7
9
  import { listMemoryMaintenanceRuns } from "../../../memory-maintenance/service.js";
8
10
  import "../../../memory-maintenance/index.js";
@@ -86,65 +88,6 @@ const RULE_STATUSES = new Set([
86
88
  "disabled",
87
89
  "archived"
88
90
  ]);
89
- function profileAssertion(predicate) {
90
- return getActiveAssertionForSlot({
91
- subject: {
92
- type: "user",
93
- id: "self"
94
- },
95
- predicate,
96
- scope: { type: "global" }
97
- });
98
- }
99
- function profileValue(predicate) {
100
- return profileAssertion(predicate)?.value;
101
- }
102
- function profileSnapshot() {
103
- return {
104
- callName: profileValue("identity.call_name"),
105
- pronouns: profileValue("identity.pronouns"),
106
- timezone: profileValue("preference.timezone"),
107
- locale: profileValue("preference.locale"),
108
- role: profileValue("identity.role")
109
- };
110
- }
111
- const PROFILE_FIELDS = {
112
- callName: {
113
- predicate: "identity.call_name",
114
- kind: "identity",
115
- volatility: "stable",
116
- importance: .95,
117
- statement: (value) => `The user prefers to be called ${value}.`
118
- },
119
- role: {
120
- predicate: "identity.role",
121
- kind: "identity",
122
- volatility: "slow",
123
- importance: .9,
124
- statement: (value) => `The user's role is ${value}.`
125
- },
126
- pronouns: {
127
- predicate: "identity.pronouns",
128
- kind: "identity",
129
- volatility: "stable",
130
- importance: .75,
131
- statement: (value) => `The user's pronouns are ${value}.`
132
- },
133
- timezone: {
134
- predicate: "preference.timezone",
135
- kind: "preference",
136
- volatility: "slow",
137
- importance: .85,
138
- statement: (value) => `The user's timezone is ${value}.`
139
- },
140
- locale: {
141
- predicate: "preference.locale",
142
- kind: "preference",
143
- volatility: "slow",
144
- importance: .85,
145
- statement: (value) => `The user's language and locale are ${value}.`
146
- }
147
- };
148
91
  function assertionView(assertion) {
149
92
  const slot = getAssertionSlot(assertion.slotId);
150
93
  if (!slot) throw new Error(`Assertion slot not found: ${assertion.slotId}`);
@@ -181,7 +124,7 @@ function registerUserModelRoutes(authenticated, deps) {
181
124
  rules: listCollaborationRules(),
182
125
  knowledge,
183
126
  maintenance: { lastRun: listMemoryMaintenanceRuns(1)[0] ?? null },
184
- profile: profileSnapshot(),
127
+ profile: getUserProfileSnapshot(),
185
128
  counts: {
186
129
  activeAssertions: assertions.filter((item) => item.status === "active").length,
187
130
  reviewAssertions: assertions.filter((item) => item.status === "needs_review" || item.status === "conflicted").length,
@@ -194,48 +137,38 @@ function registerUserModelRoutes(authenticated, deps) {
194
137
  authenticated.patch("/api/user-model/profile", write, async (c) => {
195
138
  const input = await body(c);
196
139
  if (!input) return c.json({ error: "A profile patch is required" }, 400);
197
- const entries = Object.entries(PROFILE_FIELDS).filter(([key]) => Object.hasOwn(input, key));
198
- if (!entries.length || entries.some(([key]) => typeof input[key] !== "string")) return c.json({ error: "Profile fields must be strings" }, 400);
140
+ const entries = [
141
+ "callName",
142
+ "role",
143
+ "pronouns",
144
+ "timezone",
145
+ "locale"
146
+ ].filter((key) => Object.hasOwn(input, key));
147
+ if (!entries.length || entries.some((key) => typeof input[key] !== "string")) return c.json({ error: "Profile fields must be strings" }, 400);
199
148
  try {
200
- const now = Date.now();
201
- for (const [key, field] of entries) {
202
- const value = input[key].trim();
203
- const current = profileAssertion(field.predicate);
204
- if (!value) {
205
- if (current) setAssertionStatus(current.id, "archived", {
206
- actor: "user",
207
- reason: "Profile field cleared by user.",
208
- now
209
- });
210
- continue;
211
- }
212
- reconcileAssertion({
213
- subject: {
214
- type: "user",
215
- id: "self"
216
- },
217
- predicate: field.predicate,
218
- cardinality: "single",
219
- scope: { type: "global" },
220
- kind: field.kind,
221
- value,
222
- normalizedValue: value.toLocaleLowerCase(),
223
- statement: field.statement(value),
224
- authority: "user_explicit",
225
- confidence: 1,
226
- declaredImportance: field.importance,
227
- inferredImportance: field.importance,
228
- consequence: "medium",
229
- actionability: .9,
230
- volatility: field.volatility,
231
- sensitivity: "normal",
232
- disclosurePolicy: "referenceable",
233
- observedAt: now,
234
- createdBy: "user",
235
- ...current ? { correctionOfAssertionId: current.id } : {}
236
- });
237
- }
238
- return c.json({ profile: profileSnapshot() });
149
+ return c.json({ profile: applyUserProfilePatch(Object.fromEntries(entries.map((key) => [key, input[key]]))) });
150
+ } catch (error) {
151
+ return c.json({ error: errorMessage(error) }, 400);
152
+ }
153
+ });
154
+ authenticated.post("/api/user-model/bootstrap", write, async (c) => {
155
+ const input = await body(c);
156
+ const profile = object(input?.profile);
157
+ const listFields = [
158
+ "responsibilities",
159
+ "goals",
160
+ "communicationPreferences",
161
+ "boundaries",
162
+ "relationships"
163
+ ];
164
+ const validProfile = profile && Object.values(profile).every((value) => typeof value === "string");
165
+ const validLists = listFields.every((key) => input?.[key] === void 0 || Array.isArray(input[key]) && input[key].every((value) => typeof value === "string"));
166
+ if (!input || !validProfile || !validLists) return c.json({ error: "profile and string-list user-model fields are required" }, 400);
167
+ try {
168
+ return c.json(bootstrapUserModel({
169
+ profile,
170
+ ...Object.fromEntries(listFields.flatMap((key) => input[key] === void 0 ? [] : [[key, input[key]]]))
171
+ }), 201);
239
172
  } catch (error) {
240
173
  return c.json({ error: errorMessage(error) }, 400);
241
174
  }
@@ -9,8 +9,8 @@ import { resolveWorkflowRunArtifactsDir } from "../../../workflows/store/paths.j
9
9
  import { WorkflowDraftService } from "../../../workflows/draft/workflow-draft-service.js";
10
10
  import { WorkflowDraftConflictError, WorkflowDraftStore } from "../../../workflows/authoring/workflow-draft-store.js";
11
11
  import "../../../workflows/authoring/index.js";
12
- import { ProjectWorkflowPresetRepository } from "../../../workflows/project-presets/project-workflow-preset-repository.js";
13
12
  import "../../../workflows/draft/index.js";
13
+ import { ProjectWorkflowPresetRepository } from "../../../workflows/project-presets/project-workflow-preset-repository.js";
14
14
  import { basename, join } from "node:path";
15
15
  import { readFile, stat } from "node:fs/promises";
16
16
  //#region src/gateway/hono/routes/workflows.ts
@@ -103,7 +103,8 @@ function registerWorkflowRoutes(authenticated, deps) {
103
103
  const body = await readJsonBody(c.req.raw);
104
104
  const result = validateWorkflowDefinitionInput({
105
105
  name: body.name,
106
- graph: body.graph
106
+ graph: body.graph,
107
+ manifest: body.manifest
107
108
  });
108
109
  return c.json(result);
109
110
  });
@@ -132,7 +133,8 @@ function registerWorkflowRoutes(authenticated, deps) {
132
133
  if (body.expectedRevision !== 0) return c.json({ error: "expectedRevision must be 0 when creating a workflow" }, 400);
133
134
  const validation = validateWorkflowDefinitionInput({
134
135
  name: body.name,
135
- graph: body.graph
136
+ graph: body.graph,
137
+ manifest: body.manifest
136
138
  });
137
139
  if (!validation.valid) return c.json({
138
140
  error: validation.errors[0]?.message ?? "Invalid workflow definition",
@@ -171,7 +173,8 @@ function registerWorkflowRoutes(authenticated, deps) {
171
173
  if (!Number.isSafeInteger(body.expectedRevision) || body.expectedRevision < 1) return c.json({ error: "expectedRevision is required" }, 400);
172
174
  const validation = validateWorkflowDefinitionInput({
173
175
  name: id,
174
- graph: body.graph
176
+ graph: body.graph,
177
+ manifest: body.manifest
175
178
  });
176
179
  if (!validation.valid) return c.json({
177
180
  error: validation.errors[0]?.message ?? "Invalid workflow definition",
@@ -21,9 +21,6 @@ import { loadConfig, saveConfig } from "../config/loader.js";
21
21
  import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
22
22
  import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
23
23
  import { init_providers, providers_exports } from "../providers/index.js";
24
- import { AutomationService } from "../automations/service/automation-service.js";
25
- import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
26
- import "../automations/index.js";
27
24
  import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
28
25
  import { TaskRepository } from "../tasks/task-repository.js";
29
26
  import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
@@ -34,6 +31,9 @@ import { resolveProjectAgentId } from "../projects/project-agent.js";
34
31
  import "../projects/index.js";
35
32
  import { resolveEffectiveGatewayPort } from "./host.js";
36
33
  import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
34
+ import { AutomationService } from "../automations/service/automation-service.js";
35
+ import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
36
+ import "../automations/index.js";
37
37
  import { TaskApplicationService } from "../tasks/task-application-service.js";
38
38
  import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
39
39
  import { TaskOutboxDispatcher } from "../tasks/task-outbox-dispatcher.js";
@@ -54,12 +54,6 @@ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
54
54
  import { ChannelManager } from "../channels/manager.js";
55
55
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
56
56
  import "../config/index.js";
57
- import { DiscussionService } from "../discussions/service.js";
58
- import { DiscussionOrganizer } from "../discussions/organizer.js";
59
- import { DiscussionLiveWorker } from "../discussions/live-worker.js";
60
- import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
61
- import { DiscussionSealer } from "../discussions/sealer.js";
62
- import "../discussions/index.js";
63
57
  import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
64
58
  import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
65
59
  import "../knowledge/index.js";
@@ -67,6 +61,12 @@ import { ConnectionRecoveryService } from "../connectors/connection-recovery-ser
67
61
  import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
68
62
  import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
69
63
  import { startConnectorSupervisor } from "../connectors/supervisor.js";
64
+ import { DiscussionService } from "../discussions/service.js";
65
+ import { DiscussionOrganizer } from "../discussions/organizer.js";
66
+ import { DiscussionLiveWorker } from "../discussions/live-worker.js";
67
+ import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
68
+ import { DiscussionSealer } from "../discussions/sealer.js";
69
+ import "../discussions/index.js";
70
70
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
71
71
  import "../endpoint-tools/index.js";
72
72
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
@@ -2,10 +2,10 @@ import { isHomeAttentionAcknowledged } from "../storage/sqlite/home-attention-re
2
2
  import { getRelationshipSettings } from "../storage/sqlite/relationship-settings-repository.js";
3
3
  import { listConnectorApprovals } from "../storage/sqlite/connector-repository.js";
4
4
  import "../storage/sqlite/index.js";
5
- import "../automations/domain/defaults.js";
6
- import "../automations/index.js";
7
5
  import { TaskRepository } from "./task-repository.js";
8
6
  import { TaskReadModelProjector } from "./task-read-model-projector.js";
7
+ import "../automations/domain/defaults.js";
8
+ import "../automations/index.js";
9
9
  import { AttentionGovernor } from "./attention-governor.js";
10
10
  import { listGatewayAgents } from "../gateway/agents-admin.js";
11
11
  //#region src/tasks/home-query-service.ts
@@ -11,17 +11,14 @@
11
11
  * shortest reliable path is to turn `/audit_repo` into the same plain-text
12
12
  * request the model already knows how to handle.
13
13
  *
14
- * Why catalog the workflow list at the TUI layer?
15
- * The catalog reads `~/.xopc/workflows/` synchronously (single `readdir`),
16
- * so the slash dispatch stays sync and the user sees no latency. The lookup
17
- * only runs for inputs that started with `/` and didn't match any built-in
18
- * or extension command, so the cost is negligible.
14
+ * The lookup only runs for inputs that started with `/` and did not match a
15
+ * built-in or extension command. A short cache keeps repeated dispatch cheap.
19
16
  *
20
17
  * Built-in TUI command names that overlap with a workflow file name keep their
21
18
  * existing TUI behaviour — the slash dispatcher matches the built-in switch
22
19
  * cases before this helper is consulted.
23
20
  */
24
- /** Reset the cache (for tests, or after a `/workflow save`). */
21
+ /** Reset the cache after workflow changes and in tests. */
25
22
  export declare function resetWorkflowSlashCache(): void;
26
23
  /**
27
24
  * Returns a rewritten user message when `name` matches a known workflow,
@@ -13,11 +13,8 @@ import { createWorkflowCatalog } from "../agent/workflow/catalog.js";
13
13
  * shortest reliable path is to turn `/audit_repo` into the same plain-text
14
14
  * request the model already knows how to handle.
15
15
  *
16
- * Why catalog the workflow list at the TUI layer?
17
- * The catalog reads `~/.xopc/workflows/` synchronously (single `readdir`),
18
- * so the slash dispatch stays sync and the user sees no latency. The lookup
19
- * only runs for inputs that started with `/` and didn't match any built-in
20
- * or extension command, so the cost is negligible.
16
+ * The lookup only runs for inputs that started with `/` and did not match a
17
+ * built-in or extension command. A short cache keeps repeated dispatch cheap.
21
18
  *
22
19
  * Built-in TUI command names that overlap with a workflow file name keep their
23
20
  * existing TUI behaviour — the slash dispatcher matches the built-in switch
@@ -26,7 +23,7 @@ import { createWorkflowCatalog } from "../agent/workflow/catalog.js";
26
23
  let cachedNames = null;
27
24
  let cachedAt = 0;
28
25
  const CACHE_TTL_MS = 5e3;
29
- /** Reset the cache (for tests, or after a `/workflow save`). */
26
+ /** Reset the cache after workflow changes and in tests. */
30
27
  function resetWorkflowSlashCache() {
31
28
  cachedNames = null;
32
29
  cachedAt = 0;
@@ -0,0 +1,17 @@
1
+ import { type UserProfilePatch } from './profile.js';
2
+ export interface UserModelBootstrapInput {
3
+ profile: UserProfilePatch;
4
+ responsibilities?: string[];
5
+ goals?: string[];
6
+ communicationPreferences?: string[];
7
+ boundaries?: string[];
8
+ relationships?: string[];
9
+ }
10
+ export declare function bootstrapUserModel(input: UserModelBootstrapInput, now?: number): {
11
+ profile: Partial<Record<import("./profile.js").UserProfileField, string>>;
12
+ created: {
13
+ assertions: number;
14
+ goals: number;
15
+ rules: number;
16
+ };
17
+ };
@@ -0,0 +1,118 @@
1
+ import { createCollaborationRule, listCollaborationRules } from "../storage/sqlite/collaboration-rule-repository.js";
2
+ import { createPriorityWindow, createUserGoal, listPriorityWindows, listUserGoals } from "./goals.js";
3
+ import { reconcileAssertion } from "./repository.js";
4
+ import { applyUserProfilePatch } from "./profile.js";
5
+ //#region src/user-model/bootstrap.ts
6
+ function statements(values, limit) {
7
+ return [...new Set((values ?? []).map((value) => value.trim().slice(0, 500)).filter(Boolean))].slice(0, limit);
8
+ }
9
+ function addExplicitAssertions(values, input, now) {
10
+ let created = 0;
11
+ for (const statement of values) if (reconcileAssertion({
12
+ subject: {
13
+ type: "user",
14
+ id: "self"
15
+ },
16
+ predicate: input.predicate,
17
+ cardinality: "multiple",
18
+ scope: { type: "global" },
19
+ kind: input.kind,
20
+ value: statement,
21
+ normalizedValue: statement.toLocaleLowerCase(),
22
+ statement,
23
+ authority: "user_explicit",
24
+ confidence: 1,
25
+ declaredImportance: input.importance,
26
+ inferredImportance: input.importance,
27
+ consequence: "medium",
28
+ actionability: .8,
29
+ volatility: "slow",
30
+ sensitivity: input.kind === "relationship" ? "personal" : "normal",
31
+ disclosurePolicy: "referenceable",
32
+ observedAt: now,
33
+ createdBy: "user"
34
+ }, now).action !== "deduplicated") created += 1;
35
+ return created;
36
+ }
37
+ function addRules(category, values) {
38
+ const existing = new Set(listCollaborationRules().filter((rule) => rule.category === category && rule.status !== "archived").map((rule) => rule.statement.toLocaleLowerCase()));
39
+ let created = 0;
40
+ for (const statement of values) {
41
+ if (existing.has(statement.toLocaleLowerCase())) continue;
42
+ createCollaborationRule({
43
+ category,
44
+ priority: category === "boundary" ? 0 : 50,
45
+ scope: { type: "global" },
46
+ conditions: {
47
+ enforcementLevel: "prompt",
48
+ source: "onboarding"
49
+ },
50
+ statement
51
+ });
52
+ existing.add(statement.toLocaleLowerCase());
53
+ created += 1;
54
+ }
55
+ return created;
56
+ }
57
+ function bootstrapUserModel(input, now = Date.now()) {
58
+ const responsibilities = statements(input.responsibilities, 8);
59
+ const goals = statements(input.goals, 5);
60
+ const communicationPreferences = statements(input.communicationPreferences, 8);
61
+ const boundaries = statements(input.boundaries, 8);
62
+ const relationships = statements(input.relationships, 12);
63
+ const profile = applyUserProfilePatch(input.profile, now);
64
+ const assertionCount = addExplicitAssertions(responsibilities, {
65
+ predicate: "identity.responsibility",
66
+ kind: "identity",
67
+ importance: .85
68
+ }, now) + addExplicitAssertions(relationships, {
69
+ predicate: "relationship.important",
70
+ kind: "relationship",
71
+ importance: .8
72
+ }, now);
73
+ const existingGoals = new Map(listUserGoals().filter((goal) => goal.status === "active" || goal.status === "proposed").map((goal) => [goal.desiredOutcome.toLocaleLowerCase(), goal]));
74
+ const activePriorities = new Set(listPriorityWindows().filter((priority) => priority.status === "active").map((priority) => priority.targetId));
75
+ let goalCount = 0;
76
+ for (const [index, desiredOutcome] of goals.entries()) {
77
+ const key = desiredOutcome.toLocaleLowerCase();
78
+ const existing = existingGoals.get(key);
79
+ const goal = existing ?? createUserGoal({
80
+ title: desiredOutcome.slice(0, 80),
81
+ desiredOutcome,
82
+ scope: { type: "global" },
83
+ declaredImportance: index === 0 ? 1 : .8,
84
+ status: "active",
85
+ authority: "user_explicit",
86
+ confidence: 1,
87
+ createdBy: "user",
88
+ now
89
+ });
90
+ if (!existing) goalCount += 1;
91
+ if (index === 0 && !activePriorities.has(goal.id)) {
92
+ createPriorityWindow({
93
+ targetType: "goal",
94
+ targetId: goal.id,
95
+ rank: "primary",
96
+ urgency: .9,
97
+ scope: { type: "global" },
98
+ validFrom: now,
99
+ validTo: now + 720 * 60 * 60 * 1e3,
100
+ reviewAt: now + 10080 * 60 * 1e3,
101
+ declaredImportance: 1,
102
+ now
103
+ });
104
+ activePriorities.add(goal.id);
105
+ }
106
+ existingGoals.set(key, goal);
107
+ }
108
+ return {
109
+ profile,
110
+ created: {
111
+ assertions: assertionCount,
112
+ goals: goalCount,
113
+ rules: addRules("communication", communicationPreferences) + addRules("boundary", boundaries)
114
+ }
115
+ };
116
+ }
117
+ //#endregion
118
+ export { bootstrapUserModel };
@@ -1,5 +1,8 @@
1
1
  export * from './domain.js';
2
2
  export * from './importance.js';
3
3
  export * from './goals.js';
4
+ export * from './bootstrap.js';
5
+ export * from './profile.js';
4
6
  export * from './repository.js';
5
7
  export * from './temporal.js';
8
+ export * from './usage-policy.js';
@@ -3,4 +3,7 @@ import { calculateExecutionValue } from "./importance.js";
3
3
  import { createPriorityWindow, createUserGoal, listPriorityWindows, listUserGoals, setUserGoalStatus } from "./goals.js";
4
4
  import { defaultReviewAt, isAssertionValidAt, requiresBoundedValidity, resolveCurrentAssertion } from "./temporal.js";
5
5
  import { getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, linkAssertionEvidence, listSlotAssertions, listUserAssertions, reconcileAssertion, setAssertionStatus } from "./repository.js";
6
- export { USER_MODEL_PRINCIPAL_ID, calculateExecutionValue, createPriorityWindow, createUserGoal, defaultReviewAt, getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, isAssertionValidAt, linkAssertionEvidence, listPriorityWindows, listSlotAssertions, listUserAssertions, listUserGoals, reconcileAssertion, requiresBoundedValidity, resolveCurrentAssertion, setAssertionStatus, setUserGoalStatus, validateCandidate, validateScope };
6
+ import { applyUserProfilePatch, getUserProfileSnapshot } from "./profile.js";
7
+ import { bootstrapUserModel } from "./bootstrap.js";
8
+ import { isWorkingAssumption } from "./usage-policy.js";
9
+ export { USER_MODEL_PRINCIPAL_ID, applyUserProfilePatch, bootstrapUserModel, calculateExecutionValue, createPriorityWindow, createUserGoal, defaultReviewAt, getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserProfileSnapshot, getUserTimezone, isAssertionValidAt, isWorkingAssumption, linkAssertionEvidence, listPriorityWindows, listSlotAssertions, listUserAssertions, listUserGoals, reconcileAssertion, requiresBoundedValidity, resolveCurrentAssertion, setAssertionStatus, setUserGoalStatus, validateCandidate, validateScope };
@@ -0,0 +1,5 @@
1
+ export type UserProfileField = 'callName' | 'role' | 'pronouns' | 'timezone' | 'locale';
2
+ export type UserProfilePatch = Partial<Record<UserProfileField, string>>;
3
+ export type UserProfileSnapshot = Partial<Record<UserProfileField, string>>;
4
+ export declare function getUserProfileSnapshot(): UserProfileSnapshot;
5
+ export declare function applyUserProfilePatch(input: UserProfilePatch, now?: number): UserProfileSnapshot;
@@ -0,0 +1,98 @@
1
+ import { getActiveAssertionForSlot, reconcileAssertion, setAssertionStatus } from "./repository.js";
2
+ //#region src/user-model/profile.ts
3
+ const PROFILE_FIELDS = {
4
+ callName: {
5
+ predicate: "identity.call_name",
6
+ kind: "identity",
7
+ volatility: "stable",
8
+ importance: .95,
9
+ statement: (value) => `Prefers to be called ${value}.`
10
+ },
11
+ role: {
12
+ predicate: "identity.role",
13
+ kind: "identity",
14
+ volatility: "slow",
15
+ importance: .9,
16
+ statement: (value) => `Role: ${value}.`
17
+ },
18
+ pronouns: {
19
+ predicate: "identity.pronouns",
20
+ kind: "identity",
21
+ volatility: "stable",
22
+ importance: .75,
23
+ statement: (value) => `Pronouns: ${value}.`
24
+ },
25
+ timezone: {
26
+ predicate: "preference.timezone",
27
+ kind: "preference",
28
+ volatility: "slow",
29
+ importance: .85,
30
+ statement: (value) => `Timezone: ${value}.`
31
+ },
32
+ locale: {
33
+ predicate: "preference.locale",
34
+ kind: "preference",
35
+ volatility: "slow",
36
+ importance: .85,
37
+ statement: (value) => `Language and locale: ${value}.`
38
+ }
39
+ };
40
+ function activeProfileAssertion(field) {
41
+ return getActiveAssertionForSlot({
42
+ subject: {
43
+ type: "user",
44
+ id: "self"
45
+ },
46
+ predicate: PROFILE_FIELDS[field].predicate,
47
+ scope: { type: "global" }
48
+ });
49
+ }
50
+ function getUserProfileSnapshot() {
51
+ return Object.fromEntries(Object.keys(PROFILE_FIELDS).flatMap((key) => {
52
+ const value = activeProfileAssertion(key)?.value;
53
+ return typeof value === "string" ? [[key, value]] : [];
54
+ }));
55
+ }
56
+ function applyUserProfilePatch(input, now = Date.now()) {
57
+ for (const [key, rawValue] of Object.entries(input)) {
58
+ const field = PROFILE_FIELDS[key];
59
+ const value = rawValue.trim();
60
+ const current = activeProfileAssertion(key);
61
+ if (!value) {
62
+ if (current) setAssertionStatus(current.id, "archived", {
63
+ actor: "user",
64
+ reason: "Profile field cleared by user.",
65
+ now
66
+ });
67
+ continue;
68
+ }
69
+ reconcileAssertion({
70
+ subject: {
71
+ type: "user",
72
+ id: "self"
73
+ },
74
+ predicate: field.predicate,
75
+ cardinality: "single",
76
+ scope: { type: "global" },
77
+ kind: field.kind,
78
+ value,
79
+ normalizedValue: value.toLocaleLowerCase(),
80
+ statement: field.statement(value),
81
+ authority: "user_explicit",
82
+ confidence: 1,
83
+ declaredImportance: field.importance,
84
+ inferredImportance: field.importance,
85
+ consequence: "medium",
86
+ actionability: .9,
87
+ volatility: field.volatility,
88
+ sensitivity: "normal",
89
+ disclosurePolicy: "referenceable",
90
+ observedAt: now,
91
+ createdBy: "user",
92
+ ...current ? { correctionOfAssertionId: current.id } : {}
93
+ }, now);
94
+ }
95
+ return getUserProfileSnapshot();
96
+ }
97
+ //#endregion
98
+ export { applyUserProfilePatch, getUserProfileSnapshot };
@@ -0,0 +1,2 @@
1
+ import type { UserAssertion } from './domain.js';
2
+ export declare function isWorkingAssumption(assertion: UserAssertion): boolean;
@@ -0,0 +1,6 @@
1
+ //#region src/user-model/usage-policy.ts
2
+ function isWorkingAssumption(assertion) {
3
+ return assertion.status === "candidate" && (assertion.authority === "user_observed" || assertion.authority === "system_inferred") && assertion.confidence >= .7 && assertion.consequence !== "critical" && assertion.sensitivity === "normal" && assertion.disclosurePolicy !== "ask_before_reference";
4
+ }
5
+ //#endregion
6
+ export { isWorkingAssumption };