@sema-agent/server 7.138.0 → 7.140.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 (332) hide show
  1. package/MIGRATION.md +457 -7
  2. package/README.md +7 -4
  3. package/README.zh-CN.md +6 -4
  4. package/USAGE.md +91 -41
  5. package/deploy/sema-up/README.md +1 -1
  6. package/deploy/sema-up/lib/lanes.json +3 -2
  7. package/dist/adoption/runner.js +1 -1
  8. package/dist/adoption/sql.js +1 -1
  9. package/dist/adoption/wire.d.ts +3 -3
  10. package/dist/approval-card.d.ts +26 -26
  11. package/dist/bench/s1/arms.d.ts +1 -1
  12. package/dist/bench/s1/arms.js +1 -3
  13. package/dist/bench/s1/live-deps.js +3 -2
  14. package/dist/bench/s1/row.d.ts +5 -2
  15. package/dist/bench/s1/row.js +2 -22
  16. package/dist/bench/s1/run-firm.js +2 -2
  17. package/dist/boot/adoption.js +1 -1
  18. package/dist/boot/device-lane.d.ts +8 -3
  19. package/dist/boot/device-lane.js +7 -2
  20. package/dist/boot/execution-env.d.ts +4 -2
  21. package/dist/boot/execution-env.js +28 -34
  22. package/dist/boot/execution-lane.d.ts +9 -1
  23. package/dist/boot/execution-lane.js +6 -1
  24. package/dist/boot/governance-seams.d.ts +3 -2
  25. package/dist/boot/governance-seams.js +9 -11
  26. package/dist/boot/memory-boundary.d.ts +14 -51
  27. package/dist/boot/memory-boundary.js +10 -20
  28. package/dist/boot/memory-consolidation.d.ts +15 -11
  29. package/dist/boot/memory-consolidation.js +25 -14
  30. package/dist/boot/resolve-spec.d.ts +4 -6
  31. package/dist/boot/resolve-spec.js +10 -13
  32. package/dist/boot/retention-lane.d.ts +5 -5
  33. package/dist/boot/retention-lane.js +0 -6
  34. package/dist/boot/runner-deps.d.ts +6 -4
  35. package/dist/boot/runner-deps.js +3 -1
  36. package/dist/boot/session-faces.d.ts +0 -3
  37. package/dist/boot/session-faces.js +15 -8
  38. package/dist/boot/stage-02-web-admin-pull.js +2 -2
  39. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  40. package/dist/boot/stage-03-store-backend.js +2 -3
  41. package/dist/boot/stage-04-stores.d.ts +2 -6
  42. package/dist/boot/stage-04-stores.js +5 -5
  43. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  44. package/dist/boot/stage-05-execution-env.js +2 -2
  45. package/dist/boot/stage-06-runners.d.ts +2 -6
  46. package/dist/boot/stage-06-runners.js +2 -3
  47. package/dist/boot/stage-07-capability-layer.d.ts +2 -6
  48. package/dist/boot/stage-08-reapers.d.ts +2 -6
  49. package/dist/boot/stage-09-leader.d.ts +2 -6
  50. package/dist/boot/stage-09-leader.js +1 -2
  51. package/dist/boot/stage-10-http-server.d.ts +2 -6
  52. package/dist/boot/stage-10-http-server.js +7 -6
  53. package/dist/boot/stores.d.ts +3 -6
  54. package/dist/boot/stores.js +27 -40
  55. package/dist/boot/task-list-lane.d.ts +1 -1
  56. package/dist/boot/task-list-lane.js +1 -1
  57. package/dist/boot/web-admin.js +37 -11
  58. package/dist/capabilities/execution-lane.d.ts +2 -2
  59. package/dist/capabilities/mcp-probe.js +1 -1
  60. package/dist/capabilities/scenarios.d.ts +1 -1
  61. package/dist/capability-facts.d.ts +15 -7
  62. package/dist/capability-facts.js +8 -3
  63. package/dist/config-catalog.js +9 -8
  64. package/dist/config-invariants.d.ts +23 -3
  65. package/dist/config-invariants.js +42 -0
  66. package/dist/config-provider.d.ts +33 -37
  67. package/dist/config-provider.js +51 -30
  68. package/dist/config-types.d.ts +21 -7
  69. package/dist/config.d.ts +33 -0
  70. package/dist/config.js +46 -16
  71. package/dist/delegated-session-owner.d.ts +4 -3
  72. package/dist/delegated-session-owner.js +1 -1
  73. package/dist/deployment-shape.d.ts +10 -9
  74. package/dist/deployment-shape.js +4 -4
  75. package/dist/device-enrollment.d.ts +41 -2
  76. package/dist/device-enrollment.js +27 -12
  77. package/dist/device-store.d.ts +58 -85
  78. package/dist/device-store.js +19 -49
  79. package/dist/device-ws-hub.js +2 -1
  80. package/dist/env-name-allowlist-knobs.d.ts +5 -4
  81. package/dist/exec-cut.d.ts +60 -0
  82. package/dist/exec-cut.js +36 -0
  83. package/dist/execution-lane-caps.d.ts +115 -105
  84. package/dist/execution-lane-caps.js +76 -82
  85. package/dist/execution-placement.d.ts +259 -0
  86. package/dist/execution-placement.js +199 -0
  87. package/dist/field-conflict.d.ts +3 -2
  88. package/dist/field-conflict.js +1 -0
  89. package/dist/hosted-posture.d.ts +2 -2
  90. package/dist/http/admission.js +8 -19
  91. package/dist/http/checkpoint-ctx.d.ts +21 -12
  92. package/dist/http/checkpoint-ctx.js +4 -2
  93. package/dist/http/claimed-run.d.ts +1 -1
  94. package/dist/http/durable-run-leg.js +9 -5
  95. package/dist/http/execution-context.d.ts +218 -0
  96. package/dist/http/execution-context.js +330 -0
  97. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  98. package/dist/http/memory-compliance-failure-reply.js +5 -0
  99. package/dist/http/memory-layer-reply.d.ts +30 -0
  100. package/dist/http/memory-layer-reply.js +24 -0
  101. package/dist/http/resume-legs.js +63 -36
  102. package/dist/http/retired-service-deps.d.ts +1 -1
  103. package/dist/http/retired-service-deps.js +1 -1
  104. package/dist/http/route-ctx.d.ts +14 -8
  105. package/dist/http/routes/adoption.js +1 -1
  106. package/dist/http/routes/background.d.ts +29 -1
  107. package/dist/http/routes/background.js +29 -2
  108. package/dist/http/routes/devices.d.ts +13 -19
  109. package/dist/http/routes/devices.js +21 -26
  110. package/dist/http/routes/memory-bundle.js +3 -0
  111. package/dist/http/routes/memory-compliance.js +8 -1
  112. package/dist/http/routes/memory-consolidation.js +12 -1
  113. package/dist/http/routes/memory-origin.js +14 -2
  114. package/dist/http/routes/memory-policy.js +5 -0
  115. package/dist/http/routes/session-sync.js +110 -15
  116. package/dist/http/routes/sessions.d.ts +6 -0
  117. package/dist/http/routes/sessions.js +143 -22
  118. package/dist/http/routes/side-query.d.ts +12 -4
  119. package/dist/http/routes/side-query.js +4 -5
  120. package/dist/http/routes/tasks.js +41 -33
  121. package/dist/http/server.d.ts +40 -44
  122. package/dist/http/server.js +13 -2
  123. package/dist/http/session-inherit-env.d.ts +3 -4
  124. package/dist/http/session-inherit-env.js +1 -1
  125. package/dist/http/wire-types.d.ts +8 -12
  126. package/dist/identity-source.d.ts +1 -1
  127. package/dist/identity-source.js +1 -1
  128. package/dist/index.d.ts +1 -0
  129. package/dist/lane-home-probe.d.ts +68 -42
  130. package/dist/lane-home-probe.js +53 -30
  131. package/dist/leader/wire.js +5 -4
  132. package/dist/memory-bundle-engine.d.ts +16 -9
  133. package/dist/memory-bundle-engine.js +29 -6
  134. package/dist/memory-operator-faces.d.ts +85 -30
  135. package/dist/memory-operator-faces.js +136 -30
  136. package/dist/memory-project-layer.d.ts +3 -21
  137. package/dist/memory-project-layer.js +11 -8
  138. package/dist/memory-scope-stores.d.ts +73 -0
  139. package/dist/memory-scope-stores.js +86 -0
  140. package/dist/memory-scope.d.ts +29 -5
  141. package/dist/memory-scope.js +16 -4
  142. package/dist/memory-sync-client.d.ts +70 -18
  143. package/dist/memory-sync-client.js +215 -117
  144. package/dist/memory-sync.d.ts +1 -1
  145. package/dist/memory-sync.js +3 -2
  146. package/dist/observability/cost-taxonomy.d.ts +2 -2
  147. package/dist/observability/fail-open.d.ts +12 -0
  148. package/dist/observability/fail-open.js +12 -0
  149. package/dist/observability/run-terminal.js +0 -1
  150. package/dist/orchestration/workflow-notify-journal.js +4 -4
  151. package/dist/org-memory-admission.d.ts +4 -3
  152. package/dist/org-memory-admission.js +6 -6
  153. package/dist/parked-decide.d.ts +34 -9
  154. package/dist/parked-decide.js +12 -19
  155. package/dist/parked-revive-surface.d.ts +12 -15
  156. package/dist/parked-revive-surface.js +3 -6
  157. package/dist/peer-seat.d.ts +13 -7
  158. package/dist/peer-seat.js +37 -3
  159. package/dist/plugins/adoption-log-sql.js +4 -4
  160. package/dist/plugins/approval-ask-store-file.d.ts +7 -0
  161. package/dist/plugins/approval-ask-store-file.js +11 -0
  162. package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
  163. package/dist/plugins/approval-ask-store-memory.js +12 -0
  164. package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
  165. package/dist/plugins/approval-ask-store-sql.js +44 -26
  166. package/dist/plugins/approval-nonce-store.js +4 -4
  167. package/dist/plugins/blob-backend.d.ts +4 -4
  168. package/dist/plugins/blob-backend.js +7 -7
  169. package/dist/plugins/breaker-state-sql.js +2 -2
  170. package/dist/plugins/caching-session-store.d.ts +6 -2
  171. package/dist/plugins/caching-session-store.js +9 -3
  172. package/dist/plugins/checkpoint-index-columns.js +2 -2
  173. package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
  174. package/dist/plugins/checkpoint-store-sql.js +21 -23
  175. package/dist/plugins/device-store-sql.d.ts +25 -51
  176. package/dist/plugins/device-store-sql.js +68 -122
  177. package/dist/plugins/ensure-index.d.ts +1 -2
  178. package/dist/plugins/execution-placement-sql.d.ts +151 -0
  179. package/dist/plugins/execution-placement-sql.js +223 -0
  180. package/dist/plugins/file-history-store-sql.d.ts +9 -8
  181. package/dist/plugins/file-history-store-sql.js +9 -9
  182. package/dist/plugins/file-run-store.d.ts +6 -1
  183. package/dist/plugins/file-run-store.js +4 -0
  184. package/dist/plugins/fork-routing-session-store.d.ts +6 -0
  185. package/dist/plugins/fork-routing-session-store.js +16 -0
  186. package/dist/plugins/image-bake-store-sql.js +9 -9
  187. package/dist/plugins/image-index-sql.js +11 -11
  188. package/dist/plugins/leader-run-store-sql.js +4 -4
  189. package/dist/plugins/local-session-store.d.ts +149 -50
  190. package/dist/plugins/local-session-store.js +382 -107
  191. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  192. package/dist/plugins/mailbox-store-sql.js +4 -4
  193. package/dist/plugins/memory-engine-tidb.js +5 -5
  194. package/dist/plugins/memory-key-guards.d.ts +4 -0
  195. package/dist/plugins/memory-key-guards.js +1 -0
  196. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  197. package/dist/plugins/memory-run-store.d.ts +1 -1
  198. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  199. package/dist/plugins/one-time-migrations.d.ts +117 -8
  200. package/dist/plugins/one-time-migrations.js +408 -38
  201. package/dist/plugins/org-delivery-quota-store.js +2 -2
  202. package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
  203. package/dist/plugins/outcome-ledger-sql.js +2 -2
  204. package/dist/plugins/permission-rule-store-sql.d.ts +17 -19
  205. package/dist/plugins/permission-rule-store-sql.js +29 -32
  206. package/dist/plugins/pg-pool.d.ts +7 -3
  207. package/dist/plugins/pg-session-storage.d.ts +31 -20
  208. package/dist/plugins/pg-session-storage.js +120 -52
  209. package/dist/plugins/remote-env-adb.d.ts +18 -19
  210. package/dist/plugins/remote-env-adb.js +91 -66
  211. package/dist/plugins/remote-env-device.d.ts +23 -31
  212. package/dist/plugins/remote-env-device.js +19 -17
  213. package/dist/plugins/remote-env-e2b.d.ts +27 -21
  214. package/dist/plugins/remote-env-e2b.js +91 -45
  215. package/dist/plugins/remote-env-file-error.d.ts +3 -1
  216. package/dist/plugins/remote-env-file-error.js +9 -3
  217. package/dist/plugins/remote-env-host.d.ts +31 -34
  218. package/dist/plugins/remote-env-host.js +91 -72
  219. package/dist/plugins/remote-env-k8s.d.ts +13 -29
  220. package/dist/plugins/remote-env-k8s.js +63 -55
  221. package/dist/plugins/remote-env-local-docker.d.ts +24 -12
  222. package/dist/plugins/remote-env-local-docker.js +49 -61
  223. package/dist/plugins/remote-env-ssh.d.ts +11 -19
  224. package/dist/plugins/remote-env-ssh.js +74 -57
  225. package/dist/plugins/remote-shell.d.ts +100 -3
  226. package/dist/plugins/remote-shell.js +166 -2
  227. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  228. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  229. package/dist/plugins/retention-lane-store-sql.js +2 -2
  230. package/dist/plugins/retention-store-sql.d.ts +10 -7
  231. package/dist/plugins/retention-store-sql.js +13 -7
  232. package/dist/plugins/run-store-sql.d.ts +13 -3
  233. package/dist/plugins/run-store-sql.js +20 -15
  234. package/dist/plugins/schema-consistency.d.ts +21 -11
  235. package/dist/plugins/schema-consistency.js +15 -9
  236. package/dist/plugins/schema-drift-sentence.d.ts +27 -0
  237. package/dist/plugins/schema-drift-sentence.js +38 -0
  238. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  239. package/dist/plugins/schema-ensure-legs.js +2 -2
  240. package/dist/plugins/schema-live-columns.d.ts +1 -1
  241. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  242. package/dist/plugins/session-fork.d.ts +54 -0
  243. package/dist/plugins/session-fork.js +38 -1
  244. package/dist/plugins/session-row-sql.d.ts +22 -0
  245. package/dist/plugins/session-row-sql.js +81 -0
  246. package/dist/plugins/session-rules-column.d.ts +1 -1
  247. package/dist/plugins/session-rules-column.js +1 -1
  248. package/dist/plugins/session-store.d.ts +1 -1
  249. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  250. package/dist/plugins/session-workspace-cell.js +1 -1
  251. package/dist/plugins/shared-memory-store-sql.js +2 -2
  252. package/dist/plugins/sql-driver.d.ts +10 -5
  253. package/dist/plugins/sql-driver.js +6 -6
  254. package/dist/plugins/sql-errors.js +1 -1
  255. package/dist/plugins/store-backend.d.ts +5 -7
  256. package/dist/plugins/store-backend.js +23 -11
  257. package/dist/plugins/store-contracts.d.ts +25 -5
  258. package/dist/plugins/task-list-store-sql.js +11 -11
  259. package/dist/plugins/tidb-pool.d.ts +12 -7
  260. package/dist/plugins/tidb-pool.js +13 -7
  261. package/dist/plugins/tidb-session-storage.js +4 -4
  262. package/dist/plugins/tidb-session-store.d.ts +57 -26
  263. package/dist/plugins/tidb-session-store.js +127 -59
  264. package/dist/plugins/tool-result-store-sql.d.ts +5 -4
  265. package/dist/plugins/tool-result-store-sql.js +21 -13
  266. package/dist/plugins/user-input-ledger-sql.js +2 -2
  267. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  268. package/dist/plugins/workflow-run-store-sql.js +19 -19
  269. package/dist/plugins/write-behind-counter.d.ts +2 -3
  270. package/dist/plugins/write-behind-counter.js +5 -5
  271. package/dist/project-memory.d.ts +9 -15
  272. package/dist/project-memory.js +5 -4
  273. package/dist/request-key-closure.js +1 -1
  274. package/dist/request-value-closure.d.ts +6 -7
  275. package/dist/request-value-closure.js +1 -3
  276. package/dist/resource-suspend.d.ts +14 -12
  277. package/dist/resource-suspend.js +1 -1
  278. package/dist/resource-window.d.ts +4 -3
  279. package/dist/run-local.d.ts +6 -0
  280. package/dist/run-local.js +34 -35
  281. package/dist/runs.d.ts +10 -5
  282. package/dist/runs.js +52 -66
  283. package/dist/security.d.ts +38 -12
  284. package/dist/security.js +8 -2
  285. package/dist/server-secret-env.d.ts +9 -5
  286. package/dist/session-children-retire.d.ts +27 -9
  287. package/dist/session-children-retire.js +9 -5
  288. package/dist/session-incarnation.d.ts +20 -10
  289. package/dist/session-incarnation.js +5 -3
  290. package/dist/session-policy-wire.d.ts +1 -1
  291. package/dist/session-row.d.ts +114 -5
  292. package/dist/session-row.js +55 -5
  293. package/dist/session-titler.d.ts +2 -2
  294. package/dist/sql-engine-posture.d.ts +1 -1
  295. package/dist/sql-engine-posture.js +1 -1
  296. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  297. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  298. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  299. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  300. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  301. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  302. package/dist/task-a2a.d.ts +1 -1
  303. package/dist/task-a2a.js +5 -6
  304. package/dist/task-cwd.d.ts +6 -1
  305. package/dist/task-mcp.d.ts +22 -9
  306. package/dist/task-mcp.js +17 -9
  307. package/dist/terminal.d.ts +27 -0
  308. package/dist/terminal.js +6 -0
  309. package/dist/tool-approval.d.ts +6 -0
  310. package/dist/tool-approval.js +8 -1
  311. package/dist/trace/project.d.ts +1 -0
  312. package/dist/trace/project.js +1 -0
  313. package/dist/trace/redact.d.ts +3 -1
  314. package/dist/trace/redact.js +80 -28
  315. package/dist/trace/self-minted-wire.d.ts +169 -2
  316. package/dist/trace/self-minted-wire.js +54 -1
  317. package/dist/url-refusal.d.ts +1 -1
  318. package/dist/web-admin-client/apply-effective.d.ts +17 -3
  319. package/dist/web-admin-client/apply-effective.js +20 -10
  320. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  321. package/dist/web-admin-client/candidate-gate.js +1 -1
  322. package/dist/web-admin-client/http-client.d.ts +5 -4
  323. package/dist/web-admin-client/http-client.js +2 -2
  324. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  325. package/dist/web-admin-client/read-warnings.js +5 -9
  326. package/dist/web-admin-client/skills-mcp.js +3 -2
  327. package/dist/web-admin-client/types.d.ts +6 -0
  328. package/package.json +3 -3
  329. package/wire-changes/server@7.139.0.json +348 -0
  330. package/wire-changes/server@7.140.0.json +184 -0
  331. package/dist/http/device-placement.d.ts +0 -175
  332. package/dist/http/device-placement.js +0 -145
@@ -0,0 +1,199 @@
1
+ import { sessionRowMatches } from "@sema-agent/core";
2
+ export const EXECUTION_PLACEMENT_SEAT_CARRIERS = "every built-in session store carries one (the MySQL-protocol and PostgreSQL stores and the local store, i.e. the session store a StoreBackend hands out; the caching and fork-routing wrappers forward it), and an in-memory test or embedding passes InMemoryExecutionPlacementSeat";
3
+ export function isUnusableArchive(x) {
4
+ return x !== undefined && x.state === "unusable";
5
+ }
6
+ export function executionPlacementView(cell) {
7
+ switch (cell.role) {
8
+ case "absent":
9
+ return { role: "absent" };
10
+ case "writer":
11
+ return cell.device === undefined ? { role: "writer", lane: cell.lane } : { role: "writer", lane: cell.lane, device: { deviceId: cell.device.id, rev: cell.device.rev } };
12
+ case "mirror":
13
+ return { role: "mirror" };
14
+ case "forking":
15
+ return { role: "forking" };
16
+ default: {
17
+ const unknownRole = cell;
18
+ throw new Error(`executionPlacementView: no projection for ${JSON.stringify(unknownRole)}`);
19
+ }
20
+ }
21
+ }
22
+ export function sameOccupant(a, b) {
23
+ return sessionRowMatches({ row: { owner: a.owner ?? null, incarnation: a.incarnation } }, b, noLogMark);
24
+ }
25
+ function noLogMark() {
26
+ throw new Error("sameOccupant: an occupant check carries no log mark, yet the judge asked for one");
27
+ }
28
+ export class SessionWriterPresentError extends Error {
29
+ sessionId;
30
+ lane;
31
+ code = "conflict.session_writer";
32
+ constructor(sessionId, lane) {
33
+ super(`session ${sessionId} is written here on the ${lane} lane — an import cannot turn it into a mirror; nothing was written`);
34
+ this.sessionId = sessionId;
35
+ this.lane = lane;
36
+ this.name = "SessionWriterPresentError";
37
+ }
38
+ }
39
+ export class SessionForkInProgressError extends Error {
40
+ sessionId;
41
+ code = "conflict.fork_in_progress";
42
+ constructor(sessionId) {
43
+ super(`session ${sessionId} is the target of a fork that has not finished copying — retry that fork with the same key, or delete the session`);
44
+ this.sessionId = sessionId;
45
+ this.name = "SessionForkInProgressError";
46
+ }
47
+ }
48
+ export class SessionActiveRunError extends Error {
49
+ sessionId;
50
+ activeTaskId;
51
+ constructor(sessionId, activeTaskId) {
52
+ super(`session ${sessionId} has an active run (${activeTaskId}) — this write was refused inside its transaction; nothing was written`);
53
+ this.sessionId = sessionId;
54
+ this.activeTaskId = activeTaskId;
55
+ this.name = "SessionActiveRunError";
56
+ }
57
+ }
58
+ export const WRITABLE = "writable";
59
+ export function settledPlaceOutcome(root, reading, occupant, wanted) {
60
+ if (reading === undefined || !sameOccupant(reading.occupant, occupant))
61
+ return { outcome: "gone" };
62
+ const cell = reading.cell;
63
+ switch (cell.role) {
64
+ case "absent":
65
+ return WRITABLE;
66
+ case "writer":
67
+ return cell.lane === wanted.lane ? { outcome: "same" } : { outcome: "tree_bound", boundLane: cell.lane };
68
+ case "mirror":
69
+ return { outcome: "mirror" };
70
+ case "forking":
71
+ throw new SessionForkInProgressError(root);
72
+ default: {
73
+ const unknownRole = cell;
74
+ throw new Error(`settledPlaceOutcome: no arm for ${JSON.stringify(unknownRole)}`);
75
+ }
76
+ }
77
+ }
78
+ export function settledMirrorOutcome(root, reading, occupant) {
79
+ if (reading === undefined || !sameOccupant(reading.occupant, occupant))
80
+ return { outcome: "gone" };
81
+ const cell = reading.cell;
82
+ switch (cell.role) {
83
+ case "absent":
84
+ return WRITABLE;
85
+ case "writer":
86
+ return { outcome: "writer" };
87
+ case "mirror":
88
+ return { outcome: "mirrored" };
89
+ case "forking":
90
+ throw new SessionForkInProgressError(root);
91
+ default: {
92
+ const unknownRole = cell;
93
+ throw new Error(`settledMirrorOutcome: no arm for ${JSON.stringify(unknownRole)}`);
94
+ }
95
+ }
96
+ }
97
+ export function settledDeviceBindOutcome(root, reading, occupant, deviceId) {
98
+ if (reading === undefined || !sameOccupant(reading.occupant, occupant))
99
+ return { outcome: "gone" };
100
+ const cell = reading.cell;
101
+ switch (cell.role) {
102
+ case "absent":
103
+ return WRITABLE;
104
+ case "writer":
105
+ if (cell.lane !== "device")
106
+ return { outcome: "tree_bound", boundLane: cell.lane };
107
+ if (cell.device === undefined)
108
+ return WRITABLE;
109
+ return cell.device.id === deviceId ? { outcome: "same", device: cell.device } : { outcome: "device_conflict", device: cell.device };
110
+ case "mirror":
111
+ return { outcome: "mirror" };
112
+ case "forking":
113
+ throw new SessionForkInProgressError(root);
114
+ default: {
115
+ const unknownRole = cell;
116
+ throw new Error(`settledDeviceBindOutcome: no arm for ${JSON.stringify(unknownRole)}`);
117
+ }
118
+ }
119
+ }
120
+ export function settledDeviceRebindOutcome(reading, occupant, owner, expectedRev, targetDeviceId) {
121
+ if (reading === undefined || !sameOccupant(reading.occupant, occupant))
122
+ return { outcome: "gone" };
123
+ const device = boundDeviceOf(reading.cell);
124
+ if (device === undefined)
125
+ return { outcome: "gone" };
126
+ if (device.owner.tenant !== owner.tenant || device.owner.subject !== owner.subject)
127
+ return { outcome: "gone" };
128
+ if (device.rev !== expectedRev)
129
+ return { outcome: "rev_conflict", device };
130
+ return device.id === targetDeviceId ? { outcome: "idempotent", device } : WRITABLE;
131
+ }
132
+ export function boundDeviceOf(cell) {
133
+ switch (cell.role) {
134
+ case "writer":
135
+ return cell.lane === "device" ? cell.device : undefined;
136
+ case "absent":
137
+ case "mirror":
138
+ case "forking":
139
+ return undefined;
140
+ default: {
141
+ const unknownRole = cell;
142
+ throw new Error(`boundDeviceOf: no arm for ${JSON.stringify(unknownRole)}`);
143
+ }
144
+ }
145
+ }
146
+ export function assertPlaceableLane(root, cell) {
147
+ if (cell.lane === "device" || cell.device !== undefined) {
148
+ throw new Error(`execution placement of session ${root}: the device lane is placed by the device store (it judges the device row in the same transaction), not by the session store's seat`);
149
+ }
150
+ }
151
+ export class InMemoryExecutionPlacementSeat {
152
+ rows = new Map();
153
+ seatRow(root, occupant) {
154
+ if (!this.rows.has(root))
155
+ this.rows.set(root, { occupant, cell: { role: "absent" } });
156
+ }
157
+ dropRow(root) {
158
+ this.rows.delete(root);
159
+ }
160
+ async read(root) {
161
+ return this.rows.get(root);
162
+ }
163
+ async place(root, occupant, cell) {
164
+ assertPlaceableLane(root, cell);
165
+ const settled = settledPlaceOutcome(root, this.rows.get(root), occupant, cell);
166
+ if (settled !== WRITABLE)
167
+ return settled;
168
+ this.rows.set(root, { occupant, cell: { role: "writer", lane: cell.lane } });
169
+ return { outcome: "placed" };
170
+ }
171
+ async markMirror(root, occupant) {
172
+ const settled = settledMirrorOutcome(root, this.rows.get(root), occupant);
173
+ if (settled !== WRITABLE)
174
+ return settled;
175
+ this.rows.set(root, { occupant, cell: { role: "mirror" } });
176
+ return { outcome: "mirrored" };
177
+ }
178
+ bindDevice(root, occupant, device, placedAt) {
179
+ const settled = settledDeviceBindOutcome(root, this.rows.get(root), occupant, device.id);
180
+ if (settled !== WRITABLE)
181
+ return settled;
182
+ const placed = { id: device.id, owner: device.owner, rev: 0, placedAt };
183
+ this.rows.set(root, { occupant, cell: { role: "writer", lane: "device", device: placed } });
184
+ return { outcome: "bound", device: placed };
185
+ }
186
+ rebindDevice(root, occupant, owner, expectedRev, targetDeviceId, placedAt) {
187
+ const row = this.rows.get(root);
188
+ const settled = settledDeviceRebindOutcome(row, occupant, owner, expectedRev, targetDeviceId);
189
+ if (settled !== WRITABLE)
190
+ return settled;
191
+ const from = row !== undefined ? boundDeviceOf(row.cell)?.id : undefined;
192
+ if (from === undefined)
193
+ throw new Error(`execution placement of session ${root}: the rebind judge found a device cell that is no longer there — refusing to guess`);
194
+ const placed = { id: targetDeviceId, owner, rev: expectedRev + 1, placedAt };
195
+ this.rows.set(root, { occupant, cell: { role: "writer", lane: "device", device: placed } });
196
+ return { outcome: "rebound", device: placed, from };
197
+ }
198
+ }
199
+ //# sourceMappingURL=execution-placement.js.map
@@ -1,5 +1,5 @@
1
1
  /** 冲突的类(闭集)。同一个约束的几个拒点同一个词;新增一类见文件头。 */
2
- export declare const FIELD_CONFLICT_KINDS: readonly ["cascade_verify", "image_profile", "resume_anchor", "system_prompt_fold", "file_history_restore", "skills_disabled", "existing_session", "scratchpad_root", "ask_answer", "policy_person_ask", "plan_edit", "plan_mode_after", "bound_call_door", "remember_decision", "approval_feedback"];
2
+ export declare const FIELD_CONFLICT_KINDS: readonly ["cascade_verify", "image_profile", "resume_anchor", "system_prompt_fold", "file_history_restore", "skills_disabled", "existing_session", "fork_target", "scratchpad_root", "ask_answer", "policy_person_ask", "plan_edit", "plan_mode_after", "bound_call_door", "remember_decision", "approval_feedback"];
3
3
  /** 冲突的类(闭集词)。 */
4
4
  export type FieldConflictKind = (typeof FIELD_CONFLICT_KINDS)[number];
5
5
  /**
@@ -11,9 +11,10 @@ export interface FieldConflictCoordinates {
11
11
  readonly image_profile: "capabilitiesNeeded" | "sandboxImageProfile";
12
12
  readonly resume_anchor: "resumeAtMode" | "resumeAt";
13
13
  readonly system_prompt_fold: "appendSystemPrompt" | "settings.outputStyle";
14
- readonly file_history_restore: "fileHistory" | "restoreFiles" | "rewindFilesTo" | "rewindFiles";
14
+ readonly file_history_restore: "fileHistory" | "restoreFiles" | "rewindFilesTo";
15
15
  readonly skills_disabled: "disableSkills" | "skills" | `agents[${number}].skills`;
16
16
  readonly existing_session: "requireExistingSession" | "sessionId";
17
+ readonly fork_target: "forkId" | "forkNonce";
17
18
  readonly scratchpad_root: "cwd" | "scratchpadDir";
18
19
  readonly ask_answer: "decision" | "answer";
19
20
  readonly policy_person_ask: "decision" | "decidedBy";
@@ -6,6 +6,7 @@ export const FIELD_CONFLICT_KINDS = [
6
6
  "file_history_restore",
7
7
  "skills_disabled",
8
8
  "existing_session",
9
+ "fork_target",
9
10
  "scratchpad_root",
10
11
  "ask_answer",
11
12
  "policy_person_ask",
@@ -17,7 +17,7 @@
17
17
  * `multiTenant` 的反面 ⇒ 采纳,否则忽略(**不看车道**,任何 `REMOTE_EXEC` 都一样);
18
18
  * · `additionalDirectories` / `additionalReadDirectories` —— 表行 `callerOwnsWorkerDisk`(手在本 worker 盘上 ∧ 单主 = 今天只有 host);
19
19
  * · `settings.env` / `cwd` —— 表行 `callerCwd`(读能力表 `callerCwd` 位:host 单主才开,**device 不读租户**:那条路径落在
20
- * **发起者自己的设备**上,归属由 `device_session` 绑定行验过 ⇒ 跨租户面结构性不存在)。
20
+ * **发起者自己的设备**上,归属由根会话行执行格上的设备绑定验过 ⇒ 跨租户面结构性不存在)。
21
21
  *
22
22
  * ⇒ 先把这个判定位铸成**一处**,再让各条腿都读它(clay 裁定③,2026-09-22):**不许各自加特判**——
23
23
  * 每加一条特判,「这台机器算不算托管」在本仓就多一个可以自己漂的答案。
@@ -106,7 +106,7 @@ export declare const HOST_POSTURE_REFUSED_CODE = "request.host_posture_refused";
106
106
  * [ref] 前还有腿③(`approverPosture`,忽略 + 留声),随那个请求键一起退役。射程只铸在这一处,同族声明读同一只。
107
107
  *
108
108
  * 🔴 **device 车道不适用(clay 裁定③ 2026-09-22)**:device 车道上 host 闸防的那个跨租户宿主穿越**结构性不存在**
109
- * (路径落在**发起者自己的设备**上,归属由 `device_session` 绑定行 + 准入链的 owner 谓词验过),叠加 clay [ref]
109
+ * (路径落在**发起者自己的设备**上,归属由根会话行执行格上的设备绑定 + 准入链的 owner 谓词验过),叠加 clay [ref]
110
110
  * 「device 零额外审批」⇒ 在那条车道上拿租户声明当判据就是**用错轴**。与 `settings.env` / `cwd` 两键在那条车道上的既有臂同源同形。
111
111
  * [ref] 起射程判据 = 部署形表行 `taskHostPostureDeclarations`(device 车道 ∨ 单主;轴列 lane + principal);下面是它读的键集(托管证据 + 车道)。
112
112
  */
@@ -1,4 +1,4 @@
1
- import { APPROVAL_REACH, MCP_IMAGE_MAX_BASE64, isApprovalReach, isPermissionMode, isThinkingLevel, expandTiers } from "@sema-agent/core";
1
+ import { APPROVAL_REACH, IMAGE_ADMISSION, isApprovalReach, isPermissionMode, isThinkingLevel, expandTiers } from "@sema-agent/core";
2
2
  import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../model-select.js";
3
3
  import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
4
4
  import { HttpError, sessionIdShapeIssue } from "../security.js";
@@ -20,7 +20,7 @@ import { echoCallerText, quotedCallerText } from "../caller-text-echo.js";
20
20
  import { MAX_ADDITIONAL_DIRS } from "../task-cwd.js";
21
21
  import { verifyRoundsFromBody } from "./verify-rounds.js";
22
22
  import { skillCarriesRetiredManifest } from "./retired-skill-manifest.js";
23
- import { resolveDevicePlacementIntent } from "./device-placement.js";
23
+ import { resolveExecutionContext, stampSpecRoot } from "./execution-context.js";
24
24
  import { callerTrust, requestTrustRefusal } from "./caller-trust.js";
25
25
  import { createRunAcceptance } from "../run-acceptance.js";
26
26
  import { sendError, sendHttpError } from "./send.js";
@@ -88,7 +88,7 @@ function userSkillShapeIssue(item, index) {
88
88
  }
89
89
  export const SKILL_MANIFEST_RETIRED = "skill.manifest was retired in core 7.41.0 — a skill's tools are its allowedTools / disallowedTools now (an allow-rule and a deny-rule source for the run the skill is activated in, never a fence); move manifest.allowTools to allowedTools. To fence tools use deny rules (settings.permissions.deny) or a delegated agent's allowTools; to fence write paths use the session rules' allowDirs";
90
90
  const MAX_IMAGES_PER_REQUEST = 20;
91
- const MAX_IMAGE_BASE64_BYTES = MCP_IMAGE_MAX_BASE64;
91
+ const MAX_IMAGE_BASE64_BYTES = IMAGE_ADMISSION.hard.imageBase64Chars;
92
92
  function mentionableNames(config, catalog) {
93
93
  return Object.keys(catalog).filter((n) => n !== "default" && isAtMentionable(n, catalog, config.atMention, config.modelRefusals));
94
94
  }
@@ -433,10 +433,6 @@ export function createAdmission(ctx) {
433
433
  return null;
434
434
  }
435
435
  }
436
- if (body.rewindFiles !== undefined && typeof body.rewindFiles !== "boolean") {
437
- sendError(res, 400, "request.field_invalid", "rewindFiles must be a boolean");
438
- return null;
439
- }
440
436
  if (body.restoreFiles !== undefined && typeof body.restoreFiles !== "boolean") {
441
437
  sendError(res, 400, "request.field_invalid", "restoreFiles must be a boolean");
442
438
  return null;
@@ -745,23 +741,16 @@ export function createAdmission(ctx) {
745
741
  const { body: admitted, entry: entryMode } = stampEntryPermissionMode(body, autonomyModeFloor(deps.config.autonomy));
746
742
  const lease = deps.peerDesk.lease("fresh");
747
743
  try {
748
- const auth = deps.authorize ? await deps.authorize({ req, body: admitted }) : undefined;
744
+ const auth = await deps.authorize({ req, body: admitted });
745
+ const execution = await resolveExecutionContext(deps, { kind: "fresh", root: auth.sessionId, principal: auth.principal, judged: auth.head, req, deviceId: admitted.deviceId });
749
746
  const engineNotices = [];
750
- const spec = await deps.resolveSpec(admitted, req, auth, { leg: "fresh", ...(legFacts?.liveStream === true ? { liveStream: true } : {}), onNotice: (n) => engineNotices.push(n), lease });
751
- const bindingIntent = await resolveDevicePlacementIntent({
752
- config: deps.config,
753
- req,
754
- rootSessionId: spec.sessionId,
755
- deviceId: admitted.deviceId,
756
- store: deps.deviceStore,
757
- enrollment: deps.deviceEnrollment,
758
- });
747
+ const spec = stampSpecRoot(await deps.resolveSpec(admitted, req, auth, { leg: "fresh", ...(legFacts?.liveStream === true ? { liveStream: true } : {}), onNotice: (n) => engineNotices.push(n), lease, execution }), execution);
759
748
  const model = modelIdOf(spec.model);
760
- const acceptance = createRunAcceptance({ sessionTitler: deps.sessionTitler }, { ...(spec.sessionId ? { sessionId: spec.sessionId } : {}), objective: spec.objective, ...(model !== undefined ? { model } : {}) });
749
+ const acceptance = createRunAcceptance({ sessionTitler: deps.sessionTitler }, { sessionId: spec.sessionId, objective: spec.objective, ...(model !== undefined ? { model } : {}) });
761
750
  const clampNotice = buildEntryModeClampNotice(entryMode, spec.sessionId);
762
751
  const pendingNotices = clampNotice !== undefined ? [clampNotice, ...engineNotices] : engineNotices;
763
752
  const warnings = allowSelectorWarningsOf(admitted, spec.tools ?? []);
764
- return { spec, runner: runnerFor(spec), auth, verify, cascade, jobId: admitted.jobId, body: admitted, acceptance, peerLease: lease, ...(bindingIntent === undefined ? {} : { bindingIntent }), ...(pendingNotices.length > 0 ? { engineNotices: pendingNotices } : {}), ...(warnings.length > 0 ? { warnings } : {}) };
753
+ return { spec, runner: runnerFor(spec), auth, verify, cascade, jobId: admitted.jobId, body: admitted, acceptance, peerLease: lease, execution, ...(pendingNotices.length > 0 ? { engineNotices: pendingNotices } : {}), ...(warnings.length > 0 ? { warnings } : {}) };
765
754
  }
766
755
  catch (err) {
767
756
  lease.release();
@@ -32,10 +32,15 @@
32
32
  * 与 7.121.x 的 `AUTONOMY=plan` 同一个结局,且没有入口地板 ⇒ 不拒)。删除条件登记在 `plugins/one-time-migrations.ts` 的 M12 行。
33
33
  *
34
34
  * ## 第四问(7.137.0):体里的退役请求键
35
- * 请求键退役之后(今天一只:`promptProfile` 换成布尔 `promptLean`,{@link RETIRED_REQUEST_KEYS}),新提交带它在键闭集门 400;存体里的旧键由一次性迁移在起服时原地改写
36
- * (M30,`stored-request-prompt-profile-m30.ts`,行改写经本模块的 {@link rewriteStoredBodyKeys})。改写不到的残留行(窗内从没起过服的部署;起服扫描之后滚动升级里
37
- * 旧副本才写下的行)体里仍带旧键 ⇒ 拒({@link retiredRequestKeyRefusal},码同前两只读法拒:`checkpoint.unsupported_version`)。**没有**续跑时按旧键读的第二种读法,
38
- * 也**没有**「旧键无人读、静默续跑」的臂:旧键还在 = 这份体没被改写过,它当年要的形本版读不出来。
35
+ * 请求键退役之后({@link RETIRED_REQUEST_KEYS}:今天两只 —— `promptProfile` 换成布尔 `promptLean`,`rewindFiles` 是退役的旧文件还原拼法),新提交带它在键闭集门 400。存体里的旧键怎么办,闭集里每个键有
36
+ * **一个处置格**,住在哪张表就是哪个处置:**拒**表({@link REPLAY_REFUSED_RETIRED_KEYS},今天 `promptProfile`)是塑形过任务本身的键,**惰性**表({@link INERT_RETIRED_KEYS},今天 `rewindFiles`)是一次性键。
37
+ * · 拒表的键:存体里的旧键由一次性迁移在起服时原地改写
38
+ * (M30,`stored-request-prompt-profile-m30.ts`,行改写经本模块的 {@link rewriteStoredBodyKeys})。改写不到的残留行(窗内从没起过服的部署;起服扫描之后滚动升级里
39
+ * 旧副本才写下的行)体里仍带旧键 ⇒ 拒({@link retiredRequestKeyRefusal},码同前两只读法拒:`checkpoint.unsupported_version`)。**没有**续跑时按旧键读的第二种读法,
40
+ * 也**没有**「旧键无人读、静默续跑」的臂:旧键还在 = 这份体没被改写过,它当年要的形本版读不出来。
41
+ * · 惰性表的键:一次性键 —— 只在提交的那一拍起作用(文件还原的一次性动作),续跑重建里没有任何一条腿读它,存体里留着它不要求任何事、不改变重放要做的事 ⇒ 不拒、不改写、续跑照常。
42
+ * 这不是上面那条「旧键无人读、静默续跑」的臂:那一臂的前提是读不出旧键会让续跑做一件提交时没要的事,惰性格的判据恰是「没有这个键,重放做的事一字不差」。
43
+ * 加一个退役键必须选格 —— 进拒表 ⇒ {@link retiredRequestKeyRefusal} 的 switch 与 `stored-body-replay.ts` 的迁移 id 表编译红,直到给它一句拒句和改写它的迁移;进惰性表 ⇒ 改动里要写明它为什么是一次性的。
39
44
  *
40
45
  * ## 一只判据、五个问点(`http/stored-body-replay.ts` 的 `storedBodyReplayRefusal` / 本模块的 {@link storedBodyReplayAnswer})
41
46
  * 「这条停驻行的持久化体在本版上能否重放」只有**一个**读法:上面四问合在 `stored-body-replay.ts` 的 `storedBodyReplayRefusal` 一处(前两问的判据在本模块、第三问读请求设置
@@ -117,13 +122,17 @@ export declare function permissionModeReadingStated(ctx: CheckpointCtx): boolean
117
122
  */
118
123
  export declare function permissionModeReadingRefusal(): ResumeRefusalAnswer;
119
124
  /**
120
- * 第四问:**退役的请求键**闭集(新提交在键闭集门 400;存体里还带着它 = 这份体是更早的写者写下、一次性迁移没改写到的)。加一个 ⇒ 加一行,
121
- * {@link retiredRequestKeyRefusal} 的 switch 编译红直到给它一句拒句。今天一只:`promptProfile`(7.137.0 起换成布尔 `promptLean`;存体由 M30 起服改写)。
125
+ * 第四问:**退役的请求键**闭集 = 两张处置表之并(新提交在键闭集门 400;存体里还带着它 = 这份体是更早的写者写下的)。键住在哪张表就是它的处置格,规则全文见头注第四问。
126
+ * 拒表:存体仍带它 ⇒ 续跑重放拒({@link retiredRequestKeyRefusal});加一个 ⇒ 加一行,那只函数的 switch 编译红直到给它一句拒句。今天一只:`promptProfile`(7.137.0 起换成布尔 `promptLean`;存体由 M30 起服改写)。
122
127
  */
123
- export declare const RETIRED_REQUEST_KEYS: readonly ["promptProfile"];
128
+ export declare const REPLAY_REFUSED_RETIRED_KEYS: readonly ["promptProfile"];
129
+ export type ReplayRefusedRetiredKey = (typeof REPLAY_REFUSED_RETIRED_KEYS)[number];
130
+ /** 惰性表:**一次性键**(只在提交那一拍起作用,续跑重建里没有任何一条腿读它)—— 存体里带着它不改变重放要做的事 ⇒ 不拒、不改写。今天一只:`rewindFiles`(旧的文件还原拼法;现役拼法 `restoreFiles` / `rewindFilesTo` 同为一次性动作,续跑重建整族剥掉)。 */
131
+ export declare const INERT_RETIRED_KEYS: readonly ["rewindFiles"];
132
+ export declare const RETIRED_REQUEST_KEYS: readonly ["promptProfile", "rewindFiles"];
124
133
  export type RetiredRequestKey = (typeof RETIRED_REQUEST_KEYS)[number];
125
- /** 存体顶层带的第一只退役请求键(闭集序);没有 ⇒ `undefined`。只看自有键(原型上的同名不算)。 */
126
- export declare function retiredRequestKeyOf(body: unknown): RetiredRequestKey | undefined;
134
+ /** 存体顶层带的第一只**需要拒**的退役请求键(拒表序);惰性键不算,没有 ⇒ `undefined`。只看自有键(原型上的同名不算)。 */
135
+ export declare function retiredRequestKeyOf(body: unknown): ReplayRefusedRetiredKey | undefined;
127
136
  /**
128
137
  * 第四问的拒答复 —— 码与落点同另两只读法拒(`checkpoint.unsupported_version`,409;卡仍 pending 时的 `retriable:true` 由 {@link resumeRefusalWithCard} 追加,本铸点不带)。
129
138
  * 句子说键、它换成了什么、为什么不续跑,与两条出路(运维在一次性迁移的窗内重启本服务 ⇒ 起服改写存体、同一请求可再发;否则作为新任务重提,仍停驻的先取消)。不回显值。
@@ -132,7 +141,7 @@ export declare function retiredRequestKeyOf(body: unknown): RetiredRequestKey |
132
141
  * 句子写绝对日期(过了这一天读句子的人一眼看出出路已关,不靠「本版发布日」这种随版漂的说法)。
133
142
  * 删法见登记表 M30 的 `removal`(唯一来源)。
134
143
  */
135
- export declare function retiredRequestKeyRefusal(key: RetiredRequestKey, rewriteWindowEnd: string): ResumeRefusalAnswer;
144
+ export declare function retiredRequestKeyRefusal(key: ReplayRefusedRetiredKey, rewriteWindowEnd: string): ResumeRefusalAnswer;
136
145
  /**
137
146
  * 本行能否被按当前读法重放:体里 `allow` 在生效而行上的记号不是当前这一个词 ⇒ **不能**(`true` = 拒)。
138
147
  * 记号缺席、是旧词(`"statement"`)或认不得(手改 / 将来的写者)⇒ 同样拒:只有当前这个词是「按当前读法写下」的证据。
@@ -166,7 +175,7 @@ export type StoredBodyReplayRefusal = {
166
175
  readonly writerVersion?: string;
167
176
  } | {
168
177
  readonly kind: "retired_request_key";
169
- readonly key: RetiredRequestKey;
178
+ readonly key: ReplayRefusedRetiredKey;
170
179
  /** 改写这只退役键的一次性迁移窗的最后一天(UTC 日历日 YYYY-MM-DD)—— 登记表那一行的 `removableAfter`,由判据(`stored-body-replay.ts`)读来:本模块的闭包只许 node 内建 / 引擎包根,读不了登记表,日期只能由调用方交。 */
171
180
  readonly rewriteWindowEnd: string;
172
181
  readonly writerVersion?: string;
@@ -230,7 +239,7 @@ export declare function storedBodyReplayLogFields(refusal: StoredBodyReplayRefus
230
239
  layer?: InertToolListEntry["layer"];
231
240
  storedMode?: PermissionMode | null;
232
241
  floor?: PermissionMode;
233
- key?: RetiredRequestKey;
242
+ key?: ReplayRefusedRetiredKey;
234
243
  note: string;
235
244
  };
236
245
  /**
@@ -39,11 +39,13 @@ export function permissionModeReadingRefusal() {
39
39
  }),
40
40
  };
41
41
  }
42
- export const RETIRED_REQUEST_KEYS = ["promptProfile"];
42
+ export const REPLAY_REFUSED_RETIRED_KEYS = ["promptProfile"];
43
+ export const INERT_RETIRED_KEYS = ["rewindFiles"];
44
+ export const RETIRED_REQUEST_KEYS = [...REPLAY_REFUSED_RETIRED_KEYS, ...INERT_RETIRED_KEYS];
43
45
  export function retiredRequestKeyOf(body) {
44
46
  if (body === null || typeof body !== "object" || Array.isArray(body))
45
47
  return undefined;
46
- return RETIRED_REQUEST_KEYS.find((key) => Object.hasOwn(body, key));
48
+ return REPLAY_REFUSED_RETIRED_KEYS.find((key) => Object.hasOwn(body, key));
47
49
  }
48
50
  export function retiredRequestKeyRefusal(key, rewriteWindowEnd) {
49
51
  switch (key) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 一条提交腿**刚认领**的 run 在起跑之前就收场 —— 撤掉本请求建的东西的**唯一**写法。三个调用点:device 落点拒
3
- * (`device-placement.ts` `commitPlacement`)、续跑输入写不进(`submit-ctx.ts` `persistSubmitCtx`)与 workflow 决定行没落成
3
+ * (`execution-context.ts` `commitExecutionContext`)、续跑输入写不进(`submit-ctx.ts` `persistSubmitCtx`)与 workflow 决定行没落成
4
4
  * (`durable-run-leg.ts` 的 fresh 投递腿;此刻认领可能已被收割归了别人 —— 两步都按这一跑自己的 taskId,碰不到别人的认领)。
5
5
  *
6
6
  * 撤两步,**各自独立**(一步失败不拦另一步,残余最小):
@@ -6,7 +6,8 @@ import { fleetRunPublisher, fleetRunLabels } from "../fleet/fleet-bus.js";
6
6
  import { cascadeConfig, runMeta } from "./run-meta.js";
7
7
  import { declaredApprovalFrameFamilies, resolveStreamApprovalGate } from "../tool-approval.js";
8
8
  import { buildActiveRunConflict } from "./active-run-conflict.js";
9
- import { commitPlacement, devicePlacementErrorBody } from "./device-placement.js";
9
+ import { commitExecutionContext } from "./execution-context.js";
10
+ import { rootSessionAbsentAnswer } from "./execution-context.js";
10
11
  import { commitSessionInheritEnv } from "./session-inherit-env.js";
11
12
  import { clearTurnActivity, readTurnActivityMs } from "../turn-activity.js";
12
13
  import { recordResourceWindow } from "../resource-window.js";
@@ -18,7 +19,7 @@ import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceSt
18
19
  export async function mintAndDriveDurableRun(ctx, runStore, args) {
19
20
  const { deps } = ctx;
20
21
  const { inflightRuns, preemptableRuns, steerableRuns } = ctx.registry;
21
- const sessionId = args.prepared.spec.sessionId ?? uuidv7();
22
+ const sessionId = args.prepared.spec.sessionId;
22
23
  const taskId = args.clientTaskId ?? uuidv7();
23
24
  const trustedInternals = await heldWorkflowParkDecisions(deps, sessionId, args.workflowDecision?.carried);
24
25
  const created = await runStore.createRun(taskId, sessionId, args.prepared.auth?.principal ?? null, deps.instanceId ?? "default", { ...runMeta(args.prepared, args.source), identity: args.identity, idem: args.idem ?? null });
@@ -28,6 +29,8 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
28
29
  recordResourceWindow(taskId, args.prepared.spec.resourceSuspend);
29
30
  if (created.existing)
30
31
  return { existing: created.existing };
32
+ if (created.sessionAbsent)
33
+ return rootSessionAbsentAnswer();
31
34
  if (!created.ok) {
32
35
  return { status: 409, body: await buildActiveRunConflict({ runStore, checkpointStore: deps.checkpointStore, governance: deps.config, runStaleSec: deps.config.runStaleSec, turnActivity: readTurnActivityMs }, sessionId, created.activeTaskId) };
33
36
  }
@@ -37,9 +40,9 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
37
40
  }, HEARTBEAT_MS);
38
41
  preLaunchHeartbeat.unref?.();
39
42
  try {
40
- const placementReject = await commitPlacement(deps, runStore, taskId, args.prepared.bindingIntent);
43
+ const placementReject = await commitExecutionContext(deps, { kind: "run", runStore, taskId }, args.prepared.execution);
41
44
  if (placementReject)
42
- return { status: placementReject.status, body: devicePlacementErrorBody(placementReject) };
45
+ return placementReject;
43
46
  if (deps.checkpointStore) {
44
47
  const ctxRefusal = await persistSubmitCtx(deps.checkpointStore, deps, { runStore, taskId }, sessionId, { body: args.prepared.body, memoryScope: args.prepared.auth?.memoryScope, writerVersion: serviceVersion() });
45
48
  if (ctxRefusal)
@@ -80,7 +83,7 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
80
83
  sessionId,
81
84
  ...fleetRunLabels(args.prepared.spec.objective),
82
85
  });
83
- void heldFor(args.prepared.peerLease, () => runInBackground(args.prepared.runner, { ...args.prepared.spec, sessionId }, runStore, taskId, deps.metrics, args.prepared.auth?.principal, args.prepared.verify, args.prepared.cascade ? cascadeConfig(deps.config.cascadeLadder, args.prepared.spec.limits?.maxCostUsd) : undefined, deps.instrumentDegenerate, deps.planCacheProbe, deps.config.traceThinking, inflightRuns, preemptableRuns, steerableRuns, deps.modelUsage, deps.elicitation, args.elicitOwner, captureTurnAnchor, fleetPub, captureUserMessageAnchor, deps.question, deps.workflowCompletionInbox, deps.subagentSteerRegistry, (m, x) => deps.logger?.info?.(m, x), deps.sendUserFile, deps.promptManifests, deps.toolApproval
86
+ void heldFor(args.prepared.peerLease, () => runInBackground(args.prepared.runner, args.prepared.spec, runStore, taskId, deps.metrics, args.prepared.auth?.principal, args.prepared.verify, args.prepared.cascade ? cascadeConfig(deps.config.cascadeLadder, args.prepared.spec.limits?.maxCostUsd) : undefined, deps.instrumentDegenerate, deps.planCacheProbe, deps.config.traceThinking, inflightRuns, preemptableRuns, steerableRuns, deps.modelUsage, deps.elicitation, args.elicitOwner, captureTurnAnchor, fleetPub, captureUserMessageAnchor, deps.question, deps.workflowCompletionInbox, deps.subagentSteerRegistry, (m, x) => deps.logger?.info?.(m, x), deps.sendUserFile, deps.promptManifests, deps.toolApproval
84
87
  ? {
85
88
  coordinator: deps.toolApproval,
86
89
  streamApprovalOn: resolveStreamApprovalGate({
@@ -92,6 +95,7 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
92
95
  windowMs: deps.config.streamApproval?.windowMs,
93
96
  windowMarginMs: deps.config.streamAskWindowMarginMs,
94
97
  declaredFamilies: declaredApprovalFrameFamilies(args.prepared.body.settings),
98
+ executionLane: args.prepared.execution.lane,
95
99
  }
96
100
  : undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), legSessionWitnessOf(args.prepared.spec))));
97
101
  return { status: 202, body: { taskId, sessionId, status: "running", ...(args.prepared.warnings !== undefined ? { warnings: args.prepared.warnings } : {}) } };