@xopcai/xopc 0.0.307 → 0.0.308

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 (165) 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/{agent-avatar-dicebear-CZeQo09T.js → agent-avatar-dicebear-dUotwUO6.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-C6LflMXr.js +1 -0
  5. package/dist/gateway/static/root/assets/{agents-BlrHMbRx.js → agents-VPDIGRSS.js} +1 -1
  6. package/dist/gateway/static/root/assets/{app-management-settings-panel-Bzw4fQP8.js → app-management-settings-panel-zPz0rOND.js} +1 -1
  7. package/dist/gateway/static/root/assets/{appearance-settings-8GZpUXva.js → appearance-settings-DhvhR43G.js} +1 -1
  8. package/dist/gateway/static/root/assets/{apps-page-BkQQtIxH.js → apps-page-Pmslbzzr.js} +1 -1
  9. package/dist/gateway/static/root/assets/{archive-plugin-CQ2NaoHb.js → archive-plugin-BQVZMreT.js} +1 -1
  10. package/dist/gateway/static/root/assets/{attachment-load-BFi1H7yJ.js → attachment-load-CPE-TMPf.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-page-CDBXcii_.js → automations-page-C4IAy_zF.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-workspace-Fx5VUJRu.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-D07eWmOx.js → binary-plugins-DgTl7diZ.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-CtVnjyYU.js → block-editor-CcOVA-Gw.js} +3 -3
  15. package/dist/gateway/static/root/assets/{browser-automations-page-DyrSbDdG.js → browser-automations-page--zKAgj1k.js} +1 -1
  16. package/dist/gateway/static/root/assets/browser-settings-page-DBms6d35.js +3 -0
  17. package/dist/gateway/static/root/assets/capabilities-settings-panel-epdDWIZy.js +8 -0
  18. package/dist/gateway/static/root/assets/{channels-settings-DAD9qE3J.js → channels-settings-B0bsDtmP.js} +1 -1
  19. package/dist/gateway/static/root/assets/{chat-terminal-dock-B62SZdAo.js → chat-terminal-dock-BfLd2rIJ.js} +1 -1
  20. package/dist/gateway/static/root/assets/{computer-settings-page-ClSresNq.js → computer-settings-page-Ckgc0Py-.js} +1 -1
  21. package/dist/gateway/static/root/assets/connector-service-page-BlC1OXX4.js +1 -0
  22. package/dist/gateway/static/root/assets/connectors-page-By33-bF1.js +2 -0
  23. package/dist/gateway/static/root/assets/{cron-expression-CTMi_tql.js → cron-expression-CqNE-nf6.js} +1 -1
  24. package/dist/gateway/static/root/assets/{date-picker-B71AJK50.js → date-picker-BS9ZjzYJ.js} +1 -1
  25. package/dist/gateway/static/root/assets/{dependency-picker-DlyGK-kA.js → dependency-picker-CF_zYzxX.js} +1 -1
  26. package/dist/gateway/static/root/assets/{desktop-pet-DGkbTE8_.js → desktop-pet-CDwtLR7Z.js} +1 -1
  27. package/dist/gateway/static/root/assets/{desktop-pet-settings-BY8r9j66.js → desktop-pet-settings-C0djIc1J.js} +1 -1
  28. package/dist/gateway/static/root/assets/{device-pairing-wizard-DzRrgd59.js → device-pairing-wizard-CDKj9LQj.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-debug-page-L8Mm1n3A.js → extension-debug-page-CX5OXxEU.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-page-CFc4vSNU.js → extension-page-BytR1PaY.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-settings-page-B5zWyHr3.js → extension-settings-page-CkaMJA5F.js} +1 -1
  32. package/dist/gateway/static/root/assets/{gateway-settings-D7qmTH4R.js → gateway-settings-_YU-1p0z.js} +1 -1
  33. package/dist/gateway/static/root/assets/{heartbeat-settings-Glsl3X5b.js → heartbeat-settings-CVIvvm4x.js} +1 -1
  34. package/dist/gateway/static/root/assets/home-page-COCHelcL.js +1 -0
  35. package/dist/gateway/static/root/assets/{imports-page-ByBX7ome.js → imports-page-DrtbjL8O.js} +1 -1
  36. package/dist/gateway/static/root/assets/index-CDfcPiPb.js +79 -0
  37. package/dist/gateway/static/root/assets/index-CRu1p38D.css +1 -0
  38. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C45RlO8a.js → keyboard-shortcuts-settings-BlZh41Xq.js} +1 -1
  39. package/dist/gateway/static/root/assets/{local-app-workbench-page-DP0x2jpR.js → local-app-workbench-page-D7_Raxjw.js} +2 -2
  40. package/dist/gateway/static/root/assets/{local-apps-page-C_AQc2bI.js → local-apps-page-DbP7wWuh.js} +1 -1
  41. package/dist/gateway/static/root/assets/{logs-page-DvM8Pyok.js → logs-page-C0n66FiO.js} +1 -1
  42. package/dist/gateway/static/root/assets/{management-settings-D1uwSutV.js → management-settings-i6GhxpGV.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-C4mhf13f.js → media-plugins-CnWChQ3Y.js} +1 -1
  44. package/dist/gateway/static/root/assets/note-detail-panel-C59d8vDW.js +5 -0
  45. package/dist/gateway/static/root/assets/notes-page-C1GBPrVI.js +8 -0
  46. package/dist/gateway/static/root/assets/{page-tabs-1go_BtX1.js → page-tabs-BWitjb3e.js} +1 -1
  47. package/dist/gateway/static/root/assets/{preview-open-alternatives-DmoSC0j1.js → preview-open-alternatives-UaCWCxZv.js} +1 -1
  48. package/dist/gateway/static/root/assets/{proactive-page-xAjKTIID.js → proactive-page-CtSFJxoM.js} +1 -1
  49. package/dist/gateway/static/root/assets/project-detail-page-ILTmQ1YN.js +1 -0
  50. package/dist/gateway/static/root/assets/projects-page-snl4rOQZ.js +1 -0
  51. package/dist/gateway/static/root/assets/remote-access-hub-BbaAcEN3.js +1 -0
  52. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ClkOoxDl.js → runtime-tools-settings-panel-CtOjKGWg.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schema-form-BuEmLiaU.js → schema-form-DkyyDcl2.js} +1 -1
  54. package/dist/gateway/static/root/assets/sessions-page-DrWL71O8.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-BG0kl4HT.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-form-section-Dor39QON.js → settings-form-section-C0JDGN_V.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-page-Xj-yvIc8.js → settings-page-DiIyMQ52.js} +1 -1
  58. package/dist/gateway/static/root/assets/setup-status-panel-EPazhoZO.js +1 -0
  59. package/dist/gateway/static/root/assets/{share-preview-page-BFWZoXdm.js → share-preview-page-Bt1K657Y.js} +1 -1
  60. package/dist/gateway/static/root/assets/shares-settings-g2MdRXSZ.js +1 -0
  61. package/dist/gateway/static/root/assets/skill-reload-api-B1DPzu98.js +1 -0
  62. package/dist/gateway/static/root/assets/skills-page-Wd0uYSPG.js +2 -0
  63. package/dist/gateway/static/root/assets/{skills-page.utils-Ii8qeXhs.js → skills-page.utils-vq5Ujm03.js} +1 -1
  64. package/dist/gateway/static/root/assets/{system-settings-panel-Di6OSO-0.js → system-settings-panel-Cz1P-HDH.js} +1 -1
  65. package/dist/gateway/static/root/assets/task-detail-page-BG3A5gPZ.js +1 -0
  66. package/dist/gateway/static/root/assets/{tunnel-api-DDOlOYlj.js → tunnel-api-DQGoFuZO.js} +1 -1
  67. package/dist/gateway/static/root/assets/{use-autosave-CQ8uWNnB.js → use-autosave-DVDlBb95.js} +1 -1
  68. package/dist/gateway/static/root/assets/user-model-page-qM5UiTGx.js +2 -0
  69. package/dist/gateway/static/root/assets/{voice-api-key-field-COTzshjL.js → voice-api-key-field-B2pZCcxY.js} +1 -1
  70. package/dist/gateway/static/root/assets/{work-discovery-overlay-_URrXbi4.js → work-discovery-overlay-Bptv7bEY.js} +1 -1
  71. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CALs-1nd.js → workflow-run-setup-panel-BijCrNc4.js} +2 -2
  72. package/dist/gateway/static/root/assets/workflows-page-DRy1RAYH.js +6 -0
  73. package/dist/gateway/static/root/index.html +2 -2
  74. package/dist/package.js +1 -1
  75. package/dist/packages/gateway-contract/src/notifications.js +1 -1
  76. package/dist/src/agent/background-review/prompts.js +3 -1
  77. package/dist/src/agent/context/execution-context.js +4 -4
  78. package/dist/src/agent/memory/compaction-promotion.d.ts +1 -1
  79. package/dist/src/agent/memory/compaction-promotion.js +4 -3
  80. package/dist/src/agent/tools/knowledge-memory-tool.d.ts +1 -1
  81. package/dist/src/agent/tools/knowledge-memory-tool.js +3 -3
  82. package/dist/src/agent/tools/user-context-tool.js +17 -7
  83. package/dist/src/chat-commands/builtins/understanding.js +1 -1
  84. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  85. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  86. package/dist/src/config/schema.d.ts +2 -4
  87. package/dist/src/config/schema.js +2 -2
  88. package/dist/src/connectors/connected-source-understanding.d.ts +1 -0
  89. package/dist/src/connectors/connected-source-understanding.js +1 -0
  90. package/dist/src/connectors/learning-coordinator.js +31 -9
  91. package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -2
  92. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  93. package/dist/src/gateway/hono/routes/context-sources.js +0 -23
  94. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  95. package/dist/src/gateway/hono/routes/projects.js +8 -0
  96. package/dist/src/gateway/hono/routes/user-model-refresh.d.ts +5 -0
  97. package/dist/src/gateway/hono/routes/user-model-refresh.js +128 -0
  98. package/dist/src/gateway/hono/routes/user-model.js +12 -5
  99. package/dist/src/gateway/hono/routes/work-discovery.js +0 -30
  100. package/dist/src/gateway/service.js +6 -6
  101. package/dist/src/infra/update-restart.js +1 -1
  102. package/dist/src/knowledge/connected-knowledge-pipeline.js +1 -1
  103. package/dist/src/knowledge-memory/index.js +2 -2
  104. package/dist/src/knowledge-memory/repository.d.ts +7 -0
  105. package/dist/src/knowledge-memory/repository.js +58 -8
  106. package/dist/src/memory-maintenance/service.js +61 -31
  107. package/dist/src/migrations/memory-config.d.ts +2 -0
  108. package/dist/src/migrations/memory-config.js +77 -0
  109. package/dist/src/migrations/runner.js +2 -2
  110. package/dist/src/notifications/planner.js +5 -5
  111. package/dist/src/notifications/service.d.ts +2 -2
  112. package/dist/src/notifications/service.js +1 -1
  113. package/dist/src/storage/sqlite/migrations/184_memory_suppressions.sql +12 -0
  114. package/dist/src/storage/sqlite/migrations/185_understanding_refresh_batches.sql +6 -0
  115. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  116. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  117. package/dist/src/storage/sqlite/schema.js +1 -1
  118. package/dist/src/user-context/config.d.ts +4 -9
  119. package/dist/src/user-context/config.js +7 -27
  120. package/dist/src/user-context/memory-suppression.d.ts +7 -0
  121. package/dist/src/user-context/memory-suppression.js +23 -0
  122. package/dist/src/user-context/relationship-continuity.js +1 -1
  123. package/dist/src/user-context/sources/refresh-service.d.ts +48 -0
  124. package/dist/src/user-context/sources/refresh-service.js +221 -0
  125. package/dist/src/user-context/sources/repository.js +1 -1
  126. package/dist/src/user-model/bootstrap.js +27 -24
  127. package/dist/src/user-model/capture/executor.d.ts +1 -1
  128. package/dist/src/user-model/capture/executor.js +17 -11
  129. package/dist/src/user-model/capture/semantic.js +1 -1
  130. package/dist/src/user-model/domain.d.ts +6 -2
  131. package/dist/src/user-model/index.js +3 -3
  132. package/dist/src/user-model/profile.js +1 -1
  133. package/dist/src/user-model/repository.d.ts +4 -1
  134. package/dist/src/user-model/repository.js +96 -6
  135. package/dist/src/user-model/usage-policy.d.ts +2 -0
  136. package/dist/src/user-model/usage-policy.js +6 -2
  137. package/dist/src/work-discovery/project-understanding.js +2 -1
  138. package/dist/src/work-discovery/service.d.ts +8 -24
  139. package/dist/src/work-discovery/service.js +138 -180
  140. package/package.json +3 -3
  141. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BPsRb9Ck.js +0 -1
  142. package/dist/gateway/static/root/assets/automations-workspace-CUpiTTiY.js +0 -6
  143. package/dist/gateway/static/root/assets/browser-settings-page-CqTxLpil.js +0 -3
  144. package/dist/gateway/static/root/assets/capabilities-settings-panel-BZ_-pnS6.js +0 -8
  145. package/dist/gateway/static/root/assets/connector-service-page-CPqVmNvx.js +0 -1
  146. package/dist/gateway/static/root/assets/connectors-page-BUQyg3CW.js +0 -2
  147. package/dist/gateway/static/root/assets/home-page-s9hDQ8Hc.js +0 -1
  148. package/dist/gateway/static/root/assets/index-RBCkv8a_.js +0 -79
  149. package/dist/gateway/static/root/assets/index-cFU4S35z.css +0 -1
  150. package/dist/gateway/static/root/assets/note-detail-panel-D35sErp2.js +0 -5
  151. package/dist/gateway/static/root/assets/notes-page-8jCDklDn.js +0 -8
  152. package/dist/gateway/static/root/assets/project-detail-page-BUMQHy_N.js +0 -1
  153. package/dist/gateway/static/root/assets/projects-page-DT-Mt7XR.js +0 -1
  154. package/dist/gateway/static/root/assets/remote-access-hub-Clz3byir.js +0 -1
  155. package/dist/gateway/static/root/assets/sessions-page-tQRwktKm.js +0 -1
  156. package/dist/gateway/static/root/assets/settings-advanced-gate-DqWg9XS5.js +0 -1
  157. package/dist/gateway/static/root/assets/setup-status-panel-BB_sMB7P.js +0 -1
  158. package/dist/gateway/static/root/assets/shares-settings-oDALm4b6.js +0 -1
  159. package/dist/gateway/static/root/assets/skill-reload-api-DmwelnfK.js +0 -1
  160. package/dist/gateway/static/root/assets/skills-page-BE9JXz4U.js +0 -2
  161. package/dist/gateway/static/root/assets/task-detail-page-D1AWszc7.js +0 -1
  162. package/dist/gateway/static/root/assets/user-model-page-C00i4ea0.js +0 -2
  163. package/dist/gateway/static/root/assets/workflows-page-BUiBjz6m.js +0 -6
  164. package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +0 -2
  165. package/dist/src/migrations/knowledge-memory-read-policy-config.js +0 -48
@@ -10,26 +10,6 @@ function isValidTimeZone(value) {
10
10
  return false;
11
11
  }
12
12
  }
13
- function normalizeKnowledgeMemoryConfigInput(input) {
14
- if (!input || typeof input !== "object" || Array.isArray(input)) return input;
15
- const memory = input;
16
- if (!Array.isArray(memory.sources)) return input;
17
- const oldSources = memory.sources.filter((source) => typeof source === "string");
18
- const visibilityScopes = new Set([
19
- "session",
20
- "workspace",
21
- "project"
22
- ]);
23
- const normalized = { ...memory };
24
- if (!Array.isArray(normalized.readScopes)) normalized.readScopes = oldSources.filter((source) => visibilityScopes.has(source));
25
- if (!Array.isArray(normalized.contentSources)) normalized.contentSources = [
26
- ...oldSources.some((source) => visibilityScopes.has(source)) ? ["memory"] : [],
27
- ...oldSources.includes("workspace") ? ["local_import"] : [],
28
- ...oldSources.includes("connector") ? ["connector"] : []
29
- ];
30
- delete normalized.sources;
31
- return normalized;
32
- }
33
13
  function resolveKnowledgeReadPolicy(config) {
34
14
  return {
35
15
  scopes: config.readScopes,
@@ -82,7 +62,7 @@ var init_config = __esmMin((() => {
82
62
  MaintenanceTimeSchema = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Expected time in HH:mm format");
83
63
  UserModelConfigSchema = z.object({
84
64
  enabled: z.boolean().default(true),
85
- writePolicy: WritePolicySchema.default("confirm"),
65
+ writePolicy: z.enum(["deny", "allow"]).default("allow"),
86
66
  sensitiveWritePolicy: WritePolicySchema.default("confirm"),
87
67
  processingPolicy: z.enum(["local_only", "remote_allowed"]).default("remote_allowed"),
88
68
  extraction: z.object({
@@ -124,7 +104,7 @@ var init_config = __esmMin((() => {
124
104
  })
125
105
  }).strict().default({
126
106
  enabled: true,
127
- writePolicy: "confirm",
107
+ writePolicy: "allow",
128
108
  sensitiveWritePolicy: "confirm",
129
109
  processingPolicy: "remote_allowed",
130
110
  extraction: {
@@ -143,9 +123,9 @@ var init_config = __esmMin((() => {
143
123
  staleRetentionDays: 30
144
124
  }
145
125
  });
146
- KnowledgeMemoryConfigSchema = z.preprocess(normalizeKnowledgeMemoryConfigInput, z.object({
126
+ KnowledgeMemoryConfigSchema = z.object({
147
127
  enabled: z.boolean().default(true),
148
- writePolicy: WritePolicySchema.default("confirm"),
128
+ writePolicy: z.enum(["deny", "allow"]).default("allow"),
149
129
  readScopes: z.array(z.enum([
150
130
  "global",
151
131
  "agent",
@@ -182,9 +162,9 @@ var init_config = __esmMin((() => {
182
162
  allowExternalWrites: z.boolean().default(false),
183
163
  allowedProviderIds: z.array(z.string().min(1)).optional(),
184
164
  autoWriteKinds: z.array(z.string().min(1)).optional()
185
- }).strict()).default({
165
+ }).strict().default({
186
166
  enabled: true,
187
- writePolicy: "confirm",
167
+ writePolicy: "allow",
188
168
  readScopes: [
189
169
  "global",
190
170
  "agent",
@@ -227,4 +207,4 @@ var init_config = __esmMin((() => {
227
207
  }));
228
208
  //#endregion
229
209
  init_config();
230
- export { ContextCompactionPolicySchema, ContextPlanningConfigSchema, DEFAULT_CONTEXT_COMPACTION_POLICY, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config, normalizeKnowledgeMemoryConfigInput, resolveKnowledgeReadPolicy };
210
+ export { ContextCompactionPolicySchema, ContextPlanningConfigSchema, DEFAULT_CONTEXT_COMPACTION_POLICY, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config, resolveKnowledgeReadPolicy };
@@ -0,0 +1,7 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare function memoryFingerprint(parts: unknown[]): string;
3
+ export declare function isMemorySuppressed(db: DatabaseSync, fingerprints: string[]): boolean;
4
+ export declare function suppressMemory(db: DatabaseSync, fingerprints: string[], now: number): void;
5
+ export declare function restoreMemory(db: DatabaseSync, fingerprints: string[]): void;
6
+ /** Remove cached decisions containing deleted content; retain only unrelated audit rows. */
7
+ export declare function clearMemoryAudit(db: DatabaseSync, type: 'assertion' | 'knowledge', id: string): void;
@@ -0,0 +1,23 @@
1
+ import { createHash } from "node:crypto";
2
+ //#region src/user-context/memory-suppression.ts
3
+ function memoryFingerprint(parts) {
4
+ const normalized = parts.map((part) => typeof part === "string" ? part.normalize("NFKC").toLowerCase().replace(/\s+/g, " ").trim() : part);
5
+ return createHash("sha256").update(JSON.stringify(normalized)).digest("hex");
6
+ }
7
+ function isMemorySuppressed(db, fingerprints) {
8
+ return fingerprints.some((key) => db.prepare("SELECT 1 FROM memory_suppressions WHERE fingerprint = ?").get(key));
9
+ }
10
+ function suppressMemory(db, fingerprints, now) {
11
+ const insert = db.prepare("INSERT OR IGNORE INTO memory_suppressions (fingerprint, created_at) VALUES (?, ?)");
12
+ for (const key of fingerprints) insert.run(key, now);
13
+ }
14
+ function restoreMemory(db, fingerprints) {
15
+ for (const key of fingerprints) db.prepare("DELETE FROM memory_suppressions WHERE fingerprint = ?").run(key);
16
+ }
17
+ /** Remove cached decisions containing deleted content; retain only unrelated audit rows. */
18
+ function clearMemoryAudit(db, type, id) {
19
+ db.prepare("DELETE FROM memory_maintenance_decisions WHERE object_type = ? AND object_id = ?").run(type, id);
20
+ db.prepare("DELETE FROM execution_context_items WHERE object_type = ? AND object_id = ?").run(type, id);
21
+ }
22
+ //#endregion
23
+ export { clearMemoryAudit, isMemorySuppressed, memoryFingerprint, restoreMemory, suppressMemory };
@@ -62,7 +62,7 @@ function recordExplicitRelationshipFollowUp(input) {
62
62
  createdBy: "user",
63
63
  evidenceId: evidence.id,
64
64
  evidenceConfidence: 1
65
- }, now).assertion;
65
+ }, now, { restoreDeleted: true }).assertion ?? null;
66
66
  }
67
67
  //#endregion
68
68
  export { extractExplicitRelationshipFollowUp, recordExplicitRelationshipFollowUp };
@@ -0,0 +1,48 @@
1
+ import type { UnderstandingSourceGrant, UnderstandingSourceItem, UnderstandingSourceRun } from './types.js';
2
+ export type RefreshProgress = {
3
+ status: UnderstandingSourceRun['status'];
4
+ phase: 'queued' | 'waiting_desktop' | 'reading' | 'analyzing' | 'completed';
5
+ added?: number;
6
+ updated?: number;
7
+ itemsSeen?: number;
8
+ error?: string;
9
+ };
10
+ export type RefreshSourceRun = UnderstandingSourceRun & {
11
+ adapterId: string;
12
+ displayName: string;
13
+ };
14
+ export type RefreshBatch = {
15
+ id: string;
16
+ status: 'running' | 'completed' | 'partial' | 'failed';
17
+ sources: RefreshSourceRun[];
18
+ createdAt: number;
19
+ };
20
+ export interface UnderstandingRefreshDeps {
21
+ enabled(): boolean;
22
+ start(grant: UnderstandingSourceGrant, runId: string): Promise<Record<string, unknown>>;
23
+ progress(run: UnderstandingSourceRun): RefreshProgress | undefined;
24
+ analyzeDesktop(grant: UnderstandingSourceGrant, items: UnderstandingSourceItem[], signal: AbortSignal): Promise<{
25
+ added?: number;
26
+ updated?: number;
27
+ }>;
28
+ emit?(type: string, payload: unknown): void;
29
+ }
30
+ /** Coordinates existing source executors; the source run remains the authority for progress. */
31
+ export declare class UnderstandingRefreshService {
32
+ private readonly deps;
33
+ private readonly owner;
34
+ private readonly starting;
35
+ private readonly analyzing;
36
+ constructor(deps: UnderstandingRefreshDeps);
37
+ start(sourceIds?: string[]): RefreshBatch;
38
+ sources(): RefreshSourceRun[];
39
+ latest(): RefreshBatch | null;
40
+ get(id: string): RefreshBatch | null;
41
+ private update;
42
+ private reconcile;
43
+ private dispatch;
44
+ submitDesktop(runId: string, input: {
45
+ items: UnderstandingSourceItem[];
46
+ error?: string;
47
+ }): void;
48
+ }
@@ -0,0 +1,221 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
4
+ import { createUnderstandingSourceRun, getUnderstandingSourceGrant, getUnderstandingSourceRun, listUnderstandingSourceGrants, listUnderstandingSourceRuns, updateUnderstandingSourceRun } from "./repository.js";
5
+ import { randomUUID } from "node:crypto";
6
+ //#region src/user-context/sources/refresh-service.ts
7
+ init_transaction();
8
+ init_logger();
9
+ const log = createLogger("UnderstandingRefresh");
10
+ const ACTIVE = new Set(["queued", "running"]);
11
+ const DESKTOP_WAIT_MS = 12e4;
12
+ const ANALYSIS_TIMEOUT_MS = 18e4;
13
+ /** Coordinates existing source executors; the source run remains the authority for progress. */
14
+ var UnderstandingRefreshService = class {
15
+ owner = randomUUID();
16
+ starting = /* @__PURE__ */ new Set();
17
+ analyzing = /* @__PURE__ */ new Set();
18
+ constructor(deps) {
19
+ this.deps = deps;
20
+ }
21
+ start(sourceIds) {
22
+ if (!this.deps.enabled()) throw new Error("User understanding is disabled.");
23
+ const grants = listUnderstandingSourceGrants();
24
+ const selected = sourceIds === void 0 ? grants : [...new Set(sourceIds)].map((id) => {
25
+ const grant = grants.find((item) => item.id === id);
26
+ if (!grant) throw new Error("An authorized source was not found.");
27
+ return grant;
28
+ });
29
+ if (!selected.length || selected.length > 100) throw new Error("Select between 1 and 100 authorized sources.");
30
+ const id = randomUUID();
31
+ const createdAt = Date.now();
32
+ const runs = runSqliteWriteTransaction((db) => {
33
+ const runs = selected.map((grant) => {
34
+ return listUnderstandingSourceRuns(grant.id, 100).find((run) => run.metadata.refresh === true && ACTIVE.has(this.reconcile(run).status)) ?? createUnderstandingSourceRun({
35
+ grantId: grant.id,
36
+ kind: "incremental",
37
+ status: "queued",
38
+ metadata: {
39
+ refresh: true,
40
+ owner: this.owner,
41
+ phase: "queued",
42
+ adapterId: grant.adapterId,
43
+ displayName: grant.displayName,
44
+ processingPolicy: grant.processingPolicy
45
+ }
46
+ });
47
+ });
48
+ db.prepare("INSERT INTO understanding_refresh_batches (batch_id, source_run_ids_json, created_at) VALUES (?, ?, ?)").run(id, JSON.stringify(runs.map((run) => run.id)), createdAt);
49
+ return runs;
50
+ });
51
+ for (const run of runs) if (run.status === "queued" && !this.starting.has(run.id)) this.dispatch(run);
52
+ return this.get(id);
53
+ }
54
+ sources() {
55
+ return listUnderstandingSourceGrants().flatMap((grant) => {
56
+ const saved = listUnderstandingSourceRuns(grant.id, 100).find((run) => run.metadata.refresh === true);
57
+ if (!saved) return [];
58
+ return [{
59
+ ...this.reconcile(saved),
60
+ adapterId: grant.adapterId,
61
+ displayName: grant.displayName
62
+ }];
63
+ });
64
+ }
65
+ latest() {
66
+ const row = getSqliteDatabase().prepare("SELECT batch_id FROM understanding_refresh_batches ORDER BY created_at DESC, rowid DESC LIMIT 1").get();
67
+ return row ? this.get(row.batch_id) : null;
68
+ }
69
+ get(id) {
70
+ const row = getSqliteDatabase().prepare("SELECT * FROM understanding_refresh_batches WHERE batch_id = ?").get(id);
71
+ if (!row) return null;
72
+ const sources = JSON.parse(row.source_run_ids_json).flatMap((runId) => {
73
+ const saved = getUnderstandingSourceRun(runId);
74
+ if (!saved) return [];
75
+ const run = this.reconcile(saved);
76
+ return [{
77
+ ...run,
78
+ adapterId: String(run.metadata.adapterId),
79
+ displayName: String(run.metadata.displayName)
80
+ }];
81
+ });
82
+ const completed = sources.filter((run) => run.status === "completed").length;
83
+ return {
84
+ id,
85
+ status: sources.some((run) => ACTIVE.has(run.status)) ? "running" : completed === sources.length && completed > 0 ? "completed" : completed || sources.some((run) => run.status === "partial") ? "partial" : "failed",
86
+ sources,
87
+ createdAt: row.created_at
88
+ };
89
+ }
90
+ update(run, progress) {
91
+ const next = updateUnderstandingSourceRun(run.id, {
92
+ status: progress.status,
93
+ itemsSeen: progress.itemsSeen,
94
+ ...progress.error ? { errorMessage: progress.error } : {},
95
+ completed: !ACTIVE.has(progress.status),
96
+ metadata: {
97
+ ...run.metadata,
98
+ phase: progress.phase,
99
+ ...progress.added === void 0 ? {} : { added: progress.added },
100
+ ...progress.updated === void 0 ? {} : { updated: progress.updated }
101
+ }
102
+ });
103
+ this.deps.emit?.("understanding.refresh.updated", {
104
+ runId: run.id,
105
+ grantId: run.grantId
106
+ });
107
+ return next;
108
+ }
109
+ reconcile(run) {
110
+ if (!ACTIVE.has(run.status)) return run;
111
+ const grant = getUnderstandingSourceGrant(run.grantId);
112
+ if (!grant || grant.status !== "active" || grant.processingPolicy !== run.metadata.processingPolicy || !this.deps.enabled()) return this.update(run, {
113
+ status: "canceled",
114
+ phase: "completed",
115
+ error: "Source authorization changed. Retry after reviewing its settings."
116
+ });
117
+ const progress = this.deps.progress(run);
118
+ if (progress) {
119
+ if (progress.status !== run.status || progress.phase !== run.metadata.phase || progress.added !== run.metadata.added || progress.updated !== run.metadata.updated || progress.itemsSeen !== void 0 && progress.itemsSeen !== run.itemsSeen) return this.update(run, progress);
120
+ return run;
121
+ }
122
+ if (run.metadata.owner !== this.owner) return this.update(run, {
123
+ status: "failed",
124
+ phase: "completed",
125
+ error: "Update was interrupted. Please retry."
126
+ });
127
+ if (run.metadata.phase === "waiting_desktop" && Date.now() - run.startedAt > DESKTOP_WAIT_MS) return this.update(run, {
128
+ status: "failed",
129
+ phase: "completed",
130
+ error: "Desktop collection did not finish. Open the desktop app and retry."
131
+ });
132
+ return run;
133
+ }
134
+ async dispatch(run) {
135
+ this.starting.add(run.id);
136
+ try {
137
+ const grant = getUnderstandingSourceGrant(run.grantId);
138
+ this.update(run, {
139
+ status: "running",
140
+ phase: "reading"
141
+ });
142
+ const metadata = await this.deps.start(grant, run.id);
143
+ const latest = getUnderstandingSourceRun(run.id);
144
+ updateUnderstandingSourceRun(run.id, { metadata: {
145
+ ...latest.metadata,
146
+ ...metadata
147
+ } });
148
+ this.reconcile(getUnderstandingSourceRun(run.id));
149
+ } catch (err) {
150
+ log.warn({
151
+ err,
152
+ runId: run.id,
153
+ grantId: run.grantId
154
+ }, "Understanding refresh could not start");
155
+ this.update(getUnderstandingSourceRun(run.id), {
156
+ status: "failed",
157
+ phase: "completed",
158
+ error: err instanceof Error ? err.message : String(err)
159
+ });
160
+ } finally {
161
+ this.starting.delete(run.id);
162
+ }
163
+ }
164
+ submitDesktop(runId, input) {
165
+ const saved = getUnderstandingSourceRun(runId);
166
+ const run = saved ? this.reconcile(saved) : null;
167
+ if (!run || run.metadata.refresh !== true) throw new Error("Refresh run not found.");
168
+ if (this.analyzing.has(runId) || !ACTIVE.has(run.status)) return;
169
+ if (run.metadata.phase !== "waiting_desktop") throw new Error("This run is not waiting for desktop collection.");
170
+ const grant = getUnderstandingSourceGrant(run.grantId);
171
+ if (input.items.length > 1200 || input.items.some((item) => item.sourceId !== grant.adapterId)) throw new Error("Collected items must belong to the requested source.");
172
+ if (input.error) {
173
+ this.update(run, {
174
+ status: "failed",
175
+ phase: "completed",
176
+ error: input.error.slice(0, 500)
177
+ });
178
+ return;
179
+ }
180
+ if (!input.items.length) {
181
+ this.update(run, {
182
+ status: "completed",
183
+ phase: "completed",
184
+ added: 0,
185
+ updated: 0,
186
+ itemsSeen: 0
187
+ });
188
+ return;
189
+ }
190
+ this.analyzing.add(runId);
191
+ this.update(run, {
192
+ status: "running",
193
+ phase: "analyzing",
194
+ itemsSeen: input.items.length
195
+ });
196
+ const signal = AbortSignal.timeout(ANALYSIS_TIMEOUT_MS);
197
+ this.deps.analyzeDesktop(grant, input.items, signal).then((result) => {
198
+ signal.throwIfAborted();
199
+ const current = this.reconcile(getUnderstandingSourceRun(runId));
200
+ if (ACTIVE.has(current.status)) this.update(current, {
201
+ status: "completed",
202
+ phase: "completed",
203
+ ...result
204
+ });
205
+ }).catch((err) => {
206
+ log.warn({
207
+ err,
208
+ runId,
209
+ grantId: grant.id
210
+ }, "Understanding refresh analysis failed");
211
+ const current = getUnderstandingSourceRun(runId);
212
+ if (ACTIVE.has(current.status)) this.update(current, {
213
+ status: "failed",
214
+ phase: "completed",
215
+ error: "Analysis failed. Please retry."
216
+ });
217
+ }).finally(() => this.analyzing.delete(runId));
218
+ }
219
+ };
220
+ //#endregion
221
+ export { UnderstandingRefreshService };
@@ -114,7 +114,7 @@ function getUnderstandingSourceRun(id) {
114
114
  return row ? runFromRow(row) : null;
115
115
  }
116
116
  function listUnderstandingSourceRuns(grantId, limit = 20) {
117
- return getSqliteDatabase().prepare("SELECT * FROM understanding_source_runs WHERE grant_id = ? ORDER BY started_at DESC LIMIT ?").all(grantId, Math.max(1, Math.min(100, limit))).map(runFromRow);
117
+ return getSqliteDatabase().prepare("SELECT * FROM understanding_source_runs WHERE grant_id = ? ORDER BY started_at DESC, rowid DESC LIMIT ?").all(grantId, Math.max(1, Math.min(100, limit))).map(runFromRow);
118
118
  }
119
119
  function updateUnderstandingSourceRun(id, patch) {
120
120
  const current = getUnderstandingSourceRun(id);
@@ -8,30 +8,33 @@ function statements(values, limit) {
8
8
  }
9
9
  function addExplicitAssertions(values, input, now) {
10
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;
11
+ for (const statement of values) {
12
+ const result = reconcileAssertion({
13
+ subject: {
14
+ type: "user",
15
+ id: "self"
16
+ },
17
+ predicate: input.predicate,
18
+ cardinality: "multiple",
19
+ scope: { type: "global" },
20
+ kind: input.kind,
21
+ value: statement,
22
+ normalizedValue: statement.toLocaleLowerCase(),
23
+ statement,
24
+ authority: "user_explicit",
25
+ confidence: 1,
26
+ declaredImportance: input.importance,
27
+ inferredImportance: input.importance,
28
+ consequence: "medium",
29
+ actionability: .8,
30
+ volatility: "slow",
31
+ sensitivity: input.kind === "relationship" ? "personal" : "normal",
32
+ disclosurePolicy: "referenceable",
33
+ observedAt: now,
34
+ createdBy: "user"
35
+ }, now, { restoreDeleted: true });
36
+ if (result.assertion && result.action !== "deduplicated") created += 1;
37
+ }
35
38
  return created;
36
39
  }
37
40
  function addRules(category, values) {
@@ -1,7 +1,7 @@
1
1
  import type { AssertionStatus } from '../domain.js';
2
2
  import type { CaptureEvidence, UserModelInterpretation } from './semantic.js';
3
3
  export interface UserModelCapturePolicy {
4
- write: 'deny' | 'confirm' | 'allow';
4
+ write: 'deny' | 'allow';
5
5
  sensitiveWrite: 'deny' | 'confirm' | 'allow';
6
6
  processing: 'local_only' | 'remote_allowed';
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import { createCollaborationRule, listCollaborationRules } from "../../storage/sqlite/collaboration-rule-repository.js";
2
2
  import { createContextEvidence } from "../../storage/sqlite/context-evidence-repository.js";
3
3
  import { createUserGoal, listUserGoals } from "../goals.js";
4
- import { getUserAssertion, linkAssertionEvidence, reconcileAssertion, setAssertionStatus } from "../repository.js";
4
+ import { deleteUserAssertion, getUserAssertion, linkAssertionEvidence, reconcileAssertion, setAssertionStatus } from "../repository.js";
5
5
  import { createHash } from "node:crypto";
6
6
  //#region src/user-model/capture/executor.ts
7
7
  function emptyUserModelCaptureResult() {
@@ -33,10 +33,7 @@ function executeUserModelInterpretation(input) {
33
33
  const targets = input.interpretation.targetAssertionIds.flatMap((id) => getUserAssertion(id) ?? []);
34
34
  if (input.interpretation.intent === "forget") {
35
35
  for (const target of targets) {
36
- setAssertionStatus(target.id, "rejected", {
37
- actor: "user",
38
- reason: "Explicit user forget request."
39
- });
36
+ deleteUserAssertion(target.id);
40
37
  result.outputs.push({
41
38
  candidateKey: target.id,
42
39
  assertionId: target.id,
@@ -100,12 +97,13 @@ function executeUserModelInterpretation(input) {
100
97
  });
101
98
  evidenceIds.set(ref, evidence.id);
102
99
  }
100
+ const latestUserRef = input.evidence.filter((item) => item.role === "user").sort((a, b) => b.createdAt - a.createdAt)[0]?.ref;
103
101
  const explicitCommand = input.interpretation.intent === "remember" || input.interpretation.intent === "correct";
104
102
  for (const source of input.interpretation.candidates) {
105
103
  result.proposed += 1;
106
104
  const key = candidateKey(source.predicate, source.scope.type, source.scope.id);
107
- const sensitive = source.sensitivity === "secret" || source.sensitivity === "regulated";
108
- if (input.policy.write === "deny" || sensitive && input.policy.sensitiveWrite === "deny" || !scopeAllowed(source.scope.type, source.scope.id, input.scopeContext)) {
105
+ const sensitive = source.sensitivity !== "normal";
106
+ if (input.policy.write === "deny" || sensitive && (source.authority !== "user_explicit" || input.policy.sensitiveWrite === "deny") || !scopeAllowed(source.scope.type, source.scope.id, input.scopeContext)) {
109
107
  result.rejected += 1;
110
108
  result.outputs.push({
111
109
  candidateKey: key,
@@ -113,7 +111,7 @@ function executeUserModelInterpretation(input) {
113
111
  });
114
112
  continue;
115
113
  }
116
- const requiresConfirmation = !explicitCommand && (input.policy.write === "confirm" || sensitive && input.policy.sensitiveWrite === "confirm");
114
+ const requiresConfirmation = !explicitCommand && sensitive && input.policy.sensitiveWrite === "confirm";
117
115
  const refs = source.evidenceRefs.flatMap((ref) => evidenceIds.get(ref) ?? []);
118
116
  const applied = reconcileAssertion({
119
117
  ...source,
@@ -123,7 +121,15 @@ function executeUserModelInterpretation(input) {
123
121
  evidenceId: refs[0],
124
122
  evidenceConfidence: source.confidence
125
123
  } : {}
126
- });
124
+ }, Date.now(), { restoreDeleted: explicitCommand && source.evidenceRefs.includes(latestUserRef) });
125
+ if (applied.action === "suppressed") {
126
+ result.rejected += 1;
127
+ result.outputs.push({
128
+ candidateKey: key,
129
+ outcome: "rejected"
130
+ });
131
+ continue;
132
+ }
127
133
  for (const evidenceId of refs.slice(1)) linkAssertionEvidence(applied.assertion.id, evidenceId, "supports", source.confidence);
128
134
  result.createdAssertions.push({
129
135
  id: applied.assertion.id,
@@ -158,7 +164,7 @@ function executeUserModelInterpretation(input) {
158
164
  });
159
165
  continue;
160
166
  }
161
- const active = explicitCommand || input.policy.write === "allow";
167
+ const active = explicitCommand;
162
168
  const goal = createUserGoal({
163
169
  title: source.title,
164
170
  desiredOutcome: source.desiredOutcome,
@@ -200,7 +206,7 @@ function executeUserModelInterpretation(input) {
200
206
  });
201
207
  continue;
202
208
  }
203
- const active = explicitCommand || input.policy.write === "allow";
209
+ const active = explicitCommand;
204
210
  const rule = createCollaborationRule({
205
211
  category: source.category,
206
212
  priority: source.priority,
@@ -153,7 +153,7 @@ function comparable(value) {
153
153
  return value.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
154
154
  }
155
155
  function effectiveAuthority(intent, authority) {
156
- if (intent === "remember" || intent === "correct" || intent === "confirm") return authority;
156
+ if (intent === "remember" || intent === "correct" || intent === "confirm" || intent === "user_assertion") return authority;
157
157
  return authority === "user_explicit" ? "user_observed" : authority;
158
158
  }
159
159
  function parseTime(value) {
@@ -84,10 +84,14 @@ export interface AssertionCandidate {
84
84
  correctionOfAssertionId?: string;
85
85
  }
86
86
  export type ReconciliationAction = 'created' | 'deduplicated' | 'superseded' | 'conflicted';
87
- export interface ReconciliationResult {
87
+ export type ReconciliationResult = {
88
88
  action: ReconciliationAction;
89
89
  assertion: UserAssertion;
90
90
  previousAssertion?: UserAssertion;
91
- }
91
+ } | {
92
+ action: 'suppressed';
93
+ assertion?: undefined;
94
+ previousAssertion?: undefined;
95
+ };
92
96
  export declare function validateScope(scope: UserModelScope): void;
93
97
  export declare function validateCandidate(candidate: AssertionCandidate): void;
@@ -2,8 +2,8 @@ import { USER_MODEL_PRINCIPAL_ID, validateCandidate, validateScope } from "./dom
2
2
  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
- import { getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, linkAssertionEvidence, listSlotAssertions, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus } from "./repository.js";
5
+ import { deleteUserAssertion, getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, linkAssertionEvidence, listSlotAssertions, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus } from "./repository.js";
6
6
  import { applyUserProfilePatch, getUserProfileSnapshot } from "./profile.js";
7
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, listUserAssertionSources, listUserAssertions, listUserGoals, reconcileAssertion, requiresBoundedValidity, resolveCurrentAssertion, setAssertionStatus, setUserGoalStatus, validateCandidate, validateScope };
8
+ import { canUseAssertion, isWorkingAssumption } from "./usage-policy.js";
9
+ export { USER_MODEL_PRINCIPAL_ID, applyUserProfilePatch, bootstrapUserModel, calculateExecutionValue, canUseAssertion, createPriorityWindow, createUserGoal, defaultReviewAt, deleteUserAssertion, getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserProfileSnapshot, getUserTimezone, isAssertionValidAt, isWorkingAssumption, linkAssertionEvidence, listPriorityWindows, listSlotAssertions, listUserAssertionSources, listUserAssertions, listUserGoals, reconcileAssertion, requiresBoundedValidity, resolveCurrentAssertion, setAssertionStatus, setUserGoalStatus, validateCandidate, validateScope };
@@ -90,7 +90,7 @@ function applyUserProfilePatch(input, now = Date.now()) {
90
90
  observedAt: now,
91
91
  createdBy: "user",
92
92
  ...current ? { correctionOfAssertionId: current.id } : {}
93
- }, now);
93
+ }, now, { restoreDeleted: true });
94
94
  }
95
95
  return getUserProfileSnapshot();
96
96
  }
@@ -6,7 +6,9 @@ export type UserAssertionSource = {
6
6
  category?: 'files' | 'recent_documents' | 'calendar' | 'tasks' | 'notes' | 'mail' | 'messages' | 'code_activity';
7
7
  observedAt: number;
8
8
  };
9
- export declare function reconcileAssertion(candidate: AssertionCandidate, now?: number): ReconciliationResult;
9
+ export declare function reconcileAssertion(candidate: AssertionCandidate, now?: number, options?: {
10
+ restoreDeleted?: boolean;
11
+ }): ReconciliationResult;
10
12
  export declare function getUserAssertion(id: string): UserAssertion | undefined;
11
13
  export declare function getAssertionSlot(id: string): AssertionSlot | undefined;
12
14
  export declare function listSlotAssertions(slotId: string): UserAssertion[];
@@ -29,3 +31,4 @@ export declare function setAssertionStatus(assertionId: string, status: Assertio
29
31
  reason: string;
30
32
  now?: number;
31
33
  }): UserAssertion;
34
+ export declare function deleteUserAssertion(id: string, now?: number): boolean;