@sema-agent/server 1.322.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 +59 -3
  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,18 +1,42 @@
1
1
  import type { AcquiredSession, SessionStore, SessionTreeEntry } from "@sema-agent/core";
2
2
  import type { SessionListItem } from "../security.js";
3
3
  export interface CachingOptions {
4
+ /** Idle seconds a woken session is kept warm. 0 disables caching (pure passthrough). */
4
5
  ttlSec: number;
5
6
  sweepIntervalMs?: number;
7
+ /** S25 (SILENT-FALLBACK P1): called when a cross-instance write (import/replace) evicts a WARM entry —
8
+ * the affinity-contract violation signal that previously had zero fingerprint. */
6
9
  onConflictEvict?: (sessionId: string) => void;
7
10
  }
11
+ /**
12
+ * Warm/sticky cache in front of a durable {@link SessionStore} (Option A).
13
+ *
14
+ * Keeps a woken session in memory and **reuses the same storage instance across turns**, so a hot
15
+ * session is not re-read from TiDB every short turn (treats the cattle like a warm pet while it's
16
+ * active). Idle sessions expire after `ttlSec`; `release` evicts immediately.
17
+ *
18
+ * ⚠️ **Session affinity is REQUIRED** when this cache is enabled (`SESSION_CACHE_TTL_SEC>0`): route a
19
+ * given sessionId to the same instance. Under affinity the cached storage is the sole writer, so its
20
+ * in-memory leaf is always current and consistent with TiDB (write-through; F2 CAS still applies).
21
+ * Without affinity a concurrent write from another instance makes this cache stale; that surfaces as
22
+ * a `SessionError("conflict")` on the next append — the async run driver calls `evict()` on conflict
23
+ * (defense-in-depth) and the entry also expires after `ttlSec`, but those are backstops, not the
24
+ * guarantee. If you cannot guarantee affinity, set `SESSION_CACHE_TTL_SEC=0` to disable the cache.
25
+ *
26
+ * Orthogonal to the F3 branch-floor change: floor bounds the *cold wake* size; this cache removes
27
+ * *repeated* re-reads of an active session.
28
+ */
8
29
  export declare class CachingSessionStore implements SessionStore {
9
30
  private readonly inner;
10
31
  private readonly cache;
11
32
  private readonly pending;
12
33
  private readonly ttlMs;
13
34
  private readonly timer?;
35
+ /** Delegated tenant-ownership ops, present only if the inner store exposes them (the TiDB store does). */
14
36
  readonly ownerOf?: (sessionId: string) => Promise<string | null | undefined>;
15
37
  readonly register?: (sessionId: string, owner: string | null) => Promise<void>;
38
+ /** Delegated SessionRepo seam (§0.5) — list/fork/delete operate on the DURABLE tables directly (they bypass the
39
+ * warm cache by design; a fork/delete must read/write durable state, not a possibly-stale cached view). */
16
40
  readonly listSessions?: (opts: {
17
41
  owner?: string;
18
42
  cursor?: {
@@ -24,22 +48,39 @@ export declare class CachingSessionStore implements SessionStore {
24
48
  }) => Promise<SessionListItem[]>;
25
49
  readonly fork?: (sourceId: string, owner: string | null) => Promise<string | null>;
26
50
  readonly deleteSession?: (sessionId: string, owner: string | null) => Promise<boolean>;
51
+ /** K-5c (core 1.155 SessionStore.noteTaskRun seam) — core's Runner calls it at runTask START to record the latest
52
+ * run per session (→ listSessions `lastRunId`). MUST be forwarded: the local backend's Runner store is THIS cache
53
+ * wrapper, so without forwarding `noteTaskRun?.()` silently no-ops and lastRunId stays null (review BLOCKER). Pure
54
+ * pass-through to the inner store's in-mem map — no cache interaction. (TiDB/PG don't implement it → not bound.)
55
+ * Return type matches core's `SessionStore.noteTaskRun?(): void | Promise<void>` (review: don't narrow to void). */
27
56
  readonly noteTaskRun?: (sessionId: string, taskId: string) => void | Promise<void>;
57
+ /** Write-once auto-title (SQL twins + local sidecar carry it; pure pass-through). */
28
58
  readonly setTitleIfNull?: (sessionId: string, title: string) => Promise<boolean>;
29
59
  readonly probeTitle?: (sessionId: string) => Promise<"none" | "untitled" | "titled">;
60
+ /** E18 — delegate the leaf read straight to inner (a cache-bypassing single SELECT; the resume-at turn-capture
61
+ * reads the DURABLE leaf, not a possibly-stale cached view — same discipline as the §0.5 repo ops above). */
30
62
  readonly getLeafId?: (sessionId: string) => Promise<string | null>;
63
+ /** [1196] 六轮复审:owner+leafId 原子快照透传(cache-bypassing,getLeafId 同姿势)。 */
31
64
  readonly getHead?: (sessionId: string) => Promise<{
32
65
  owner: string | null;
33
66
  leafId: string | null;
34
67
  } | undefined>;
68
+ /** 2c session-sync — delegated export/import seam, DURABLE (bypasses the warm cache exactly like
69
+ * list/fork: an export reads the full durable log, an import writes durable state). */
35
70
  readonly exportEntries?: (sessionId: string) => Promise<SessionTreeEntry[] | null>;
71
+ /** 2c session-sync P1d-α (PULL streaming) — delegated ids-only projection + keyset-paged entry STREAM, DURABLE
72
+ * (read straight from the durable log, bypassing the warm cache, like exportEntries). The stream's per-batch query
73
+ * discipline (one pooled query per page) lives in the inner store; this wrapper just forwards. */
36
74
  readonly listEntryIds?: (sessionId: string) => Promise<string[] | null>;
37
75
  readonly exportEntriesStream?: (sessionId: string, opts?: {
38
76
  afterSeq?: number;
39
77
  batchSize?: number;
40
78
  }) => Promise<AsyncIterable<SessionTreeEntry> | null>;
79
+ /** 轴A #1(1.254):core B-17 forget 面(evict 本地 + 转发 inner 可选面)。 */
41
80
  forget?: (sessionId: string) => void | Promise<void>;
42
81
  readonly importEntries?: (sessionId: string, owner: string | null, entries: SessionTreeEntry[]) => Promise<void>;
82
+ /** 2c session-sync (§7/§8) — delegated IDEMPOTENT replace; like importEntries it writes durable state under
83
+ * `sessionId`, so a stale warm handle for that id is evicted on success (next acquire re-wakes from the new log). */
43
84
  readonly replaceEntries?: (sessionId: string, owner: string | null, entries: SessionTreeEntry[]) => Promise<void>;
44
85
  constructor(inner: SessionStore, opts: CachingOptions);
45
86
  acquire(sessionId?: string, opts?: {
@@ -47,6 +88,7 @@ export declare class CachingSessionStore implements SessionStore {
47
88
  }): Promise<AcquiredSession>;
48
89
  touch(sessionId: string): Promise<void>;
49
90
  release(sessionId: string): Promise<void>;
91
+ /** Drop a session from the warm cache (e.g. after a cross-instance write conflict). */
50
92
  evict(sessionId: string): void;
51
93
  get size(): number;
52
94
  dispose(): void;
@@ -1,24 +1,62 @@
1
+ /**
2
+ * Warm/sticky cache in front of a durable {@link SessionStore} (Option A).
3
+ *
4
+ * Keeps a woken session in memory and **reuses the same storage instance across turns**, so a hot
5
+ * session is not re-read from TiDB every short turn (treats the cattle like a warm pet while it's
6
+ * active). Idle sessions expire after `ttlSec`; `release` evicts immediately.
7
+ *
8
+ * ⚠️ **Session affinity is REQUIRED** when this cache is enabled (`SESSION_CACHE_TTL_SEC>0`): route a
9
+ * given sessionId to the same instance. Under affinity the cached storage is the sole writer, so its
10
+ * in-memory leaf is always current and consistent with TiDB (write-through; F2 CAS still applies).
11
+ * Without affinity a concurrent write from another instance makes this cache stale; that surfaces as
12
+ * a `SessionError("conflict")` on the next append — the async run driver calls `evict()` on conflict
13
+ * (defense-in-depth) and the entry also expires after `ttlSec`, but those are backstops, not the
14
+ * guarantee. If you cannot guarantee affinity, set `SESSION_CACHE_TTL_SEC=0` to disable the cache.
15
+ *
16
+ * Orthogonal to the F3 branch-floor change: floor bounds the *cold wake* size; this cache removes
17
+ * *repeated* re-reads of an active session.
18
+ */
1
19
  export class CachingSessionStore {
2
20
  inner;
3
21
  cache = new Map();
4
22
  pending = new Map();
5
23
  ttlMs;
6
24
  timer;
25
+ /** Delegated tenant-ownership ops, present only if the inner store exposes them (the TiDB store does). */
7
26
  ownerOf;
8
27
  register;
28
+ /** Delegated SessionRepo seam (§0.5) — list/fork/delete operate on the DURABLE tables directly (they bypass the
29
+ * warm cache by design; a fork/delete must read/write durable state, not a possibly-stale cached view). */
9
30
  listSessions;
10
31
  fork;
11
32
  deleteSession;
33
+ /** K-5c (core 1.155 SessionStore.noteTaskRun seam) — core's Runner calls it at runTask START to record the latest
34
+ * run per session (→ listSessions `lastRunId`). MUST be forwarded: the local backend's Runner store is THIS cache
35
+ * wrapper, so without forwarding `noteTaskRun?.()` silently no-ops and lastRunId stays null (review BLOCKER). Pure
36
+ * pass-through to the inner store's in-mem map — no cache interaction. (TiDB/PG don't implement it → not bound.)
37
+ * Return type matches core's `SessionStore.noteTaskRun?(): void | Promise<void>` (review: don't narrow to void). */
12
38
  noteTaskRun;
39
+ /** Write-once auto-title (SQL twins + local sidecar carry it; pure pass-through). */
13
40
  setTitleIfNull;
14
41
  probeTitle;
42
+ /** E18 — delegate the leaf read straight to inner (a cache-bypassing single SELECT; the resume-at turn-capture
43
+ * reads the DURABLE leaf, not a possibly-stale cached view — same discipline as the §0.5 repo ops above). */
15
44
  getLeafId;
45
+ /** [1196] 六轮复审:owner+leafId 原子快照透传(cache-bypassing,getLeafId 同姿势)。 */
16
46
  getHead;
47
+ /** 2c session-sync — delegated export/import seam, DURABLE (bypasses the warm cache exactly like
48
+ * list/fork: an export reads the full durable log, an import writes durable state). */
17
49
  exportEntries;
50
+ /** 2c session-sync P1d-α (PULL streaming) — delegated ids-only projection + keyset-paged entry STREAM, DURABLE
51
+ * (read straight from the durable log, bypassing the warm cache, like exportEntries). The stream's per-batch query
52
+ * discipline (one pooled query per page) lives in the inner store; this wrapper just forwards. */
18
53
  listEntryIds;
19
54
  exportEntriesStream;
55
+ /** 轴A #1(1.254):core B-17 forget 面(evict 本地 + 转发 inner 可选面)。 */
20
56
  forget;
21
57
  importEntries;
58
+ /** 2c session-sync (§7/§8) — delegated IDEMPOTENT replace; like importEntries it writes durable state under
59
+ * `sessionId`, so a stale warm handle for that id is evicted on success (next acquire re-wakes from the new log). */
22
60
  replaceEntries;
23
61
  constructor(inner, opts) {
24
62
  this.inner = inner;
@@ -37,7 +75,7 @@ export class CachingSessionStore {
37
75
  if (ownerAware.fork)
38
76
  this.fork = ownerAware.fork.bind(inner);
39
77
  if (ownerAware.noteTaskRun)
40
- this.noteTaskRun = ownerAware.noteTaskRun.bind(inner);
78
+ this.noteTaskRun = ownerAware.noteTaskRun.bind(inner); // K-5c: pass-through so the Runner's noteTaskRun reaches the inner map (review BLOCKER fix)
41
79
  if (ownerAware.getLeafId)
42
80
  this.getLeafId = ownerAware.getLeafId.bind(inner);
43
81
  if (ownerAware.getHead)
@@ -48,29 +86,39 @@ export class CachingSessionStore {
48
86
  this.listEntryIds = ownerAware.listEntryIds.bind(inner);
49
87
  if (ownerAware.exportEntriesStream)
50
88
  this.exportEntriesStream = ownerAware.exportEntriesStream.bind(inner);
89
+ // 历史复审轴A #1(1.254,core B-17 缝):core prepare-task 在 reconcile 冲突重试/prepare-throw 清理时
90
+ // 调 `sessions.forget?.()`,缺席=无 fallback(B-17 判例:绝不代之以 release)——本店此前无 forget,
91
+ // tidb+cache 形态下运行内冲突自愈失效(暖缓存命中同一 stale 实例→重试预算耗尽→该 run 以 conflict 败;
92
+ // runs.ts evictIfConflict 只兜 run 后)。补齐=evict 本地缓存 + 转发 inner 可选面(fork-routing 店同款)。
51
93
  this.forget = (sessionId) => {
52
94
  this.evict(sessionId);
53
95
  return inner.forget?.(sessionId);
54
96
  };
55
97
  if (ownerAware.importEntries) {
98
+ // An import writes durable state under `sessionId`; if a stale handle for that id is warm, drop it so the
99
+ // next acquire re-wakes from the freshly-imported durable log (mirrors the deleteSession evict discipline).
56
100
  const imp = ownerAware.importEntries.bind(inner);
57
101
  this.importEntries = async (sessionId, owner, entries) => {
58
102
  await imp(sessionId, owner, entries);
59
103
  if (this.cache.has(sessionId))
60
- opts.onConflictEvict?.(sessionId);
104
+ opts.onConflictEvict?.(sessionId); // S25: a warm entry was live → stale-affinity fingerprint
61
105
  this.evict(sessionId);
62
106
  };
63
107
  }
64
108
  if (ownerAware.replaceEntries) {
109
+ // A replace REWRITES durable state under `sessionId` (purge + re-import); evict any warm handle so the next
110
+ // acquire re-wakes from the replaced log (same discipline as importEntries / deleteSession above).
65
111
  const rep = ownerAware.replaceEntries.bind(inner);
66
112
  this.replaceEntries = async (sessionId, owner, entries) => {
67
113
  await rep(sessionId, owner, entries);
68
114
  if (this.cache.has(sessionId))
69
- opts.onConflictEvict?.(sessionId);
115
+ opts.onConflictEvict?.(sessionId); // S25
70
116
  this.evict(sessionId);
71
117
  };
72
118
  }
73
119
  if (ownerAware.deleteSession) {
120
+ // A durable delete must also drop the deleted session from THIS warm cache (else a stale cached handle
121
+ // could keep serving a purged session until its idle TTL). Wrap to evict on success.
74
122
  const del = ownerAware.deleteSession.bind(inner);
75
123
  this.deleteSession = async (sessionId, owner) => {
76
124
  const removed = await del(sessionId, owner);
@@ -93,9 +141,20 @@ export class CachingSessionStore {
93
141
  }
94
142
  const hit = this.cache.get(sessionId);
95
143
  if (hit) {
144
+ // A warm cache hit means the session EXISTS → it satisfies `requireExisting` (no need to re-open the durable
145
+ // log). design/114 Phase3: the fail-loud only ever fires on a genuinely-missing (uncached) session below.
146
+ // 🟡 Affinity caveat (doc-as-intentional, LOW): under the REQUIRED session affinity (see the class header), the
147
+ // cached instance is the sole writer, so a warm handle can't be stale w.r.t. a purge — a same-instance E21
148
+ // delete evicts this entry (deleteSession wrapper). Only an out-of-band / cross-instance purge that VIOLATES
149
+ // affinity could leave a stale hit that satisfies requireExisting until the idle TTL expires. Bypassing the
150
+ // cache for strict acquires would add a DB round-trip to EVERY warm-resume (the hot path) to close an
151
+ // affinity-violation-only window — not worth it; the affinity contract already governs cross-instance writes.
96
152
  hit.expiresAt = Date.now() + this.ttlMs;
97
153
  return hit.acquired;
98
154
  }
155
+ // design/114 Phase3 (F1): a `requireExisting` acquire can REJECT (not_found) and never creates — it MUST bypass
156
+ // the shared create-dedup `pending`, else a concurrent create-capable waiter would inherit the not_found rejection
157
+ // instead of creating-on-miss. Forward the option to the inner (durable) store, which does the fail-loud.
99
158
  if (opts?.requireExisting) {
100
159
  const a = await this.inner.acquire(sessionId, opts);
101
160
  this.store(a);
@@ -124,6 +183,7 @@ export class CachingSessionStore {
124
183
  this.cache.delete(sessionId);
125
184
  await this.inner.release(sessionId);
126
185
  }
186
+ /** Drop a session from the warm cache (e.g. after a cross-instance write conflict). */
127
187
  evict(sessionId) {
128
188
  this.cache.delete(sessionId);
129
189
  }
@@ -2,23 +2,64 @@ import type { Pool as MySqlPool } from "mysql2/promise";
2
2
  import type { Pool as PgPool } from "pg";
3
3
  import { type Checkpoint, type CheckpointStore, type CheckpointSummary, type CheckpointToken, type ResumeOutcome, type ResolveExpectation, type ReopenReason, type RiskDescriptor } from "@sema-agent/core";
4
4
  import { type SqlDriver } from "./sql-driver.js";
5
+ /**
6
+ * design/80 D-1 (§3 invariant #3 — crash-safe reaper backstop): an ABSOLUTE upper bound on a pending
7
+ * checkpoint's lifetime, stamped at put() into `terminal_at` INDEPENDENT of the per-approval `deadline`. The
8
+ * SLA-timer (D-D) does the fine, per-gate-kind resolve-deny; THIS coarse backstop ensures even a pending row
9
+ * with a NULL `deadline` (no approval TTL configured) is eventually GC'd if the SLA service dies — closing a
10
+ * forever-leak of a never-resolved suspension (the current `reap`/`reapExpired` only catch non-NULL deadlines).
11
+ * Generous (default 30d) so it never pre-empts a legitimately long-lived human/irreversible_ask gate;
12
+ * env-overridable. Clamped ≥1min so a misconfig can't expire live suspensions instantly.
13
+ */
5
14
  export declare const TERMINAL_BACKSTOP_MS: number;
15
+ /**
16
+ * design/80 D-D (adversarial fix): the crash-safe `terminal_at` backstop must fall STRICTLY AFTER any SLA
17
+ * `deadline`, never AT it. `terminal_at = max(createdAt+backstop, deadline)` made the two coincide whenever an
18
+ * operator tuned APPROVAL_TERMINAL_BACKSTOP_MS at/below the SLA — and reapExpired's terminal_at-branch (which
19
+ * has NO gate_kind filter) then abort-EXPIRED a human/irreversible_ask gate in the SAME tick the deny-sweep
20
+ * wanted to gracefully DENY it, racing it away. Adding this grace to the deadline term guarantees the deny-sweep
21
+ * at least this window of clean ticks before the absolute backstop can fire. Far smaller than the backstop, so
22
+ * it never meaningfully delays the eventual crash-safe GC.
23
+ */
6
24
  export declare const TERMINAL_GRACE_MS = 3600000;
25
+ /**
26
+ * The capability token IS the resume credential (token-as-auth) — anyone who reads it can impersonate a
27
+ * resume, so it must never reach the logs (which fan out to a log-aggregation pipeline). For the diagnostic
28
+ * resume-read-path log we emit a stable, non-reversible fingerprint instead, enough to correlate get↔resolve.
29
+ */
7
30
  export declare function tokenFingerprint(token: string): string;
31
+ /** Non-secret view of a pending checkpoint for the operator approval queue — deliberately NO token. */
8
32
  export interface PendingCheckpoint {
9
33
  sessionId: string;
10
34
  scope: string;
11
35
  toolName: string | null;
12
36
  toolCallId: string | null;
37
+ /** design/80 D-1: the decision-action binding fields the operator/portal must ECHO back on /decide so the
38
+ * resume binds to the EXACT action they saw (a stale view is then rejected fail-closed PRE-CAS). `boundCallId`
39
+ * === `toolCallId` (the pending tool call); `boundInputHash` is the server-minted opaque hash of the shown
40
+ * input (NEVER recomputed by the portal — echoed verbatim). Surfacing them here is what makes the D-1 TOCTOU
41
+ * guard REACHABLE by the portal (without it the portal can only do the unbound legacy fallback). `null` on a
42
+ * pre-D-1 / legacy-deserialized checkpoint ⇒ the consumer falls back to the unbound resolve. */
13
43
  boundCallId: string | null;
14
44
  boundInputHash: string | null;
45
+ /** The suspended run's taskId (task_active join) — the key to the run/trace ("view task context"). */
15
46
  taskId: string | null;
47
+ /** The pending tool call's args (post-hook), redacted + bounded — for tool_approval the write payload, for a
48
+ * durable AskUserQuestion the question itself. Lets the approval card render WITHOUT an N+1 trace.turns
49
+ * fetch. `null` for pre-migration rows (suspended before the column existed) ⇒ consumer falls back. */
16
50
  input: unknown;
17
51
  createdAt: number;
18
52
  deadline: number | null;
53
+ /** design/80 riskDescriptor inbox: core's INERT triage descriptor ({severity 1-5, axes, toolName, redacted
54
+ * summary, touchedPaths}) for human/irreversible_ask gates. listPending returns the queue severity-sorted
55
+ * (DESC) so the supervisor inbox triages high-risk asks first. `null` for gates with no descriptor. */
19
56
  riskDescriptor: RiskDescriptor | null;
20
57
  }
58
+ /** Redact + size-bound a pending tool call's args for persistence/serving. JSON-roundtrips so the stored shape
59
+ * matches what the operator queue serves; oversized payloads collapse to a marker rather than bloating the row.
60
+ * Exported for the LOCAL twin (local-checkpoint-store.ts) so the operator-queue projection can't drift. */
21
61
  export declare function boundedToolInput(args: unknown): unknown;
62
+ /** Dual-dialect durable CheckpointStore. See the file header for the dialect-delta ledger. */
22
63
  export declare class SqlCheckpointStore implements CheckpointStore {
23
64
  protected readonly db: SqlDriver;
24
65
  protected readonly logger?: {
@@ -27,38 +68,176 @@ export declare class SqlCheckpointStore implements CheckpointStore {
27
68
  constructor(db: SqlDriver, logger?: {
28
69
  info?(msg: string, meta?: unknown): void;
29
70
  } | undefined);
71
+ /** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
30
72
  private q;
73
+ /** JSON column binding: TiDB stores the string verbatim; PG goes through the LOSSLESS protocol envelope
74
+ * (R4-H1 — the operator's review surface must agree with the executed args at the NUL position). */
31
75
  private json;
32
76
  private isDupKey;
77
+ /** Create-once. core mints the token (`mintCheckpointToken`) and calls this during suspend. */
33
78
  put(token: CheckpointToken, cp: Checkpoint): Promise<void>;
34
79
  get(token: CheckpointToken): Promise<Checkpoint | null>;
80
+ /**
81
+ * Atomic CAS: pending → resolved, scoped. Returns true for the single winner, false if already
82
+ * resolved/expired (AlreadyResolved → caller no-ops, never re-executes). `outcome` is persisted atomically
83
+ * with the flip (R20 #1 — a future v2 resumable-resume can recover a crash-after-CAS; v1 runner write-only).
84
+ *
85
+ * design/80 D-1 (atomicity): the winner-persist (the full `outcome` is stored; the winner
86
+ * {boundCallId,decision,updatedInput?} is derived from it on read) + the `rev` bump happen ATOMICALLY in the
87
+ * SAME UPDATE as the pending→resolved CAS — one statement, no get→write window. When the caller passes the
88
+ * `rev` it observed at get() (ResolveExpectation), the CAS additionally requires the LIVE rev to still equal
89
+ * it: ANY intervening resolve/reopen cycle bumps rev, so a cycle in the get→resolve window loses the CAS
90
+ * (returns false → core re-inspects → checkpoint.reopened_concurrently). Omitting `expect` keeps the legacy
91
+ * unconditional CAS (a first resume of a never-reopened checkpoint is unconstrained by rev).
92
+ * 🔴 reopen_reason = NULL on a winning resolve — parity with the core reference InMemoryCheckpointStore
93
+ * (MINOR-12: "a freshly-resolved row carries no stale reopen reason"). Without this, an env_failed reopen
94
+ * followed by a correct winner-replay resolve leaves reopen_reason='env_failed' stale on the now-resolved
95
+ * row; a later DUPLICATE resume of that token would hit core's pre-CAS env_failed winner-replay guard
96
+ * against the stale reason and throw checkpoint.reopen_revote (which the service classifies RETRIABLE →
97
+ * re-parks the run suspended) instead of the terminal checkpoint.already_resolved — stranding the run.
98
+ */
35
99
  resolve(token: CheckpointToken, scope: string, outcome: ResumeOutcome, expect?: ResolveExpectation): Promise<boolean>;
100
+ /**
101
+ * Inverse of `resolve` (core `CheckpointStore.reopen`): CAS `resolved → pending`. Returns the CAS winner
102
+ * (true = was resolved → now pending again). Compensates a post-CAS env-restore failure
103
+ * (`resume.env_failed`): `resumeStream` consumes the checkpoint BEFORE `resumeVM`, so a restore failure
104
+ * would otherwise strand the suspended work as `resolved` + unfindable (`findPendingTokenBySession` only
105
+ * matches `pending`). Reopening lets a retry re-resume the SAME work.
106
+ *
107
+ * design/80 D-1 (reopen-by-reason): the `reason` distinguishes the two triggers (both fire at core's
108
+ * runtask.ts) so the re-resume can validate per reason (§3 inv #1) — `env_failed` = the action is still
109
+ * valid, the re-resume MUST replay the persisted winner (core rejects a different decision with
110
+ * `checkpoint.reopen_revote`); `tool_unavailable` = the action could not run and may now be stale, so a
111
+ * FRESH decision is allowed (P-7). We RECORD the reason on the row and bump `rev` (so a concurrent resume's
112
+ * resolve CAS loses — atomicity). 🔴 We DELIBERATELY leave the persisted `outcome` UNTOUCHED (NOT stale junk
113
+ * as a pre-D-1 reopen treated it): `resolvedOutcome` derives from it on get(), and an `env_failed` re-resume
114
+ * is validated against it — clearing it would defeat the winner-replay invariant.
115
+ */
36
116
  reopen(token: CheckpointToken, scope: string, reason: ReopenReason): Promise<boolean>;
117
+ /**
118
+ * design/80 D-A (durable steering): park a steer message on a STILL-PENDING checkpoint (last-writer-wins),
119
+ * surfaced via get() as `state.pendingSteer` and injected on resume. CAS on `status='pending'` (+ scope) so a
120
+ * steer NEVER lands on a resolved/expired checkpoint and NEVER touches status/the resolve path (§3 inv #4).
121
+ * Returns the CAS winner (`true` = landed on a live pending checkpoint; `false` = no pending row to steer).
122
+ */
37
123
  setPendingSteer(token: CheckpointToken, scope: string, steer: {
38
124
  text: string;
39
125
  trusted: boolean;
40
126
  }): Promise<boolean>;
127
+ /**
128
+ * CAS-expire a SINGLE checkpoint by token (core 1.71 `CheckpointStore.expire`, for `TaskStream.destroy`'s
129
+ * suspended-worker reap — core [R33] {delta}). `pending → expired`, returns the CAS winner (true = we
130
+ * expired it; false = already resolved/expired). Same UPDATE as `reap`, keyed by **token** not deadline.
131
+ * It races the SAME `pending` row as `resolve`, so the two are mutually exclusive: destroy() must `expire`
132
+ * (fence) BEFORE destroying the env — if a concurrent resume already won `resolve`, expire returns false and
133
+ * destroy leaves the env for that resume; if expire wins, the resume's resolve fails → never resume-to-dead-env.
134
+ * Uses `expired` (not a `resolve`-deny) so a CANCELLED checkpoint never pollutes resolved-count / outcome.
135
+ */
41
136
  expire(token: CheckpointToken, scope: string): Promise<boolean>;
137
+ /** Interface reap: CAS-expire pending checkpoints in `scope` past `cutoff`. Returns count. */
42
138
  reap(scope: string, cutoff: number): Promise<number>;
139
+ /**
140
+ * GLOBAL sweep for the service's per-replica TTL reaper (expiry isn't tenant-
141
+ * sensitive — only `resolve` is scoped). Idempotent across replicas (DB serializes; no election). Returns count.
142
+ * Called with `cutoff = Date.now()` (deadline/terminal_at are ABSOLUTE epoch-ms), so it expires any pending row
143
+ * whose per-approval `deadline` OR its design/80 D-1 §3-inv#3 `terminal_at` crash-safe backstop has passed —
144
+ * the latter closes the forever-leak of a pending row with a NULL `deadline` (no approval TTL was configured).
145
+ *
146
+ * design/80 D-D: the deadline-branch EXPIRES (≈ abort) every kind EXCEPT a tool-approval human/irreversible_ask
147
+ * gate — those are resolve-DENIED gracefully by the SLA deny-sweep (listExpiredApprovalGates →
148
+ * resumeCheckpoint(deny)), so expiring them here too would race + lose the graceful denial. 🔴 A durable
149
+ * AskUserQuestion ALSO mints gate.kind='human' (no question-specific kind in core) — but DENYING a question is
150
+ * incoherent (the model gets a "denied" tool-result, not an answer), so it is carved BACK INTO the expire path
151
+ * (COALESCE(tool_name,'')='AskUserQuestion') to abort-expire on timeout instead. Legacy rows (gate_kind NULL)
152
+ * stay on the expire path. The terminal_at-branch is the crash-safe backstop for ANY kind (incl. a human gate
153
+ * whose deny-resume keeps failing) — it always abort-expires past the absolute cap (which is now STRICTLY after
154
+ * the deadline, so it never races the deny-sweep at the deadline instant).
155
+ */
43
156
  reapExpired(cutoff: number): Promise<number>;
157
+ /**
158
+ * design/80 D-D (SLA-timer): the sessions of pending human/irreversible_ask checkpoints past their `deadline`
159
+ * (the per-approval SLA). The reaper resolve-DENIES each (re-resume with decision=deny → the model continues
160
+ * with the denial) — graceful, vs the abort that expire() gives resource_limit/needs_review. Excludes legacy
161
+ * rows (gate_kind NULL — they predate the split and fall through to reapExpired's expire path). LIMIT bounds
162
+ * the per-tick deny-resume work (each is a model run). Scope is read off the COMMITTED row (invariant #4).
163
+ * 🔴 EXCLUDES AskUserQuestion gates (which also mint gate.kind='human'): denying a question is incoherent —
164
+ * the model would get a "denied" tool-result instead of an answer — so a timed-out durable question falls to
165
+ * reapExpired's abort-expire path instead of this graceful-deny path.
166
+ */
44
167
  listExpiredApprovalGates(cutoff: number, limit?: number): Promise<Array<{
45
168
  sessionId: string;
46
169
  scope: string;
47
170
  }>>;
171
+ /** Pending checkpoints for the operator queue — NON-secret fields only (never the token). `taskId` is
172
+ * joined from task_active (the JOIN KEY to the run/trace — a suspended run KEEPS its
173
+ * session claim, so the join is live for every pending row; null only in pathological windows). */
48
174
  listPending(scope?: string): Promise<PendingCheckpoint[]>;
175
+ /**
176
+ * design/80 #2 (scheduler seam, core 1.105): a scope's PENDING checkpoints as lightweight
177
+ * {@link CheckpointSummary} rows in ONE query — the cross-task triage view a supervisor scheduler needs
178
+ * (gate kind + risk severity + budget spent + deadline per suspended task), no N+1 `get`s. The projection is
179
+ * core's shared {@link summarizeCheckpoint} run over the persisted blob (the `checkpoint` column = the same full
180
+ * {@link Checkpoint} `get()` parses), so this stays byte-identical to core's InMemory/Pg/File impls. Order =
181
+ * created_at ASC; callers (the inbox/scheduler) sort by severity. The COLUMN `status` is authoritative (the blob
182
+ * is the suspend-time snapshot), so it overrides the blob's status before the summary is derived.
183
+ *
184
+ * LIMIT bounds the fan-out (review w16yqkkxv): a triage view never needs more than a few — 500 is a generous
185
+ * ceiling that still protects memory/latency if a scope ever accumulates pathologically many pending gates.
186
+ */
49
187
  listByScope(scope: string): Promise<CheckpointSummary[]>;
188
+ /**
189
+ * Map a session (the non-secret handle the operator decides by) → its single pending checkpoint token,
190
+ * INTERNALLY. A suspended session has exactly one pending checkpoint. `scope` is enforced so an operator
191
+ * can only resolve within its own tenant. Returns null if there is no pending checkpoint for that session/scope.
192
+ */
50
193
  findPendingTokenBySession(sessionId: string, scope?: string): Promise<CheckpointToken | null>;
194
+ /**
195
+ * The owner SCOPE of a session's pending checkpoint (the multi-tenant key === the owner principal in the
196
+ * BFF/non-operator flow, the same key listPending filters by). For the /decide owner-gate: a non-operator
197
+ * caller may only decide a checkpoint in their OWN scope. Returns `undefined` (no pending row), `null`
198
+ * (anonymous/dev session — open), or the owner scope string.
199
+ */
51
200
  peekPendingScope(sessionId: string): Promise<string | null | undefined>;
201
+ /** Upsert the resume rebuild inputs for a session (written at SUBMIT when durable mode is on). */
52
202
  putCtx(sessionId: string, ctx: unknown): Promise<void>;
53
203
  getCtx<T = unknown>(sessionId: string): Promise<T | null>;
204
+ /**
205
+ * GC ctx rows whose lifecycle is over (bound to the checkpoint, don't leak):
206
+ * a session with NO pending checkpoint, NO active run, AND not touched since `cutoff`.
207
+ *
208
+ * The extra `task_active` guard closes a multi-gate window: between a resume's CAS (pending→resolved) and
209
+ * the task hitting its NEXT gate (writing a new pending checkpoint), the session has no pending checkpoint —
210
+ * yet `putCtx` only stamps `updated_at` at submit, so the ctx could be older than `cutoff` and was being
211
+ * reaped, making the next resume 409 ("resume context missing"). `task_active` holds the session lock for
212
+ * the WHOLE submit→last-resume-complete span (running OR suspended), so excluding sessions with an active
213
+ * claim keeps the ctx exactly as long as a run still needs it, while still GC'ing it once the run is terminal.
214
+ */
54
215
  reapCtx(cutoff: number): Promise<number>;
216
+ /**
217
+ * E21 (§0.5 session delete) — purge ALL checkpoint state for one session: the durable checkpoint rows
218
+ * (suspended-task gates) AND their service-side resume-context rows (checkpoint_ctx). Keyed on the
219
+ * `session_id` column both tables carry. Idempotent (returns the count of `checkpoint` rows removed).
220
+ * Unconditional by design: a session being deleted has no resumable future, so any pending gate is moot.
221
+ *
222
+ * `owner` is a single-DB-fleet defense-in-depth guard (adversarial-review MEDIUM). Neither table carries an
223
+ * owner column, so the guard threads through `session_meta.owner` via an EXISTS sub-select (null-safe compare:
224
+ * `<=>` on TiDB, `IS NOT DISTINCT FROM` on PG). The purge coordinator runs this BEFORE deleting session_meta,
225
+ * so the meta row (with its authoritative owner) is still present here — a wrong-owner caller's EXISTS fails
226
+ * and purges nothing. `owner=null` (legacy/dev, never threaded by the route) keeps the historical
227
+ * unconditional behaviour via the null-safe match.
228
+ *
229
+ * 🔴 Placeholder ARITY differs, not just the syntax: `?` cannot be reused, so the TiDB arm binds `sessionId`
230
+ * TWICE (row key + guard sub-select) while PG reuses `$1`.
231
+ */
55
232
  deleteBySession(sessionId: string, owner: string | null): Promise<number>;
56
233
  }
234
+ /** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
57
235
  export declare class TiDBCheckpointStore extends SqlCheckpointStore {
58
236
  constructor(pool: MySqlPool, logger?: {
59
237
  info?(msg: string, meta?: unknown): void;
60
238
  });
61
239
  }
240
+ /** PostgreSQL binding — historical class name + ctor shape preserved. */
62
241
  export declare class PgCheckpointStore extends SqlCheckpointStore {
63
242
  constructor(pool: PgPool, logger?: {
64
243
  info?(msg: string, meta?: unknown): void;