@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
@@ -1,5 +1,6 @@
1
1
  import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
2
2
  import { USER_MODEL_PRINCIPAL_ID, validateCandidate, validateScope } from "./domain.js";
3
+ import { clearMemoryAudit, isMemorySuppressed, memoryFingerprint, restoreMemory, suppressMemory } from "../user-context/memory-suppression.js";
3
4
  import { defaultReviewAt, requiresBoundedValidity } from "./temporal.js";
4
5
  import { basename } from "node:path";
5
6
  import { randomUUID } from "node:crypto";
@@ -136,9 +137,13 @@ function authorityRank(authority) {
136
137
  user_explicit: 3
137
138
  }[authority];
138
139
  }
139
- function reconcileAssertion(candidate, now = Date.now()) {
140
+ function reconcileAssertion(candidate, now = Date.now(), options = {}) {
140
141
  validateCandidate(candidate);
141
142
  return runSqliteWriteTransaction((db) => {
143
+ if (candidate.authority !== "user_explicit" && candidate.sensitivity !== "normal") return { action: "suppressed" };
144
+ const keys = assertionFingerprints(candidate);
145
+ if (options.restoreDeleted && candidate.authority === "user_explicit") restoreMemory(db, keys);
146
+ if (isMemorySuppressed(db, keys)) return { action: "suppressed" };
142
147
  const slot = findOrCreateSlot(db, candidate, now);
143
148
  const existing = listReconcilableAssertions(db, slot.id);
144
149
  if (candidate.correctionOfAssertionId) {
@@ -146,14 +151,21 @@ function reconcileAssertion(candidate, now = Date.now()) {
146
151
  const target = existing.find((item) => item.id === candidate.correctionOfAssertionId);
147
152
  if (!target) throw new Error("Correction target does not belong to the resolved assertion slot.");
148
153
  if (target.normalizedValue === candidate.normalizedValue.trim()) {
154
+ db.prepare("UPDATE user_assertions SET statement = ?, authority = 'user_explicit', confidence = 1, status = 'active', observed_at = ?, review_at = ? WHERE assertion_id = ?").run(candidate.statement.trim(), candidate.observedAt, defaultReviewAt(candidate.volatility, candidate.observedAt) ?? null, target.id);
155
+ db.prepare("UPDATE user_assertions_fts SET statement = ? WHERE assertion_id = ?").run(candidate.statement.trim(), target.id);
149
156
  attachEvidence(db, target.id, candidate, now);
150
157
  return {
151
158
  action: "deduplicated",
152
- assertion: target
159
+ assertion: getUserAssertion(target.id)
153
160
  };
154
161
  }
162
+ if (slot.cardinality === "multiple") suppressMemory(db, assertionFingerprints({
163
+ ...target,
164
+ ...slot
165
+ }), now);
155
166
  const assertion = insertAssertion(db, slot.id, candidate, "active", now, target.id);
156
- closeValidity(db, target, candidate.validFrom ?? candidate.observedAt, now);
167
+ closeValidity(db, target, candidate.observedAt, now);
168
+ updateStatus(db, target, "archived", "Replaced by user correction.", now);
157
169
  return {
158
170
  action: "superseded",
159
171
  assertion,
@@ -163,10 +175,12 @@ function reconcileAssertion(candidate, now = Date.now()) {
163
175
  const overlapping = sortByAuthorityAndRecorded(existing.filter((item) => intervalsOverlap(item, candidate)));
164
176
  const duplicate = overlapping.find((item) => item.normalizedValue === candidate.normalizedValue.trim());
165
177
  if (duplicate) {
178
+ refreshSupportingObservation(db, duplicate, candidate, now);
179
+ if (candidate.authority === "user_explicit" && (duplicate.authority !== "user_explicit" || candidate.observedAt > duplicate.observedAt)) db.prepare("UPDATE user_assertions SET authority = 'user_explicit', confidence = ?, status = ?, observed_at = ?, review_at = ? WHERE assertion_id = ?").run(candidate.confidence, initialStatus(candidate), candidate.observedAt, candidate.reviewAt ?? defaultReviewAt(candidate.volatility, candidate.observedAt) ?? null, duplicate.id);
166
180
  attachEvidence(db, duplicate.id, candidate, now);
167
181
  return {
168
182
  action: "deduplicated",
169
- assertion: duplicate
183
+ assertion: getUserAssertion(duplicate.id)
170
184
  };
171
185
  }
172
186
  const status = initialStatus(candidate);
@@ -345,13 +359,89 @@ function linkAssertionEvidence(assertionId, evidenceId, relation, confidence, no
345
359
  function setAssertionStatus(assertionId, status, input) {
346
360
  const current = getUserAssertion(assertionId);
347
361
  if (!current) throw new Error(`User assertion not found: ${assertionId}`);
348
- if (current.status === status) return current;
362
+ if (current.status === status && !(status === "active" && input.actor === "user" && current.authority !== "user_explicit")) return current;
349
363
  const now = input.now ?? Date.now();
350
364
  runSqliteWriteTransaction((db) => {
351
365
  db.prepare("UPDATE user_assertions SET status = ? WHERE assertion_id = ?").run(status, assertionId);
366
+ if ((status === "rejected" || status === "archived") && input.actor === "user") {
367
+ const slot = getAssertionSlot(current.slotId);
368
+ suppressMemory(db, assertionFingerprints({
369
+ ...current,
370
+ ...slot
371
+ }), now);
372
+ }
373
+ if (status === "active" && input.actor === "user") db.prepare("UPDATE user_assertions SET authority = 'user_explicit', confidence = 1 WHERE assertion_id = ?").run(assertionId);
352
374
  recordStatusEvent(db, assertionId, current.status, status, input.actor, input.reason, now);
353
375
  });
354
376
  return getUserAssertion(assertionId);
355
377
  }
378
+ function assertionFingerprints(candidate) {
379
+ const scope = [
380
+ candidate.principalId ?? "local-owner",
381
+ candidate.scope.type,
382
+ candidate.scope.id ?? ""
383
+ ];
384
+ return [memoryFingerprint([
385
+ "assertion-slot",
386
+ ...scope,
387
+ candidate.subject.type,
388
+ candidate.subject.id,
389
+ candidate.predicate,
390
+ candidate.cardinality === "single" ? "" : candidate.normalizedValue
391
+ ]), memoryFingerprint([
392
+ "assertion-content",
393
+ ...scope,
394
+ candidate.statement
395
+ ])];
396
+ }
397
+ function deleteUserAssertion(id, now = Date.now()) {
398
+ return runSqliteWriteTransaction((db) => {
399
+ const current = getUserAssertion(id);
400
+ if (!current) return false;
401
+ const slot = getAssertionSlot(current.slotId);
402
+ const rows = db.prepare(`WITH RECURSIVE versions(id) AS (
403
+ SELECT ? UNION SELECT a.assertion_id FROM user_assertions a JOIN versions v
404
+ ON a.supersedes_assertion_id = v.id OR a.assertion_id = (
405
+ SELECT supersedes_assertion_id FROM user_assertions WHERE assertion_id = v.id)
406
+ ) SELECT * FROM user_assertions WHERE assertion_id IN (SELECT id FROM versions)
407
+ OR (? = 'single' AND slot_id = ?)`).all(id, slot.cardinality, slot.id);
408
+ const evidenceIds = new Set(rows.flatMap((row) => db.prepare("SELECT evidence_id FROM user_assertion_evidence WHERE assertion_id = ?").all(row.assertion_id).map((evidence) => evidence.evidence_id)));
409
+ for (const row of rows) {
410
+ const assertion = assertionFromRow(row);
411
+ suppressMemory(db, assertionFingerprints({
412
+ ...assertion,
413
+ ...slot,
414
+ principalId: slot.principalId
415
+ }), now);
416
+ clearMemoryAudit(db, "assertion", assertion.id);
417
+ db.prepare("DELETE FROM user_assertions_fts WHERE assertion_id = ?").run(assertion.id);
418
+ db.prepare(`UPDATE work_discovery_runs SET result_json = json_set(result_json, '$.profileCandidates',
419
+ json((SELECT COALESCE(json_group_array(json(value)), '[]')
420
+ FROM json_each(result_json, '$.profileCandidates')
421
+ WHERE COALESCE(json_extract(value, '$.assertionId'), '') != ?)))
422
+ WHERE EXISTS (SELECT 1 FROM json_each(result_json, '$.profileCandidates')
423
+ WHERE json_extract(value, '$.assertionId') = ?)`).run(assertion.id, assertion.id);
424
+ }
425
+ for (const row of rows) db.prepare("DELETE FROM user_assertions WHERE assertion_id = ?").run(row.assertion_id);
426
+ for (const evidenceId of evidenceIds) db.prepare(`UPDATE context_evidence SET redacted_excerpt = NULL WHERE evidence_id = ?
427
+ AND NOT EXISTS (SELECT 1 FROM user_assertion_evidence WHERE evidence_id = ?)`).run(evidenceId, evidenceId);
428
+ db.prepare(`DELETE FROM user_assertion_slots WHERE slot_id = ?
429
+ AND NOT EXISTS (SELECT 1 FROM user_assertions WHERE slot_id = ?)`).run(slot.id, slot.id);
430
+ return true;
431
+ });
432
+ }
433
+ function refreshSupportingObservation(db, current, candidate, now) {
434
+ if (!candidate.evidenceId || current.authority === "user_explicit" || ![
435
+ "active",
436
+ "candidate",
437
+ "stale"
438
+ ].includes(current.status)) return;
439
+ const evidence = db.prepare(`SELECT observed_at FROM context_evidence WHERE evidence_id = ?
440
+ AND trust_level = 'owner' AND source_type IN ('conversation', 'user', 'connector')`).get(candidate.evidenceId);
441
+ if (!evidence || evidence.observed_at <= current.observedAt || evidence.observed_at > now || candidate.confidence < .7) return;
442
+ const reviewAt = defaultReviewAt(current.volatility, evidence.observed_at);
443
+ db.prepare(`UPDATE user_assertions SET observed_at = ?, review_at = ? WHERE assertion_id = ?`).run(evidence.observed_at, reviewAt ?? null, current.id);
444
+ if (current.status === "stale" && (current.validTo === void 0 || current.validTo >= now)) updateStatus(db, current, "candidate", "Fresh source evidence supports this understanding.", now);
445
+ }
356
446
  //#endregion
357
- export { getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, linkAssertionEvidence, listSlotAssertions, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus };
447
+ export { deleteUserAssertion, getActiveAssertionByPredicate, getActiveAssertionForSlot, getAssertionSlot, getUserAssertion, getUserTimezone, linkAssertionEvidence, listSlotAssertions, listUserAssertionSources, listUserAssertions, reconcileAssertion, setAssertionStatus };
@@ -1,2 +1,4 @@
1
1
  import type { UserAssertion } from './domain.js';
2
+ /** Automatic personalization never grants execution authority. */
2
3
  export declare function isWorkingAssumption(assertion: UserAssertion): boolean;
4
+ export declare function canUseAssertion(assertion: UserAssertion, asOf?: number): boolean;
@@ -1,6 +1,10 @@
1
1
  //#region src/user-model/usage-policy.ts
2
+ /** Automatic personalization never grants execution authority. */
2
3
  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
+ return (assertion.status === "candidate" || assertion.status === "active") && (assertion.authority === "user_observed" || assertion.authority === "system_inferred") && assertion.confidence >= .7 && (assertion.consequence === "low" || assertion.consequence === "medium") && assertion.sensitivity === "normal" && assertion.disclosurePolicy !== "ask_before_reference";
5
+ }
6
+ function canUseAssertion(assertion, asOf = Date.now()) {
7
+ return (assertion.validFrom === void 0 || assertion.validFrom <= asOf) && (assertion.validTo === void 0 || assertion.validTo >= asOf) && (assertion.reviewAt === void 0 || assertion.reviewAt > asOf) && assertion.sensitivity !== "secret" && assertion.sensitivity !== "regulated" && assertion.disclosurePolicy !== "ask_before_reference" && (assertion.status === "active" && assertion.authority === "user_explicit" || isWorkingAssumption(assertion));
4
8
  }
5
9
  //#endregion
6
- export { isWorkingAssumption };
10
+ export { canUseAssertion, isWorkingAssumption };
@@ -31,7 +31,8 @@ function saveProjectUnderstandingOverview(input) {
31
31
  provider: "project-understanding",
32
32
  evidenceRefs: input.evidenceRefs ?? []
33
33
  },
34
- replaceExisting: true
34
+ replaceExisting: true,
35
+ restoreDeleted: input.correctedByUser
35
36
  }).item;
36
37
  }
37
38
  //#endregion
@@ -62,7 +62,14 @@ export declare class WorkDiscoveryService {
62
62
  reused?: undefined;
63
63
  }>;
64
64
  revokeDirectorySource(id: string): import("./types.js").WorkDiscoveryDirectorySource;
65
- importUnderstandingSources(rawItems: unknown[], processingPolicy: ModelProcessingPolicy, signal?: AbortSignal, runId?: string, rawCheckpoints?: Record<string, unknown>): Promise<{
65
+ importUnderstandingSources(rawItems: unknown[], processingPolicy: ModelProcessingPolicy, signal?: AbortSignal, runId?: string, rawCheckpoints?: Record<string, unknown>, refresh?: {
66
+ grantId: string;
67
+ }): Promise<{
68
+ profileCandidates: any[];
69
+ workThreads: import("./types.js").WorkUnderstandingThread[];
70
+ knowledgeCandidates: import("../knowledge-memory/domain.js").KnowledgeItem[];
71
+ sourceStatuses: import("./analyzer.js").UnderstandingSourceAnalysisStatus[];
72
+ } | {
66
73
  profileCandidates: any[];
67
74
  workThreads: any[];
68
75
  knowledgeCandidates: any[];
@@ -70,21 +77,6 @@ export declare class WorkDiscoveryService {
70
77
  sourceId: string;
71
78
  status: "completed";
72
79
  }[];
73
- } | {
74
- profileCandidates: {
75
- status: "pending" | "rejected";
76
- assertionId: string;
77
- id: string;
78
- category: "role" | "responsibility" | "preference" | "routine" | "communication" | "boundary" | "relationship";
79
- factKey: string;
80
- statement: string;
81
- confidence: "high" | "medium" | "low";
82
- evidence: string[];
83
- evidenceRefs?: string[];
84
- }[];
85
- workThreads: import("./types.js").WorkUnderstandingThread[];
86
- knowledgeCandidates: import("../knowledge-memory/domain.js").KnowledgeItem[];
87
- sourceStatuses: import("./analyzer.js").UnderstandingSourceAnalysisStatus[];
88
80
  }>;
89
81
  rescanDirectorySource(input: {
90
82
  id: string;
@@ -103,14 +95,6 @@ export declare class WorkDiscoveryService {
103
95
  private publish;
104
96
  private execute;
105
97
  private persistProfileCandidates;
106
- updateProfileCandidates(input: {
107
- runId: string;
108
- decisions: Array<{
109
- id: string;
110
- status: 'accepted' | 'edited' | 'rejected';
111
- statement?: string;
112
- }>;
113
- }): WorkDiscoveryRun | null;
114
98
  cancelRun(id: string): WorkDiscoveryRun | null;
115
99
  retryRun(id: string): WorkDiscoveryRun | null;
116
100
  submitRecognitionFeedback(input: {