@sema-agent/core 5.20.0 → 5.21.0

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 (312) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/agents/agent-definition.d.ts +7 -0
  3. package/dist/agents/agent-transcript-tool.d.ts +30 -0
  4. package/dist/agents/builtin-agents.d.ts +60 -0
  5. package/dist/agents/cascade.d.ts +107 -0
  6. package/dist/agents/cumulative-stats.d.ts +56 -0
  7. package/dist/agents/observer.d.ts +162 -0
  8. package/dist/agents/peer-admission.d.ts +95 -0
  9. package/dist/agents/repair-loop.d.ts +226 -0
  10. package/dist/agents/retain-ledger.d.ts +141 -0
  11. package/dist/agents/roster-store.d.ts +105 -0
  12. package/dist/agents/send-message-tool.d.ts +92 -0
  13. package/dist/agents/session-util.d.ts +5 -0
  14. package/dist/agents/subagent-steps.d.ts +66 -0
  15. package/dist/agents/subagent.d.ts +600 -0
  16. package/dist/agents/suspend-guard.d.ts +29 -0
  17. package/dist/agents/teacher.d.ts +75 -0
  18. package/dist/agents/team.d.ts +120 -1
  19. package/dist/agents/tool-filter.d.ts +34 -0
  20. package/dist/agents/verify.d.ts +198 -0
  21. package/dist/bench/metrics.d.ts +455 -0
  22. package/dist/brain/anthropic.d.ts +30 -0
  23. package/dist/brain/circuit-breaker.d.ts +33 -0
  24. package/dist/brain/context-overflow.d.ts +60 -3
  25. package/dist/brain/degrading.d.ts +67 -0
  26. package/dist/brain/errors.d.ts +42 -0
  27. package/dist/brain/failover.d.ts +15 -0
  28. package/dist/brain/media-degrade.d.ts +39 -0
  29. package/dist/brain/model-presets.d.ts +31 -0
  30. package/dist/brain/open-responses.d.ts +19 -0
  31. package/dist/brain/openai.d.ts +46 -0
  32. package/dist/brain/reasoning.d.ts +106 -1
  33. package/dist/brain/repetition.d.ts +83 -0
  34. package/dist/brain/request-params.d.ts +56 -0
  35. package/dist/brain/retry.d.ts +46 -0
  36. package/dist/brain/routing.d.ts +12 -0
  37. package/dist/brain/status-sink.d.ts +30 -1
  38. package/dist/brain/stream-engine.d.ts +147 -0
  39. package/dist/brain/stream-shared.d.ts +34 -0
  40. package/dist/brain/terminal-cause.d.ts +31 -0
  41. package/dist/brain/timeout.d.ts +107 -0
  42. package/dist/brain/tool-call-id.d.ts +20 -0
  43. package/dist/brain/tool-call-repair.d.ts +13 -0
  44. package/dist/config/catalog.d.ts +47 -0
  45. package/dist/config/defaults.d.ts +33 -0
  46. package/dist/core/a2a-task-state.d.ts +53 -0
  47. package/dist/core/a2a.d.ts +51 -0
  48. package/dist/core/arg-summary.d.ts +62 -0
  49. package/dist/core/ask-question.d.ts +272 -2
  50. package/dist/core/auto-compaction.d.ts +467 -0
  51. package/dist/core/auto-compaction.js +20 -6
  52. package/dist/core/auto-mode-prompt-assets.d.ts +8 -0
  53. package/dist/core/auto-mode-prompt.d.ts +27 -0
  54. package/dist/core/auto-mode.d.ts +54 -3
  55. package/dist/core/auto-promote.d.ts +100 -0
  56. package/dist/core/background-agent-store.d.ts +292 -0
  57. package/dist/core/background-shell.d.ts +110 -0
  58. package/dist/core/cache-break-detector.d.ts +34 -0
  59. package/dist/core/canonical-json.d.ts +57 -0
  60. package/dist/core/checkpoint-store.d.ts +1574 -16
  61. package/dist/core/compliance.d.ts +30 -0
  62. package/dist/core/consolidate-scope.d.ts +75 -0
  63. package/dist/core/context-edit.d.ts +99 -0
  64. package/dist/core/context-guard.d.ts +46 -0
  65. package/dist/core/exec-gate.d.ts +44 -0
  66. package/dist/core/exec-output-tail.d.ts +61 -0
  67. package/dist/core/file-snapshot-store.d.ts +104 -0
  68. package/dist/core/fs-write-gate-policy.d.ts +36 -0
  69. package/dist/core/git-worktree-env.d.ts +31 -0
  70. package/dist/core/governance-codes.d.ts +19 -0
  71. package/dist/core/hooks.d.ts +608 -1
  72. package/dist/core/human-input-projection.d.ts +37 -0
  73. package/dist/core/human-input-projection.js +13 -0
  74. package/dist/core/image-downsample.d.ts +74 -0
  75. package/dist/core/locked-config.d.ts +37 -0
  76. package/dist/core/lsp-diagnostics.d.ts +77 -0
  77. package/dist/core/lsp-protocol.d.ts +29 -0
  78. package/dist/core/lsp-session.d.ts +60 -1
  79. package/dist/core/lsp.d.ts +150 -1
  80. package/dist/core/mailbox-store.d.ts +57 -0
  81. package/dist/core/mcp.d.ts +381 -0
  82. package/dist/core/media-byte-cap.d.ts +21 -0
  83. package/dist/core/memory-admission.d.ts +71 -0
  84. package/dist/core/memory-engine/content-origin.d.ts +64 -0
  85. package/dist/core/memory-engine/data-plane.d.ts +43 -0
  86. package/dist/core/memory-engine/dual-root.d.ts +24 -0
  87. package/dist/core/memory-engine/engine.d.ts +230 -0
  88. package/dist/core/memory-engine/engine.js +103 -35
  89. package/dist/core/memory-engine/file-backend.d.ts +155 -0
  90. package/dist/core/memory-engine/frontmatter.d.ts +16 -0
  91. package/dist/core/memory-engine/layout.d.ts +217 -0
  92. package/dist/core/memory-engine/memory-backend-contract.d.ts +12 -0
  93. package/dist/core/memory-engine/migrate.d.ts +9 -0
  94. package/dist/core/memory-engine/scan.d.ts +12 -0
  95. package/dist/core/memory-engine/scope-contract.d.ts +61 -1
  96. package/dist/core/memory-engine/sync-client.d.ts +87 -0
  97. package/dist/core/memory-engine/sync.d.ts +60 -0
  98. package/dist/core/memory-engine/tools.d.ts +41 -0
  99. package/dist/core/memory-engine/types.d.ts +188 -0
  100. package/dist/core/memory-recall.d.ts +141 -0
  101. package/dist/core/memory-vector.d.ts +20 -0
  102. package/dist/core/memory.d.ts +458 -0
  103. package/dist/core/message-utils.d.ts +6 -0
  104. package/dist/core/oracle-isolation.d.ts +69 -0
  105. package/dist/core/permission-rule-consent.d.ts +138 -0
  106. package/dist/core/permission-rule-model.d.ts +122 -0
  107. package/dist/core/permission-rule-store.d.ts +119 -3
  108. package/dist/core/permission-rules.d.ts +87 -1
  109. package/dist/core/present-plan-tool.d.ts +20 -0
  110. package/dist/core/pricing.d.ts +26 -0
  111. package/dist/core/property-harness.d.ts +86 -0
  112. package/dist/core/protocol-naming.d.ts +38 -0
  113. package/dist/core/protocol-table.d.ts +61 -0
  114. package/dist/core/push-queue.d.ts +1 -0
  115. package/dist/core/remote-env.d.ts +383 -1
  116. package/dist/core/retention-policy.d.ts +33 -0
  117. package/dist/core/retention.d.ts +51 -0
  118. package/dist/core/roles.d.ts +59 -0
  119. package/dist/core/runner/active-skill-scope.d.ts +34 -0
  120. package/dist/core/runner/assemble-result.d.ts +134 -0
  121. package/dist/core/runner/compaction-call-options.d.ts +97 -1
  122. package/dist/core/runner/grounding-signal.d.ts +10 -0
  123. package/dist/core/runner/image.d.ts +17 -0
  124. package/dist/core/runner/image.js +29 -15
  125. package/dist/core/runner/memory-consolidation.d.ts +60 -0
  126. package/dist/core/runner/prepare-memory.d.ts +59 -0
  127. package/dist/core/runner/prepare-task.d.ts +1011 -2
  128. package/dist/core/runner/prepare-task.js +12 -11
  129. package/dist/core/runner/prompt-suggestions.d.ts +7 -0
  130. package/dist/core/runner/runtask.d.ts +304 -3
  131. package/dist/core/runner/session-file-state-replay.d.ts +49 -0
  132. package/dist/core/runner/session-rule-policy.d.ts +58 -0
  133. package/dist/core/runner/strict-output-schema.d.ts +18 -3
  134. package/dist/core/runner/synthetic-tools.d.ts +113 -0
  135. package/dist/core/runner/teardown-bounded.d.ts +34 -0
  136. package/dist/core/runner/tool-disclosure.d.ts +227 -0
  137. package/dist/core/runner/tool-output-projection.d.ts +6 -0
  138. package/dist/core/runner/turn-attachments.d.ts +634 -0
  139. package/dist/core/runner/usage-accounting.d.ts +32 -0
  140. package/dist/core/runtime.d.ts +9 -0
  141. package/dist/core/safe-notify.d.ts +64 -0
  142. package/dist/core/safety-axis-vocab.d.ts +23 -0
  143. package/dist/core/safety-merge-corpus.d.ts +37 -0
  144. package/dist/core/scheduler.d.ts +121 -0
  145. package/dist/core/secret-env.d.ts +32 -0
  146. package/dist/core/select-model.d.ts +15 -0
  147. package/dist/core/sensitive-path-policy.d.ts +42 -0
  148. package/dist/core/session-policy-store.d.ts +94 -0
  149. package/dist/core/session-reconcile.d.ts +80 -0
  150. package/dist/core/session-store.d.ts +85 -0
  151. package/dist/core/session.d.ts +153 -0
  152. package/dist/core/shared-memory/contract.d.ts +22 -0
  153. package/dist/core/shared-memory/normalize.d.ts +123 -2
  154. package/dist/core/shared-memory/tools.d.ts +14 -0
  155. package/dist/core/shared-memory/types.d.ts +105 -0
  156. package/dist/core/shutdown-debug.d.ts +6 -0
  157. package/dist/core/side-query.d.ts +38 -0
  158. package/dist/core/side-query.js +6 -1
  159. package/dist/core/skill-tool-specifier.d.ts +72 -0
  160. package/dist/core/skills-directory.d.ts +100 -1
  161. package/dist/core/spec-contract.d.ts +89 -0
  162. package/dist/core/store-contracts/background-agent-store-contract.d.ts +31 -0
  163. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +26 -0
  164. package/dist/core/store-contracts/contract-harness.d.ts +20 -0
  165. package/dist/core/store-contracts/contract-kit-version.d.ts +27 -0
  166. package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +8 -0
  167. package/dist/core/store-contracts/mailbox-store-contract.d.ts +42 -0
  168. package/dist/core/store-contracts/tool-result-store-contract.d.ts +13 -0
  169. package/dist/core/strategy-store.d.ts +37 -0
  170. package/dist/core/stub-env.d.ts +7 -0
  171. package/dist/core/surrogate-safe-slice.d.ts +35 -0
  172. package/dist/core/task-notification.d.ts +202 -0
  173. package/dist/core/task-outcome.d.ts +53 -0
  174. package/dist/core/task-registry-agent.d.ts +337 -1
  175. package/dist/core/task-registry-monitor.d.ts +12 -0
  176. package/dist/core/task-registry-shared.d.ts +540 -0
  177. package/dist/core/task-registry.d.ts +343 -0
  178. package/dist/core/task-registry.js +13 -2
  179. package/dist/core/task-tool-shape.d.ts +44 -0
  180. package/dist/core/tighten-task-spec.d.ts +21 -0
  181. package/dist/core/tool-detach.d.ts +21 -0
  182. package/dist/core/tool-errors.d.ts +131 -0
  183. package/dist/core/tool-errors.js +4 -0
  184. package/dist/core/tool-name-aliases.d.ts +27 -0
  185. package/dist/core/tool-policy.d.ts +555 -0
  186. package/dist/core/tool-result-budget.d.ts +32 -0
  187. package/dist/core/tool-result-store.d.ts +174 -1
  188. package/dist/core/tools.d.ts +45 -0
  189. package/dist/core/trace.d.ts +323 -0
  190. package/dist/core/types.d.ts +3859 -2
  191. package/dist/core/untrusted-egress.d.ts +8 -0
  192. package/dist/core/untrusted-text.d.ts +156 -0
  193. package/dist/core/usage-window-store.d.ts +95 -0
  194. package/dist/core/version.d.ts +1 -0
  195. package/dist/core/warm-resume.d.ts +17 -0
  196. package/dist/core/wiring-manifest.d.ts +169 -0
  197. package/dist/core/with-retry.d.ts +24 -0
  198. package/dist/core/workflow-journal-store.d.ts +160 -0
  199. package/dist/core/workflow-run-store-contract.d.ts +25 -0
  200. package/dist/core/workflow-run-store.d.ts +119 -0
  201. package/dist/engine/compaction/compaction.d.ts +256 -1
  202. package/dist/engine/compaction/utils.d.ts +94 -0
  203. package/dist/engine/execution-env/kill-tree.d.ts +29 -0
  204. package/dist/engine/execution-env/node-execution-env.d.ts +94 -0
  205. package/dist/engine/harness/agent-harness.d.ts +116 -0
  206. package/dist/engine/harness/agent-harness.js +3 -14
  207. package/dist/engine/harness/messages.d.ts +15 -0
  208. package/dist/engine/harness/types.d.ts +464 -2
  209. package/dist/engine/llm/diagnostics.d.ts +4 -0
  210. package/dist/engine/llm/event-stream.d.ts +3 -0
  211. package/dist/engine/llm/index.d.ts +7 -0
  212. package/dist/engine/llm/types.d.ts +500 -3
  213. package/dist/engine/llm/validation.d.ts +3 -0
  214. package/dist/engine/loop/agent-loop.d.ts +87 -2
  215. package/dist/engine/loop/runtime-deps.d.ts +7 -0
  216. package/dist/engine/loop/types.d.ts +424 -0
  217. package/dist/engine/lsp/frame-decoder.d.ts +13 -0
  218. package/dist/engine/lsp/node-lsp-manager.d.ts +107 -0
  219. package/dist/engine/lsp/stdio-lsp-transport.d.ts +7 -0
  220. package/dist/engine/session/import-validate.d.ts +27 -0
  221. package/dist/engine/session/log-digest.d.ts +93 -0
  222. package/dist/engine/session/memory-repo.d.ts +6 -0
  223. package/dist/engine/session/memory-storage.d.ts +2 -0
  224. package/dist/engine/session/session.d.ts +75 -0
  225. package/dist/engine/session/storage-base.d.ts +8 -0
  226. package/dist/fixtures/index.d.ts +36 -0
  227. package/dist/index.d.ts +16 -1
  228. package/dist/index.js +0 -1
  229. package/dist/internal/harness-types.d.ts +6 -0
  230. package/dist/internal/harness.d.ts +11 -0
  231. package/dist/internal/llm.d.ts +6 -0
  232. package/dist/orchestration/builtin-workflows.d.ts +53 -0
  233. package/dist/orchestration/dev-vm-script-runner.d.ts +19 -0
  234. package/dist/orchestration/goal.d.ts +57 -0
  235. package/dist/orchestration/goal.js +3 -0
  236. package/dist/orchestration/run-spec.d.ts +42 -0
  237. package/dist/orchestration/run-workflow-tool.d.ts +169 -0
  238. package/dist/orchestration/workflow-governance.d.ts +61 -0
  239. package/dist/orchestration/workflow-meta.d.ts +28 -0
  240. package/dist/orchestration/workflow-observe.d.ts +60 -0
  241. package/dist/orchestration/workflow-primitives.d.ts +23 -1
  242. package/dist/orchestration/workflow-sandbox-conformance.d.ts +38 -0
  243. package/dist/orchestration/workflow-script-runner.d.ts +88 -0
  244. package/dist/orchestration/workflow-script-store.d.ts +98 -0
  245. package/dist/orchestration/workflow-size-guideline.d.ts +67 -0
  246. package/dist/orchestration/workflow-types.d.ts +169 -2
  247. package/dist/orchestration/workflow.d.ts +358 -0
  248. package/dist/prompt-assembly/artifact-store.d.ts +33 -0
  249. package/dist/prompt-assembly/artifact.d.ts +25 -0
  250. package/dist/prompt-assembly/assemble.d.ts +20 -0
  251. package/dist/prompt-assembly/composer.d.ts +29 -0
  252. package/dist/prompt-assembly/epoch.d.ts +55 -1
  253. package/dist/prompt-assembly/event-registry.d.ts +35 -0
  254. package/dist/prompt-assembly/explain.d.ts +12 -0
  255. package/dist/prompt-assembly/tool-catalog.d.ts +38 -0
  256. package/dist/prompt-assembly/turn-snapshot.d.ts +40 -0
  257. package/dist/prompt-assembly/types.d.ts +115 -0
  258. package/dist/prompts/coordinator.d.ts +27 -0
  259. package/dist/prompts/default.d.ts +539 -0
  260. package/dist/prompts/simple-sections.d.ts +45 -0
  261. package/dist/prompts/supervisor.d.ts +66 -0
  262. package/dist/scenarios/env.d.ts +28 -0
  263. package/dist/scenarios/full-body.d.ts +50 -0
  264. package/dist/scenarios/scenario-registry.d.ts +60 -0
  265. package/dist/scenarios/teacher-quickstart.d.ts +27 -0
  266. package/dist/server/http.d.ts +17 -0
  267. package/dist/stores/cc/lockfile.d.ts +6 -0
  268. package/dist/stores/cc/mailbox-store.d.ts +8 -0
  269. package/dist/stores/cc/roster-adapter.d.ts +4 -0
  270. package/dist/stores/cc/sidecar-transcript.d.ts +66 -0
  271. package/dist/stores/file/background-agent-store.d.ts +24 -0
  272. package/dist/stores/file/checkpoint-store.d.ts +38 -0
  273. package/dist/stores/file/file-snapshot-store.d.ts +25 -0
  274. package/dist/stores/file/fs-atomic.d.ts +155 -0
  275. package/dist/stores/file/index.d.ts +89 -0
  276. package/dist/stores/file/mailbox-store.d.ts +36 -0
  277. package/dist/stores/file/memory-store.d.ts +82 -0
  278. package/dist/stores/file/permission-rule-store.d.ts +79 -0
  279. package/dist/stores/file/session-policy-store.d.ts +28 -0
  280. package/dist/stores/file/session-store.d.ts +40 -0
  281. package/dist/stores/file/shared-ledger.d.ts +83 -0
  282. package/dist/stores/file/tool-result-store.d.ts +11 -0
  283. package/dist/stores/file/usage-window-store.d.ts +18 -0
  284. package/dist/stores/file/workflow-journal-store.d.ts +100 -0
  285. package/dist/stores/file/workflow-run-store.d.ts +11 -0
  286. package/dist/tools/fs/bash-readonly-classifier.d.ts +282 -0
  287. package/dist/tools/fs/encoding.d.ts +60 -0
  288. package/dist/tools/fs/fs-bash.d.ts +133 -0
  289. package/dist/tools/fs/fs-pdf.d.ts +28 -0
  290. package/dist/tools/fs/fs-search-tools.d.ts +5 -0
  291. package/dist/tools/fs/fs-shared.d.ts +360 -0
  292. package/dist/tools/fs/fs-write.d.ts +16 -0
  293. package/dist/tools/fs/gh-rate-limit.d.ts +22 -0
  294. package/dist/tools/fs/index.d.ts +79 -0
  295. package/dist/tools/fs/notebook.d.ts +56 -0
  296. package/dist/tools/fs/pdf.d.ts +70 -0
  297. package/dist/tools/fs/pdf.js +8 -2
  298. package/dist/tools/fs/repo-map.d.ts +10 -0
  299. package/dist/tools/fs/safety.d.ts +376 -0
  300. package/dist/tools/fs/search.d.ts +131 -0
  301. package/dist/tools/loop-tick.d.ts +24 -0
  302. package/dist/tools/monitor.d.ts +55 -0
  303. package/dist/tools/scheduler-tools.d.ts +51 -0
  304. package/dist/tools/sql-adapters.d.ts +18 -0
  305. package/dist/tools/sql.d.ts +25 -0
  306. package/dist/tools/task-list.d.ts +77 -0
  307. package/dist/tools/todo.d.ts +8 -0
  308. package/dist/tools/web.d.ts +184 -0
  309. package/dist/tools/worktree.d.ts +81 -0
  310. package/package.json +2 -2
  311. package/dist/tools/gitea-issue.d.ts +0 -13
  312. package/dist/tools/gitea-issue.js +0 -75
@@ -1,116 +1,574 @@
1
+ /**
2
+ * A scored memory candidate returned by {@link MemoryStore.searchScored} (design/41). Carries a
3
+ * **stable id** (for {@link MemoryStore.update}/{@link MemoryStore.delete}) and a similarity `score`.
4
+ *
5
+ * `score` is a **cosine distance ∈ [0, 2]** where **0 = identical** and larger = less similar — pinned
6
+ * by contract so the consolidation band (`{lo, hi}`) is calibrated the same way across stores (a store
7
+ * that returned a *similarity* instead of a *distance* would invert the band). The reference
8
+ * {@link InMemoryMemoryStore} has no embeddings, so it returns a lexical distance in [0, 1] (a subset
9
+ * of the range) as a stand-in for tests/dev; a production store returns a real cosine distance.
10
+ */
1
11
  export interface ScoredMemory {
2
12
  id: string;
3
13
  text: string;
4
14
  score: number;
15
+ /** design/84 Seam B (前置 BLOCKER): true when this note was CREATED by a consolidation ADD (not the
16
+ * `remember` tool / a caller). Periodic/incremental consolidation EXCLUDES these from its candidate set so
17
+ * it never re-consolidates its own output (infinite re-merge). Stores that don't track it leave it absent
18
+ * (treated as not-generated — back-compat: the inline task-end path already excludes this-task notes by id). */
5
19
  consolidationGenerated?: boolean;
6
20
  }
21
+ /**
22
+ * The vector-ranking capability RUNG a {@link MemoryStore} actually achieves (design/81 Slice 5). It is a
23
+ * runtime OBSERVABLE (it depends on whether an embedder was injected AND whether the backend has native vector
24
+ * ops), NOT a static class trait — a deployment reads `store.vectorMode` to decide whether to build a native
25
+ * index / for metrics, and to answer "does this backend do neural recall?".
26
+ * - `lexical` — no embedder: `1 - Jaccard` everywhere (the default; byte-identical to the pre-Slice-5 floor).
27
+ * - `portable` — embedder + IN-PROCESS cosine over stored vectors (File jsonl / Pg jsonb / **MySQL JSON** —
28
+ * any backend that can store a float array; O(n), no index). MySQL sits HERE, not "unsupported".
29
+ * - `native` — embedder + a backend index/operator (pgvector `<=>` / TiDB `VEC_COSINE_DISTANCE`).
30
+ */
7
31
  export type MemoryVectorMode = "lexical" | "portable" | "native";
32
+ /**
33
+ * Produces an embedding for one note/query (design/81 Slice 3 — the OPTIONAL vector seam). **Byte-identical
34
+ * to the repo example `PgEmbedder` (src/examples/adapters/pg-adapter.ts — repo example only, not part of the
35
+ * npm surface since 1.424.0)** so the same caller-injected embedder satisfies both the Pg and File backends. It is an OPTIONAL injection: a store WITHOUT one falls back to the lexical
36
+ * cosine-distance (the TOC default — no model file, no native binary in core's default path). When one IS
37
+ * injected the File backend uses it for vector ranking (Slice 5) via a rebuildable sidecar index; injecting
38
+ * none keeps the lexical floor unchanged. Core bundles NO embedder; a cloud/TOB consumer injects its own.
39
+ */
8
40
  export interface Embedder {
9
41
  embed(text: string): Promise<number[]>;
10
42
  dimensions: number;
11
43
  }
44
+ /**
45
+ * Long-term (L2) memory backend — pluggable, scoped, durable across sessions.
46
+ *
47
+ * Design adapted (MIT) from CodeWhale's `memory.rs` (a persistent note file injected into the
48
+ * system prompt) and Anthropic's memory tool (the model manages its own memory via a tool; the
49
+ * backend lives in your infrastructure). The default is in-memory; a deployment provides a durable
50
+ * backend (e.g. TiDB) implementing this interface.
51
+ *
52
+ * `scope` partitions memory by tenant — e.g. `user:42`, `org:7`, `agent:main`, or `global`.
53
+ */
12
54
  export interface MemoryStore {
55
+ /** Full memory content for a scope (timestamped bullets), or null when empty. */
13
56
  read(scope: string): Promise<string | null> | string | null;
57
+ /**
58
+ * Append one durable note to a scope. Implementations timestamp it. A store that supports
59
+ * consolidation (implements {@link searchScored}/{@link update}/{@link delete}) **MUST** return the new
60
+ * note's **stable id**: memory consolidation (design/41) uses it to exclude a just-appended note from
61
+ * its own reconcile candidates, so an id-addressable store that returns `void` would let a note
62
+ * self-match and trigger a wasteful no-op every cycle. Returning `void` is fine only for stores that
63
+ * do NOT support consolidation.
64
+ */
14
65
  append(scope: string, note: string): Promise<string | void> | string | void;
66
+ /** Clear a scope's memory. */
15
67
  clear(scope: string): Promise<void> | void;
68
+ /**
69
+ * Optional just-in-time (L3) retrieval: return notes in `scope` relevant to `query`.
70
+ * When implemented, the Runner exposes a `recall` tool so the model can query memory on demand
71
+ * instead of relying only on the injected block (useful when a scope's memory is large).
72
+ */
16
73
  search?(scope: string, query: string, limit?: number): Promise<string[]> | string[];
74
+ /**
75
+ * Optional id-addressable similarity retrieval (design/41): return up to `limit` notes in `scope`
76
+ * most similar to `query`, each with a **stable id** and a cosine-distance `score` (see
77
+ * {@link ScoredMemory}). Required (together with {@link update}/{@link delete}) for memory
78
+ * consolidation; when any of the three is absent, consolidation is a safe no-op.
79
+ *
80
+ * **Concurrency contract:** memory consolidation keys on the task's memory `scope`, NOT its session,
81
+ * and the Runner's per-session lock does not serialize across sessions. So `searchScored`/`update`/
82
+ * `delete` MAY be called concurrently for the SAME scope from different sessions. A durable async store
83
+ * must therefore either linearize per-scope writes (e.g. optimistic lock by id) or accept eventual
84
+ * consistency — at worst a near-duplicate survives one extra consolidation pass (fail-open, no loss).
85
+ */
17
86
  searchScored?(scope: string, query: string, limit?: number): Promise<ScoredMemory[]> | ScoredMemory[];
87
+ /** The vector-ranking rung this store achieves (design/81 Slice 5). Absent ⇒ treated as `"lexical"`
88
+ * (back-compat). A runtime observable — a deployment reads it to decide index/metrics, NOT to decide
89
+ * whether to inject an embedder (injection is config-driven; this is the RESULT). See {@link MemoryVectorMode}. */
18
90
  readonly vectorMode?: MemoryVectorMode;
91
+ /** Optional: replace a note's text by id (consolidation UPDATE). The id stays stable. Must be safe
92
+ * under concurrent same-scope calls — see {@link searchScored}'s concurrency contract. */
19
93
  update?(scope: string, id: string, text: string): Promise<void> | void;
94
+ /** Optional: remove a note by id (consolidation DELETE). The id is never reused afterwards. Must be
95
+ * safe under concurrent same-scope calls — see {@link searchScored}'s concurrency contract. */
20
96
  delete?(scope: string, id: string): Promise<void> | void;
97
+ /**
98
+ * Optional **manifest** for selective recall (design/65 §2.2/§8#6): a per-note HEADER (id + a short
99
+ * description + mtime [+ name/type when structured]) — **NOT the body** (mirrors CC reading only the
100
+ * frontmatter, `memoryScan.ts FRONTMATTER_MAX_LINES=30`). The Runner injects this index for a large
101
+ * scope and side-queries which ids are relevant, then fetches only those via {@link getByIds}.
102
+ */
21
103
  listStructuredNotes?(scope: string): Promise<MemoryNoteHeader[]> | MemoryNoteHeader[];
104
+ /** Optional: fetch the FULL records (with body) for the selected ids (design/65 §2.2). Unknown ids are
105
+ * silently skipped. Order is not guaranteed. Pairs with {@link listStructuredNotes}. */
22
106
  getByIds?(scope: string, ids: string[]): Promise<MemoryNoteRecord[]> | MemoryNoteRecord[];
107
+ /**
108
+ * Optional: append a **structured/typed** note (design/65 §2.1, P2). `type` defaults to `"project"` and
109
+ * `description` to the body's first sentence (derived at write time — store responsibility, §8#6). Returns
110
+ * the new note's stable id (like {@link append}). A store that supports this surfaces `name`/`type` in
111
+ * {@link listStructuredNotes} so the selective-recall side-query gets a `[type]` relevance signal.
112
+ */
23
113
  appendStructured?(scope: string, note: StructuredNoteInput): Promise<string> | string;
114
+ /**
115
+ * Optional **legitimate door** for a *promotable* artifact write (design/77 §2 Gate-2). A promotable
116
+ * note (a self-evolution artifact — skill/playbook/outcome-stats; classified by NOTE STRUCTURE, not a
117
+ * caller flag, via {@link classifyPromotable}) may ONLY reach the backend through this method, which
118
+ * carries the required `utilityVerdict`. The store-boundary gate ({@link guardedMemoryStore}) routes a
119
+ * present+positive promotable write here; a promotable note WITHOUT a present+positive verdict is
120
+ * fail-closed REJECTED at the boundary (never reaches any store method). `utilityVerdict` is opaque
121
+ * `unknown` in core — the *definition* of "positive" stays in the profile (taxonomy never enters core).
122
+ * Stores that do not implement this can still serve caller-authored writes; promotable writes simply
123
+ * have nowhere legitimate to land and are rejected (fail-closed).
124
+ */
24
125
  appendPromotable?(scope: string, note: StructuredNoteInput, utilityVerdict: unknown): Promise<string> | string;
126
+ /**
127
+ * **INTERNAL consolidation-only door** for the design/84 Seam B marker. Memory consolidation (and ONLY
128
+ * it — `runMemoryConsolidation`) calls this to materialize a merged "add" decision tagged
129
+ * `consolidationGenerated:true`, so a later periodic/incremental pass EXCLUDES its own output from the
130
+ * candidate set (no infinite re-merge). It is the COUNTERPART to the {@link guardedMemoryStore} boundary
131
+ * defense: the public {@link appendStructured} STRIPS a caller-supplied `consolidationGenerated` (an
132
+ * external caller must never be able to mark a note "consolidation-generated" and silently exile it from
133
+ * consolidation forever), while THIS method is the single legitimate inlet that may set it. The guarded
134
+ * store wires it to set the marker then forward to the inner `appendStructured`; a raw (un-wrapped) store
135
+ * need not implement it — consolidation then falls back to `appendStructured` (which on an un-wrapped
136
+ * store still honors the marker, preserving the old behavior for direct-store tests). NOT a public caller
137
+ * surface: it carries no extra capability beyond `appendStructured` + the one internal flag.
138
+ */
25
139
  appendConsolidationGenerated?(scope: string, note: StructuredNoteInput): Promise<string> | string;
140
+ /**
141
+ * design/84 Seam B — read the periodic/incremental consolidation cursor for `scope` (decision 3). The
142
+ * cursor is an **opaque ordering marker** the STORE defines (this core never inspects it): a value such
143
+ * that every note whose ordering marker is `<= cursor` has ALREADY been folded into a prior consolidation
144
+ * pass and MUST NOT be re-fed (no infinite re-merge), while every note `> cursor` is still pending. In the
145
+ * reference stores it is a note **id** (uuidv7 — lexicographically time-sortable), so "after the cursor"
146
+ * is a simple string `>` comparison. Returns `undefined` when no pass has run yet (⇒ the WHOLE scope is
147
+ * pending — the first pass sweeps it all). PAIR with {@link setConsolidationCursor}: a store implements
148
+ * BOTH or NEITHER ({@link supportsPeriodicConsolidation}); a store with neither makes {@link consolidateScope}
149
+ * a safe NO-OP (it never silently degrades to a full re-consolidation).
150
+ */
26
151
  getConsolidationCursor?(scope: string): Promise<string | undefined> | string | undefined;
152
+ /**
153
+ * design/84 Seam B — persist the periodic/incremental consolidation cursor for `scope` (decision 3). Called
154
+ * by {@link consolidateScope} ONLY after a pass succeeds in full, advancing the cursor to the max ordering
155
+ * marker the pass observed (seen note ids ∪ added ids). Must be durable (a later pass reads it back). PAIR
156
+ * with {@link getConsolidationCursor}.
157
+ */
27
158
  setConsolidationCursor?(scope: string, cursor: string): Promise<void> | void;
28
159
  }
160
+ /** Standard structured-note types (design/65 §2.1, CC `memoryTypes.ts`). Any other string is accepted and
161
+ * degrades gracefully (stored + shown as-is) — `type` is widened to `string` everywhere for that reason. */
29
162
  export type MemoryNoteType = "user" | "feedback" | "project" | "reference";
163
+ /** Input to {@link MemoryStore.appendStructured}. Only `body` is required. */
30
164
  export interface StructuredNoteInput {
31
165
  body: string;
166
+ /** A short slug for `[[name]]` cross-references (design/65 §2.1). Optional. */
32
167
  name?: string;
168
+ /** One of {@link MemoryNoteType}, or any string (unknown types degrade). Default `"project"`. */
33
169
  type?: string;
170
+ /** One-line summary for the manifest. Default = first sentence of `body`. */
34
171
  description?: string;
172
+ /** `[[name]]` cross-reference slugs (design/65 §2.1; v1 stores/displays, no link-following). */
35
173
  links?: string[];
174
+ /**
175
+ * design/77 §2 Gate-2 structural marker. An opaque (`unknown`) outcome-statistics blob attached to a
176
+ * self-evolution artifact (held-out pass-rate, usage count, …). Its PRESENCE makes a note *promotable*
177
+ * even when `type` is in the caller-authored closed set — the structural marker WINS over the type
178
+ * (see {@link classifyPromotable}). Core never inspects its shape; the taxonomy/threshold stays in the
179
+ * profile (the `utilityGate` a deployment threads into {@link guardedMemoryStore}, e.g. via
180
+ * `FileStorageBackendOptions.utilityGate`).
181
+ */
36
182
  outcomeStats?: unknown;
183
+ /**
184
+ * design/84 Seam B (前置 BLOCKER): mark a note as CREATED BY A CONSOLIDATION ADD. Set ONLY by
185
+ * {@link import("./runner/memory-consolidation.js").runMemoryConsolidation} when it materializes a merged
186
+ * "add" decision — never by the `remember` tool or a normal caller. A store persists it (and surfaces it on
187
+ * {@link ScoredMemory}/{@link MemoryNoteHeader}) so periodic/incremental consolidation can EXCLUDE these
188
+ * notes from its candidate set and not re-consolidate its own output forever. It does NOT affect the
189
+ * promotable/secret gates (a consolidation ADD is `caller_authored` by construction).
190
+ */
37
191
  consolidationGenerated?: boolean;
38
192
  }
193
+ /** A manifest entry: enough to judge relevance, never the body (design/65 §2.2). */
39
194
  export interface MemoryNoteHeader {
195
+ /** Store contract: ids must be SINGLE-LINE whitespace-free tokens (uuid-like). The manifest renders
196
+ * `- {id}: …` lines and the side-query matches selected ids by string equality — an id containing
197
+ * a newline could forge manifest lines, and a renderer-side rewrite would break the equality match,
198
+ * so the contract sits on the store (search 1.95.1 review #2). */
40
199
  id: string;
200
+ /** A one-line summary used as the relevance signal (derived from the note's first sentence when untyped). */
41
201
  description: string;
202
+ /** Append/update time as ms since epoch — drives the freshness caveat (design/65 §8#8).
203
+ * ⚠️ Always read together with {@link timestampMissing}: when that flag is set this slot is a `0`
204
+ * SHELL, not a measurement. Never infer "unknown" from the value — `0` is a legal real timestamp. */
42
205
  mtimeMs: number;
206
+ /**
207
+ * Set when the note carries NO usable write time, so {@link mtimeMs} above is an unknown-shell rather
208
+ * than a measurement (the same "unknown ≠ zero" shape as the brain layer's `usageMissing`).
209
+ *
210
+ * Minted only by {@link parseNoteTimestamp}, which produces the pair together — see its note for why a
211
+ * bare `0` was a silent recall loss. A consumer that ORDERS or AGES notes must branch on this flag:
212
+ * an unknown time is INCOMPARABLE (neither the oldest nor the newest note in the scope), and it must
213
+ * never be rendered as an age. It does NOT remove the note from recall — the note stays in the
214
+ * manifest, stays searchable, and stays selectable; only the recency axis abstains.
215
+ */
43
216
  timestampMissing?: true;
217
+ /** Present once notes are structured (design/65 §2.1, P2); absent for legacy flat notes. */
44
218
  name?: string;
219
+ /** One of {@link MemoryNoteType} or any other string (unknown degrades gracefully). */
45
220
  type?: string;
221
+ /** design/84 Seam B: true when this note was created by a consolidation ADD (excluded from periodic
222
+ * consolidation candidates). Absent for `remember`/caller notes. */
46
223
  consolidationGenerated?: boolean;
47
224
  }
225
+ /** A full note record (header + body) returned by {@link MemoryStore.getByIds}. */
48
226
  export interface MemoryNoteRecord extends MemoryNoteHeader {
49
227
  text: string;
50
228
  }
229
+ /** A store that has passed {@link supportsConsolidation} — the id-addressable trio is present. */
51
230
  export type ConsolidationCapableStore = MemoryStore & Required<Pick<MemoryStore, "searchScored" | "update" | "delete">>;
231
+ /**
232
+ * True when a store implements the full id-addressable trio required for memory consolidation
233
+ * (design/41): {@link MemoryStore.searchScored}/{@link MemoryStore.update}/{@link MemoryStore.delete}.
234
+ * When false, the Runner skips consolidation entirely (graceful no-op).
235
+ *
236
+ * RB-436-g: a TYPE PREDICATE, so the guard's conclusion travels to the call sites. A bare boolean left
237
+ * every post-guard call site writing `store.update!(…)`, and a guard that later forgot one of the three
238
+ * would have been invisible — the `!`s keep compiling. Now dropping a method from the check turns the
239
+ * call sites red.
240
+ */
52
241
  export declare function supportsConsolidation(store: MemoryStore): store is ConsolidationCapableStore;
242
+ /** A store that has passed {@link supportsPeriodicConsolidation} — the Seam B cursor pair is present. */
53
243
  export type PeriodicConsolidationCapableStore = MemoryStore & Required<Pick<MemoryStore, "getConsolidationCursor" | "setConsolidationCursor">>;
244
+ /**
245
+ * True when a store implements the design/84 Seam B cursor PAIR
246
+ * ({@link MemoryStore.getConsolidationCursor}/{@link MemoryStore.setConsolidationCursor}). Periodic/incremental
247
+ * consolidation ({@link import("./consolidate-scope.js").consolidateScope}) GATES on this: a store missing
248
+ * either method makes a periodic pass a safe **NO-OP** (never a silent full re-consolidation of the whole
249
+ * scope, which would re-merge already-consolidated notes forever). Both-or-neither — a store implementing
250
+ * only one is treated as unsupported. Independent of {@link supportsConsolidation} (the id-addressable trio),
251
+ * which a periodic pass ALSO needs to actually mutate.
252
+ */
54
253
  export declare function supportsPeriodicConsolidation(store: MemoryStore): store is PeriodicConsolidationCapableStore;
254
+ /** The closed set of caller-authored note types (design/65 {@link MemoryNoteType}, memory.ts). A note
255
+ * whose `type` is in this set is caller-authored; a `type` *outside* it (e.g. `"skill"`) is promotable.
256
+ * Exported so a caller-authored inlet (e.g. consolidation ADD) can NORMALIZE a model-suggested type to
257
+ * the closed set before the store boundary — a legitimate caller_authored write must never trip the
258
+ * promotable gate just because the model invented a non-standard `type` slug (MINOR-3). */
55
259
  export declare const CALLER_AUTHORED_TYPES: ReadonlySet<string>;
260
+ /** The default caller-authored note type (matches {@link StructuredNoteInput.type}'s documented default). */
56
261
  export declare const DEFAULT_CALLER_AUTHORED_TYPE: MemoryNoteType;
262
+ /**
263
+ * Profile-injected predicate that judges whether a promotable note's `outcomeStats` clear the promotion bar
264
+ * (design/77 §2). Core only guarantees a verdict is PRESENT for a promotable write; this predicate — wired
265
+ * by the deployment — receives the note's (opaque) `outcomeStats` blob and returns whether it clears the
266
+ * bar. (It is NOT handed the `utilityVerdict` token; the verdict's PRESENCE is checked separately by
267
+ * {@link enforcePromotableWriteGate}, then the gate judges the outcome statistics.) When UNWIRED, a
268
+ * promotable write fails closed.
269
+ */
57
270
  export type UtilityGate = (stats: unknown) => boolean;
271
+ /** Typed, fail-closed error thrown when a promotable artifact write reaches the store boundary without a
272
+ * present-and-positive `utilityVerdict` (design/77 §2). The `code` is stable for callers to switch on;
273
+ * the write NEVER reaches the backend. */
58
274
  export declare class MemoryGateError extends Error {
59
275
  readonly code: string;
60
276
  constructor(code: string, detail?: string);
61
277
  }
278
+ /**
279
+ * Scan `text` for a high-confidence credential (CC-parity P0-2). Returns the matched pattern's stable
280
+ * `label` (NEVER the matched secret value — labels are safe to log/surface), or `null` when clean.
281
+ * Deliberately CONSERVATIVE: only provider-prefixed keys + PEM private-key headers match, so ordinary
282
+ * prose that merely mentions tokens/keys/passwords passes through untouched (false-positives are the head
283
+ * risk — a wrongly-rejected normal note silently breaks legitimate memory).
284
+ *
285
+ * 🔴 RB-445 (blackboard [2230]): this is a BEST-EFFORT tripwire for a handful of high-signal token
286
+ * formats, NOT a data-loss-prevention boundary — "the write gate passed" never means "the text contains
287
+ * no credential". Known-through shapes (deliberate, per the false-positive stance above): connection
288
+ * strings carrying passwords, `password=`/`Authorization:` header values, bare high-entropy bodies
289
+ * (40-char keys, 64-hex — indistinguishable from git SHAs/digests in engineering notes), and structured
290
+ * tokens without a vendor prefix. A deployment needing a real DLP boundary must put its OWN scanner in
291
+ * front of the store; widening candidates are evaluated per-format in the review backlog (RB-445).
292
+ */
62
293
  export declare function detectSecret(text: string): string | null;
294
+ /**
295
+ * Store-boundary secret-scan invariant (CC-parity P0-2). Fail-closed: if `body` carries a high-confidence
296
+ * credential, throw {@link MemoryGateError}`("memory.secret_detected")` — the write NEVER reaches the
297
+ * backend. The error detail names the pattern LABEL (e.g. `aws_access_key_id`), never the matched value,
298
+ * so the secret is not re-leaked into a log/error sink. A clean body is a no-op. Applied by
299
+ * {@link guardedMemoryStore} on EVERY durable write inlet (`append`, `appendStructured`, the
300
+ * `appendPromotable` door) so both the `remember` tool and consolidation ADD are covered at one chokepoint.
301
+ */
63
302
  export declare function enforceSecretWriteGate(body: string): void;
303
+ /**
304
+ * Structured-note secret-scan invariant (CC-parity P0-2). Scans EVERY text field of a {@link StructuredNoteInput}
305
+ * that becomes DURABLE and/or enters the manifest — not just `body`. The body alone is insufficient: `name`
306
+ * (rendered as `[[name]]` cross-references) and `description` (rendered into the recall manifest + injected
307
+ * into the side-query sub-prompt) are ALSO persisted and surfaced, so a secret hidden there
308
+ * (`appendStructured({ body: "safe", description: "sk_live_…" })`) would otherwise be durably stored and
309
+ * leaked into every later same-scope manifest — a real bypass of the body-only scan. `links` slugs are NOT
310
+ * scanned: they are short `[[name]]`-style reference tokens (no credential body shape clears the
311
+ * conservative detector), and scanning them adds FP surface for no realistic gain. Fail-closed: the first
312
+ * field that carries a high-confidence credential throws {@link MemoryGateError}`("memory.secret_detected")`.
313
+ */
64
314
  export declare function enforceStructuredNoteSecretGate(note: StructuredNoteInput): void;
315
+ /**
316
+ * Classify a structured-note write as `caller_authored` (normal memory — ungated) or `promotable` (a
317
+ * self-evolution artifact — gated) — design/77 §2. PURE, taxonomy-free CORE logic.
318
+ *
319
+ * `promotable` iff the note's `type` is defined AND outside the caller-authored closed set, OR the note
320
+ * carries a structural promotable marker. **The structural marker WINS over the closed-set type** — a
321
+ * `type:"reference"` note WITH an `outcomeStats` marker classifies `promotable`.
322
+ */
65
323
  export declare function classifyPromotable(note: StructuredNoteInput): "caller_authored" | "promotable";
324
+ /**
325
+ * The store-boundary Gate-2 check (design/77 §2). For a `promotable` note, require a present-and-positive
326
+ * `utilityVerdict`; otherwise throw {@link MemoryGateError}`("memory.promotable_ungated")` fail-closed —
327
+ * the write NEVER reaches the backend. A `caller_authored` note is unchanged (no verdict needed).
328
+ *
329
+ * **Gate-presence invariant (CRITICAL):** "positive" is decided by the profile `utilityGate`. When the
330
+ * gate is UNWIRED, a promotable note STILL fails closed (an absent gate never auto-passes). When wired,
331
+ * the verdict must be present (`!== undefined`) and the gate must accept its `outcomeStats`.
332
+ */
66
333
  export declare function enforcePromotableWriteGate(note: StructuredNoteInput, utilityVerdict: unknown, utilityGate?: UtilityGate): void;
334
+ /**
335
+ * Wrap a {@link MemoryStore} so EVERY durable write path runs the Gate-2 chokepoint (design/77 §2). One
336
+ * wrapper at the store boundary covers BOTH inlets (the `remember` tool and consolidation ADD) — no
337
+ * per-inlet edits. It intercepts BOTH write methods (§2 polish):
338
+ * - `appendStructured` — classify the structured note; a `promotable` one needs a present+positive verdict.
339
+ * Since `appendStructured` carries NO verdict, a promotable structured write is ALWAYS rejected here;
340
+ * the legitimate way to land one is {@link MemoryStore.appendPromotable} (which carries the verdict).
341
+ * - `append` — the legacy/typeless fallback CANNOT carry structure, so any append-path write is
342
+ * classified `caller_authored` and passes through unchanged (documents the chokepoint's exhaustiveness
343
+ * across store methods — a promotable artifact structurally cannot flow out of this path).
344
+ *
345
+ * `appendPromotable` is the gated legitimate door: it runs the gate WITH the supplied verdict, then (on
346
+ * pass) writes via the inner store's `appendStructured` (or `append` fallback). The id-addressed `update`
347
+ * (consolidation's UPDATE op) replaces a note's text with new model-generated content, so it is ALSO
348
+ * secret-scanned (a promotable artifact structurally cannot flow out of it — only existing-note text is
349
+ * rewritten). `delete` and the read/search/manifest surface are straight pass-throughs (they carry no new
350
+ * content and never WRITE a promotable artifact).
351
+ */
67
352
  export declare function guardedMemoryStore(inner: MemoryStore, utilityGate?: UtilityGate): MemoryStore;
353
+ /**
354
+ * Default in-memory MemoryStore (lost on restart). Use a durable backend in production.
355
+ *
356
+ * Id-addressable (design/41): each note gets a UUID stable across `update` and never reused after
357
+ * `delete`, so {@link searchScored}/{@link update}/{@link delete} work and memory consolidation can run.
358
+ * It has no embeddings, so `searchScored` returns a **lexical** (Jaccard) distance as a stand-in for a
359
+ * real cosine distance — fine for dev/tests, but a production store should back this with vectors.
360
+ */
68
361
  export declare class InMemoryMemoryStore implements MemoryStore {
69
362
  private byScope;
363
+ /** design/84 Seam B: per-scope periodic-consolidation cursor (lost on restart, like the rest of this store). */
70
364
  private cursorByScope;
365
+ /** design/81 Slice 5: the in-memory store has no embedder — always the lexical floor. */
71
366
  readonly vectorMode: "lexical";
72
367
  read(scope: string): string | null;
73
368
  append(scope: string, note: string): string | void;
74
369
  appendStructured(scope: string, note: StructuredNoteInput): string;
75
370
  clear(scope: string): void;
371
+ /**
372
+ * Keyword search backing the `recall` tool. design/81 Slice 2b — uses the SHARED synonym/stem-aware
373
+ * {@link lexicalSearchMatch} (the SAME matcher as {@link import("../stores/file/memory-store.js").FileMemoryStore.search}),
374
+ * so the `recall` tool returns IDENTICAL results across the InMemory and File backends. With no synonym/stem
375
+ * hit it degrades to the plain substring filter (byte-identical to the pre-Slice-2b behavior).
376
+ */
76
377
  search(scope: string, query: string, limit?: number): string[];
378
+ /**
379
+ * Lexical-distance retrieval (consolidation candidate source). Distance = `1 - Jaccard(terms)` so it
380
+ * lives in [0, 1] ⊂ the [0, 2] cosine-distance contract (0 = identical term set). Returns the top
381
+ * `limit` nearest entries (excludes zero-overlap ones). Deterministic — handy for tests.
382
+ */
77
383
  searchScored(scope: string, query: string, limit?: number): ScoredMemory[];
78
384
  update(scope: string, id: string, text: string): void;
79
385
  delete(scope: string, id: string): void;
386
+ /** Manifest (design/65 §2.2): a header per note, body excluded. description = the note's first sentence
387
+ * (legacy flat notes have no frontmatter; this is the council #10 P1 fallback). */
80
388
  listStructuredNotes(scope: string): MemoryNoteHeader[];
389
+ /** design/84 Seam B: read the periodic-consolidation cursor (opaque note-id high-water mark). */
81
390
  getConsolidationCursor(scope: string): string | undefined;
391
+ /** design/84 Seam B: persist the periodic-consolidation cursor. */
82
392
  setConsolidationCursor(scope: string, cursor: string): void;
83
393
  getByIds(scope: string, ids: string[]): MemoryNoteRecord[];
84
394
  }
395
+ /**
396
+ * design/81 Slice 2b — a ZERO-MODEL lexical term expander closing the only real lexical recall weakness the
397
+ * defect-hunt raised (the `recall`-tool `search` misses paraphrases like "auth token" vs "credentials/bearer").
398
+ * Pure TS, NO embedder/native/model dep — same posture as the Jaccard stand-in. For a lower-cased query
399
+ * term it returns that term PLUS:
400
+ * - its members of a small bidirectional **synonym set** (auth↔credentials↔bearer, token↔key↔secret, …),
401
+ * looked up for BOTH the original term AND its plural stem (so an inflected query like "tokens" — whose
402
+ * singular "token" is the synonym-group member — still expands to {bearer, apikey, secret, key}), and
403
+ * - a light **plural** stem (`-ies→-y`, `-es`, `-s`, with a ≥3-char guard) so "tokens" reaches "token".
404
+ * (The `-ing`/`-ed` rules were removed — they over-truncated and produced wrong stems.)
405
+ * Always includes the original term, so a non-expandable term degrades to the existing substring match
406
+ * (byte-identical to the prior behavior when no synonym/stem applies). The caller (`lexicalSearchMatch`)
407
+ * treats the returned variants as an OR within one query term (still AND across terms).
408
+ */
85
409
  export declare function expandLexicalTerms(term: string): string[];
410
+ /**
411
+ * Shared SYNONYM/STEM-aware lexical match (design/81 Slice 2b) — the ONE matcher used by BOTH
412
+ * {@link InMemoryMemoryStore.search} and {@link import("../stores/file/memory-store.js").FileMemoryStore.search},
413
+ * so the `recall` tool returns IDENTICAL results across backends (the "byte-identical to InMemory" contract).
414
+ * It is a recall-QUALITY behavior, correct to apply everywhere. (Pg's `search` is a separate SQL path —
415
+ * a known follow-on, unchanged in this pass.)
416
+ *
417
+ * Matching rule: tokenize `text` on word boundaries, then for each whitespace-separated `query` term the
418
+ * text must match AT LEAST ONE of that term's {@link expandLexicalTerms} variants (OR within a term), and
419
+ * EVERY query term must match (AND across terms). The ORIGINAL query term keeps its pre-Slice-2b SUBSTRING
420
+ * semantics (back-compat); the EXPANDED synonym/stem variants are matched on WORD BOUNDARIES (set membership
421
+ * over the text's token set) so a short injected synonym like "key"/"db" cannot substring-match an unrelated
422
+ * word ("keyboard"/"double"). An empty/whitespace-only query never matches.
423
+ */
86
424
  export declare function lexicalSearchMatch(query: string, text: string): boolean;
425
+ /** First sentence (or ~120-char head) of a note — the manifest description fallback for untyped notes. */
87
426
  export declare function firstSentence(text: string): string;
427
+ /**
428
+ * Parse a note's `"YYYY-MM-DD HH:MM"` (UTC) stamp into the {@link MemoryNoteHeader} timestamp PAIR —
429
+ * the ONE mint point for `mtimeMs`/`timestampMissing`, shared by the in-memory and file stores.
430
+ *
431
+ * **Unknown is not 1970.** This used to return a bare `0` for anything unparseable, and every consumer
432
+ * then read that `0` as a real epoch timestamp. A note whose stamp was absent, blank, or written in a
433
+ * foreign format (a full ISO-8601 `2026-08-04T12:30:00Z` from a third-party producer survives JSON
434
+ * replay intact, but the `" " → "T"` rewrite below turns it into an unparseable `…T12:30:00Z:00Z`)
435
+ * therefore became the OLDEST note in its scope forever: it lost every `[[name]]` collision to every
436
+ * stamped note, and the recall renderer told the model it was "written 678 months ago — verify it's
437
+ * still current". Both are silent recall losses caused by the sentinel, not by the note.
438
+ *
439
+ * The unknown case is now an EXPLICIT axis (same shape as the brain layer's `usageMissing`): the numeric
440
+ * slot stays a `0` shell and `timestampMissing: true` states that the shell is not a measurement. The two
441
+ * fields are minted TOGETHER here and callers spread the result, so it is not constructible to publish
442
+ * the shell without its flag. Consumers branch on the flag and never on the value — `mtimeMs === 0` is a
443
+ * legal timestamp (a note genuinely stamped `1970-01-01 00:00` parses fine and is NOT flagged).
444
+ *
445
+ * **No persisted format ripple.** What the stores durably hold is the `ts` STRING, never this parsed
446
+ * number, so there is no stored `0` whose meaning has to be re-decided: unknown-ness is re-derived on
447
+ * every read from whether the string parses. The one genuinely ambiguous stored value is the literal
448
+ * string `"1970-01-01 00:00"`. It is treated as a real time, and that is the honest call rather than a
449
+ * convenient one — neither store has ever WRITTEN that string (both stamp `new Date()` at append/update),
450
+ * so it can only come from a foreign producer, and a foreign producer that meant "unknown" has always
451
+ * had the unambiguous spelling available: omit `ts`, or leave it blank.
452
+ *
453
+ * Takes `unknown` because the stamp arrives from a PERSISTED WIRE record (the file store's `append`
454
+ * event, whose forward-compat promise covers logs this build did not write). A line carrying no `ts` at
455
+ * all reached the old signature as `undefined` and threw a `TypeError` out of the manifest build — the
456
+ * whole scope's recall died on one malformed line.
457
+ */
88
458
  export declare function parseNoteTimestamp(ts: unknown): {
89
459
  mtimeMs: number;
90
460
  timestampMissing?: true;
91
461
  };
462
+ /** The canonical, normalized shape of {@link import("./types.js").TaskSpec.memory} — the ONE form every
463
+ * consumer reads (prepare-task, recall, consolidation, the remember tool), so the union never narrows
464
+ * downstream. `scopes` is the ordered read-side layering (first = stable prefix, last = volatile tail =
465
+ * highest priority); `writeScope` is the single layer ALL writes land in (`null` = read-only, no writes). */
92
466
  export interface NormalizedMemorySpec {
467
+ /** Ordered, deduped, non-empty opaque scopes for read-side layered injection (list order = inject order). */
93
468
  scopes: string[];
469
+ /** The single scope all writes route to (decision 3), or `null` for a read-only (inherited) layering. */
94
470
  writeScope: string | null;
471
+ /** Mirrors `memory.enabled` (default true) — false ⇒ the whole memory feature is off for this task. */
95
472
  enabled: boolean;
473
+ /** design/142 §1.2 — present iff the task opted into the v2 scope identity contract (keys validated). */
96
474
  scopeContract?: "v2";
475
+ /**
476
+ * design/178 §3 — host allowlist for UNDECLARED tools: names listed here classify `"local"` instead
477
+ * of the fail-closed `"external"` default. The explicit-config channel for a deployment whose custom
478
+ * tools predate the {@link import("./types.js").ToolSpec.contentOrigin} declaration; it never
479
+ * overrides a tool's OWN declaration. Normalized: trimmed, deduped, empties dropped.
480
+ */
97
481
  trustedTools?: string[];
482
+ /**
483
+ * design/178 §3 strict upgrade (`execIsExternalContent`): treat `"execution"`-class tools as
484
+ * external-content sources — invoking one then marks the session's memory polluted. For
485
+ * high-assurance deployments; default false (the execution class is a NAMED residual channel:
486
+ * write-side scans/fences compensate, and disabling memory for every shell session would disable
487
+ * it for the main coding scenario).
488
+ */
98
489
  execIsExternalContent?: boolean;
490
+ /** Per-scope origin provenance stamped by the deployment's ASSEMBLY point (a server that resolved an
491
+ * operator registry entry knows what core cannot). Two-tier absence semantics (ruled 2026-08-05):
492
+ * the WHOLE key absent = legacy — admission classifies by the deployment-scope set exactly as
493
+ * before (a `^5.12` default install must not have its single-user deployment refused by its own
494
+ * upgrade); the key PRESENT but missing an entry for a scope = that scope is `"request"`
495
+ * (fail-closed for the stamped form). Domain covers `writeScope` strings too. */
99
496
  scopeOrigins?: Readonly<Record<string, "deployment" | "request">>;
100
497
  }
498
+ /** The memory spec accepted on `TaskSpec.memory`. RB-479-B② (ruled 2026-08-02): ONE form —
499
+ * the legacy singular `scope` field is REMOVED; `scopes` (ordered read layers) is the only spelling.
500
+ * An input still carrying an own `scope` property is REFUSED by {@link normalizeMemorySpec}
501
+ * (`config.memory_scope_spelling`), not quietly read as "no scopes" — see the throw there. */
101
502
  export type MemorySpecInput = {
102
503
  scopes?: ReadonlyArray<string>;
103
504
  writeScope?: string | null;
104
505
  enabled?: boolean;
506
+ /**
507
+ * design/142 §1.2 — EXPLICIT opt-in to the v2 scope identity contract (`user:` / `org:` /
508
+ * `proj:<tenant>/<projectId>` / `userproj:` typed keys). Absent ⇒ every scope stays byte-identically
509
+ * OPAQUE, including keys that happen to look like `user:42` (the documented legacy shape above — the
510
+ * contract is NEVER activated by prefix sniffing, 复审 F1 double-confirmed). Under `"v2"`, keys
511
+ * carrying a reserved prefix are validated fail-loud (`config.memory_scope_key`); unprefixed keys
512
+ * remain legal opaque legacy scopes.
513
+ */
105
514
  scopeContract?: "v2";
515
+ /** See {@link NormalizedMemorySpec.trustedTools} — design/178 §3 allowlist for undeclared tools. */
106
516
  trustedTools?: ReadonlyArray<string>;
517
+ /** See {@link NormalizedMemorySpec.execIsExternalContent} — design/178 §3 strict upgrade. */
107
518
  execIsExternalContent?: boolean;
519
+ /** See {@link NormalizedMemorySpec.scopeOrigins} — assembly-point provenance, additive. */
108
520
  scopeOrigins?: Readonly<Record<string, "deployment" | "request">>;
109
521
  };
522
+ /**
523
+ * Normalize {@link import("./types.js").TaskSpec.memory} into ONE canonical
524
+ * {@link NormalizedMemorySpec} (design/84 Seam A decision 1). The consumer side reads ONLY this result — no
525
+ * narrowing of the union anywhere downstream:
526
+ * - an own `scope` property (the removed singular spelling) is a THROW, not a normalization —
527
+ * `config.memory_scope_spelling`, so the task fails to start instead of running memory-less.
528
+ * - blank/whitespace scopes are dropped and duplicates collapsed (FIRST occurrence wins — keeps the
529
+ * caller's stable→volatile order); list order is the inject order (stable prefix first, volatile tail last).
530
+ * - `writeScope` defaults to the LAST scope (the highest-priority layer); an EXPLICIT `null` means read-only
531
+ * (no `remember` tool, no consolidation); an explicit non-null string is taken as-is (it need NOT be one
532
+ * of `scopes` — a deployment may write a layer it does not inject, though normally it is the last scope).
533
+ * ⚠️ Layered READ seeding (service [646]①, 142-S4): when `scopes` comes from a registry's defaultScopes
534
+ * (shared read layers), ALWAYS pin `writeScope` explicitly — the last-scope default would land every
535
+ * harvest in whichever shared layer happens to be listed last (a cross-tenant write surface).
536
+ * - returns `undefined` when there are no usable scopes (the caller treats it like "no memory configured").
537
+ *
538
+ */
110
539
  export declare function normalizeMemorySpec(input: MemorySpecInput | undefined): NormalizedMemorySpec | undefined;
540
+ /** Max bytes of memory injected into the prompt; larger is truncated with a marker. (CodeWhale: 100 KiB)
541
+ * Exported so the inject-all de-dup seeding (prepare-task.ts) can detect truncation and NOT seed dropped
542
+ * (truncated-out) note ids as "already surfaced" — see the MINOR-1 audit fix there. */
111
543
  export declare const MAX_MEMORY_BYTES: number;
544
+ /** The wrapper-tag family the memory injection fences neutralize (`<system-reminder>` is ALWAYS
545
+ * included by {@link sanitizeUntrustedText} itself). Single source (design/138 S2-C, C-F10/O-F11):
546
+ * the memory write-time scan (`memory-engine/scan.ts`) detects break-out markup by diffing
547
+ * `sanitizeUntrustedText(text, MEMORY_WRAPPER_TAGS)` against the raw text, so the scan rules and
548
+ * the ACTUAL injection boundary (this file's compose* fences) can never drift apart. */
112
549
  export declare const MEMORY_WRAPPER_TAGS: readonly string[];
550
+ /**
551
+ * Wrap memory content in a `<user_memory>` block. This is the **variable tail** of the system prompt
552
+ * (per-user, scoped, timestamped) — the default prompt provider places it LAST so the stable base
553
+ * prompt before it stays a cacheable prefix (see `defaultPromptProvider`).
554
+ * Truncates over-cap content with a `<truncated bytes=N>` marker (mirrors CodeWhale `as_system_block`).
555
+ * Returns undefined for empty content.
556
+ */
113
557
  export declare function composeMemoryBlock(content: string | null | undefined, scope: string): string | undefined;
558
+ /**
559
+ * Compose the LAYERED inject-all memory block for multiple scopes (design/84 Seam A decision 2). One
560
+ * `<user_memory>` block with a `<scope name="…">` subsection per scope, **in the given list order** — the
561
+ * caller passes stable layers FIRST (cacheable prefix) and volatile layers LAST (re-computed tail), and the
562
+ * highest-priority layer is therefore at the END of the block (closest to the model's attention, matching the
563
+ * single-scope tail placement). Empty layers are omitted. Each layer's content is byte-capped + fence-sanitized
564
+ * exactly like {@link composeMemoryBlock} (the same A-7 escape class). Returns `undefined` when every layer is
565
+ * empty (no block to inject).
566
+ *
567
+ * **Cache-stability guarantee (§5):** the subsection order is EXACTLY the caller's list order — never sorted
568
+ * or reordered here — and the per-scope wrapper/format is fixed, so a stable layer at the front renders
569
+ * byte-identically across turns (the 90/98% prefix-cache hit measured in §5.1/§5.2 depends on this). The
570
+ * VOLATILE layers the caller places last are the only part that changes, so only the tail re-computes.
571
+ */
114
572
  export declare function composeLayeredMemoryBlock(layers: ReadonlyArray<{
115
573
  scope: string;
116
574
  content: string | null | undefined;
@@ -1,4 +1,10 @@
1
1
  import type { AgentMessage } from "../internal/harness-types.js";
2
2
  import type { ToolResultMessage } from "../internal/llm.js";
3
+ /** Read the (possibly absent) `role` off an AgentMessage defensively — the union doesn't expose it
4
+ * uniformly, so context passes narrow by role with a single cast in one place. */
3
5
  export declare function messageRole(m: AgentMessage): string | undefined;
6
+ /** True if the message is a tool-result message (shared by the context-edit and context-guard passes).
7
+ * A TYPE PREDICATE, not a bare boolean: `role: "toolResult"` belongs to exactly one member of the
8
+ * union, so callers that check it can read `.content`/`.toolName` and rebuild the message directly
9
+ * instead of asserting the shape back with `as unknown as` (RB-436-g). */
4
10
  export declare function isToolResult(m: AgentMessage): m is ToolResultMessage;