@remnic/core 9.3.723 → 9.3.725

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 (270) hide show
  1. package/dist/access-boundary.d.ts +6 -11
  2. package/dist/access-boundary.js +9 -9
  3. package/dist/access-cli.js +29 -23
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +5 -5
  6. package/dist/access-http.js +19 -14
  7. package/dist/access-mcp.d.ts +5 -5
  8. package/dist/access-mcp.js +18 -13
  9. package/dist/access-operations-batch.js +16 -10
  10. package/dist/access-operations.d.ts +5 -5
  11. package/dist/access-operations.js +17 -11
  12. package/dist/{access-service-Dj3I-VBS.d.ts → access-service-B2PlPtxh.d.ts} +3 -3
  13. package/dist/access-service.d.ts +5 -5
  14. package/dist/access-service.js +8 -8
  15. package/dist/access-surface-catalog.d.ts +5 -5
  16. package/dist/access-surface-catalog.js +82 -82
  17. package/dist/access-surface-catalog.js.map +1 -1
  18. package/dist/action-confidence.d.ts +1 -1
  19. package/dist/active-memory-bridge.d.ts +1 -1
  20. package/dist/active-recall.d.ts +1 -1
  21. package/dist/behavior-learner.d.ts +1 -1
  22. package/dist/behavior-signals.d.ts +1 -1
  23. package/dist/bootstrap.d.ts +4 -4
  24. package/dist/briefing.d.ts +1 -1
  25. package/dist/briefing.js +3 -3
  26. package/dist/buffer-surprise-report.d.ts +1 -1
  27. package/dist/buffer.d.ts +1 -1
  28. package/dist/calibration.d.ts +1 -1
  29. package/dist/capabilities.d.ts +1 -1
  30. package/dist/{catalog-F-OEVbRQ.d.ts → catalog-CzUb-GyD.d.ts} +1 -1
  31. package/dist/causal-behavior.d.ts +1 -1
  32. package/dist/causal-consolidation.d.ts +1 -1
  33. package/dist/causal-consolidation.js +4 -4
  34. package/dist/causal-trajectory-graph.d.ts +1 -1
  35. package/dist/{chunk-EVPNWN7Z.js → chunk-4R3CGCI5.js} +2 -2
  36. package/dist/{chunk-UO5ZHIIH.js → chunk-4WZ3J7M6.js} +2 -2
  37. package/dist/{chunk-PD42EYQN.js → chunk-5OPYYPJN.js} +2 -2
  38. package/dist/{chunk-EEJMD2L2.js → chunk-6CWGS2LY.js} +2 -2
  39. package/dist/{chunk-7CTNUVHZ.js → chunk-6SQQOJ4U.js} +2 -2
  40. package/dist/{chunk-ILFSEIRT.js → chunk-7AG54AF3.js} +1 -1
  41. package/dist/{chunk-ILFSEIRT.js.map → chunk-7AG54AF3.js.map} +1 -1
  42. package/dist/{chunk-UIXXE6NI.js → chunk-C6BWLYW5.js} +24 -15
  43. package/dist/chunk-C6BWLYW5.js.map +1 -0
  44. package/dist/{chunk-A5XNBK2D.js → chunk-DF3I6JGP.js} +6 -6
  45. package/dist/{chunk-GJSL4WG2.js → chunk-F3XZN24Z.js} +2 -2
  46. package/dist/{chunk-J3JPB7ZI.js → chunk-FACTVMXQ.js} +2 -2
  47. package/dist/{chunk-B7WISIAJ.js → chunk-FN6QP7JQ.js} +154 -1067
  48. package/dist/chunk-FN6QP7JQ.js.map +1 -0
  49. package/dist/{chunk-EBDA5TYA.js → chunk-FXCIOLRB.js} +2 -2
  50. package/dist/{chunk-TXQCG6SE.js → chunk-H7HUQIY7.js} +3 -3
  51. package/dist/{chunk-QD6QP5P6.js → chunk-I2HL5M6T.js} +17 -17
  52. package/dist/{chunk-M7R5R6OJ.js → chunk-IAIPNEHD.js} +20 -2
  53. package/dist/{chunk-M7R5R6OJ.js.map → chunk-IAIPNEHD.js.map} +1 -1
  54. package/dist/{chunk-Z4RU5VPM.js → chunk-J334N6QV.js} +2 -2
  55. package/dist/{chunk-NXRUUDUF.js → chunk-JJJCVCCQ.js} +2 -2
  56. package/dist/{chunk-GDUOCHCD.js → chunk-KGZF2VO3.js} +10 -10
  57. package/dist/{chunk-LA3HZKES.js → chunk-KLFYKC3K.js} +448 -49
  58. package/dist/chunk-KLFYKC3K.js.map +1 -0
  59. package/dist/{chunk-LLUGAZ3B.js → chunk-NT36GU6X.js} +30 -4
  60. package/dist/chunk-NT36GU6X.js.map +1 -0
  61. package/dist/{chunk-OHTOPFRF.js → chunk-SC2YAWRF.js} +2 -2
  62. package/dist/{chunk-YEE5KJQQ.js → chunk-T55EGZSJ.js} +2 -2
  63. package/dist/{chunk-N77ELJ2D.js → chunk-TT5U3UDO.js} +4 -4
  64. package/dist/{chunk-6FAMMBQ3.js → chunk-UBHVAGO7.js} +2 -2
  65. package/dist/chunk-VI5SGGXB.js +420 -0
  66. package/dist/chunk-VI5SGGXB.js.map +1 -0
  67. package/dist/{chunk-EDOQM4E4.js → chunk-WAFDHKES.js} +2 -2
  68. package/dist/{chunk-EXUCUPV2.js → chunk-WM7DNKBD.js} +2 -2
  69. package/dist/{dreams-ledger-3WSCI5V4.js → chunk-YF6FMLBT.js} +5 -6
  70. package/dist/{dreams-ledger-3WSCI5V4.js.map → chunk-YF6FMLBT.js.map} +1 -1
  71. package/dist/{chunk-WQYSDPMA.js → chunk-YQMPUYHE.js} +2 -2
  72. package/dist/{chunk-5O42UKXI.js → chunk-YUYPWJD3.js} +2 -2
  73. package/dist/{chunk-VCLGUIFM.js → chunk-Z3FGC3QE.js} +2 -2
  74. package/dist/{chunk-A7TJZLPK.js → chunk-ZK2L72VN.js} +2 -2
  75. package/dist/{chunk-BXEOHV7K.js → chunk-ZOHMPFOB.js} +3 -3
  76. package/dist/{graph-edge-decay-QPRJQ7DL.js → chunk-ZQNCHPTZ.js} +4 -5
  77. package/dist/{graph-edge-decay-QPRJQ7DL.js.map → chunk-ZQNCHPTZ.js.map} +1 -1
  78. package/dist/{cli-P_GaYcCY.d.ts → cli-IOlDHSBT.d.ts} +3 -3
  79. package/dist/cli.d.ts +6 -6
  80. package/dist/cli.js +31 -26
  81. package/dist/compounding/engine.d.ts +1 -1
  82. package/dist/compounding/engine.js +3 -3
  83. package/dist/compounding/preference-consolidator.d.ts +1 -1
  84. package/dist/compression-optimizer.d.ts +1 -1
  85. package/dist/config.d.ts +1 -1
  86. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  87. package/dist/connectors/codex-materialize-runner.js +3 -3
  88. package/dist/connectors/codex-materialize.d.ts +1 -1
  89. package/dist/connectors/index.d.ts +1 -1
  90. package/dist/connectors/index.js +3 -3
  91. package/dist/consolidation-provenance-check.d.ts +1 -1
  92. package/dist/consolidation-undo.d.ts +1 -1
  93. package/dist/contradiction/index.d.ts +1 -1
  94. package/dist/conversation-index/backend.d.ts +1 -1
  95. package/dist/conversation-index/chunker.d.ts +1 -1
  96. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  97. package/dist/conversation-index/indexer.d.ts +1 -1
  98. package/dist/conversation-index/search.d.ts +1 -1
  99. package/dist/day-summary.d.ts +1 -1
  100. package/dist/delinearize.d.ts +1 -1
  101. package/dist/direct-answer-wiring.d.ts +1 -1
  102. package/dist/direct-answer.d.ts +1 -1
  103. package/dist/dreams-ledger-6UODQOX6.js +22 -0
  104. package/dist/dreams-ledger-6UODQOX6.js.map +1 -0
  105. package/dist/embedding-fallback.d.ts +1 -1
  106. package/dist/enrichment/index.d.ts +1 -1
  107. package/dist/entity-retrieval.d.ts +1 -1
  108. package/dist/entity-retrieval.js +3 -3
  109. package/dist/entity-schema.d.ts +1 -1
  110. package/dist/event-time.d.ts +33 -1
  111. package/dist/event-time.js +3 -1
  112. package/dist/explicit-capture.d.ts +4 -4
  113. package/dist/extraction-faithfulness.d.ts +1 -1
  114. package/dist/extraction-judge-telemetry.d.ts +1 -1
  115. package/dist/extraction-judge-training.d.ts +1 -1
  116. package/dist/extraction-judge.d.ts +1 -1
  117. package/dist/extraction.d.ts +1 -1
  118. package/dist/fallback-llm.d.ts +1 -1
  119. package/dist/graph-dashboard-diff.d.ts +1 -1
  120. package/dist/graph-dashboard-key.d.ts +1 -1
  121. package/dist/graph-dashboard-parser.d.ts +1 -1
  122. package/dist/graph-edge-decay-RXUCJIN4.js +22 -0
  123. package/dist/graph-edge-decay-RXUCJIN4.js.map +1 -0
  124. package/dist/graph-edge-reinforcement.d.ts +1 -1
  125. package/dist/graph-snapshot.d.ts +1 -1
  126. package/dist/graph.d.ts +1 -1
  127. package/dist/identity-continuity.d.ts +1 -1
  128. package/dist/importance.d.ts +1 -1
  129. package/dist/index.d.ts +9 -9
  130. package/dist/index.js +58 -56
  131. package/dist/index.js.map +1 -1
  132. package/dist/intent.d.ts +1 -1
  133. package/dist/lcm/engine.d.ts +1 -1
  134. package/dist/lcm/index.d.ts +1 -1
  135. package/dist/lcm/tools.d.ts +1 -1
  136. package/dist/lifecycle.d.ts +1 -1
  137. package/dist/live-connectors-runner.d.ts +1 -1
  138. package/dist/local-llm.d.ts +1 -1
  139. package/dist/local-model-endpoint.d.ts +1 -1
  140. package/dist/maintenance/memory-governance.d.ts +1 -1
  141. package/dist/maintenance/memory-governance.js +3 -3
  142. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  143. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  144. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  145. package/dist/memory-action-policy.d.ts +1 -1
  146. package/dist/memory-cache.d.ts +1 -1
  147. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  148. package/dist/memory-projection-store.d.ts +1 -1
  149. package/dist/memory-provenance.d.ts +1 -1
  150. package/dist/memory-worth-outcomes.d.ts +1 -1
  151. package/dist/models-json.d.ts +1 -1
  152. package/dist/namespaces/migrate.d.ts +2 -2
  153. package/dist/namespaces/migrate.js +4 -4
  154. package/dist/namespaces/principal.d.ts +1 -1
  155. package/dist/namespaces/search.d.ts +1 -1
  156. package/dist/namespaces/storage.d.ts +2 -2
  157. package/dist/namespaces/storage.js +3 -3
  158. package/dist/native-knowledge.d.ts +1 -1
  159. package/dist/operator-toolkit.d.ts +1 -1
  160. package/dist/operator-toolkit.js +8 -8
  161. package/dist/orchestration/maintenance.d.ts +2 -2
  162. package/dist/orchestration/maintenance.js +5 -5
  163. package/dist/{orchestrator-f5xv19kp.d.ts → orchestrator-C_OMSIMZ.d.ts} +34 -3
  164. package/dist/orchestrator.d.ts +4 -4
  165. package/dist/orchestrator.js +17 -17
  166. package/dist/patterns-cli.d.ts +1 -1
  167. package/dist/policy-runtime.d.ts +1 -1
  168. package/dist/provenance.d.ts +1 -1
  169. package/dist/qmd-recall-cache.d.ts +1 -1
  170. package/dist/qmd.d.ts +1 -1
  171. package/dist/recall-disclosure-escalation.d.ts +1 -1
  172. package/dist/recall-explain-renderer.d.ts +1 -1
  173. package/dist/recall-explain-renderer.js +3 -3
  174. package/dist/recall-planner-llm.d.ts +1 -1
  175. package/dist/recall-state.d.ts +1 -1
  176. package/dist/recall-tag-filter.d.ts +1 -1
  177. package/dist/recall-xray-cli.d.ts +1 -1
  178. package/dist/recall-xray-cli.js +4 -4
  179. package/dist/recall-xray-renderer.d.ts +1 -1
  180. package/dist/recall-xray-renderer.js +3 -3
  181. package/dist/recall-xray.d.ts +1 -1
  182. package/dist/recall-xray.js +2 -2
  183. package/dist/resolve-auth-token.d.ts +1 -1
  184. package/dist/retrieval-agents.d.ts +1 -1
  185. package/dist/retrieval-tiers.d.ts +1 -1
  186. package/dist/routing/engine.d.ts +1 -1
  187. package/dist/routing/store.d.ts +1 -1
  188. package/dist/schemas.d.ts +22 -22
  189. package/dist/search/embed-helper.d.ts +1 -1
  190. package/dist/search/factory.d.ts +1 -1
  191. package/dist/search/index.d.ts +1 -1
  192. package/dist/search/lancedb-backend.d.ts +1 -1
  193. package/dist/search/meilisearch-backend.d.ts +1 -1
  194. package/dist/search/noop-backend.d.ts +1 -1
  195. package/dist/search/orama-backend.d.ts +1 -1
  196. package/dist/search/port.d.ts +1 -1
  197. package/dist/search/remote-backend.d.ts +1 -1
  198. package/dist/{semantic-consolidation-BQm1e1Pn.d.ts → semantic-consolidation-B8LiYtvx.d.ts} +1 -1
  199. package/dist/semantic-consolidation.d.ts +2 -2
  200. package/dist/semantic-consolidation.js +4 -4
  201. package/dist/semantic-rule-promotion.js +3 -3
  202. package/dist/semantic-rule-verifier.d.ts +1 -1
  203. package/dist/semantic-rule-verifier.js +3 -3
  204. package/dist/session-observer-bands.d.ts +1 -1
  205. package/dist/session-observer-state.d.ts +1 -1
  206. package/dist/shared-context/manager.d.ts +1 -1
  207. package/dist/signal.d.ts +1 -1
  208. package/dist/storage.d.ts +1 -1
  209. package/dist/storage.js +2 -2
  210. package/dist/summarizer.d.ts +1 -1
  211. package/dist/summary-snapshot.d.ts +1 -1
  212. package/dist/temporal-supersession.d.ts +1 -1
  213. package/dist/temporal-validity.d.ts +1 -1
  214. package/dist/threading.d.ts +1 -1
  215. package/dist/tier-migration.d.ts +1 -1
  216. package/dist/tier-routing.d.ts +1 -1
  217. package/dist/topics.d.ts +1 -1
  218. package/dist/transcript.d.ts +1 -1
  219. package/dist/transfer/types.d.ts +12 -12
  220. package/dist/trust-score-stage.d.ts +1 -1
  221. package/dist/trust-score.d.ts +1 -1
  222. package/dist/{types-DwO1Ot4n.d.ts → types-DmTaqob2.d.ts} +14 -0
  223. package/dist/types.d.ts +1 -1
  224. package/dist/types.js +1 -1
  225. package/dist/utility-runtime.d.ts +1 -1
  226. package/dist/verified-recall.js +3 -3
  227. package/package.json +2 -2
  228. package/src/access-boundary.ts +36 -2
  229. package/src/access-http.ts +17 -8
  230. package/src/access-mcp.ts +149 -1189
  231. package/src/access-operations-batch.ts +227 -1439
  232. package/src/access-surface-catalog.test.ts +4 -15
  233. package/src/access-surface-catalog.ts +82 -82
  234. package/src/bitemporal-dedup-backfill.test.ts +169 -0
  235. package/src/event-time.ts +57 -0
  236. package/src/extraction-eventtime-wiring.test.ts +101 -1
  237. package/src/orchestrator.ts +238 -43
  238. package/src/recall/archive-scoring.ts +526 -0
  239. package/src/types.ts +14 -0
  240. package/dist/chunk-B7WISIAJ.js.map +0 -1
  241. package/dist/chunk-EM2LDXJ2.js +0 -1315
  242. package/dist/chunk-EM2LDXJ2.js.map +0 -1
  243. package/dist/chunk-LA3HZKES.js.map +0 -1
  244. package/dist/chunk-LLUGAZ3B.js.map +0 -1
  245. package/dist/chunk-UIXXE6NI.js.map +0 -1
  246. /package/dist/{chunk-EVPNWN7Z.js.map → chunk-4R3CGCI5.js.map} +0 -0
  247. /package/dist/{chunk-UO5ZHIIH.js.map → chunk-4WZ3J7M6.js.map} +0 -0
  248. /package/dist/{chunk-PD42EYQN.js.map → chunk-5OPYYPJN.js.map} +0 -0
  249. /package/dist/{chunk-EEJMD2L2.js.map → chunk-6CWGS2LY.js.map} +0 -0
  250. /package/dist/{chunk-7CTNUVHZ.js.map → chunk-6SQQOJ4U.js.map} +0 -0
  251. /package/dist/{chunk-A5XNBK2D.js.map → chunk-DF3I6JGP.js.map} +0 -0
  252. /package/dist/{chunk-GJSL4WG2.js.map → chunk-F3XZN24Z.js.map} +0 -0
  253. /package/dist/{chunk-J3JPB7ZI.js.map → chunk-FACTVMXQ.js.map} +0 -0
  254. /package/dist/{chunk-EBDA5TYA.js.map → chunk-FXCIOLRB.js.map} +0 -0
  255. /package/dist/{chunk-TXQCG6SE.js.map → chunk-H7HUQIY7.js.map} +0 -0
  256. /package/dist/{chunk-QD6QP5P6.js.map → chunk-I2HL5M6T.js.map} +0 -0
  257. /package/dist/{chunk-Z4RU5VPM.js.map → chunk-J334N6QV.js.map} +0 -0
  258. /package/dist/{chunk-NXRUUDUF.js.map → chunk-JJJCVCCQ.js.map} +0 -0
  259. /package/dist/{chunk-GDUOCHCD.js.map → chunk-KGZF2VO3.js.map} +0 -0
  260. /package/dist/{chunk-OHTOPFRF.js.map → chunk-SC2YAWRF.js.map} +0 -0
  261. /package/dist/{chunk-YEE5KJQQ.js.map → chunk-T55EGZSJ.js.map} +0 -0
  262. /package/dist/{chunk-N77ELJ2D.js.map → chunk-TT5U3UDO.js.map} +0 -0
  263. /package/dist/{chunk-6FAMMBQ3.js.map → chunk-UBHVAGO7.js.map} +0 -0
  264. /package/dist/{chunk-EDOQM4E4.js.map → chunk-WAFDHKES.js.map} +0 -0
  265. /package/dist/{chunk-EXUCUPV2.js.map → chunk-WM7DNKBD.js.map} +0 -0
  266. /package/dist/{chunk-WQYSDPMA.js.map → chunk-YQMPUYHE.js.map} +0 -0
  267. /package/dist/{chunk-5O42UKXI.js.map → chunk-YUYPWJD3.js.map} +0 -0
  268. /package/dist/{chunk-VCLGUIFM.js.map → chunk-Z3FGC3QE.js.map} +0 -0
  269. /package/dist/{chunk-A7TJZLPK.js.map → chunk-ZK2L72VN.js.map} +0 -0
  270. /package/dist/{chunk-BXEOHV7K.js.map → chunk-ZOHMPFOB.js.map} +0 -0
@@ -1,26 +1,38 @@
1
1
  /**
2
2
  * Batch migration of remaining access-surface handlers through the boundary
3
- * (issue #1525). Each operation routes MCP/HTTP/CLI dispatch through the
4
- * shared validation + error-mapping layer in access-boundary.ts.
3
+ * (issue #1525 / #1668). Each operation routes MCP/HTTP/CLI dispatch through
4
+ * the shared validation + error-mapping layer in access-boundary.ts.
5
5
  *
6
- * Schemas use a null-stripping preprocessor (MCP clients send null for absent
7
- * optional fields repo gotcha #2) over a permissive record. Individual
8
- * schema tightening lands as follow-up PRs; the boundary already centralizes
9
- * error mapping and enforces "no handler bypasses the boundary."
6
+ * Strict per-tool Zod schemas replace the earlier permissive looseSchema (#1668).
7
+ * Each schema validates known field types; .passthrough() tolerates MCP client
8
+ * context injection (cwd/projectTag/sessionKey) without silent type coercion.
9
+ * The stripNulls preprocessor handles the OpenAI-schema null-for-absent gotcha.
10
10
  */
11
11
 
12
+ import { randomUUID } from "node:crypto";
12
13
  import { z } from "zod";
13
- import { defineOperation, type OperationContext } from "./access-boundary.js";
14
+ import type { DreamsPhase, RecallDisclosure, RecallPlanMode } from "./types.js";
15
+ import type { RemnicChatGptMemoryInspectorInput } from "./mcp-memory-inspector-app.js";
16
+ import { defineOperation } from "./access-boundary.js";
14
17
  import { EngramAccessInputError, type EngramAccessService } from "./access-service.js";
15
- import type { RecallPlanMode, RecallDisclosure } from "./types.js";
16
18
  import { projectTagProjectId } from "./coding/coding-namespace.js";
17
19
  import { expandTildePath } from "./utils/path.js";
20
+ import { resolvePrincipal } from "./namespaces/principal.js";
21
+ import { validateBriefingFormat } from "./briefing.js";
22
+ import {
23
+ buildChatGptMemoryInspectorActionRequest,
24
+ buildChatGptMemoryInspectorResult,
25
+ } from "./mcp-memory-inspector-app.js";
26
+ import { listPairs, isDefaultReviewNamespace } from "./contradiction/contradiction-review.js";
27
+ import { executeResolution, isValidResolutionVerb } from "./contradiction/resolution.js";
28
+ import { runContradictionScan } from "./contradiction/contradiction-scan.js";
29
+ import { runGraphEdgeDecayMaintenanceAcrossNamespaces } from "./maintenance/graph-edge-decay.js";
30
+ import { normalizeDreamsStatusWindowHours } from "./maintenance/dreams-ledger.js";
18
31
 
19
32
  // ---------------------------------------------------------------------------
20
- // Shared helpers — type-safe extraction from unknown input (no `any`)
33
+ // Shared helpers
21
34
  // ---------------------------------------------------------------------------
22
35
 
23
- /** Strip null values from an object (MCP clients send null for absent optionals). */
24
36
  function stripNulls(data: unknown): unknown {
25
37
  if (data !== null && typeof data === "object" && !Array.isArray(data)) {
26
38
  const obj = data as Record<string, unknown>;
@@ -33,1450 +45,226 @@ function stripNulls(data: unknown): unknown {
33
45
  return data;
34
46
  }
35
47
 
36
- /** Permissive schema: null-strip then accept any string-keyed record. */
37
- const looseSchema = z.preprocess(
38
- stripNulls,
39
- z.record(z.string(), z.unknown()),
40
- ) as z.ZodType<Record<string, unknown>>;
41
-
42
- function optStr(v: unknown): string | undefined {
43
- return typeof v === "string" ? v : undefined;
48
+ function strictSchema<T extends z.ZodRawShape>(shape: T): z.ZodType<Record<string, unknown>> {
49
+ return z.preprocess(stripNulls, z.object(shape).passthrough()) as unknown as z.ZodType<Record<string, unknown>>;
44
50
  }
51
+
52
+ function optStr(v: unknown): string | undefined { return typeof v === "string" ? v : undefined; }
45
53
  function reqStr(v: unknown, field: string): string {
46
- if (typeof v !== "string" || v.length === 0) {
47
- throw new EngramAccessInputError(`${field} is required and must be a non-empty string`);
48
- }
54
+ if (typeof v !== "string" || v.length === 0) throw new EngramAccessInputError(field + " is required and must be a non-empty string");
49
55
  return v;
50
56
  }
51
- function defStr(v: unknown, d: string): string {
52
- return typeof v === "string" ? v : d;
53
- }
54
- function optNum(v: unknown): number | undefined {
55
- return typeof v === "number" && Number.isFinite(v) ? v : undefined;
56
- }
57
- function optBool(v: unknown): boolean | undefined {
58
- return typeof v === "boolean" ? v : undefined;
59
- }
60
- function optStrArr(v: unknown): string[] | undefined {
61
- return Array.isArray(v) && v.every((x) => typeof x === "string") ? v : undefined;
62
- }
63
- // ===========================================================================
64
- // Recall operations
65
- // ===========================================================================
66
-
67
- defineOperation({
68
- name: "recall",
69
- description: "Semantic recall across memories.",
70
- schema: looseSchema,
71
- handler: async (input, ctx) => {
72
- const result = await ctx.service.recall({
73
- query: defStr(input.query, ""),
74
- sessionKey: optStr(input.sessionKey),
75
- authenticatedPrincipal: ctx.authenticatedPrincipal,
76
- namespace: optStr(input.namespace),
77
- topK: optNum(input.topK),
78
- mode: optStr(input.mode) as RecallPlanMode | "auto" | undefined,
79
- includeDebug: input.includeDebug === true,
80
- disclosure: optStr(input.disclosure) as RecallDisclosure | undefined,
81
- cwd: optStr(input.cwd),
82
- projectTag: optStr(input.projectTag),
83
- asOf: optStr(input.asOf),
84
- ...(optStrArr(input.tags) !== undefined ? { tags: optStrArr(input.tags)! } : {}),
85
- ...(optStr(input.tagMatch) !== undefined ? { tagMatch: optStr(input.tagMatch) as "any" | "all" } : {}),
86
- });
87
- return { result };
88
- },
89
- });
90
-
91
- defineOperation({
92
- name: "recall_explain",
93
- description: "Explain the recall plan for the session.",
94
- schema: looseSchema,
95
- handler: async (input, ctx) => {
96
- const result = await ctx.service.recallExplain({
97
- sessionKey: optStr(input.sessionKey),
98
- namespace: optStr(input.namespace),
99
- authenticatedPrincipal: ctx.authenticatedPrincipal,
100
- });
101
- return { result };
102
- },
103
- });
104
-
105
- defineOperation({
106
- name: "set_coding_context",
107
- description: "Set the coding context for a session (issue #569).",
108
- schema: looseSchema,
57
+ function defStr(v: unknown, d: string): string { return typeof v === "string" ? v : d; }
58
+ function optNum(v: unknown): number | undefined { return typeof v === "number" && Number.isFinite(v) ? v : undefined; }
59
+ function optBool(v: unknown): boolean | undefined { return typeof v === "boolean" ? v : undefined; }
60
+ function optStrArr(v: unknown): string[] | undefined { return Array.isArray(v) && v.every((x) => typeof x === "string") ? v : undefined; }
61
+
62
+ const S = {
63
+ str: z.string().optional(),
64
+ num: z.number().optional(),
65
+ // Accept numbers and numeric strings (MCP clients sometimes send "7" for 7).
66
+ flexNum: z.union([z.number(), z.string()]).optional(),
67
+ bool: z.boolean().optional(),
68
+ strArr: z.array(z.string()).optional(),
69
+ };
70
+
71
+ // === RECALL ===
72
+ defineOperation({ name: "recall", description: "Semantic recall.", schema: strictSchema({ query: S.str, sessionKey: S.str, namespace: S.str, topK: S.num, mode: S.str, includeDebug: S.bool, disclosure: S.str, cwd: S.str, projectTag: S.str, asOf: S.str, tags: S.strArr, tagMatch: S.str }),
73
+ handler: async (input, ctx) => {
74
+ let disclosure: RecallDisclosure | undefined;
75
+ if (input.disclosure !== undefined) { if (typeof input.disclosure !== "string") throw new EngramAccessInputError("disclosure must be a string"); disclosure = input.disclosure as RecallDisclosure; }
76
+ if (input.cwd !== undefined && typeof input.cwd !== "string") throw new EngramAccessInputError("cwd must be a string");
77
+ if (input.projectTag !== undefined && typeof input.projectTag !== "string") throw new EngramAccessInputError("projectTag must be a string");
78
+ if (input.asOf !== undefined && typeof input.asOf !== "string") throw new EngramAccessInputError("asOf must be a string");
79
+ let tags: string[] | undefined;
80
+ if (input.tags !== undefined) { if (!Array.isArray(input.tags) || !input.tags.every((t) => typeof t === "string")) throw new EngramAccessInputError("tags must be an array of strings"); tags = input.tags; }
81
+ let tagMatch: "any" | "all" | undefined;
82
+ if (input.tagMatch !== undefined) { if (input.tagMatch !== "any" && input.tagMatch !== "all") throw new EngramAccessInputError("tagMatch must be one of: any, all"); tagMatch = input.tagMatch; }
83
+ const result = await ctx.service.recall({ query: typeof input.query === "string" ? input.query : "", sessionKey: optStr(input.sessionKey), authenticatedPrincipal: ctx.authenticatedPrincipal, namespace: optStr(input.namespace), topK: optNum(input.topK), mode: optStr(input.mode) as RecallPlanMode | "auto" | undefined, includeDebug: input.includeDebug === true, disclosure, cwd: optStr(input.cwd), projectTag: optStr(input.projectTag), asOf: optStr(input.asOf), ...(tags ? { tags } : {}), ...(tagMatch ? { tagMatch } : {}) });
84
+ return { result };
85
+ },
86
+ });
87
+ defineOperation({ name: "recall_explain", description: "Explain recall plan.", schema: strictSchema({ sessionKey: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.recallExplain({ sessionKey: optStr(input.sessionKey), namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
88
+ defineOperation({ name: "set_coding_context", description: "Set coding context.", schema: z.preprocess((data) => { // Strip null from all fields EXCEPT codingContext (null = clear context).
89
+ if (data !== null && typeof data === "object" && !Array.isArray(data)) { const o = data as Record<string, unknown>; const c: Record<string, unknown> = {}; for (const [k, v] of Object.entries(o)) { if (v !== null || k === "codingContext") c[k] = v; } return c; } return data; }, z.object({ sessionKey: S.str, codingContext: z.union([z.null(), z.object({ projectId: S.str, branch: z.union([z.string(), z.null()]).optional(), rootPath: S.str, defaultBranch: z.union([z.string(), z.null()]).optional() }).passthrough()]).optional(), projectTag: S.str }).passthrough()) as unknown as z.ZodType<Record<string, unknown>>,
109
90
  handler: async (input, ctx) => {
110
91
  const sessionKey = defStr(input.sessionKey, "");
111
92
  const projectTag = optStr(input.projectTag);
112
93
  const hasProjectTag = projectTag !== undefined && projectTag.trim().length > 0;
113
94
  const hasCodingContext = "codingContext" in input;
114
- if (!hasCodingContext && hasProjectTag) {
115
- const tag = projectTag!.trim();
116
- const projectId = projectTagProjectId(tag);
117
- ctx.service.setCodingContext({
118
- sessionKey,
119
- codingContext: { projectId, branch: null, rootPath: projectId, defaultBranch: null },
120
- });
121
- return { result: { ok: true } };
122
- }
123
- if (!hasCodingContext && !hasProjectTag) {
124
- throw new EngramAccessInputError("set_coding_context requires either codingContext or projectTag");
125
- }
126
- const rawCtx = input.codingContext;
95
+ if (!hasCodingContext && hasProjectTag) { const tag = projectTag!.trim(); const pid = projectTagProjectId(tag); ctx.service.setCodingContext({ sessionKey, codingContext: { projectId: pid, branch: null, rootPath: pid, defaultBranch: null } }); return { result: { ok: true } }; }
96
+ if (!hasCodingContext && !hasProjectTag) throw new EngramAccessInputError("set_coding_context requires either codingContext or projectTag");
97
+ const rawCtx = (input as Record<string, unknown>).codingContext;
127
98
  let codingContext: { projectId: string; branch: string | null; rootPath: string; defaultBranch: string | null } | null = null;
128
- if (rawCtx !== null) {
129
- if (typeof rawCtx !== "object" || rawCtx === undefined) {
130
- throw new EngramAccessInputError("codingContext must be an object or null");
131
- }
132
- const obj = rawCtx as Record<string, unknown>;
133
- const projectId = defStr(obj.projectId, "");
134
- const rootPath = defStr(obj.rootPath, "");
135
- const branch = obj.branch === null ? null : optStr(obj.branch);
136
- const defaultBranch = obj.defaultBranch === null ? null : optStr(obj.defaultBranch);
137
- if (branch === undefined) throw new EngramAccessInputError("codingContext.branch must be a string or null");
138
- if (defaultBranch === undefined) throw new EngramAccessInputError("codingContext.defaultBranch must be a string or null");
139
- codingContext = { projectId, branch, rootPath, defaultBranch };
140
- }
99
+ if (rawCtx !== null) { if (typeof rawCtx !== "object") throw new EngramAccessInputError("codingContext must be an object or null"); const o = rawCtx as Record<string, unknown>; const branch = o.branch === null ? null : optStr(o.branch); const dB = o.defaultBranch === null ? null : optStr(o.defaultBranch); if (branch === undefined) throw new EngramAccessInputError("codingContext.branch must be a string or null"); if (dB === undefined) throw new EngramAccessInputError("codingContext.defaultBranch must be a string or null"); codingContext = { projectId: defStr(o.projectId, ""), branch, rootPath: defStr(o.rootPath, ""), defaultBranch: dB }; }
141
100
  ctx.service.setCodingContext({ sessionKey, codingContext });
142
101
  return { result: { ok: true } };
143
102
  },
144
103
  });
145
-
146
- defineOperation({
147
- name: "recall_tier_explain",
148
- description: "Explain the recall tier breakdown.",
149
- schema: looseSchema,
150
- handler: async (input, ctx) => {
151
- const sessionKey = optStr(input.sessionKey);
152
- const namespace = optStr(input.namespace);
153
- const result = await ctx.service.recallTierExplain(
154
- sessionKey !== undefined && sessionKey.length > 0 ? sessionKey : undefined,
155
- namespace !== undefined && namespace.length > 0 ? namespace : undefined,
156
- ctx.authenticatedPrincipal,
157
- );
158
- return { result };
159
- },
160
- });
161
-
162
- defineOperation({
163
- name: "recall_xray",
164
- description: "X-ray the recall pipeline for a query.",
165
- schema: looseSchema,
104
+ defineOperation({ name: "recall_tier_explain", description: "Explain recall tiers.", schema: strictSchema({ sessionKey: S.str, namespace: S.str }), handler: async (input, ctx) => { const sk = optStr(input.sessionKey); const ns = optStr(input.namespace); return { result: await ctx.service.recallTierExplain(sk && sk.length > 0 ? sk : undefined, ns && ns.length > 0 ? ns : undefined, ctx.authenticatedPrincipal) }; } });
105
+ defineOperation({ name: "recall_xray", description: "X-ray recall.", schema: strictSchema({ query: S.str, sessionKey: S.str, namespace: S.str, budget: z.unknown().optional(), disclosure: S.str }),
166
106
  handler: async (input, ctx) => {
167
- const budgetRaw = input.budget;
168
107
  let budget: number | undefined;
169
- if (budgetRaw !== undefined && budgetRaw !== null) {
170
- const parsed = typeof budgetRaw === "number" ? budgetRaw : typeof budgetRaw === "string" ? Number(budgetRaw) : undefined;
171
- if (parsed === undefined || !Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
172
- throw new EngramAccessInputError("recall_xray: budget expects a positive integer");
173
- }
174
- budget = parsed;
175
- }
176
- const disclosureRaw = optStr(input.disclosure);
177
- const result = await ctx.service.recallXray({
178
- query: defStr(input.query, ""),
179
- sessionKey: optStr(input.sessionKey),
180
- namespace: optStr(input.namespace),
181
- budget,
182
- authenticatedPrincipal: ctx.authenticatedPrincipal,
183
- ...(disclosureRaw !== undefined && disclosureRaw !== "" ? { disclosure: disclosureRaw as RecallDisclosure } : {}),
184
- });
185
- return { result };
186
- },
187
- });
188
-
189
- // ===========================================================================
190
- // Wearables + transcript operations
191
- // ===========================================================================
192
-
193
- defineOperation({
194
- name: "wearables_status",
195
- description: "Get wearables sync status.",
196
- schema: looseSchema,
197
- handler: async (_input, ctx) => ({ result: await ctx.service.wearablesStatus() }),
198
- });
199
-
200
- defineOperation({
201
- name: "wearables_sync",
202
- description: "Sync wearables data.",
203
- schema: looseSchema,
204
- handler: async (input, ctx) => {
205
- const result = await ctx.service.wearablesSync({
206
- source: optStr(input.source),
207
- date: optStr(input.date),
208
- days: optNum(input.days),
209
- forceMemories: optBool(input.forceMemories),
210
- });
211
- return { result };
212
- },
213
- });
214
-
215
- defineOperation({
216
- name: "transcript_day",
217
- description: "Get transcript for a specific day.",
218
- schema: looseSchema,
219
- handler: async (input, ctx) => {
220
- const date = defStr(input.date, "");
221
- if (date.trim().length === 0) throw new EngramAccessInputError("transcript_day: date is required and must be YYYY-MM-DD");
222
- const result = await ctx.service.wearablesTranscriptDay({ date, source: optStr(input.source) });
223
- return { result };
224
- },
225
- });
226
-
227
- defineOperation({
228
- name: "transcript_search",
229
- description: "Search transcripts.",
230
- schema: looseSchema,
231
- handler: async (input, ctx) => {
232
- const query = defStr(input.query, "");
233
- if (query.trim().length === 0) throw new EngramAccessInputError("transcript_search: query is required and must be non-empty");
234
- const result = await ctx.service.wearablesTranscriptSearch({
235
- query,
236
- source: optStr(input.source),
237
- from: optStr(input.from),
238
- to: optStr(input.to),
239
- limit: optNum(input.limit),
240
- });
241
- return { result };
242
- },
243
- });
244
-
245
- defineOperation({
246
- name: "transcript_memories",
247
- description: "Get transcript memories.",
248
- schema: looseSchema,
249
- handler: async (input, ctx) => {
250
- const result = await ctx.service.wearablesTranscriptMemories({
251
- source: optStr(input.source),
252
- date: optStr(input.date),
253
- limit: optNum(input.limit),
254
- });
255
- return { result };
256
- },
257
- });
258
-
259
- // ===========================================================================
260
- // Action confidence, day summary, capsule operations
261
- // ===========================================================================
262
-
263
- defineOperation({
264
- name: "action_confidence",
265
- description: "Get action confidence for recent memories.",
266
- schema: looseSchema,
267
- handler: async (input, ctx) => {
268
- const result = await ctx.service.actionConfidence({
269
- intendedAction: optStr(input.intendedAction),
270
- confidence: optNum(input.confidence),
271
- risk: optStr(input.risk) as import("./action-confidence.js").ActionConfidenceRiskCategory | undefined,
272
- contextReadiness: optStr(input.contextReadiness) as import("./action-confidence.js").ActionConfidenceContextReadiness | undefined,
273
- currentContextScopes: optStrArr(input.currentContextScopes),
274
- });
275
- return { result };
276
- },
277
- });
278
-
279
- defineOperation({
280
- name: "chatgpt_memory_inspector",
281
- description: "ChatGPT memory inspector (recall xray + action confidence orchestrator).",
282
- schema: looseSchema,
283
- handler: async (input, ctx) => {
284
- const xray = await ctx.service.recallXray({
285
- query: defStr(input.query, ""),
286
- sessionKey: optStr(input.sessionKey),
287
- namespace: optStr(input.namespace),
288
- authenticatedPrincipal: ctx.authenticatedPrincipal,
289
- });
290
- const confidence = await ctx.service.actionConfidence({});
291
- return { result: { xray, confidence } };
292
- },
293
- });
294
-
295
- defineOperation({
296
- name: "day_summary",
297
- description: "Get a day summary.",
298
- schema: looseSchema,
299
- handler: async (input, ctx) => {
300
- const result = await ctx.service.daySummary({
301
- memories: optStr(input.memories),
302
- sessionKey: optStr(input.sessionKey),
303
- namespace: optStr(input.namespace),
304
- timeZone: optStr(input.timeZone),
305
- });
306
- return { result };
307
- },
308
- });
309
-
310
- defineOperation({
311
- name: "capsule_export",
312
- description: "Export a capsule.",
313
- schema: looseSchema,
314
- handler: async (input, ctx) => {
315
- const result = await ctx.service.capsuleExport({
316
- name: optStr(input.name) ?? "",
317
- namespace: optStr(input.namespace),
318
- since: optStr(input.since),
319
- includeKinds: optStrArr(input.includeKinds),
320
- peerIds: optStrArr(input.peerIds),
321
- includeTranscripts: optBool(input.includeTranscripts),
322
- encrypt: optBool(input.encrypt),
323
- principal: ctx.authenticatedPrincipal,
324
- } as Parameters<typeof ctx.service.capsuleExport>[0]);
325
- return { result };
326
- },
327
- });
328
-
329
- defineOperation({
330
- name: "capsule_import",
331
- description: "Import a capsule.",
332
- schema: looseSchema,
333
- handler: async (input, ctx) => {
334
- const result = await ctx.service.capsuleImport({
335
- archivePath: expandTildePath(optStr(input.archivePath) ?? ""),
336
- namespace: optStr(input.namespace),
337
- mode: optStr(input.mode) as "skip" | "overwrite" | "fork" | undefined,
338
- passphrase: optStr(input.passphrase),
339
- principal: ctx.authenticatedPrincipal,
340
- });
341
- return { result };
342
- },
343
- });
344
-
345
- defineOperation({
346
- name: "capsule_list",
347
- description: "List capsules.",
348
- schema: looseSchema,
349
- handler: async (input, ctx) => {
350
- const result = await ctx.service.capsuleList({
351
- namespace: optStr(input.namespace),
352
- principal: ctx.authenticatedPrincipal,
353
- });
354
- return { result };
355
- },
356
- });
357
-
358
- // ===========================================================================
359
- // Governance, maintenance, procedural operations
360
- // ===========================================================================
361
-
362
- defineOperation({
363
- name: "memory_governance_run",
364
- description: "Run memory governance.",
365
- schema: looseSchema,
366
- handler: async (input, ctx) => {
367
- const result = await ctx.service.governanceRun({
368
- namespace: optStr(input.namespace),
369
- mode: optStr(input.mode) as "shadow" | "apply" | undefined,
370
- recentDays: optNum(input.recentDays),
371
- maxMemories: optNum(input.maxMemories),
372
- batchSize: optNum(input.batchSize),
373
- authenticatedPrincipal: ctx.authenticatedPrincipal,
374
- });
375
- return { result };
376
- },
377
- });
378
-
379
- defineOperation({
380
- name: "procedure_mining_run",
381
- description: "Run procedure mining.",
382
- schema: looseSchema,
383
- handler: async (input, ctx) => {
384
- const result = await ctx.service.procedureMiningRun({
385
- namespace: optStr(input.namespace),
386
- authenticatedPrincipal: ctx.authenticatedPrincipal,
387
- });
388
- return { result };
389
- },
390
- });
391
-
392
- defineOperation({
393
- name: "pattern_reinforcement_run",
394
- description: "Run pattern reinforcement.",
395
- schema: looseSchema,
396
- handler: async (input, ctx) => {
397
- const result = await ctx.service.patternReinforcementRun({
398
- namespace: optStr(input.namespace),
399
- force: input.force === true,
400
- authenticatedPrincipal: ctx.authenticatedPrincipal,
401
- });
402
- return { result };
403
- },
404
- });
405
-
406
- defineOperation({
407
- name: "procedural_stats",
408
- description: "Get procedural stats.",
409
- schema: looseSchema,
410
- handler: async (input, ctx) => {
411
- const result = await ctx.service.procedureStats({ namespace: optStr(input.namespace) }, ctx.authenticatedPrincipal);
412
- return { result };
413
- },
414
- });
415
-
416
- // ===========================================================================
417
- // Memory timeline, suggestion, entity, observe, LCM operations
418
- // ===========================================================================
419
-
420
- defineOperation({
421
- name: "memory_timeline",
422
- description: "Get the timeline for a memory.",
423
- schema: looseSchema,
424
- handler: async (input, ctx) => {
425
- const result = await ctx.service.memoryTimeline(
426
- optStr(input.memoryId) ?? "",
427
- optStr(input.namespace),
428
- optNum(input.limit),
429
- ctx.authenticatedPrincipal,
430
- );
431
- return { result };
432
- },
433
- });
434
-
435
- defineOperation({
436
- name: "suggestion_submit",
437
- description: "Submit a memory suggestion.",
438
- schema: looseSchema,
439
- handler: async (input, ctx) => {
440
- const result = await ctx.service.suggestionSubmit({
441
- schemaVersion: optNum(input.schemaVersion),
442
- idempotencyKey: optStr(input.idempotencyKey),
443
- dryRun: input.dryRun === true,
444
- sessionKey: optStr(input.sessionKey),
445
- authenticatedPrincipal: ctx.authenticatedPrincipal,
446
- content: optStr(input.content) ?? "",
447
- category: optStr(input.category),
448
- confidence: optNum(input.confidence),
449
- namespace: optStr(input.namespace),
450
- tags: optStrArr(input.tags),
451
- entityRef: optStr(input.entityRef),
452
- ttl: optStr(input.ttl),
453
- sourceReason: optStr(input.sourceReason),
454
- cwd: optStr(input.cwd),
455
- projectTag: optStr(input.projectTag),
456
- });
457
- return { result };
458
- },
459
- });
460
-
461
- defineOperation({
462
- name: "entity_get",
463
- description: "Get an entity by name.",
464
- schema: looseSchema,
465
- handler: async (input, ctx) => {
466
- const result = await ctx.service.entityGet(optStr(input.name) ?? "", optStr(input.namespace));
467
- return { result };
468
- },
469
- });
470
-
471
- defineOperation({
472
- name: "review_queue_list",
473
- description: "List the review queue.",
474
- schema: looseSchema,
475
- handler: async (input, ctx) => {
476
- const result = await ctx.service.reviewQueue(optStr(input.runId) ?? "", optStr(input.namespace), ctx.authenticatedPrincipal);
477
- return { result };
478
- },
479
- });
480
-
481
- defineOperation({
482
- name: "observe",
483
- description: "Observe messages into the memory system.",
484
- schema: looseSchema,
485
- handler: async (input, ctx) => {
486
- const messages = input.messages;
487
- if (!Array.isArray(messages)) throw new EngramAccessInputError("observe: messages must be an array");
488
- const result = await ctx.service.observe({
489
- sessionKey: defStr(input.sessionKey, ""),
490
- messages: messages as unknown as Parameters<typeof ctx.service.observe>[0]["messages"],
491
- authenticatedPrincipal: ctx.authenticatedPrincipal,
492
- namespace: optStr(input.namespace),
493
- skipExtraction: input.skipExtraction === true,
494
- cwd: optStr(input.cwd),
495
- projectTag: optStr(input.projectTag),
496
- });
497
- return { result };
498
- },
499
- });
500
-
501
- defineOperation({
502
- name: "lcm_search",
503
- description: "Search the LCM (long-context memory).",
504
- schema: looseSchema,
505
- handler: async (input, ctx) => {
506
- const result = await ctx.service.lcmSearch({
507
- query: defStr(input.query, ""),
508
- sessionKey: optStr(input.sessionKey),
509
- sessionPrefix: optStr(input.sessionPrefix),
510
- namespace: optStr(input.namespace),
511
- limit: optNum(input.limit),
512
- authenticatedPrincipal: ctx.authenticatedPrincipal,
513
- });
514
- return { result };
515
- },
516
- });
517
-
518
- defineOperation({
519
- name: "lcm_compaction_flush",
520
- description: "Flush LCM compaction.",
521
- schema: looseSchema,
522
- handler: async (input, ctx) => {
523
- const result = await ctx.service.lcmCompactionFlush({
524
- sessionKey: optStr(input.sessionKey) ?? "",
525
- namespace: optStr(input.namespace),
526
- authenticatedPrincipal: ctx.authenticatedPrincipal,
527
- });
528
- return { result };
529
- },
530
- });
531
-
532
- defineOperation({
533
- name: "lcm_compaction_record",
534
- description: "Record an LCM compaction.",
535
- schema: looseSchema,
536
- handler: async (input, ctx) => {
537
- const result = await ctx.service.lcmCompactionRecord({
538
- sessionKey: optStr(input.sessionKey) ?? "",
539
- namespace: optStr(input.namespace),
540
- tokensBefore: optNum(input.tokensBefore) ?? 0,
541
- tokensAfter: optNum(input.tokensAfter) ?? 0,
542
- authenticatedPrincipal: ctx.authenticatedPrincipal,
543
- });
544
- return { result };
545
- },
546
- });
547
-
548
- // ===========================================================================
549
- // Continuity, identity operations
550
- // ===========================================================================
551
-
552
- defineOperation({
553
- name: "continuity_audit_generate",
554
- description: "Generate a continuity audit.",
555
- schema: looseSchema,
556
- handler: async (input, ctx) => {
557
- const result = await ctx.service.continuityAuditGenerate({
558
- period: optStr(input.period) as "weekly" | "monthly" | undefined,
559
- key: optStr(input.key),
560
- });
561
- return { result };
562
- },
563
- });
564
-
565
- defineOperation({
566
- name: "continuity_incident_open",
567
- description: "Open a continuity incident.",
568
- schema: looseSchema,
569
- handler: async (input, ctx) => {
570
- const result = await ctx.service.continuityIncidentOpen({
571
- symptom: optStr(input.symptom) ?? "",
572
- namespace: optStr(input.namespace),
573
- triggerWindow: optStr(input.triggerWindow),
574
- suspectedCause: optStr(input.suspectedCause),
575
- principal: ctx.authenticatedPrincipal,
576
- });
577
- return { result };
578
- },
579
- });
580
-
581
- defineOperation({
582
- name: "continuity_incident_close",
583
- description: "Close a continuity incident.",
584
- schema: looseSchema,
585
- handler: async (input, ctx) => {
586
- const result = await ctx.service.continuityIncidentClose({
587
- id: optStr(input.id) ?? "",
588
- namespace: optStr(input.namespace),
589
- fixApplied: optStr(input.fixApplied) ?? "",
590
- verificationResult: optStr(input.verificationResult) ?? "",
591
- preventiveRule: optStr(input.preventiveRule),
592
- principal: ctx.authenticatedPrincipal,
593
- });
594
- return { result };
595
- },
596
- });
597
-
598
- defineOperation({
599
- name: "continuity_incident_list",
600
- description: "List continuity incidents.",
601
- schema: looseSchema,
602
- handler: async (input, ctx) => {
603
- const result = await ctx.service.continuityIncidentList({
604
- state: optStr(input.state) as "all" | "open" | "closed" | undefined,
605
- namespace: optStr(input.namespace),
606
- limit: optNum(input.limit),
607
- principal: ctx.authenticatedPrincipal,
608
- });
609
- return { result };
610
- },
611
- });
612
-
613
- defineOperation({
614
- name: "continuity_loop_add_or_update",
615
- description: "Add or update a continuity loop.",
616
- schema: looseSchema,
617
- handler: async (input, ctx) => {
618
- const result = await ctx.service.continuityLoopAddOrUpdate({
619
- id: optStr(input.id) ?? "",
620
- cadence: optStr(input.cadence) as "daily" | "weekly" | "monthly" | "quarterly",
621
- purpose: optStr(input.purpose) ?? "",
622
- status: optStr(input.status) as "active" | "paused" | "retired",
623
- killCondition: optStr(input.killCondition) ?? "",
624
- namespace: optStr(input.namespace),
625
- lastReviewed: optStr(input.lastReviewed),
626
- notes: optStr(input.notes),
627
- principal: ctx.authenticatedPrincipal,
628
- });
629
- return { result };
630
- },
631
- });
632
-
633
- defineOperation({
634
- name: "continuity_loop_review",
635
- description: "Review a continuity loop.",
636
- schema: looseSchema,
637
- handler: async (input, ctx) => {
638
- const result = await ctx.service.continuityLoopReview({
639
- id: optStr(input.id) ?? "",
640
- namespace: optStr(input.namespace),
641
- status: optStr(input.status) as "active" | "paused" | "retired" | undefined,
642
- notes: optStr(input.notes),
643
- reviewedAt: optStr(input.reviewedAt),
644
- principal: ctx.authenticatedPrincipal,
645
- });
646
- return { result };
647
- },
648
- });
649
-
650
- defineOperation({
651
- name: "identity_anchor_get",
652
- description: "Get identity anchor.",
653
- schema: looseSchema,
654
- handler: async (input, ctx) => {
655
- const result = await ctx.service.identityAnchorGet({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal });
656
- return { result };
657
- },
658
- });
659
-
660
- defineOperation({
661
- name: "identity_anchor_update",
662
- description: "Update identity anchor.",
663
- schema: looseSchema,
664
- handler: async (input, ctx) => {
665
- const result = await ctx.service.identityAnchorUpdate({
666
- namespace: optStr(input.namespace),
667
- identityTraits: optStr(input.identityTraits) ?? "",
668
- communicationPreferences: optStr(input.communicationPreferences) ?? "",
669
- operatingPrinciples: optStr(input.operatingPrinciples) ?? "",
670
- continuityNotes: optStr(input.continuityNotes) ?? "",
671
- });
672
- return { result };
673
- },
674
- });
675
-
676
- defineOperation({
677
- name: "memory_identity",
678
- description: "Get memory identity.",
679
- schema: looseSchema,
680
- handler: async (input, ctx) => {
681
- const result = await ctx.service.memoryIdentity({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal });
682
- return { result };
683
- },
684
- });
685
-
686
- // ===========================================================================
687
- // Work, shared-context, compounding, compression operations
688
- // ===========================================================================
689
-
690
- defineOperation({
691
- name: "work_task",
692
- description: "Manage a work task.",
693
- schema: looseSchema,
694
- handler: async (input, ctx) => {
695
- const result = await ctx.service.workTask({
696
- action: optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "transition",
697
- id: optStr(input.id) ?? "",
698
- title: optStr(input.title),
699
- description: optStr(input.description),
700
- status: optStr(input.status),
701
- priority: optStr(input.priority),
702
- owner: optStr(input.owner),
703
- assignee: optStr(input.assignee),
704
- projectId: optStr(input.projectId),
705
- tags: optStrArr(input.tags),
706
- dueAt: optStr(input.dueAt),
707
- });
708
- return { result };
709
- },
710
- });
711
-
712
- defineOperation({
713
- name: "work_project",
714
- description: "Manage a work project.",
715
- schema: looseSchema,
716
- handler: async (input, ctx) => {
717
- const result = await ctx.service.workProject({
718
- action: optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "link_task",
719
- id: optStr(input.id) ?? "",
720
- name: optStr(input.name),
721
- description: optStr(input.description),
722
- status: optStr(input.status),
723
- owner: optStr(input.owner),
724
- tags: optStrArr(input.tags),
725
- taskId: optStr(input.taskId),
726
- projectId: optStr(input.projectId),
727
- });
728
- return { result };
729
- },
730
- });
731
-
732
- defineOperation({
733
- name: "work_board",
734
- description: "Manage a work board.",
735
- schema: looseSchema,
736
- handler: async (input, ctx) => {
737
- const result = await ctx.service.workBoard({
738
- action: optStr(input.action) as "export_markdown" | "export_snapshot" | "import_snapshot",
739
- projectId: optStr(input.projectId) ?? "",
740
- snapshotJson: optStr(input.snapshotJson) ?? "",
741
- linkToMemory: input.linkToMemory === true,
742
- });
743
- return { result };
744
- },
745
- });
746
-
747
- defineOperation({
748
- name: "shared_context_write_output",
749
- description: "Write shared context output.",
750
- schema: looseSchema,
751
- handler: async (input, ctx) => {
752
- const result = await ctx.service.sharedContextWriteOutput({
753
- agentId: optStr(input.agentId) ?? "",
754
- title: optStr(input.title) ?? "",
755
- content: optStr(input.content) ?? "",
756
- });
757
- return { result };
758
- },
759
- });
760
-
761
- defineOperation({
762
- name: "shared_feedback_record",
763
- description: "Record shared feedback.",
764
- schema: looseSchema,
765
- handler: async (input, ctx) => {
766
- const result = await ctx.service.sharedFeedbackRecord({
767
- agent: optStr(input.agent) ?? "",
768
- decision: optStr(input.decision) as "rejected" | "approved" | "approved_with_feedback",
769
- reason: optStr(input.reason) ?? "",
770
- date: optStr(input.date) ?? "",
771
- learning: optStr(input.learning) ?? "",
772
- outcome: optStr(input.outcome) ?? "",
773
- severity: optStr(input.severity) as "high" | "low" | "medium" | undefined,
774
- confidence: optNum(input.confidence),
775
- workflow: optStr(input.workflow),
776
- tags: optStrArr(input.tags),
777
- evidenceWindowStart: optStr(input.evidenceWindowStart),
778
- evidenceWindowEnd: optStr(input.evidenceWindowEnd),
779
- refs: optStrArr(input.refs),
780
- });
781
- return { result };
782
- },
783
- });
784
-
785
- defineOperation({
786
- name: "shared_priorities_append",
787
- description: "Append to shared priorities.",
788
- schema: looseSchema,
789
- handler: async (input, ctx) => {
790
- const result = await ctx.service.sharedPrioritiesAppend({
791
- agentId: optStr(input.agentId) ?? "",
792
- text: optStr(input.text) ?? "",
793
- });
794
- return { result };
795
- },
796
- });
797
-
798
- defineOperation({
799
- name: "shared_context_cross_signals_run",
800
- description: "Run shared context cross signals.",
801
- schema: looseSchema,
802
- handler: async (input, ctx) => {
803
- const result = await ctx.service.sharedContextCrossSignalsRun({ date: optStr(input.date) });
804
- return { result };
805
- },
806
- });
807
-
808
- defineOperation({
809
- name: "shared_context_curate_daily",
810
- description: "Curate daily shared context.",
811
- schema: looseSchema,
812
- handler: async (input, ctx) => {
813
- const result = await ctx.service.sharedContextCurateDaily({ date: optStr(input.date) });
814
- return { result };
815
- },
816
- });
817
-
818
- defineOperation({
819
- name: "compounding_weekly_synthesize",
820
- description: "Weekly compound synthesis.",
821
- schema: looseSchema,
822
- handler: async (input, ctx) => {
823
- const result = await ctx.service.compoundingWeeklySynthesize({ weekId: optStr(input.weekId) });
824
- return { result };
825
- },
826
- });
827
-
828
- defineOperation({
829
- name: "compounding_promote_candidate",
830
- description: "Promote a compounding candidate.",
831
- schema: looseSchema,
832
- handler: async (input, ctx) => {
833
- const result = await ctx.service.compoundingPromoteCandidate({
834
- weekId: optStr(input.weekId) ?? "",
835
- candidateId: optStr(input.candidateId) ?? "",
836
- dryRun: input.dryRun === true,
837
- });
838
- return { result };
839
- },
840
- });
841
-
842
- defineOperation({
843
- name: "compression_guidelines_optimize",
844
- description: "Optimize compression guidelines.",
845
- schema: looseSchema,
846
- handler: async (input, ctx) => {
847
- const result = await ctx.service.compressionGuidelinesOptimize({
848
- dryRun: input.dryRun === true,
849
- eventLimit: optNum(input.eventLimit),
850
- });
851
- return { result };
852
- },
853
- });
854
-
855
- defineOperation({
856
- name: "compression_guidelines_activate",
857
- description: "Activate compression guidelines.",
858
- schema: looseSchema,
859
- handler: async (input, ctx) => {
860
- const result = await ctx.service.compressionGuidelinesActivate({
861
- expectedContentHash: optStr(input.expectedContentHash) ?? "",
862
- expectedGuidelineVersion: optNum(input.expectedGuidelineVersion),
863
- });
864
- return { result };
865
- },
866
- });
867
-
868
- // ===========================================================================
869
- // Memory read/debug, graph, feedback, promote, outcome operations
870
- // ===========================================================================
871
-
872
- defineOperation({
873
- name: "memory_profile",
874
- description: "Get the memory profile.",
875
- schema: looseSchema,
876
- handler: async (input, ctx) => {
877
- const result = await ctx.service.memoryProfile(optStr(input.namespace), ctx.authenticatedPrincipal);
878
- return { result };
879
- },
880
- });
881
-
882
- defineOperation({
883
- name: "memory_entities_list",
884
- description: "List memory entities.",
885
- schema: looseSchema,
886
- handler: async (input, ctx) => {
887
- const result = await ctx.service.memoryEntitiesList(optStr(input.namespace), ctx.authenticatedPrincipal);
888
- return { result };
889
- },
890
- });
891
-
892
- defineOperation({
893
- name: "memory_questions",
894
- description: "List memory questions.",
895
- schema: looseSchema,
896
- handler: async (input, ctx) => {
897
- const result = await ctx.service.memoryQuestions(optStr(input.namespace), ctx.authenticatedPrincipal);
898
- return { result };
899
- },
900
- });
901
-
902
- defineOperation({
903
- name: "memory_last_recall",
904
- description: "Get last recall snapshot.",
905
- schema: looseSchema,
906
- handler: async (input, ctx) => {
907
- const result = await ctx.service.lastRecallSnapshot(optStr(input.sessionKey));
908
- return { result };
909
- },
910
- });
911
-
912
- defineOperation({
913
- name: "memory_intent_debug",
914
- description: "Debug memory intent.",
915
- schema: looseSchema,
916
- handler: async (input, ctx) => {
917
- const result = await ctx.service.intentDebug(optStr(input.namespace));
918
- return { result };
919
- },
920
- });
921
-
922
- defineOperation({
923
- name: "memory_qmd_debug",
924
- description: "Debug QMD.",
925
- schema: looseSchema,
926
- handler: async (input, ctx) => {
927
- const result = await ctx.service.qmdDebug(optStr(input.namespace));
928
- return { result };
929
- },
930
- });
931
-
932
- defineOperation({
933
- name: "memory_graph_explain",
934
- description: "Explain the memory graph.",
935
- schema: looseSchema,
936
- handler: async (input, ctx) => {
937
- const result = await ctx.service.graphExplainLastRecall(optStr(input.namespace));
938
- return { result };
939
- },
940
- });
941
-
942
- defineOperation({
943
- name: "graph_snapshot",
944
- description: "Get a graph snapshot.",
945
- schema: looseSchema,
946
- handler: async (input, ctx) => {
947
- const result = await ctx.service.graphSnapshot({
948
- namespace: optStr(input.namespace),
949
- limit: optNum(input.limit),
950
- since: optStr(input.since),
951
- focusNodeId: optStr(input.focusNodeId),
952
- categories: optStrArr(input.categories),
953
- }, ctx.authenticatedPrincipal);
954
- return { result };
955
- },
956
- });
957
-
958
- defineOperation({
959
- name: "memory_feedback",
960
- description: "Record memory feedback.",
961
- schema: looseSchema,
962
- handler: async (input, ctx) => {
963
- const result = await ctx.service.memoryFeedback({
964
- memoryId: optStr(input.memoryId) ?? "",
965
- vote: optStr(input.vote) as "up" | "down",
966
- note: optStr(input.note),
967
- });
968
- return { result };
969
- },
970
- });
971
-
972
- defineOperation({
973
- name: "memory_promote",
974
- description: "Promote a memory.",
975
- schema: looseSchema,
976
- handler: async (input, ctx) => {
977
- const result = await ctx.service.memoryPromote({
978
- memoryId: optStr(input.memoryId) ?? "",
979
- namespace: optStr(input.namespace),
980
- sessionKey: optStr(input.sessionKey),
981
- principal: ctx.authenticatedPrincipal,
982
- });
983
- return { result };
984
- },
985
- });
986
-
987
- defineOperation({
988
- name: "memory_outcome",
989
- description: "Record a memory outcome.",
990
- schema: looseSchema,
991
- handler: async (input, ctx) => {
992
- const result = await ctx.service.memoryOutcome({
993
- memoryId: optStr(input.memoryId) ?? "",
994
- outcome: optStr(input.outcome) as "success" | "failure",
995
- namespace: optStr(input.namespace),
996
- sessionKey: optStr(input.sessionKey),
997
- timestamp: optStr(input.timestamp),
998
- principal: ctx.authenticatedPrincipal,
999
- });
1000
- return { result };
1001
- },
1002
- });
1003
-
1004
- defineOperation({
1005
- name: "memory_action_apply",
1006
- description: "Apply a memory action.",
1007
- schema: looseSchema,
1008
- handler: async (input, ctx) => {
1009
- const result = await ctx.service.memoryActionApply({
1010
- action: optStr(input.action) ?? "",
1011
- outcome: optStr(input.outcome),
1012
- reason: optStr(input.reason),
1013
- memoryId: optStr(input.memoryId) ?? "",
1014
- namespace: optStr(input.namespace),
1015
- sessionKey: optStr(input.sessionKey),
1016
- content: optStr(input.content),
1017
- category: optStr(input.category),
1018
- linkTargetId: optStr(input.linkTargetId),
1019
- linkType: optStr(input.linkType),
1020
- linkStrength: optNum(input.linkStrength),
1021
- artifactType: optStr(input.artifactType),
1022
- execute: input.execute === true,
1023
- sourcePrompt: optStr(input.sourcePrompt),
1024
- dryRun: input.dryRun === true,
1025
- principal: ctx.authenticatedPrincipal,
1026
- });
1027
- return { result };
1028
- },
1029
- });
1030
-
1031
- defineOperation({
1032
- name: "context_checkpoint",
1033
- description: "Create a context checkpoint.",
1034
- schema: looseSchema,
1035
- handler: async (input, ctx) => {
1036
- const result = await ctx.service.contextCheckpoint({
1037
- sessionKey: optStr(input.sessionKey) ?? "",
1038
- context: optStr(input.context) ?? "",
1039
- namespace: optStr(input.namespace),
1040
- principal: ctx.authenticatedPrincipal,
1041
- });
1042
- return { result };
1043
- },
1044
- });
1045
-
1046
- defineOperation({
1047
- name: "briefing",
1048
- description: "Get a daily context briefing.",
1049
- schema: looseSchema,
1050
- handler: async (input, ctx) => {
1051
- const result = await ctx.service.briefing({
1052
- since: optStr(input.since),
1053
- focus: optStr(input.focus),
1054
- namespace: optStr(input.namespace),
1055
- format: optStr(input.format) as "json" | "markdown" | undefined,
1056
- maxFollowups: optNum(input.maxFollowups),
1057
- principal: ctx.authenticatedPrincipal,
1058
- });
1059
- return { result };
1060
- },
1061
- });
1062
-
1063
- // ===========================================================================
1064
- // Contradiction review, scan, graph-edge-decay (dynamic-import handlers)
1065
- // ===========================================================================
1066
-
1067
- defineOperation({
1068
- name: "review_list",
1069
- description: "List contradiction review pairs.",
1070
- schema: looseSchema,
1071
- handler: async (input, ctx) => {
1072
- const { isDefaultReviewNamespace, listPairs } = await import("./contradiction/contradiction-review.js");
1073
- const VALID_FILTERS = new Set(["all", "unresolved", "contradicts", "independent", "duplicates", "needs-user"]);
1074
- const rawFilter = optStr(input.filter) ?? "unresolved";
1075
- if (!VALID_FILTERS.has(rawFilter)) {
1076
- throw new EngramAccessInputError("Invalid filter '" + rawFilter + "'. Valid: " + [...VALID_FILTERS].join(", "));
1077
- }
1078
- const filter = rawFilter as "all" | "unresolved" | "contradicts" | "independent" | "duplicates" | "needs-user";
108
+ if (input.budget !== undefined) { const p = typeof input.budget === "number" ? input.budget : typeof input.budget === "string" ? Number(input.budget) : undefined; if (p === undefined || !Number.isFinite(p) || p <= 0 || !Number.isInteger(p)) throw new EngramAccessInputError("recall_xray: budget expects a positive integer"); budget = p; }
109
+ const dr = optStr(input.disclosure);
110
+ return { result: await ctx.service.recallXray({ query: defStr(input.query, ""), sessionKey: optStr(input.sessionKey), namespace: optStr(input.namespace), budget, authenticatedPrincipal: ctx.authenticatedPrincipal, ...(dr && dr !== "" ? { disclosure: dr as RecallDisclosure } : {}) }) };
111
+ },
112
+ });
113
+
114
+ // === WEARABLES ===
115
+ defineOperation({ name: "wearables_status", description: "Wearables status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.wearablesStatus() }) });
116
+ defineOperation({ name: "wearables_sync", description: "Sync wearables.", schema: strictSchema({ source: S.str, date: S.str, days: S.flexNum, forceMemories: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesSync({ source: optStr(input.source), date: optStr(input.date), days: typeof input.days === "number" ? input.days : typeof input.days === "string" && Number.isFinite(Number(input.days)) ? Number(input.days) : undefined, forceMemories: optBool(input.forceMemories) }) }) });
117
+ defineOperation({ name: "transcript_day", description: "Transcript for a day.", schema: strictSchema({ date: S.str, source: S.str }), handler: async (input, ctx) => { const d = defStr(input.date, ""); if (d.trim().length === 0) throw new EngramAccessInputError("transcript_day: date is required (YYYY-MM-DD)"); return { result: await ctx.service.wearablesTranscriptDay({ date: d, source: optStr(input.source) }) }; } });
118
+ defineOperation({ name: "transcript_search", description: "Search transcripts.", schema: strictSchema({ query: S.str, source: S.str, from: S.str, to: S.str, limit: S.flexNum }), handler: async (input, ctx) => { const q = defStr(input.query, ""); if (q.trim().length === 0) throw new EngramAccessInputError("transcript_search: query is required"); return { result: await ctx.service.wearablesTranscriptSearch({ query: q, source: optStr(input.source), from: optStr(input.from), to: optStr(input.to), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined }) }; } });
119
+ defineOperation({ name: "transcript_memories", description: "Transcript memories.", schema: strictSchema({ source: S.str, date: S.str, limit: S.flexNum }), handler: async (input, ctx) => ({ result: await ctx.service.wearablesTranscriptMemories({ source: optStr(input.source), date: optStr(input.date), limit: typeof input.limit === "number" ? input.limit : typeof input.limit === "string" && Number.isFinite(Number(input.limit)) ? Number(input.limit) : undefined }) }) });
120
+
121
+ // === ACTION CONFIDENCE + INSPECTOR + CAPSULE ===
122
+ defineOperation({ name: "action_confidence", description: "Action confidence.", schema: strictSchema({ intendedAction: S.str, confidence: S.num, risk: S.str, contextReadiness: S.str, currentContextScopes: S.strArr, userRules: z.array(z.unknown()).optional(), retrievedMemories: z.array(z.unknown()).optional() }), handler: async (input, ctx) => { const req: Record<string, unknown> = {}; if (input.intendedAction !== undefined) req.intendedAction = optStr(input.intendedAction); if (input.confidence !== undefined) req.confidence = optNum(input.confidence); if (input.risk !== undefined) req.risk = optStr(input.risk) as "low" | "medium" | "high" | "irreversible" | "restricted" | undefined; if (input.contextReadiness !== undefined) req.contextReadiness = optStr(input.contextReadiness) as "none" | "partial" | "sufficient" | undefined; if (input.currentContextScopes !== undefined) req.currentContextScopes = optStrArr(input.currentContextScopes); if (input.userRules !== undefined) req.userRules = input.userRules; if (input.retrievedMemories !== undefined) req.retrievedMemories = input.retrievedMemories; return { result: await ctx.service.actionConfidence(req) }; } });
123
+ defineOperation({ name: "chatgpt_memory_inspector", description: "Memory inspector.", schema: strictSchema({ query: S.str, sessionKey: S.str, namespace: S.str, currentContextScopes: S.strArr, allowUnverifiedPreview: S.bool }),
124
+ handler: async (input, ctx) => {
125
+ const q = defStr(input.query, "");
126
+ if (q.trim().length === 0) throw new EngramAccessInputError("chatgpt_memory_inspector requires a non-empty query string");
127
+ const ii: RemnicChatGptMemoryInspectorInput = { query: q.trim() };
128
+ if (typeof input.sessionKey === "string" && input.sessionKey.trim().length > 0) ii.sessionKey = input.sessionKey;
129
+ if (typeof input.namespace === "string" && input.namespace.trim().length > 0) ii.namespace = input.namespace;
130
+ if (input.currentContextScopes !== undefined) ii.currentContextScopes = input.currentContextScopes as string[];
131
+ if (input.allowUnverifiedPreview !== undefined) ii.allowUnverifiedPreview = input.allowUnverifiedPreview as boolean;
132
+ const rsk = ii.sessionKey ?? (ctx.authenticatedPrincipal ? "remnic:chatgpt-memory-inspector:" + randomUUID() : undefined);
133
+ const xr = await ctx.service.recallXray({ query: ii.query, sessionKey: rsk, namespace: ii.namespace, currentContextScopes: ii.currentContextScopes, authenticatedPrincipal: ctx.authenticatedPrincipal, mode: "full", disclosure: "chunk", includeRecall: true });
134
+ const x = xr.snapshotFound === true ? (xr.snapshot ?? null) : null;
135
+ const r = xr.recall ?? { query: ii.query, namespace: ii.namespace ?? x?.namespace ?? "global", context: "", count: 0, memoryIds: [], results: [], fallbackUsed: false, sourcesUsed: [], disclosure: "chunk" as const };
136
+ const ac = await ctx.service.actionConfidence(buildChatGptMemoryInspectorActionRequest(ii, r, x));
137
+ return { result: buildChatGptMemoryInspectorResult(ii, r, x, ac) };
138
+ },
139
+ });
140
+ defineOperation({ name: "day_summary", description: "Day summary.", schema: strictSchema({ memories: S.str, sessionKey: S.str, namespace: S.str, timeZone: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => { const req: Record<string, unknown> = {}; if (input.memories !== undefined) req.memories = optStr(input.memories); if (input.sessionKey !== undefined) req.sessionKey = optStr(input.sessionKey); if (input.namespace !== undefined) req.namespace = optStr(input.namespace); if (input.timeZone !== undefined) req.timeZone = optStr(input.timeZone); return { result: await ctx.service.daySummary(req) }; } });
141
+ defineOperation({ name: "capsule_export", description: "Export capsule.", schema: strictSchema({ name: S.str, namespace: S.str, since: S.str, includeKinds: S.strArr, peerIds: S.strArr, includeTranscripts: S.bool, encrypt: S.bool, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.capsuleExport({ name: optStr(input.name) ?? "", namespace: optStr(input.namespace), since: optStr(input.since), includeKinds: optStrArr(input.includeKinds), peerIds: optStrArr(input.peerIds), includeTranscripts: optBool(input.includeTranscripts as unknown), encrypt: optBool(input.encrypt as unknown), principal: ctx.authenticatedPrincipal } as unknown as Parameters<EngramAccessService["capsuleExport"]>[0]) }) });
142
+ defineOperation({ name: "capsule_import", description: "Import capsule.", schema: strictSchema({ archivePath: S.str, namespace: S.str, mode: S.str, passphrase: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.capsuleImport({ archivePath: expandTildePath(optStr(input.archivePath) ?? ""), namespace: optStr(input.namespace), mode: optStr(input.mode) as "skip" | "overwrite" | "fork" | undefined, passphrase: optStr(input.passphrase), principal: ctx.authenticatedPrincipal }) }) });
143
+ defineOperation({ name: "capsule_list", description: "List capsules.", schema: strictSchema({ namespace: S.str, sessionKey: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => {
144
+ const rp = ctx.authenticatedPrincipal ?? (typeof input.sessionKey === "string" && input.sessionKey.length > 0 && ctx.service.configRef ? resolvePrincipal(input.sessionKey, ctx.service.configRef) : undefined);
145
+ return { result: await ctx.service.capsuleList({ namespace: optStr(input.namespace), principal: rp }) };
146
+ } });
147
+
148
+ // === GOVERNANCE ===
149
+ defineOperation({ name: "memory_governance_run", description: "Run governance.", schema: strictSchema({ namespace: S.str, mode: S.str, recentDays: S.num, maxMemories: S.num, batchSize: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.governanceRun({ namespace: optStr(input.namespace), mode: optStr(input.mode) === "apply" ? "apply" : "shadow", recentDays: optNum(input.recentDays), maxMemories: optNum(input.maxMemories), batchSize: optNum(input.batchSize), authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
150
+ defineOperation({ name: "procedure_mining_run", description: "Run procedure mining.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.procedureMiningRun({ namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
151
+ defineOperation({ name: "pattern_reinforcement_run", description: "Run pattern reinforcement.", schema: strictSchema({ namespace: S.str, force: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.patternReinforcementRun({ namespace: optStr(input.namespace), force: input.force === true, authenticatedPrincipal: ctx.authenticatedPrincipal }, ctx.authenticatedPrincipal) }) });
152
+ defineOperation({ name: "procedural_stats", description: "Procedural stats.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.procedureStats({ namespace: optStr(input.namespace) }, ctx.authenticatedPrincipal) }) });
153
+
154
+ // === MEMORY/ENTITY/OBSERVE/LCM ===
155
+ defineOperation({ name: "memory_timeline", description: "Memory timeline.", schema: strictSchema({ memoryId: S.str, namespace: S.str, limit: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.memoryTimeline(optStr(input.memoryId) ?? "", optStr(input.namespace), optNum(input.limit) ?? 200, ctx.authenticatedPrincipal) }) });
156
+ defineOperation({ name: "suggestion_submit", description: "Submit suggestion.", schema: strictSchema({ schemaVersion: S.num, idempotencyKey: S.str, dryRun: S.bool, sessionKey: S.str, content: S.str, category: S.str, confidence: S.num, namespace: S.str, tags: S.strArr, entityRef: S.str, ttl: S.str, sourceReason: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.suggestionSubmit({ schemaVersion: optNum(input.schemaVersion), idempotencyKey: optStr(input.idempotencyKey), dryRun: input.dryRun === true, sessionKey: optStr(input.sessionKey), authenticatedPrincipal: ctx.authenticatedPrincipal, content: optStr(input.content) ?? "", category: optStr(input.category), confidence: optNum(input.confidence), namespace: optStr(input.namespace), tags: optStrArr(input.tags), entityRef: optStr(input.entityRef), ttl: optStr(input.ttl), sourceReason: optStr(input.sourceReason), cwd: optStr(input.cwd), projectTag: optStr(input.projectTag) }) }) });
157
+ defineOperation({ name: "entity_get", description: "Get entity.", schema: strictSchema({ name: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.entityGet(optStr(input.name) ?? "", optStr(input.namespace)) }) });
158
+ defineOperation({ name: "review_queue_list", description: "List review queue.", schema: strictSchema({ runId: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.reviewQueue(optStr(input.runId) ?? "", optStr(input.namespace), ctx.authenticatedPrincipal) }) });
159
+ defineOperation({ name: "observe", description: "Observe messages.", schema: strictSchema({ sessionKey: S.str, messages: z.array(z.object({ role: z.string(), content: z.string(), parts: z.array(z.unknown()).optional(), rawContent: z.unknown().optional(), sourceFormat: z.string().optional() }).passthrough()), skipExtraction: S.bool, idempotencyKey: S.str, namespace: S.str, cwd: S.str, projectTag: S.str }),
160
+ handler: async (input, ctx) => ({ result: await ctx.service.observe({ sessionKey: defStr(input.sessionKey, ""), messages: (input.messages as unknown[]).map((m: unknown) => { const r = m as Record<string, unknown>; return { role: String(r.role), content: String(r.content), parts: r.parts as unknown[], rawContent: r.rawContent as string | undefined, sourceFormat: r.sourceFormat as string | undefined }; }) as never, skipExtraction: input.skipExtraction === true, idempotencyKey: optStr(input.idempotencyKey), namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal, cwd: optStr(input.cwd), projectTag: optStr(input.projectTag) }, ctx.hooks?.enforceWriteQuota ? { enforceWriteQuota: ctx.hooks.enforceWriteQuota } : undefined) }),
161
+ });
162
+ defineOperation({ name: "lcm_search", description: "Search LCM.", schema: strictSchema({ query: S.str, sessionKey: S.str, sessionPrefix: S.str, namespace: S.str, limit: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.lcmSearch({ query: defStr(input.query, ""), sessionKey: optStr(input.sessionKey), sessionPrefix: optStr(input.sessionPrefix), namespace: optStr(input.namespace), limit: optNum(input.limit), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
163
+ defineOperation({ name: "lcm_compaction_flush", description: "Flush LCM compaction.", schema: strictSchema({ sessionKey: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.lcmCompactionFlush({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
164
+ defineOperation({ name: "lcm_compaction_record", description: "Record LCM compaction.", schema: strictSchema({ sessionKey: S.str, namespace: S.str, tokensBefore: S.num, tokensAfter: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.lcmCompactionRecord({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), tokensBefore: optNum(input.tokensBefore) ?? 0, tokensAfter: optNum(input.tokensAfter) ?? 0, authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
165
+
166
+ // === CONTINUITY/IDENTITY ===
167
+ defineOperation({ name: "continuity_audit_generate", description: "Continuity audit.", schema: strictSchema({ period: S.str, key: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.continuityAuditGenerate({ period: optStr(input.period) === "monthly" ? "monthly" : optStr(input.period) === "weekly" ? "weekly" : undefined, key: optStr(input.key) }) }) });
168
+ defineOperation({ name: "continuity_incident_open", description: "Open incident.", schema: strictSchema({ symptom: S.str, namespace: S.str, triggerWindow: S.str, suspectedCause: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.continuityIncidentOpen({ symptom: optStr(input.symptom) ?? "", namespace: optStr(input.namespace), triggerWindow: optStr(input.triggerWindow), suspectedCause: optStr(input.suspectedCause), principal: ctx.authenticatedPrincipal }) }) });
169
+ defineOperation({ name: "continuity_incident_close", description: "Close incident.", schema: strictSchema({ id: S.str, namespace: S.str, fixApplied: S.str, verificationResult: S.str, preventiveRule: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.continuityIncidentClose({ id: optStr(input.id) ?? "", namespace: optStr(input.namespace), fixApplied: optStr(input.fixApplied) ?? "", verificationResult: optStr(input.verificationResult) ?? "", preventiveRule: optStr(input.preventiveRule), principal: ctx.authenticatedPrincipal }) }) });
170
+ defineOperation({ name: "continuity_incident_list", description: "List incidents.", schema: strictSchema({ state: S.str, namespace: S.str, limit: S.num }), handler: async (input, ctx) => { const st = optStr(input.state); return { result: await ctx.service.continuityIncidentList({ state: st === "closed" ? "closed" : st === "all" ? "all" : st === "open" ? "open" : undefined, namespace: optStr(input.namespace), limit: optNum(input.limit), principal: ctx.authenticatedPrincipal }) }; } });
171
+ defineOperation({ name: "continuity_loop_add_or_update", description: "Add/update loop.", schema: strictSchema({ id: S.str, cadence: S.str, purpose: S.str, status: S.str, killCondition: S.str, namespace: S.str, lastReviewed: S.str, notes: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.continuityLoopAddOrUpdate({ id: optStr(input.id) ?? "", cadence: (optStr(input.cadence) as "daily" | "weekly" | "monthly" | "quarterly") ?? "weekly", purpose: optStr(input.purpose) ?? "", status: (optStr(input.status) as "active" | "paused" | "retired") ?? "active", killCondition: optStr(input.killCondition) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, lastReviewed: optStr(input.lastReviewed), notes: optStr(input.notes) }) }) });
172
+ defineOperation({ name: "continuity_loop_review", description: "Review loop.", schema: strictSchema({ id: S.str, namespace: S.str, status: S.str, notes: S.str, reviewedAt: S.str }), handler: async (input, ctx) => { const st = optStr(input.status); return { result: await ctx.service.continuityLoopReview({ id: optStr(input.id) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, status: st === "active" || st === "paused" || st === "retired" ? st as "active" | "paused" | "retired" : undefined, notes: optStr(input.notes), reviewedAt: optStr(input.reviewedAt) }) }; } });
173
+ defineOperation({ name: "identity_anchor_get", description: "Get identity anchor.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.identityAnchorGet({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
174
+ defineOperation({ name: "identity_anchor_update", description: "Update identity anchor.", schema: strictSchema({ namespace: S.str, identityTraits: S.str, communicationPreferences: S.str, operatingPrinciples: S.str, continuityNotes: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.identityAnchorUpdate({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, identityTraits: optStr(input.identityTraits), communicationPreferences: optStr(input.communicationPreferences), operatingPrinciples: optStr(input.operatingPrinciples), continuityNotes: optStr(input.continuityNotes) }) }) });
175
+ defineOperation({ name: "memory_identity", description: "Memory identity.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryIdentity({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
176
+
177
+ // === WORK/SHARED ===
178
+ defineOperation({ name: "work_task", description: "Manage work task.", schema: strictSchema({ action: S.str, id: S.str, title: S.str, description: S.str, status: S.str, priority: S.str, owner: S.str, assignee: S.str, projectId: S.str, tags: S.strArr, dueAt: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.workTask({ action: (optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "transition") ?? "list", id: optStr(input.id), title: optStr(input.title), description: optStr(input.description), status: optStr(input.status), priority: optStr(input.priority), owner: optStr(input.owner), assignee: optStr(input.assignee), projectId: optStr(input.projectId), tags: optStrArr(input.tags), dueAt: optStr(input.dueAt) }) }) });
179
+ defineOperation({ name: "work_project", description: "Manage work project.", schema: strictSchema({ action: S.str, id: S.str, name: S.str, description: S.str, status: S.str, owner: S.str, tags: S.strArr, taskId: S.str, projectId: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.workProject({ action: (optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "link_task") ?? "list", id: optStr(input.id), name: optStr(input.name), description: optStr(input.description), status: optStr(input.status), owner: optStr(input.owner), tags: optStrArr(input.tags), taskId: optStr(input.taskId), projectId: optStr(input.projectId) }) }) });
180
+ defineOperation({ name: "work_board", description: "Manage work board.", schema: strictSchema({ action: S.str, projectId: S.str, snapshotJson: S.str, linkToMemory: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.workBoard({ action: (optStr(input.action) as "export_markdown" | "export_snapshot" | "import_snapshot") ?? "export_markdown", projectId: optStr(input.projectId) ?? "", snapshotJson: optStr(input.snapshotJson) ?? "", linkToMemory: input.linkToMemory === true }) }) });
181
+ defineOperation({ name: "shared_context_write_output", description: "Write shared output.", schema: strictSchema({ agentId: S.str, title: S.str, content: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.sharedContextWriteOutput({ agentId: optStr(input.agentId) ?? "", title: optStr(input.title) ?? "", content: optStr(input.content) ?? "" }) }) });
182
+ defineOperation({ name: "shared_feedback_record", description: "Record shared feedback.", schema: strictSchema({ agent: S.str, decision: S.str, reason: S.str, date: S.str, learning: S.str, outcome: S.str, severity: S.str, confidence: S.num, workflow: S.str, tags: S.strArr, evidenceWindowStart: S.str, evidenceWindowEnd: S.str, refs: S.strArr }), handler: async (input, ctx) => { const sv = optStr(input.severity); return { result: await ctx.service.sharedFeedbackRecord({ agent: optStr(input.agent) ?? "", decision: (optStr(input.decision) as "rejected" | "approved" | "approved_with_feedback") ?? "approved", reason: optStr(input.reason) ?? "", date: optStr(input.date), learning: optStr(input.learning), outcome: optStr(input.outcome), severity: sv === "low" || sv === "medium" || sv === "high" ? sv as "low" | "medium" | "high" : undefined, confidence: optNum(input.confidence), workflow: optStr(input.workflow), tags: optStrArr(input.tags), evidenceWindowStart: optStr(input.evidenceWindowStart), evidenceWindowEnd: optStr(input.evidenceWindowEnd), refs: optStrArr(input.refs) }) }; } });
183
+ defineOperation({ name: "shared_priorities_append", description: "Append priorities.", schema: strictSchema({ agentId: S.str, text: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.sharedPrioritiesAppend({ agentId: optStr(input.agentId) ?? "", text: optStr(input.text) ?? "" }) }) });
184
+ defineOperation({ name: "shared_context_cross_signals_run", description: "Run cross signals.", schema: strictSchema({ date: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.sharedContextCrossSignalsRun({ date: optStr(input.date) }) }) });
185
+ defineOperation({ name: "shared_context_curate_daily", description: "Curate daily.", schema: strictSchema({ date: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.sharedContextCurateDaily({ date: optStr(input.date) }) }) });
186
+ defineOperation({ name: "compounding_weekly_synthesize", description: "Weekly synthesize.", schema: strictSchema({ weekId: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.compoundingWeeklySynthesize({ weekId: optStr(input.weekId) }) }) });
187
+ defineOperation({ name: "compounding_promote_candidate", description: "Promote candidate.", schema: strictSchema({ weekId: S.str, candidateId: S.str, dryRun: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.compoundingPromoteCandidate({ weekId: optStr(input.weekId) ?? "", candidateId: optStr(input.candidateId) ?? "", dryRun: input.dryRun === true }) }) });
188
+ defineOperation({ name: "compression_guidelines_optimize", description: "Optimize guidelines.", schema: strictSchema({ dryRun: S.bool, eventLimit: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.compressionGuidelinesOptimize({ dryRun: input.dryRun === true, eventLimit: optNum(input.eventLimit) }) }) });
189
+ defineOperation({ name: "compression_guidelines_activate", description: "Activate guidelines.", schema: strictSchema({ expectedContentHash: S.str, expectedGuidelineVersion: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.compressionGuidelinesActivate({ expectedContentHash: optStr(input.expectedContentHash), expectedGuidelineVersion: optNum(input.expectedGuidelineVersion) }) }) });
190
+
191
+ // === MEMORY DEBUG/GRAPH/FEEDBACK ===
192
+ defineOperation({ name: "memory_profile", description: "Memory profile.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryProfile(optStr(input.namespace), ctx.authenticatedPrincipal) }) });
193
+ defineOperation({ name: "memory_entities_list", description: "List entities.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryEntitiesList(optStr(input.namespace), ctx.authenticatedPrincipal) }) });
194
+ defineOperation({ name: "memory_questions", description: "Memory questions.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryQuestions(optStr(input.namespace), ctx.authenticatedPrincipal) }) });
195
+ defineOperation({ name: "memory_last_recall", description: "Last recall.", schema: strictSchema({ sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.lastRecallSnapshot(optStr(input.sessionKey)) }) });
196
+ defineOperation({ name: "memory_intent_debug", description: "Debug intent.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.intentDebug(optStr(input.namespace)) }) });
197
+ defineOperation({ name: "memory_qmd_debug", description: "Debug QMD.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.qmdDebug(optStr(input.namespace)) }) });
198
+ defineOperation({ name: "memory_graph_explain", description: "Explain graph.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.graphExplainLastRecall(optStr(input.namespace)) }) });
199
+ defineOperation({ name: "graph_snapshot", description: "Graph snapshot.", schema: strictSchema({ namespace: S.str, limit: S.num, since: S.str, focusNodeId: S.str, categories: S.strArr }), handler: async (input, ctx) => ({ result: await ctx.service.graphSnapshot({ namespace: optStr(input.namespace), limit: optNum(input.limit), since: optStr(input.since), focusNodeId: optStr(input.focusNodeId), categories: optStrArr(input.categories) }, ctx.authenticatedPrincipal) }) });
200
+ defineOperation({ name: "memory_feedback", description: "Record feedback.", schema: strictSchema({ memoryId: S.str, vote: S.str, note: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryFeedback({ memoryId: optStr(input.memoryId) ?? "", vote: optStr(input.vote) === "down" ? "down" : "up", note: optStr(input.note) }) }) });
201
+ defineOperation({ name: "memory_promote", description: "Promote memory.", schema: strictSchema({ memoryId: S.str, namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.memoryPromote({ memoryId: optStr(input.memoryId) ?? "", namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey), principal: ctx.authenticatedPrincipal }) }) });
202
+ defineOperation({ name: "memory_outcome", description: "Record outcome.", schema: strictSchema({ memoryId: S.str, outcome: S.str, namespace: S.str, sessionKey: S.str, timestamp: S.str }), handler: async (input, ctx) => { const o = optStr(input.outcome); if (o !== "success" && o !== "failure") throw new EngramAccessInputError("memory_outcome: outcome must be \"success\" or \"failure\"; got " + JSON.stringify(o)); return { result: await ctx.service.memoryOutcome({ memoryId: optStr(input.memoryId) ?? "", outcome: o, namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey), timestamp: optStr(input.timestamp), principal: ctx.authenticatedPrincipal }) }; } });
203
+ defineOperation({ name: "memory_action_apply", description: "Apply action.", schema: strictSchema({ action: S.str, outcome: S.str, reason: S.str, memoryId: S.str, namespace: S.str, sessionKey: S.str, content: S.str, category: S.str, linkTargetId: S.str, linkType: S.str, linkStrength: S.num, artifactType: S.str, execute: S.bool, sourcePrompt: S.str, dryRun: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.memoryActionApply({ action: optStr(input.action) ?? "", outcome: optStr(input.outcome), reason: optStr(input.reason), memoryId: optStr(input.memoryId) ?? "", namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey), content: optStr(input.content), category: optStr(input.category), linkTargetId: optStr(input.linkTargetId), linkType: optStr(input.linkType), linkStrength: optNum(input.linkStrength), artifactType: optStr(input.artifactType), execute: optBool(input.execute), sourcePrompt: optStr(input.sourcePrompt), dryRun: input.dryRun === true, principal: ctx.authenticatedPrincipal }) }) });
204
+ defineOperation({ name: "context_checkpoint", description: "Context checkpoint.", schema: strictSchema({ sessionKey: S.str, context: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.contextCheckpoint({ sessionKey: optStr(input.sessionKey) ?? "", context: optStr(input.context) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
205
+ defineOperation({ name: "briefing", description: "Daily briefing.", schema: strictSchema({ since: S.str, focus: S.str, namespace: S.str, format: S.str, maxFollowups: S.num }), handler: async (input, ctx) => { const rf = optStr(input.format); const fe = validateBriefingFormat(rf); if (fe) throw new EngramAccessInputError(fe); return { result: await ctx.service.briefing({ since: optStr(input.since), focus: optStr(input.focus), namespace: optStr(input.namespace), format: rf as "json" | "markdown" | undefined, maxFollowups: optNum(input.maxFollowups), principal: ctx.authenticatedPrincipal }) }; } });
206
+
207
+ // === CONTRADICTION/REVIEW ===
208
+ defineOperation({ name: "review_list", description: "List review pairs.", schema: strictSchema({ filter: S.str, namespace: S.str, limit: S.num }),
209
+ handler: async (input, ctx) => {
210
+ const VF = new Set(["all", "unresolved", "contradicts", "independent", "duplicates", "needs-user"]);
211
+ const rf = optStr(input.filter) ?? "unresolved";
212
+ if (!VF.has(rf)) throw new EngramAccessInputError("Invalid filter '" + rf + "'. Valid: " + [...VF].join(", "));
1079
213
  const ns = optStr(input.namespace);
1080
- const limit = optNum(input.limit) ?? 50;
1081
214
  const resolved = await ctx.service.getReadableStorageForNamespace(ns, ctx.authenticatedPrincipal);
1082
- const reviewNamespace = ctx.service.configRef.namespacesEnabled ? resolved.namespace : undefined;
1083
- const includeUnscopedForNamespace = Boolean(
1084
- reviewNamespace && isDefaultReviewNamespace(ctx.service.configRef.defaultNamespace, ns, reviewNamespace),
1085
- );
1086
- const result = await listPairs(ctx.service.memoryDir, { filter, namespace: reviewNamespace, includeUnscopedForNamespace, limit });
1087
- return { result };
1088
- },
1089
- });
1090
-
1091
- defineOperation({
1092
- name: "review_resolve",
1093
- description: "Resolve a contradiction pair.",
1094
- schema: looseSchema,
1095
- handler: async (input, ctx) => {
1096
- const pairId = defStr(input.pairId, "");
1097
- const verb = defStr(input.verb, "");
1098
- if (!pairId) throw new EngramAccessInputError("pairId is required");
1099
- if (!verb) throw new EngramAccessInputError("verb is required");
1100
- const { isValidResolutionVerb, executeResolution } = await import("./contradiction/resolution.js");
1101
- if (!isValidResolutionVerb(verb)) throw new EngramAccessInputError("Invalid verb: " + verb + ". Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context");
1102
- const result = await executeResolution(ctx.service.memoryDir, ctx.service.storageRef, pairId, verb, {
1103
- mergedMemoryId: optStr(input.mergedMemoryId),
1104
- mergedContent: optStr(input.mergedContent),
1105
- storageForNamespace: async (namespace: string | undefined) => {
1106
- const r = await ctx.service.getWritableStorageForNamespace(namespace, ctx.authenticatedPrincipal);
1107
- return r.storage;
1108
- },
1109
- onMergedMemoryWritten: () => { /* #1522: catalog touch at storage chokepoint */ },
1110
- });
1111
- return { result };
1112
- },
1113
- });
1114
-
1115
- defineOperation({
1116
- name: "contradiction_scan_run",
1117
- description: "Run a contradiction scan.",
1118
- schema: looseSchema,
1119
- handler: async (input, ctx) => {
1120
- const { runContradictionScan } = await import("./contradiction/contradiction-scan.js");
1121
- const result = await runContradictionScan({
1122
- storage: ctx.service.storageRef,
1123
- config: ctx.service.configRef,
1124
- memoryDir: ctx.service.memoryDir,
1125
- embeddingLookupFactory: ctx.service.embeddingLookupFactoryRef,
1126
- storageForNamespace: (namespace: string | undefined) =>
1127
- ctx.service.getWritableStorageForNamespace(namespace ?? undefined, ctx.authenticatedPrincipal),
1128
- localLlm: ctx.service.localLlmRef,
1129
- fallbackLlm: ctx.service.fallbackLlmRef,
1130
- namespace: optStr(input.namespace),
1131
- });
1132
- return { result };
1133
- },
1134
- });
1135
-
1136
- defineOperation({
1137
- name: "graph_edge_decay_run",
1138
- description: "Run graph edge decay maintenance.",
1139
- schema: looseSchema,
1140
- handler: async (input, ctx) => {
1141
- const cfg = ctx.service.configRef;
1142
- if (!cfg.graphEdgeDecayEnabled) {
1143
- return { result: { ranAt: new Date().toISOString(), disabled: true, reason: "graphEdgeDecayEnabled is false" } };
1144
- }
1145
- const { runGraphEdgeDecayMaintenanceAcrossNamespaces } = await import("./maintenance/graph-edge-decay.js");
1146
- const dryRun = input.dryRun === true;
1147
- const results = await runGraphEdgeDecayMaintenanceAcrossNamespaces(ctx.service.memoryDir, {
1148
- windowMs: cfg.graphEdgeDecayWindowMs,
1149
- perWindow: cfg.graphEdgeDecayPerWindow,
1150
- floor: cfg.graphEdgeDecayFloor,
1151
- visibilityThreshold: cfg.graphEdgeDecayVisibilityThreshold,
1152
- dryRun,
1153
- namespacesEnabled: cfg.namespacesEnabled === true,
1154
- defaultNamespace: cfg.defaultNamespace,
1155
- });
1156
- return { result: { results } };
1157
- },
1158
- });
1159
-
1160
- // ===========================================================================
1161
- // Remaining operations: summarize, profiling, connectors, peers, console, dreams
1162
- // ===========================================================================
1163
-
1164
- defineOperation({
1165
- name: "memory_summarize_hourly",
1166
- description: "Run hourly memory summarization.",
1167
- schema: looseSchema,
1168
- handler: async (_input, ctx) => ({ result: await ctx.service.memorySummarizeHourly() }),
1169
- });
1170
-
1171
- defineOperation({
1172
- name: "conversation_index_update",
1173
- description: "Update the conversation index.",
1174
- schema: looseSchema,
1175
- handler: async (input, ctx) => {
1176
- const result = await ctx.service.conversationIndexUpdate({
1177
- sessionKey: optStr(input.sessionKey),
1178
- hours: optNum(input.hours),
1179
- embed: optBool(input.embed),
1180
- });
1181
- return { result };
1182
- },
1183
- });
1184
-
1185
- defineOperation({
1186
- name: "profiling_report",
1187
- description: "Get a profiling report.",
1188
- schema: looseSchema,
1189
- handler: async (input, ctx) => {
1190
- const result = await ctx.service.profilingReport({
1191
- format: optStr(input.format),
1192
- limit: optNum(input.limit),
1193
- });
1194
- return { result };
1195
- },
1196
- });
1197
-
1198
- defineOperation({
1199
- name: "live_connectors_run",
1200
- description: "Run live connectors.",
1201
- schema: looseSchema,
1202
- handler: async (input, ctx) => {
1203
- const result = await ctx.service.liveConnectorsRun(
1204
- { authenticatedPrincipal: ctx.authenticatedPrincipal, force: input.force === true },
1205
- ctx.authenticatedPrincipal,
1206
- );
1207
- return { result };
1208
- },
1209
- });
1210
-
1211
- defineOperation({
1212
- name: "peer_list",
1213
- description: "List peers.",
1214
- schema: looseSchema,
1215
- handler: async (_input, ctx) => ({ result: await ctx.service.peerList() }),
1216
- });
1217
-
1218
- defineOperation({
1219
- name: "peer_get",
1220
- description: "Get a peer.",
1221
- schema: looseSchema,
1222
- handler: async (input, ctx) => {
1223
- const result = await ctx.service.peerGet(defStr(input.id, ""));
1224
- return { result };
1225
- },
1226
- });
1227
-
1228
- defineOperation({
1229
- name: "peer_set",
1230
- description: "Create or update a peer.",
1231
- schema: looseSchema,
1232
- handler: async (input, ctx) => {
1233
- const result = await ctx.service.peerSet({
1234
- id: optStr(input.id) ?? "",
1235
- kind: optStr(input.kind),
1236
- displayName: optStr(input.displayName),
1237
- notes: optStr(input.notes),
1238
- });
1239
- return { result };
1240
- },
1241
- });
1242
-
1243
- defineOperation({
1244
- name: "peer_delete",
1245
- description: "Delete a peer.",
1246
- schema: looseSchema,
1247
- handler: async (input, ctx) => {
1248
- const result = await ctx.service.peerDelete(defStr(input.id, ""));
1249
- return { result };
1250
- },
1251
- });
1252
-
1253
- defineOperation({
1254
- name: "peer_profile_get",
1255
- description: "Get a peer profile.",
1256
- schema: looseSchema,
1257
- handler: async (input, ctx) => {
1258
- const result = await ctx.service.peerProfileGet(optStr(input.id) ?? "");
1259
- return { result };
1260
- },
1261
- });
1262
-
1263
- defineOperation({
1264
- name: "peer_forget",
1265
- description: "Forget a peer.",
1266
- schema: looseSchema,
1267
- handler: async (input, ctx) => {
1268
- const result = await ctx.service.peerForget(optStr(input.id) ?? "", { confirm: input.confirm === true || optStr(input.confirm) === "yes" ? "yes" : "" });
1269
- return { result };
1270
- },
1271
- });
1272
-
1273
- defineOperation({
1274
- name: "console_state",
1275
- description: "Get console state.",
1276
- schema: looseSchema,
1277
- handler: async (input, ctx) => {
1278
- const result = await ctx.service.consoleState(optStr(input.namespace), ctx.authenticatedPrincipal);
1279
- return { result };
1280
- },
1281
- });
1282
-
1283
- defineOperation({
1284
- name: "dreams_status",
1285
- description: "Get dreams status.",
1286
- schema: looseSchema,
1287
- handler: async (input, ctx) => {
1288
- const result = await ctx.service.dreamsStatus({
1289
- windowHours: optNum(input.windowHours),
1290
- namespace: optStr(input.namespace),
1291
- principal: ctx.authenticatedPrincipal,
1292
- });
1293
- return { result };
1294
- },
1295
- });
1296
-
1297
- defineOperation({
1298
- name: "dreams_run",
1299
- description: "Run dreams.",
1300
- schema: looseSchema,
1301
- handler: async (input, ctx) => {
1302
- const result = await ctx.service.dreamsRun({
1303
- phase: optStr(input.phase) as import("./types.js").DreamsPhase,
1304
- dryRun: input.dryRun === true,
1305
- namespace: optStr(input.namespace),
1306
- authenticatedPrincipal: ctx.authenticatedPrincipal,
1307
- });
1308
- return { result };
1309
- },
1310
- });
1311
-
1312
- // ===========================================================================
1313
- // HTTP-only operations (routes with no direct MCP tool equivalent)
1314
- // ===========================================================================
1315
-
1316
- defineOperation({
1317
- name: "offline_sync_snapshot",
1318
- description: "Get or create an offline-sync snapshot.",
1319
- schema: looseSchema,
1320
- handler: async (_input, ctx) => {
1321
- const result = await ctx.service.offlineSyncSnapshot();
1322
- return { result };
1323
- },
1324
- });
1325
-
1326
- defineOperation({
1327
- name: "offline_sync_files",
1328
- description: "List offline-sync files.",
1329
- schema: looseSchema,
1330
- handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFiles({ paths: optStrArr(input.paths) ?? [], namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
1331
- });
1332
-
1333
- defineOperation({
1334
- name: "offline_sync_file_content",
1335
- description: "Read offline-sync file content.",
1336
- schema: looseSchema,
1337
- handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFileContent({ path: optStr(input.path) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, offset: optNum(input.offset), length: optNum(input.length) }) }),
1338
- });
1339
-
1340
- defineOperation({
1341
- name: "offline_sync_apply_file_content",
1342
- description: "Apply offline-sync file content.",
1343
- schema: looseSchema,
1344
- handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApplyFileContent({ sourceId: optStr(input.sourceId) ?? "", path: optStr(input.path) ?? "", sha256: optStr(input.sha256) ?? "", bytes: optNum(input.bytes) ?? 0, mtimeMs: optNum(input.mtimeMs) ?? 0, offset: optNum(input.offset), baseSha256: optStr(input.baseSha256), content: Buffer.from(defStr(input.content, ""), "base64"), namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
1345
- });
1346
-
1347
- defineOperation({
1348
- name: "offline_sync_apply",
1349
- description: "Apply an offline-sync snapshot.",
1350
- schema: looseSchema,
1351
- handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApply({ changeset: input.changeset, namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
1352
- });
1353
-
1354
- defineOperation({
1355
- name: "lcm_status",
1356
- description: "Get LCM status.",
1357
- schema: looseSchema,
1358
- handler: async (_input, ctx) => ({ result: await ctx.service.lcmStatus() }),
1359
- });
1360
-
1361
- defineOperation({
1362
- name: "memory_list",
1363
- description: "Browse/list memories (HTTP GET /memories).",
1364
- schema: looseSchema,
1365
- handler: async (input, ctx) => ({ result: await ctx.service.memoryBrowse() }),
1366
- });
1367
-
1368
- defineOperation({
1369
- name: "entity_list",
1370
- description: "List entities (HTTP GET /entities).",
1371
- schema: looseSchema,
1372
- handler: async (input, ctx) => ({ result: await ctx.service.entityList() }),
1373
- });
1374
-
1375
- defineOperation({
1376
- name: "maintenance_status",
1377
- description: "Get maintenance status (HTTP GET /maintenance).",
1378
- schema: looseSchema,
1379
- handler: async (input, ctx) => ({ result: await ctx.service.maintenance() }),
1380
- });
1381
-
1382
- defineOperation({
1383
- name: "quality_status",
1384
- description: "Get quality status (HTTP GET /quality).",
1385
- schema: looseSchema,
1386
- handler: async (input, ctx) => ({ result: await ctx.service.quality() }),
1387
- });
1388
-
1389
- defineOperation({
1390
- name: "trust_zones_status",
1391
- description: "Get trust-zone status.",
1392
- schema: looseSchema,
1393
- handler: async (input, ctx) => ({ result: await ctx.service.trustZoneStatus() }),
1394
- });
1395
-
1396
- defineOperation({
1397
- name: "trust_zones_records",
1398
- description: "Browse trust-zone records.",
1399
- schema: looseSchema,
1400
- handler: async (input, ctx) => ({ result: await ctx.service.trustZoneBrowse({ namespace: optStr(input.namespace), limit: optNum(input.limit), offset: optNum(input.offset) }, ctx.authenticatedPrincipal) }),
1401
- });
1402
-
1403
- defineOperation({
1404
- name: "review_disposition",
1405
- description: "Apply a review disposition.",
1406
- schema: looseSchema,
1407
- handler: async (input, ctx) => ({ result: await ctx.service.reviewDisposition({ memoryId: optStr(input.memoryId) ?? "", status: (optStr(input.status) ?? "archived") as import("./access-service.js").EngramAccessReviewDispositionRequest["status"], reasonCode: optStr(input.reasonCode) ?? "", namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
1408
- });
1409
-
1410
- defineOperation({
1411
- name: "trust_zones_promote",
1412
- description: "Promote a trust-zone record.",
1413
- schema: looseSchema,
1414
- handler: async (input, ctx) => ({ result: await ctx.service.trustZonePromote({ recordId: optStr(input.recordId) ?? "", targetZone: (optStr(input.targetZone) ?? "working") as import("./trust-zones.js").TrustZoneName, promotionReason: optStr(input.promotionReason) ?? "", dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
1415
- });
1416
-
1417
- defineOperation({
1418
- name: "trust_zones_demo_seed",
1419
- description: "Seed demo trust-zone records.",
1420
- schema: looseSchema,
1421
- handler: async (input, ctx) => ({ result: await ctx.service.trustZoneDemoSeed({ scenario: optStr(input.scenario), dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
1422
- });
1423
-
1424
- defineOperation({
1425
- name: "citations_observed",
1426
- description: "Record observed citations (HTTP POST /v1/citations/observed).",
1427
- schema: looseSchema,
1428
- handler: async (input, ctx) => {
1429
- // The HTTP handler has complex citation-entry parsing; this operation
1430
- // owns the shape validation boundary. The handler forwards the cleaned
1431
- // input so the transport-specific entry parsing stays in the surface.
1432
- return { result: { ok: true } };
1433
- },
1434
- });
1435
-
1436
- defineOperation({
1437
- name: "contradiction_detail",
1438
- description: "Get a single contradiction pair detail (HTTP GET /review/contradictions/:id).",
1439
- schema: looseSchema,
1440
- handler: async (input, ctx) => {
1441
- const { listPairs } = await import("./contradiction/contradiction-review.js");
1442
- const result = await listPairs(ctx.service.memoryDir, {
1443
- filter: "all" as const,
1444
- namespace: optStr(input.namespace),
1445
- includeUnscopedForNamespace: false,
1446
- limit: 1,
1447
- });
1448
- return { result };
1449
- },
1450
- });
1451
-
1452
- // ===========================================================================
1453
- // SSE-stream operations (endpoint registration; streaming handled by transport)
1454
- // ===========================================================================
1455
-
1456
- defineOperation({
1457
- name: "offline_sync_snapshot_stream",
1458
- description: "Stream offline-sync snapshot updates (SSE).",
1459
- schema: looseSchema,
1460
- handler: async (_input, ctx) => ({ result: await ctx.service.offlineSyncSnapshotStream() }),
1461
- });
1462
-
1463
- defineOperation({
1464
- name: "graph_events",
1465
- description: "Stream graph mutation events (SSE). Endpoint registration only.",
1466
- schema: looseSchema,
1467
- handler: async (_input, _ctx) => ({ result: { stream: "sse" } }),
1468
- });
1469
-
1470
- defineOperation({
1471
- name: "chat_message",
1472
- description: "Send a message to Remnic Chat (issue #1583). Endpoint registration only — the handler enforces the chat_disabled gate, message validation, and the confirmation protocol.",
1473
- schema: looseSchema,
1474
- handler: async (_input, _ctx) => ({ result: { ok: true } }),
1475
- });
1476
-
1477
- defineOperation({
1478
- name: "chat_events",
1479
- description: "Stream chat session transcript events (SSE, issue #1583). Endpoint registration only.",
1480
- schema: looseSchema,
1481
- handler: async (_input, _ctx) => ({ result: { stream: "sse" } }),
1482
- });
215
+ const rn = ctx.service.configRef.namespacesEnabled ? resolved.namespace : undefined;
216
+ const iun = Boolean(rn && isDefaultReviewNamespace(ctx.service.configRef.defaultNamespace, ns, rn));
217
+ return { result: await listPairs(ctx.service.memoryDir, { filter: rf as "all" | "unresolved" | "contradicts" | "independent" | "duplicates" | "needs-user", namespace: rn, includeUnscopedForNamespace: iun, limit: optNum(input.limit) ?? 50 }) };
218
+ },
219
+ });
220
+ defineOperation({ name: "review_resolve", description: "Resolve pair.", schema: strictSchema({ pairId: S.str, verb: S.str, mergedMemoryId: S.str, mergedContent: S.str }),
221
+ handler: async (input, ctx) => {
222
+ const pid = defStr(input.pairId, ""); const vb = defStr(input.verb, "");
223
+ if (!pid) throw new EngramAccessInputError("pairId is required");
224
+ if (!vb) throw new EngramAccessInputError("verb is required");
225
+ if (!isValidResolutionVerb(vb)) throw new EngramAccessInputError("Invalid verb: " + vb);
226
+ return { result: await executeResolution(ctx.service.memoryDir, ctx.service.storageRef, pid, vb, { mergedMemoryId: optStr(input.mergedMemoryId), mergedContent: optStr(input.mergedContent), storageForNamespace: async (namespace) => { const r = await ctx.service.getWritableStorageForNamespace(namespace, ctx.authenticatedPrincipal); return r.storage; }, onMergedMemoryWritten: () => {} }) };
227
+ },
228
+ });
229
+ defineOperation({ name: "contradiction_scan_run", description: "Run scan.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await runContradictionScan({ storage: ctx.service.storageRef, config: ctx.service.configRef, memoryDir: ctx.service.memoryDir, embeddingLookupFactory: ctx.service.embeddingLookupFactoryRef, storageForNamespace: (ns) => ctx.service.getWritableStorageForNamespace(ns ?? undefined, ctx.authenticatedPrincipal), localLlm: ctx.service.localLlmRef, fallbackLlm: ctx.service.fallbackLlmRef, namespace: optStr(input.namespace) }) }) });
230
+ defineOperation({ name: "graph_edge_decay_run", description: "Run edge decay.", schema: strictSchema({ dryRun: S.bool }), handler: async (input, ctx) => { const cfg = ctx.service.configRef; if (!cfg.graphEdgeDecayEnabled) return { result: { ranAt: new Date().toISOString(), disabled: true, reason: "graphEdgeDecayEnabled is false" } }; return { result: { results: await runGraphEdgeDecayMaintenanceAcrossNamespaces(ctx.service.memoryDir, { windowMs: cfg.graphEdgeDecayWindowMs, perWindow: cfg.graphEdgeDecayPerWindow, floor: cfg.graphEdgeDecayFloor, visibilityThreshold: cfg.graphEdgeDecayVisibilityThreshold, dryRun: input.dryRun === true, namespacesEnabled: cfg.namespacesEnabled === true, defaultNamespace: cfg.defaultNamespace }) } }; } });
231
+
232
+ // === SUMMARIZE/PROFILING/PEERS/CONSOLE/DREAMS ===
233
+ defineOperation({ name: "memory_summarize_hourly", description: "Hourly summarize.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.memorySummarizeHourly() }) });
234
+ defineOperation({ name: "conversation_index_update", description: "Update conv index.", schema: strictSchema({ sessionKey: S.str, hours: S.num, embed: S.bool }), handler: async (input, ctx) => { if (input.sessionKey !== undefined && typeof input.sessionKey !== "string") throw new EngramAccessInputError("sessionKey must be a string when provided"); return { result: await ctx.service.conversationIndexUpdate({ sessionKey: optStr(input.sessionKey), hours: optNum(input.hours), embed: optBool(input.embed) }) }; } });
235
+ defineOperation({ name: "profiling_report", description: "Profiling report.", schema: strictSchema({ format: S.str, limit: S.num }), handler: async (input, ctx) => { if (input.format !== undefined && typeof input.format !== "string") throw new EngramAccessInputError("format must be a string when provided"); if (input.limit !== undefined && typeof input.limit !== "number") throw new EngramAccessInputError("limit must be a number when provided"); return { result: await ctx.service.profilingReport({ format: optStr(input.format), limit: optNum(input.limit) }) }; } });
236
+ defineOperation({ name: "live_connectors_run", description: "Run connectors.", schema: strictSchema({ force: S.bool }), handler: async (input, ctx) => ({ result: await ctx.service.liveConnectorsRun({ authenticatedPrincipal: ctx.authenticatedPrincipal, force: input.force === true }, ctx.authenticatedPrincipal) }) });
237
+ defineOperation({ name: "peer_list", description: "List peers.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.peerList() }) });
238
+ defineOperation({ name: "peer_get", description: "Get peer.", schema: strictSchema({ id: S.str }), handler: async (input, ctx) => { const id = defStr(input.id, ""); if (!id) throw new EngramAccessInputError("peer_get: id is required"); return { result: await ctx.service.peerGet(id) }; } });
239
+ defineOperation({ name: "peer_set", description: "Set peer.", schema: strictSchema({ id: S.str, kind: S.str, displayName: S.str, notes: S.str }), handler: async (input, ctx) => { const id = defStr(input.id, ""); if (!id) throw new EngramAccessInputError("peer_set: id is required"); if (input.kind !== undefined && typeof input.kind !== "string") throw new EngramAccessInputError("peer_set: kind must be a string when provided"); if (input.displayName !== undefined && typeof input.displayName !== "string") throw new EngramAccessInputError("peer_set: displayName must be a string when provided"); if (input.notes !== undefined && typeof input.notes !== "string") throw new EngramAccessInputError("peer_set: notes must be a string when provided"); return { result: await ctx.service.peerSet({ id, kind: optStr(input.kind), displayName: optStr(input.displayName), notes: optStr(input.notes) }) }; } });
240
+ defineOperation({ name: "peer_delete", description: "Delete peer.", schema: strictSchema({ id: S.str }), handler: async (input, ctx) => { const id = defStr(input.id, ""); if (!id) throw new EngramAccessInputError("peer_delete: id is required"); return { result: await ctx.service.peerDelete(id) }; } });
241
+ defineOperation({ name: "peer_profile_get", description: "Get peer profile.", schema: strictSchema({ id: S.str }), handler: async (input, ctx) => { const id = defStr(input.id, ""); if (!id) throw new EngramAccessInputError("peer_profile_get: id is required"); return { result: await ctx.service.peerProfileGet(id) }; } });
242
+ defineOperation({ name: "peer_forget", description: "Forget peer.", schema: strictSchema({ id: S.str, confirm: S.str }), handler: async (input, ctx) => { const id = defStr(input.id, ""); if (!id) throw new EngramAccessInputError("peer_forget: id is required"); const c = optStr(input.confirm) ?? ""; if (c !== "yes") throw new EngramAccessInputError("peer_forget: confirm must be 'yes' to prevent accidental data loss"); return { result: await ctx.service.peerForget(id, { confirm: "yes" }) }; } });
243
+ defineOperation({ name: "console_state", description: "Console state.", schema: strictSchema({ namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.consoleState(optStr(input.namespace), ctx.authenticatedPrincipal) }) });
244
+ defineOperation({ name: "dreams_status", description: "Dreams status.", schema: strictSchema({ windowHours: S.num, namespace: S.str }), handler: async (input, ctx) => { let wh = 24; try { wh = normalizeDreamsStatusWindowHours(input.windowHours); } catch { throw new EngramAccessInputError("dreams_status: windowHours must be a positive integer. Got: " + String(input.windowHours)); } return { result: await ctx.service.dreamsStatus({ windowHours: wh, namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }; } });
245
+ defineOperation({ name: "dreams_run", description: "Run dreams.", schema: strictSchema({ phase: S.str, dryRun: S.bool, namespace: S.str }), handler: async (input, ctx) => { const VP = ["lightSleep", "rem", "deepSleep"]; const ph = optStr(input.phase) ?? ""; if (!ph || !VP.includes(ph)) throw new EngramAccessInputError("dreams_run: phase must be one of: " + VP.join(", ")); if (input.dryRun !== undefined && typeof input.dryRun !== "boolean") throw new EngramAccessInputError("dreams_run: dryRun must be boolean"); return { result: await ctx.service.dreamsRun({ phase: ph as DreamsPhase, dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }; } });
246
+
247
+ defineOperation({ name: "correction_pending", description: "List pending corrections (HTTP GET).", schema: strictSchema({ namespace: S.str, sessionKey: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.correctionListPending({ namespace: optStr(input.namespace), sessionKey: optStr(input.sessionKey), principal: ctx.authenticatedPrincipal }) }) });
248
+
249
+ // === HTTP-ONLY ===
250
+ defineOperation({ name: "offline_sync_snapshot", description: "Offline sync snapshot.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.offlineSyncSnapshot() }) });
251
+ defineOperation({ name: "offline_sync_files", description: "Offline sync files.", schema: strictSchema({ paths: S.strArr, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFiles({ paths: optStrArr(input.paths) ?? [], namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
252
+ defineOperation({ name: "offline_sync_file_content", description: "Read file content.", schema: strictSchema({ path: S.str, namespace: S.str, offset: S.num, length: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFileContent({ path: optStr(input.path) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, offset: optNum(input.offset), length: optNum(input.length) }) }) });
253
+ defineOperation({ name: "offline_sync_apply_file_content", description: "Apply file content.", schema: strictSchema({ sourceId: S.str, path: S.str, sha256: S.str, bytes: S.num, mtimeMs: S.num, offset: S.num, baseSha256: S.str, content: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApplyFileContent({ sourceId: optStr(input.sourceId) ?? "", path: optStr(input.path) ?? "", sha256: optStr(input.sha256) ?? "", bytes: optNum(input.bytes) ?? 0, mtimeMs: optNum(input.mtimeMs) ?? 0, offset: optNum(input.offset), baseSha256: optStr(input.baseSha256), content: Buffer.from(defStr(input.content, ""), "base64"), namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
254
+ defineOperation({ name: "offline_sync_apply", description: "Apply sync.", schema: strictSchema({ changeset: z.unknown().optional(), namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApply({ changeset: input.changeset, namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }) });
255
+ defineOperation({ name: "lcm_status", description: "LCM status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.lcmStatus() }) });
256
+ defineOperation({ name: "memory_list", description: "List memories.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.memoryBrowse() }) });
257
+ defineOperation({ name: "entity_list", description: "List entities.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.entityList() }) });
258
+ defineOperation({ name: "maintenance_status", description: "Maintenance status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.maintenance() }) });
259
+ defineOperation({ name: "quality_status", description: "Quality status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.quality() }) });
260
+ defineOperation({ name: "trust_zones_status", description: "Trust-zone status.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.trustZoneStatus() }) });
261
+ defineOperation({ name: "trust_zones_records", description: "Browse trust-zone records.", schema: strictSchema({ namespace: S.str, limit: S.num, offset: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.trustZoneBrowse({ namespace: optStr(input.namespace), limit: optNum(input.limit), offset: optNum(input.offset) }, ctx.authenticatedPrincipal) }) });
262
+ defineOperation({ name: "review_disposition", description: "Review disposition.", schema: strictSchema({ memoryId: S.str, status: S.str, reasonCode: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.reviewDisposition({ memoryId: optStr(input.memoryId) ?? "", status: (optStr(input.status) ?? "archived") as never, reasonCode: optStr(input.reasonCode) ?? "", namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
263
+ defineOperation({ name: "trust_zones_promote", description: "Promote trust-zone.", schema: strictSchema({ recordId: S.str, targetZone: S.str, promotionReason: S.str, dryRun: S.bool, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.trustZonePromote({ recordId: optStr(input.recordId) ?? "", targetZone: (optStr(input.targetZone) ?? "working") as never, promotionReason: optStr(input.promotionReason) ?? "", dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
264
+ defineOperation({ name: "trust_zones_demo_seed", description: "Demo seed.", schema: strictSchema({ scenario: S.str, dryRun: S.bool, namespace: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.trustZoneDemoSeed({ scenario: optStr(input.scenario), dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
265
+ defineOperation({ name: "citations_observed", description: "Record citations.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
266
+ defineOperation({ name: "contradiction_detail", description: "Contradiction detail.", schema: strictSchema({ id: S.str, namespace: S.str }), handler: async (input, ctx) => ({ result: await listPairs(ctx.service.memoryDir, { filter: "all" as const, namespace: optStr(input.namespace), includeUnscopedForNamespace: false, limit: 1 }) }) });
267
+ defineOperation({ name: "offline_sync_snapshot_stream", description: "SSE stream.", schema: strictSchema({}), handler: async (_i, ctx) => ({ result: await ctx.service.offlineSyncSnapshotStream() }) });
268
+ defineOperation({ name: "graph_events", description: "SSE graph events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
269
+ defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
270
+ defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });