@sema-agent/server 7.43.0 → 7.44.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 (345) hide show
  1. package/USAGE.md +18 -0
  2. package/dist/adoption/plan.js +31 -192
  3. package/dist/adoption/quiesce.js +3 -86
  4. package/dist/adoption/runner.js +3 -140
  5. package/dist/adoption/sql.js +0 -74
  6. package/dist/adoption/wire.js +0 -80
  7. package/dist/approval-ask-machine.js +0 -75
  8. package/dist/approval-card.js +0 -323
  9. package/dist/approval-deny-reasons.js +0 -42
  10. package/dist/approval-hmac.js +0 -35
  11. package/dist/approval-reconciler.js +8 -166
  12. package/dist/approval.js +4 -67
  13. package/dist/audit.js +1 -44
  14. package/dist/auth-bridge.js +4 -47
  15. package/dist/auth-keys.js +0 -23
  16. package/dist/bake-runner/main.js +4 -65
  17. package/dist/bake-runner/protocol.js +3 -58
  18. package/dist/bake-runner/runner.js +5 -91
  19. package/dist/bench/l8/artifact.js +2 -61
  20. package/dist/bench/l8/escape.js +0 -25
  21. package/dist/bench/l8/index.js +0 -14
  22. package/dist/bench/l8/probes.js +0 -60
  23. package/dist/bench/l8/run-probes.js +2 -45
  24. package/dist/bench/s1/arms.js +14 -189
  25. package/dist/bench/s1/live-deps.js +11 -253
  26. package/dist/bench/s1/oracle.js +1 -36
  27. package/dist/bench/s1/repair-oracle-adapter.js +0 -30
  28. package/dist/bench/s1/reviewer.js +0 -34
  29. package/dist/bench/s1/row.js +0 -62
  30. package/dist/bench/s1/run-firm.js +4 -70
  31. package/dist/bench/s1/runner-ctx.js +0 -40
  32. package/dist/bench/s1/tasks.js +0 -115
  33. package/dist/boot/adoption.js +0 -20
  34. package/dist/boot/budget-tracing.js +3 -55
  35. package/dist/boot/config-center.js +43 -551
  36. package/dist/boot/coordinators.js +1 -69
  37. package/dist/boot/crash-last.js +0 -18
  38. package/dist/boot/deferred-sandbox-path-env.js +3 -119
  39. package/dist/boot/execution-env.js +5 -171
  40. package/dist/boot/governance-seams.js +0 -92
  41. package/dist/boot/leader.js +0 -69
  42. package/dist/boot/limit-sync.js +0 -2
  43. package/dist/boot/memory-boundary.js +3 -91
  44. package/dist/boot/org-memory.js +1 -25
  45. package/dist/boot/parked-revive-gate.js +0 -150
  46. package/dist/boot/permission-rules-audit.js +1 -56
  47. package/dist/boot/reapers.js +15 -273
  48. package/dist/boot/resolve-spec.js +9 -768
  49. package/dist/boot/retention-lane.js +4 -87
  50. package/dist/boot/runner-deps.js +3 -297
  51. package/dist/boot/runtime-caps.js +0 -40
  52. package/dist/boot/session-faces.js +2 -133
  53. package/dist/boot/shutdown.js +9 -83
  54. package/dist/boot/side-query-lane.js +2 -137
  55. package/dist/boot/stores.js +15 -215
  56. package/dist/boot/task-list-lane.js +0 -18
  57. package/dist/boot/webfetch-summarize-lane.js +0 -47
  58. package/dist/boot/workflow-orchestration.js +3 -99
  59. package/dist/boot-reclaim.js +0 -20
  60. package/dist/bounded-session-map.js +0 -19
  61. package/dist/brain.js +2 -139
  62. package/dist/budget.js +9 -244
  63. package/dist/capabilities/builtin-tools.js +0 -3
  64. package/dist/capabilities/center-plugins.js +6 -51
  65. package/dist/capabilities/center-prompts.js +6 -71
  66. package/dist/capabilities/code-review-council.js +7 -40
  67. package/dist/capabilities/collab-workflows.js +1 -44
  68. package/dist/capabilities/hands-lane.js +0 -65
  69. package/dist/capabilities/memory-notice.js +0 -70
  70. package/dist/capabilities/prompt.js +0 -14
  71. package/dist/capabilities/prompts/code-review.js +0 -14
  72. package/dist/capabilities/prompts/identity.js +0 -6
  73. package/dist/capabilities/prompts/team.js +0 -4
  74. package/dist/capabilities/repo-tools.js +0 -34
  75. package/dist/capabilities/sandbox-file-send.js +3 -92
  76. package/dist/capabilities/scenarios.d.ts +0 -1
  77. package/dist/capabilities/scenarios.js +18 -279
  78. package/dist/capabilities/select-environment-tool.js +0 -32
  79. package/dist/capabilities/send-user-file-tool.js +2 -66
  80. package/dist/capabilities/skills.d.ts +1 -2
  81. package/dist/capabilities/skills.js +3 -21
  82. package/dist/capabilities/team.d.ts +3 -11
  83. package/dist/capabilities/team.js +3 -51
  84. package/dist/capabilities/tool-defer.js +0 -3
  85. package/dist/config-center/apply-effective.js +15 -330
  86. package/dist/config-center/apply-ledger.js +5 -38
  87. package/dist/config-center/facade.js +0 -41
  88. package/dist/config-center/hot-keys-registry.js +0 -20
  89. package/dist/config-center/http-client.js +2 -125
  90. package/dist/config-center/mcp-revocation.js +2 -34
  91. package/dist/config-center/read-face.js +0 -59
  92. package/dist/config-center/restart-signal.js +1 -85
  93. package/dist/config-center/skills-mcp.d.ts +1 -1
  94. package/dist/config-center/skills-mcp.js +9 -76
  95. package/dist/config-center/stage-limits.js +8 -35
  96. package/dist/config-invariants.js +0 -16
  97. package/dist/config-lkg.js +0 -42
  98. package/dist/config-provider.js +3 -186
  99. package/dist/config-types.js +0 -5
  100. package/dist/config.js +107 -1145
  101. package/dist/degenerate-instrument.js +3 -67
  102. package/dist/deployment-governance.js +0 -124
  103. package/dist/digest-form.js +0 -12
  104. package/dist/elicitation.js +3 -86
  105. package/dist/env-facts.js +7 -75
  106. package/dist/fleet/fleet-bus.js +34 -507
  107. package/dist/fleet/fleet-reconciler.js +9 -149
  108. package/dist/fleet/fleet-terminal-window.js +10 -178
  109. package/dist/fleet/subagent-tail-bus.js +3 -72
  110. package/dist/fleet-client.js +10 -70
  111. package/dist/fleet-lease.js +5 -79
  112. package/dist/git-api-kind.js +0 -3
  113. package/dist/governance-ask-marks.js +2 -78
  114. package/dist/hooks/branch-transcript.js +0 -74
  115. package/dist/hooks/cc-agent-hook-prompt.js +0 -29
  116. package/dist/hooks/cc-stop-prompt.js +1 -46
  117. package/dist/hooks/hook-llm.js +1 -53
  118. package/dist/hooks/hook-runner.js +20 -414
  119. package/dist/http/active-run-conflict.js +4 -129
  120. package/dist/http/cursor-fingerprint.d.ts +5 -0
  121. package/dist/http/cursor-fingerprint.js +5 -0
  122. package/dist/http/idempotency.js +0 -37
  123. package/dist/http/principal-gate.js +3 -40
  124. package/dist/http/route-ctx.js +0 -9
  125. package/dist/http/routes/a2a-serve.js +7 -319
  126. package/dist/http/routes/admin-config-refresh.js +0 -4
  127. package/dist/http/routes/admin-drain.js +0 -10
  128. package/dist/http/routes/adoption.js +1 -29
  129. package/dist/http/routes/agents-roster.js +1 -47
  130. package/dist/http/routes/approvals-assistant.js +32 -395
  131. package/dist/http/routes/attachments.js +4 -22
  132. package/dist/http/routes/capabilities.js +3 -420
  133. package/dist/http/routes/diagnostics.js +1 -81
  134. package/dist/http/routes/fleet.js +9 -185
  135. package/dist/http/routes/images.js +14 -239
  136. package/dist/http/routes/leader.js +0 -13
  137. package/dist/http/routes/memory-bundle.js +1 -61
  138. package/dist/http/routes/memory-policy.js +9 -99
  139. package/dist/http/routes/notify-wake.js +3 -37
  140. package/dist/http/routes/observability.js +2 -19
  141. package/dist/http/routes/retention-ops.js +2 -34
  142. package/dist/http/routes/rules.js +1 -93
  143. package/dist/http/routes/runs.js +64 -873
  144. package/dist/http/routes/session-sync.js +19 -258
  145. package/dist/http/routes/sessions-list.js +17 -43
  146. package/dist/http/routes/sessions.js +34 -226
  147. package/dist/http/routes/shared-memory.js +5 -36
  148. package/dist/http/routes/side-query.js +1 -87
  149. package/dist/http/routes/tasks.js +52 -722
  150. package/dist/http/routes/trace-usage.js +32 -195
  151. package/dist/http/routes/workflows.js +19 -195
  152. package/dist/http/run-meta.js +0 -6
  153. package/dist/http/send.js +0 -32
  154. package/dist/http/server.js +92 -1597
  155. package/dist/http/sse-lifecycle.js +2 -13
  156. package/dist/http/sse-log.js +3 -48
  157. package/dist/http/tar.js +5 -21
  158. package/dist/http/verify-rounds.js +0 -5
  159. package/dist/http/wire-gate.js +0 -9
  160. package/dist/http/workspace-content.js +0 -10
  161. package/dist/images/bake-validate.js +1 -70
  162. package/dist/images/manifest.js +1 -6
  163. package/dist/index.js +0 -21
  164. package/dist/key-resolver.js +2 -17
  165. package/dist/leader/diffout.js +1 -20
  166. package/dist/leader/diffup.js +0 -47
  167. package/dist/leader/endpoint.js +2 -57
  168. package/dist/leader/fanout.js +3 -45
  169. package/dist/leader/grader-env-factory.js +3 -72
  170. package/dist/leader/leader.js +5 -156
  171. package/dist/leader/merge.js +8 -115
  172. package/dist/leader/planner.js +3 -54
  173. package/dist/leader/repair-oracle.js +1 -60
  174. package/dist/leader/repair-wire.js +2 -79
  175. package/dist/leader/wire.js +8 -307
  176. package/dist/lsp/e2b-bridge.js +4 -64
  177. package/dist/lsp/e2b-manager.js +6 -94
  178. package/dist/lsp/lsp-frames.js +0 -12
  179. package/dist/lsp/manager.js +4 -96
  180. package/dist/lsp/ws-transport.js +5 -55
  181. package/dist/lsp-evict.js +1 -15
  182. package/dist/main.js +57 -765
  183. package/dist/memory-bundle-engine.js +0 -55
  184. package/dist/memory-export.js +0 -4
  185. package/dist/memory-posture.js +1 -15
  186. package/dist/memory-scope.js +11 -148
  187. package/dist/memory-sync-client.js +2 -44
  188. package/dist/memory-sync.js +1 -80
  189. package/dist/model-select.js +3 -80
  190. package/dist/observability/cost-quota.js +1 -17
  191. package/dist/observability/cost-taxonomy.js +0 -34
  192. package/dist/observability/fail-open.js +7 -86
  193. package/dist/observability/logger.js +0 -6
  194. package/dist/observability/metrics.js +0 -94
  195. package/dist/observability/otel-exporter.js +3 -13
  196. package/dist/observability/principal-context.js +0 -9
  197. package/dist/observability/prompt-manifest.js +1 -37
  198. package/dist/observability/rate-limit.js +0 -4
  199. package/dist/observability/secret-env-scrub.js +2 -56
  200. package/dist/observability/tool-trace.js +1 -70
  201. package/dist/orchestration/hardened-vm-runner.js +4 -118
  202. package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
  203. package/dist/orchestration/hardened-vm-worker.js +0 -27
  204. package/dist/orchestration/subagent-steer.js +1 -45
  205. package/dist/orchestration/workflow-agent-steer.js +1 -80
  206. package/dist/orchestration/workflow-completion-inbox.js +32 -285
  207. package/dist/orchestration/workflow-notify-journal.js +16 -259
  208. package/dist/org-memory-admission.js +3 -47
  209. package/dist/parent-watch.js +2 -48
  210. package/dist/parked-decide.js +1 -109
  211. package/dist/per-task-image.js +0 -57
  212. package/dist/plan-cache-probe.js +3 -27
  213. package/dist/plugins/adoption-log-sql.js +2 -119
  214. package/dist/plugins/approval-ask-store-memory.js +3 -38
  215. package/dist/plugins/approval-ask-store-sql.js +6 -188
  216. package/dist/plugins/approval-exemption-store.js +2 -28
  217. package/dist/plugins/background-agent-store-sql.js +4 -105
  218. package/dist/plugins/background-shell-support.js +14 -122
  219. package/dist/plugins/blob-backend.js +6 -169
  220. package/dist/plugins/breaker-state-sql.js +8 -46
  221. package/dist/plugins/caching-session-store.js +4 -106
  222. package/dist/plugins/checkpoint-store-sql.js +18 -505
  223. package/dist/plugins/e2b-orphan-reclaim.js +0 -45
  224. package/dist/plugins/file-outcome-sink.js +0 -9
  225. package/dist/plugins/file-resume-anchor-store.js +4 -43
  226. package/dist/plugins/file-run-store.js +26 -364
  227. package/dist/plugins/file-snapshot-store-sql.js +10 -181
  228. package/dist/plugins/fork-routing-session-store.js +8 -111
  229. package/dist/plugins/host-platform.js +2 -91
  230. package/dist/plugins/image-bake-store-sql.js +7 -250
  231. package/dist/plugins/image-index-sql.js +4 -123
  232. package/dist/plugins/k8s-bg-scripts.js +4 -88
  233. package/dist/plugins/k8s-exec-protocol.js +0 -41
  234. package/dist/plugins/leader-run-store-sql.js +0 -101
  235. package/dist/plugins/local-checkpoint-store.js +8 -128
  236. package/dist/plugins/local-session-store.js +34 -296
  237. package/dist/plugins/local-task-attachment-store.js +2 -16
  238. package/dist/plugins/mailbox-store-sql.js +8 -65
  239. package/dist/plugins/memory-embedder-fingerprint.js +5 -166
  240. package/dist/plugins/memory-embedder.js +4 -70
  241. package/dist/plugins/memory-engine-pg.js +6 -170
  242. package/dist/plugins/memory-engine-tidb.js +7 -155
  243. package/dist/plugins/memory-engine-vector-util.js +0 -10
  244. package/dist/plugins/memory-key-guards.js +0 -34
  245. package/dist/plugins/memory-origin-law.js +0 -187
  246. package/dist/plugins/memory-resume-anchor-store.js +0 -17
  247. package/dist/plugins/memory-run-store.js +12 -89
  248. package/dist/plugins/memory-session-policy-store.js +0 -17
  249. package/dist/plugins/memory-sync-store-pg.js +4 -49
  250. package/dist/plugins/memory-sync-store-tidb.js +3 -35
  251. package/dist/plugins/outcome-ledger-sql.js +3 -97
  252. package/dist/plugins/permission-rule-store-file.js +5 -133
  253. package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
  254. package/dist/plugins/permission-rule-store-sql.js +50 -307
  255. package/dist/plugins/pg-cost-quota.js +0 -7
  256. package/dist/plugins/pg-pool.js +0 -92
  257. package/dist/plugins/pg-rate-limiter.js +2 -13
  258. package/dist/plugins/pg-safe-json.js +4 -40
  259. package/dist/plugins/pg-session-storage.js +25 -189
  260. package/dist/plugins/posix-shell-fs.js +1 -31
  261. package/dist/plugins/remote-env-adb.js +12 -101
  262. package/dist/plugins/remote-env-e2b.js +40 -371
  263. package/dist/plugins/remote-env-file-error.js +0 -37
  264. package/dist/plugins/remote-env-host.js +63 -483
  265. package/dist/plugins/remote-env-k8s.js +32 -326
  266. package/dist/plugins/remote-env-local-docker.js +24 -157
  267. package/dist/plugins/remote-env-ssh.js +20 -128
  268. package/dist/plugins/remote-scratchpad.js +2 -32
  269. package/dist/plugins/remote-shell.js +1 -32
  270. package/dist/plugins/resume-anchor-store-sql.js +0 -11
  271. package/dist/plugins/retention-lane-store-sql.js +0 -108
  272. package/dist/plugins/retention-store-sql.js +4 -383
  273. package/dist/plugins/roster-store-sql.js +0 -55
  274. package/dist/plugins/run-store-sql.js +14 -251
  275. package/dist/plugins/s3-presign.js +2 -49
  276. package/dist/plugins/scheduler-support.js +3 -80
  277. package/dist/plugins/send-file-ledger.js +4 -53
  278. package/dist/plugins/send-user-file.js +4 -94
  279. package/dist/plugins/session-placement.js +1 -89
  280. package/dist/plugins/session-policy-store-sql.js +3 -81
  281. package/dist/plugins/session-store.js +0 -57
  282. package/dist/plugins/shared-memory-store-sql.js +4 -167
  283. package/dist/plugins/sql-driver.js +0 -17
  284. package/dist/plugins/sql-errors.js +0 -7
  285. package/dist/plugins/sql-escape.js +0 -8
  286. package/dist/plugins/sql-row-helpers.js +0 -25
  287. package/dist/plugins/store-backend.js +42 -222
  288. package/dist/plugins/store-contracts.js +2 -46
  289. package/dist/plugins/task-attachment-store.js +3 -49
  290. package/dist/plugins/task-list-store-sql.js +0 -79
  291. package/dist/plugins/tidb-cost-quota.js +1 -4
  292. package/dist/plugins/tidb-pool.js +1 -207
  293. package/dist/plugins/tidb-rate-limiter.js +3 -9
  294. package/dist/plugins/tidb-session-storage.js +4 -70
  295. package/dist/plugins/tidb-session-store.js +19 -341
  296. package/dist/plugins/tool-result-store-sql.js +4 -179
  297. package/dist/plugins/usage-window-store-sql.js +0 -8
  298. package/dist/plugins/web-search.js +10 -132
  299. package/dist/plugins/workflow-journal-store-sql.js +2 -58
  300. package/dist/plugins/workflow-run-store-sql.js +6 -91
  301. package/dist/plugins/worktree-isolation.js +6 -126
  302. package/dist/plugins/write-behind-counter.js +16 -75
  303. package/dist/principal-jwt.js +5 -60
  304. package/dist/project-memory.js +15 -146
  305. package/dist/prompts-domain-validate.js +1 -51
  306. package/dist/question.js +2 -111
  307. package/dist/resource-suspend.js +0 -18
  308. package/dist/router/route-orchestration.js +0 -77
  309. package/dist/rules-consent.d.ts +44 -5
  310. package/dist/rules-consent.js +75 -215
  311. package/dist/run-local.js +14 -381
  312. package/dist/runs.js +29 -617
  313. package/dist/runtime-caps-resolver.js +6 -132
  314. package/dist/runtime-governance.js +1 -232
  315. package/dist/sandbox-pkg-source.js +0 -37
  316. package/dist/sealed-key.js +3 -68
  317. package/dist/security.js +6 -291
  318. package/dist/session-leaf-bus.js +0 -32
  319. package/dist/session-sync-content.js +1 -69
  320. package/dist/session-sync-kernel.js +3 -60
  321. package/dist/session-sync.js +3 -66
  322. package/dist/session-titler.js +7 -41
  323. package/dist/session-watch.js +9 -73
  324. package/dist/shared-memory-scope-authorizer.js +0 -18
  325. package/dist/sighup-idle.js +1 -12
  326. package/dist/spec-fields.js +4 -143
  327. package/dist/store-live-probe.js +3 -49
  328. package/dist/task-a2a.js +1 -126
  329. package/dist/task-cwd.js +1 -103
  330. package/dist/task-mcp.js +1 -89
  331. package/dist/task-settings.js +10 -300
  332. package/dist/task-workflow.js +8 -75
  333. package/dist/tool-approval.d.ts +28 -1
  334. package/dist/tool-approval.js +70 -1430
  335. package/dist/trace/artifacts.js +5 -20
  336. package/dist/trace/engine-notice-wire.js +6 -138
  337. package/dist/trace/ledger-sink.js +7 -96
  338. package/dist/trace/project.js +4 -448
  339. package/dist/trace/redact.js +9 -77
  340. package/dist/turn-activity.js +1 -27
  341. package/dist/usage-analytics.js +4 -34
  342. package/dist/wall-clock-jump-guard.js +1 -68
  343. package/package.json +3 -3
  344. package/dist/capabilities/scenario-alias.d.ts +0 -27
  345. package/dist/capabilities/scenario-alias.js +0 -61
@@ -1,43 +1,10 @@
1
- /**
2
- * #242([3738] / design/242 v1)— E2B 孤儿沙盒回收。
3
- *
4
- * 病:server 进程崩溃(SIGKILL/OOM)后 core Runner 的 `destroy()` 不跑,E2B 沙盒按自己的
5
- * timeout 窗继续存活计费;崩溃循环下泄漏累积。create 侧的归属打标早已在
6
- * (`remote-env-e2b.ts` factory:metadata 带 sessionId/taskId,本批补 `semaManaged:"1"`);
7
- * 本模块是缺的另一半——回收腿。
8
- *
9
- * 判据(全部保守方向,**拿不准恒不杀**——回收是清理型能力,缺席判据=不动作,方向纪律见
10
- * memory `capability-probe-fail-direction`;误杀的代价是杀死一个活任务的手,漏杀的代价只是钱):
11
- * a. `metadata.semaManaged !== "1"` → 非我方铸造,provider 侧 query 过滤已排除;防御性重验。
12
- * b. `metadata.taskId` 缺席 → 病态形(factory 恒打标),不杀 + failOpen 留痕。
13
- * c. run 行在场:
14
- * LIVE 词(running/suspended/needs_review)→ 活,跳过;
15
- * TERMINAL 词 → 孤儿,kill;
16
- * 两表皆不中的词 → 词表纪律(#157):不杀 + failOpen(新词先安全后收编)。
17
- * d. 行不存在:
18
- * startedAt 距今 < GRACE → create→行落库窗口,跳过(防误杀新沙盒);
19
- * ≥ GRACE → 真孤儿,kill(单库 fleet 方向下行跨副本可见)。
20
- * e. `getRun` 抛错 → 不杀 + failOpen(不知道 ≠ 孤儿)。
21
- *
22
- * v1 边界(design/242 §设计②,发车说明同步):跨部署**异库**共用一把 E2B key 的形不支持——
23
- * 别家沙盒的 taskId 在本库查不到行,超 GRACE 会被误杀;前置=每部署独立 E2B key(本就是推荐姿势)。
24
- * metadata 无跨重启稳定的部署标识可用(instanceId 每 boot 变,恰是要回收上一世代)是结构原因。
25
- *
26
- * kill 逐只 try/catch(一只失败不挡其余);list 整体失败由调用方(reaper throttled catch)兜底。
27
- */
28
1
  import { recordFailOpen } from "../observability/fail-open.js";
29
- /** create→run 行落库窗口的误杀护栏。非行为表态面,常量不设旋钮(理由:它只需要「远大于一次
30
- * create+首写延迟、远小于沙盒 timeout 窗」,10min 对两端都有量级余量;错设它的运维事故面比
31
- * 它保护的窗口更大)。 */
32
2
  export const E2B_ORPHAN_GRACE_MS = 10 * 60 * 1000;
33
- /** factory 打进 metadata 的归属标(create 半场,remote-env-e2b.ts);值恒 "1"。 */
34
3
  export const SEMA_MANAGED_METADATA_KEY = "semaManaged";
35
- // 构造侧 satisfies 锚类型真源;容器声明 ReadonlySet<string> 让消费侧(窄读口的 status: string)直判。
36
4
  const LIVE_STATUSES = new Set(["running", "suspended", "needs_review"]);
37
5
  const TERMINAL_STATUSES = new Set(["completed", "blocked", "failed"]);
38
6
  const _statusesCovered = true;
39
7
  void _statusesCovered;
40
- /** 一轮回收(boot 一次 + reaper interval 周期共用)。list 抛错穿透给调用方(reaper catch 族)。 */
41
8
  export async function reclaimOrphanE2bSandboxes(deps) {
42
9
  const now = deps.now ?? Date.now;
43
10
  const graceMs = deps.graceMs ?? E2B_ORPHAN_GRACE_MS;
@@ -45,14 +12,12 @@ export async function reclaimOrphanE2bSandboxes(deps) {
45
12
  const sandboxes = await deps.provider.listManaged();
46
13
  for (const sbx of sandboxes) {
47
14
  summary.scanned++;
48
- // a. 防御性重验(provider 装配侧已 query 过滤;fake/将来的宽 provider 不许绕过归属判别)。
49
15
  if (sbx.metadata[SEMA_MANAGED_METADATA_KEY] !== "1") {
50
16
  summary.skippedUnknown++;
51
17
  recordFailOpen("server.e2b.orphan-skip-unknown");
52
18
  continue;
53
19
  }
54
20
  const taskId = sbx.metadata.taskId;
55
- // b. 病态形:factory 恒打 taskId(ctx.taskId 缺席时连 sessionId 都在而 taskId 不在)——不杀,留痕。
56
21
  if (!taskId) {
57
22
  summary.skippedUnknown++;
58
23
  recordFailOpen("server.e2b.orphan-skip-unknown");
@@ -62,7 +27,6 @@ export async function reclaimOrphanE2bSandboxes(deps) {
62
27
  try {
63
28
  const run = await deps.runs.getRun(taskId);
64
29
  if (run === undefined) {
65
- // d. 无行:GRACE 内=create→落库窗口;超窗=真孤儿。
66
30
  verdict = now() - sbx.startedAt.getTime() < graceMs ? "grace" : "kill";
67
31
  }
68
32
  else if (LIVE_STATUSES.has(run.status)) {
@@ -72,12 +36,10 @@ export async function reclaimOrphanE2bSandboxes(deps) {
72
36
  verdict = "kill";
73
37
  }
74
38
  else {
75
- // c. 词表外的新词:不杀 + failOpen(先安全后收编;收编=上面两表加词,遗漏在 census 计数可见)。
76
39
  verdict = "unknown";
77
40
  }
78
41
  }
79
42
  catch {
80
- // e. store 读错:不知道 ≠ 孤儿。
81
43
  verdict = "unknown";
82
44
  }
83
45
  if (verdict === "live")
@@ -105,19 +67,12 @@ export async function reclaimOrphanE2bSandboxes(deps) {
105
67
  }
106
68
  return summary;
107
69
  }
108
- /** provider RPC 墙钟上限。🔴 codex 对抗复审 R2(验真后修):无超时的 list/kill 一次 provider 挂起会让
109
- * 调用方的重入旗永挂(finally 等的 promise 永不结算)⇒ 回收腿从此静默死掉。SDK 原生收
110
- * `requestTimeoutMs`(SandboxApiOpts),用它而非外包 race——超时语义留在 SDK 的连接层。 */
111
70
  const PROVIDER_RPC_TIMEOUT_MS = 30_000;
112
- /** 真实 provider(E2B SDK 包装)。SDK 静态面动态 import——回收腿只在 e2b 部署形挂载,
113
- * 非 e2b 形零加载(与 execution-env 的按需装配同姿势)。 */
114
71
  export function createE2bOrphanSandboxProvider(cfg) {
115
72
  return {
116
73
  async listManaged() {
117
74
  const { Sandbox } = await import("e2b");
118
75
  const out = [];
119
- // 服务端 metadata 过滤(SandboxListOpts.query.metadata,AND 语义);state 默认含 running+paused
120
- // ——paused 也计费存储位且同样是孤儿人群,刻意不收窄。
121
76
  const paginator = Sandbox.list({ apiKey: cfg.apiKey, requestTimeoutMs: PROVIDER_RPC_TIMEOUT_MS, query: { metadata: { [SEMA_MANAGED_METADATA_KEY]: "1" } } });
122
77
  while (paginator.hasNext) {
123
78
  const items = await paginator.nextItems();
@@ -1,18 +1,9 @@
1
- /**
2
- * design/73 §1 consumption, LOCAL lane — the File twin of the TiDB/Pg outcome ledgers for the single-user /
3
- * no-DB posture: append each core `TaskOutcome` fact VERBATIM to an owner-only JSONL ledger. Read-only v1
4
- * (dashboard/backtest dataset — mirrors the SQL ledgers' read-only red line); no query surface here, the
5
- * file IS the dataset. Non-load-bearing observability → no fsync (a crash may lose the tail fact; the run
6
- * itself is unaffected — same posture as metrics).
7
- */
8
1
  import { mkdirSync, appendFileSync } from "node:fs";
9
2
  import { join } from "node:path";
10
3
  export class FileOutcomeSink {
11
4
  path;
12
5
  constructor(root) {
13
6
  const dir = join(root, "outcomes");
14
- // 0o700 dir + 0o600 file: outcome facts carry model/taskSignature/oracle detail — operator-only, parity
15
- // with the other File ledgers' posture.
16
7
  mkdirSync(dir, { recursive: true, mode: 0o700 });
17
8
  this.path = join(dir, "outcomes.jsonl");
18
9
  }
@@ -1,47 +1,23 @@
1
- /**
2
- * File-backed resume-at anchor map (E18) — the DURABLE local twin of {@link MemoryResumeAnchorStore}, persisting the
3
- * service-owned eventId→entryId translation across a process restart (P0.5 variant-1, clay 2026-06-26; the file-backed
4
- * follow-on the Memory twin's header promised). Behaviour is byte-identical to the Memory store (put/resolve/
5
- * deleteBySession + the §0.5/2c `listBySession` add); the only difference is durability.
6
- *
7
- * Persistence: one append-only JSONL log per session at `<root>/resume-anchors/<sanitizePathComponent(sessionId)>.jsonl`,
8
- * each line `{eventId, entryId, owner, ts}`. `put` APPENDS (fsync:true — an anchor is a durable rewind boundary; a lost
9
- * anchor silently breaks the next rewind), and the in-memory index is upserted last-wins so a re-stamped eventId
10
- * overwrites (parity with the SQL ON DUPLICATE/CONFLICT). On construction the index is HYDRATED by replaying every
11
- * session log via core's `readJsonlRecords` (torn-tail-safe: a crash mid-append drops only the partial last line, and a
12
- * later `put` re-records it). `resolve`/`listBySession` read the in-memory index (O(1)/O(per-session)); `deleteBySession`
13
- * unlinks the file + drops the index entry. owner null-safe guard (`(a??null)===(b??null)`) = the SQL `owner <=> ?`
14
- * defense-in-depth twin. Single-process (the FileStorageBackend boot lock guarantees one writer per data dir), so there
15
- * is no per-op lock — the in-process model is the premise (core fs-atomic BootLock).
16
- */
17
1
  import { join } from "node:path";
18
2
  import { existsSync, readdirSync, rmSync } from "node:fs";
19
3
  import { AppendLog, ensureDir, readJsonlRecords, sanitizePathComponent } from "@sema-agent/core";
20
- /** Null-safe owner equality — the JS twin of the SQL `owner <=> ?` guard (a legacy null-owner anchor matches owner=null). */
21
4
  const ownerEq = (a, b) => (a ?? null) === (b ?? null);
22
5
  export class FileResumeAnchorStore {
23
6
  dir;
24
- /** sessionId → (eventId → {entryId, owner}) — the same in-memory shape MemoryResumeAnchorStore holds, hydrated on ctor. */
25
7
  bySession = new Map();
26
- /** sessionId → the open append log (one O_APPEND fd per session, lazily opened on first put, held for lifetime). */
27
8
  logs = new Map();
28
9
  constructor(root) {
29
10
  this.dir = join(root, "resume-anchors");
30
11
  ensureDir(this.dir);
31
12
  this.hydrate();
32
13
  }
33
- /** `<dir>/<sanitizePathComponent(sessionId)>.jsonl` — the per-session log path (sessionId is uuidv7, already safe). */
34
14
  pathFor(sessionId) {
35
15
  return join(this.dir, `${sanitizePathComponent(sessionId)}.jsonl`);
36
16
  }
37
- /** Replay every session log into the in-memory index on boot (torn-tail-safe via readJsonlRecords; last-wins upsert
38
- * so a re-stamped eventId reflects the latest appended record). The in-memory index is keyed by the SANITIZED
39
- * sessionId throughout (put/resolve/list/delete all sanitize), and each on-disk file's base name IS
40
- * `sanitizePathComponent(sessionId)` — so the index key is just the file base, with no de-sanitize needed. */
41
17
  hydrate() {
42
18
  let names;
43
19
  try {
44
- names = readdirSync(this.dir); // a fresh root has the (just-ensured) empty dir → []
20
+ names = readdirSync(this.dir);
45
21
  }
46
22
  catch {
47
23
  return;
@@ -49,20 +25,19 @@ export class FileResumeAnchorStore {
49
25
  for (const name of names) {
50
26
  if (!name.endsWith(".jsonl"))
51
27
  continue;
52
- const key = name.slice(0, -".jsonl".length); // the file base IS sanitizePathComponent(sessionId) = the index key
28
+ const key = name.slice(0, -".jsonl".length);
53
29
  const records = readJsonlRecords(join(this.dir, name));
54
30
  if (!records.length)
55
31
  continue;
56
32
  const m = this.bySession.get(key) ?? new Map();
57
33
  for (const r of records) {
58
34
  if (!r || typeof r.eventId !== "string" || typeof r.entryId !== "string")
59
- continue; // skip a malformed record
60
- m.set(r.eventId, { entryId: r.entryId, owner: r.owner ?? null }); // last-wins upsert (replay order = append order)
35
+ continue;
36
+ m.set(r.eventId, { entryId: r.entryId, owner: r.owner ?? null });
61
37
  }
62
38
  this.bySession.set(key, m);
63
39
  }
64
40
  }
65
- /** Open (or reuse) the append log for a session. The file base is the SANITIZED id (matches hydrate's de-sanitize). */
66
41
  logFor(sessionId) {
67
42
  const key = sanitizePathComponent(sessionId);
68
43
  let log = this.logs.get(key);
@@ -72,9 +47,6 @@ export class FileResumeAnchorStore {
72
47
  }
73
48
  return log;
74
49
  }
75
- /** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL
76
- * ON DUPLICATE/CONFLICT). Appends a durable record (fsync:true) THEN upserts the index — a crash after the
77
- * fsync is recovered by hydrate (the record is on disk); a crash before it just loses an un-acked anchor. */
78
50
  async put(sessionId, eventId, entryId, owner) {
79
51
  const key = sanitizePathComponent(sessionId);
80
52
  this.logFor(sessionId).append({ eventId, entryId, owner: owner ?? null, ts: new Date().toISOString() }, true);
@@ -85,15 +57,10 @@ export class FileResumeAnchorStore {
85
57
  }
86
58
  m.set(eventId, { entryId, owner });
87
59
  }
88
- /** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
89
- * anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
90
60
  async resolve(sessionId, eventId, owner) {
91
61
  const e = this.bySession.get(sanitizePathComponent(sessionId))?.get(eventId);
92
62
  return e && ownerEq(e.owner, owner) ? e.entryId : undefined;
93
63
  }
94
- /** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
95
- * session EXPORT bundles the whole anchor map so the importer can RE-KEY owner to the target principal (§9). The
96
- * route already proved session ownership (the export gate), so no per-row owner filter here. Twin of the SQL stores. */
97
64
  async listBySession(sessionId) {
98
65
  const m = this.bySession.get(sanitizePathComponent(sessionId));
99
66
  if (!m)
@@ -103,9 +70,6 @@ export class FileResumeAnchorStore {
103
70
  out.push({ eventId, entryId: e.entryId, owner: e.owner });
104
71
  return out;
105
72
  }
106
- /** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
107
- * ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count).
108
- * Closes + unlinks the session log so the dir does not leak a file, and drops the in-memory index entry. */
109
73
  async deleteBySession(sessionId) {
110
74
  const key = sanitizePathComponent(sessionId);
111
75
  const removed = this.bySession.get(key)?.size ?? 0;
@@ -121,19 +85,16 @@ export class FileResumeAnchorStore {
121
85
  rmSync(path, { force: true });
122
86
  }
123
87
  catch {
124
- /* best-effort — a stale file is harmless (the index entry is already gone) */
125
88
  }
126
89
  }
127
90
  return removed;
128
91
  }
129
- /** Release every open append-log fd (called by LocalBackend.close so a graceful restart can re-open the data dir). */
130
92
  dispose() {
131
93
  for (const log of this.logs.values()) {
132
94
  try {
133
95
  log.close();
134
96
  }
135
97
  catch {
136
- /* best-effort */
137
98
  }
138
99
  }
139
100
  this.logs.clear();