@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,25 +1,62 @@
1
+ /**
2
+ * Structured header fields of one memory entry (the CC frontmatter shape: `name`/`description`/
3
+ * `metadata.type`). `extra` preserves any additional frontmatter lines VERBATIM (round-trip safety:
4
+ * the engine must never destroy model-authored frontmatter it doesn't understand — same posture as
5
+ * the file store's unknown-op replay skip).
6
+ */
1
7
  export interface MemoryEntryFrontmatter {
8
+ /** Short kebab-case slug (CC `name:`). Defaults to the file slug when the model omits it. */
2
9
  name?: string;
10
+ /** One-line summary used for recall relevance (CC `description:`). */
3
11
  description?: string;
12
+ /** CC `metadata.type`: user | feedback | project | reference (unknown strings degrade, design/65). */
4
13
  type?: string;
14
+ /** design/138 §2.4 删除防线 — the EXPLICIT tombstone. A file that merely disappears is NEVER a
15
+ * delete; only `deleted: true` in frontmatter produces a delete patch. */
5
16
  deleted?: boolean;
17
+ /**
18
+ * design-A C-5 (AGENTS.md×ingest, [A1]) — TYPED provenance for entries an INGEST producer minted
19
+ * from a repo file (project instruction files: AGENTS.md/CLAUDE.md — the file-name policy lives
20
+ * in the deployment; this type never names files). `path` is repo-relative; `contentHash` covers
21
+ * the raw pre-cap source bytes (opaque to the engine — equality comparison only); `ingestedAt`
22
+ * is ms epoch. Closed kind on purpose: `"repo_file"` is the only provenance the trust gates
23
+ * reason about (I-2 below); a malformed/unknown provenance block in a file round-trips through
24
+ * `extra` verbatim instead (never destroyed, never trusted).
25
+ */
6
26
  provenance?: {
7
27
  kind: "repo_file";
8
28
  path: string;
9
29
  contentHash: string;
10
30
  ingestedAt: number;
11
31
  };
32
+ /**
33
+ * design-A C-5/I-2 — the trust marker for repo-originated content: once `"untrusted"`, it can
34
+ * never be whitewashed. Enforcement is STRUCTURAL, not conventional: the backend contract
35
+ * (memory-backend-contract.ts) refuses any update patch that strips `trust`/`provenance` from an
36
+ * entry whose committed state carries `provenance.kind === "repo_file"` (malformed-refusal seat,
37
+ * same family as the `entry.id !== patch.id` clause). Single-value union on purpose — there is
38
+ * no `"trusted"` spelling to escalate to.
39
+ */
12
40
  trust?: "untrusted";
41
+ /** Unknown frontmatter lines preserved verbatim (order kept), re-serialized on projection. */
13
42
  extra?: string[];
14
43
  }
44
+ /** design/138 §2.1 — one memory entry (the unit the backend stores and the engine projects to a file). */
15
45
  export interface MemoryEntry {
46
+ /** IMMUTABLE uuid — survives slug renames (consolidation cursors/vectors/dedup all key on it).
47
+ * Hidden in the file's frontmatter as `id:`; minted at harvest for id-less new files. */
16
48
  id: string;
49
+ /** File-name identity (the path relative to its scope dir, without `.md`) — model-visible, renameable. */
17
50
  slug: string;
18
51
  frontmatter: MemoryEntryFrontmatter;
52
+ /** The markdown body (everything after the frontmatter block). */
19
53
  body: string;
54
+ /** CAS baseline — a content hash over (id, frontmatter, body). See {@link computeEntryRev}. */
20
55
  rev: string;
56
+ /** Owning scope (tenant/layer key, same vocabulary as `TaskSpec.memory.scopes`). */
21
57
  scope: string;
22
58
  }
59
+ /** Manifest-level header: enough to judge relevance / build the derived index, never the body. */
23
60
  export interface MemoryEntryHeader {
24
61
  id: string;
25
62
  slug: string;
@@ -27,20 +64,45 @@ export interface MemoryEntryHeader {
27
64
  name?: string;
28
65
  description?: string;
29
66
  type?: string;
67
+ /** Last content change (ms epoch) — drives the natural-language age rendering in the derived index. */
30
68
  mtimeMs: number;
31
69
  rev: string;
70
+ /** Approximate stored size (bytes of body+frontmatter) — drives the per-scope materialization budget. */
32
71
  sizeBytes: number;
33
72
  }
73
+ /** A scored search hit (FileBackend = lexical floor; PgBackend = design/81 vector rungs, S3). */
34
74
  export interface ScoredMemoryEntry extends MemoryEntryHeader {
75
+ /** Cosine-DISTANCE ∈ [0,2], 0 = identical (same contract as {@link import("../memory.js").ScoredMemory}). */
35
76
  score: number;
36
77
  }
78
+ /**
79
+ * design/138 §2.1 — one entry transaction. `add`/`delete` are naturally commutative; `update` carries
80
+ * a per-id CAS baseline (`baseRev`): when the backend's current rev differs, the patch is reported as a
81
+ * CONFLICT (never blind-written) and the next task re-materializes fresh state (§2.4 并发).
82
+ */
37
83
  export interface NotePatch {
38
84
  op: "add" | "update" | "delete";
85
+ /** The immutable entry id this patch addresses. */
39
86
  id: string;
87
+ /** The full new entry state (`add`/`update`). Absent for `delete`. */
40
88
  entry?: MemoryEntry;
89
+ /** CAS baseline for `update`/`delete`: the rev this patch was computed against. Absent (a brand-new
90
+ * add) ⇒ no CAS. */
41
91
  baseRev?: string;
92
+ /** ADD-ONLY guard (design/142 S2.5, E-02). Meaningful only on `op: "add"`:
93
+ * - `"absent"` ⇒ add-if-absent: if the target id already exists, the backend compares revs —
94
+ * same rev AND same projection (scope+slug) = idempotent apply; DIFFERENT rev, or same rev at a
95
+ * DIFFERENT projection (三轮复查: rev hashes id/frontmatter/body, not slug/scope — a same-content
96
+ * copy at another slug/scope is no no-op, "applying" it would mint a duplicate file for the id) =
97
+ * a REPORTED conflict (`add_guard_absent_conflict`, carrying `currentRev`), NEVER a blind
98
+ * overwrite or a duplicate. This is for sync's first-round pull adds, where a concurrent local
99
+ * create during the RTT must not be clobbered.
100
+ * A plain add WITHOUT this guard keeps its existing idempotent-overwrite semantics (the
101
+ * `same-scope re-add of an existing id is the idempotent overwrite` contract clause is unchanged).
102
+ * Ignored on `update`/`delete`. */
42
103
  guard?: "absent";
43
104
  }
105
+ /** Result of {@link MemoryBackend.applyPatches} — applied ops + per-id CAS conflicts (reported, not thrown). */
44
106
  export interface PatchReport {
45
107
  applied: Array<{
46
108
  op: NotePatch["op"];
@@ -55,81 +117,207 @@ export interface PatchReport {
55
117
  currentRev?: string;
56
118
  }>;
57
119
  }
120
+ /**
121
+ * design/138 §2.1 — the storage seam under the MemoryEngine. NOT a MemoryStore replacement shim: this
122
+ * is the S1 new-architecture surface (the legacy `MemoryStore` path is untouched and switched off it).
123
+ */
58
124
  export interface MemoryBackend {
125
+ /** Headers for every entry in the given scopes (manifest surface — bodies excluded). */
59
126
  listHeaders(scopes: readonly string[]): Promise<MemoryEntryHeader[]>;
127
+ /** Full entries for the selected ids (unknown ids silently skipped). */
60
128
  getByIds(ids: readonly string[]): Promise<MemoryEntry[]>;
129
+ /** Scored retrieval (FileBackend = lexical floor; vector rungs live in the S3 PgBackend). */
61
130
  search(query: string, scopes: readonly string[], opts?: {
62
131
  limit?: number;
63
132
  }): Promise<ScoredMemoryEntry[]>;
133
+ /**
134
+ * Apply entry transactions (add/update/delete) against the backend's CURRENT state (per-id CAS).
135
+ *
136
+ * Behavior clauses a conforming implementation MUST honor (ext-dogfood F1 — each is asserted by
137
+ * `memoryBackendContract`, listed here so a third party doesn't have to discover them case by case):
138
+ * - a repeated id WITHIN one batch: first op wins, later ones conflict with reason matching
139
+ * /duplicate id in batch/;
140
+ * - `entry.id !== patch.id` (either op) is refused with reason matching /malformed patch refused/
141
+ * — never silently rekeyed;
142
+ * - an `add` whose slug is taken by a DIFFERENT id in the same scope gets a deterministic `-n`
143
+ * suffix (`taken` → `taken-2`); the id stays the identity anchor;
144
+ * - SAME-SCOPE re-`add` of an existing id is the idempotent overwrite — not a conflict. An add of
145
+ * an id living in ANOTHER scope is REFUSED with reason matching /cross-scope add refused/ (2026-07-12
146
+ * 裁定, all three backends agree — the Pg/TiDB twins always pre-checked this; File now matches).
147
+ * The one spelling of a cross-scope MOVE is `update` (next clause) — an add can never relocate an id;
148
+ * - an `add` carrying `guard: "absent"` is add-if-absent: onto a MISSING id it is a plain add;
149
+ * onto an EXISTING id it is idempotent when the rev AND the projection (scope+slug) match, else a
150
+ * REPORTED conflict with reason matching /add_guard_absent_conflict/ carrying `currentRev` —
151
+ * NEVER a blind overwrite, never a second file for one id (E-02 + 三轮复查投影校验);
152
+ * - `update` MAY move an entry across scopes; a stale `baseRev` is a REPORTED conflict, never
153
+ * thrown, never blind-written;
154
+ * - design-A I-2 洗白拒收 ([A1]): when the entry's CURRENT committed state carries
155
+ * `frontmatter.provenance.kind === "repo_file"`, an `update` whose new frontmatter drops
156
+ * `provenance`, or drops a present `trust` marker, is refused with reason matching
157
+ * /malformed patch refused/ (same seat as the id-mismatch clause) — repo-originated content
158
+ * can never be whitewashed into an unmarked (implicitly trusted) entry. A conforming update of
159
+ * such an entry (the ingest producer's own re-ingest) always carries both fields forward;
160
+ * - conflicts are per-patch and non-fatal: the rest of the batch still applies.
161
+ */
64
162
  applyPatches(patches: readonly NotePatch[]): Promise<PatchReport>;
163
+ /** design/84 Seam B cursor pair, migrated verbatim onto the entry-id plane (S2 rewires consolidation). */
65
164
  getConsolidationCursor(scope: string): Promise<string | undefined>;
66
165
  setConsolidationCursor(scope: string, cursor: string): Promise<void>;
67
166
  }
167
+ /** One file the engine materialized into the session memory directory. */
68
168
  export interface MaterializedFile {
169
+ /** Absolute canonical path of the projected file. */
69
170
  path: string;
171
+ /** Path relative to the memory dir root (the link target used in the derived MEMORY.md index). */
70
172
  relPath: string;
71
173
  scope: string;
72
174
  id: string;
73
175
  slug: string;
176
+ /** Rev of the ON-DISK content at materialize time (for a stub: the stub content's rev). */
74
177
  rev: string;
178
+ /** True when this file is a budget stub (frontmatter+description only, body archived — §2.3). */
75
179
  stub: boolean;
180
+ /** True when the file belongs to a read-only inherited layer (chmod-protected, never harvested as a write). */
76
181
  readonly: boolean;
77
182
  }
183
+ /**
184
+ * design/138 §2.2 — the session handle `materialize` returns and `harvest`/`rebaseline` consume.
185
+ * `materialized` IS the harvest diff domain (plus session-new files under `writableRoot`): an entry
186
+ * that was never materialized can never be deleted by its absence (镜头 G).
187
+ */
78
188
  export interface MemorySessionHandle {
189
+ /** The memory directory root. PURE CONFIG (§2.7 r2.1): a project scope may live IN-REPO
190
+ * (git-tracked `memory/`), a user/personal scope OUTSIDE — the engine never asserts either.
191
+ * TODO(S1b): per-scope PHYSICAL roots (project scope in-repo + user scope in the home mount in ONE
192
+ * session) — `fileToScope` already keys absolute paths, so only the layout mapping needs the split. */
79
193
  memoryDir: string;
194
+ /** The single directory the model may write memory into (the writeScope's home). Equals `memoryDir`
195
+ * when the writeScope owns the root (the standard TOC layout). */
80
196
  writableRoot: string;
81
197
  writeScope: string | null;
82
198
  scopes: string[];
199
+ /** The materialized manifest = the harvest diff domain. */
83
200
  materialized: MaterializedFile[];
201
+ /** Absolute file path → owning scope. */
84
202
  fileToScope: Map<string, string>;
203
+ /** Absolute file path → materialize-time rev (the per-id CAS baseline harvest sends with updates). */
85
204
  baseRevs: Map<string, string>;
205
+ /** Absolute file path → entry id at materialize time (rename/id-restore bookkeeping). */
86
206
  baseIds: Map<string, string>;
207
+ /** design-A C-6 ([A3]) — ingest 条目不投影: entry id → repo-relative `provenance.path` for the
208
+ * repo-ingested entries (`frontmatter.provenance.kind === "repo_file"`) materialize did NOT
209
+ * project into the writable memory dir (copy-out mode only — the true body lives in the repo;
210
+ * a projection would be a duplicate the model can edit into a forgery, I-3). The derived-index
211
+ * rebuild links these entries to the recorded repo path instead of a projection file. Absent /
212
+ * empty when the session has no such entries (projection behavior byte-identical, pinned). */
87
213
  repoIndexTargets?: Map<string, string>;
214
+ /** Lines of the derived MEMORY.md at materialize time (the index-cleared fuse baseline). */
88
215
  indexBaselineLines: number;
216
+ /** 评审 M6 — the derived index TEXT as of materialize. `inject` reads THIS when no on-disk
217
+ * MEMORY.md exists (a read-only layering never writes one), so first-session read-only injection
218
+ * works without a disk round-trip. */
89
219
  indexText: string;
220
+ /** Set when the index gate fired AND its containment did not complete — the on-disk MEMORY.md
221
+ * still holds the rejected bytes (a clear can be refused: a non-file index path, an unwritable
222
+ * one). `inject` then reads {@link indexText} instead of the live file, and offers no index seed:
223
+ * the gate's whole purpose is keeping those bytes out of the prompt, so a refused clear must not
224
+ * leave the injection path reading them anyway. Absent ⇒ the normal "live file wins" behavior. */
225
+ indexOnDiskUntrusted?: boolean;
90
226
  }
227
+ /** Stable rejection codes a harvest gate can produce (model-visible gate events — 镜头 I). */
91
228
  export type HarvestRejectionCode = "outside_root" | "symlink" | "secret" | "injection" | "filename" | "too_large" | "file_cap" | "readonly_layer" | "stub_modified" | "nested_too_deep" | "quarantine_failed" | "unreadable" | "polluted" | "invalid";
229
+ /** One rejected file: path (relative to the memory dir), stable code, and a model-readable reason. */
92
230
  export interface HarvestRejection {
93
231
  path: string;
94
232
  code: HarvestRejectionCode;
95
233
  reason: string;
96
234
  }
235
+ /**
236
+ * design/138 S2-C — one finding from the shared write-time/harvest scan rule set
237
+ * (`scan.ts` `scanMemoryWrite`/`scanMemoryFileName`; ONE rule set, TWO mount points).
238
+ */
97
239
  export interface ScanFinding {
240
+ /** The subset of {@link HarvestRejectionCode} the scan can produce. */
98
241
  code: "secret" | "injection" | "filename" | "too_large";
242
+ /** Engine-composed, model-readable reason fragment (for `secret`: the pattern LABEL, never the value). */
99
243
  reason: string;
100
244
  }
245
+ /**
246
+ * design/138 S2-B — one queued memory-change announcement, drained into the NEXT session's first
247
+ * injection (时机① only; there is no in-run delivery lane — O-F2/C-F4 裁撤). Queued via the
248
+ * journaled control-plane queue ({@link import("./layout.js").enqueueMemoryAnnouncement}) so
249
+ * concurrent writers never overwrite each other (O-F6/C-F5).
250
+ */
101
251
  export interface MemoryAnnouncement {
252
+ /** `gate` = engine gate/harvest events (rejections, quarantine, incidents, restores, conflicts,
253
+ * degradation, applied-patch summary); `external` = out-of-session changes the backend's read-side
254
+ * detected (disk rev ≠ ledger: adopted external edits + inbound-gate rejects). */
102
255
  kind: "gate" | "external";
256
+ /** ms epoch at enqueue. */
103
257
  at: number;
258
+ /** Optional producing-session id (repo-level event stream — Q-G: no worktree attribution in S2). */
104
259
  sessionId?: string;
260
+ /** Engine-composed single-line items. O-F1/C-F8: every model/collaborator-controllable identifier
261
+ * (path/slug/name/description) is neutralized (inlineUntrusted) AND JSON-quoted at ENQUEUE time —
262
+ * the stored strings are already render-safe; the render step only adds the trusted lead/frame. */
105
263
  items: string[];
106
264
  }
265
+ /**
266
+ * design/138 §2.4 — the harvest outcome. Rejections are MODEL-VISIBLE gate events: S1 delivers the
267
+ * structure; the runner's boundary-announcement wiring (attachments member) lands in S2 (TODO(S2)).
268
+ */
107
269
  export interface HarvestReport {
270
+ /** False ⇔ the whole harvest was refused (deletion fuse / missing dir / corrupt sidecar incident). */
108
271
  ok: boolean;
272
+ /** Set when a fuse tripped (§2.4 删除防线 / B3 fail-closed): the harvest is refused wholesale, NO
273
+ * patches (especially no deletes) are produced, and the report is surfaced as an alert. */
109
274
  incident?: {
110
275
  kind: "mass_deletion" | "index_cleared" | "dir_missing" | "sidecar_corrupt";
111
276
  detail: string;
112
277
  };
278
+ /** Patch counts actually APPLIED by the backend. */
113
279
  patches: {
114
280
  add: number;
115
281
  update: number;
116
282
  delete: number;
117
283
  };
284
+ /** Per-id CAS conflicts from the backend (reported, never blind-written). */
118
285
  conflicts: PatchReport["conflicts"];
119
286
  rejections: HarvestRejection[];
287
+ /** Non-`.md` / non-structural files found in the diff domain — listed, never persisted (they stay
288
+ * on disk: they may be the model's working files). Files REMOVED from the model-visible plane go
289
+ * in {@link movedToQuarantine}. */
120
290
  quarantined: string[];
291
+ /** Gate-rejected files physically MOVED into the control plane's `quarantine/` (out of the scan
292
+ * domain and off the model-visible disk — B2/验收 L4: secret-bearing files never linger). */
121
293
  movedToQuarantine: string[];
294
+ /** C-F9 (S2-0) — quarantine escalations: any deviation from the clean capture+remove path is
295
+ * REPORT-VISIBLE here (never a debug-only downgrade). `contained` = the suspect content no longer
296
+ * sits raw on the model-visible plane (deleted / cleared in place / overwritten with the committed
297
+ * copy); `contained: false` is the worst case — residue remains and a human/runner must act. */
122
298
  quarantineFailures?: Array<{
123
299
  path: string;
124
300
  contained: boolean;
125
301
  detail: string;
126
302
  }>;
303
+ /** Materialized files absent at harvest. NOT deletes (§2.4: 文件缺失≠删除). Files whose entry id
304
+ * re-appears at another path (a RENAME) are NOT counted here (验收 M1 — a rename is an id-keyed
305
+ * update, never a missing file, and never feeds the deletion fuse). */
127
306
  missing: string[];
307
+ /** B1 committed-shadow recovery: missing (non-tombstoned) files RESTORED onto disk from the
308
+ * committed copy (backend/shadow). Disclosed here (the restore is an engine action, never silent).
309
+ * Restored paths also appear in {@link missing} (the honest record of what vanished). */
128
310
  restored: string[];
311
+ /** Index self-heal notes (L8): suspected-duplicate index lines kept-with-warning, cleared orphans. */
129
312
  warnings: string[];
313
+ /** M7 harvest budget: set when the deadline/file budget cut the harvest short. `pending` files were
314
+ * NOT processed this round (no patches, still on disk) — the next boundary harvest picks them up. */
130
315
  degraded?: {
131
316
  reason: "deadline" | "file_budget";
132
317
  pending: string[];
133
318
  };
319
+ /** B2 §2.7 r2.1 inbound gate: findings from scanning changes that did NOT originate in this session
320
+ * (e.g. a git-pull-borne edit of an in-repo memory dir — a write channel that bypasses the harvest
321
+ * gate). Populated by the backend's read-side sync gate and drained into the report at harvest. */
134
322
  inboundFindings?: HarvestRejection[];
135
323
  }
@@ -1,14 +1,70 @@
1
1
  import type { MemoryNoteHeader, MemoryNoteRecord, MemoryStore } from "./memory.js";
2
+ /**
3
+ * Selective memory recall (design/65 §2.2 — port of CC `findRelevantMemories`). For a LARGE memory scope,
4
+ * instead of injecting the whole `<user_memory>` block (inject-all), we inject a compact **manifest** (one
5
+ * header line per note) + a side-query that picks the ≤K relevant note ids + only those bodies. Small
6
+ * scopes keep inject-all (the common case after consolidation) — this path is threshold-gated, so most
7
+ * tasks pay nothing.
8
+ *
9
+ * ⚠️ WHAT IS ACTUALLY IN THIS FILE (RB-446, corrected 2026-07-31 — the text below used to describe a
10
+ * DRIVER that no longer exists here, in the present tense). The 2.0.0 B19 export sweep removed the
11
+ * function that ran the pipeline; what remains, and what the rest of core consumes, is the set of PURE
12
+ * HELPERS plus the declared shape of that pipeline:
13
+ * · helpers, all live and in use: {@link formatMemoryAge}, {@link RECALL_CAVEAT},
14
+ * {@link buildManifestText}, {@link validateSelectedIds}, {@link resolveLinkedIds},
15
+ * {@link composeSelectiveBody}, {@link encodeSurfacedKey};
16
+ * · seam DECLARATIONS with no in-tree caller: {@link MemorySelector} /
17
+ * {@link SelectiveRecallOptions} / {@link SelectiveRecallResult} / {@link LayeredRecallOptions} /
18
+ * {@link LayeredRecallResult}. They stay exported because they are the published contract a
19
+ * deployment implements its own driver against — the helpers above are exactly the pieces such a
20
+ * driver assembles — but nothing under `src/` calls them today. Read them as a specification, not
21
+ * as a description of code that runs.
22
+ *
23
+ * The pipeline those declarations specify: pure + deterministic given a selector — validate the returned
24
+ * ids against the manifest (reject hallucinated ids, council #5), cap at K, apply a hard timeout
25
+ * (council #12), and on ANY selector failure/timeout DEGRADE to inject-all (council #4 — never silently
26
+ * drop knowledge). Output goes in the variable tail (manifest + selected bodies are per-user/volatile,
27
+ * like the current memory block). `validateSelectedIds` is the one rung of it that IS implemented here.
28
+ */
29
+ /** Default max notes the side-query may select (CC `findRelevantMemories` ≤5). */
2
30
  export declare const DEFAULT_MAX_SELECTED = 5;
31
+ /** Default max 1-hop link-followed notes appended after the selected ones (design/65 P3). */
3
32
  export declare const DEFAULT_MAX_LINKED = 3;
33
+ /** Default side-query hard timeout (ms) — council #12; on timeout we degrade to inject-all. */
4
34
  export declare const DEFAULT_SELECT_TIMEOUT_MS = 5000;
35
+ /**
36
+ * Render a memory note's age as a natural-language phrase (CC-parity P0-1, design/65). CC's eval found
37
+ * models reason about memory age much better from natural language ("3 days ago") than from a boolean
38
+ * "older note" flag (verify-claims 0/2 → 3/3 once the age was spelled out), because the model can weigh
39
+ * staleness proportionally instead of as a single cliff. This is the relative phrase only; the
40
+ * point-in-time / verify-before-trust discipline still lives in {@link RECALL_CAVEAT} + the per-note
41
+ * "verify it's still current" hint (the age is ADDITIONAL signal, not a replacement).
42
+ *
43
+ * Buckets (each chooses the coarsest unit that's ≥1): `today` (<1 day, incl. future mtime / clock skew →
44
+ * clamped to today, never a negative age), `yesterday` (1–2 days), `N days ago` (2–7 days),
45
+ * `N weeks ago` (1 week – ~1 month), `N months ago` (≥ ~1 month). N is floored to the whole unit.
46
+ */
5
47
  export declare function formatMemoryAge(ageMs: number): string;
48
+ /**
49
+ * Read-side recall caveat (design/65 §8#2 / §9#1 — ported from CC's MEMORY_DRIFT_CAVEAT +
50
+ * TRUSTING_RECALL_SECTION). The council found CC's two-section form is **eval-validated** (verify-claims
51
+ * 0/2→3/3) and that the structure carries the effect: the precise decision-point heading
52
+ * "## Before recommending from memory" scored 3/3 while an abstract heading or a buried bullet scored 0/3.
53
+ * So this is deliberately TWO sections — a drift bullet + a titled action section with the frame-shift
54
+ * sentence and concrete verify actions — NOT one merged paragraph (same semantics, 3× worse eval).
55
+ * MEMORY_SAFETY already carries the authority hierarchy; this adds the point-in-time / verify-before-trust
56
+ * discipline selective recall specifically needs.
57
+ */
6
58
  export declare const RECALL_CAVEAT: string;
7
59
  export interface MemorySelectRequest {
60
+ /** The task objective the recall is for. */
8
61
  objective: string;
62
+ /** The manifest the selector chooses from (id + description [+ type]). */
9
63
  manifest: MemoryNoteHeader[];
64
+ /** Tools the task will use — for these, keep gotchas/warnings, skip pure usage notes (design/65 §2.2). */
10
65
  recentTools?: string[];
11
66
  }
67
+ /** The side-query seam: pick the relevant note ids from the manifest. MUST be fail-fast (throw → degrade). */
12
68
  export type MemorySelector = (req: MemorySelectRequest, signal?: AbortSignal) => Promise<string[]>;
13
69
  export interface SelectiveRecallOptions {
14
70
  store: MemoryStore;
@@ -16,13 +72,54 @@ export interface SelectiveRecallOptions {
16
72
  objective: string;
17
73
  selector: MemorySelector;
18
74
  recentTools?: string[];
75
+ /** Absolute time for the freshness caveat (default Date.now()). */
19
76
  nowMs?: number;
20
77
  maxSelected?: number;
78
+ /** Max 1-hop `[[name]]` link-followed notes appended after the selected ones (design/65 P3).
79
+ * `0` disables link-following. Default {@link DEFAULT_MAX_LINKED}. */
21
80
  maxLinked?: number;
22
81
  timeoutMs?: number;
23
82
  signal?: AbortSignal;
83
+ /**
84
+ * CC-parity P1 (durable cross-worker recall de-dup). Note ids ALREADY surfaced to this logical
85
+ * conversation in earlier turns/runs (CC's in-process `alreadySurfaced`/readFileState filter, lifted
86
+ * to a **durable, caller-owned** set so it survives task hops, resume, and multi-worker fan-out). When
87
+ * provided, these ids are **filtered out of the manifest BEFORE the selector sees it** — the selector
88
+ * never sees an already-shown note, so it cannot re-select it, so a long/resumed/multi-worker session
89
+ * does not re-inject the same bodies. core does NOT store this set (like {@link CheckpointStore}, the
90
+ * durable store is the caller's): the caller persists {@link surfacedIds} from one call and feeds it
91
+ * back here as `priorSurfacedIds` on the next. Omitted ⇒ no filtering (the prior, non-de-duped behavior).
92
+ */
24
93
  priorSurfacedIds?: ReadonlySet<string>;
25
94
  }
95
+ /**
96
+ * Result of a single-scope selective-recall pass. `surfacedIds` (CC-parity P1) is the set of note ids whose
97
+ * BODIES this call injected into the prompt — the caller appends them to its durable surfaced-set and
98
+ * feeds that back as {@link SelectiveRecallOptions.priorSurfacedIds} next time, so a long/resumed/
99
+ * multi-worker session does not re-inject the same notes. THREE shapes (all carry `surfacedIds`):
100
+ *
101
+ * - **block branch** (`{ block: string }`): a selective-recall block was rendered. `surfacedIds` = the
102
+ * validated selection + the 1-hop linked notes (everything whose body was rendered). The caller injects
103
+ * `block` verbatim.
104
+ *
105
+ * - **no-new branch** (`{ block: undefined }`): a SUCCESS, NOT a degrade. Every selectable candidate was
106
+ * already surfaced earlier (filtered out by {@link SelectiveRecallOptions.priorSurfacedIds}), so there is
107
+ * NOTHING NEW to inject. The caller injects NOTHING (no block) — it must NOT fall back to inject-all,
108
+ * because inject-all would re-dump the WHOLE scope including the already-shown notes, defeating the
109
+ * de-dup. `surfacedIds` is `[]` (this call added no new note to the durable set; the prior ids are
110
+ * already in the caller's store). Distinguished from `degrade` precisely so the caller does not
111
+ * re-inject (the bug this branch fixes). `"block" in result` is TRUE here (the key is present, value
112
+ * `undefined`), so the caller's `"degrade" in result` narrow routes this to the non-degrade path.
113
+ *
114
+ * - **degrade branch** (`{ degrade: true }`): a true FALLBACK — the store can't do selective recall
115
+ * (missing manifest/getByIds), the scope is empty, OR the selector failed/timed out. The caller falls
116
+ * back to inject-all (never drops knowledge, council #4), a best-effort FULL DUMP that
117
+ * `composeMemoryBlock` hard-truncates to a head slice (so it does NOT reliably render every body), and
118
+ * the caller already holds the prior surfaced ids. Degrade is therefore not a precise per-id surface that
119
+ * can be de-duped: `surfacedIds` is ALWAYS `[]` and degrade does **not** advance the durable surfaced-set.
120
+ * (Reporting the full header id list here would over-claim the truncated tail as surfaced → permanent
121
+ * silent under-recall on the next turn.)
122
+ */
26
123
  export type SelectiveRecallResult = {
27
124
  block: string;
28
125
  surfacedIds: string[];
@@ -34,18 +131,57 @@ export type SelectiveRecallResult = {
34
131
  surfacedIds: string[];
35
132
  };
36
133
  export declare function resolveLinkedIds(headers: MemoryNoteHeader[], selected: MemoryNoteRecord[], max: number): string[];
134
+ /** Render the manifest as compact lines, double-capped (council #7). One line per note, guaranteed. */
37
135
  export declare function buildManifestText(headers: MemoryNoteHeader[]): string;
136
+ /** Keep only ids present in the manifest (reject hallucinated, council #5), de-duped, capped at `max`. */
38
137
  export declare function validateSelectedIds(headers: MemoryNoteHeader[], ids: string[], max: number): string[];
138
+ /**
139
+ * Render the BODY of a selective-recall block: the optional `recall` manifest index + the selected note
140
+ * bodies (+ 1-hop linked notes), WITHOUT the outer `<user_memory>` wrapper and WITHOUT {@link RECALL_CAVEAT}.
141
+ * The wrapper + caveat are the caller's job — a single-scope caller places ONE caveat
142
+ * inside ONE `<user_memory scope=… mode="selective">`, and the layered renderer places ONE caveat inside ONE
143
+ * `<user_memory mode="selective">` ahead of N `<scope>` subsections (MAJOR fix: no nested fences, no per-scope
144
+ * caveat duplication).
145
+ *
146
+ * `recallable` controls the "Memory index — load in full …" affordance (MAJOR fix): the on-demand recall
147
+ * tool is bound to a SINGLE scope, so the "load in full" instruction is only TRUE for that scope. Pass
148
+ * `false` for non-recallable layers — the selected bodies are already rendered inline, so the index is just a
149
+ * false affordance that wastes a tool call (model searches the wrong scope → "No memory matches").
150
+ *
151
+ * `recallToolName` (#181-F1, additive) is the WIRE name of the host-mounted recall tool the affordance
152
+ * teaches. Core mounts no such tool ("Recall" is a RETIRED name — tool-name-aliases.ts), so a hard-coded
153
+ * name here can only ever be stale; the host that mounted the tool passes the name it mounted it under.
154
+ * Omitted ⇒ a name-free "search the memory-recall tool" wording (honest without inventing a name).
155
+ *
156
+ * Notes are tagged with their natural-language age (CC-parity P0-1, design/65; >1-day-old ones keep the
157
+ * "verify it's still current" hint, council #8). `linked` (design/65 P3) are 1-hop `[[name]]`-followed notes,
158
+ * rendered in their own clearly-labeled subsection AFTER the selected ones — expanded as DATA under the same
159
+ * fence/sanitize/byte-cap discipline (design/65 §8#9: a followed link must not become markup or escalate authority).
160
+ */
39
161
  export declare function composeSelectiveBody(manifestText: string, selected: MemoryNoteRecord[], nowMs: number, linked?: MemoryNoteRecord[], recallable?: boolean, recallToolName?: string): string;
162
+ /** A `(scope, id)` composite key for the multi-scope durable de-dup (design/84 Seam A decision 5). Note ids
163
+ * are only unique WITHIN a scope, so the cross-scope `priorSurfacedKeys`/`surfacedKeys` set MUST be keyed on
164
+ * both. Core owns the FORMAT so a caller can't drift the wire format (decision 7) — the encoding is OPAQUE
165
+ * and length-prefixes the scope so a scope/id containing the separator cannot forge a collision.
166
+ *
167
+ * ONE-WAY by design (codex MINOR (d)): the key is only ever PRODUCED here (`surfacedKeys`) and compared by
168
+ * STRING EQUALITY against the caller's persisted set ({@link LayeredRecallOptions.priorSurfacedKeys}, applied
169
+ * at memory-recall.ts via `priorSurfacedKeys.has(encodeSurfacedKey(h.scope, h.id))`). Nothing ever needs the
170
+ * `(scope, id)` BACK out of a key, so there is intentionally NO `decodeSurfacedKey` — adding a decode would
171
+ * widen the public surface (and invite callers to parse the opaque format) for zero consumer. Treat the key
172
+ * as an opaque token: persist it, feed it back, compare for equality — never split it. */
40
173
  export declare function encodeSurfacedKey(scope: string, id: string): string;
174
+ /** A manifest header tagged with the scope it came from (design/84 Seam A decision 5). */
41
175
  export interface ScopedNoteHeader extends MemoryNoteHeader {
42
176
  scope: string;
43
177
  }
178
+ /** A full record tagged with its scope (for cross-scope getByIds). */
44
179
  export interface ScopedNoteRecord extends MemoryNoteRecord {
45
180
  scope: string;
46
181
  }
47
182
  export interface LayeredRecallOptions {
48
183
  store: MemoryStore;
184
+ /** Ordered scopes (design/84 Seam A): list order = priority; the last is highest. */
49
185
  scopes: ReadonlyArray<string>;
50
186
  objective: string;
51
187
  selector: MemorySelector;
@@ -55,8 +191,13 @@ export interface LayeredRecallOptions {
55
191
  maxLinked?: number;
56
192
  timeoutMs?: number;
57
193
  signal?: AbortSignal;
194
+ /** CC-parity P1, multi-scope: `(scope,id)` composite keys ({@link encodeSurfacedKey}) already surfaced to
195
+ * this logical conversation. Filtered out of the merged manifest BEFORE the selector sees it. */
58
196
  priorSurfacedKeys?: ReadonlySet<string>;
59
197
  }
198
+ /** Result of a multi-scope (layered) selective-recall pass. `surfacedKeys` are `(scope,id)` composite keys
199
+ * ({@link encodeSurfacedKey}) — the caller appends them to its durable set and feeds them back as
200
+ * {@link LayeredRecallOptions.priorSurfacedKeys}. Mirrors {@link SelectiveRecallResult}'s three shapes. */
60
201
  export type LayeredRecallResult = {
61
202
  block: string;
62
203
  surfacedKeys: string[];
@@ -1,3 +1,23 @@
1
+ /**
2
+ * design/81 Slice 5 — the shared distance primitives for the consolidation `searchScored` retrieval, extracted
3
+ * BYTE-IDENTICAL from the original PgMemoryStore implementation so the File (portable/TOC) and Pg (native/TOB)
4
+ * backends rank on ONE source of truth and can't drift. The `{@link import("./runner/memory-consolidation.js")}`
5
+ * band `{0.05, 0.3}` is defined on this cosine-distance scale; the lexical `1 - Jaccard ∈ [0,1] ⊂ [0,2]` is the
6
+ * same-zero-point stand-in used when no embedding vector is present (fail-open per row).
7
+ *
8
+ * The capability LADDER a store reports via {@link import("./memory.js").MemoryStore.vectorMode}:
9
+ * - `lexical` — no embedder: `1 - Jaccard(terms)` everywhere.
10
+ * - `portable` — embedder + IN-PROCESS cosine over stored vectors (File jsonl / Pg jsonb / MySQL JSON — ANY
11
+ * backend that can store a float array; O(n) over the scope, no index).
12
+ * - `native` — embedder + a backend index/operator (pgvector `<=>` / TiDB `VEC_COSINE_DISTANCE`).
13
+ * MySQL is NOT "can't support vectors" — it is `portable`-capable (JSON column + in-process cosine), just not
14
+ * `native`. A deployment injects an embedder (config-driven); the store then reports the achieved rung.
15
+ */
16
+ /** Lower-cased alphanumeric term set of a string (for the lexical stand-in distance). */
1
17
  export declare function termSet(s: string): Set<string>;
18
+ /** Lexical stand-in distance: `1 - Jaccard(terms)` ∈ [0,1] ⊂ [0,2]; `null` = no overlap (not a candidate). */
2
19
  export declare function jaccardDistance(query: Set<string>, text: string): number | null;
20
+ /** Cosine distance ∈ [0,2] (0 = identical), the {@link import("./memory.js").ScoredMemory} contract. Uses
21
+ * `Math.min(a.length,b.length)` — a store MUST only call this on dimension-matched vectors (the row-level
22
+ * dimension guard lives at the caller; a mismatch falls open to {@link jaccardDistance}). */
3
23
  export declare function cosineDistance(a: number[], b: number[]): number;