@sema-agent/server 1.323.0 → 2.0.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 (539) hide show
  1. package/dist/approval-hmac.d.ts +40 -0
  2. package/dist/approval-hmac.js +67 -0
  3. package/dist/approval.d.ts +31 -0
  4. package/dist/approval.js +72 -4
  5. package/dist/audit.d.ts +26 -0
  6. package/dist/audit.js +40 -1
  7. package/dist/auth-bridge.d.ts +10 -0
  8. package/dist/auth-bridge.js +47 -4
  9. package/dist/auth-keys.d.ts +19 -0
  10. package/dist/auth-keys.js +13 -0
  11. package/dist/bake-runner/main.d.ts +5 -0
  12. package/dist/bake-runner/main.js +43 -4
  13. package/dist/bake-runner/protocol.d.ts +57 -0
  14. package/dist/bake-runner/protocol.js +58 -3
  15. package/dist/bake-runner/runner.d.ts +54 -0
  16. package/dist/bake-runner/runner.js +87 -5
  17. package/dist/bench/l8/artifact.d.ts +63 -0
  18. package/dist/bench/l8/artifact.js +61 -2
  19. package/dist/bench/l8/escape.d.ts +36 -0
  20. package/dist/bench/l8/escape.js +25 -0
  21. package/dist/bench/l8/index.d.ts +14 -0
  22. package/dist/bench/l8/index.js +14 -0
  23. package/dist/bench/l8/probes.d.ts +74 -0
  24. package/dist/bench/l8/probes.js +60 -0
  25. package/dist/bench/l8/run-probes.d.ts +43 -0
  26. package/dist/bench/l8/run-probes.js +45 -2
  27. package/dist/bench/s1/arms.d.ts +126 -0
  28. package/dist/bench/s1/arms.js +188 -13
  29. package/dist/bench/s1/live-deps.d.ts +66 -0
  30. package/dist/bench/s1/live-deps.js +249 -11
  31. package/dist/bench/s1/oracle.d.ts +49 -0
  32. package/dist/bench/s1/oracle.js +36 -1
  33. package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
  34. package/dist/bench/s1/repair-oracle-adapter.js +30 -0
  35. package/dist/bench/s1/reviewer.d.ts +38 -0
  36. package/dist/bench/s1/reviewer.js +34 -0
  37. package/dist/bench/s1/row.d.ts +77 -0
  38. package/dist/bench/s1/row.js +62 -0
  39. package/dist/bench/s1/run-firm.d.ts +47 -0
  40. package/dist/bench/s1/run-firm.js +70 -4
  41. package/dist/bench/s1/runner-ctx.d.ts +71 -0
  42. package/dist/bench/s1/runner-ctx.js +36 -0
  43. package/dist/bench/s1/tasks.d.ts +108 -0
  44. package/dist/bench/s1/tasks.js +115 -0
  45. package/dist/boot-reclaim.d.ts +19 -0
  46. package/dist/boot-reclaim.js +20 -0
  47. package/dist/brain.d.ts +25 -0
  48. package/dist/brain.js +61 -1
  49. package/dist/budget.d.ts +66 -0
  50. package/dist/budget.js +128 -4
  51. package/dist/capabilities/builtin-tools.d.ts +3 -0
  52. package/dist/capabilities/builtin-tools.js +3 -0
  53. package/dist/capabilities/center-plugins.d.ts +17 -1
  54. package/dist/capabilities/center-plugins.js +45 -4
  55. package/dist/capabilities/center-prompts.d.ts +46 -0
  56. package/dist/capabilities/center-prompts.js +57 -3
  57. package/dist/capabilities/code-review-council.d.ts +28 -0
  58. package/dist/capabilities/code-review-council.js +40 -7
  59. package/dist/capabilities/collab-wire.d.ts +2 -0
  60. package/dist/capabilities/collab-workflows.d.ts +7 -0
  61. package/dist/capabilities/collab-workflows.js +44 -1
  62. package/dist/capabilities/oa-tools.d.ts +6 -0
  63. package/dist/capabilities/oa-tools.js +10 -0
  64. package/dist/capabilities/prompt.d.ts +14 -0
  65. package/dist/capabilities/prompt.js +14 -0
  66. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  67. package/dist/capabilities/prompts/code-review.js +14 -0
  68. package/dist/capabilities/prompts/identity.d.ts +6 -0
  69. package/dist/capabilities/prompts/identity.js +6 -0
  70. package/dist/capabilities/prompts/team.d.ts +4 -0
  71. package/dist/capabilities/prompts/team.js +4 -0
  72. package/dist/capabilities/repo-tools.d.ts +11 -0
  73. package/dist/capabilities/repo-tools.js +8 -0
  74. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  75. package/dist/capabilities/sandbox-file-send.js +91 -3
  76. package/dist/capabilities/scenarios.d.ts +130 -0
  77. package/dist/capabilities/scenarios.js +180 -7
  78. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  79. package/dist/capabilities/select-environment-tool.js +30 -0
  80. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  81. package/dist/capabilities/send-user-file-tool.js +65 -1
  82. package/dist/capabilities/skills.d.ts +29 -0
  83. package/dist/capabilities/skills.js +13 -2
  84. package/dist/capabilities/team.d.ts +22 -0
  85. package/dist/capabilities/team.js +22 -2
  86. package/dist/capabilities/tool-defer.d.ts +26 -0
  87. package/dist/capabilities/tool-defer.js +3 -0
  88. package/dist/config-center/apply-effective.d.ts +65 -0
  89. package/dist/config-center/apply-effective.js +204 -12
  90. package/dist/config-center/http-client.d.ts +34 -0
  91. package/dist/config-center/http-client.js +68 -0
  92. package/dist/config-center/restart-signal.d.ts +22 -0
  93. package/dist/config-center/restart-signal.js +39 -0
  94. package/dist/config-center/skills-mcp.d.ts +20 -1
  95. package/dist/config-center/skills-mcp.js +42 -7
  96. package/dist/config-center/types.d.ts +92 -1
  97. package/dist/config-lkg.d.ts +12 -0
  98. package/dist/config-lkg.js +41 -0
  99. package/dist/config-provider.d.ts +78 -0
  100. package/dist/config-provider.js +165 -2
  101. package/dist/config-types.d.ts +546 -0
  102. package/dist/config.d.ts +64 -0
  103. package/dist/config.js +455 -60
  104. package/dist/degenerate-instrument.d.ts +38 -0
  105. package/dist/degenerate-instrument.js +55 -3
  106. package/dist/elicitation.d.ts +39 -0
  107. package/dist/elicitation.js +87 -3
  108. package/dist/env-facts.d.ts +61 -0
  109. package/dist/env-facts.js +73 -7
  110. package/dist/fleet/fleet-bus.d.ts +185 -0
  111. package/dist/fleet/fleet-bus.js +333 -27
  112. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  113. package/dist/fleet/subagent-tail-bus.js +33 -2
  114. package/dist/fleet-client.d.ts +38 -0
  115. package/dist/fleet-client.js +44 -9
  116. package/dist/fleet-lease.d.ts +46 -0
  117. package/dist/fleet-lease.js +73 -5
  118. package/dist/hooks/branch-transcript.d.ts +8 -0
  119. package/dist/hooks/branch-transcript.js +33 -0
  120. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  121. package/dist/hooks/cc-stop-prompt.js +43 -1
  122. package/dist/hooks/hook-llm.d.ts +15 -0
  123. package/dist/hooks/hook-llm.js +47 -0
  124. package/dist/hooks/hook-runner.d.ts +89 -0
  125. package/dist/hooks/hook-runner.js +327 -18
  126. package/dist/http/idempotency.d.ts +31 -0
  127. package/dist/http/idempotency.js +34 -0
  128. package/dist/http/principal-gate.d.ts +17 -0
  129. package/dist/http/principal-gate.js +35 -3
  130. package/dist/http/route-ctx.d.ts +36 -0
  131. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  132. package/dist/http/routes/approvals-assistant.js +253 -23
  133. package/dist/http/routes/attachments.js +22 -4
  134. package/dist/http/routes/capabilities.d.ts +7 -0
  135. package/dist/http/routes/capabilities.js +202 -1
  136. package/dist/http/routes/fleet.d.ts +6 -0
  137. package/dist/http/routes/fleet.js +94 -5
  138. package/dist/http/routes/images.d.ts +17 -0
  139. package/dist/http/routes/images.js +222 -14
  140. package/dist/http/routes/leader.d.ts +7 -0
  141. package/dist/http/routes/leader.js +10 -0
  142. package/dist/http/routes/memory-policy.d.ts +6 -0
  143. package/dist/http/routes/memory-policy.js +38 -6
  144. package/dist/http/routes/notify-wake.d.ts +10 -0
  145. package/dist/http/routes/notify-wake.js +19 -3
  146. package/dist/http/routes/observability.d.ts +6 -0
  147. package/dist/http/routes/observability.js +19 -2
  148. package/dist/http/routes/runs.d.ts +15 -0
  149. package/dist/http/routes/runs.js +464 -41
  150. package/dist/http/routes/session-sync.d.ts +15 -0
  151. package/dist/http/routes/session-sync.js +229 -19
  152. package/dist/http/routes/sessions-list.d.ts +6 -0
  153. package/dist/http/routes/sessions-list.js +35 -4
  154. package/dist/http/routes/sessions.d.ts +14 -0
  155. package/dist/http/routes/sessions.js +176 -31
  156. package/dist/http/routes/side-query.d.ts +8 -0
  157. package/dist/http/routes/side-query.js +26 -1
  158. package/dist/http/routes/tasks.d.ts +18 -0
  159. package/dist/http/routes/tasks.js +501 -38
  160. package/dist/http/routes/trace-usage.d.ts +10 -0
  161. package/dist/http/routes/trace-usage.js +66 -14
  162. package/dist/http/routes/workflows.d.ts +12 -0
  163. package/dist/http/routes/workflows.js +180 -19
  164. package/dist/http/run-meta.d.ts +11 -0
  165. package/dist/http/run-meta.js +6 -0
  166. package/dist/http/send.d.ts +19 -0
  167. package/dist/http/send.js +11 -0
  168. package/dist/http/server.d.ts +255 -0
  169. package/dist/http/server.js +921 -75
  170. package/dist/http/sse-log.d.ts +15 -0
  171. package/dist/http/sse-log.js +16 -0
  172. package/dist/http/tar.d.ts +9 -0
  173. package/dist/http/tar.js +21 -5
  174. package/dist/http/wire-gate.d.ts +9 -0
  175. package/dist/http/wire-gate.js +9 -0
  176. package/dist/http/wire-types.d.ts +187 -0
  177. package/dist/http/workspace-content.d.ts +8 -0
  178. package/dist/http/workspace-content.js +10 -0
  179. package/dist/images/bake-validate.d.ts +63 -0
  180. package/dist/images/bake-validate.js +71 -1
  181. package/dist/images/manifest.d.ts +19 -0
  182. package/dist/images/manifest.js +6 -1
  183. package/dist/index.d.ts +1 -5
  184. package/dist/index.js +10 -5
  185. package/dist/key-resolver.d.ts +23 -0
  186. package/dist/key-resolver.js +27 -2
  187. package/dist/leader/diffout.d.ts +23 -0
  188. package/dist/leader/diffout.js +8 -1
  189. package/dist/leader/diffup.d.ts +32 -0
  190. package/dist/leader/diffup.js +43 -0
  191. package/dist/leader/endpoint.d.ts +20 -0
  192. package/dist/leader/endpoint.js +25 -2
  193. package/dist/leader/fanout.d.ts +60 -0
  194. package/dist/leader/fanout.js +29 -3
  195. package/dist/leader/grader-env-factory.d.ts +74 -0
  196. package/dist/leader/grader-env-factory.js +62 -3
  197. package/dist/leader/leader.d.ts +97 -0
  198. package/dist/leader/leader.js +151 -4
  199. package/dist/leader/merge.d.ts +94 -0
  200. package/dist/leader/merge.js +112 -9
  201. package/dist/leader/planner.d.ts +52 -0
  202. package/dist/leader/planner.js +47 -3
  203. package/dist/leader/repair-oracle.d.ts +61 -0
  204. package/dist/leader/repair-oracle.js +59 -1
  205. package/dist/leader/repair-wire.d.ts +78 -0
  206. package/dist/leader/repair-wire.js +79 -2
  207. package/dist/leader/wire.d.ts +79 -0
  208. package/dist/leader/wire.js +255 -8
  209. package/dist/lsp/e2b-bridge.d.ts +16 -0
  210. package/dist/lsp/e2b-bridge.js +32 -4
  211. package/dist/lsp/e2b-manager.d.ts +10 -0
  212. package/dist/lsp/e2b-manager.js +18 -2
  213. package/dist/lsp/lsp-frames.d.ts +12 -0
  214. package/dist/lsp/lsp-frames.js +12 -0
  215. package/dist/lsp/manager.d.ts +12 -0
  216. package/dist/lsp/manager.js +35 -2
  217. package/dist/lsp/types.d.ts +10 -0
  218. package/dist/lsp/ws-transport.d.ts +12 -0
  219. package/dist/lsp/ws-transport.js +53 -5
  220. package/dist/lsp-evict.d.ts +14 -0
  221. package/dist/lsp-evict.js +15 -1
  222. package/dist/main.js +2132 -96
  223. package/dist/memory-export.d.ts +1 -0
  224. package/dist/memory-export.js +4 -0
  225. package/dist/memory-scope.d.ts +49 -0
  226. package/dist/memory-scope.js +87 -4
  227. package/dist/memory-sync-client.d.ts +24 -0
  228. package/dist/memory-sync-client.js +41 -2
  229. package/dist/memory-sync.d.ts +23 -0
  230. package/dist/memory-sync.js +70 -1
  231. package/dist/model-select.d.ts +39 -0
  232. package/dist/model-select.js +42 -1
  233. package/dist/observability/cost-quota.d.ts +20 -0
  234. package/dist/observability/cost-quota.js +4 -0
  235. package/dist/observability/cost-taxonomy.d.ts +45 -0
  236. package/dist/observability/cost-taxonomy.js +34 -0
  237. package/dist/observability/logger.d.ts +1 -0
  238. package/dist/observability/logger.js +6 -0
  239. package/dist/observability/metrics.d.ts +13 -0
  240. package/dist/observability/metrics.js +63 -0
  241. package/dist/observability/otel-exporter.d.ts +9 -0
  242. package/dist/observability/otel-exporter.js +11 -3
  243. package/dist/observability/principal-context.d.ts +9 -0
  244. package/dist/observability/principal-context.js +9 -0
  245. package/dist/observability/prompt-manifest.d.ts +37 -0
  246. package/dist/observability/prompt-manifest.js +35 -1
  247. package/dist/observability/rate-limit.d.ts +10 -0
  248. package/dist/observability/rate-limit.js +1 -0
  249. package/dist/observability/tool-trace.d.ts +24 -0
  250. package/dist/observability/tool-trace.js +41 -1
  251. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  252. package/dist/orchestration/hardened-vm-runner.js +119 -4
  253. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  254. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  255. package/dist/orchestration/hardened-vm-worker.js +27 -0
  256. package/dist/orchestration/subagent-steer.d.ts +44 -0
  257. package/dist/orchestration/subagent-steer.js +45 -1
  258. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  259. package/dist/orchestration/workflow-agent-steer.js +80 -1
  260. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  261. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  262. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  263. package/dist/orchestration/workflow-notify-journal.js +187 -13
  264. package/dist/parked-decide.d.ts +61 -0
  265. package/dist/parked-decide.js +58 -1
  266. package/dist/per-task-image.d.ts +54 -0
  267. package/dist/per-task-image.js +41 -0
  268. package/dist/plan-cache-probe.d.ts +35 -0
  269. package/dist/plan-cache-probe.js +18 -3
  270. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  271. package/dist/plugins/approval-exemption-store.js +28 -2
  272. package/dist/plugins/approval-store-sql.d.ts +64 -0
  273. package/dist/plugins/approval-store-sql.js +32 -0
  274. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  275. package/dist/plugins/background-agent-store-sql.js +91 -4
  276. package/dist/plugins/background-shell-support.d.ts +98 -0
  277. package/dist/plugins/background-shell-support.js +117 -13
  278. package/dist/plugins/blob-backend.d.ts +104 -0
  279. package/dist/plugins/blob-backend.js +163 -6
  280. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  281. package/dist/plugins/breaker-state-sql.js +46 -8
  282. package/dist/plugins/caching-session-store.d.ts +42 -0
  283. package/dist/plugins/caching-session-store.js +63 -3
  284. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  285. package/dist/plugins/checkpoint-store-sql.js +239 -11
  286. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  287. package/dist/plugins/file-outcome-sink.js +9 -0
  288. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  289. package/dist/plugins/file-resume-anchor-store.js +43 -4
  290. package/dist/plugins/file-run-store.d.ts +90 -0
  291. package/dist/plugins/file-run-store.js +145 -13
  292. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  293. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  294. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  295. package/dist/plugins/file-workflow-journal-store.js +10 -0
  296. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  297. package/dist/plugins/fork-routing-session-store.js +51 -3
  298. package/dist/plugins/host-platform.d.ts +69 -0
  299. package/dist/plugins/host-platform.js +81 -2
  300. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  301. package/dist/plugins/image-bake-store-sql.js +241 -7
  302. package/dist/plugins/image-index-sql.d.ts +46 -0
  303. package/dist/plugins/image-index-sql.js +113 -4
  304. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  305. package/dist/plugins/k8s-bg-scripts.js +88 -4
  306. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  307. package/dist/plugins/k8s-exec-protocol.js +41 -0
  308. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  309. package/dist/plugins/local-checkpoint-store.js +86 -7
  310. package/dist/plugins/local-session-store.d.ts +157 -0
  311. package/dist/plugins/local-session-store.js +289 -34
  312. package/dist/plugins/local-task-attachment-store.js +14 -2
  313. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  314. package/dist/plugins/mailbox-store-sql.js +39 -6
  315. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  316. package/dist/plugins/memory-engine-pg.js +122 -4
  317. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  318. package/dist/plugins/memory-engine-tidb.js +115 -5
  319. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  320. package/dist/plugins/memory-engine-vector-util.js +5 -0
  321. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  322. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  323. package/dist/plugins/memory-run-store.d.ts +63 -0
  324. package/dist/plugins/memory-run-store.js +73 -8
  325. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  326. package/dist/plugins/memory-session-policy-store.js +17 -0
  327. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  328. package/dist/plugins/memory-sync-store-pg.js +45 -2
  329. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  330. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  331. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  332. package/dist/plugins/outcome-ledger-sql.js +97 -3
  333. package/dist/plugins/pg-approval-store.d.ts +7 -0
  334. package/dist/plugins/pg-approval-store.js +7 -0
  335. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  336. package/dist/plugins/pg-breaker-state.js +6 -0
  337. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  338. package/dist/plugins/pg-checkpoint-store.js +8 -0
  339. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  340. package/dist/plugins/pg-cost-quota.js +6 -0
  341. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  342. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  343. package/dist/plugins/pg-image-bake.d.ts +9 -0
  344. package/dist/plugins/pg-image-bake.js +9 -0
  345. package/dist/plugins/pg-image-index.d.ts +9 -0
  346. package/dist/plugins/pg-image-index.js +9 -0
  347. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  348. package/dist/plugins/pg-outcome-ledger.js +9 -0
  349. package/dist/plugins/pg-pool.d.ts +50 -0
  350. package/dist/plugins/pg-pool.js +78 -0
  351. package/dist/plugins/pg-query.d.ts +11 -0
  352. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  353. package/dist/plugins/pg-rate-limiter.js +12 -2
  354. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  355. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  356. package/dist/plugins/pg-run-store.d.ts +7 -0
  357. package/dist/plugins/pg-run-store.js +7 -0
  358. package/dist/plugins/pg-safe-json.d.ts +13 -0
  359. package/dist/plugins/pg-safe-json.js +40 -4
  360. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  361. package/dist/plugins/pg-session-policy-store.js +5 -0
  362. package/dist/plugins/pg-session-storage.d.ts +72 -0
  363. package/dist/plugins/pg-session-storage.js +152 -20
  364. package/dist/plugins/pg-session-store.d.ts +10 -0
  365. package/dist/plugins/pg-session-store.js +10 -0
  366. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  367. package/dist/plugins/pg-tool-result-store.js +7 -0
  368. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  369. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  370. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  371. package/dist/plugins/pg-workflow-run-store.js +7 -0
  372. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  373. package/dist/plugins/posix-shell-fs.js +31 -1
  374. package/dist/plugins/remote-env-adb.d.ts +25 -0
  375. package/dist/plugins/remote-env-adb.js +95 -12
  376. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  377. package/dist/plugins/remote-env-e2b.js +371 -40
  378. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  379. package/dist/plugins/remote-env-file-error.js +37 -0
  380. package/dist/plugins/remote-env-host.d.ts +151 -0
  381. package/dist/plugins/remote-env-host.js +468 -70
  382. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  383. package/dist/plugins/remote-env-k8s.js +318 -32
  384. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  385. package/dist/plugins/remote-env-local-docker.js +149 -24
  386. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  387. package/dist/plugins/remote-env-ssh.js +117 -20
  388. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  389. package/dist/plugins/remote-scratchpad.js +32 -2
  390. package/dist/plugins/remote-shell.d.ts +22 -0
  391. package/dist/plugins/remote-shell.js +27 -1
  392. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  393. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  394. package/dist/plugins/roster-store-sql.d.ts +27 -0
  395. package/dist/plugins/roster-store-sql.js +54 -0
  396. package/dist/plugins/run-store-sql.d.ts +194 -0
  397. package/dist/plugins/run-store-sql.js +210 -9
  398. package/dist/plugins/s3-presign.d.ts +20 -0
  399. package/dist/plugins/s3-presign.js +49 -2
  400. package/dist/plugins/scheduler-support.d.ts +12 -0
  401. package/dist/plugins/scheduler-support.js +75 -3
  402. package/dist/plugins/send-file-ledger.d.ts +15 -0
  403. package/dist/plugins/send-file-ledger.js +53 -4
  404. package/dist/plugins/send-user-file.d.ts +77 -0
  405. package/dist/plugins/send-user-file.js +92 -4
  406. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  407. package/dist/plugins/session-policy-store-sql.js +75 -3
  408. package/dist/plugins/session-store.d.ts +45 -0
  409. package/dist/plugins/session-store.js +51 -0
  410. package/dist/plugins/sql-driver.d.ts +77 -0
  411. package/dist/plugins/sql-driver.js +4 -0
  412. package/dist/plugins/sql-escape.d.ts +8 -0
  413. package/dist/plugins/sql-escape.js +8 -0
  414. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  415. package/dist/plugins/sql-row-helpers.js +25 -0
  416. package/dist/plugins/store-backend.d.ts +103 -0
  417. package/dist/plugins/store-backend.js +120 -27
  418. package/dist/plugins/store-contracts.d.ts +62 -0
  419. package/dist/plugins/store-contracts.js +3 -0
  420. package/dist/plugins/task-attachment-store.d.ts +60 -0
  421. package/dist/plugins/task-attachment-store.js +49 -3
  422. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  423. package/dist/plugins/task-list-store-sql.js +21 -0
  424. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  425. package/dist/plugins/tidb-approval-store.js +6 -0
  426. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  427. package/dist/plugins/tidb-breaker-state.js +5 -0
  428. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  429. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  430. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  431. package/dist/plugins/tidb-cost-quota.js +1 -0
  432. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  433. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  434. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  435. package/dist/plugins/tidb-image-bake.js +8 -0
  436. package/dist/plugins/tidb-image-index.d.ts +8 -0
  437. package/dist/plugins/tidb-image-index.js +8 -0
  438. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  439. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  440. package/dist/plugins/tidb-pool.d.ts +56 -0
  441. package/dist/plugins/tidb-pool.js +181 -1
  442. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  443. package/dist/plugins/tidb-rate-limiter.js +5 -2
  444. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  445. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  446. package/dist/plugins/tidb-run-store.d.ts +7 -0
  447. package/dist/plugins/tidb-run-store.js +7 -0
  448. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  449. package/dist/plugins/tidb-session-policy-store.js +5 -0
  450. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  451. package/dist/plugins/tidb-session-storage.js +62 -3
  452. package/dist/plugins/tidb-session-store.d.ts +142 -0
  453. package/dist/plugins/tidb-session-store.js +264 -16
  454. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  455. package/dist/plugins/tidb-tool-result-store.js +7 -0
  456. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  457. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  458. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  459. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  460. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  461. package/dist/plugins/tool-result-store-sql.js +38 -2
  462. package/dist/plugins/web-search.d.ts +35 -0
  463. package/dist/plugins/web-search.js +45 -9
  464. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  465. package/dist/plugins/workflow-journal-limits.js +10 -0
  466. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  467. package/dist/plugins/workflow-journal-store-sql.js +58 -2
  468. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  469. package/dist/plugins/workflow-run-store-sql.js +84 -6
  470. package/dist/plugins/worktree-isolation.d.ts +45 -0
  471. package/dist/plugins/worktree-isolation.js +105 -6
  472. package/dist/plugins/write-behind-counter.d.ts +56 -1
  473. package/dist/plugins/write-behind-counter.js +53 -14
  474. package/dist/principal-jwt.d.ts +24 -0
  475. package/dist/principal-jwt.js +60 -5
  476. package/dist/project-memory.d.ts +22 -0
  477. package/dist/project-memory.js +144 -15
  478. package/dist/prompts-domain-validate.d.ts +28 -0
  479. package/dist/prompts-domain-validate.js +42 -1
  480. package/dist/question.d.ts +33 -0
  481. package/dist/question.js +69 -2
  482. package/dist/resource-suspend.d.ts +21 -0
  483. package/dist/resource-suspend.js +16 -0
  484. package/dist/router/route-orchestration.d.ts +78 -0
  485. package/dist/router/route-orchestration.js +77 -0
  486. package/dist/run-local.d.ts +32 -0
  487. package/dist/run-local.js +172 -8
  488. package/dist/runs.d.ts +189 -4
  489. package/dist/runs.js +465 -24
  490. package/dist/runtime-caps-resolver.d.ts +106 -0
  491. package/dist/runtime-caps-resolver.js +89 -4
  492. package/dist/runtime-governance.d.ts +84 -0
  493. package/dist/runtime-governance.js +127 -1
  494. package/dist/sandbox-pkg-source.d.ts +23 -0
  495. package/dist/sandbox-pkg-source.js +37 -0
  496. package/dist/sealed-key.d.ts +54 -0
  497. package/dist/sealed-key.js +68 -3
  498. package/dist/security.d.ts +108 -0
  499. package/dist/security.js +145 -6
  500. package/dist/sema-registry.d.ts +21 -0
  501. package/dist/sema-registry.js +21 -0
  502. package/dist/session-leaf-bus.d.ts +31 -0
  503. package/dist/session-leaf-bus.js +32 -0
  504. package/dist/session-sync-content.d.ts +46 -0
  505. package/dist/session-sync-content.js +47 -1
  506. package/dist/session-sync-kernel.d.ts +89 -0
  507. package/dist/session-sync-kernel.js +48 -3
  508. package/dist/session-sync.d.ts +125 -0
  509. package/dist/session-sync.js +181 -8
  510. package/dist/session-titler.d.ts +26 -0
  511. package/dist/session-titler.js +41 -7
  512. package/dist/session-watch.d.ts +53 -1
  513. package/dist/session-watch.js +73 -9
  514. package/dist/sighup-idle.d.ts +30 -0
  515. package/dist/sighup-idle.js +12 -1
  516. package/dist/spec-fields.d.ts +91 -3
  517. package/dist/spec-fields.js +116 -4
  518. package/dist/task-cwd.d.ts +50 -0
  519. package/dist/task-cwd.js +68 -1
  520. package/dist/task-mcp.d.ts +47 -0
  521. package/dist/task-mcp.js +29 -0
  522. package/dist/task-settings.d.ts +175 -0
  523. package/dist/task-settings.js +226 -11
  524. package/dist/task-workflow.d.ts +67 -0
  525. package/dist/task-workflow.js +75 -8
  526. package/dist/tool-approval.d.ts +91 -0
  527. package/dist/tool-approval.js +215 -0
  528. package/dist/trace/artifacts.d.ts +9 -0
  529. package/dist/trace/artifacts.js +30 -5
  530. package/dist/trace/core-keyset-guard.d.ts +18 -0
  531. package/dist/trace/ledger-sink.d.ts +43 -0
  532. package/dist/trace/ledger-sink.js +64 -5
  533. package/dist/trace/project.d.ts +133 -0
  534. package/dist/trace/project.js +189 -2
  535. package/dist/trace/redact.d.ts +19 -0
  536. package/dist/trace/redact.js +66 -9
  537. package/dist/usage-analytics.d.ts +26 -0
  538. package/dist/usage-analytics.js +26 -3
  539. package/package.json +1 -1
@@ -1,9 +1,37 @@
1
+ // TiDB (MySQL wire) dialect twin of `memory-engine-pg.ts` — the THIRD MemoryBackend implementation
2
+ // (边界重切:core 养 File backend+seam+memoryBackendContract,SQL 方言归 service;先例=
3
+ // TiDBRunStore/PgRunStore 方言孪生对)。Same tables, same contract, mysql2 posture throughout.
4
+ //
5
+ // 方言改造点(core 指引,与 Pg 版逐条对照):
6
+ // - `$n` 占位符 → `?`;`jsonb` → `JSON`(mysql2 对 JSON 列返回已解析对象,fromJson 防御 string 形);
7
+ // - `UPDATE/DELETE … WHERE rev = ? RETURNING` → MySQL 无 RETURNING:条件写后看 affectedRows;零行=
8
+ // conflict,且 currentRev 必须 SELECT 现值(freshRev 语义——绝不把 pre-race SELECT 的旧值当 currentRev)。
9
+ // ⚠️ affectedRows 语义(归因修正:mysql2 默认 flags 含 FOUND_ROWS ⇒ affectedRows=
10
+ // MATCHED 行数;此前注释写反)。真库契约在真默认语义下全绿;下述 fresh-rev 比对分支让两种语义都正确:matched-but-
11
+ // identical 也是 0——零行后用 freshRev 消歧(现 rev==新 rev ⇒ 内容已是目标态=幂等成功,非 conflict);
12
+ // - add 路径 Pg 用 `INSERT … ON CONFLICT (id) DO UPDATE`(冲突靶=仅 PK)。MySQL 的 ON DUPLICATE KEY
13
+ // UPDATE 会被 **任意** 唯一键触发——(scope,slug) 撞键时它会把竞争对手的行改写成本 entry 的 id(数据毁),
14
+ // 不能用;拆成「不存在→INSERT / 已存在→UPDATE by id」,两条腿的 ER_DUP_ENTRY 都按键名分诊(PRIMARY=
15
+ // 并发同 id add → 转 UPDATE 腿;uk_scope_slug=并发 slug 竞争 → 下一个 -n 后缀重试);
16
+ // - unique violation 判定:ER_DUP_ENTRY(errno 1062),不是 Pg 的 23505;
17
+ // - pg-mem 伪影 workaround(索引列 ANY 零行/重复占位符重复行)不抄——MySQL 本就走 IN-list,dedupe 保留
18
+ // 是因为它同时是诚实语义(重复 key 问的是同一个 entry,契约锁死 once-per-entry);
19
+ // - (scope, slug) UNIQUE 约束照立(竞态正确性:两实例各自探得 free 同时 INSERT,DB 约束是唯一仲裁);
20
+ // - 表名与 Pg 版同名(两方言不会同库;与退役 MemoryStore 的 `agent_memory*` 面刻意不相交);
21
+ // - v1 lexical only:embedder/vector 面无 TiDB 对应(Pg 的 pgvector rung 是 Pg 专属);构造签名保留
22
+ // opts 但传入 embedder=fail-loud 拒绝,search 恒走 jaccard 词面,haystack 与 Pg/File 逐字节同构
23
+ // (`${name ?? slug} ${description} ${body}`——memoryBackendContract 的 search 等价断言依赖)。
1
24
  import { jaccardDistance, termSet } from "./memory-engine-vector-util.js";
2
25
  import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
26
+ /** Table names (single source) — SAME names as PG_MEMORY_ENGINE_TABLES (the two dialects never share
27
+ * one database), deliberately DISJOINT from the legacy `agent_memory*` MemoryStore plane. */
3
28
  export const TIDB_MEMORY_ENGINE_TABLES = {
4
29
  entries: "agent_memory_engine_entries",
5
30
  cursors: "agent_memory_engine_cursors",
6
31
  };
32
+ /** Idempotent DDL for the entry plane (TiDB dialect). Call once at startup.
33
+ * Key lengths: utf8mb4 = 4 bytes/char and the default index-key cap is 3072 bytes, so the
34
+ * (scope, slug) unique key budget is scope 190 + slug 512 = 702 chars ⇒ 2808 bytes ≤ 3072. */
7
35
  export async function ensureTiDBMemoryEngineSchema(pool) {
8
36
  await pool.query(`CREATE TABLE IF NOT EXISTS ${TIDB_MEMORY_ENGINE_TABLES.entries} (
9
37
  id VARCHAR(64) NOT NULL,
@@ -19,6 +47,9 @@ export async function ensureTiDBMemoryEngineSchema(pool) {
19
47
  KEY idx_scope (scope),
20
48
  UNIQUE KEY uk_scope_slug (scope, slug)
21
49
  )`);
50
+ // The (scope, slug) UNIQUE key above is CORRECTNESS, not perf (Pg 版同注):two
51
+ // instances racing an add of one scope+slug (different ids) can both probe "free" and both insert;
52
+ // the DB constraint is the only true arbiter and the add path retries the next suffix on violation.
22
53
  await pool.query(`CREATE TABLE IF NOT EXISTS ${TIDB_MEMORY_ENGINE_TABLES.cursors} (
23
54
  scope VARCHAR(190) NOT NULL,
24
55
  \`cursor\` TEXT NOT NULL,
@@ -30,9 +61,12 @@ function isDupEntry(err) {
30
61
  return false;
31
62
  return err.code === "ER_DUP_ENTRY" || err.errno === 1062;
32
63
  }
64
+ /** ER_DUP_ENTRY messages name the violated key (`… for key 'tbl.PRIMARY'` / `… for key 'tbl.uk_scope_slug'`)
65
+ * — the add path uses this to tell "id already exists (→ overwrite leg)" from "slug race (→ -n retry)". */
33
66
  function isPrimaryKeyDup(err) {
34
67
  return isDupEntry(err) && /for key '[^']*PRIMARY'/i.test(String(err.message ?? ""));
35
68
  }
69
+ /** `?, ?, …` for a dynamic IN list (MySQL has no ANY(param); plain IN-list on both engines). */
36
70
  function inPlaceholders(count) {
37
71
  return Array.from({ length: count }, () => "?").join(", ");
38
72
  }
@@ -43,7 +77,9 @@ export class TiDBMemoryEngineBackend {
43
77
  pool;
44
78
  clock;
45
79
  history;
80
+ /** Cumulative lost-row count — audit-line breakage must itself be auditable. */
46
81
  historyRowsLost = 0;
82
+ /** design/81 rung indicator — TiDB v1 sits on the lexical floor (Pg twin parity surface). */
47
83
  get vectorMode() {
48
84
  return "lexical";
49
85
  }
@@ -63,6 +99,7 @@ export class TiDBMemoryEngineBackend {
63
99
  const [res] = await this.pool.query(sql, params);
64
100
  return res;
65
101
  }
102
+ /** The search haystack — BYTE-EQUAL to the File/Pg backends' lexical haystack (contract equivalence). */
66
103
  haystackOf(slug, fm, body) {
67
104
  return `${fm.name ?? slug} ${fm.description ?? ""} ${body}`;
68
105
  }
@@ -91,6 +128,8 @@ export class TiDBMemoryEngineBackend {
91
128
  };
92
129
  }
93
130
  async listHeaders(scopes) {
131
+ // Dedupe (all three read paths): honest semantic — a caller repeating a key asks about ONE entry
132
+ // (contract-locked once-per-entry; real IN-lists don't duplicate anyway).
94
133
  const uniq = [...new Set(scopes)];
95
134
  if (uniq.length === 0)
96
135
  return [];
@@ -102,13 +141,15 @@ export class TiDBMemoryEngineBackend {
102
141
  if (uniq.length === 0)
103
142
  return [];
104
143
  const rows = await this.selectRows(`SELECT id, scope, slug, frontmatter, body, rev, mtime_ms, size_bytes FROM ${TIDB_MEMORY_ENGINE_TABLES.entries} WHERE id IN (${inPlaceholders(uniq.length)}) ORDER BY id`, uniq);
105
- return rows.map((r) => this.entryFromRow(r));
144
+ return rows.map((r) => this.entryFromRow(r)); // unknown ids: silently absent
106
145
  }
107
146
  async search(query, scopes, opts) {
147
+ // Limit normalization mirrors the Pg twin verbatim (floor semantics; NaN rejected; Infinity = no cap).
108
148
  const rawLimit = opts?.limit ?? 20;
109
149
  const limit = Number.isFinite(rawLimit) ? Math.floor(rawLimit) : rawLimit;
110
150
  if (scopes.length === 0 || !(limit > 0))
111
151
  return [];
152
+ // EMPTY-QUERY contract is backend-uniform: no terms → [] (File/Pg parity).
112
153
  const q = termSet(query);
113
154
  if (q.size === 0)
114
155
  return [];
@@ -120,16 +161,22 @@ export class TiDBMemoryEngineBackend {
120
161
  const fm = fromJson(r.frontmatter);
121
162
  const d = jaccardDistance(q, this.haystackOf(r.slug, fm, r.body));
122
163
  if (d === null)
123
- continue;
164
+ continue; // zero-overlap: not a candidate
124
165
  scored.push({ ...this.headerFromRow(r), score: d });
125
166
  }
167
+ // Deterministic id tie-break (opus 审 C4,Pg 版同注): tied scores must not order by row-arrival
168
+ // accident — the cross-backend equivalence assertion compares ordered projections.
126
169
  scored.sort((a, b) => a.score - b.score || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
127
170
  return scored.slice(0, limit);
128
171
  }
129
172
  async applyPatches(patches) {
130
173
  const report = { applied: [], conflicts: [] };
174
+ // At most ONE non-delete op per id per batch (file-backend parity — a COPY keeping its frontmatter
175
+ // id would leave the projection↔applied binding ambiguous; refuse the later one).
131
176
  const nonDeleteIds = new Set();
177
+ // In-batch (scope, slug) claims so two adds of one slug in one batch suffix deterministically.
132
178
  const plannedSlugs = new Set();
179
+ // 142-S5.1: one history row per APPLIED patch, flushed as one batch below (append-only audit face).
133
180
  const historyRows = [];
134
181
  for (const patch of patches) {
135
182
  try {
@@ -146,11 +193,17 @@ export class TiDBMemoryEngineBackend {
146
193
  report.conflicts.push({ op: patch.op, id: patch.id, reason: `io error: ${err instanceof Error ? err.message : String(err)}` });
147
194
  }
148
195
  }
196
+ // BEST-EFFORT history append (see TiDBMemoryEngineBackendOptions.history for the honest trade-off:
197
+ // the entry writes above are already committed; a failed audit append must not fail the report —
198
+ // swallow + warn, never throw. appendHistory is (id,rev)-idempotent, so a caller retry is safe.
149
199
  if (this.history && historyRows.length > 0) {
150
200
  try {
151
201
  await this.history.appendHistory(historyRows);
152
202
  }
153
203
  catch (err) {
204
+ // Every warn carries the CUMULATIVE lost count — a persistent silent failure
205
+ // (history table dropped, grant flipped) shows as a growing number, not a one-off line.
206
+ // The metrics counter leg lives in the main.ts sink wrapper (memory_history_append_failed_total).
154
207
  this.historyRowsLost += historyRows.length;
155
208
  console.warn(`TiDBMemoryEngineBackend: best-effort history append failed (${historyRows.length} row(s) lost, ${this.historyRowsLost} cumulative — audit face only, entries committed): ${err instanceof Error ? err.message : String(err)}`);
156
209
  }
@@ -159,6 +212,8 @@ export class TiDBMemoryEngineBackend {
159
212
  }
160
213
  async applyOne(patch, report, plannedSlugs, historyRows) {
161
214
  const T = TIDB_MEMORY_ENGINE_TABLES.entries;
215
+ // A patch whose entry carries a DIFFERENT id than the patch addresses is malformed — refused up
216
+ // front, all backends alike (Pg 版同注).
162
217
  if (patch.op !== "delete" && patch.entry !== undefined && patch.entry.id !== patch.id) {
163
218
  report.conflicts.push({ op: patch.op, id: patch.id, reason: `patch id ${JSON.stringify(patch.id)} != entry id ${JSON.stringify(patch.entry.id)} (malformed patch refused)` });
164
219
  return;
@@ -169,9 +224,15 @@ export class TiDBMemoryEngineBackend {
169
224
  report.conflicts.push({ op: "add", id: patch.id, reason: "add patch without an entry" });
170
225
  return;
171
226
  }
227
+ // Cross-scope add refusal (opus 审 C3,Pg 版同注): an add whose id already lives in a DIFFERENT
228
+ // scope must not silently MOVE the row; same-scope re-add stays the idempotent overwrite.
229
+ // One probe serves BOTH the E-02 guard and the cross-scope refusal (File/Pg parity).
172
230
  const prior = await this.selectRows(`SELECT scope, slug, rev FROM ${T} WHERE id = ?`, [entry.id]);
173
231
  const priorRow = prior.length > 0 ? prior[0] : undefined;
174
232
  let existsById = priorRow !== undefined;
233
+ // E-02 add-if-absent guard (core 1.275.1/1.276.0 contract clause; caught live by the contract
234
+ // suite on real TiDB 2026-07-13): same rev AND same (scope, slug) projection = idempotent
235
+ // fall-through; different rev OR projection = REPORTED add_guard_absent_conflict + currentRev.
175
236
  if (patch.guard === "absent" && priorRow) {
176
237
  const currentRev = String(priorRow.rev);
177
238
  if (currentRev !== computeEntryRev(entry)) {
@@ -182,6 +243,7 @@ export class TiDBMemoryEngineBackend {
182
243
  report.conflicts.push({ op: "add", id: entry.id, reason: `add_guard_absent_conflict (id already exists at the same rev but a different projection ${JSON.stringify(`${String(priorRow.scope)}/${String(priorRow.slug)}`)}; add-if-absent refuses to duplicate)`, currentRev });
183
244
  return;
184
245
  }
246
+ // same rev AND same projection ⇒ idempotent; fall through to the normal add (no-op re-write).
185
247
  }
186
248
  if (priorRow) {
187
249
  const held = String(priorRow.scope);
@@ -190,6 +252,9 @@ export class TiDBMemoryEngineBackend {
190
252
  return;
191
253
  }
192
254
  }
255
+ // Slug collision with a DIFFERENT entry → deterministic `-n` suffix (file-backend parity); the
256
+ // probe is only an optimization — the write INSIDE the loop is arbitrated by uk_scope_slug, and
257
+ // a concurrent loser retries the next suffix (Pg 版同注).
193
258
  let slug = entry.slug;
194
259
  for (let n = 2;; n++) {
195
260
  const key = `${entry.scope}|${slug}`;
@@ -202,12 +267,18 @@ export class TiDBMemoryEngineBackend {
202
267
  const sizeBytes = Buffer.byteLength(serializeEntryFile(stored), "utf8");
203
268
  try {
204
269
  if (existsById) {
270
+ // Idempotent overwrite leg (Pg 的 ON CONFLICT(id) DO UPDATE 对应面;见文件头:MySQL 的
271
+ // ON DUPLICATE KEY UPDATE 会被 (scope,slug) 键劫持改写他人行,禁用)。
205
272
  const res = await this.write(`UPDATE ${T} SET scope = ?, slug = ?, frontmatter = ?, body = ?, rev = ?, mtime_ms = ?, size_bytes = ?, embedding = NULL WHERE id = ?`, [stored.scope, stored.slug, JSON.stringify(stored.frontmatter), stored.body, rev, this.clock(), sizeBytes, stored.id]);
206
273
  if (res.affectedRows === 0) {
274
+ // affectedRows: under mysql2 default (FOUND_ROWS ⇒ matched count) 0 = row gone;
275
+ // under changed-only semantics 0 could also mean already-at-target — the fresh-rev branch below covers BOTH: 0 = either the row already
276
+ // holds exactly this content (idempotent no-op = success) or it vanished under a
277
+ // concurrent delete (→ fall back to the INSERT leg, same slug).
207
278
  const still = await this.selectRows(`SELECT id FROM ${T} WHERE id = ?`, [stored.id]);
208
279
  if (still.length === 0) {
209
280
  existsById = false;
210
- continue;
281
+ continue; // row deleted concurrently — retry this slug via the INSERT leg
211
282
  }
212
283
  }
213
284
  }
@@ -218,16 +289,18 @@ export class TiDBMemoryEngineBackend {
218
289
  catch (err) {
219
290
  if (isDupEntry(err)) {
220
291
  if (isPrimaryKeyDup(err)) {
221
- existsById = true;
292
+ existsById = true; // concurrent same-id add won the PK — retry this slug via the overwrite leg
222
293
  continue;
223
294
  }
224
- slug = `${entry.slug}-${n}`;
295
+ slug = `${entry.slug}-${n}`; // concurrent winner took this (scope,slug) — next suffix
225
296
  continue;
226
297
  }
227
298
  throw err;
228
299
  }
229
300
  plannedSlugs.add(key);
230
301
  report.applied.push({ op: "add", id: stored.id, slug: stored.slug });
302
+ // History: chain head — prevRev absent by contract (a same-scope idempotent re-add of
303
+ // identical content dedupes on the (id, rev) PK; changed content starts a fresh head).
231
304
  if (this.history)
232
305
  historyRows.push({ id: stored.id, rev, op: "add", scope: stored.scope, snapshot: { ...stored, rev }, writtenAtMs: this.clock() });
233
306
  return;
@@ -236,6 +309,8 @@ export class TiDBMemoryEngineBackend {
236
309
  slug = `${entry.slug}-${n}`;
237
310
  }
238
311
  }
312
+ // update/delete address an EXISTING entry by immutable id. (scope in the projection = the
313
+ // history row's scope for delete — a tombstone can't be joined back to the deleted row.)
239
314
  const cur = await this.selectRows(`SELECT slug, rev, scope, frontmatter FROM ${T} WHERE id = ?`, [patch.id]);
240
315
  if (cur.length === 0) {
241
316
  report.conflicts.push({ op: patch.op, id: patch.id, reason: "unknown id (entry not found in backend)" });
@@ -244,6 +319,10 @@ export class TiDBMemoryEngineBackend {
244
319
  const currentRev = String(cur[0].rev);
245
320
  const currentSlug = String(cur[0].slug);
246
321
  const currentScope = String(cur[0].scope);
322
+ // Read-side whitewash refusal (core 1.302 contract I-2, File-backend parity incl. ordering: judged
323
+ // BEFORE the rev CAS): an update may not strip provenance/trust off a repo-ingested entry. Judged on
324
+ // the committed frontmatter of THIS SELECT — a write racing past it flips rev and the conditional
325
+ // write below re-reports as a CAS conflict, so the window stays closed.
247
326
  if (patch.op === "update" && patch.entry !== undefined) {
248
327
  const committedFm = fromJson(cur[0].frontmatter);
249
328
  if (committedFm.provenance?.kind === "repo_file") {
@@ -261,16 +340,26 @@ export class TiDBMemoryEngineBackend {
261
340
  }
262
341
  }
263
342
  if (patch.baseRev !== undefined && patch.baseRev !== currentRev) {
343
+ // Per-id CAS (§2.4 并发): NEVER blind-write over a concurrent change. ABA note shared with the
344
+ // File/Pg backends (rev is a content hash — an A→B→A round-trip re-arms a stale baseRev; benign
345
+ // by construction, same canonical content).
264
346
  report.conflicts.push({ op: patch.op, id: patch.id, reason: "rev mismatch (concurrent change)", baseRev: patch.baseRev, currentRev });
265
347
  return;
266
348
  }
267
349
  if (patch.op === "delete") {
350
+ // Conditional on the rev we just judged — a write landing between the SELECT and this DELETE
351
+ // re-reports as the same CAS conflict instead of silently deleting the newer committed state.
352
+ // DELETE's affectedRows counts deleted rows (FOUND_ROWS only affects UPDATE): 0 = the row changed/vanished.
268
353
  const res = await this.write(`DELETE FROM ${T} WHERE id = ? AND rev = ?`, [patch.id, currentRev]);
269
354
  if (res.affectedRows === 0) {
270
355
  report.conflicts.push({ op: "delete", id: patch.id, reason: "rev mismatch (concurrent change)", baseRev: patch.baseRev, currentRev: await this.freshRev(patch.id, currentRev) });
271
356
  return;
272
357
  }
273
358
  report.applied.push({ op: "delete", id: patch.id, slug: currentSlug });
359
+ // History tombstone. rev must be DISTINCT from the deleted version's rev — the (id, rev) PK
360
+ // already holds a row for currentRev (the add/update that committed it), and the idempotent
361
+ // no-op ODKU would silently drop a colliding tombstone. Deterministic derived key: revs are
362
+ // 16-hex content hashes (computeEntryRev), so the prefixed form stays well under VARCHAR(128).
274
363
  if (this.history)
275
364
  historyRows.push({ id: patch.id, rev: `tombstone:${currentRev}`, prevRev: currentRev, op: "delete", scope: currentScope, writtenAtMs: this.clock() });
276
365
  return;
@@ -283,9 +372,22 @@ export class TiDBMemoryEngineBackend {
283
372
  const rev = computeEntryRev(entry);
284
373
  const res = await this.write(`UPDATE ${T} SET scope = ?, slug = ?, frontmatter = ?, body = ?, rev = ?, mtime_ms = ?, size_bytes = ?, embedding = NULL WHERE id = ? AND rev = ?`, [entry.scope, entry.slug, JSON.stringify(entry.frontmatter), entry.body, rev, this.clock(), Buffer.byteLength(serializeEntryFile(entry), "utf8"), entry.id, currentRev]);
285
374
  if (res.affectedRows === 0) {
375
+ // Zero AFFECTED rows is ambiguous under the default protocol (changed-rows counting): the row may
376
+ // hold rev==currentRev with byte-identical values (matched but unchanged). Disambiguate on the
377
+ // fresh rev: the row must STILL EXIST and already be at the NEW rev ⇒ the content is exactly the
378
+ // target state (idempotent success — also covers a concurrent writer landing the same hash);
379
+ // anything else ⇒ CAS conflict with the rev NOW.
380
+ // 🔴 codex lens-3: the row-EXISTENCE check is load-bearing. When the row was concurrently DELETED
381
+ // between the SELECT and this UPDATE, affectedRows is also 0; a fallback that returned the pre-race
382
+ // rev would make `fresh === rev` true for a byte-identical update and FALSELY report `applied` on a
383
+ // row that no longer exists — while the Pg twin (UPDATE … RETURNING → zero rows) correctly reports a
384
+ // conflict. `freshRevOrMissing` returns undefined for a gone row, so it falls through to conflict,
385
+ // restoring dialect parity (never accept a lost write as applied).
286
386
  const fresh = await this.freshRevOrMissing(entry.id);
287
387
  if (fresh === rev) {
288
388
  report.applied.push({ op: "update", id: entry.id, slug: entry.slug });
389
+ // History: the idempotent already-at-target success is a committed version too — the
390
+ // (id, rev) idempotent append dedupes if this exact version was already recorded.
289
391
  if (this.history)
290
392
  historyRows.push({ id: entry.id, rev, prevRev: currentRev, op: "update", scope: entry.scope, snapshot: { ...entry, rev }, writtenAtMs: this.clock() });
291
393
  return;
@@ -294,13 +396,19 @@ export class TiDBMemoryEngineBackend {
294
396
  return;
295
397
  }
296
398
  report.applied.push({ op: "update", id: entry.id, slug: entry.slug });
399
+ // History: rev-chain link — snapshot carries the committed entry (rev = the NEW content hash).
297
400
  if (this.history)
298
401
  historyRows.push({ id: entry.id, rev, prevRev: currentRev, op: "update", scope: entry.scope, snapshot: { ...entry, rev }, writtenAtMs: this.clock() });
299
402
  }
403
+ /** The row's rev NOW, or undefined if the row is gone. The existence distinction is the whole point
404
+ * (codex lens-3): a concurrent delete must not be mistaken for an idempotent already-at-target write. */
300
405
  async freshRevOrMissing(id) {
301
406
  const rows = await this.selectRows(`SELECT rev FROM ${TIDB_MEMORY_ENGINE_TABLES.entries} WHERE id = ?`, [id]);
302
407
  return rows.length > 0 ? String(rows[0].rev) : undefined;
303
408
  }
409
+ /** When the conditional write reports zero rows (a write landed inside the SELECT→write window), the
410
+ * report's `currentRev` must be the rev NOW — re-reporting the pre-race SELECT value could claim
411
+ * `baseRev === currentRev` alongside a "rev mismatch" reason. Row gone ⇒ fallback (Pg parity). */
304
412
  async freshRev(id, fallback) {
305
413
  return (await this.freshRevOrMissing(id)) ?? fallback;
306
414
  }
@@ -309,6 +417,8 @@ export class TiDBMemoryEngineBackend {
309
417
  return rows.length > 0 ? String(rows[0].cursor) : undefined;
310
418
  }
311
419
  async setConsolidationCursor(scope, cursor) {
420
+ // Single unique key (the PK) on this table — ON DUPLICATE KEY UPDATE is unambiguous here,
421
+ // unlike the two-unique-key entries table (see the file-head dialect note).
312
422
  await this.write(`INSERT INTO ${TIDB_MEMORY_ENGINE_TABLES.cursors} (scope, \`cursor\`) VALUES (?, ?) ON DUPLICATE KEY UPDATE \`cursor\` = VALUES(\`cursor\`)`, [scope, cursor]);
313
423
  }
314
424
  }
@@ -1,3 +1,8 @@
1
+ /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
2
+ * 单一语义源;memoryBackendContract 的 search 等价断言依赖同源 haystack 距离)。
3
+ * `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
4
+ * 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
5
+ * `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
1
6
  export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
2
7
  export declare function isUniqueViolation(err: unknown): boolean;
3
8
  //# sourceMappingURL=memory-engine-vector-util.d.ts.map
@@ -1,3 +1,8 @@
1
+ /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
2
+ * 单一语义源;memoryBackendContract 的 search 等价断言依赖同源 haystack 距离)。
3
+ * `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
4
+ * 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
5
+ * `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
1
6
  export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
2
7
  export function isUniqueViolation(err) {
3
8
  if (typeof err !== "object" || err === null)
@@ -1,12 +1,20 @@
1
1
  export declare class MemoryResumeAnchorStore {
2
2
  private readonly bySession;
3
+ /** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL ON DUPLICATE/CONFLICT). */
3
4
  put(sessionId: string, eventId: string, entryId: string, owner: string | null): Promise<void>;
5
+ /** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
6
+ * anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
4
7
  resolve(sessionId: string, eventId: string, owner: string | null): Promise<string | undefined>;
8
+ /** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
9
+ * session EXPORT bundles the whole anchor map so the importer can re-key owner to the target principal (§9). Twin of
10
+ * the SQL/file stores; kept on all three backends so the ResumeAnchorStore union shares a single contract. */
5
11
  listBySession(sessionId: string): Promise<Array<{
6
12
  eventId: string;
7
13
  entryId: string;
8
14
  owner: string | null;
9
15
  }>>;
16
+ /** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
17
+ * ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count). */
10
18
  deleteBySession(sessionId: string): Promise<number>;
11
19
  }
12
20
  //# sourceMappingURL=memory-resume-anchor-store.d.ts.map
@@ -1,6 +1,16 @@
1
+ /**
2
+ * In-memory resume-at anchor map — the LOCAL (DB-less) twin of {@link TiDBResumeAnchorStore}/{@link PgResumeAnchorStore}
3
+ * (E18 resume-at; clay seamless local↔cloud). The shell holds the live E2 `eventId` (core never persists it);
4
+ * core's `TaskSpec.resumeAt` takes a persisted `SessionTreeEntry.id`. This store is the service-owned translation
5
+ * ("a deployment that holds eventIds owns the eventId→entryId map", core types). resume-at works LOCALLY (it needs
6
+ * only the session tree + this map, no cloud-only checkpoint), so this is PRESENT on the local backend (a singleton,
7
+ * like MemoryRunStore) — not omitted like the cloud-only stores. Process-local + ephemeral (lost on restart, same
8
+ * blast radius as MemoryRunStore; the file-backed follow-on persists it alongside run history).
9
+ */
1
10
  const ownerEq = (a, b) => (a ?? null) === (b ?? null);
2
11
  export class MemoryResumeAnchorStore {
3
12
  bySession = new Map();
13
+ /** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL ON DUPLICATE/CONFLICT). */
4
14
  async put(sessionId, eventId, entryId, owner) {
5
15
  let m = this.bySession.get(sessionId);
6
16
  if (!m) {
@@ -9,10 +19,15 @@ export class MemoryResumeAnchorStore {
9
19
  }
10
20
  m.set(eventId, { entryId, owner });
11
21
  }
22
+ /** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
23
+ * anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
12
24
  async resolve(sessionId, eventId, owner) {
13
25
  const e = this.bySession.get(sessionId)?.get(eventId);
14
26
  return e && ownerEq(e.owner, owner) ? e.entryId : undefined;
15
27
  }
28
+ /** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
29
+ * session EXPORT bundles the whole anchor map so the importer can re-key owner to the target principal (§9). Twin of
30
+ * the SQL/file stores; kept on all three backends so the ResumeAnchorStore union shares a single contract. */
16
31
  async listBySession(sessionId) {
17
32
  const m = this.bySession.get(sessionId);
18
33
  if (!m)
@@ -22,6 +37,8 @@ export class MemoryResumeAnchorStore {
22
37
  out.push({ eventId, entryId: e.entryId, owner: e.owner });
23
38
  return out;
24
39
  }
40
+ /** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
41
+ * ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count). */
25
42
  async deleteBySession(sessionId) {
26
43
  const removed = this.bySession.get(sessionId)?.size ?? 0;
27
44
  this.bySession.delete(sessionId);
@@ -1,17 +1,49 @@
1
+ /**
2
+ * In-memory async run registry + replayable event log — the LOCAL (DB-less) twin of {@link TiDBRunStore}/
3
+ * {@link PgRunStore} (clay 2026-06-25: the seamless local↔cloud switch — a locally-run HTTP service must serve the
4
+ * SAME contract a cloud worker does, incl. `/v1/runs` async runs + the trace event log). Behaviourally identical to
5
+ * the SQL twins (the shared `storeBehaviorSuite` keeps them in lock-step), but process-local + ephemeral: a restart
6
+ * loses run history (file-backed durability is the immediate follow-on; the conversation HISTORY + checkpoints DO
7
+ * persist via core's FileStorageBackend). Single-process, so the cross-replica/durable reapers degrade — see below.
8
+ *
9
+ * Mirrors the SQL semantics exactly: the `task_active` single-active-run claim (a Map keyed by sessionId), the
10
+ * NON-terminal suspend/needs_review parks that KEEP the claim, the markResuming CAS that resets cancel/preempt, the
11
+ * owner null-safe guard on the flag/heartbeat paths (`<=>` → JS `(a??null)===(b??null)`), and the keyset list order.
12
+ */
1
13
  import { type UsageRow } from "../usage-analytics.js";
2
14
  import type { TaskResult, TaskStatus } from "@sema-agent/core";
3
15
  import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
16
+ /**
17
+ * [868] P0 — the local lane's stand-in for the SQL twins' checkpoint-table JOIN. The file/memory run stores
18
+ * cannot JOIN `checkpoint` (separate store, separate files), so the suspended-run reapers were NO-OPs — which
19
+ * left a durable HITL park whose approval was never answered holding the task_active claim FOREVER (the
20
+ * "suspended run locks the session" incident: every later submit 409s and no reaper path releases it).
21
+ * The backend assembly (store-backend.ts local lane, where checkpoint + run store are built side by side)
22
+ * injects this probe so the reapers get the SAME two predicates the SQL twins express as EXISTS subqueries:
23
+ * - hasPending = EXISTS (checkpoint c WHERE c.session_id = ? AND c.status = 'pending') — the design/80 D-D
24
+ * NOT-EXISTS-pending guard: a row whose checkpoint is STILL pending is owned by the checkpoint-state-driven
25
+ * sweeps and must NEVER be time-reaped (else two-runs-one-session, see tidb-run-store.ts reapSuspended doc).
26
+ * - hasExpired = EXISTS (checkpoint ce WHERE ce.session_id = ? AND ce.status = 'expired') — the
27
+ * failSuspendedWithExpiredCheckpoint driver (checkpoint-STATE-driven, not time-driven).
28
+ * Probe ABSENT (old assembly / no checkpoint store wired) ⇒ the reapers stay honest NO-OPs — without the
29
+ * pending-guard there is no safe way to distinguish "abandoned park" from "operator still deciding".
30
+ */
4
31
  export interface RunStoreCheckpointProbe {
5
32
  hasPending(sessionId: string): Promise<boolean>;
6
33
  hasExpired(sessionId: string): Promise<boolean>;
7
34
  }
8
35
  export declare class MemoryRunStore {
9
36
  private readonly runs;
37
+ /** sessionId → taskId — the single-active-run claim (the `task_active` table). */
10
38
  private readonly active;
39
+ /** taskId → events (kept seq-sorted on read). */
11
40
  private readonly events;
41
+ /** [868] the checkpoint-table stand-in (see {@link RunStoreCheckpointProbe}); absent ⇒ reapers NO-OP. */
12
42
  private checkpointProbe?;
43
+ /** [868] wire the checkpoint probe (backend assembly, where checkpoint + run store are built together). */
13
44
  setCheckpointProbe(probe: RunStoreCheckpointProbe): void;
14
45
  private toRecord;
46
+ /** Create a run iff the session has no active run (the task_active unique-key claim). */
15
47
  createRun(taskId: string, sessionId: string, owner: string | null, instanceId: string, meta?: {
16
48
  jobId?: string | null;
17
49
  source?: string | null;
@@ -31,12 +63,18 @@ export declare class MemoryRunStore {
31
63
  maxSeq(taskId: string): Promise<number>;
32
64
  retainedFrom(taskId: string): Promise<number>;
33
65
  getEvents(taskId: string, afterSeq: number): Promise<RunEvent[]>;
66
+ /** [888] FIRST terminal writer wins(SQL 孪生同款正向 CAS on running/suspended/needs_review,
67
+ * [1.207 codex M1] 负向形漏 blocked/timeout);claim 释放保持无条件(幂等)。 */
34
68
  setTerminal(taskId: string, status: TaskStatus, result: TaskResult | null, error: string | null): Promise<void>;
69
+ /** Durable F4: park NON-terminal `suspended`, KEEP the task_active claim. CAS on running/suspended (reaper-revert guard). */
35
70
  setSuspended(taskId: string): Promise<void>;
71
+ /** design/80 D-B: park NON-terminal `needs_review`, KEEP the claim. CAS on running/needs_review. */
36
72
  setNeedsReview(taskId: string): Promise<void>;
73
+ /** Durable F4 resume: flip suspended/needs_review → running (CAS) + reset cancel/preempt flags. */
37
74
  markResuming(taskId: string): Promise<boolean>;
38
75
  getActiveTaskId(sessionId: string): Promise<string | undefined>;
39
76
  getRun(taskId: string): Promise<RunRecord | undefined>;
77
+ /** Runs newest-first, keyset on (createdAt, taskId) DESC; optional exact-match filters (owner is exact, like the SQL). */
40
78
  listRuns(opts: {
41
79
  status?: string;
42
80
  jobId?: string;
@@ -48,6 +86,7 @@ export declare class MemoryRunStore {
48
86
  };
49
87
  limit: number;
50
88
  }): Promise<RunRecord[]>;
89
+ /** DISTINCT sessions newest-first by last activity (the CC /resume picker): latest run's preview/status + first/last/count. */
51
90
  listSessions(opts: {
52
91
  owner?: string;
53
92
  cursor?: {
@@ -57,11 +96,13 @@ export declare class MemoryRunStore {
57
96
  limit: number;
58
97
  q?: string;
59
98
  }): Promise<SessionSummary[]>;
99
+ /** E21 (§0.5 delete) — purge the runs ledger for one session, owner-guarded; aborts (returns {active}) if a run is live. */
60
100
  deleteBySession(sessionId: string, owner: string | null): Promise<{
61
101
  removed: number;
62
102
  } | {
63
103
  active: string;
64
104
  }>;
105
+ /** 用量扫窗——in-memory 腿:遍历窗内行,投影同 usage-analytics 纯函数(SQL 孪生 parity)。 */
65
106
  usageScan(fromMs: number, toMs: number, opts?: {
66
107
  owner?: string;
67
108
  limit?: number;
@@ -74,10 +115,32 @@ export declare class MemoryRunStore {
74
115
  status: string;
75
116
  count: number;
76
117
  }>>;
118
+ /** Fail stale `running` rows (crashed-run backstop) + release task_active for any now-terminal row. */
77
119
  reapStale(olderThanMs: number): Promise<number>;
120
+ /** [868] shared tail of both suspended-run reapers: flip one parked row → failed('approval.expired'), the
121
+ * in-memory twin of the SQL UPDATE (`error`/`error_code` set directly — no result blob to derive from). */
78
122
  private failExpiredPark;
123
+ /** Release the claim for TERMINAL rows only — suspended/needs_review keep it (the `DELETE ta … WHERE tr.status
124
+ * NOT IN ('running','suspended','needs_review')` twin, shared by reapStale + the [868] suspended reapers). */
79
125
  private releaseTerminalClaims;
126
+ /**
127
+ * [868] Durable F4 expiry — the local twin of TiDBRunStore.reapSuspended, driven by the injected checkpoint
128
+ * probe instead of a SQL JOIN (formerly a NO-OP, which was one of the five closed doors in the "suspended run
129
+ * locks the session forever" incident). Semantics verbatim from the SQL twin: suspended ∧ updatedAt < cutoff
130
+ * ∧ NOT probe.hasPending(session) → failed 'approval expired before decision' / error_code 'approval.expired'
131
+ * + release the task_active claim. The NOT-pending clause is the design/80 D-D adversarial-blocker guard
132
+ * (see tidb-run-store.ts:577-583): a row whose checkpoint is STILL pending belongs to the checkpoint-state
133
+ * sweeps (SLA deny-sweep / failSuspendedWithExpiredCheckpoint) — time-reaping it here would orphan a model
134
+ * leg on a now-unlocked session. Probe absent ⇒ honest NO-OP (never kill a park without the guard).
135
+ */
80
136
  reapSuspended(olderThanMs: number): Promise<number>;
137
+ /**
138
+ * [868] design/80 §3 inv#3 crash-safe backstop — the local twin of TiDBRunStore.failSuspendedWithExpiredCheckpoint
139
+ * (checkpoint-STATE-driven, not time-driven; runs UNCONDITIONALLY every reaper tick, no APPROVAL_TIMEOUT_SEC gate).
140
+ * Semantics verbatim from the SQL twin: (suspended ∨ needs_review) ∧ probe.hasExpired(session) ∧ NOT
141
+ * probe.hasPending(session) → same fail + claim release. The NOT-pending clause covers a re-suspended session
142
+ * that minted a NEW pending gate (wq64gmm5e: an abandoned needs_review park leaks exactly like a suspended one).
143
+ */
81
144
  failSuspendedWithExpiredCheckpoint(): Promise<number>;
82
145
  }
83
146
  //# sourceMappingURL=memory-run-store.d.ts.map