@sema-agent/server 7.149.0 → 7.151.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 (441) hide show
  1. package/MIGRATION.md +307 -9
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +92 -40
  5. package/deploy/sema-up/README.md +7 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  9. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  10. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  11. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  12. package/deploy/sema-up/chart/values.yaml +8 -1
  13. package/deploy/sema-up/cluster-up.sh +1 -0
  14. package/deploy/sema-up/kube-up.sh +1 -1
  15. package/deploy/sema-up/lib/flagshape.sh +1 -1
  16. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  17. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  18. package/dist/adoption/import.js +3 -3
  19. package/dist/approval-ask-machine.d.ts +1 -1
  20. package/dist/approval-card.d.ts +3 -3
  21. package/dist/approval-gate-currency.d.ts +2 -2
  22. package/dist/audit.d.ts +1 -1
  23. package/dist/audit.js +2 -2
  24. package/dist/auth-bridge.d.ts +20 -0
  25. package/dist/auth-bridge.js +9 -0
  26. package/dist/background-session-reap.d.ts +2 -2
  27. package/dist/bake-runner/main.d.ts +4 -2
  28. package/dist/bind-host.d.ts +2 -3
  29. package/dist/bind-host.js +2 -4
  30. package/dist/boot/budget-tracing.js +1 -1
  31. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  32. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  33. package/dist/boot/engine-lease.d.ts +5 -0
  34. package/dist/boot/engine-lease.js +1 -0
  35. package/dist/boot/execution-env.d.ts +8 -14
  36. package/dist/boot/execution-env.js +54 -17
  37. package/dist/boot/execution-lane.js +32 -5
  38. package/dist/boot/late-binds.d.ts +8 -4
  39. package/dist/boot/late-binds.js +7 -1
  40. package/dist/boot/memory-consolidation.d.ts +3 -2
  41. package/dist/boot/memory-consolidation.js +6 -6
  42. package/dist/boot/parked-revive-gate.d.ts +5 -5
  43. package/dist/boot/parked-revive-gate.js +2 -3
  44. package/dist/boot/reapers.d.ts +5 -0
  45. package/dist/boot/reapers.js +12 -1
  46. package/dist/boot/resolve-spec.d.ts +7 -8
  47. package/dist/boot/resolve-spec.js +80 -35
  48. package/dist/boot/retention-lane.d.ts +1 -1
  49. package/dist/boot/runner-deps.d.ts +9 -2
  50. package/dist/boot/runner-deps.js +3 -3
  51. package/dist/boot/session-age-out.d.ts +36 -0
  52. package/dist/boot/session-age-out.js +101 -0
  53. package/dist/boot/session-faces.d.ts +5 -14
  54. package/dist/boot/session-faces.js +28 -24
  55. package/dist/boot/stage-01-config.js +2 -0
  56. package/dist/boot/stage-03-store-backend.js +2 -2
  57. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  58. package/dist/boot/stage-05-execution-env.js +2 -2
  59. package/dist/boot/stage-06-runners.d.ts +7 -4
  60. package/dist/boot/stage-06-runners.js +16 -8
  61. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  62. package/dist/boot/stage-07-capability-layer.js +3 -2
  63. package/dist/boot/stage-08-reapers.d.ts +7 -4
  64. package/dist/boot/stage-08-reapers.js +4 -2
  65. package/dist/boot/stage-09-leader.d.ts +11 -5
  66. package/dist/boot/stage-09-leader.js +12 -3
  67. package/dist/boot/stage-10-http-server.d.ts +44 -6
  68. package/dist/boot/stage-10-http-server.js +12 -10
  69. package/dist/boot/web-admin.d.ts +1 -1
  70. package/dist/boot/web-admin.js +3 -1
  71. package/dist/boot/workflow-orchestration.d.ts +7 -2
  72. package/dist/boot/workflow-orchestration.js +24 -7
  73. package/dist/bounded-rotation.d.ts +29 -0
  74. package/dist/bounded-rotation.js +24 -0
  75. package/dist/capability-facts.d.ts +84 -66
  76. package/dist/capability-facts.js +58 -41
  77. package/dist/center-credential.d.ts +25 -6
  78. package/dist/center-credential.js +25 -5
  79. package/dist/config-catalog.d.ts +26 -7
  80. package/dist/config-catalog.js +15 -12
  81. package/dist/config-invariants.d.ts +2 -1
  82. package/dist/config-invariants.js +4 -4
  83. package/dist/config-types.d.ts +22 -15
  84. package/dist/config.d.ts +51 -2
  85. package/dist/config.js +35 -24
  86. package/dist/deployment-governance.d.ts +7 -28
  87. package/dist/deployment-governance.js +1 -14
  88. package/dist/deployment-shape.d.ts +9 -1
  89. package/dist/deployment-shape.js +2 -1
  90. package/dist/device-protocol.d.ts +5 -4
  91. package/dist/device-protocol.js +1 -1
  92. package/dist/device-ws-hub.d.ts +1 -0
  93. package/dist/device-ws-hub.js +66 -29
  94. package/dist/device-ws-protocol.d.ts +79 -12
  95. package/dist/device-ws-protocol.js +64 -26
  96. package/dist/engine-identity.d.ts +23 -5
  97. package/dist/engine-identity.js +13 -0
  98. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  99. package/dist/execution-env-refusal.d.ts +23 -0
  100. package/dist/execution-env-refusal.js +5 -0
  101. package/dist/execution-lane-caps.d.ts +3 -1
  102. package/dist/field-conflict.d.ts +3 -3
  103. package/dist/file-history-capture.d.ts +11 -4
  104. package/dist/file-history-capture.js +9 -6
  105. package/dist/file-history-disclosure.d.ts +7 -5
  106. package/dist/file-history-disclosure.js +7 -5
  107. package/dist/fleet/drain-entry.d.ts +4 -0
  108. package/dist/fleet/engine-signal.d.ts +14 -1
  109. package/dist/fleet/engine-signal.js +5 -1
  110. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  111. package/dist/fleet/serving-lease.d.ts +18 -3
  112. package/dist/fleet/serving-lease.js +81 -35
  113. package/dist/fleet-client.d.ts +13 -11
  114. package/dist/fleet-client.js +53 -33
  115. package/dist/history-anchor.js +1 -1
  116. package/dist/hitl-delivery.d.ts +1 -3
  117. package/dist/hitl-delivery.js +1 -1
  118. package/dist/hooks/hook-runner.js +2 -2
  119. package/dist/host-lsp-manager.d.ts +2 -2
  120. package/dist/http/active-run-conflict.d.ts +3 -7
  121. package/dist/http/active-run-conflict.js +2 -2
  122. package/dist/http/admission.js +19 -4
  123. package/dist/http/approval-sweeps.js +7 -6
  124. package/dist/http/caller-trust.d.ts +2 -2
  125. package/dist/http/caller-trust.js +3 -3
  126. package/dist/http/checkpoint-ctx.d.ts +20 -63
  127. package/dist/http/checkpoint-ctx.js +2 -24
  128. package/dist/http/claim-heartbeat.d.ts +4 -4
  129. package/dist/http/claim-heartbeat.js +3 -3
  130. package/dist/http/dispatch.d.ts +2 -1
  131. package/dist/http/dispatch.js +36 -29
  132. package/dist/http/durable-run-leg.js +17 -17
  133. package/dist/http/health-self-report.d.ts +9 -1
  134. package/dist/http/health-self-report.js +2 -0
  135. package/dist/http/owner-access.d.ts +264 -20
  136. package/dist/http/owner-access.js +215 -5
  137. package/dist/http/readiness.d.ts +4 -2
  138. package/dist/http/resume-ctx-read.js +38 -1
  139. package/dist/http/resume-legs.d.ts +2 -1
  140. package/dist/http/resume-legs.js +273 -89
  141. package/dist/http/route-ctx.d.ts +41 -19
  142. package/dist/http/route-table.d.ts +1 -1
  143. package/dist/http/routes/a2a-serve.js +15 -14
  144. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  145. package/dist/http/routes/agents-roster.js +2 -3
  146. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  147. package/dist/http/routes/approvals-assistant.js +12 -12
  148. package/dist/http/routes/background.d.ts +3 -3
  149. package/dist/http/routes/capabilities.js +10 -6
  150. package/dist/http/routes/config-catalog.d.ts +1 -1
  151. package/dist/http/routes/fleet.js +10 -8
  152. package/dist/http/routes/mcp-reconnect.js +2 -2
  153. package/dist/http/routes/memory-origin.d.ts +1 -1
  154. package/dist/http/routes/notify-wake.js +2 -3
  155. package/dist/http/routes/projects.d.ts +4 -2
  156. package/dist/http/routes/projects.js +7 -6
  157. package/dist/http/routes/retention-ops.d.ts +1 -1
  158. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  159. package/dist/http/routes/run-permission-mode.js +2 -2
  160. package/dist/http/routes/runs.d.ts +1 -1
  161. package/dist/http/routes/runs.js +125 -66
  162. package/dist/http/routes/session-memory-sync.js +4 -5
  163. package/dist/http/routes/session-sync.d.ts +4 -3
  164. package/dist/http/routes/session-sync.js +174 -83
  165. package/dist/http/routes/sessions-list.js +13 -7
  166. package/dist/http/routes/sessions.d.ts +1 -1
  167. package/dist/http/routes/sessions.js +26 -48
  168. package/dist/http/routes/tasks.js +38 -23
  169. package/dist/http/routes/trace-usage.js +14 -14
  170. package/dist/http/routes/workflows.d.ts +1 -0
  171. package/dist/http/routes/workflows.js +20 -38
  172. package/dist/http/server.d.ts +28 -30
  173. package/dist/http/server.js +7 -3
  174. package/dist/http/stored-body-replay.d.ts +3 -24
  175. package/dist/http/stored-body-replay.js +2 -12
  176. package/dist/http/submit-ctx.d.ts +1 -2
  177. package/dist/http/submit-ctx.js +8 -6
  178. package/dist/http/submit-replay.d.ts +15 -2
  179. package/dist/http/submit-replay.js +10 -4
  180. package/dist/http/wire-types.d.ts +19 -6
  181. package/dist/identity-source.d.ts +20 -3
  182. package/dist/identity-source.js +14 -0
  183. package/dist/index.d.ts +4 -0
  184. package/dist/lane-home-probe.d.ts +3 -7
  185. package/dist/lane-home-probe.js +0 -1
  186. package/dist/leader/endpoint.js +9 -8
  187. package/dist/leader/leader.d.ts +2 -1
  188. package/dist/leg-facts.d.ts +19 -5
  189. package/dist/leg-facts.js +3 -1
  190. package/dist/mcp-authorization-face.d.ts +18 -14
  191. package/dist/mcp-authorization-face.js +3 -2
  192. package/dist/memory-scope.d.ts +5 -4
  193. package/dist/memory-scope.js +4 -4
  194. package/dist/memory-store-refusal.d.ts +1 -1
  195. package/dist/memory-sync-client.d.ts +30 -2
  196. package/dist/memory-sync-client.js +16 -9
  197. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  198. package/dist/observability/err-text.d.ts +7 -0
  199. package/dist/observability/err-text.js +5 -0
  200. package/dist/observability/fail-open.d.ts +12 -8
  201. package/dist/observability/fail-open.js +12 -8
  202. package/dist/observability/logger.d.ts +7 -0
  203. package/dist/observability/logger.js +3 -1
  204. package/dist/observability/metrics.js +1 -0
  205. package/dist/observability/run-terminal.d.ts +1 -1
  206. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  207. package/dist/orchestration/workflow-notify-journal.js +12 -1
  208. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  209. package/dist/orchestration/workflow-park-decision.js +49 -10
  210. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  211. package/dist/orchestration/workflow-park-holder.js +98 -0
  212. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  213. package/dist/orchestration/workflow-record-fence.js +42 -0
  214. package/dist/owner-faces.d.ts +28 -4
  215. package/dist/owner-faces.js +2 -0
  216. package/dist/parked-decide.d.ts +104 -53
  217. package/dist/parked-decide.js +153 -117
  218. package/dist/peer-directory.d.ts +2 -2
  219. package/dist/peer-inbound-face.d.ts +2 -6
  220. package/dist/peer-inbound-face.js +0 -3
  221. package/dist/peer-seat.d.ts +1 -1
  222. package/dist/peer-seat.js +52 -59
  223. package/dist/permission-mode-admission.d.ts +41 -5
  224. package/dist/permission-mode-admission.js +29 -3
  225. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  226. package/dist/plugins/adoption-log-sql.js +7 -1
  227. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  228. package/dist/plugins/approval-ask-store-file.js +8 -0
  229. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  230. package/dist/plugins/approval-ask-store-memory.js +28 -9
  231. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  232. package/dist/plugins/approval-ask-store-sql.js +34 -5
  233. package/dist/plugins/approval-exemption-store.js +3 -0
  234. package/dist/plugins/approval-nonce-store.js +2 -0
  235. package/dist/plugins/breaker-state-sql.js +2 -0
  236. package/dist/plugins/caching-session-store.d.ts +9 -15
  237. package/dist/plugins/caching-session-store.js +6 -0
  238. package/dist/plugins/device-store-sql.js +6 -0
  239. package/dist/plugins/error-origin.d.ts +18 -0
  240. package/dist/plugins/error-origin.js +10 -0
  241. package/dist/plugins/exec-path-law.d.ts +34 -0
  242. package/dist/plugins/exec-path-law.js +13 -0
  243. package/dist/plugins/execution-placement-sql.js +6 -6
  244. package/dist/plugins/file-run-store.js +1 -1
  245. package/dist/plugins/image-bake-store-sql.js +6 -0
  246. package/dist/plugins/image-index-sql.js +4 -0
  247. package/dist/plugins/landed-attendants.d.ts +212 -0
  248. package/dist/plugins/landed-attendants.js +161 -0
  249. package/dist/plugins/leader-run-store-sql.js +4 -0
  250. package/dist/plugins/local-checkpoint-store.d.ts +4 -1
  251. package/dist/plugins/local-checkpoint-store.js +3 -0
  252. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  253. package/dist/plugins/local-session-live-reference.js +39 -0
  254. package/dist/plugins/local-session-store.d.ts +71 -33
  255. package/dist/plugins/local-session-store.js +129 -27
  256. package/dist/plugins/memory-engine-pg.js +4 -0
  257. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  258. package/dist/plugins/memory-engine-tidb.js +4 -0
  259. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  260. package/dist/plugins/memory-run-store.js +1 -1
  261. package/dist/plugins/memory-sync-store-pg.js +5 -0
  262. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  263. package/dist/plugins/one-time-migrations.d.ts +80 -61
  264. package/dist/plugins/one-time-migrations.js +241 -104
  265. package/dist/plugins/org-delivery-quota-store.js +4 -1
  266. package/dist/plugins/outcome-ledger-sql.js +2 -0
  267. package/dist/plugins/permission-rule-store-sql.js +11 -4
  268. package/dist/plugins/pg-cost-quota.js +4 -0
  269. package/dist/plugins/pg-pool.js +28 -1
  270. package/dist/plugins/pg-rate-limiter.js +2 -0
  271. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  272. package/dist/plugins/posix-shell-fs.js +8 -3
  273. package/dist/plugins/remote-env-adb.d.ts +19 -15
  274. package/dist/plugins/remote-env-adb.js +44 -17
  275. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  276. package/dist/plugins/remote-env-connect-seat.js +72 -0
  277. package/dist/plugins/remote-env-device.d.ts +22 -5
  278. package/dist/plugins/remote-env-device.js +114 -14
  279. package/dist/plugins/remote-env-e2b.d.ts +18 -7
  280. package/dist/plugins/remote-env-e2b.js +53 -40
  281. package/dist/plugins/remote-env-file-error.js +6 -2
  282. package/dist/plugins/remote-env-host.d.ts +18 -1
  283. package/dist/plugins/remote-env-host.js +48 -47
  284. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  285. package/dist/plugins/remote-env-k8s.js +56 -32
  286. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  287. package/dist/plugins/remote-env-local-docker.js +37 -43
  288. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  289. package/dist/plugins/remote-env-ssh.js +64 -62
  290. package/dist/plugins/remote-shell.d.ts +101 -2
  291. package/dist/plugins/remote-shell.js +221 -3
  292. package/dist/plugins/replica-registration.d.ts +35 -0
  293. package/dist/plugins/replica-registration.js +48 -0
  294. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  295. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  296. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  297. package/dist/plugins/retention-lane-store-sql.js +4 -0
  298. package/dist/plugins/retention-sql.d.ts +20 -2
  299. package/dist/plugins/retention-sql.js +11 -0
  300. package/dist/plugins/run-store-sql.d.ts +22 -3
  301. package/dist/plugins/run-store-sql.js +33 -9
  302. package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
  303. package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
  304. package/dist/plugins/schema-consistency.d.ts +9 -5
  305. package/dist/plugins/schema-consistency.js +48 -18
  306. package/dist/plugins/schema-drift-sentence.js +1 -1
  307. package/dist/plugins/send-file-ledger.js +3 -0
  308. package/dist/plugins/serving-requirement.d.ts +68 -0
  309. package/dist/plugins/serving-requirement.js +60 -0
  310. package/dist/plugins/session-birth.d.ts +6 -2
  311. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  312. package/dist/plugins/session-ext-table.d.ts +14 -1
  313. package/dist/plugins/session-ext-table.js +5 -1
  314. package/dist/plugins/session-row-sql.d.ts +49 -2
  315. package/dist/plugins/session-row-sql.js +56 -13
  316. package/dist/plugins/session-store-sql.d.ts +34 -18
  317. package/dist/plugins/session-store-sql.js +98 -17
  318. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  319. package/dist/plugins/shared-memory-store-sql.js +6 -2
  320. package/dist/plugins/sql-driver.d.ts +2 -1
  321. package/dist/plugins/sql-driver.js +18 -3
  322. package/dist/plugins/sql-errors.d.ts +11 -6
  323. package/dist/plugins/sql-errors.js +5 -6
  324. package/dist/plugins/stop-then-start-sentence.d.ts +48 -3
  325. package/dist/plugins/stop-then-start-sentence.js +48 -0
  326. package/dist/plugins/stop-then-start.d.ts +109 -0
  327. package/dist/plugins/stop-then-start.js +104 -0
  328. package/dist/plugins/store-backend.d.ts +40 -13
  329. package/dist/plugins/store-backend.js +169 -27
  330. package/dist/plugins/store-boundary.d.ts +57 -0
  331. package/dist/plugins/store-boundary.js +139 -0
  332. package/dist/plugins/store-contracts.d.ts +29 -2
  333. package/dist/plugins/store-contracts.js +3 -0
  334. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  335. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  336. package/dist/plugins/store-fault.d.ts +26 -7
  337. package/dist/plugins/store-fault.js +18 -2
  338. package/dist/plugins/task-attachment-store.js +9 -0
  339. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  340. package/dist/plugins/task-list-store-sql.js +10 -8
  341. package/dist/plugins/tidb-cost-quota.js +4 -0
  342. package/dist/plugins/tidb-pool.js +6 -1
  343. package/dist/plugins/tidb-rate-limiter.js +4 -0
  344. package/dist/plugins/user-input-ledger-sql.js +4 -0
  345. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  346. package/dist/plugins/workflow-run-store-sql.js +64 -4
  347. package/dist/plugins/workspace-fill.d.ts +4 -7
  348. package/dist/plugins/workspace-fill.js +2 -1
  349. package/dist/plugins/write-behind-counter.js +5 -0
  350. package/dist/process-instance.d.ts +3 -0
  351. package/dist/process-instance.js +7 -0
  352. package/dist/project-context.d.ts +64 -0
  353. package/dist/project-context.js +66 -0
  354. package/dist/project-registry.d.ts +46 -0
  355. package/dist/project-registry.js +44 -0
  356. package/dist/question.d.ts +9 -21
  357. package/dist/question.js +28 -19
  358. package/dist/request-key-closure.js +1 -1
  359. package/dist/request-value-closure.d.ts +4 -0
  360. package/dist/request-value-closure.js +10 -0
  361. package/dist/run-acceptance.d.ts +3 -2
  362. package/dist/run-acceptance.js +4 -6
  363. package/dist/run-cancel-card.d.ts +1 -1
  364. package/dist/run-cancel-card.js +2 -1
  365. package/dist/run-local.js +1 -0
  366. package/dist/runs.d.ts +37 -8
  367. package/dist/runs.js +53 -12
  368. package/dist/runtime-governance.d.ts +5 -4
  369. package/dist/security.d.ts +31 -33
  370. package/dist/security.js +41 -7
  371. package/dist/server-secret-env.d.ts +12 -10
  372. package/dist/server-secret-env.js +24 -15
  373. package/dist/session-agent.d.ts +1 -10
  374. package/dist/session-agent.js +0 -6
  375. package/dist/session-bindings.d.ts +82 -0
  376. package/dist/session-bindings.js +18 -0
  377. package/dist/session-children-retire.d.ts +2 -2
  378. package/dist/session-children-retire.js +2 -6
  379. package/dist/session-deletion.d.ts +16 -1
  380. package/dist/session-error-wire.d.ts +3 -3
  381. package/dist/session-error-wire.js +3 -3
  382. package/dist/session-incarnation.d.ts +28 -4
  383. package/dist/session-incarnation.js +14 -2
  384. package/dist/session-kind.d.ts +57 -0
  385. package/dist/session-kind.js +22 -0
  386. package/dist/session-notify-door.d.ts +4 -4
  387. package/dist/session-notify-door.js +5 -6
  388. package/dist/session-row.d.ts +21 -1
  389. package/dist/session-row.js +7 -1
  390. package/dist/session-rules-seat.d.ts +4 -3
  391. package/dist/session-rules-seat.js +3 -11
  392. package/dist/session-sync-kernel.d.ts +24 -14
  393. package/dist/session-sync-kernel.js +3 -6
  394. package/dist/session-sync.d.ts +4 -98
  395. package/dist/session-sync.js +4 -74
  396. package/dist/session-titler.d.ts +10 -3
  397. package/dist/session-titler.js +19 -6
  398. package/dist/ssh-host-key.d.ts +5 -0
  399. package/dist/ssh-host-key.js +3 -0
  400. package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
  401. package/dist/stores-sql/checkpoint-store-sql.js +106 -18
  402. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  403. package/dist/stores-sql/file-history-store-sql.js +108 -70
  404. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  405. package/dist/stores-sql/pg-session-storage.js +37 -13
  406. package/dist/stores-sql/retention-store-sql.d.ts +2 -10
  407. package/dist/stores-sql/retention-store-sql.js +2 -10
  408. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  409. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  410. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  411. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  412. package/dist/stores-sql/tidb-session-store.js +37 -13
  413. package/dist/submission-exit.d.ts +3 -2
  414. package/dist/submission-exit.js +9 -1
  415. package/dist/task-cwd.d.ts +6 -5
  416. package/dist/task-settings.d.ts +19 -5
  417. package/dist/task-settings.js +13 -7
  418. package/dist/terminal.d.ts +33 -2
  419. package/dist/terminal.js +139 -9
  420. package/dist/tool-approval.d.ts +147 -12
  421. package/dist/tool-approval.js +206 -109
  422. package/dist/trace/engine-notice-wire.d.ts +14 -0
  423. package/dist/trace/engine-notice-wire.js +18 -1
  424. package/dist/trace/project.d.ts +4 -3
  425. package/dist/trace/project.js +3 -2
  426. package/dist/trace/projection-table.d.ts +33 -2
  427. package/dist/trace/self-minted-wire.d.ts +422 -26
  428. package/dist/trace/self-minted-wire.js +149 -23
  429. package/dist/trace/tool-card.d.ts +3 -0
  430. package/dist/trace/tool-card.js +24 -0
  431. package/dist/trace/tool-output-media.d.ts +2 -1
  432. package/dist/unattended-permission-mode.d.ts +1 -1
  433. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  434. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  435. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  436. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
  437. package/package.json +3 -3
  438. package/wire-changes/server@7.150.0.json +335 -0
  439. package/wire-changes/server@7.151.0.json +762 -0
  440. package/dist/http/session-inherit-env.d.ts +0 -36
  441. package/dist/http/session-inherit-env.js +0 -6
@@ -152,10 +152,15 @@ pre-auth frame closes the connection outright.
152
152
 
153
153
  **Which revision to declare.** `challenge.protocolVersion` is the highest protocol revision this server speaks
154
154
  (`DEVICE_MIN_PROTOCOL_VERSION` is the lowest it accepts, §2.1). Put the highest revision *you* implement that is
155
- not above `challenge.protocolVersion` into `hello.protocolVersion` — the same integer you sign (§1.3) — and emit
156
- only the `errorCode` words of that revision (the revision table in §2.1). Nothing is renegotiated after `hello`:
155
+ not above `challenge.protocolVersion` into `hello.protocolVersion` — the same integer you sign (§1.3) — declare in
156
+ `supports` only the instruction kinds of that revision, and emit only the `errorCode` words of that revision (the revision
157
+ table in §2.1). Nothing is renegotiated after `hello`:
157
158
  the revision you declared is the contract for the whole connection. If the highest revision you implement is below
158
159
  `DEVICE_MIN_PROTOCOL_VERSION`, the server answers `helloReject: protocol_version_unsupported` (§1.4).
160
+ Revisions are cumulative on the executor's side: an executor that implements revision *N* implements every revision
161
+ below it, so against an older server it declares that server's revision (a revision-5 executor serves a revision-4
162
+ server, whose paths arrive folded — a subset of what revision 5 sends). `DEVICE_MIN_PROTOCOL_VERSION` is the lowest
163
+ revision **this server** accepts, not a floor for your own negotiation.
159
164
 
160
165
  ### 1.3 The `hello` signature (byte-exact — do not improvise)
161
166
 
@@ -247,7 +252,7 @@ sign exactly these bytes with the device's Ed25519 private key.
247
252
  |---|---|---|
248
253
  | `auth_failed` | deliberately ambiguous: unknown device id, malformed id, malformed epoch, bad signature, or the server's device registry was unreachable | do **not** hammer: back off exponentially. If it never clears, the enrollment is gone — re-enroll. The server will not tell you which of these it was (anti-enumeration) |
249
254
  | `revoked` | this device has been revoked. Terminal | stop reconnecting, delete the private key, ask the user to re-enroll (it yields a new `deviceId`) |
250
- | `protocol_version_unsupported` | your `protocolVersion` is outside the range this server accepts; the frame carries `minProtocolVersion` | upgrade the executor. Never retry-with-a-different-version in a loop |
255
+ | `protocol_version_unsupported` | your `protocolVersion` is outside the range this server accepts; the frame carries `minProtocolVersion` and a one-line `message` that names your revision, the range and — below the floor — the change at the floor revision (§2.1) | upgrade the executor (`message` is fit to show as is). Never retry-with-a-different-version in a loop |
251
256
  | `draining` | this replica is shutting down or upgrading and takes no new connections | reconnect with backoff; a replacement replica will accept you |
252
257
  | `already_connected` | **the connection lease for this `deviceId` is not available right now**: a previous connection is still considered fresh, the stored lease has not expired yet, or the deployment forbids takeover | retry with bounded backoff — the lease expires on its own (deployment default 45 s, and a previous socket is judged stale after ~3 missed heartbeats). This code does **not** prove another process is alive: a half-open network drop can make your *own* previous connection look fresh. Do not exit permanently on it; do hold a machine-local single-instance lock so you are never racing yourself |
253
258
 
@@ -341,8 +346,8 @@ base64 inside JSON fields.
341
346
  | Constant | Value | Meaning |
342
347
  |---|---|---|
343
348
  | `DEVICE_WS_PATH` | `/v1/device/ws` | the upgrade path (prefer the `wsPath` from `/v1/capabilities`) |
344
- | `DEVICE_PROTOCOL_VERSION` | `4` | the protocol revision this server speaks (the highest it accepts) |
345
- | `DEVICE_MIN_PROTOCOL_VERSION` | `1` | the lowest revision it accepts; below it (or above the highest), a loud `helloReject` — never a silent downgrade |
349
+ | `DEVICE_PROTOCOL_VERSION` | `6` | the protocol revision this server speaks (the highest it accepts) |
350
+ | `DEVICE_MIN_PROTOCOL_VERSION` | `5` | the lowest revision it accepts (the revision table says why); below it (or above the highest), a loud `helloReject` — never a silent downgrade |
346
351
  | `DEVICE_HELLO_DOMAIN_TAG` | `sema.device.hello.v1` | the handshake signature domain tag (§1.3) |
347
352
 
348
353
  <!-- closed-set: DEVICE_WS_LIMITS -->
@@ -357,30 +362,48 @@ base64 inside JSON fields.
357
362
  Note the asymmetry: the transport cap is 1 MiB, and the 4096-byte pre-auth cap is applied **after** the
358
363
  frame has been reassembled. Keep `hello` small; it is not a place for long `supports` prose.
359
364
 
360
- #### Protocol revisions and the `errorCode` set
365
+ `maxFrameBytes` binds the server too: every frame it sends is measured after serialization and is never over the
366
+ cap. An instruction whose frame would be over it is refused before dispatch (you never receive it), and `payload`
367
+ chunks are sliced so that a chunk frame, base64 and envelope included, fits. You can therefore cap the frames you
368
+ accept at `maxFrameBytes`.
369
+
370
+ #### Protocol revisions: the `errorCode` set and the instruction kinds
361
371
 
362
372
  The protocol revision is the only thing an executor can read *before* it sends `hello` (the `challenge` frame
363
- carries it), so the set of `errorCode` words the server accepts from you is a function of the revision, not a
364
- separate list. The table gives, per revision, the words **added** at that revision; the set at revision *N* is
365
- the union of the rows up to *N*, and the full set at the current revision is the §3.3 table.
373
+ carries it), so everything you must know to be correct on this server is a function of the revision, not a
374
+ separate list: the set of `errorCode` words the server accepts from you, the set of instruction kinds it may send you,
375
+ and what the frames it sends you mean. The table gives, per revision, the words **added** to each set at that revision
376
+ and any other change made at it; a set at revision *N* is the union of its column's rows up to *N*, and the full sets at
377
+ the current revision are the §3.3 table (`errorCode`) and the §3.1 table (instruction kinds, in this order).
366
378
 
367
379
  <!-- closed-set: DEVICE_OUTCOME_ERROR_CODES_BY_REVISION -->
368
380
 
369
- | Revision | `errorCode` words added at this revision |
370
- |---|---|
371
- | `1` | `aborted`, `already_exists`, `auth_failed`, `callback_error`, `invalid`, `is_directory`, `not_directory`, `not_found`, `not_supported`, `outcome_unknown`, `permission_denied`, `precondition_failed`, `shell_unavailable`, `spawn_error`, `suspended`, `target_unavailable`, `timeout`, `transport_lost`, `unknown` |
372
- | `2` | `liveness_no_output` |
373
- | `3` | `name_too_long` |
374
- | `4` | `symlink_loop` |
375
-
376
- Rules: adding a frame or a field is additive and does not raise the revision; adding a word to a closed set the
377
- server *accepts from you* (today: the `errorCode` set) raises `DEVICE_PROTOCOL_VERSION` and adds a row here; a
378
- released row never changes. Declare a revision as §1.2 says and send only the words of that revision: an executor
381
+ | Revision | `errorCode` words added at this revision | Instruction kinds added at this revision | Other change at this revision |
382
+ |---|---|---|---|
383
+ | `1` | `aborted`, `already_exists`, `auth_failed`, `callback_error`, `invalid`, `is_directory`, `not_directory`, `not_found`, `not_supported`, `outcome_unknown`, `permission_denied`, `precondition_failed`, `shell_unavailable`, `spawn_error`, `suspended`, `target_unavailable`, `timeout`, `transport_lost`, `unknown` | `exec`, `execStream`, `readTextFile`, `readTextLines`, `readBinaryFile`, `writeFile`, `writeFileExclusive`, `writeFileGuarded`, `appendFile`, `fileInfo`, `listDir`, `canonicalPath`, `exists`, `readLink`, `createDir`, `remove`, `createTempDir`, `createTempFile`, `statBatch` | — |
384
+ | `2` | `liveness_no_output` | — | — |
385
+ | `3` | `name_too_long` | — | — |
386
+ | `4` | `symlink_loop` | — | — |
387
+ | `5` | — | — | every path an instruction carries (`args.path`, `args.paths`, `cwd`) arrives **unfolded** (since server 7.150.0): absolute as written, or anchored at the session's working directory, with `.` / `..` / empty segments kept — the server anchors and never folds. Resolve it as your filesystem does and judge containment on where it resolves (§3.1, §6 item 6). An executor written for revision 4 or below expects folded paths, so this is also the lowest revision the server accepts |
388
+ | `6` | — | `openBound` | — |
389
+
390
+ Rules: adding a frame or a field is additive and does not raise the revision. Every other change
391
+ raises `DEVICE_PROTOCOL_VERSION` and adds a row here — a word added to either closed set of the instruction exchange:
392
+ an `errorCode` word the server *accepts from you* (second column) or an instruction kind the server *sends you*
393
+ (third column) — or a **semantic change**, a change in what a frame the server sends you means (fourth column):
394
+ a semantic change raises the revision. A released row never changes. The server sends a kind only on a connection
395
+ whose declared revision is at or above the row that added it, and only if that connection's `supports` declares it
396
+ (§3.2): a kind above your revision is never sent to you, so an executor written for the older revision still honors
397
+ the newer one and the lowest accepted revision stays where it was (revision 6 added `openBound`; a revision-5 executor
398
+ never receives it). When an executor written for
399
+ an older revision cannot honor the change, the same release raises `DEVICE_MIN_PROTOCOL_VERSION` to the new
400
+ revision, so such an executor is refused once at `hello` (§1.4) instead of failing call by call.
401
+ Declare a revision as §1.2 says and use only the words of that revision: an executor
379
402
  that declared revision 1 never sends `liveness_no_output` (the server does not police this per connection — it
380
403
  decodes every connection against the current revision's full set — but a word above your declared revision is outside
381
- your contract). The same sets are importable:
382
- `DEVICE_OUTCOME_ERROR_CODES_BY_REVISION` and `deviceOutcomeErrorCodesAt(revision)` from
383
- `@sema-agent/server/device-protocol`.
404
+ your contract), and a kind above your declared revision in `supports` is ignored like a word the server does not know.
405
+ The same sets are importable: `DEVICE_OUTCOME_ERROR_CODES_BY_REVISION` / `deviceOutcomeErrorCodesAt(revision)` and
406
+ `DEVICE_INSTRUCTION_KINDS_BY_REVISION` / `deviceInstructionKindsAt(revision)` from `@sema-agent/server/device-protocol`.
384
407
 
385
408
  ### 2.2 Device → server frames
386
409
 
@@ -407,7 +430,7 @@ zeros, a plus sign, whitespace or a float form are rejected as malformed.
407
430
  |---|---|---|
408
431
  | `challenge` | `nonce` string, `protocolVersion` int | first frame the server sends, immediately on open |
409
432
  | `helloAck` | `ok`, `heartbeatIntervalMs`, `maxInflight`, `gen`, `pendingInstructions`, `chunkWatermarks`, `reconnectGraceMs`, `cancelGraceMs`, `chunkGapTimeoutMs`, `executionCeilingGraceMs` | §1.5 |
410
- | `helloReject` | `code`, `minProtocolVersion?` | §1.4; the socket closes right after |
433
+ | `helloReject` | `code`, `minProtocolVersion?`, `message?` | §1.4; `minProtocolVersion` and `message` appear on `protocol_version_unsupported` only; the socket closes right after |
411
434
  | `instruction` | `gen`, `instructionId`, `rootSessionId`, `issuedSeq` int, `kind`, `args`, `cwd?`, `shellEnv?`, `timeoutMs` int | one unit of work (§3). `cwd` appears on `exec` / `execStream` only, and always there (§3.1) |
412
435
  | `payload` | `gen`, `instructionId`, `part` (`begin` \| `chunk` \| `commit`), `offset?`, `dataB64?`, `totalLen?`, `sha256?` | the bytes for a write-family instruction (§3.4) |
413
436
  | `cancel` | `gen`, `instructionId` | idempotent; answer with a terminal `result` (§5 R11) |
@@ -480,11 +503,19 @@ silently forgiven: it becomes a gap or a missing terminal, and the instruction e
480
503
 
481
504
  ### 3.1 The closed set, its arguments, and the success outcome each one owes
482
505
 
483
- Every `path` in `args` arrives **already absolute and POSIX-normalized** — the server resolved it against
484
- the session's working directory before sending. `exec` and `execStream` additionally carry `cwd`, which is
485
- **always present and always absolute**: run the command in exactly that directory. There is no implicit
486
- base to fall back to, so an executor needs no branch for a missing or relative `cwd`. Every other kind
487
- carries no `cwd` — its paths are already absolute.
506
+ Every `path` in `args` arrives **already absolute** — the server anchored a relative one at the session's
507
+ working directory before sending — and **as written: a `..` or `.` segment, or an empty one, is never folded**
508
+ (revision 5, §2.1). Hand it to your
509
+ filesystem as it is. The kernel resolves `..` component by component, so a `..` that follows a symbolic link
510
+ goes where the link leads (`<root>/bridge/../next` with `bridge -> elsewhere/sub` is `<root>/elsewhere/next`,
511
+ not `<root>/next`) — and that is the file the engine's gates judged: they asked you about this same spelling
512
+ (`exists` / `canonicalPath` / `fileInfo` / `readLink`). `exec` and `execStream` additionally carry `cwd`, which is
513
+ **always present and always absolute** (unfolded the same way): run the command in exactly that directory.
514
+ There is no implicit base to fall back to, so an executor needs no branch for a missing or relative `cwd`.
515
+ Every other kind carries no `cwd` — its paths are already absolute. The paths the server reports back are its
516
+ own spellings, not the ones you return: `fileInfo` reports the path it asked; `listDir` reads only the leaf name
517
+ (last segment) of each entry's `WireFileInfo.path` and reports the entry as `<asked path>/<leaf>`, so a listed
518
+ entry can be asked again as written.
488
519
 
489
520
  <!-- closed-set: DEVICE_INSTRUCTION_KINDS -->
490
521
 
@@ -509,6 +540,7 @@ carries no `cwd` — its paths are already absolute.
509
540
  | `createTempDir` | `{ prefix? }` | `{ok:true, kind:"write", canonicalPath}` | the created directory's path **is** the receipt |
510
541
  | `createTempFile` | `{ prefix?, suffix? }` | `{ok:true, kind:"write", canonicalPath}` | same |
511
542
  | `statBatch` | `{ paths: string[] }` | `{ok:true, kind:"stat", …}` | declared but **not dispatched today** (see §8) |
543
+ | `openBound` | `{ path, op, identity?, kind?, max? }` | per `op`: `open` / `size` / `list` ⇒ `{ok:true, kind:"stat", …}`, `readBytes` ⇒ `{ok:true, kind:"read"}` | **optional face**, revision 6 — a bound read: the object judged is the object read (§3.7) |
512
544
 
513
545
  The server checks the outcome *kind* against the instruction kind. Answering an `execStream` with
514
546
  `{ok:true, kind:"void"}` — a perfectly well-formed frame — is refused as a protocol violation and the
@@ -517,22 +549,26 @@ outcome are always accepted.
517
549
 
518
550
  ### 3.2 Declaring what you implement: `hello.supports`
519
551
 
520
- `supports` is a plain `string[]` of instruction kinds. The server intersects it with its own closed set;
521
- **a kind you do not declare is never dispatched to you**, and a call that needs it fails loudly with
522
- `not_supported` instead of silently doing something else. A kind the server does not recognize is simply
523
- ignored (that is how a newer executor talks to an older server without breaking it).
552
+ `supports` is a plain `string[]` of instruction kinds. The server intersects it with the kinds of the revision you declared
553
+ (§2.1); **a kind you do not declare is never dispatched to you**, and a call that needs it fails loudly with
554
+ `not_supported` instead of silently doing something else. A kind the server does not recognize — or one above the
555
+ revision you declared — is simply ignored (that is how a newer executor talks to an older server without breaking it).
524
556
 
525
- Three faces are **presence-typed**, which is a stronger statement than "optional":
557
+ Four faces are **presence-typed**, which is a stronger statement than "optional":
526
558
 
527
559
  - `writeFileExclusive` — atomic create-if-absent
528
560
  - `writeFileGuarded` — verify-and-write in one atomic step
529
561
  - `readLink` — read a symlink target
562
+ - `openBound` — a bound read (§3.7): every answer is about the object that was opened and checked
530
563
 
531
564
  The engine decides *at environment-construction time* whether these exist, and when they do not it
532
565
  degrades honestly (an advisory check instead of an atomic one). **Therefore: absence is absence. Never
533
566
  emulate a guarded or exclusive write with a two-step "check then write".** A two-step emulation reopens
534
567
  exactly the race the atomic primitive exists to close, while wearing the face of an atomic operation —
535
- which is worse than not having it, because nothing downstream can tell.
568
+ which is worse than not having it, because nothing downstream can tell. The same holds for `openBound`:
569
+ **never emulate it with `fileInfo` + `readBinaryFile`** (two path reads cannot tell that the bytes came from the
570
+ object that was judged); without it, the engine simply does not bind a read on this device (a path attachment is
571
+ accepted and reported `not_attached`).
536
572
 
537
573
  Two more consequences you must design for:
538
574
 
@@ -567,8 +603,8 @@ a moment ago. If you omit `created`, the consumer reports the weaker of the two
567
603
 
568
604
  `message` is required on the failure arm and is shown to the model — make it specific.
569
605
 
570
- This is the full set at the current revision (`3`); the revision table in §2.1 says which revision each word arrived
571
- with, and an executor sends only the words of the revision it declared (§1.2).
606
+ This is the full set at the current revision (`DEVICE_PROTOCOL_VERSION`, §2.1); the revision table in §2.1 says which revision
607
+ each word arrived with, and an executor sends only the words of the revision it declared (§1.2).
572
608
 
573
609
  <!-- closed-set: DEVICE_OUTCOME_ERROR_CODES -->
574
610
 
@@ -689,8 +725,45 @@ side**. Verifying with `stat` and then writing is exactly the emulation that is
689
725
  - `readLink` — optional but strongly recommended: it is the fourth governance read, and its absence makes
690
726
  symlink adjudication coarser.
691
727
  - `writeFileExclusive`, `writeFileGuarded` — optional; implement them only if you can do them atomically.
728
+ - `openBound` — optional (revision 6); without it a path attachment on this device is accepted but not attached (§3.7).
692
729
  - `statBatch` — safe to omit today.
693
730
 
731
+
732
+ ### 3.7 `openBound` and its four answers
733
+
734
+ `openBound` is a revision-6 kind: the server sends it only on a connection whose `hello.protocolVersion` is 6 or above
735
+ **and** whose `supports` declares it. On a revision-5 connection the face is absent, exactly as if you had not declared
736
+ it (the engine does not bind a read; a path attachment is reported `not_attached`).
737
+
738
+ The protocol has no handle that lives across instructions, so the engine's bound-read object is answered one
739
+ instruction per answer. Every `openBound` instruction is a **complete rebinding**: open `path` locally (do not
740
+ follow a final symbolic link), ask the kernel **once, through that open**, which path the opened object now has and
741
+ what it is, answer **through that same open**, then close it. Never read the path a second time to answer.
742
+
743
+ <!-- closed-set: DEVICE_BOUND_READ_OPS -->
744
+
745
+ | `op` | Carries | Answer with | Refuse with |
746
+ |---|---|---|---|
747
+ | `open` | `path` | `{ok:true, kind:"stat", identity, info}` — `identity` = the opened object's `<device>:<inode>`; `info.kind` is `file` or `dir` | `precondition_failed` (the final component is a link, or the opened object is not at `path`); `invalid` (neither a regular file nor a directory) |
748
+ | `size` | `path`, `identity`, `kind` | `{ok:true, kind:"stat", info}` — `info.size` = the current size | `precondition_failed` when the object opened now is not `identity` / `kind` or not at `path` |
749
+ | `readBytes` | `path`, `identity`, `kind`, `max` | `{ok:true, kind:"read"}`, the bytes as `data` chunks | as `size`, plus `invalid` when the file is over `max` bytes when the read starts (read nothing) |
750
+ | `list` | `path`, `identity`, `kind` | `{ok:true, kind:"stat", entries}` — the opened directory's direct children, links not followed; the server reads only each entry's leaf name | as `size` |
751
+
752
+ Rules:
753
+
754
+ - **One observation per answer.** The check that the opened object is at `path` must be a single observation of
755
+ that open (Linux: `readlink("/proc/self/fd/<fd>")`; macOS: an open with `O_NOFOLLOW_ANY` refuses a link on any
756
+ component, so the open itself is the observation). Separate `fstat` / `lstat` / `realpath` calls are three
757
+ observations that a directory swapped in and out between them gets through. If your platform cannot give one
758
+ observation, answer `not_supported` — the engine reads that as "this face is absent here".
759
+ - **Identity and kind both.** For `size` / `readBytes` / `list`, the object you opened must equal both `identity`
760
+ and `kind` from the `open` answer, else `precondition_failed`. Two opens whose identities are equal do not prove
761
+ they opened one object after an inode number was reused; that residue is accepted by the engine's contract.
762
+ - **Bounded.** An open can block (a FIFO swapped in under the path); the whole answer must finish within the
763
+ instruction's `timeoutMs` and your executor must not leave the blocked open behind.
764
+ - **No privilege above the session's own commands.** Open as the same user that runs the session's `exec`.
765
+ - Error codes are the words of your declared revision (§2.1); nothing new is needed.
766
+
694
767
  ---
695
768
 
696
769
  ## 4. Streaming execution
@@ -972,11 +1045,16 @@ These two are a real distinction to the caller: `not_started` is safely retryabl
972
1045
  *Honest boundary*: this is a decision-and-audit property, not enforcement against a compromised
973
1046
  machine. The protocol assumes an honest executor; it protects against races and mistakes, not against
974
1047
  an executor that lies.
975
- 6. **Respect `workspaceRoot` and resolve nothing yourself.** Paths arrive absolute and normalized; the
976
- server has already resolved them against the session's working directory, falling back to the
977
- `workspaceRoot` you registered. Do not re-interpret them, do not expand `~`, do not follow a different
978
- base. You **may** enforce your own containment policy on top (refusing paths outside a root you are
979
- willing to serve) — if you do, refuse with `permission_denied`. What you must never do is silently
1048
+ 6. **Respect `workspaceRoot` and resolve nothing yourself.** Paths arrive absolute and unfolded; the
1049
+ server has already anchored them at the session's working directory, falling back to the
1050
+ `workspaceRoot` you registered. Do not re-interpret them: never fold a `..` lexically (with a link before
1051
+ it, the folded spelling names a different file than the one the gates judged), do not expand `~`, do not
1052
+ follow a different base. You **may** enforce your own containment policy on top (refusing paths outside a
1053
+ root you are willing to serve) — judge it on where the path resolves (the real path of its existing part),
1054
+ never on a string prefix of the spelling (`<root>/../etc` starts with `<root>/`); if you refuse, refuse
1055
+ with `permission_denied`. Negative control: with `bridge` a link to `/opt/x/sub` (outside the root),
1056
+ `<root>/bridge/../next` resolves to `/opt/x/next` — the link carried the `..` out of the root, so the
1057
+ answer is `permission_denied` (not `not_found`, not success). What you must never do is silently
980
1058
  redirect a path to somewhere else: a write that lands in a different place than the caller adjudicated
981
1059
  is the exact failure this lane is built to prevent.
982
1060
  7. **Do not cache and replay results.** No answer may be served from a cache keyed by command text, path
@@ -1027,6 +1105,7 @@ These two are a real distinction to the caller: `not_started` is safely retryabl
1027
1105
 
1028
1106
  - [ ] `readLink` (recommended soon after — it is the fourth governance read)
1029
1107
  - [ ] `writeFileExclusive`, `writeFileGuarded` — declare only when atomic (§3.2)
1108
+ - [ ] `openBound` — declare only with one observation per answer, and only when you declare revision 6 or above (§3.7)
1030
1109
  - [ ] `statBatch` — not dispatched today
1031
1110
 
1032
1111
  **Process shape (recommended)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.149.0",
3
+ "version": "7.151.0",
4
4
  "description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -83,8 +83,8 @@
83
83
  },
84
84
  "dependencies": {
85
85
  "@modelcontextprotocol/server": "2.4.0",
86
- "@sema-agent/core": "7.66.0",
87
- "@sema-agent/settings-schema": "24.0.0",
86
+ "@sema-agent/core": "7.66.1",
87
+ "@sema-agent/settings-schema": "25.1.0",
88
88
  "e2b": "2.36.0",
89
89
  "libsodium-wrappers": "0.8.4",
90
90
  "mysql2": "3.22.6",
@@ -0,0 +1,335 @@
1
+ {
2
+ "repo": "server",
3
+ "version": "7.150.0",
4
+ "from": "v7.149.0",
5
+ "fromCommit": "4ddd53ff8ba95bf63354b58203d01db51e025795",
6
+ "to": "v7.150.0",
7
+ "generator": "scripts/wire-changes-server.mjs",
8
+ "sources": [
9
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1",
10
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1b",
11
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1h",
12
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1g",
13
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.1",
14
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.1a",
15
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.2b",
16
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.2",
17
+ "docs/ASSISTANT-WIRE-CONTRACT.md#D.3",
18
+ "src/trace/wire-projection-faces.ts",
19
+ "src/trace/self-minted-wire.ts",
20
+ "node_modules/@sema-agent/core/wire-changes",
21
+ "src/trace/core-vocab-wire.ts"
22
+ ],
23
+ "added": [
24
+ {
25
+ "id": "A1",
26
+ "source": "capability",
27
+ "member": "projectInheritance",
28
+ "text": "附录 B.1 能力位新增 `projectInheritance`(谓词类 config 依赖)"
29
+ },
30
+ {
31
+ "id": "A2",
32
+ "source": "selfMinted.deviceProtocolRevision",
33
+ "member": "5",
34
+ "text": "自铸 GET /v1/capabilities deviceExecutor.protocolVersion 与 device WS challenge 帧的修订号(<修订号> → 它加进结局码闭集的词;零加词的语义修订 → 变更名) 新增 `5`(属性 paths-unfolded;since 7.150.0 = 本版新上 wire)"
35
+ },
36
+ {
37
+ "id": "A3",
38
+ "source": "selfMinted.listeningLineKey",
39
+ "member": "boundAddress",
40
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 新增 `boundAddress`(属性 always;since 7.150.0 = 本版新上 wire)"
41
+ },
42
+ {
43
+ "id": "A4",
44
+ "source": "selfMinted.projectRowKey",
45
+ "member": "contentAttestedAt",
46
+ "text": "自铸 GET /v1/projects projects[] 行键 = GET /v1/projects/:id 200 体(<键> → 在场律) 新增 `contentAttestedAt`(属性 present-iff the registration carries the configuration center's content attestation (settings-schema 25.1.0; the time the center's write path last admitted the project's goal / notes / contextItems under the publisher role);since 7.150.0 = 本版新上 wire)"
47
+ }
48
+ ],
49
+ "registered": [
50
+ {
51
+ "id": "L1",
52
+ "source": "selfMinted.listeningLineKey",
53
+ "member": "bindHost",
54
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `bindHost`(属性 always;since 1.306.0 —— 早于本版,只是登记)"
55
+ },
56
+ {
57
+ "id": "L2",
58
+ "source": "selfMinted.listeningLineKey",
59
+ "member": "bindHostNote",
60
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `bindHostNote`(属性 present-iff BIND_HOST unset and the bind was narrowed to loopback (unauthenticated write face);since 3.15.0 —— 早于本版,只是登记)"
61
+ },
62
+ {
63
+ "id": "L3",
64
+ "source": "selfMinted.listeningLineKey",
65
+ "member": "brain",
66
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `brain`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
67
+ },
68
+ {
69
+ "id": "L4",
70
+ "source": "selfMinted.listeningLineKey",
71
+ "member": "breakerState",
72
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `breakerState`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
73
+ },
74
+ {
75
+ "id": "L5",
76
+ "source": "selfMinted.listeningLineKey",
77
+ "member": "costQuota",
78
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `costQuota`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
79
+ },
80
+ {
81
+ "id": "L6",
82
+ "source": "selfMinted.listeningLineKey",
83
+ "member": "instanceId",
84
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `instanceId`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
85
+ },
86
+ {
87
+ "id": "L7",
88
+ "source": "selfMinted.listeningLineKey",
89
+ "member": "maxPrincipalCostUsd",
90
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `maxPrincipalCostUsd`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
91
+ },
92
+ {
93
+ "id": "L8",
94
+ "source": "selfMinted.listeningLineKey",
95
+ "member": "memory",
96
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `memory`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
97
+ },
98
+ {
99
+ "id": "L9",
100
+ "source": "selfMinted.listeningLineKey",
101
+ "member": "model",
102
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `model`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
103
+ },
104
+ {
105
+ "id": "L10",
106
+ "source": "selfMinted.listeningLineKey",
107
+ "member": "otel",
108
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `otel`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
109
+ },
110
+ {
111
+ "id": "L11",
112
+ "source": "selfMinted.listeningLineKey",
113
+ "member": "perModelKeys",
114
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `perModelKeys`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
115
+ },
116
+ {
117
+ "id": "L12",
118
+ "source": "selfMinted.listeningLineKey",
119
+ "member": "port",
120
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `port`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
121
+ },
122
+ {
123
+ "id": "L13",
124
+ "source": "selfMinted.listeningLineKey",
125
+ "member": "rateLimit",
126
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `rateLimit`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
127
+ },
128
+ {
129
+ "id": "L14",
130
+ "source": "selfMinted.listeningLineKey",
131
+ "member": "rateLimitPerMin",
132
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `rateLimitPerMin`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
133
+ },
134
+ {
135
+ "id": "L15",
136
+ "source": "selfMinted.listeningLineKey",
137
+ "member": "sealedModelKeys",
138
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `sealedModelKeys`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
139
+ },
140
+ {
141
+ "id": "L16",
142
+ "source": "selfMinted.listeningLineKey",
143
+ "member": "sealedPoisonedModels",
144
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `sealedPoisonedModels`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
145
+ },
146
+ {
147
+ "id": "L17",
148
+ "source": "selfMinted.listeningLineKey",
149
+ "member": "session",
150
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `session`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
151
+ },
152
+ {
153
+ "id": "L18",
154
+ "source": "selfMinted.listeningLineKey",
155
+ "member": "toolResultStore",
156
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `toolResultStore`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
157
+ },
158
+ {
159
+ "id": "L19",
160
+ "source": "selfMinted.listeningLineKey",
161
+ "member": "workflowRunStore",
162
+ "text": "自铸 stdout 启动协议行 listening(<键> → 在场律) 登记 `workflowRunStore`(属性 always;since 1.214.2 —— 早于本版,只是登记)"
163
+ },
164
+ {
165
+ "id": "L20",
166
+ "source": "selfMinted.mcpAuthorizationKey",
167
+ "member": "GET /v1/capabilities/mcp#servers[].authorization",
168
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `GET /v1/capabilities/mcp#servers[].authorization`(属性 present-iff errorCode unauthorized;since 7.138.0 —— 早于本版,只是登记)"
169
+ },
170
+ {
171
+ "id": "L21",
172
+ "source": "selfMinted.mcpAuthorizationKey",
173
+ "member": "GET /v1/runs/:id/events#tool_end.structured.authorization",
174
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `GET /v1/runs/:id/events#tool_end.structured.authorization`(属性 present-iff structured.code unauthorized and reason in the closed set; members = reason;since 7.138.0 —— 早于本版,只是登记)"
175
+ },
176
+ {
177
+ "id": "L22",
178
+ "source": "selfMinted.mcpAuthorizationKey",
179
+ "member": "GET /v1/sessions/:id#messages[].details.authorization",
180
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `GET /v1/sessions/:id#messages[].details.authorization`(属性 present-iff details.code unauthorized;since 7.138.0 —— 早于本版,只是登记)"
181
+ },
182
+ {
183
+ "id": "L23",
184
+ "source": "selfMinted.mcpAuthorizationKey",
185
+ "member": "GET /v1/sessions/:id/mcp#lastLegMcp.mcp[].authorization",
186
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `GET /v1/sessions/:id/mcp#lastLegMcp.mcp[].authorization`(属性 present-iff errorCode unauthorized;since 7.138.0 —— 早于本版,只是登记)"
187
+ },
188
+ {
189
+ "id": "L24",
190
+ "source": "selfMinted.mcpAuthorizationKey",
191
+ "member": "POST /v1/capabilities/mcp/probe#servers[].authorization",
192
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `POST /v1/capabilities/mcp/probe#servers[].authorization`(属性 present-iff errorCode unauthorized;since 7.138.0 —— 早于本版,只是登记)"
193
+ },
194
+ {
195
+ "id": "L25",
196
+ "source": "selfMinted.mcpAuthorizationKey",
197
+ "member": "SSE tool_end#structured.authorization",
198
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 登记 `SSE tool_end#structured.authorization`(属性 present-iff structured.code unauthorized and reason in the closed set; members = reason;since 7.138.0 —— 早于本版,只是登记)"
199
+ }
200
+ ],
201
+ "excluded": [],
202
+ "removed": [
203
+ {
204
+ "id": "R1",
205
+ "source": "selfMinted.mcpAuthorizationKey",
206
+ "member": "GET /v1/runs/:id/events#tool_end.structured.authorization(reason 以外的成员)",
207
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 于本版退役 `GET /v1/runs/:id/events#tool_end.structured.authorization(reason 以外的成员)`(原属性 card members passed through the text redactor (resourceMetadataUrl, a custom card's own members);自 7.138.0 起在 wire 上,until 7.150.0 = 本版)"
208
+ },
209
+ {
210
+ "id": "R2",
211
+ "source": "selfMinted.mcpAuthorizationKey",
212
+ "member": "GET /v1/sessions/:id#messages[].details.authorization.resourceMetadataUrl",
213
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 于本版退役 `GET /v1/sessions/:id#messages[].details.authorization.resourceMetadataUrl`(原属性 remote-claimed URL from the endpoint's challenge (deep-scrubbed text);自 7.138.0 起在 wire 上,until 7.150.0 = 本版)"
214
+ },
215
+ {
216
+ "id": "R3",
217
+ "source": "selfMinted.mcpAuthorizationKey",
218
+ "member": "SSE tool_end#structured.authorization(reason 以外的成员)",
219
+ "text": "自铸 MCP 授权记录 authorization 的出现面(<面>#<键> → 在场律) 于本版退役 `SSE tool_end#structured.authorization(reason 以外的成员)`(原属性 card members passed through the text redactor (resourceMetadataUrl, a custom card's own members);自 7.138.0 起在 wire 上,until 7.150.0 = 本版)"
220
+ }
221
+ ],
222
+ "changed": [
223
+ {
224
+ "id": "C1",
225
+ "source": "engineNotice",
226
+ "member": "mcp.authorization_required",
227
+ "text": "附录 D.3 engine_notice 码 `mcp.authorization_required` 的detail:`{ server, reason, authorizeUrl?, principal?, sessionId, runId }` —— `reason` ∈ `rejected`(401)/ `scope`(403 `insufficient_scope`)/ `none`(授权座没有这位用户的授权),闭集属主 core,server echo-only;`authorizeUrl` 只来自部署的授权座(本部署今天没有授权座 ⇒ 恒缺席,句子指向连接器设置) → `{ server, reason, authorizeUrl?, principal?, sessionId, runId }` —— `reason` ∈ `rejected`(401)/ `scope`(403 `insufficient_scope`)/ `none`(对端座答这位用户未授权),闭集属主 core;`reason` / `authorizeUrl` 是 MCP 授权记录的成员,经与状态行同一张处置表出门(结构位:不过 detail 的自由文本消毒与截断;词出闭集 ⇒ 记录成员整组缺席);`authorizeUrl` 只来自部署的对端座,处置表今天不放行 ⇒ 恒缺席,句子指向连接器设置"
228
+ },
229
+ {
230
+ "id": "C2",
231
+ "source": "selfMinted.fieldConflictReason",
232
+ "member": "scratchpad_root",
233
+ "text": "自铸 400 / 409 / 422 request.field_conflict reason `scratchpad_root` 的属性:- → fields = cwd (sent) or projectId (inherited from the project), then scratchpadDir when the request's own covers it(since 7.150.0)"
234
+ },
235
+ {
236
+ "id": "C3",
237
+ "source": "selfMinted.fieldConflictReason",
238
+ "member": "system_prompt_fold",
239
+ "text": "自铸 400 / 409 / 422 request.field_conflict reason `system_prompt_fold` 的属性:- → fields in fold order from appendSystemPrompt / projectId (the inherited project brief) / settings.outputStyle; count / cap(since 7.150.0)"
240
+ }
241
+ ],
242
+ "narrowed": [],
243
+ "closedSetMembers": [
244
+ {
245
+ "set": "capability",
246
+ "at": [
247
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.1"
248
+ ],
249
+ "added": [
250
+ "projectInheritance"
251
+ ],
252
+ "registered": [],
253
+ "removed": [],
254
+ "breaking": false
255
+ },
256
+ {
257
+ "set": "selfMinted.deviceProtocolRevision",
258
+ "at": [
259
+ "src/trace/self-minted-wire.ts#deviceProtocolRevision"
260
+ ],
261
+ "added": [
262
+ "5"
263
+ ],
264
+ "registered": [],
265
+ "removed": [],
266
+ "breaking": false
267
+ },
268
+ {
269
+ "set": "selfMinted.listeningLineKey",
270
+ "at": [
271
+ "src/trace/self-minted-wire.ts#listeningLineKey"
272
+ ],
273
+ "added": [
274
+ "boundAddress"
275
+ ],
276
+ "registered": [
277
+ "bindHost",
278
+ "bindHostNote",
279
+ "brain",
280
+ "breakerState",
281
+ "costQuota",
282
+ "instanceId",
283
+ "maxPrincipalCostUsd",
284
+ "memory",
285
+ "model",
286
+ "otel",
287
+ "perModelKeys",
288
+ "port",
289
+ "rateLimit",
290
+ "rateLimitPerMin",
291
+ "sealedModelKeys",
292
+ "sealedPoisonedModels",
293
+ "session",
294
+ "toolResultStore",
295
+ "workflowRunStore"
296
+ ],
297
+ "removed": [],
298
+ "breaking": false
299
+ },
300
+ {
301
+ "set": "selfMinted.mcpAuthorizationKey",
302
+ "at": [
303
+ "src/trace/self-minted-wire.ts#mcpAuthorizationKey"
304
+ ],
305
+ "added": [],
306
+ "registered": [
307
+ "GET /v1/capabilities/mcp#servers[].authorization",
308
+ "GET /v1/runs/:id/events#tool_end.structured.authorization",
309
+ "GET /v1/sessions/:id#messages[].details.authorization",
310
+ "GET /v1/sessions/:id/mcp#lastLegMcp.mcp[].authorization",
311
+ "POST /v1/capabilities/mcp/probe#servers[].authorization",
312
+ "SSE tool_end#structured.authorization"
313
+ ],
314
+ "removed": [
315
+ "GET /v1/runs/:id/events#tool_end.structured.authorization(reason 以外的成员)",
316
+ "GET /v1/sessions/:id#messages[].details.authorization.resourceMetadataUrl",
317
+ "SSE tool_end#structured.authorization(reason 以外的成员)"
318
+ ],
319
+ "breaking": true
320
+ },
321
+ {
322
+ "set": "selfMinted.projectRowKey",
323
+ "at": [
324
+ "src/trace/self-minted-wire.ts#projectRowKey"
325
+ ],
326
+ "added": [
327
+ "contentAttestedAt"
328
+ ],
329
+ "registered": [],
330
+ "removed": [],
331
+ "breaking": false
332
+ }
333
+ ],
334
+ "breaking": 3
335
+ }