@sema-agent/server 7.146.0 → 7.147.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 (398) hide show
  1. package/MIGRATION.md +384 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +170 -66
  5. package/deploy/facts/lanes.json +7 -0
  6. package/deploy/sema-up/README.md +2 -2
  7. package/deploy/sema-up/chart/templates/_helpers.tpl +22 -0
  8. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -4
  9. package/deploy/sema-up/chart/templates/server.yaml +5 -4
  10. package/deploy/sema-up/chart/values.yaml +1 -1
  11. package/deploy/sema-up/cluster-up.sh +2 -1
  12. package/deploy/sema-up/lib/flagshape.sh +4 -0
  13. package/deploy/sema-up/lib/lanes.json +2 -5
  14. package/deploy/sema-up/sema-up.sh +12 -9
  15. package/deploy/sema-up/stack/compose.yaml +5 -4
  16. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -3
  17. package/dist/approval-card.d.ts +4 -4
  18. package/dist/approval.d.ts +3 -3
  19. package/dist/audit.js +2 -2
  20. package/dist/bench/s1/live-deps.js +3 -1
  21. package/dist/boot/crash-last.js +2 -1
  22. package/dist/boot/device-lane.js +5 -5
  23. package/dist/boot/engine-lease.d.ts +12 -11
  24. package/dist/boot/execution-env.d.ts +2 -1
  25. package/dist/boot/execution-env.js +45 -33
  26. package/dist/boot/execution-lane.d.ts +37 -9
  27. package/dist/boot/execution-lane.js +74 -20
  28. package/dist/boot/exit-boundary.d.ts +1 -1
  29. package/dist/boot/exit-last.js +2 -1
  30. package/dist/boot/governance-seams.d.ts +2 -2
  31. package/dist/boot/leader.js +1 -1
  32. package/dist/boot/memory-boundary.d.ts +11 -11
  33. package/dist/boot/memory-boundary.js +3 -3
  34. package/dist/boot/memory-consolidation.d.ts +13 -24
  35. package/dist/boot/memory-consolidation.js +0 -13
  36. package/dist/boot/org-memory.js +3 -2
  37. package/dist/boot/parked-revive-gate.d.ts +1 -1
  38. package/dist/boot/parked-revive-gate.js +1 -1
  39. package/dist/boot/reapers.js +1 -1
  40. package/dist/boot/resolve-spec.js +91 -111
  41. package/dist/boot/retention-lane.d.ts +4 -42
  42. package/dist/boot/session-faces.d.ts +1 -0
  43. package/dist/boot/session-faces.js +8 -2
  44. package/dist/boot/stage-01-config.d.ts +1 -1
  45. package/dist/boot/stage-01-config.js +6 -2
  46. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
  47. package/dist/boot/stage-02-web-admin-pull.js +10 -8
  48. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  49. package/dist/boot/stage-04-stores.d.ts +1 -1
  50. package/dist/boot/stage-05-execution-env.d.ts +2 -2
  51. package/dist/boot/stage-05-execution-env.js +3 -3
  52. package/dist/boot/stage-06-runners.d.ts +3 -3
  53. package/dist/boot/stage-06-runners.js +1 -3
  54. package/dist/boot/stage-07-capability-layer.d.ts +3 -3
  55. package/dist/boot/stage-07-capability-layer.js +4 -9
  56. package/dist/boot/stage-08-reapers.d.ts +3 -3
  57. package/dist/boot/stage-09-leader.d.ts +4 -3
  58. package/dist/boot/stage-10-http-server.d.ts +4 -3
  59. package/dist/boot/stage-10-http-server.js +2 -1
  60. package/dist/boot/stores.d.ts +9 -0
  61. package/dist/boot/stores.js +18 -7
  62. package/dist/boot/web-admin.js +3 -3
  63. package/dist/capabilities/center-plugins.d.ts +2 -0
  64. package/dist/capabilities/center-plugins.js +6 -2
  65. package/dist/capabilities/composite-members.d.ts +1 -0
  66. package/dist/capabilities/composite-members.js +1 -0
  67. package/dist/capabilities/execution-lane.d.ts +7 -7
  68. package/dist/capabilities/execution-lane.js +2 -2
  69. package/dist/capabilities/hands-lane.d.ts +1 -1
  70. package/dist/capabilities/scenarios.d.ts +32 -18
  71. package/dist/capabilities/scenarios.js +13 -9
  72. package/dist/capabilities/settings-contract.d.ts +29 -0
  73. package/dist/capabilities/settings-contract.js +14 -0
  74. package/dist/capabilities/skills.d.ts +5 -5
  75. package/dist/capability-facts.d.ts +38 -0
  76. package/dist/capability-facts.js +34 -1
  77. package/dist/center-credential-renewer.js +3 -2
  78. package/dist/config-catalog.js +6 -5
  79. package/dist/config-invariants.d.ts +18 -3
  80. package/dist/config-invariants.js +36 -19
  81. package/dist/config-lkg.d.ts +1 -1
  82. package/dist/config-lkg.js +5 -6
  83. package/dist/config-provider.js +2 -0
  84. package/dist/config-types.d.ts +190 -186
  85. package/dist/config.d.ts +68 -5
  86. package/dist/config.js +80 -54
  87. package/dist/degenerate-instrument.js +1 -1
  88. package/dist/deploy-facts.js +3 -2
  89. package/dist/deployment-shape.d.ts +21 -12
  90. package/dist/deployment-shape.js +24 -6
  91. package/dist/env-facts.d.ts +7 -5
  92. package/dist/env-facts.js +10 -6
  93. package/dist/execution-config-root.d.ts +5 -5
  94. package/dist/execution-config-root.js +5 -5
  95. package/dist/execution-env-purpose.d.ts +14 -0
  96. package/dist/execution-env-purpose.js +29 -0
  97. package/dist/execution-lane-caps.d.ts +49 -86
  98. package/dist/execution-lane-caps.js +52 -62
  99. package/dist/execution-placement.d.ts +18 -2
  100. package/dist/execution-placement.js +19 -0
  101. package/dist/file-history-disclosure.d.ts +2 -2
  102. package/dist/fleet/drain-entry.d.ts +17 -10
  103. package/dist/fleet/drain-entry.js +1 -1
  104. package/dist/fleet/serving-lease.js +3 -4
  105. package/dist/history-anchor.d.ts +22 -0
  106. package/dist/history-anchor.js +14 -0
  107. package/dist/hooks/command-spawn.d.ts +1 -4
  108. package/dist/hooks/command-spawn.js +0 -11
  109. package/dist/hooks/hook-runner.d.ts +52 -8
  110. package/dist/hooks/hook-runner.js +160 -36
  111. package/dist/http/approval-sweeps.d.ts +2 -5
  112. package/dist/http/approval-sweeps.js +3 -2
  113. package/dist/http/checkpoint-ctx.d.ts +17 -0
  114. package/dist/http/checkpoint-ctx.js +6 -0
  115. package/dist/http/claim-latency.d.ts +10 -0
  116. package/dist/http/claim-latency.js +12 -0
  117. package/dist/http/dispatch.js +1 -1
  118. package/dist/http/durable-run-leg.js +2 -1
  119. package/dist/http/execution-context.d.ts +3 -1
  120. package/dist/http/execution-context.js +4 -0
  121. package/dist/http/memory-compliance-failure-reply.d.ts +1 -1
  122. package/dist/http/memory-compliance-failure-reply.js +3 -0
  123. package/dist/http/memory-store-refusal-reply.d.ts +3 -3
  124. package/dist/http/memory-store-refusal-reply.js +3 -0
  125. package/dist/http/owner-access.d.ts +11 -0
  126. package/dist/http/owner-access.js +7 -4
  127. package/dist/http/principal-gate.d.ts +3 -14
  128. package/dist/http/principal-gate.js +0 -13
  129. package/dist/http/request-guards.d.ts +1 -1
  130. package/dist/http/resume-legs.d.ts +7 -10
  131. package/dist/http/resume-legs.js +79 -50
  132. package/dist/http/rewind-files-reply.d.ts +34 -0
  133. package/dist/http/rewind-files-reply.js +36 -0
  134. package/dist/http/route-ctx.d.ts +32 -16
  135. package/dist/http/route-table.js +2 -0
  136. package/dist/http/routes/approvals-assistant.js +5 -25
  137. package/dist/http/routes/capabilities.js +8 -2
  138. package/dist/http/routes/devices.js +1 -1
  139. package/dist/http/routes/memory-origin.d.ts +1 -1
  140. package/dist/http/routes/notify-wake.js +2 -1
  141. package/dist/http/routes/projects.d.ts +70 -0
  142. package/dist/http/routes/projects.js +86 -0
  143. package/dist/http/routes/rules.js +30 -2
  144. package/dist/http/routes/runs.js +8 -8
  145. package/dist/http/routes/session-sync.js +27 -10
  146. package/dist/http/routes/sessions.d.ts +7 -1
  147. package/dist/http/routes/sessions.js +104 -2
  148. package/dist/http/routes/tasks.js +9 -3
  149. package/dist/http/server.d.ts +24 -10
  150. package/dist/http/server.js +17 -6
  151. package/dist/http/stored-body-replay.d.ts +5 -3
  152. package/dist/http/stored-body-replay.js +10 -1
  153. package/dist/http/wire-types.d.ts +19 -10
  154. package/dist/index.d.ts +2 -2
  155. package/dist/index.js +1 -1
  156. package/dist/instruction-source-notice.d.ts +1 -1
  157. package/dist/memory-embedder-reembed.d.ts +38 -0
  158. package/dist/memory-embedder-reembed.js +20 -0
  159. package/dist/memory-incident-sink.d.ts +0 -28
  160. package/dist/memory-incident-sink.js +5 -0
  161. package/dist/memory-scope.d.ts +2 -2
  162. package/dist/memory-scope.js +1 -1
  163. package/dist/memory-store-refusal.d.ts +17 -4
  164. package/dist/memory-store-refusal.js +1 -1
  165. package/dist/memory-sync-client.d.ts +2 -0
  166. package/dist/memory-sync-client.js +13 -11
  167. package/dist/memory-sync.js +1 -1
  168. package/dist/model-compat.d.ts +35 -21
  169. package/dist/model-compat.js +49 -21
  170. package/dist/model-entry-refusal.d.ts +11 -1
  171. package/dist/model-entry-refusal.js +7 -0
  172. package/dist/namespaced-rule-name.d.ts +18 -1
  173. package/dist/namespaced-rule-name.js +12 -0
  174. package/dist/observability/fail-open.d.ts +17 -9
  175. package/dist/observability/fail-open.js +17 -9
  176. package/dist/observability/metrics.d.ts +2 -0
  177. package/dist/observability/metrics.js +2 -0
  178. package/dist/observability/secret-env-scrub.d.ts +30 -4
  179. package/dist/observability/secret-env-scrub.js +15 -3
  180. package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
  181. package/dist/orchestration/workflow-agent-session-index.js +1 -6
  182. package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
  183. package/dist/orchestration/workflow-completion-inbox.js +63 -45
  184. package/dist/org-memory-admission.d.ts +5 -2
  185. package/dist/org-memory-admission.js +25 -10
  186. package/dist/parked-decide.d.ts +33 -26
  187. package/dist/parked-decide.js +36 -44
  188. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  189. package/dist/plugins/approval-ask-store-file.js +37 -4
  190. package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
  191. package/dist/plugins/approval-ask-store-memory.js +11 -2
  192. package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
  193. package/dist/plugins/approval-ask-store-sql.js +3 -1
  194. package/dist/plugins/blob-backend.d.ts +38 -195
  195. package/dist/plugins/blob-backend.js +33 -229
  196. package/dist/plugins/caching-session-store.d.ts +9 -4
  197. package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
  198. package/dist/plugins/checkpoint-index-columns.js +3 -2
  199. package/dist/plugins/checkpoint-store-face.d.ts +1 -1
  200. package/dist/plugins/device-store-sql.d.ts +2 -2
  201. package/dist/plugins/device-store-sql.js +5 -10
  202. package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
  203. package/dist/plugins/execution-lane-rename-m40.js +10 -0
  204. package/dist/plugins/execution-placement-sql.d.ts +63 -88
  205. package/dist/plugins/execution-placement-sql.js +94 -54
  206. package/dist/plugins/file-run-store.d.ts +26 -12
  207. package/dist/plugins/file-run-store.js +63 -63
  208. package/dist/plugins/imported-layer-root-retirement.d.ts +17 -8
  209. package/dist/plugins/imported-layer-root-retirement.js +4 -8
  210. package/dist/plugins/inbox-payload-column.d.ts +14 -0
  211. package/dist/plugins/inbox-payload-column.js +13 -0
  212. package/dist/plugins/local-checkpoint-store.d.ts +5 -0
  213. package/dist/plugins/local-checkpoint-store.js +11 -7
  214. package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
  215. package/dist/plugins/local-data-dir-modes-m39.js +182 -0
  216. package/dist/plugins/local-engine-high-water.d.ts +11 -0
  217. package/dist/plugins/local-engine-high-water.js +59 -0
  218. package/dist/plugins/local-session-store.d.ts +91 -25
  219. package/dist/plugins/local-session-store.js +124 -45
  220. package/dist/plugins/local-task-attachment-store.d.ts +2 -0
  221. package/dist/plugins/local-task-attachment-store.js +10 -11
  222. package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
  223. package/dist/plugins/memory-embedder-fingerprint.js +52 -12
  224. package/dist/plugins/memory-embedder.d.ts +1 -1
  225. package/dist/plugins/memory-embedder.js +2 -2
  226. package/dist/plugins/memory-engine-pg.d.ts +4 -3
  227. package/dist/plugins/memory-engine-pg.js +4 -4
  228. package/dist/plugins/memory-engine-sql-apply.d.ts +13 -4
  229. package/dist/plugins/memory-engine-sql-apply.js +1 -1
  230. package/dist/plugins/memory-engine-tidb.d.ts +8 -5
  231. package/dist/plugins/memory-engine-tidb.js +7 -8
  232. package/dist/plugins/one-time-migrations.d.ts +145 -35
  233. package/dist/plugins/one-time-migrations.js +272 -120
  234. package/dist/plugins/owner-only-file-mode.d.ts +29 -0
  235. package/dist/plugins/owner-only-file-mode.js +141 -0
  236. package/dist/plugins/permission-rule-store-file.d.ts +8 -8
  237. package/dist/plugins/permission-rule-store-file.js +14 -2
  238. package/dist/plugins/pg-pool.d.ts +2 -1
  239. package/dist/plugins/pg-pool.js +11 -4
  240. package/dist/plugins/release-version.d.ts +20 -0
  241. package/dist/plugins/release-version.js +28 -0
  242. package/dist/plugins/remote-env-adb.d.ts +20 -4
  243. package/dist/plugins/remote-env-adb.js +39 -11
  244. package/dist/plugins/remote-env-e2b.d.ts +12 -3
  245. package/dist/plugins/remote-env-e2b.js +6 -4
  246. package/dist/plugins/remote-env-host.d.ts +9 -1
  247. package/dist/plugins/remote-env-host.js +6 -5
  248. package/dist/plugins/remote-env-k8s.d.ts +5 -2
  249. package/dist/plugins/remote-env-k8s.js +15 -4
  250. package/dist/plugins/remote-env-local-docker.d.ts +4 -1
  251. package/dist/plugins/remote-env-local-docker.js +3 -3
  252. package/dist/plugins/remote-env-ssh.d.ts +8 -2
  253. package/dist/plugins/remote-env-ssh.js +26 -24
  254. package/dist/plugins/remote-shell.d.ts +59 -30
  255. package/dist/plugins/remote-shell.js +175 -62
  256. package/dist/plugins/retention-declaration.d.ts +37 -0
  257. package/dist/plugins/retention-declaration.js +9 -0
  258. package/dist/plugins/retention-deployment.d.ts +126 -0
  259. package/dist/plugins/retention-deployment.js +88 -0
  260. package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
  261. package/dist/plugins/retention-lane-store-sql.js +103 -1
  262. package/dist/plugins/retention-sql.d.ts +29 -0
  263. package/dist/plugins/retention-sql.js +8 -0
  264. package/dist/plugins/schema-consistency.d.ts +0 -6
  265. package/dist/plugins/schema-consistency.js +1 -2
  266. package/dist/plugins/schema-ensure-legs.d.ts +1 -1
  267. package/dist/plugins/schema-ensure-legs.js +11 -1
  268. package/dist/plugins/session-ext-table.d.ts +74 -0
  269. package/dist/plugins/session-ext-table.js +121 -0
  270. package/dist/plugins/session-fork.d.ts +1 -1
  271. package/dist/plugins/session-row-sql.d.ts +8 -7
  272. package/dist/plugins/session-row-sql.js +15 -7
  273. package/dist/plugins/session-store-sql.d.ts +131 -0
  274. package/dist/plugins/session-store-sql.js +298 -0
  275. package/dist/plugins/session-workspace-cell.d.ts +2 -2
  276. package/dist/plugins/session-workspace-cell.js +2 -2
  277. package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
  278. package/dist/plugins/shared-memory-store-sql.js +13 -13
  279. package/dist/plugins/snapshot-bucket-presence.js +1 -1
  280. package/dist/plugins/sql-driver.d.ts +23 -7
  281. package/dist/plugins/sql-driver.js +41 -8
  282. package/dist/plugins/sql-errors.d.ts +5 -2
  283. package/dist/plugins/sql-errors.js +4 -0
  284. package/dist/plugins/store-backend.d.ts +35 -8
  285. package/dist/plugins/store-backend.js +184 -62
  286. package/dist/plugins/store-contracts.d.ts +9 -2
  287. package/dist/plugins/store-contracts.js +1 -0
  288. package/dist/plugins/task-attachment-store.d.ts +6 -8
  289. package/dist/plugins/task-attachment-store.js +15 -10
  290. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  291. package/dist/plugins/text-column-capacity.d.ts +21 -0
  292. package/dist/plugins/text-column-capacity.js +5 -0
  293. package/dist/plugins/tidb-pool.d.ts +3 -2
  294. package/dist/plugins/tidb-pool.js +19 -31
  295. package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
  296. package/dist/read-face-posture.d.ts +6 -6
  297. package/dist/read-face-posture.js +2 -2
  298. package/dist/request-value-closure.d.ts +5 -5
  299. package/dist/request-value-closure.js +1 -1
  300. package/dist/rules-consent.d.ts +41 -13
  301. package/dist/rules-consent.js +101 -53
  302. package/dist/run-local.js +17 -13
  303. package/dist/runs.d.ts +48 -30
  304. package/dist/runs.js +26 -16
  305. package/dist/runtime-caps-resolver.d.ts +15 -8
  306. package/dist/runtime-caps-resolver.js +14 -10
  307. package/dist/sealed-key-layout.d.ts +2 -3
  308. package/dist/sealed-key-layout.js +0 -1
  309. package/dist/sealed-key.js +7 -5
  310. package/dist/security.d.ts +5 -3
  311. package/dist/sema-config-dir.js +2 -2
  312. package/dist/server-secret-env.d.ts +2 -0
  313. package/dist/service-version.d.ts +2 -1
  314. package/dist/service-version.js +2 -2
  315. package/dist/session-error-wire.d.ts +1 -1
  316. package/dist/session-incarnation.d.ts +8 -5
  317. package/dist/session-resident-background.d.ts +85 -32
  318. package/dist/session-resident-background.js +75 -7
  319. package/dist/session-row.d.ts +1 -1
  320. package/dist/session-sync-kernel.d.ts +1 -1
  321. package/dist/session-workspace.d.ts +11 -2
  322. package/dist/session-workspace.js +5 -0
  323. package/dist/sighup-idle.d.ts +1 -1
  324. package/dist/store-posture.d.ts +2 -1
  325. package/dist/stored-request-hooks-m20.d.ts +3 -2
  326. package/dist/stored-request-hooks-m20.js +19 -14
  327. package/dist/stores-sql/blob-index-sql.d.ts +148 -0
  328. package/dist/stores-sql/blob-index-sql.js +154 -0
  329. package/dist/stores-sql/checkpoint-store-sql.d.ts +1 -1
  330. package/dist/stores-sql/checkpoint-store-sql.js +11 -27
  331. package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
  332. package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
  333. package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +23 -76
  334. package/dist/{plugins → stores-sql}/pg-session-storage.js +80 -209
  335. package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
  336. package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
  337. package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
  338. package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
  339. package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
  340. package/dist/stores-sql/session-write-hooks.d.ts +59 -0
  341. package/dist/stores-sql/session-write-hooks.js +2 -0
  342. package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
  343. package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
  344. package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +32 -122
  345. package/dist/{plugins → stores-sql}/tidb-session-store.js +71 -171
  346. package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
  347. package/dist/stores-sql/tool-result-store-sql.js +1 -1
  348. package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
  349. package/dist/stores-sql/windowed-session-storage.js +61 -0
  350. package/dist/task-a2a.d.ts +7 -1
  351. package/dist/task-a2a.js +15 -14
  352. package/dist/task-cwd.d.ts +11 -3
  353. package/dist/task-cwd.js +17 -1
  354. package/dist/task-mcp.d.ts +10 -2
  355. package/dist/task-mcp.js +13 -16
  356. package/dist/task-settings.d.ts +9 -4
  357. package/dist/task-settings.js +17 -6
  358. package/dist/tool-approval.d.ts +21 -8
  359. package/dist/tool-approval.js +10 -6
  360. package/dist/trace/core-keyset-guard.d.ts +9 -3
  361. package/dist/trace/engine-notice-wire.d.ts +1 -1
  362. package/dist/trace/engine-notice-wire.js +2 -0
  363. package/dist/trace/exit-seat.d.ts +23 -1
  364. package/dist/trace/exit-seat.js +3 -0
  365. package/dist/trace/project.d.ts +33 -16
  366. package/dist/trace/project.js +12 -9
  367. package/dist/trace/redact.d.ts +1 -1
  368. package/dist/trace/redact.js +61 -73
  369. package/dist/trace/self-minted-wire.d.ts +263 -10
  370. package/dist/trace/self-minted-wire.js +90 -2
  371. package/dist/trace/sema-provenance.d.ts +45 -41
  372. package/dist/trace/sema-provenance.js +81 -10
  373. package/dist/trace/task-notification-facets.d.ts +70 -2
  374. package/dist/trace/task-notification-facets.js +71 -1
  375. package/dist/trace/wire-projection-faces.d.ts +38 -2
  376. package/dist/trace/wire-projection-faces.js +26 -1
  377. package/dist/unread-request-members.d.ts +66 -0
  378. package/dist/unread-request-members.js +41 -0
  379. package/dist/user-input-ledger.d.ts +2 -2
  380. package/dist/web-admin-client/apply-effective.js +22 -26
  381. package/dist/web-admin-client/candidate-gate.d.ts +35 -3
  382. package/dist/web-admin-client/candidate-gate.js +53 -5
  383. package/dist/web-admin-client/center-request.d.ts +4 -1
  384. package/dist/web-admin-client/center-request.js +2 -1
  385. package/dist/web-admin-client/effective-keys.js +0 -1
  386. package/dist/web-admin-client/facade.d.ts +1 -1
  387. package/dist/web-admin-client/http-client.d.ts +1 -0
  388. package/dist/web-admin-client/http-client.js +17 -9
  389. package/dist/web-admin-client/restart-signal.js +5 -2
  390. package/dist/web-admin-client/skills-mcp.d.ts +20 -6
  391. package/dist/web-admin-client/skills-mcp.js +26 -21
  392. package/dist/web-admin-client/types.d.ts +34 -49
  393. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
  394. package/package.json +13 -12
  395. package/scripts/drain-check-local.mjs +2 -28
  396. package/scripts/drain-check.mysql.sql +2 -18
  397. package/scripts/drain-check.pg.sql +2 -18
  398. package/wire-changes/server@7.147.0.json +813 -0
@@ -2,7 +2,7 @@ import { redactErrorMessage, redactLedgerEventData, sealRunRowResult } from "../
2
2
  import { outwardPlane } from "../terminal.js";
3
3
  import { projectUsageStats, USAGE_SCAN_LIMIT } from "../usage-analytics.js";
4
4
  import { join } from "node:path";
5
- import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync } from "node:fs";
5
+ import { existsSync, readFileSync, readdirSync, renameSync, rmSync, statSync } from "node:fs";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { AppendLog, atomicWriteFile, ensureDir, isProcessLive, processFingerprint, sanitizePathComponent, sanitizeScope, writeThenLink } from "@sema-agent/core";
8
8
  import { recordFailOpen } from "../observability/fail-open.js";
@@ -58,6 +58,9 @@ const PARK_ORPHAN_SETTLE_MS = 30_000;
58
58
  export class RunStoreStrictHydrateError extends StoreBootRefusalError {
59
59
  name = "RunStoreStrictHydrateError";
60
60
  }
61
+ export function fileRunStoreDirsFor(root) {
62
+ return { runs: join(root, "runs"), active: join(root, "runs", "active"), tmp: join(root, "tmp"), spaceCommits: join(root, "space-commits") };
63
+ }
61
64
  export class FileRunStore {
62
65
  runsDir;
63
66
  activeDir;
@@ -81,15 +84,16 @@ export class FileRunStore {
81
84
  constructor(root, opts) {
82
85
  this.logger = opts;
83
86
  this.strictHydrate = opts?.strictHydrate === true;
84
- this.runsDir = join(root, "runs");
85
- this.activeDir = join(root, "runs", "active");
86
- this.tmpDir = join(root, "tmp");
87
+ const dirs = fileRunStoreDirsFor(root);
88
+ this.runsDir = dirs.runs;
89
+ this.activeDir = dirs.active;
90
+ this.tmpDir = dirs.tmp;
87
91
  this.blobsDir = join(root, "run-blobs");
88
- this.spaceCommitsDir = join(root, "space-commits");
92
+ this.spaceCommitsDir = dirs.spaceCommits;
89
93
  this.spaceCommits = createInProcessSpaceCommitTable({
90
94
  load: (spaceKey) => this.loadSpaceCommit(spaceKey),
91
95
  save: (record) => {
92
- mkdirSync(this.spaceCommitsDir, { recursive: true });
96
+ ensureDir(this.spaceCommitsDir);
93
97
  atomicWriteFile(this.tmpDir, this.spaceCommitPath(record.spaceKey), `${JSON.stringify(record)}\n`);
94
98
  },
95
99
  remove: (spaceKey) => rmSync(this.spaceCommitPath(spaceKey), { force: true }),
@@ -353,17 +357,21 @@ export class FileRunStore {
353
357
  }
354
358
  }
355
359
  writeRunFile(r) {
356
- mkdirSync(this.runDir(r.taskId), { recursive: true });
360
+ ensureDir(this.runDir(r.taskId));
357
361
  atomicWriteFile(this.tmpDir, this.runJsonPath(r.taskId), `${JSON.stringify(this.toDisk(r))}\n`);
358
362
  }
359
- persist(r) {
360
- this.writeRunFile(r);
361
- this.runs.set(r.taskId, r);
363
+ persist(draft) {
364
+ this.writeRunFile(draft);
365
+ const live = this.runs.get(draft.taskId);
366
+ if (live === undefined)
367
+ this.runs.set(draft.taskId, draft);
368
+ else
369
+ Object.assign(live, draft);
362
370
  }
363
371
  eventLogFor(taskId) {
364
372
  let log = this.eventLogs.get(taskId);
365
373
  if (!log) {
366
- mkdirSync(this.runDir(taskId), { recursive: true });
374
+ ensureDir(this.runDir(taskId));
367
375
  log = new AppendLog(this.eventsPath(taskId));
368
376
  this.eventLogs.set(taskId, log);
369
377
  }
@@ -434,15 +442,13 @@ export class FileRunStore {
434
442
  const r = this.runs.get(taskId);
435
443
  if (!r || r.objectivePreview !== null)
436
444
  return;
437
- this.writeRunFile({ ...r, objectivePreview: preview });
438
- r.objectivePreview = preview;
445
+ this.persist({ ...r, objectivePreview: preview });
439
446
  }
440
447
  async requestCancel(taskId, owner) {
441
448
  const r = this.runs.get(taskId);
442
449
  if (!r || !ownerEq(r.owner, owner) || r.status !== "running")
443
450
  return false;
444
- r.cancelRequested = true;
445
- this.persist(r);
451
+ this.persist({ ...r, cancelRequested: true });
446
452
  return true;
447
453
  }
448
454
  async isCancelRequested(taskId, owner) {
@@ -453,8 +459,7 @@ export class FileRunStore {
453
459
  const r = this.runs.get(taskId);
454
460
  if (!r || !ownerEq(r.owner, owner) || r.status !== "running")
455
461
  return false;
456
- r.preemptRequested = true;
457
- this.persist(r);
462
+ this.persist({ ...r, preemptRequested: true });
458
463
  return true;
459
464
  }
460
465
  async isPreemptRequested(taskId, owner) {
@@ -463,10 +468,8 @@ export class FileRunStore {
463
468
  }
464
469
  async heartbeat(taskId, owner) {
465
470
  const r = this.runs.get(taskId);
466
- if (r && ownerEq(r.owner, owner) && r.status === "running") {
467
- r.updatedAt = new Date();
468
- this.persist(r);
469
- }
471
+ if (r && ownerEq(r.owner, owner) && r.status === "running")
472
+ this.persist({ ...r, updatedAt: new Date() });
470
473
  }
471
474
  async appendEvent(taskId, seq, type, data) {
472
475
  data = redactLedgerEventData(type, data);
@@ -569,12 +572,8 @@ export class FileRunStore {
569
572
  }
570
573
  let pending;
571
574
  if (r.status === "running" || r.status === "suspended" || r.status === "needs_review") {
572
- r.status = status;
573
- r.result = result;
574
- r.error = error;
575
- r.errorCode = result === null ? null : (outwardPlane(result.terminal).errorCode ?? null);
576
- r.updatedAt = new Date();
577
- this.persist(r);
575
+ const errorCode = result === null ? null : (outwardPlane(result.terminal).errorCode ?? null);
576
+ this.persist({ ...r, status, result, error, errorCode, updatedAt: new Date() });
578
577
  pending = {
579
578
  runId: taskId,
580
579
  sessionId: r.sessionId,
@@ -582,7 +581,7 @@ export class FileRunStore {
582
581
  status,
583
582
  resultTaskId: result?.taskId,
584
583
  model: result?.model,
585
- errorCode: r.errorCode ?? undefined,
584
+ errorCode: errorCode ?? undefined,
586
585
  errorMessage: (result === null ? undefined : outwardPlane(result.terminal).errorMessage) ?? error ?? undefined,
587
586
  elapsedMs: Math.max(0, Date.now() - r.createdAt.getTime()),
588
587
  };
@@ -597,33 +596,29 @@ export class FileRunStore {
597
596
  const sealed = sealRunRowResult(result);
598
597
  const r = this.runs.get(taskId);
599
598
  if (r && (r.status === "running" || r.status === "suspended")) {
600
- r.status = "suspended";
601
- r.result = sealed;
602
- r.updatedAt = new Date();
603
- this.persist(r);
599
+ this.persist({ ...r, status: "suspended", result: sealed, updatedAt: new Date() });
604
600
  }
605
601
  }
606
602
  async setNeedsReview(taskId, result) {
607
603
  const sealed = sealRunRowResult(result);
608
604
  const r = this.runs.get(taskId);
609
605
  if (r && (r.status === "running" || r.status === "needs_review")) {
610
- r.status = "needs_review";
611
- r.result = sealed;
612
- r.updatedAt = new Date();
613
- this.persist(r);
606
+ this.persist({ ...r, status: "needs_review", result: sealed, updatedAt: new Date() });
614
607
  }
615
608
  }
616
609
  async markResuming(taskId, instanceId) {
617
610
  const r = this.runs.get(taskId);
618
611
  if (!r || (r.status !== "suspended" && r.status !== "needs_review"))
619
612
  return false;
620
- r.status = "running";
621
- r.result = null;
622
- r.instanceId = instanceId;
623
- r.cancelRequested = false;
624
- r.preemptRequested = false;
625
- r.updatedAt = new Date();
626
- this.persist(r);
613
+ this.persist({
614
+ ...r,
615
+ status: "running",
616
+ result: null,
617
+ instanceId,
618
+ cancelRequested: false,
619
+ preemptRequested: false,
620
+ updatedAt: new Date(),
621
+ });
627
622
  return true;
628
623
  }
629
624
  async getActiveTaskId(sessionId) {
@@ -633,8 +628,7 @@ export class FileRunStore {
633
628
  const r = this.runs.get(taskId);
634
629
  if (this.active.get(sessionId) !== taskId || r === undefined || r.status !== "running")
635
630
  return false;
636
- r.updatedAt = new Date();
637
- this.persist(r);
631
+ this.persist({ ...r, updatedAt: new Date() });
638
632
  write({ instanceId: r.instanceId });
639
633
  return true;
640
634
  }
@@ -806,12 +800,14 @@ export class FileRunStore {
806
800
  let reaped = 0;
807
801
  for (const r of this.runs.values()) {
808
802
  if (r.status === "running" && pred(r)) {
809
- r.status = "failed";
810
- r.result = null;
811
- r.error = reason;
812
- r.errorCode = code;
813
- r.updatedAt = new Date();
814
- this.persist(r);
803
+ this.persist({
804
+ ...r,
805
+ status: "failed",
806
+ result: null,
807
+ error: reason,
808
+ errorCode: code,
809
+ updatedAt: new Date(),
810
+ });
815
811
  reaped += 1;
816
812
  }
817
813
  }
@@ -829,12 +825,14 @@ export class FileRunStore {
829
825
  orphans.push(r);
830
826
  }
831
827
  for (const r of orphans) {
832
- r.status = "failed";
833
- r.result = null;
834
- r.error = RUN_ORPHANED_ERROR;
835
- r.errorCode = RUN_HOLDER_DEATH_CODES.orphaned;
836
- r.updatedAt = new Date();
837
- this.persist(r);
828
+ this.persist({
829
+ ...r,
830
+ status: "failed",
831
+ result: null,
832
+ error: RUN_ORPHANED_ERROR,
833
+ errorCode: RUN_HOLDER_DEATH_CODES.orphaned,
834
+ updatedAt: new Date(),
835
+ });
838
836
  }
839
837
  this.sweepClaims();
840
838
  return orphans.length;
@@ -843,12 +841,14 @@ export class FileRunStore {
843
841
  this.checkpointProbe = probe;
844
842
  }
845
843
  failExpiredPark(r) {
846
- r.status = "failed";
847
- r.result = null;
848
- r.error = "approval expired before decision";
849
- r.errorCode = "approval.expired";
850
- r.updatedAt = new Date();
851
- this.persist(r);
844
+ this.persist({
845
+ ...r,
846
+ status: "failed",
847
+ result: null,
848
+ error: "approval expired before decision",
849
+ errorCode: "approval.expired",
850
+ updatedAt: new Date(),
851
+ });
852
852
  }
853
853
  async reapSuspended(olderThanMs) {
854
854
  const probe = this.checkpointProbe;
@@ -16,10 +16,12 @@
16
16
  * 一律问**店**:它能叫出名字的每一只桶,判据在桶里判(不在桶外按「谁可能有」预筛)。
17
17
  * · SQL:规则表里的每一只桶(`listRuleBucketOwners`,按 `owner_key` 分页)。不从审批记录推 —— 收编把规则桶整桶改键到新身份、审批史留在旧身份名下,
18
18
  * 从记录推出的属主集在收编之后漏掉新桶。
19
- * · File:本店导入记录点名过的属主(`FileRuleApprovalRecordStore.importRecordOwners`;`imported-cc` 只由导入记录派生,记录是只增日志)∪ 引擎 File 分区后端
20
- * 自己列得出名字的属主(`FileDurableRulePartitionProvider.listBucketOwners().owners`:本机属主那只桶,与收编标记点名的身份 —— 收编把桶改名到一个没有任何
21
- * 导入记录点名的身份之后,那只桶照样被叫出来、被读)。**已知缺口(如实)**:桶文件按属主名的单向摘要命名,记录与收编标记都叫不出属主的桶本步不读;
22
- * 引擎给的「叫不出名字的桶数」(`unnamedBuckets`)只认本机属主那只桶与收编标记、把导入记录点名过的桶也算进去,不是本步的缺数 —— 不报它(报了会把读过的桶说成没读)。
19
+ * · File:引擎 File 分区后端的列桶口一次答(`FileDurableRulePartitionProvider.listBucketOwners({ knownOwners })`):目录自己叫得出名字的属主(本机属主那只桶、
20
+ * 收编标记点名的身份 —— 收编把桶改名到一个没有任何导入记录点名的身份之后,那只桶照样被叫出来、被读),加上本店导入记录点名过的身份里桶文件在场的那些
21
+ * (`knownOwners` = `FileRuleApprovalRecordStore.importRecordOwners` 的身份名;`imported-cc` 只由导入记录派生,记录是只增日志;桶名由引擎的那一只摘要算,本仓不算)。
22
+ * **两者都叫不出属主的桶**(桶文件按属主名的单向摘要命名)本步读不到 —— 引擎在同一次答里给出它们的个数(`unnamedBuckets`),本步原样记进报告
23
+ * (`importedLayerRootBucketsUnnamed`),非零每次起服 warn 一行;它不是「空」,是本步的普查缺了这么多只。
24
+ * 一种店一个来源、一次答 ⇒ 属主不重(引擎:同名给两次、或收编标记也点了它,是一个属主;SQL:按 `owner_key` 分页,键唯一)。
23
25
  *
24
26
  * ## 写在哪里(一处)
25
27
  * 墓碑经**这只桶自己的写面**落(`writerOf(partition).apply({ kind: "tighten-delete" })`,引擎的写面契约)—— SQL 两孪生走 `SqlDurableRulePartition` 的那只
@@ -63,14 +65,21 @@ export interface ImportedLayerRootBucketSkipped {
63
65
  * 原句由店自己的披露口说,File 店的 `permission_rule_store_disclosure`、SQL 店的整桶拒句);写面拒的是闭集词,原样带。 */
64
66
  readonly why: string;
65
67
  }
66
- /** 本步记进收据账的两格(`OneTimeMigrationReport` 的两只键,随提交追加)。 */
68
+ /** 本步记进收据账的三格(`OneTimeMigrationReport` 的三只键;前两格随提交追加,第三格在列桶那一刻落定)。 */
67
69
  export interface ImportedLayerRootReadings {
68
70
  importedLayerRootAllowsRetired: ImportedLayerRootAllowRetired[];
69
71
  importedLayerRootBucketsSkipped: ImportedLayerRootBucketSkipped[];
72
+ /** 店在场却叫不出属主、本步因此没读的桶数(见头注「读哪些桶」;SQL 恒 0)。 */
73
+ importedLayerRootBucketsUnnamed: number;
70
74
  }
71
- /** 一种店交给本步的三样东西:它能叫出名字的桶的属主(见头注「读哪些桶」)、它的 durable 分区后端(读桶、写墓碑)、它的整桶拒判别(见头注「失败方向」)。 */
75
+ /** 一种店的桶普查(一次答):叫得出名字的属主,与在场却叫不出名字的桶数。 */
76
+ export interface RuleBucketCensus {
77
+ readonly owners: readonly RuleOwner[];
78
+ readonly unnamedBuckets: number;
79
+ }
80
+ /** 一种店交给本步的三样东西:它的桶普查(见头注「读哪些桶」)、它的 durable 分区后端(读桶、写墓碑)、它的整桶拒判别(见头注「失败方向」)。 */
72
81
  export interface ImportedLayerRootRetirementSource {
73
- candidateOwners(): Promise<readonly RuleOwner[]>;
82
+ candidateOwners(): Promise<RuleBucketCensus>;
74
83
  readonly durable: DurableRulePartitionProvider;
75
84
  /** 这只读桶抛出物是不是店的唯一判官的**确定性**整桶拒(真 ⇒ 点名跳过、读下一只桶;假 ⇒ 原样抛、起服拒)。判的是读面**真往外交的**抛出物的类,不按文案。 */
76
85
  isWholeBucketRefusal(e: unknown): boolean;
@@ -79,6 +88,6 @@ export interface ImportedLayerRootRetirementSource {
79
88
  }
80
89
  /** 判据(引擎 §5.14 那一句,逐字):这一行里该退役的 add;不选 ⇒ 空。 */
81
90
  export declare function importedLayerRootAddsOf(row: PersistedRule): readonly RuleAdd[];
82
- /** 跑一遍:读店叫得出名字的每只桶(`candidateOwners()`,见头注「读哪些桶」;两源有重 ⇒ 按桶键去重),退役判据选中的 add。读数随每次提交记进 `into`。 */
91
+ /** 跑一遍:读店叫得出名字的每只桶(`candidateOwners()` 一次答,见头注「读哪些桶」),退役判据选中的 add;叫不出名字的桶数记进 `into`。读数随每次提交记进 `into`。 */
83
92
  export declare function retireImportedLayerRootAllows(source: ImportedLayerRootRetirementSource, into: ImportedLayerRootReadings): Promise<void>;
84
93
  //# sourceMappingURL=imported-layer-root-retirement.d.ts.map
@@ -7,14 +7,10 @@ export function importedLayerRootAddsOf(row) {
7
7
  return row.adds.filter((a) => a.origin === "imported-cc");
8
8
  }
9
9
  export async function retireImportedLayerRootAllows(source, into) {
10
- const seen = new Set();
11
- for (const owner of await source.candidateOwners()) {
12
- const ownerKey = buildRuleOwnerKey(owner);
13
- if (seen.has(ownerKey))
14
- continue;
15
- seen.add(ownerKey);
16
- await retireInBucket(source, owner, ownerKey, into);
17
- }
10
+ const census = await source.candidateOwners();
11
+ into.importedLayerRootBucketsUnnamed = census.unnamedBuckets;
12
+ for (const owner of census.owners)
13
+ await retireInBucket(source, owner, buildRuleOwnerKey(owner), into);
18
14
  }
19
15
  async function retireInBucket(source, owner, ownerKey, into) {
20
16
  const durable = source.durable;
@@ -0,0 +1,14 @@
1
+ /** 两方言的列类型词(键表对 {@link SqlDialect} 闭合:加一种方言 ⇒ 编译红)。 */
2
+ export declare const INBOX_PAYLOAD_COLUMN_TYPE: {
3
+ readonly mysql: "TEXT";
4
+ readonly pg: "TEXT";
5
+ };
6
+ /** 列定义(两方言 DDL 内插;存量库缺列由起服列册对账拒启,拒句里的 ALTER 由建表语句生成)。 */
7
+ export declare const INBOX_PAYLOAD_COLUMN: {
8
+ readonly name: "payload";
9
+ readonly mysql: "payload TEXT NULL";
10
+ readonly pg: "payload TEXT COLLATE \"C\"";
11
+ };
12
+ /** 收件条目 `payload` 的字节预算(UTF-8 字节,量最终 JSON)= 各方言 `payload` 列容量的最小值。 */
13
+ export declare const INBOX_PAYLOAD_MAX_BYTES: number;
14
+ //# sourceMappingURL=inbox-payload-column.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { TEXT_COLUMN_TYPE_MAX_BYTES } from "./text-column-capacity.js";
2
+ export const INBOX_PAYLOAD_COLUMN_TYPE = { mysql: "TEXT", pg: "TEXT" };
3
+ export const INBOX_PAYLOAD_COLUMN = {
4
+ name: "payload",
5
+ mysql: `payload ${INBOX_PAYLOAD_COLUMN_TYPE.mysql} NULL`,
6
+ pg: `payload ${INBOX_PAYLOAD_COLUMN_TYPE.pg} COLLATE "C"`,
7
+ };
8
+ const INBOX_PAYLOAD_COLUMN_MAX_BYTES = {
9
+ mysql: TEXT_COLUMN_TYPE_MAX_BYTES.mysql[INBOX_PAYLOAD_COLUMN_TYPE.mysql],
10
+ pg: TEXT_COLUMN_TYPE_MAX_BYTES.pg[INBOX_PAYLOAD_COLUMN_TYPE.pg],
11
+ };
12
+ export const INBOX_PAYLOAD_MAX_BYTES = Math.min(...Object.values(INBOX_PAYLOAD_COLUMN_MAX_BYTES));
13
+ //# sourceMappingURL=inbox-payload-column.js.map
@@ -11,6 +11,11 @@ export interface LocalCheckpointStoreOptions {
11
11
  /** ctx 改写的认领栅栏({@link LocalCheckpointStore.rewriteCtxWhileClaimed}):同一数据根上的文件 run 店(进程内栅栏形)。缺席 ⇒ 那一口响亮抛(装配缺陷)。 */
12
12
  claims?: InProcessClaimFence;
13
13
  }
14
+ /** checkpoint 店在数据根下自己铸的目录(构造器与一次性迁移 M39 的名册同读这一只)。 */
15
+ export declare function localCheckpointStoreDirsFor(root: string): {
16
+ readonly ctx: string;
17
+ readonly tmp: string;
18
+ };
14
19
  export declare class LocalCheckpointStore {
15
20
  /** [ref] 车1:托管留存声明 —— **诚实的 none**(与 local session 店同一条判据:本店的行没有按期删除的腿;
16
21
  * 留存三方法只实现在 SQL 聚合店上)。locked policy + 本店 ⇒ core 的门拒启,那是契约的正确行为。 */
@@ -3,14 +3,14 @@ import { denySweepOwns, parkedApprovalCard } from "../approval-content-kind.js";
3
3
  import { parkRowFacts, skillCardFacts } from "../approval-card.js";
4
4
  import { durableRowIdentity } from "../checkpoint-identity.js";
5
5
  import { createHash } from "node:crypto";
6
- import { existsSync, readFileSync, readdirSync, unlinkSync, mkdirSync } from "node:fs";
6
+ import { existsSync, readFileSync, readdirSync, unlinkSync } from "node:fs";
7
7
  import { join } from "node:path";
8
- import { CHECKPOINT_LIST_LIMITS, FileCheckpointStore, atomicWriteFile, executionVerdict, sanitizePathComponent, } from "@sema-agent/core";
8
+ import { CHECKPOINT_LIST_LIMITS, FileCheckpointStore, atomicWriteFile, ensureDir, executionVerdict, sanitizePathComponent, } from "@sema-agent/core";
9
9
  import { approvalPayloadFingerprint } from "./approval-payload-fingerprint.js";
10
10
  import { approvalDecisionOfWinner, boundedRuleOffers, boundedToolInput, candidateIdentityOf, pendingRowPrecedes, queueRowGateKind, TERMINAL_BACKSTOP_MS, TERMINAL_GRACE_MS } from "./checkpoint-store-face.js";
11
11
  import { quarantineUnreadableSidecar } from "./local-sidecar-quarantine.js";
12
12
  import { createZodColumnReader, decodeJsonColumn, foldJsonColumn, readStringArrayColumn } from "./sql-json-column.js";
13
- import { UNMANAGED_RETENTION } from "./retention-store-sql.js";
13
+ import { UNMANAGED_RETENTION } from "./retention-declaration.js";
14
14
  import { assertJsonColumnWritable, createObjectColumnReader } from "./sql-json-column.js";
15
15
  import { FENCE_LANDED } from "./store-contracts.js";
16
16
  function terminalAtOf(cp) {
@@ -47,6 +47,9 @@ function refusingCtx(sessionId, read) {
47
47
  throw foldJsonColumn(e, (m) => `LocalCheckpointStore: ${m} — refusing rather than serve a resume context nobody can read (session ${JSON.stringify(sessionId)})`);
48
48
  }
49
49
  }
50
+ export function localCheckpointStoreDirsFor(root) {
51
+ return { ctx: join(root, "checkpoint-ctx"), tmp: join(root, ".tmp") };
52
+ }
50
53
  export class LocalCheckpointStore {
51
54
  retention = UNMANAGED_RETENTION;
52
55
  durability = "durable";
@@ -65,10 +68,11 @@ export class LocalCheckpointStore {
65
68
  this.opts = opts;
66
69
  this.scopesPath = join(root, "checkpoint-scopes.json");
67
70
  this.sessionTokensPath = join(root, "checkpoint-session-tokens.json");
68
- this.ctxDir = join(root, "checkpoint-ctx");
69
- this.tmpDir = join(root, ".tmp");
70
- mkdirSync(this.ctxDir, { recursive: true });
71
- mkdirSync(this.tmpDir, { recursive: true });
71
+ const dirs = localCheckpointStoreDirsFor(root);
72
+ this.ctxDir = dirs.ctx;
73
+ this.tmpDir = dirs.tmp;
74
+ ensureDir(this.ctxDir);
75
+ ensureDir(this.tmpDir);
72
76
  if (existsSync(this.scopesPath)) {
73
77
  try {
74
78
  for (const s of decodeJsonColumn(readFileSync(this.scopesPath, "utf8"), readScopeRegistry, "checkpoint-scopes.json (the local scope registry)"))
@@ -0,0 +1,48 @@
1
+ /** 披露码:路径(含数据根自身、名册目录的子项)经符号链接 —— 不跟,这一条不走(「不在根内」一类,不按链接指向哪里特判)。 */
2
+ export declare const SYMLINK_IN_PATH = "SYMLINK_IN_PATH";
3
+ /**
4
+ * 本迁移看的两只根:数据根(`LocalBackend` 持锁的那一只物理路径 —— core `resolveDataRoot` 的 `physicalPathOf` 拼写 = 店构造时拿到的值;身份核拿它当「根内」的唯一判据,
5
+ * 不是物理拼写的值 ⇒ 每一只目录都过不了核、逐个进披露行)与记忆引擎根(boot 的 `memoryEngineRootFor` 推导,同步游标在它下面;
6
+ * 调用方先把它换成与数据根同一种拼写 —— 见 `LocalBackend` 的 `dataDirLayout`)。名册包含关系按字面判:引擎根经数据根之外的别名拼写 ⇒ 当作在数据根之外(不进名册)。
7
+ */
8
+ export interface DataDirLayout {
9
+ readonly dataRoot: string;
10
+ readonly memoryEngineRoot: string;
11
+ }
12
+ /**
13
+ * 布局只在这里铸一次(`LocalBackend` 取锁之后调):数据根 = 持锁的物理路径(配置里的拼写若经链接,事后改指也不影响);
14
+ * 记忆引擎根落在配置拼写的数据根之下 ⇒ 换成物理拼写(同一只目录只认一种拼写),否则原样(在数据根之外,名册不收)。
15
+ */
16
+ export declare function buildDataDirLayout(a: {
17
+ readonly configuredRoot: string;
18
+ readonly physicalRoot: string;
19
+ readonly memoryEngineRoot: string;
20
+ }): DataDirLayout;
21
+ export interface DataDirModeRefusal {
22
+ /** 相对数据根的路径。 */
23
+ readonly path: string;
24
+ /** 错误码(`EPERM` / `EACCES` / `ESTALE` / …)或 {@link SYMLINK_IN_PATH};没有码的错误记 `UNKNOWN`。 */
25
+ readonly code: string;
26
+ }
27
+ export interface DataDirModeReading {
28
+ /** 本次收紧成 0o700 的目录(相对数据根)。 */
29
+ readonly tightened: readonly string[];
30
+ /** 本次没能收紧 / 没能看见 / 没有走的目录。 */
31
+ readonly refused: readonly DataDirModeRefusal[];
32
+ }
33
+ /** 两只日志座:成功提示与失败披露各一(失败那只由调用方接**不可缺席**的口)。 */
34
+ export interface DataDirModeSinks {
35
+ readonly tightened: (msg: string, meta: Record<string, unknown>) => void;
36
+ readonly refused: (msg: string, meta: Record<string, unknown>) => void;
37
+ }
38
+ /** 测试座:收紧动作(默认对过了身份核的 fd `fchmod`)与平台(默认 `IS_WIN32`)。 */
39
+ export interface DataDirModeSeats {
40
+ readonly fchmod?: (fd: number, mode: number, rel: string) => void;
41
+ readonly win32?: boolean;
42
+ }
43
+ /**
44
+ * 把数据根下名册里的 0755 店目录一次收紧成 0o700。起服时调(`LocalBackend.runOneTimeMigrations`,任何读者之前);数据根独占 ⇒ 没有滚动升级窗,不需要读侧半场。
45
+ * 失败不抛(见头注);读数也由两只日志座打出。
46
+ */
47
+ export declare function tightenLocalDataDirModes(layout: DataDirLayout, sinks: DataDirModeSinks, seats?: DataDirModeSeats): DataDirModeReading;
48
+ //# sourceMappingURL=local-data-dir-modes-m39.d.ts.map
@@ -0,0 +1,182 @@
1
+ import { closeSync, constants as FS, fchmodSync, fstatSync, lstatSync, openSync, readdirSync } from "node:fs";
2
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { physicalPathOf } from "@sema-agent/core";
4
+ import { IS_WIN32 } from "./host-platform.js";
5
+ import { fileRunStoreDirsFor } from "./file-run-store.js";
6
+ import { localCheckpointStoreDirsFor } from "./local-checkpoint-store.js";
7
+ import { attachmentStoreDirFor } from "./local-task-attachment-store.js";
8
+ import { scratchpadRootFor } from "../env-facts.js";
9
+ import { pluginCacheRootFor } from "../capabilities/center-plugins.js";
10
+ import { memorySyncCursorDirFor } from "../memory-sync-client.js";
11
+ const DIR_MODE = 0o700;
12
+ const GROUP_OTHER_BITS = 0o077;
13
+ const TIGHTENED_EXAMPLES = 5;
14
+ const REFUSED_LISTED = 10;
15
+ export const SYMLINK_IN_PATH = "SYMLINK_IN_PATH";
16
+ export function buildDataDirLayout(a) {
17
+ const rel = relative(resolve(a.configuredRoot), resolve(a.memoryEngineRoot));
18
+ const underConfigured = rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
19
+ return { dataRoot: a.physicalRoot, memoryEngineRoot: underConfigured ? join(a.physicalRoot, rel) : a.memoryEngineRoot };
20
+ }
21
+ function rosterFor(layout) {
22
+ const run = fileRunStoreDirsFor(layout.dataRoot);
23
+ const checkpoint = localCheckpointStoreDirsFor(layout.dataRoot);
24
+ return [
25
+ { abs: run.runs, children: 1 },
26
+ { abs: run.tmp, children: 0 },
27
+ { abs: run.spaceCommits, children: 0 },
28
+ { abs: checkpoint.ctx, children: 0 },
29
+ { abs: checkpoint.tmp, children: 0 },
30
+ { abs: attachmentStoreDirFor(layout.dataRoot), children: 0 },
31
+ { abs: scratchpadRootFor(layout.dataRoot), children: 1 },
32
+ { abs: pluginCacheRootFor(layout.dataRoot), children: 2 },
33
+ { abs: memorySyncCursorDirFor(layout.memoryEngineRoot), children: 0 },
34
+ ];
35
+ }
36
+ function segmentsUnder(root, abs) {
37
+ const rel = relative(resolve(root), resolve(abs));
38
+ if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel))
39
+ return undefined;
40
+ return rel.split(sep);
41
+ }
42
+ const codeOf = (e) => (typeof e === "object" && e !== null && "code" in e && typeof e.code === "string" ? e.code : "UNKNOWN");
43
+ const emit = (sink, msg, meta) => {
44
+ try {
45
+ sink(msg, meta);
46
+ }
47
+ catch {
48
+ console.warn(msg, meta);
49
+ }
50
+ };
51
+ const sameObject = (a, b) => a.dev === b.dev && a.ino === b.ino;
52
+ function inRootBreak(root, segs, fd) {
53
+ try {
54
+ const held = fstatSync(fd, { bigint: true });
55
+ const physical = physicalPathOf(join(root, ...segs));
56
+ if (segmentsUnder(root, physical) === undefined)
57
+ return SYMLINK_IN_PATH;
58
+ if (!sameObject(lstatSync(physical, { bigint: true }), held))
59
+ return "ESTALE";
60
+ for (let i = 0; i <= segs.length; i += 1) {
61
+ const st = lstatSync(join(root, ...segs.slice(0, i)), { bigint: true });
62
+ if (st.isSymbolicLink())
63
+ return SYMLINK_IN_PATH;
64
+ if (!st.isDirectory())
65
+ return "ESTALE";
66
+ }
67
+ return undefined;
68
+ }
69
+ catch (e) {
70
+ return codeOf(e);
71
+ }
72
+ }
73
+ export function tightenLocalDataDirModes(layout, sinks, seats = {}) {
74
+ if (seats.win32 ?? IS_WIN32)
75
+ return { tightened: [], refused: [] };
76
+ const fchmod = seats.fchmod ?? ((fd, mode) => fchmodSync(fd, mode));
77
+ const root = layout.dataRoot;
78
+ const tightened = [];
79
+ const refused = [];
80
+ const refuse = (rel, code) => {
81
+ if (code !== "ENOENT")
82
+ refused.push({ path: rel, code });
83
+ };
84
+ const tighten = (segs, rel) => {
85
+ let fd;
86
+ try {
87
+ fd = openSync(join(root, ...segs), FS.O_RDONLY | FS.O_DIRECTORY | FS.O_NOFOLLOW);
88
+ }
89
+ catch (e) {
90
+ refuse(rel, codeOf(e));
91
+ return;
92
+ }
93
+ try {
94
+ const broken = inRootBreak(root, segs, fd);
95
+ if (broken !== undefined) {
96
+ refuse(rel, broken);
97
+ return;
98
+ }
99
+ fchmod(fd, DIR_MODE, rel);
100
+ tightened.push(rel);
101
+ }
102
+ catch (e) {
103
+ refuse(rel, codeOf(e));
104
+ }
105
+ finally {
106
+ closeSync(fd);
107
+ }
108
+ };
109
+ const step = (parent, name, more, depth) => {
110
+ const segs = [...parent, name];
111
+ const rel = join(...segs);
112
+ let mode;
113
+ try {
114
+ const st = lstatSync(join(root, ...segs));
115
+ if (st.isSymbolicLink()) {
116
+ refused.push({ path: rel, code: SYMLINK_IN_PATH });
117
+ return;
118
+ }
119
+ if (!st.isDirectory())
120
+ return;
121
+ mode = st.mode;
122
+ }
123
+ catch (e) {
124
+ refuse(rel, codeOf(e));
125
+ return;
126
+ }
127
+ const [next, ...rest] = more;
128
+ if (next !== undefined) {
129
+ step(segs, next, rest, depth);
130
+ return;
131
+ }
132
+ if ((mode & GROUP_OTHER_BITS) !== 0)
133
+ tighten(segs, rel);
134
+ if (depth === 0)
135
+ return;
136
+ let entries;
137
+ try {
138
+ entries = readdirSync(join(root, ...segs), { withFileTypes: true });
139
+ }
140
+ catch (e) {
141
+ refuse(rel, codeOf(e));
142
+ return;
143
+ }
144
+ for (const entry of entries) {
145
+ if (entry.isDirectory() || entry.isSymbolicLink())
146
+ step(segs, entry.name, [], depth - 1);
147
+ }
148
+ };
149
+ let rootIntact = false;
150
+ try {
151
+ if (lstatSync(root).isSymbolicLink())
152
+ refused.push({ path: ".", code: SYMLINK_IN_PATH });
153
+ else
154
+ rootIntact = true;
155
+ }
156
+ catch (e) {
157
+ refuse(".", codeOf(e));
158
+ }
159
+ for (const { abs, children } of rootIntact ? rosterFor(layout) : []) {
160
+ const [first, ...rest] = segmentsUnder(root, abs) ?? [];
161
+ if (first !== undefined)
162
+ step([], first, rest, children);
163
+ }
164
+ if (refused.length > 0) {
165
+ emit(sinks.refused, "local_data_dir_mode_refused", {
166
+ count: refused.length,
167
+ mode: "0700",
168
+ entries: refused.slice(0, REFUSED_LISTED),
169
+ remedy: "these directories (relative to the data root) could not be tightened or read, or are reached through a symbolic link (SYMLINK_IN_PATH: links are never followed, the data root itself included) — as the owner of the real directory run `chmod 700` on it (or chown it to the server's user) and restart; the server keeps serving meanwhile",
170
+ });
171
+ }
172
+ if (tightened.length > 0) {
173
+ emit(sinks.tightened, "local_data_dir_modes_tightened", {
174
+ count: tightened.length,
175
+ mode: "0700",
176
+ examples: tightened.slice(0, TIGHTENED_EXAMPLES),
177
+ note: "store directories created by earlier versions with the default mode were tightened to 0700 once; later boots find them tight",
178
+ });
179
+ }
180
+ return { tightened, refused };
181
+ }
182
+ //# sourceMappingURL=local-data-dir-modes-m39.js.map
@@ -0,0 +1,11 @@
1
+ /** marker 的文件名(数据根顶层;公开契约)。 */
2
+ export declare const ENGINE_HIGH_WATER_FILE = "engine-high-water.json";
3
+ /**
4
+ * **判与抬**(唯一的座;唯一调用点 `openLocalBackend`,数据根锁在手、本仓任何一只店建起之前):
5
+ * ① 本构建版本 `engine` 按发布线读不出({@link buildReleaseTriple})⇒ 抛 {@link StoreBootRefusalError}(marker 不读、不写);
6
+ * ② 读 `<root>/engine-high-water.json`:读不出 / 高水位高于本构建 ⇒ 抛 {@link LocalDataRootSchemaMismatchError}(`boot` 形;文件原地不动,不抬);
7
+ * ③ 缺席或低于本构建 ⇒ 原子写 `{"highWater": <本构建的纯三段>}`(`required`);相等 ⇒ 不写,只过持久化屏障(读到的可能是上一次没证完的那份)。写不进 / 证不了 ⇒ 抛(点名路径与原因)。
8
+ * 同步:它在后端打开的同步段里跑(建店之前),拒在这里就不会有一只店被建起。
9
+ */
10
+ export declare function holdEngineHighWater(root: string, engine: string): void;
11
+ //# sourceMappingURL=local-engine-high-water.d.ts.map