@sema-agent/server 7.145.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 (526) hide show
  1. package/MIGRATION.md +876 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +374 -99
  5. package/deploy/facts/CHANGES.json +25 -0
  6. package/deploy/facts/README.md +57 -0
  7. package/deploy/facts/lanes.json +61 -0
  8. package/deploy/facts/lanes.schema.json +57 -0
  9. package/deploy/facts/sandbox-rbac.json +113 -0
  10. package/deploy/facts/sandbox-rbac.schema.json +74 -0
  11. package/deploy/facts/sealed-key.json +9 -0
  12. package/deploy/facts/sealed-key.schema.json +52 -0
  13. package/deploy/sema-up/README.md +2 -2
  14. package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
  15. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
  16. package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
  17. package/deploy/sema-up/chart/templates/server.yaml +9 -4
  18. package/deploy/sema-up/chart/values.yaml +8 -1
  19. package/deploy/sema-up/cluster-up.sh +2 -1
  20. package/deploy/sema-up/lib/flagshape.sh +4 -0
  21. package/deploy/sema-up/lib/lanes.json +2 -5
  22. package/deploy/sema-up/sema-up.sh +12 -9
  23. package/deploy/sema-up/stack/compose.yaml +5 -4
  24. package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
  25. package/dist/adoption/import-limits.d.ts +6 -0
  26. package/dist/adoption/import-limits.js +7 -0
  27. package/dist/adoption/import.d.ts +62 -0
  28. package/dist/adoption/import.js +107 -0
  29. package/dist/adoption/wire.d.ts +52 -0
  30. package/dist/adoption/wire.js +9 -0
  31. package/dist/approval-ask-machine.d.ts +2 -2
  32. package/dist/approval-card.d.ts +7 -16
  33. package/dist/approval-card.js +0 -4
  34. package/dist/approval-gate-currency.d.ts +1 -1
  35. package/dist/approval-gate-currency.js +1 -1
  36. package/dist/approval-reconciler.d.ts +1 -1
  37. package/dist/approval.d.ts +3 -3
  38. package/dist/audit.js +2 -2
  39. package/dist/bench/s1/live-deps.js +3 -1
  40. package/dist/boot/crash-last.js +2 -1
  41. package/dist/boot/deployment-mods.d.ts +11 -1
  42. package/dist/boot/deployment-mods.js +15 -2
  43. package/dist/boot/device-lane.js +7 -5
  44. package/dist/boot/engine-lease.d.ts +195 -22
  45. package/dist/boot/engine-lease.js +146 -20
  46. package/dist/boot/execution-env.d.ts +5 -0
  47. package/dist/boot/execution-env.js +57 -33
  48. package/dist/boot/execution-lane.d.ts +37 -9
  49. package/dist/boot/execution-lane.js +74 -20
  50. package/dist/boot/exit-boundary.d.ts +50 -0
  51. package/dist/boot/exit-boundary.js +32 -0
  52. package/dist/boot/exit-last.d.ts +20 -4
  53. package/dist/boot/exit-last.js +23 -5
  54. package/dist/boot/governance-seams.d.ts +2 -2
  55. package/dist/boot/governance-seams.js +1 -0
  56. package/dist/boot/leader.js +1 -1
  57. package/dist/boot/memory-boundary.d.ts +11 -11
  58. package/dist/boot/memory-boundary.js +3 -3
  59. package/dist/boot/memory-consolidation.d.ts +42 -41
  60. package/dist/boot/memory-consolidation.js +26 -28
  61. package/dist/boot/org-memory.js +3 -2
  62. package/dist/boot/parked-revive-gate.d.ts +1 -1
  63. package/dist/boot/parked-revive-gate.js +1 -1
  64. package/dist/boot/reapers.d.ts +12 -4
  65. package/dist/boot/reapers.js +40 -16
  66. package/dist/boot/resolve-spec.d.ts +2 -0
  67. package/dist/boot/resolve-spec.js +126 -123
  68. package/dist/boot/retention-lane.d.ts +4 -42
  69. package/dist/boot/runner-deps.js +1 -1
  70. package/dist/boot/session-faces.d.ts +1 -0
  71. package/dist/boot/session-faces.js +11 -3
  72. package/dist/boot/shutdown.js +27 -9
  73. package/dist/boot/stage-01-config.d.ts +1 -1
  74. package/dist/boot/stage-01-config.js +7 -3
  75. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
  76. package/dist/boot/stage-02-web-admin-pull.js +10 -8
  77. package/dist/boot/stage-03-store-backend.d.ts +2 -1
  78. package/dist/boot/stage-03-store-backend.js +2 -2
  79. package/dist/boot/stage-04-stores.d.ts +2 -1
  80. package/dist/boot/stage-05-execution-env.d.ts +4 -1
  81. package/dist/boot/stage-05-execution-env.js +6 -6
  82. package/dist/boot/stage-06-runners.d.ts +5 -2
  83. package/dist/boot/stage-06-runners.js +12 -13
  84. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  85. package/dist/boot/stage-07-capability-layer.js +7 -7
  86. package/dist/boot/stage-08-reapers.d.ts +5 -2
  87. package/dist/boot/stage-08-reapers.js +3 -3
  88. package/dist/boot/stage-09-leader.d.ts +6 -2
  89. package/dist/boot/stage-10-http-server.d.ts +6 -2
  90. package/dist/boot/stage-10-http-server.js +5 -3
  91. package/dist/boot/stores.d.ts +10 -0
  92. package/dist/boot/stores.js +53 -26
  93. package/dist/boot/web-admin.js +3 -3
  94. package/dist/boot/workflow-orchestration.d.ts +1 -1
  95. package/dist/boot/workflow-orchestration.js +2 -1
  96. package/dist/capabilities/center-plugins.d.ts +2 -0
  97. package/dist/capabilities/center-plugins.js +6 -2
  98. package/dist/capabilities/composite-members.d.ts +4 -1
  99. package/dist/capabilities/composite-members.js +4 -1
  100. package/dist/capabilities/execution-lane.d.ts +7 -7
  101. package/dist/capabilities/execution-lane.js +2 -2
  102. package/dist/capabilities/hands-lane.d.ts +1 -1
  103. package/dist/capabilities/scenarios.d.ts +34 -20
  104. package/dist/capabilities/scenarios.js +13 -9
  105. package/dist/capabilities/settings-contract.d.ts +29 -0
  106. package/dist/capabilities/settings-contract.js +14 -0
  107. package/dist/capabilities/skills.d.ts +5 -5
  108. package/dist/capability-facts.d.ts +56 -1
  109. package/dist/capability-facts.js +59 -8
  110. package/dist/center-credential-renewer.js +3 -2
  111. package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
  112. package/dist/config-catalog.js +19 -9
  113. package/dist/config-invariants.d.ts +18 -3
  114. package/dist/config-invariants.js +36 -19
  115. package/dist/config-lkg.d.ts +1 -1
  116. package/dist/config-lkg.js +5 -6
  117. package/dist/config-provider.d.ts +2 -2
  118. package/dist/config-provider.js +2 -0
  119. package/dist/config-types.d.ts +228 -185
  120. package/dist/config.d.ts +74 -6
  121. package/dist/config.js +146 -64
  122. package/dist/degenerate-instrument.js +1 -1
  123. package/dist/deleted-session-ids.d.ts +19 -0
  124. package/dist/deleted-session-ids.js +26 -0
  125. package/dist/deploy-facts.d.ts +155 -0
  126. package/dist/deploy-facts.js +95 -0
  127. package/dist/deployment-shape.d.ts +21 -12
  128. package/dist/deployment-shape.js +24 -6
  129. package/dist/device-ws-hub.d.ts +48 -3
  130. package/dist/device-ws-hub.js +48 -2
  131. package/dist/env-facts.d.ts +7 -5
  132. package/dist/env-facts.js +10 -6
  133. package/dist/error-code-family.d.ts +35 -0
  134. package/dist/error-code-family.js +26 -0
  135. package/dist/execution-config-root.d.ts +5 -5
  136. package/dist/execution-config-root.js +5 -5
  137. package/dist/execution-env-purpose.d.ts +14 -0
  138. package/dist/execution-env-purpose.js +29 -0
  139. package/dist/execution-lane-caps.d.ts +49 -86
  140. package/dist/execution-lane-caps.js +52 -62
  141. package/dist/execution-placement.d.ts +18 -2
  142. package/dist/execution-placement.js +19 -0
  143. package/dist/file-history-disclosure.d.ts +2 -2
  144. package/dist/fleet/drain-entry.d.ts +46 -3
  145. package/dist/fleet/drain-entry.js +6 -0
  146. package/dist/fleet/fleet-bus.d.ts +2 -1
  147. package/dist/fleet/serving-lease.js +3 -4
  148. package/dist/history-anchor.d.ts +22 -0
  149. package/dist/history-anchor.js +14 -0
  150. package/dist/hooks/branch-transcript.d.ts +1 -1
  151. package/dist/hooks/branch-transcript.js +1 -0
  152. package/dist/hooks/classic-stations.d.ts +25 -8
  153. package/dist/hooks/classic-stations.js +29 -3
  154. package/dist/hooks/command-spawn.d.ts +1 -4
  155. package/dist/hooks/command-spawn.js +0 -11
  156. package/dist/hooks/hook-runner.d.ts +85 -24
  157. package/dist/hooks/hook-runner.js +326 -109
  158. package/dist/hooks/hook-source.d.ts +14 -2
  159. package/dist/hooks/hook-source.js +8 -0
  160. package/dist/http/active-run-conflict.d.ts +1 -1
  161. package/dist/http/active-run-conflict.js +1 -1
  162. package/dist/http/admission.js +11 -1
  163. package/dist/http/approval-sweeps.d.ts +2 -5
  164. package/dist/http/approval-sweeps.js +3 -2
  165. package/dist/http/checkpoint-ctx.d.ts +76 -71
  166. package/dist/http/checkpoint-ctx.js +40 -40
  167. package/dist/http/claim-latency.d.ts +10 -0
  168. package/dist/http/claim-latency.js +12 -0
  169. package/dist/http/dispatch.js +19 -3
  170. package/dist/http/durable-run-leg.d.ts +5 -0
  171. package/dist/http/durable-run-leg.js +3 -1
  172. package/dist/http/execution-context.d.ts +7 -1
  173. package/dist/http/execution-context.js +13 -0
  174. package/dist/http/health-self-report.d.ts +6 -2
  175. package/dist/http/health-self-report.js +3 -2
  176. package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
  177. package/dist/http/memory-compliance-failure-reply.js +5 -15
  178. package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
  179. package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
  180. package/dist/http/memory-store-refusal-reply.d.ts +3 -3
  181. package/dist/http/memory-store-refusal-reply.js +3 -0
  182. package/dist/http/owner-access.d.ts +11 -0
  183. package/dist/http/owner-access.js +7 -4
  184. package/dist/http/principal-gate.d.ts +28 -16
  185. package/dist/http/principal-gate.js +10 -19
  186. package/dist/http/request-guards.d.ts +2 -2
  187. package/dist/http/request-guards.js +5 -5
  188. package/dist/http/resume-legs.d.ts +29 -10
  189. package/dist/http/resume-legs.js +94 -56
  190. package/dist/http/rewind-files-reply.d.ts +34 -0
  191. package/dist/http/rewind-files-reply.js +36 -0
  192. package/dist/http/route-ctx.d.ts +43 -26
  193. package/dist/http/route-table.js +4 -0
  194. package/dist/http/routes/adoption.d.ts +11 -0
  195. package/dist/http/routes/adoption.js +80 -6
  196. package/dist/http/routes/agents-roster.js +1 -0
  197. package/dist/http/routes/approvals-assistant.js +7 -26
  198. package/dist/http/routes/background.js +1 -0
  199. package/dist/http/routes/capabilities.js +12 -3
  200. package/dist/http/routes/devices.js +1 -1
  201. package/dist/http/routes/diagnostics.d.ts +9 -14
  202. package/dist/http/routes/diagnostics.js +10 -20
  203. package/dist/http/routes/engine.d.ts +31 -0
  204. package/dist/http/routes/engine.js +81 -0
  205. package/dist/http/routes/memory-bundle.js +3 -0
  206. package/dist/http/routes/memory-consolidation.js +3 -5
  207. package/dist/http/routes/memory-origin.d.ts +2 -2
  208. package/dist/http/routes/memory-origin.js +2 -4
  209. package/dist/http/routes/memory-policy.js +5 -1
  210. package/dist/http/routes/notify-wake.js +2 -1
  211. package/dist/http/routes/observability.js +3 -6
  212. package/dist/http/routes/projects.d.ts +70 -0
  213. package/dist/http/routes/projects.js +86 -0
  214. package/dist/http/routes/rules.js +30 -2
  215. package/dist/http/routes/runs.js +15 -11
  216. package/dist/http/routes/session-sync.js +39 -35
  217. package/dist/http/routes/sessions-list.d.ts +1 -1
  218. package/dist/http/routes/sessions.d.ts +7 -1
  219. package/dist/http/routes/sessions.js +108 -2
  220. package/dist/http/routes/tasks.js +32 -8
  221. package/dist/http/routes/trace-usage.js +1 -1
  222. package/dist/http/run-concurrency-cap.d.ts +86 -0
  223. package/dist/http/run-concurrency-cap.js +54 -0
  224. package/dist/http/server.d.ts +31 -14
  225. package/dist/http/server.js +29 -3
  226. package/dist/http/stored-body-replay.d.ts +12 -7
  227. package/dist/http/stored-body-replay.js +28 -5
  228. package/dist/http/wire-types.d.ts +27 -13
  229. package/dist/index.d.ts +2 -2
  230. package/dist/index.js +1 -1
  231. package/dist/instruction-source-notice.d.ts +1 -1
  232. package/dist/json-body-limit.d.ts +8 -0
  233. package/dist/json-body-limit.js +2 -0
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/local-data-root.d.ts +2 -2
  236. package/dist/memory-embedder-reembed.d.ts +38 -0
  237. package/dist/memory-embedder-reembed.js +20 -0
  238. package/dist/memory-incident-sink.d.ts +0 -28
  239. package/dist/memory-incident-sink.js +5 -0
  240. package/dist/memory-operator-faces.d.ts +9 -4
  241. package/dist/memory-scope-stores.d.ts +9 -7
  242. package/dist/memory-scope-stores.js +3 -14
  243. package/dist/memory-scope.d.ts +38 -2
  244. package/dist/memory-scope.js +33 -2
  245. package/dist/memory-store-refusal.d.ts +17 -4
  246. package/dist/memory-store-refusal.js +1 -1
  247. package/dist/memory-sync-client.d.ts +2 -0
  248. package/dist/memory-sync-client.js +13 -11
  249. package/dist/memory-sync.js +1 -1
  250. package/dist/model-compat.d.ts +35 -21
  251. package/dist/model-compat.js +49 -21
  252. package/dist/model-entry-refusal.d.ts +11 -1
  253. package/dist/model-entry-refusal.js +7 -0
  254. package/dist/namespaced-rule-name.d.ts +18 -1
  255. package/dist/namespaced-rule-name.js +12 -0
  256. package/dist/net-address.d.ts +53 -0
  257. package/dist/net-address.js +111 -0
  258. package/dist/observability/fail-open.d.ts +29 -17
  259. package/dist/observability/fail-open.js +29 -17
  260. package/dist/observability/metrics.d.ts +2 -0
  261. package/dist/observability/metrics.js +2 -0
  262. package/dist/observability/secret-env-scrub.d.ts +30 -4
  263. package/dist/observability/secret-env-scrub.js +15 -3
  264. package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
  265. package/dist/orchestration/workflow-agent-session-index.js +1 -6
  266. package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
  267. package/dist/orchestration/workflow-completion-inbox.js +63 -45
  268. package/dist/orchestration/workflow-notify-journal.js +2 -3
  269. package/dist/org-delivery-gate.js +1 -1
  270. package/dist/org-memory-admission.d.ts +5 -2
  271. package/dist/org-memory-admission.js +25 -10
  272. package/dist/parked-decide.d.ts +33 -26
  273. package/dist/parked-decide.js +36 -44
  274. package/dist/peer-directory.d.ts +6 -12
  275. package/dist/peer-directory.js +5 -1
  276. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  277. package/dist/plugins/approval-ask-store-file.js +37 -4
  278. package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
  279. package/dist/plugins/approval-ask-store-memory.js +11 -2
  280. package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
  281. package/dist/plugins/approval-ask-store-sql.js +3 -1
  282. package/dist/plugins/blob-backend.d.ts +38 -195
  283. package/dist/plugins/blob-backend.js +33 -229
  284. package/dist/plugins/caching-session-store.d.ts +12 -5
  285. package/dist/plugins/caching-session-store.js +3 -0
  286. package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
  287. package/dist/plugins/checkpoint-index-columns.js +3 -2
  288. package/dist/plugins/checkpoint-store-face.d.ts +426 -0
  289. package/dist/plugins/checkpoint-store-face.js +152 -0
  290. package/dist/plugins/device-store-sql.d.ts +2 -2
  291. package/dist/plugins/device-store-sql.js +5 -10
  292. package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
  293. package/dist/plugins/execution-lane-rename-m40.js +10 -0
  294. package/dist/plugins/execution-placement-sql.d.ts +63 -88
  295. package/dist/plugins/execution-placement-sql.js +94 -54
  296. package/dist/plugins/file-run-store.d.ts +26 -18
  297. package/dist/plugins/file-run-store.js +64 -75
  298. package/dist/plugins/fork-routing-session-store.d.ts +6 -2
  299. package/dist/plugins/fork-routing-session-store.js +2 -2
  300. package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
  301. package/dist/plugins/imported-layer-root-retirement.js +4 -8
  302. package/dist/plugins/inbox-payload-column.d.ts +14 -0
  303. package/dist/plugins/inbox-payload-column.js +13 -0
  304. package/dist/plugins/local-checkpoint-store.d.ts +7 -2
  305. package/dist/plugins/local-checkpoint-store.js +13 -8
  306. package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
  307. package/dist/plugins/local-data-dir-modes-m39.js +182 -0
  308. package/dist/plugins/local-engine-high-water.d.ts +11 -0
  309. package/dist/plugins/local-engine-high-water.js +59 -0
  310. package/dist/plugins/local-session-store.d.ts +119 -30
  311. package/dist/plugins/local-session-store.js +156 -53
  312. package/dist/plugins/local-task-attachment-store.d.ts +2 -0
  313. package/dist/plugins/local-task-attachment-store.js +10 -11
  314. package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
  315. package/dist/plugins/memory-embedder-fingerprint.js +52 -12
  316. package/dist/plugins/memory-embedder.d.ts +1 -1
  317. package/dist/plugins/memory-embedder.js +2 -2
  318. package/dist/plugins/memory-engine-pg.d.ts +30 -6
  319. package/dist/plugins/memory-engine-pg.js +96 -214
  320. package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
  321. package/dist/plugins/memory-engine-sql-apply.js +358 -0
  322. package/dist/plugins/memory-engine-tidb.d.ts +38 -9
  323. package/dist/plugins/memory-engine-tidb.js +99 -230
  324. package/dist/plugins/memory-key-guards.d.ts +1 -1
  325. package/dist/plugins/memory-origin-law.d.ts +3 -3
  326. package/dist/plugins/one-time-migrations.d.ts +169 -83
  327. package/dist/plugins/one-time-migrations.js +295 -235
  328. package/dist/plugins/owner-only-file-mode.d.ts +29 -0
  329. package/dist/plugins/owner-only-file-mode.js +141 -0
  330. package/dist/plugins/permission-rule-store-file.d.ts +17 -3
  331. package/dist/plugins/permission-rule-store-file.js +20 -1
  332. package/dist/plugins/pg-pool.d.ts +2 -1
  333. package/dist/plugins/pg-pool.js +12 -5
  334. package/dist/plugins/release-version.d.ts +20 -0
  335. package/dist/plugins/release-version.js +28 -0
  336. package/dist/plugins/remote-env-adb.d.ts +20 -4
  337. package/dist/plugins/remote-env-adb.js +39 -11
  338. package/dist/plugins/remote-env-e2b.d.ts +12 -3
  339. package/dist/plugins/remote-env-e2b.js +6 -4
  340. package/dist/plugins/remote-env-host.d.ts +9 -1
  341. package/dist/plugins/remote-env-host.js +6 -5
  342. package/dist/plugins/remote-env-k8s.d.ts +5 -2
  343. package/dist/plugins/remote-env-k8s.js +15 -4
  344. package/dist/plugins/remote-env-local-docker.d.ts +4 -1
  345. package/dist/plugins/remote-env-local-docker.js +3 -3
  346. package/dist/plugins/remote-env-ssh.d.ts +8 -2
  347. package/dist/plugins/remote-env-ssh.js +26 -24
  348. package/dist/plugins/remote-shell.d.ts +59 -30
  349. package/dist/plugins/remote-shell.js +175 -62
  350. package/dist/plugins/retention-declaration.d.ts +37 -0
  351. package/dist/plugins/retention-declaration.js +9 -0
  352. package/dist/plugins/retention-deployment.d.ts +126 -0
  353. package/dist/plugins/retention-deployment.js +88 -0
  354. package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
  355. package/dist/plugins/retention-lane-store-sql.js +103 -1
  356. package/dist/plugins/retention-sql.d.ts +29 -0
  357. package/dist/plugins/retention-sql.js +8 -0
  358. package/dist/plugins/run-store-sql.js +2 -2
  359. package/dist/plugins/schema-consistency.d.ts +0 -6
  360. package/dist/plugins/schema-consistency.js +1 -2
  361. package/dist/plugins/schema-ensure-legs.d.ts +1 -1
  362. package/dist/plugins/schema-ensure-legs.js +13 -3
  363. package/dist/plugins/session-ext-table.d.ts +74 -0
  364. package/dist/plugins/session-ext-table.js +121 -0
  365. package/dist/plugins/session-fork.d.ts +31 -9
  366. package/dist/plugins/session-fork.js +3 -2
  367. package/dist/plugins/session-placement.d.ts +4 -2
  368. package/dist/plugins/session-row-sql.d.ts +8 -7
  369. package/dist/plugins/session-row-sql.js +15 -7
  370. package/dist/plugins/session-store-sql.d.ts +131 -0
  371. package/dist/plugins/session-store-sql.js +298 -0
  372. package/dist/plugins/session-workspace-cell.d.ts +2 -2
  373. package/dist/plugins/session-workspace-cell.js +2 -2
  374. package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
  375. package/dist/plugins/shared-memory-store-sql.js +13 -13
  376. package/dist/plugins/snapshot-bucket-presence.js +1 -1
  377. package/dist/plugins/sql-driver.d.ts +23 -7
  378. package/dist/plugins/sql-driver.js +41 -8
  379. package/dist/plugins/sql-errors.d.ts +5 -2
  380. package/dist/plugins/sql-errors.js +4 -0
  381. package/dist/plugins/sql-json-column.d.ts +5 -1
  382. package/dist/plugins/store-backend.d.ts +46 -16
  383. package/dist/plugins/store-backend.js +192 -69
  384. package/dist/plugins/store-contracts.d.ts +10 -13
  385. package/dist/plugins/store-contracts.js +1 -9
  386. package/dist/plugins/store-sweep.d.ts +63 -0
  387. package/dist/plugins/store-sweep.js +48 -0
  388. package/dist/plugins/task-attachment-store.d.ts +6 -8
  389. package/dist/plugins/task-attachment-store.js +15 -10
  390. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  391. package/dist/plugins/text-column-capacity.d.ts +21 -0
  392. package/dist/plugins/text-column-capacity.js +5 -0
  393. package/dist/plugins/tidb-pool.d.ts +3 -2
  394. package/dist/plugins/tidb-pool.js +20 -32
  395. package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
  396. package/dist/prompt-screen.d.ts +6 -9
  397. package/dist/prompt-screen.js +2 -5
  398. package/dist/read-face-posture.d.ts +6 -6
  399. package/dist/read-face-posture.js +2 -2
  400. package/dist/request-value-closure.d.ts +5 -5
  401. package/dist/request-value-closure.js +1 -1
  402. package/dist/rules-consent.d.ts +48 -27
  403. package/dist/rules-consent.js +147 -23
  404. package/dist/run-cancel-context.d.ts +4 -1
  405. package/dist/run-cancel-context.js +2 -1
  406. package/dist/run-local.js +17 -13
  407. package/dist/runs.d.ts +48 -30
  408. package/dist/runs.js +27 -17
  409. package/dist/runtime-caps-resolver.d.ts +15 -8
  410. package/dist/runtime-caps-resolver.js +14 -10
  411. package/dist/sandbox-egress-policy.js +6 -11
  412. package/dist/sandbox-rbac-rules.d.ts +88 -0
  413. package/dist/sandbox-rbac-rules.js +80 -0
  414. package/dist/sealed-key-layout.d.ts +16 -0
  415. package/dist/sealed-key-layout.js +3 -0
  416. package/dist/sealed-key.js +8 -6
  417. package/dist/security.d.ts +43 -9
  418. package/dist/security.js +9 -2
  419. package/dist/sema-config-dir.js +2 -2
  420. package/dist/server-secret-env.d.ts +2 -0
  421. package/dist/service-version.d.ts +2 -1
  422. package/dist/service-version.js +2 -2
  423. package/dist/session-error-wire.d.ts +1 -1
  424. package/dist/session-incarnation.d.ts +8 -5
  425. package/dist/session-notify-door.d.ts +5 -3
  426. package/dist/session-resident-background.d.ts +110 -0
  427. package/dist/session-resident-background.js +88 -0
  428. package/dist/session-row.d.ts +1 -1
  429. package/dist/session-sync-kernel.d.ts +53 -14
  430. package/dist/session-sync-kernel.js +70 -1
  431. package/dist/session-sync.d.ts +5 -3
  432. package/dist/session-workspace.d.ts +12 -2
  433. package/dist/session-workspace.js +6 -0
  434. package/dist/sighup-idle.d.ts +9 -7
  435. package/dist/sighup-idle.js +4 -5
  436. package/dist/spec-fields.d.ts +16 -0
  437. package/dist/spec-fields.js +7 -0
  438. package/dist/store-posture.d.ts +2 -1
  439. package/dist/stored-request-env-credentials-m38.d.ts +3 -0
  440. package/dist/stored-request-env-credentials-m38.js +8 -0
  441. package/dist/stored-request-hooks-m20.d.ts +3 -2
  442. package/dist/stored-request-hooks-m20.js +19 -14
  443. package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
  444. package/dist/stores-sql/blob-index-sql.d.ts +148 -0
  445. package/dist/stores-sql/blob-index-sql.js +154 -0
  446. package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
  447. package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
  448. package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
  449. package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
  450. package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
  451. package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
  452. package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
  453. package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
  454. package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
  455. package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
  456. package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
  457. package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
  458. package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
  459. package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
  460. package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
  461. package/dist/stores-sql/session-write-hooks.d.ts +59 -0
  462. package/dist/stores-sql/session-write-hooks.js +2 -0
  463. package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
  464. package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
  465. package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
  466. package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
  467. package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
  468. package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
  469. package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
  470. package/dist/stores-sql/windowed-session-storage.js +61 -0
  471. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
  472. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
  473. package/dist/task-a2a.d.ts +7 -1
  474. package/dist/task-a2a.js +15 -14
  475. package/dist/task-cwd.d.ts +11 -3
  476. package/dist/task-cwd.js +17 -1
  477. package/dist/task-mcp.d.ts +10 -2
  478. package/dist/task-mcp.js +13 -16
  479. package/dist/task-settings.d.ts +68 -8
  480. package/dist/task-settings.js +63 -6
  481. package/dist/tool-approval.d.ts +23 -10
  482. package/dist/tool-approval.js +10 -6
  483. package/dist/trace/core-keyset-guard.d.ts +17 -10
  484. package/dist/trace/engine-notice-wire.d.ts +1 -1
  485. package/dist/trace/engine-notice-wire.js +4 -0
  486. package/dist/trace/exit-seat.d.ts +29 -1
  487. package/dist/trace/exit-seat.js +4 -0
  488. package/dist/trace/project.d.ts +33 -16
  489. package/dist/trace/project.js +21 -9
  490. package/dist/trace/redact.d.ts +13 -2
  491. package/dist/trace/redact.js +347 -78
  492. package/dist/trace/self-minted-wire.d.ts +587 -16
  493. package/dist/trace/self-minted-wire.js +215 -9
  494. package/dist/trace/sema-provenance.d.ts +45 -41
  495. package/dist/trace/sema-provenance.js +81 -10
  496. package/dist/trace/task-notification-facets.d.ts +70 -2
  497. package/dist/trace/task-notification-facets.js +71 -1
  498. package/dist/trace/wire-projection-faces.d.ts +39 -3
  499. package/dist/trace/wire-projection-faces.js +27 -2
  500. package/dist/unread-request-members.d.ts +66 -0
  501. package/dist/unread-request-members.js +41 -0
  502. package/dist/usage-analytics.d.ts +4 -0
  503. package/dist/user-input-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/apply-effective.js +22 -26
  505. package/dist/web-admin-client/candidate-gate.d.ts +35 -3
  506. package/dist/web-admin-client/candidate-gate.js +53 -5
  507. package/dist/web-admin-client/center-request.d.ts +4 -1
  508. package/dist/web-admin-client/center-request.js +2 -1
  509. package/dist/web-admin-client/effective-keys.js +0 -1
  510. package/dist/web-admin-client/facade.d.ts +1 -1
  511. package/dist/web-admin-client/http-client.d.ts +1 -0
  512. package/dist/web-admin-client/http-client.js +17 -9
  513. package/dist/web-admin-client/restart-signal.js +5 -2
  514. package/dist/web-admin-client/skills-mcp.d.ts +20 -6
  515. package/dist/web-admin-client/skills-mcp.js +26 -21
  516. package/dist/web-admin-client/types.d.ts +34 -49
  517. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
  518. package/package.json +22 -13
  519. package/scripts/drain-check-local.mjs +8 -55
  520. package/scripts/drain-check.mysql.sql +3 -40
  521. package/scripts/drain-check.pg.sql +3 -40
  522. package/skills/update-config.md +1 -1
  523. package/wire-changes/server@7.146.0.json +3221 -0
  524. package/wire-changes/server@7.147.0.json +813 -0
  525. package/dist/approval-batch-census.d.ts +0 -27
  526. package/dist/approval-batch-census.js +0 -27
@@ -5,7 +5,7 @@ import { createLogger } from "./observability/logger.js";
5
5
  import { ABSOLUTE_HOST_PATH_MAX, hasControlOrBidi } from "@sema-agent/settings-schema";
6
6
  import { isDirectWritableRuleBehavior } from "./permission-rule-vocab.js";
7
7
  import { hasBidiControls } from "./text-bidi.js";
8
- import { confirmRuleApproval, RULE_BEHAVIORS, parseRuleText, ruleReachesProgramRun, precheckEditedRuleText, prepareCardApproval, prepareCcImport, redeemRuleBatch, redeemRuleTicket, addPersistedRule, removePersistedRule, isValidDurableScope, effectiveOrThrow, readRowBehavior, readRuleOwner, } from "@sema-agent/core";
8
+ import { confirmRuleApproval, RULE_BEHAVIORS, RULE_REFUSAL_CODES, parseRuleText, ruleReachesProgramRun, precheckEditedRuleText, prepareCardApproval, prepareCcImport, redeemRuleBatch, redeemRuleTicket, addPersistedRule, removePersistedRule, isValidDurableScope, effectiveOrThrow, readRowBehavior, readRuleOwner, } from "@sema-agent/core";
9
9
  import { buildRulePayloadHash } from "./plugins/permission-rule-store-sql.js";
10
10
  export const RULE_IMPORT_TICKET_TTL_MS = 10 * 60_000;
11
11
  export const RULE_IMPORT_RETRY_AFTER_SEC = 2;
@@ -21,7 +21,7 @@ const ImportOutcomeSchema = z
21
21
  .object({
22
22
  key: z.object({ behavior: z.preprocess((v) => readRowBehavior(v) ?? v, z.enum(RULE_BEHAVIORS)), rule: z.string().min(1), scope: z.string().min(1) }).strict(),
23
23
  outcome: z.enum(["persisted", "no-op", "refused", "indeterminate"]),
24
- reason: z.literal("store_refused").optional(),
24
+ reason: z.enum(RULE_REFUSAL_CODES).optional(),
25
25
  detail: z.string().optional(),
26
26
  })
27
27
  .strict()),
@@ -114,8 +114,12 @@ function isCommandRuleMatch(match) {
114
114
  }
115
115
  }
116
116
  const unknownReasonLogger = createLogger();
117
- function confirmRefusalWord(reason) {
117
+ function confirmRefusalWord(confirmed) {
118
+ const { reason } = confirmed;
118
119
  switch (reason) {
120
+ case "store_read":
121
+ case "store_write":
122
+ throw new RuleStoreFaultError({ code: reason, reason: confirmed.detail?.message ?? reason });
119
123
  case "edit_disabled":
120
124
  case "edit_binding_mismatch":
121
125
  return "edit-unsupported";
@@ -137,6 +141,75 @@ function confirmRefusalWord(reason) {
137
141
  }
138
142
  }
139
143
  }
144
+ export function isRuleStoreFault(code) {
145
+ switch (code) {
146
+ case "store_read":
147
+ case "store_write":
148
+ return true;
149
+ case "unsupported.layer_root":
150
+ case "ticket_invalid":
151
+ case "record_missing":
152
+ case "wrong_principal":
153
+ case "record_schema_stale":
154
+ case "not_confirmed":
155
+ case "record_malformed":
156
+ case "not_chosen":
157
+ case "parse_rejected":
158
+ case "store_unavailable":
159
+ case "record_changed":
160
+ case "withheld":
161
+ case "session_ended":
162
+ case "occ":
163
+ case "dot_removed":
164
+ return false;
165
+ default: {
166
+ const unknown = code;
167
+ unknownReasonLogger.warn("isRuleStoreFault: unknown RuleRefusalCode from core (dist/core version skew?) — read as not a store failure", { code: String(unknown) });
168
+ return false;
169
+ }
170
+ }
171
+ }
172
+ class RuleStoreFaultError extends Error {
173
+ code;
174
+ constructor(refusal) {
175
+ super(refusal.reason);
176
+ this.name = "RuleStoreFaultError";
177
+ this.code = refusal.code;
178
+ }
179
+ }
180
+ const retriableSkewLogger = createLogger();
181
+ function throwIfRetriable(refusal) {
182
+ if (!refusal.retriable)
183
+ return;
184
+ const { code } = refusal;
185
+ if (isRuleStoreFault(code))
186
+ throw new RuleStoreFaultError({ code, reason: refusal.reason });
187
+ retriableSkewLogger.warn("an engine refusal says retriable but its code is not a store failure (core/dist skew?) — not retried", { code });
188
+ }
189
+ export function confirmRefusalRetries(reason) {
190
+ switch (reason) {
191
+ case "conflict":
192
+ case "store_read":
193
+ case "store_write":
194
+ return true;
195
+ case "record_not_found":
196
+ case "record_schema_stale":
197
+ case "record_malformed":
198
+ case "selection_missing":
199
+ case "selection_invalid":
200
+ case "selection_mismatch":
201
+ case "not_pending":
202
+ case "edit_disabled":
203
+ case "edit_binding_mismatch":
204
+ case "edit_rejected":
205
+ return false;
206
+ default: {
207
+ const unknown = reason;
208
+ unknownReasonLogger.warn("confirmRefusalRetries: unknown ConfirmRefusalReason from core (dist/core version skew?) — read as not retriable", { reason: String(unknown) });
209
+ return false;
210
+ }
211
+ }
212
+ }
140
213
  function refusedMembersOf(members) {
141
214
  const refused = [];
142
215
  for (const m of members) {
@@ -241,22 +314,50 @@ function buildLocalImportLayers(candidates) {
241
314
  return root === "" ? { layer: "userSettings", path: LOCAL_IMPORT_LAYER_PATH, readFile } : { layer: "projectSettings", path: `${LOCAL_IMPORT_LAYER_PATH}:${root}`, root, readFile };
242
315
  });
243
316
  }
244
- function buildImportOutcomeMembers(members) {
245
- return members.map((m) => {
317
+ function settleImportWalk(members) {
318
+ const settled = [];
319
+ for (const m of members) {
246
320
  const key = { behavior: m.behavior, rule: m.rule, scope: serializeRuleScope(m.scope) };
247
321
  switch (m.status) {
248
322
  case "persisted":
249
- return { key, outcome: "persisted" };
323
+ settled.push({ key, outcome: "persisted" });
324
+ break;
250
325
  case "deduped":
251
- return { key, outcome: "no-op" };
252
- case "refused":
253
- return { key, outcome: "indeterminate", reason: "store_refused", detail: m.reason };
326
+ settled.push({ key, outcome: "no-op" });
327
+ break;
328
+ case "refused": {
329
+ const open = openRefusalOf(m);
330
+ if (open !== undefined)
331
+ return { open: `the outcome of ${m.rule} is not settled (${m.code}, ${open}): ${m.reason}` };
332
+ settled.push({ key, outcome: "refused", reason: m.code, detail: m.reason });
333
+ break;
334
+ }
254
335
  default: {
255
336
  const unknown = m;
256
337
  throw new Error(`unknown redeemed-batch member status: ${JSON.stringify(unknown)}`);
257
338
  }
258
339
  }
259
- });
340
+ }
341
+ return { settled };
342
+ }
343
+ function openRefusalOf(refusal) {
344
+ if (refusal.retriable)
345
+ return "retriable";
346
+ switch (refusal.committed) {
347
+ case "no":
348
+ return undefined;
349
+ case "unknown":
350
+ return "committed unknown";
351
+ default: {
352
+ const unknown = refusal.committed;
353
+ throw new Error(`unknown redeemed-batch member committed word: ${JSON.stringify(unknown)}`);
354
+ }
355
+ }
356
+ }
357
+ function importRecordRefusal(refusal) {
358
+ if (!refusal.retriable)
359
+ throw new Error(`the engine refused to prepare this import and says repeating will not help (${refusal.code}): ${refusal.reason}`);
360
+ return { ok: false, reason: "record-store-refused", committed: refusal.committed, detail: refusal.reason };
260
361
  }
261
362
  export function createRuleConsentLane(stores, opts) {
262
363
  const deps = { provider: stores.provider, approvals: stores.approvals, cardEdits: true };
@@ -289,6 +390,10 @@ export function createRuleConsentLane(stores, opts) {
289
390
  if (prepared === undefined) {
290
391
  return { ok: false, reason: "no-candidates", detail: "the rule lane cannot speak for this command (compound / redirection / unsupported tool)" };
291
392
  }
393
+ if ("status" in prepared) {
394
+ throwIfRetriable(prepared);
395
+ return { ok: false, reason: "redeem-refused", detail: prepared.reason };
396
+ }
292
397
  const redemption = input.redemption;
293
398
  if (redemption.kind === "batch") {
294
399
  const wanted = new Set(redemption.offer.rules.map((r) => r.rule));
@@ -298,12 +403,17 @@ export function createRuleConsentLane(stores, opts) {
298
403
  }
299
404
  const confirmed = await confirmRuleApproval({ approvalId: prepared.approvalId, principal: input.principal, selectedOffer: offerIndex, deps });
300
405
  if (!confirmed.ok)
301
- return { ok: false, reason: "confirm-refused", detail: confirmed.reason };
406
+ return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
302
407
  const result = await redeemRuleBatch({ approvalId: prepared.approvalId, principal: input.principal, deps });
303
- if ("status" in result)
408
+ if ("status" in result) {
409
+ throwIfRetriable(result);
304
410
  return { ok: false, reason: "redeem-refused", detail: result.reason };
411
+ }
305
412
  const refused = refusedMembersOf(result.members);
306
413
  if (refused.length > 0) {
414
+ const first = refused[0];
415
+ if (first !== undefined && refused.length === result.members.length && refused.every((m) => m.retriable))
416
+ throwIfRetriable(first);
307
417
  return { ok: false, reason: "redeem-refused", detail: `partial batch: ${refused.length} member(s) refused (${refused.map((x) => x.reason).join("; ")})` };
308
418
  }
309
419
  return { ok: true, ...anchorBatchMembers(result.members, redemption.offer), rev: result.rev };
@@ -318,7 +428,7 @@ export function createRuleConsentLane(stores, opts) {
318
428
  }
319
429
  const confirmed = await confirmRuleApproval({ approvalId: prepared.approvalId, principal: input.principal, selectedOffer: offerIndex, deps });
320
430
  if (!confirmed.ok)
321
- return { ok: false, reason: "confirm-refused", detail: confirmed.reason };
431
+ return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
322
432
  ticket = offered;
323
433
  }
324
434
  else {
@@ -336,7 +446,7 @@ export function createRuleConsentLane(stores, opts) {
336
446
  deps,
337
447
  });
338
448
  if (!confirmed.ok)
339
- return { ok: false, reason: confirmRefusalWord(confirmed.reason), detail: confirmed.detail?.message ?? confirmed.reason };
449
+ return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
340
450
  const minted = confirmed.mintedCandidate;
341
451
  if (minted === undefined) {
342
452
  return { ok: false, reason: "confirm-refused", detail: "the edited confirmation landed without a minted candidate — nothing to redeem" };
@@ -351,8 +461,10 @@ export function createRuleConsentLane(stores, opts) {
351
461
  ticket = minted.ticket;
352
462
  }
353
463
  const redeemed = await redeemRuleTicket({ ticket, principal: input.principal, deps });
354
- if (redeemed.status !== "redeemed")
464
+ if (redeemed.status !== "redeemed") {
465
+ throwIfRetriable(redeemed);
355
466
  return { ok: false, reason: "redeem-refused", detail: redeemed.reason };
467
+ }
356
468
  return { ok: true, kind: "single", rule: redeemed.rule, rev: redeemed.rev, alreadyRedeemed: redeemed.alreadyRedeemed };
357
469
  },
358
470
  async prepareImport(principal, layers) {
@@ -360,7 +472,10 @@ export function createRuleConsentLane(stores, opts) {
360
472
  const readFile = async () => l.content;
361
473
  return l.layer === "userSettings" ? { layer: l.layer, path: l.path, readFile } : { layer: l.layer, path: l.path, root: l.root, readFile };
362
474
  });
363
- const { preview, approvalId } = await prepareCcImport({ layers: ccLayers, principal, deps });
475
+ const prepared = await prepareCcImport({ layers: ccLayers, principal, deps });
476
+ if ("status" in prepared)
477
+ return importRecordRefusal(prepared);
478
+ const { preview, approvalId } = prepared;
364
479
  if (approvalId === undefined) {
365
480
  return { ok: true, preview };
366
481
  }
@@ -440,8 +555,8 @@ export function createRuleConsentLane(stores, opts) {
440
555
  if (record.state === "pending") {
441
556
  const confirmed = await confirmRuleApproval({ approvalId: consumed.approvalId, principal, deps });
442
557
  if (!confirmed.ok) {
443
- if (confirmed.reason === "conflict")
444
- return await indeterminate(confirmed.reason);
558
+ if (confirmRefusalRetries(confirmed.reason))
559
+ return await indeterminate(confirmed.detail?.message ?? confirmed.reason);
445
560
  return { ok: false, reason: "record-unusable", detail: confirmed.reason };
446
561
  }
447
562
  }
@@ -449,7 +564,10 @@ export function createRuleConsentLane(stores, opts) {
449
564
  if ("status" in result) {
450
565
  return await indeterminate(result.reason);
451
566
  }
452
- return { ok: true, outcome: { members: buildImportOutcomeMembers(result.members), rev: result.rev } };
567
+ const walk = settleImportWalk(result.members);
568
+ if ("open" in walk)
569
+ return await indeterminate(walk.open);
570
+ return { ok: true, outcome: { members: walk.settled, rev: result.rev } };
453
571
  }
454
572
  catch (err) {
455
573
  return await indeterminate(err instanceof Error ? err.message : String(err));
@@ -507,7 +625,10 @@ export function createRuleConsentLane(stores, opts) {
507
625
  }
508
626
  if (allows.length === 0)
509
627
  return { ok: true, preview: { members } };
510
- const { preview, approvalId } = await prepareCcImport({ layers: buildLocalImportLayers(allows), principal, deps });
628
+ const prepared = await prepareCcImport({ layers: buildLocalImportLayers(allows), principal, deps });
629
+ if ("status" in prepared)
630
+ return importRecordRefusal(prepared);
631
+ const { preview, approvalId } = prepared;
511
632
  const engineKeys = new Set(preview.candidates.map((c) => `${c.behavior}${LOCAL_IMPORT_KEY_SEP}${serializeRuleScope(c.scope)}${LOCAL_IMPORT_KEY_SEP}${c.rule}`));
512
633
  for (let i = 0; i < members.length; i++) {
513
634
  const m = members[i];
@@ -596,8 +717,8 @@ export function createRuleConsentLane(stores, opts) {
596
717
  if (record.state === "pending") {
597
718
  const confirmed = await confirmRuleApproval({ approvalId, principal, deps });
598
719
  if (!confirmed.ok) {
599
- if (confirmed.reason === "conflict")
600
- return await transient(confirmed.reason);
720
+ if (confirmRefusalRetries(confirmed.reason))
721
+ return await transient(confirmed.detail?.message ?? confirmed.reason);
601
722
  return await verdict("record-unusable", confirmed.reason);
602
723
  }
603
724
  }
@@ -605,7 +726,10 @@ export function createRuleConsentLane(stores, opts) {
605
726
  if ("status" in result) {
606
727
  return await transient(result.reason);
607
728
  }
608
- members = buildImportOutcomeMembers(result.members);
729
+ const walk = settleImportWalk(result.members);
730
+ if ("open" in walk)
731
+ return await transient(walk.open);
732
+ members = walk.settled;
609
733
  rev = result.rev;
610
734
  }
611
735
  catch (err) {
@@ -136,6 +136,9 @@ export declare function buildCancelledLedgerRow(c: PersistedTaskResult): {
136
136
  * `signal.reason`:那会改掉引擎与 provider 层收到的拒绝值,是在下游改上游接缝的输入(立宪禁区)。
137
137
  */
138
138
  export interface RunAbort {
139
+ /** 这条腿的**属主**(run 行的 `owner` 列;无主体 = `null`)—— 在飞集(`inflightRuns`)里「谁占着几条」的唯一读处:并发帽按主体数在飞腿时读它
140
+ * (`http/run-concurrency-cap.ts`),不另起一张按 taskId 键控的旁表。句柄与腿同寿,换腿就是换句柄。 */
141
+ readonly owner: string | null;
139
142
  /** 交给引擎的那只信号(`spec.signal` / 审批 / 提问 ALS 的 `abortSignal` / 子代 stoppedBy 归因都用它)。 */
140
143
  readonly signal: AbortSignal;
141
144
  /** 以 `cause` 中止本腿。已中止 ⇒ no-op(成因不改写)。 */
@@ -143,6 +146,6 @@ export interface RunAbort {
143
146
  /** 让本腿停下来的那次中止的成因;未中止 ⇒ `undefined`。 */
144
147
  cause(): AbortCause | undefined;
145
148
  }
146
- export declare function createRunAbort(): RunAbort;
149
+ export declare function createRunAbort(owner: string | null): RunAbort;
147
150
  export {};
148
151
  //# sourceMappingURL=run-cancel-context.d.ts.map
@@ -51,10 +51,11 @@ export function buildCancelledLedgerRow(c) {
51
51
  ...(c.abortCause !== undefined ? { abortCause: c.abortCause } : {}),
52
52
  };
53
53
  }
54
- export function createRunAbort() {
54
+ export function createRunAbort(owner) {
55
55
  const ctrl = new AbortController();
56
56
  let landed;
57
57
  return {
58
+ owner,
58
59
  signal: ctrl.signal,
59
60
  abort(cause) {
60
61
  if (ctrl.signal.aborted)
package/dist/run-local.js CHANGED
@@ -23,7 +23,7 @@ import { buildUnpricedCeilingNotice, isRosterGateArmed, loadConfig, logConfigDia
23
23
  import { buildStoreOpenRefusalTail } from "./plugins/store-open-refusal.js";
24
24
  import { acquireLocalBackendWithWait } from "./plugins/store-lock-wait.js";
25
25
  import { configLocalRoot, createConfigProvider } from "./config-provider.js";
26
- import { CONFIG_DOMAIN_INVALID_NOTE, buildCandidateRejectedFields, judgeConfigCandidate } from "./web-admin-client/candidate-gate.js";
26
+ import { CONFIG_DOMAIN_INVALID_NOTE, buildCandidateRejectedFields, buildCandidateRejectionNotes, judgeConfigCandidate } from "./web-admin-client/candidate-gate.js";
27
27
  import { buildUnreadConfigFileFields, buildUnreadConfigKeyFields } from "./web-admin-client/read-warnings.js";
28
28
  import { composeExecutionLane, settleHostLaneShell, warnReadDenyFloorUnkept } from "./boot/execution-lane.js";
29
29
  import { judgeConsolidationValve } from "./boot/memory-consolidation.js";
@@ -316,6 +316,7 @@ function buildUnfinishedStopFooter(stop, sessionId) {
316
316
  }
317
317
  }
318
318
  }
319
+ const RUN_LOCAL_LANE_ENTRY = { name: "run-local", runs: ["host", "none"], declares: "host" };
319
320
  export const RUN_LOCAL_CONFIG_SOURCE_REFUSAL = "CONFIG_PROVIDER=remote: run-local reads its configuration from the local config directory only — it does not pull a web-admin center " +
320
321
  "(center credential renewal, sealed model keys and the roster gate are assembled by the HTTP service). Unset CONFIG_PROVIDER or set " +
321
322
  "CONFIG_PROVIDER=local for this command, or run the HTTP service to use the center.";
@@ -345,30 +346,31 @@ export async function runLocal(argv, deps = {}) {
345
346
  if (args.root)
346
347
  process.env.CONFIG_LOCAL_DIR = args.root;
347
348
  declareServerWithheldEnv();
348
- const config = loadConfig();
349
- bindOwnCredentialsConfig(config);
350
- const root = configLocalRoot(config);
351
- const logger = deps.logger ?? createLogger(config.logLevel);
349
+ const loaded = loadConfig();
350
+ bindOwnCredentialsConfig(loaded);
351
+ const root = configLocalRoot(loaded);
352
+ const logger = deps.logger ?? createLogger(loaded.logLevel);
352
353
  const metrics = createMetrics();
353
354
  const memoryEngineIncident = createMemoryEngineIncidentSink({ logger, metrics });
354
355
  installSecretEnvScrubRecorder({ logger, metrics });
355
356
  installDefaultEngineNoticeSeat(logger, metrics);
356
357
  logConfigDiagnostics(logger);
357
- provisionSemaConfigDir(config, logger);
358
+ provisionSemaConfigDir(loaded, logger);
358
359
  installOutboundDispatcher(logger);
359
- const providerInput = { provider: "local", localDir: root, localOwnerUid: config.configLocalOwnerUid };
360
+ const providerInput = { provider: "local", localDir: root, localOwnerUid: loaded.configLocalOwnerUid };
360
361
  try {
361
- await assertLocalConfigDirTrusted({ root, declaredOwnerUid: config.configLocalOwnerUid });
362
+ await assertLocalConfigDirTrusted({ root, declaredOwnerUid: loaded.configLocalOwnerUid });
362
363
  }
363
364
  catch (err) {
364
365
  printErr(err instanceof Error ? err.message : String(err));
365
366
  return 2;
366
367
  }
367
- const envModelsMigration = { root, env: process.env, envTableIsPlaceholder: isRosterGateArmed(config.webAdmin) };
368
+ const envModelsMigration = { root, env: process.env, envTableIsPlaceholder: isRosterGateArmed(loaded.webAdmin) };
368
369
  logEnvModelsMigration(logger, envModelsMigration, await runEnvModelsMigration(envModelsMigration));
369
370
  logConfigDirMigration(logger, await migrateLocalConfigDirectory(root));
371
+ let config;
370
372
  try {
371
- await composeExecutionLane(config, { configSource: "local", localRoot: root, logger, drivesFromFile: ["host"] });
373
+ config = await composeExecutionLane(loaded, { configSource: "local", localRoot: root, logger, entry: RUN_LOCAL_LANE_ENTRY });
372
374
  }
373
375
  catch (err) {
374
376
  printErr(err instanceof Error ? err.message : String(err));
@@ -379,12 +381,14 @@ export async function runLocal(argv, deps = {}) {
379
381
  const rosterLease = peerDesk.lease("roster");
380
382
  let effective;
381
383
  let candidatePrompts;
384
+ let candidateRejectionNotes;
382
385
  let applying = false;
383
386
  try {
384
387
  const r = await configProvider.fetchEffective(undefined);
385
388
  if (r) {
386
389
  const verdict = judgeConfigCandidate(r);
387
390
  if (verdict.verdict === "rejected") {
391
+ candidateRejectionNotes = buildCandidateRejectionNotes({ errors: verdict.errors, ...(configProvider.kind === "local" ? { dir: root } : {}) });
388
392
  for (const de of r.domainErrors ?? [])
389
393
  logger.warn("config_domain_invalid", { domain: de.domain, error: de.error, note: CONFIG_DOMAIN_INVALID_NOTE });
390
394
  logger.warn("config_candidate_rejected", buildCandidateRejectedFields(r, verdict, "run-local", { lkgVersion: "(env)", ...(configProvider.kind === "local" ? { dir: root } : {}) }));
@@ -419,7 +423,7 @@ export async function runLocal(argv, deps = {}) {
419
423
  else
420
424
  logger.warn("config_source_unreachable_using_env", { source: configProvider.kind, err: String(err) });
421
425
  }
422
- const noDefaultModel = defaultModelRefusal(config, servedModelTableLeg(config));
426
+ const noDefaultModel = defaultModelRefusal({ models: config.models, modelRefusals: config.modelRefusals, candidateRejectionNotes }, servedModelTableLeg(config));
423
427
  if (noDefaultModel !== undefined)
424
428
  throw new Error(noDefaultModel);
425
429
  const routeVerdict = judgeServedModelRoute(config, { envTableIsPlaceholder: false });
@@ -474,7 +478,7 @@ export async function runLocal(argv, deps = {}) {
474
478
  }
475
479
  const sessionStore = fileBackend.sessionStore;
476
480
  const keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
477
- const hostRx = config.remoteExec?.provider === "host" ? config.remoteExec : undefined;
481
+ const hostRx = config.remoteExec.provider === "host" ? config.remoteExec : undefined;
478
482
  const workspaceDir = args.workspace ?? hostRx?.workspaceBase ?? process.cwd();
479
483
  await settleHostLaneShell(config, logger);
480
484
  warnReadDenyFloorUnkept(config, logger);
@@ -720,7 +724,7 @@ export async function runLocal(argv, deps = {}) {
720
724
  ...(a2a ? { a2a } : {}),
721
725
  ...(Object.keys(limits).length > 0 ? { limits } : {}),
722
726
  }, config, workspaceDir), onAsk);
723
- logger.info("run_local_start", { scenario: scenarioName, model: spec.model, sessionId, exec: executionLaneOf(config.remoteExec?.provider) });
727
+ logger.info("run_local_start", { scenario: scenarioName, model: spec.model, sessionId, exec: config.remoteExec.provider });
724
728
  const settleSessionBackground = async () => {
725
729
  const reaped = defaultTaskRegistry.reapSessionBackground(sessionId, scope);
726
730
  if (reaped === 0)
package/dist/runs.d.ts CHANGED
@@ -151,33 +151,40 @@ export declare function releaseKeyIfZeroWorkRefusal(runStore: {
151
151
  * observable instead of a silent feature outage.
152
152
  */
153
153
  /**
154
- * 「这一次用户消息提交是不是一句**提问**」的唯一读法 —— 三处用户回退锚(后台腿与续跑腿的 {@link TurnAnchorCapture}、`/v1/tasks/stream`
155
- * 腿的 `userMsgEntryId`)同调这一只。
154
+ * 「这一次用户消息提交是不是这个 run 的**开场提示**」的唯一读法 —— 三处用户回退锚(后台腿与续跑腿的 {@link TurnAnchorCapture}、`/v1/tasks/stream`
155
+ * 腿的 `userMsgEntryId`)同调这一只;调用点零各自判、零按正文判,且都是「最后一次交出的赢」。
156
156
  *
157
- * 目标声明了附件时,引擎把每只附件铸成**一条自己的用户消息**,紧跟在目标后面提交(core `human_input.attachments` 顶注:
158
- * 「each attachment is delivered as its own message after the objective; its `message_committed` is the delivery」)。
159
- * 所以一次带 N 只附件的提交会出 1 + N 次 `message_committed{role:"user"}`,而「回到这条提问」的锚要的是**人的那条**
160
- * (core 的 `resumeAt` 认它:「a `resumeAt` that keeps the message keeps its group」;以附件帧作 `resumeAt` 引擎拒 `resume_at.not_a_message`),
161
- * 不是排在最后的附件帧。目标**之前**还可能有引擎排队的注入消息同批提交(亲读 core `engine/harness/agent-harness.js` 的 `takePrompts`:
162
- * 排队消息 ⇒ 目标 ⇒ 附件帧;真案 = 工作区是 git 仓且带图时,git 状态帧单独排在目标前面),所以「窗口里第一次用户提交」不是判据。
157
+ * **回退锚 = 该轮开场提示,一个 run 一个(开场窗 + 闩)**:run 一开始就开着一个**开场窗**,收集第一次模型输出之前的 user 提交;窗关上之后(闩上),同 run 的 user-role 提交 ——
158
+ * 用户打断时引擎收尾追加的「[Request interrupted by user]」、第一次模型调用前后排进来的 steer 正文、答完之后再来的 steer —— 一律不交。这是 CC「rewind to the message that started this turn」的
159
+ * 同义,与 core `resumeAt` 的 `before` 语义(叶 = 目标的 parent)配对:锚在开场提示上,切到它的 parent = 这一轮整个撤回;锚若漂到打断标记行上,
160
+ * parent 就是被撤回的那句提示本身,模型仍见它。同根:core 的文件历史边界按「本 run 第一条 user 提交」的 entry 键入(`rewindFilesTo` / `POST /v1/sessions/:id/rewind-files`
161
+ * 凭锚找边界),锚漂到没有自己边界的打断标记行上就解不到。打断标记行永远不是锚。
162
+ * 「一个 run」= 锚的键(`taskId`)的边界:读法实例每个 run 新建一只;续既有 run 的续跑腿不写用户锚(见 `resume-legs.ts`)。
163
163
  *
164
- * **为什么是「窗口 + 严格吻合」而不是读标记**:`message_committed` 上只有 `entryId / role / toolCallId?`,附件帧与用户真提交在事件上**不可辨认**;
165
- * 落盘的行上有标记(`attachment` 键;引擎收尾的中断标记带 `provenance: "engine-note"`),但事件到手的那一刻本仓读不到那一行
166
- * (会话店面没有按条目读的口,只有整日志导出),所以只能数。数的前提是「目标之后紧接恰好 N 只帧、其后才是别的」—— 前提成立才落锚,
167
- * **不成立就不猜**:猜错的锚会落在附件帧上(引擎拒)或引擎的中断标记上(回到的不是用户那句)。
164
+ * **窗里怎么认**。`message_committed` 上只有 `entryId / role / toolCallId?`:引擎排队在目标之前同批提交的消息(带图且工作区是 git 仓时单独排的 git 状态帧;会话空闲期间到的后台任务通知)、
165
+ * 目标、目标声明的附件帧、引擎收尾的中断标记,在事件上**不可辨认**(落盘的行上有标记 —— `attachment` 键、`provenance: "engine-note"` —— 但事件到手那一刻本仓读不到那一行:
166
+ * 会话店面没有按条目读的口,只有整日志导出),所以只能数。引擎的提交序(亲读 core `engine/harness/agent-harness.js` 的 `takePrompts`):排队消息 ⇒ 目标 ⇒ 附件帧;
167
+ * 中断标记只在打断收尾时追加(此时第一次模型输出没有出来,窗是被 `turn_end` 切断,不是被输出关上)。
168
+ * · **临时锚**:不带附件的提交,窗里**第一条** user 提交到手那一刻就交出 —— 打断 / 取消 / 断连常发生在第一次模型输出之前,那时窗还没关,锚必须已经在;
169
+ * 它也是 core 文件历史边界的键(本 run 第一条 user 提交)。
170
+ * · **校正**:窗被**非用户提交**(第一次助手消息 / 工具结果)关上 ⇒ 窗内共 k 条 user 提交、声明了 N 只附件帧:k ≥ N+1 时开场提示 = 倒数第 N+1 条(严格吻合)。
171
+ * 不带附件而 k > 1(目标之前有引擎排队的消息)⇒ 交出这一条,**盖过**临时锚(调用方「最后一次赢」,与修前同读:修前的读法就是『开场批里最后一条 user 提交』);k = 1 ⇒ 临时锚已是它,不再交。
172
+ * 带附件的提交没有临时锚(此刻还不知道哪几条是帧),只在关窗这一刻交一次;k < N+1(帧数不符)⇒ 不猜。
173
+ * · 窗被 `turn_end` 先切断 ⇒ 第一次模型调用没出任何输出就收了(halt / interrupt / cancel / 空失败):窗里可能夹着引擎收尾的中断标记,数 N 会落在帧或标记上 ⇒ **不校正**,
174
+ * 临时锚(不带附件)原样留着,带附件的提交不猜、不落锚。切断即闩上。
175
+ * · 带附件的提交,窗内又应用了一条别的输入(`human_input{applied}`,如第一次模型调用前排进来的 steer;事件先于它的正文提交到手)⇒ 窗里多了一条别人的消息,数 N 会落在帧后面的 steer 上 ⇒ 不猜。
176
+ * 不带附件的提交不看输入条数:多条 applied 输入可以合成一条提交(续跑把停驻的 steer 与 wake 文本并成一条续跑消息),按修前同读校正到窗内最后一条。排队未应用(`delivery: "queued"`)的输入不动窗。窗还开着时继续攒,直到被关上。
177
+ * · 「不猜」= 这个 run 不落(带附件)或不校正(不带附件),且窗关上之后闩上 —— 其后的 user 提交(steer 正文、打断标记)不是开场提示,不顶上来;拿这次 run 的 taskId 去 `resumeAt`
178
+ * 得 404 `resume_at.unknown_event`(文案点名带附件这一类成因)。
179
+ * 窗关上之前一个 user 提交都没有就关了(续跑腿里先到的是工具结果 / 助手消息)⇒ 窗照开着,不闩:那一条之后第一条 user 提交才是这个 run 里的第一条。
168
180
  *
169
- * 读法:
170
- * · `human_input{delivery:"applied"}` 带 N 只附件 ⇒ 开窗;窗内的用户提交只攒、不落锚(此刻还不知道它们是不是『目标 + N 只帧』)。
171
- * · 窗被**非用户提交**(第一次助手消息 / 工具结果)关上 ⇒ 窗内共 k 次用户提交,k ≥ N+1 时提问 = 倒数第 N+1 次(严格吻合);k < N+1(帧数不符)⇒ 不猜。
172
- * · 窗被 `turn_end` 先切断 ⇒ 第一次模型调用没出任何提交就收了(halt / interrupt / 空失败):窗里可能夹着引擎收尾的中断标记,数 N 会落在帧或标记上 ⇒ 不猜。
173
- * · 窗内又应用了一条别的输入(`human_input{applied}`,如第一次模型调用前排进来的 steer;事件先于它的正文提交到手)⇒ 窗里多了一条别人的消息,数 N 会落在帧上 ⇒ 窗作废、不猜,
174
- * 之后的用户提交(含那条 steer 正文)是窗口之外的提交,最后一次赢。排队未应用(`delivery: "queued"`)的输入不动窗。
175
- * · 「不猜」= 返回 `undefined`、这次提交不落锚;拿这次 run 的 taskId 去 `resumeAt` 得 404 `resume_at.unknown_event`(文案点名这一类成因)。
176
- * 窗口之外的用户提交(如 interrupt 带话的 steer 正文,在 `turn_end` 之后提交)照修前读法(是提问,最后一次赢)。
177
- * 返回这次提交之后的提问 `entryId`(调用方照旧「最后一次赢」地落锚),不是提问相关的提交返回 `undefined`。
181
+ * 已知边界(引擎在 `message_committed` 上带来源标 / 输入标之日见下):
182
+ * · 被 `turn_end` 切断(第一次模型输出之前打断 / 取消)、不带附件、且由引擎排队的消息领头的 run —— 窗来不及校正,锚落在领头的那一条上(修前:取消 = 目标,halt / interrupt = 打断标记)。
183
+ * 它与 core 文件历史边界的键是同一条消息,`resumeAtMode:"before"` 的叶仍是整轮之前;含目标的 `resumeAt` 只留下领头那条。
184
+ * · 不带附件、第一次模型输出之前就应用了一条 steer:校正到窗内最后一条 = steer 正文(与修前同读)。
178
185
  *
179
- * 退役条件:引擎在落盘的帧上(`message_committed`)带上附件标记之日,本读法整体换成「按标记判一次」(零计数、无窗口、无拒臂),
180
- * 窗口 / 严格吻合 / 不猜三臂与 `resume_at.unknown_event` 文案里对应的那一句一并删除。
186
+ * 退役条件:引擎在落盘的帧上(`message_committed`)带上来源标(附件标记 / 引擎消息标)之日,本读法整体换成「第一条非引擎消息」(零计数、无窗口、无校正、无拒臂),
187
+ * 窗口 / 严格吻合 / 不猜三臂与 `resume_at.unknown_event` 文案里对应的那一句一并删除,领头排队消息的边界随之消失。
181
188
  */
182
189
  export declare function createPromptCommitReader(): (ev: {
183
190
  readonly type: string;
@@ -206,12 +213,17 @@ export declare class TurnAnchorCapture {
206
213
  * assistant). This is the CC rewind target ("rewind to the prompt" = the code-restore parity path — a code
207
214
  * change happens in a tool turn WITHIN a prompt's run, so rewinding to the prompt + rewindFiles undoes it).
208
215
  * Keyed by the run's taskId (the handle the shell already holds from the POST response — no eventId→entryId
209
- * side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus. */
216
+ * side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
217
+ * The anchor is the run's OPENING prompt (the reader's opening window: provisional on the first user commit, corrected
218
+ * when the first model output closes the window, latched after); a later
219
+ * user-role commit in the same run — the interruption marker, a steer — never moves it. The capture instance is per
220
+ * run: a leg that CONTINUES an existing run (same taskId) wires no `captureUser` (its opening prompt was anchored
221
+ * by the first leg). */
210
222
  private readonly captureUser?;
211
223
  /** The turn's FIRST text_delta eventId = the message's stable resume handle (also stamped on the durable text event). */
212
224
  firstTextEventId: string | undefined;
213
225
  private turnHadTool;
214
- /** 用户提交是不是提问的唯一读法({@link createPromptCommitReader};附件帧不是提问)。 */
226
+ /** 用户提交是不是开场提示的唯一读法({@link createPromptCommitReader};开场窗 + 闩 —— 开场提示之后打断标记 / steer 不改锚;附件帧不是提问)。 */
215
227
  private readonly promptCommit;
216
228
  constructor(capture: ((eventId: string) => Promise<void>) | undefined,
217
229
  /** 这只捕获器在哪条腿上(写失败的 fail-open 探针行带它)。 */
@@ -222,16 +234,22 @@ export declare class TurnAnchorCapture {
222
234
  * assistant). This is the CC rewind target ("rewind to the prompt" = the code-restore parity path — a code
223
235
  * change happens in a tool turn WITHIN a prompt's run, so rewinding to the prompt + rewindFiles undoes it).
224
236
  * Keyed by the run's taskId (the handle the shell already holds from the POST response — no eventId→entryId
225
- * side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus. */
237
+ * side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
238
+ * The anchor is the run's OPENING prompt (the reader's opening window: provisional on the first user commit, corrected
239
+ * when the first model output closes the window, latched after); a later
240
+ * user-role commit in the same run — the interruption marker, a steer — never moves it. The capture instance is per
241
+ * run: a leg that CONTINUES an existing run (same taskId) wires no `captureUser` (its opening prompt was anchored
242
+ * by the first leg). */
226
243
  captureUser?: ((entryId: string) => Promise<void>) | undefined);
227
- /** A `human_input` arrived — the objective's declared attachments open the frame window of {@link createPromptCommitReader}. */
244
+ /** A `human_input` arrived — the objective's declared attachments open the frame window of {@link createPromptCommitReader} (another applied input inside the window voids it). */
228
245
  onHumanInput(ev: {
229
246
  readonly type: string;
230
247
  }): void;
231
248
  /** A `message_committed` arrived — capture a USER-message rewind anchor (CC parity). Best-effort (a failure only
232
- * makes that one prompt non-rewindable). Only a user commit that is a PROMPT (not an attachment frame trailing the
233
- * objective — {@link createPromptCommitReader}; an attachment window is decided when a non-user commit closes it, so
234
- * the anchor of an attachment-carrying prompt lands on THAT call); assistant/toolResult committed entries are handled by
249
+ * makes that one prompt non-rewindable). Only the run's OPENING prompt anchors (the opening window's user commit — not an
250
+ * attachment frame trailing the objective, not the interruption marker / a steer that follows it —
251
+ * {@link createPromptCommitReader}; an attachment window is decided when a non-user commit closes it, so the anchor of an
252
+ * attachment-carrying prompt lands on THAT call); assistant/toolResult committed entries are handled by
235
253
  * the turn-text path (assistant) or deliberately not anchored (toolResult — `resumeAt` rejects them). */
236
254
  onMessageCommitted(role: string | undefined, entryId: string | undefined): Promise<void>;
237
255
  /** A text_delta arrived — latch the first DEFINED eventId as the message handle (eventId is optional on the stream). */