@sema-agent/server 7.137.0 → 7.139.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 (328) hide show
  1. package/MIGRATION.md +600 -142
  2. package/README.md +7 -3
  3. package/README.zh-CN.md +6 -3
  4. package/USAGE.md +132 -41
  5. package/deploy/sema-up/README.md +1 -1
  6. package/deploy/sema-up/lib/lanes.json +3 -2
  7. package/dist/adoption/wire.d.ts +3 -3
  8. package/dist/approval-card.d.ts +23 -16
  9. package/dist/approval-card.js +1 -0
  10. package/dist/audit.js +1 -0
  11. package/dist/background-agent-name.d.ts +5 -0
  12. package/dist/background-agent-name.js +5 -0
  13. package/dist/bench/s1/arms.d.ts +1 -1
  14. package/dist/bench/s1/arms.js +1 -3
  15. package/dist/bench/s1/run-firm.js +2 -2
  16. package/dist/boot/budget-tracing.d.ts +1 -12
  17. package/dist/boot/deployment-mods.d.ts +46 -16
  18. package/dist/boot/deployment-mods.js +82 -6
  19. package/dist/boot/device-lane.d.ts +8 -3
  20. package/dist/boot/device-lane.js +7 -2
  21. package/dist/boot/execution-env.d.ts +4 -2
  22. package/dist/boot/execution-env.js +16 -24
  23. package/dist/boot/execution-lane.d.ts +1 -1
  24. package/dist/boot/governance-seams.d.ts +12 -18
  25. package/dist/boot/governance-seams.js +10 -24
  26. package/dist/boot/leader.d.ts +3 -0
  27. package/dist/boot/leader.js +1 -0
  28. package/dist/boot/memory-consolidation.js +2 -2
  29. package/dist/boot/org-delivery.js +15 -2
  30. package/dist/boot/resolve-spec.d.ts +4 -1
  31. package/dist/boot/resolve-spec.js +29 -19
  32. package/dist/boot/retention-lane.d.ts +14 -8
  33. package/dist/boot/retention-lane.js +2 -8
  34. package/dist/boot/runner-deps.d.ts +10 -4
  35. package/dist/boot/runner-deps.js +2 -0
  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-04-stores.d.ts +1 -12
  40. package/dist/boot/stage-05-execution-env.d.ts +3 -12
  41. package/dist/boot/stage-05-execution-env.js +8 -5
  42. package/dist/boot/stage-06-runners.d.ts +3 -12
  43. package/dist/boot/stage-06-runners.js +5 -3
  44. package/dist/boot/stage-07-capability-layer.d.ts +3 -12
  45. package/dist/boot/stage-07-capability-layer.js +2 -2
  46. package/dist/boot/stage-08-reapers.d.ts +3 -12
  47. package/dist/boot/stage-09-leader.d.ts +3 -12
  48. package/dist/boot/stage-09-leader.js +2 -3
  49. package/dist/boot/stage-10-http-server.d.ts +3 -12
  50. package/dist/boot/stage-10-http-server.js +5 -3
  51. package/dist/boot/stores.js +4 -4
  52. package/dist/boot/web-admin.d.ts +5 -2
  53. package/dist/boot/web-admin.js +5 -5
  54. package/dist/brain.js +5 -5
  55. package/dist/budget.d.ts +17 -15
  56. package/dist/budget.js +2 -2
  57. package/dist/capabilities/mcp-probe.d.ts +36 -11
  58. package/dist/capabilities/mcp-probe.js +44 -5
  59. package/dist/capabilities/scenarios.d.ts +1 -1
  60. package/dist/capability-facts.d.ts +21 -7
  61. package/dist/capability-facts.js +13 -3
  62. package/dist/checkpoint-identity.d.ts +13 -6
  63. package/dist/config-catalog.js +14 -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 +19 -24
  67. package/dist/config-provider.js +27 -12
  68. package/dist/config-types.d.ts +25 -12
  69. package/dist/config.d.ts +33 -0
  70. package/dist/config.js +52 -20
  71. package/dist/delegated-session-owner.d.ts +2 -2
  72. package/dist/deployment-shape.d.ts +7 -7
  73. package/dist/device-enrollment.d.ts +41 -2
  74. package/dist/device-enrollment.js +27 -12
  75. package/dist/device-store.d.ts +58 -85
  76. package/dist/device-store.js +19 -49
  77. package/dist/device-ws-hub.js +2 -1
  78. package/dist/env-name-allowlist-knobs.d.ts +5 -4
  79. package/dist/exec-cut.d.ts +60 -0
  80. package/dist/exec-cut.js +36 -0
  81. package/dist/execution-lane-caps.d.ts +19 -0
  82. package/dist/execution-lane-caps.js +10 -0
  83. package/dist/execution-placement.d.ts +259 -0
  84. package/dist/execution-placement.js +199 -0
  85. package/dist/field-conflict.d.ts +3 -2
  86. package/dist/field-conflict.js +1 -0
  87. package/dist/gate-settlement.d.ts +71 -0
  88. package/dist/gate-settlement.js +40 -0
  89. package/dist/hooks/classic-stations.d.ts +1 -0
  90. package/dist/hooks/classic-stations.js +1 -0
  91. package/dist/hooks/command-spawn.d.ts +2 -2
  92. package/dist/hooks/hook-runner.js +14 -14
  93. package/dist/hosted-posture.d.ts +2 -2
  94. package/dist/http/admission.js +10 -19
  95. package/dist/http/checkpoint-ctx.d.ts +21 -12
  96. package/dist/http/checkpoint-ctx.js +4 -2
  97. package/dist/http/claimed-run.d.ts +1 -1
  98. package/dist/http/dispatch.d.ts +4 -0
  99. package/dist/http/dispatch.js +3 -0
  100. package/dist/http/durable-run-leg.js +12 -6
  101. package/dist/http/execution-context.d.ts +218 -0
  102. package/dist/http/execution-context.js +330 -0
  103. package/dist/http/memory-compliance-failure-reply.js +3 -0
  104. package/dist/http/resume-legs.d.ts +5 -11
  105. package/dist/http/resume-legs.js +179 -104
  106. package/dist/http/route-ctx.d.ts +44 -59
  107. package/dist/http/route-ctx.js +2 -5
  108. package/dist/http/routes/a2a-serve.js +10 -4
  109. package/dist/http/routes/agents-roster.d.ts +1 -1
  110. package/dist/http/routes/agents-roster.js +5 -1
  111. package/dist/http/routes/approvals-assistant.js +6 -6
  112. package/dist/http/routes/background.d.ts +29 -1
  113. package/dist/http/routes/background.js +29 -2
  114. package/dist/http/routes/capabilities.js +12 -10
  115. package/dist/http/routes/devices.d.ts +13 -19
  116. package/dist/http/routes/devices.js +21 -26
  117. package/dist/http/routes/mcp-reconnect.d.ts +3 -2
  118. package/dist/http/routes/mcp-reconnect.js +7 -5
  119. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  120. package/dist/http/routes/memory-origin.d.ts +1 -1
  121. package/dist/http/routes/rules.js +3 -3
  122. package/dist/http/routes/runs.js +11 -7
  123. package/dist/http/routes/session-sync.js +110 -15
  124. package/dist/http/routes/sessions.d.ts +6 -0
  125. package/dist/http/routes/sessions.js +119 -13
  126. package/dist/http/routes/side-query.d.ts +12 -4
  127. package/dist/http/routes/side-query.js +6 -8
  128. package/dist/http/routes/tasks.js +800 -782
  129. package/dist/http/server.d.ts +61 -39
  130. package/dist/http/server.js +11 -0
  131. package/dist/http/session-inherit-env.d.ts +3 -4
  132. package/dist/http/session-inherit-env.js +1 -1
  133. package/dist/http/wire-types.d.ts +22 -18
  134. package/dist/identity-source.d.ts +1 -1
  135. package/dist/index.d.ts +3 -0
  136. package/dist/index.js +1 -0
  137. package/dist/leader/wire.d.ts +7 -0
  138. package/dist/leader/wire.js +5 -4
  139. package/dist/mcp-assertion-header.d.ts +51 -40
  140. package/dist/mcp-assertion-header.js +10 -11
  141. package/dist/mcp-authorization-face.d.ts +27 -0
  142. package/dist/mcp-authorization-face.js +15 -0
  143. package/dist/memory-operator-faces.d.ts +13 -4
  144. package/dist/memory-operator-faces.js +1 -17
  145. package/dist/memory-sync-client.d.ts +53 -14
  146. package/dist/memory-sync-client.js +187 -92
  147. package/dist/memory-sync.d.ts +1 -1
  148. package/dist/memory-sync.js +3 -2
  149. package/dist/model-route-gap.d.ts +6 -22
  150. package/dist/model-route-gap.js +7 -5
  151. package/dist/mods-declaration.d.ts +110 -0
  152. package/dist/mods-declaration.js +109 -0
  153. package/dist/observability/cost-taxonomy.d.ts +2 -2
  154. package/dist/observability/err-text.d.ts +5 -0
  155. package/dist/observability/err-text.js +9 -0
  156. package/dist/observability/fail-open.d.ts +17 -1
  157. package/dist/observability/fail-open.js +17 -1
  158. package/dist/observability/run-terminal.js +0 -1
  159. package/dist/observability/secret-env-scrub.d.ts +1 -1
  160. package/dist/observability/secret-env-scrub.js +1 -1
  161. package/dist/orchestration/workflow-notify-journal.js +4 -4
  162. package/dist/org-memory-admission.d.ts +4 -3
  163. package/dist/org-memory-admission.js +6 -6
  164. package/dist/parked-decide.d.ts +49 -11
  165. package/dist/parked-decide.js +25 -26
  166. package/dist/parked-revive-surface.d.ts +12 -15
  167. package/dist/parked-revive-surface.js +3 -6
  168. package/dist/peer-seat.d.ts +156 -0
  169. package/dist/peer-seat.js +273 -0
  170. package/dist/permission-rule-vocab.d.ts +7 -7
  171. package/dist/permission-rule-vocab.js +3 -3
  172. package/dist/plain-string-record.d.ts +38 -0
  173. package/dist/plain-string-record.js +38 -0
  174. package/dist/plugins/approval-ask-store-file.d.ts +7 -0
  175. package/dist/plugins/approval-ask-store-file.js +11 -0
  176. package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
  177. package/dist/plugins/approval-ask-store-memory.js +12 -0
  178. package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
  179. package/dist/plugins/approval-ask-store-sql.js +30 -12
  180. package/dist/plugins/background-agent-store-sql.js +6 -3
  181. package/dist/plugins/caching-session-store.d.ts +11 -2
  182. package/dist/plugins/caching-session-store.js +15 -3
  183. package/dist/plugins/checkpoint-store-sql.d.ts +21 -25
  184. package/dist/plugins/checkpoint-store-sql.js +13 -15
  185. package/dist/plugins/device-store-sql.d.ts +25 -51
  186. package/dist/plugins/device-store-sql.js +49 -103
  187. package/dist/plugins/execution-placement-sql.d.ts +151 -0
  188. package/dist/plugins/execution-placement-sql.js +223 -0
  189. package/dist/plugins/file-history-store-sql.d.ts +7 -6
  190. package/dist/plugins/file-history-store-sql.js +8 -7
  191. package/dist/plugins/file-run-store.d.ts +6 -1
  192. package/dist/plugins/file-run-store.js +4 -0
  193. package/dist/plugins/fork-routing-session-store.d.ts +6 -0
  194. package/dist/plugins/fork-routing-session-store.js +16 -0
  195. package/dist/plugins/k8s-pod-reaper.d.ts +2 -8
  196. package/dist/plugins/k8s-pod-reaper.js +3 -3
  197. package/dist/plugins/local-checkpoint-store.d.ts +1 -11
  198. package/dist/plugins/local-checkpoint-store.js +0 -1
  199. package/dist/plugins/local-session-store.d.ts +183 -45
  200. package/dist/plugins/local-session-store.js +412 -105
  201. package/dist/plugins/mailbox-store-sql.d.ts +11 -3
  202. package/dist/plugins/mailbox-store-sql.js +103 -15
  203. package/dist/plugins/memory-key-guards.d.ts +4 -0
  204. package/dist/plugins/memory-key-guards.js +1 -0
  205. package/dist/plugins/memory-run-store.d.ts +1 -1
  206. package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
  207. package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
  208. package/dist/plugins/one-time-migrations.d.ts +117 -6
  209. package/dist/plugins/one-time-migrations.js +383 -14
  210. package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
  211. package/dist/plugins/permission-rule-store-sql.d.ts +13 -15
  212. package/dist/plugins/permission-rule-store-sql.js +34 -29
  213. package/dist/plugins/pg-pool.d.ts +7 -3
  214. package/dist/plugins/pg-session-storage.d.ts +41 -22
  215. package/dist/plugins/pg-session-storage.js +136 -55
  216. package/dist/plugins/remote-env-adb.d.ts +22 -4
  217. package/dist/plugins/remote-env-adb.js +70 -62
  218. package/dist/plugins/remote-env-device.d.ts +32 -12
  219. package/dist/plugins/remote-env-device.js +18 -17
  220. package/dist/plugins/remote-env-e2b.d.ts +19 -3
  221. package/dist/plugins/remote-env-e2b.js +41 -42
  222. package/dist/plugins/remote-env-file-error.d.ts +2 -0
  223. package/dist/plugins/remote-env-file-error.js +1 -1
  224. package/dist/plugins/remote-env-host.d.ts +23 -8
  225. package/dist/plugins/remote-env-host.js +66 -70
  226. package/dist/plugins/remote-env-k8s.d.ts +13 -16
  227. package/dist/plugins/remote-env-k8s.js +61 -54
  228. package/dist/plugins/remote-env-local-docker.d.ts +30 -5
  229. package/dist/plugins/remote-env-local-docker.js +46 -59
  230. package/dist/plugins/remote-env-ssh.d.ts +18 -4
  231. package/dist/plugins/remote-env-ssh.js +72 -56
  232. package/dist/plugins/remote-shell.d.ts +100 -3
  233. package/dist/plugins/remote-shell.js +166 -2
  234. package/dist/plugins/retention-store-sql.d.ts +23 -8
  235. package/dist/plugins/retention-store-sql.js +13 -1
  236. package/dist/plugins/run-store-sql.d.ts +13 -3
  237. package/dist/plugins/run-store-sql.js +5 -0
  238. package/dist/plugins/schema-consistency.d.ts +15 -5
  239. package/dist/plugins/schema-consistency.js +14 -8
  240. package/dist/plugins/schema-drift-sentence.d.ts +27 -0
  241. package/dist/plugins/schema-drift-sentence.js +38 -0
  242. package/dist/plugins/session-fork.d.ts +63 -12
  243. package/dist/plugins/session-fork.js +38 -21
  244. package/dist/plugins/session-ownership.d.ts +7 -0
  245. package/dist/plugins/session-ownership.js +5 -0
  246. package/dist/plugins/session-row-sql.d.ts +22 -0
  247. package/dist/plugins/session-row-sql.js +81 -0
  248. package/dist/plugins/session-store.d.ts +1 -1
  249. package/dist/plugins/session-workspace-cell.d.ts +17 -0
  250. package/dist/plugins/session-workspace-cell.js +38 -0
  251. package/dist/plugins/store-backend.d.ts +1 -1
  252. package/dist/plugins/store-backend.js +26 -14
  253. package/dist/plugins/store-contracts.d.ts +25 -5
  254. package/dist/plugins/tidb-pool.d.ts +12 -7
  255. package/dist/plugins/tidb-pool.js +15 -3
  256. package/dist/plugins/tidb-session-store.d.ts +74 -28
  257. package/dist/plugins/tidb-session-store.js +132 -53
  258. package/dist/plugins/tool-result-store-sql.d.ts +16 -8
  259. package/dist/plugins/tool-result-store-sql.js +26 -17
  260. package/dist/plugins/worktree-isolation.d.ts +3 -2
  261. package/dist/plugins/worktree-isolation.js +1 -7
  262. package/dist/project-identity.d.ts +1 -14
  263. package/dist/project-identity.js +0 -4
  264. package/dist/project-memory.d.ts +9 -15
  265. package/dist/project-memory.js +5 -4
  266. package/dist/request-key-closure.js +1 -1
  267. package/dist/request-value-closure.d.ts +6 -7
  268. package/dist/request-value-closure.js +1 -3
  269. package/dist/rules-consent.js +6 -4
  270. package/dist/run-local.d.ts +6 -0
  271. package/dist/run-local.js +36 -26
  272. package/dist/runs.d.ts +9 -2
  273. package/dist/runs.js +9 -2
  274. package/dist/sandbox-git-plane.d.ts +2 -2
  275. package/dist/security.d.ts +38 -12
  276. package/dist/security.js +8 -2
  277. package/dist/server-secret-env.d.ts +15 -8
  278. package/dist/server-secret-env.js +4 -2
  279. package/dist/session-children-retire.d.ts +27 -9
  280. package/dist/session-children-retire.js +9 -5
  281. package/dist/session-incarnation.d.ts +19 -10
  282. package/dist/session-incarnation.js +5 -3
  283. package/dist/session-row.d.ts +114 -5
  284. package/dist/session-row.js +55 -5
  285. package/dist/session-titler.d.ts +2 -2
  286. package/dist/session-workspace.d.ts +130 -0
  287. package/dist/session-workspace.js +83 -0
  288. package/dist/spec-fields.d.ts +1 -1
  289. package/dist/standing-answer-grant.d.ts +2 -13
  290. package/dist/standing-answer-grant.js +0 -7
  291. package/dist/task-a2a.d.ts +44 -14
  292. package/dist/task-a2a.js +46 -20
  293. package/dist/task-cwd.d.ts +6 -1
  294. package/dist/task-mcp.d.ts +33 -20
  295. package/dist/task-mcp.js +46 -22
  296. package/dist/tool-approval.d.ts +38 -8
  297. package/dist/tool-approval.js +57 -13
  298. package/dist/trace/core-keyset-guard.d.ts +33 -18
  299. package/dist/trace/engine-notice-wire.d.ts +1 -1
  300. package/dist/trace/engine-notice-wire.js +2 -0
  301. package/dist/trace/exit-seat.d.ts +20 -1
  302. package/dist/trace/exit-seat.js +3 -0
  303. package/dist/trace/extension-call-face.d.ts +33 -0
  304. package/dist/trace/extension-call-face.js +39 -0
  305. package/dist/trace/project.d.ts +26 -7
  306. package/dist/trace/project.js +30 -3
  307. package/dist/trace/redact.js +42 -13
  308. package/dist/trace/self-minted-wire.d.ts +240 -12
  309. package/dist/trace/self-minted-wire.js +100 -4
  310. package/dist/trace/wire-projection-faces.d.ts +6 -6
  311. package/dist/trace/wire-projection-faces.js +6 -5
  312. package/dist/url-refusal.d.ts +1 -1
  313. package/dist/user-authored-text.d.ts +2 -2
  314. package/dist/user-authored-text.js +16 -1
  315. package/dist/web-admin-client/apply-effective.d.ts +17 -3
  316. package/dist/web-admin-client/apply-effective.js +20 -10
  317. package/dist/web-admin-client/center-request.d.ts +3 -2
  318. package/dist/web-admin-client/center-request.js +2 -3
  319. package/dist/web-admin-client/skills-mcp.d.ts +8 -4
  320. package/dist/web-admin-client/skills-mcp.js +32 -18
  321. package/dist/web-admin-client/types.d.ts +11 -0
  322. package/package.json +3 -3
  323. package/wire-changes/server@7.138.0.json +446 -0
  324. package/wire-changes/server@7.139.0.json +348 -0
  325. package/dist/http/device-placement.d.ts +0 -175
  326. package/dist/http/device-placement.js +0 -145
  327. package/dist/http/mcp-remote-text.d.ts +0 -5
  328. package/dist/http/mcp-remote-text.js +0 -7
@@ -0,0 +1,348 @@
1
+ {
2
+ "repo": "server",
3
+ "version": "7.139.0",
4
+ "from": "v7.138.0",
5
+ "fromCommit": "8b41148fef6d0d0c316c0e963efec70714a24e98",
6
+ "to": "v7.139.0",
7
+ "generator": "scripts/wire-changes-server.mjs",
8
+ "sources": [
9
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1",
10
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1b",
11
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.1",
12
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.1a",
13
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.2b",
14
+ "docs/ASSISTANT-WIRE-CONTRACT.md#B.2",
15
+ "docs/ASSISTANT-WIRE-CONTRACT.md#D.3",
16
+ "src/trace/wire-projection-faces.ts",
17
+ "src/trace/self-minted-wire.ts",
18
+ "node_modules/@sema-agent/core/wire-changes"
19
+ ],
20
+ "added": [
21
+ {
22
+ "id": "A1",
23
+ "source": "errorCode",
24
+ "member": "conflict.fork_id_taken",
25
+ "text": "附录 A.1 / A.1b 错误码新增 `conflict.fork_id_taken`(状态码 409)"
26
+ },
27
+ {
28
+ "id": "A2",
29
+ "source": "errorCode",
30
+ "member": "conflict.fork_in_progress",
31
+ "text": "附录 A.1 / A.1b 错误码新增 `conflict.fork_in_progress`(状态码 409)"
32
+ },
33
+ {
34
+ "id": "A3",
35
+ "source": "errorCode",
36
+ "member": "conflict.session_mirror",
37
+ "text": "附录 A.1 / A.1b 错误码新增 `conflict.session_mirror`(状态码 409)"
38
+ },
39
+ {
40
+ "id": "A4",
41
+ "source": "errorCode",
42
+ "member": "conflict.session_row_changed",
43
+ "text": "附录 A.1 / A.1b 错误码新增 `conflict.session_row_changed`(状态码 409)"
44
+ },
45
+ {
46
+ "id": "A5",
47
+ "source": "errorCode",
48
+ "member": "conflict.session_writer",
49
+ "text": "附录 A.1 / A.1b 错误码新增 `conflict.session_writer`(状态码 409)"
50
+ },
51
+ {
52
+ "id": "A6",
53
+ "source": "errorCode",
54
+ "member": "execution_lane.not_served",
55
+ "text": "附录 A.1 / A.1b 错误码新增 `execution_lane.not_served`(状态码 409)"
56
+ },
57
+ {
58
+ "id": "A7",
59
+ "source": "errorCode",
60
+ "member": "execution_lane.tree_bound",
61
+ "text": "附录 A.1 / A.1b 错误码新增 `execution_lane.tree_bound`(状态码 409)"
62
+ },
63
+ {
64
+ "id": "A8",
65
+ "source": "errorCode",
66
+ "member": "state.fork_target_unsettled",
67
+ "text": "附录 A.1 / A.1b 错误码新增 `state.fork_target_unsettled`(状态码 503)"
68
+ },
69
+ {
70
+ "id": "A9",
71
+ "source": "selfMinted.endpointFaceStatus",
72
+ "member": "PATCH /v1/sessions/:id#expectedRowTag_current(行仍在那只标签上;体 = 列表行)",
73
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `PATCH /v1/sessions/:id#expectedRowTag_current(行仍在那只标签上;体 = 列表行)`(属性 200;since 7.139.0 = 本版新上 wire)"
74
+ },
75
+ {
76
+ "id": "A10",
77
+ "source": "selfMinted.endpointFaceStatus",
78
+ "member": "PATCH /v1/sessions/:id#expectedRowTag_stale(行已不在那只标签上;体 conflict.session_row_changed + currentRow)",
79
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `PATCH /v1/sessions/:id#expectedRowTag_stale(行已不在那只标签上;体 conflict.session_row_changed + currentRow)`(属性 409;since 7.139.0 = 本版新上 wire)"
80
+ },
81
+ {
82
+ "id": "A11",
83
+ "source": "selfMinted.endpointFaceStatus",
84
+ "member": "PATCH /v1/sessions/:id#mirror_row(只读镜像行上的写,带不带 expectedRowTag;体 conflict.session_mirror + forkPath)",
85
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `PATCH /v1/sessions/:id#mirror_row(只读镜像行上的写,带不带 expectedRowTag;体 conflict.session_mirror + forkPath)`(属性 409;since 7.139.0 = 本版新上 wire)"
86
+ },
87
+ {
88
+ "id": "A12",
89
+ "source": "selfMinted.endpointFaceStatus",
90
+ "member": "PATCH /v1/sessions/:id#owner_changed_after_gate(门那一读之后同一会话的属主被改;体 not_found.session)",
91
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `PATCH /v1/sessions/:id#owner_changed_after_gate(门那一读之后同一会话的属主被改;体 not_found.session)`(属性 404;since 7.139.0 = 本版新上 wire)"
92
+ },
93
+ {
94
+ "id": "A13",
95
+ "source": "selfMinted.endpointFaceStatus",
96
+ "member": "POST /v1/side-query#uncoded_error_with_preflight_prefix(没有引擎码、英文开头与前缀表同形的错误;体 internal.error)",
97
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `POST /v1/side-query#uncoded_error_with_preflight_prefix(没有引擎码、英文开头与前缀表同形的错误;体 internal.error)`(属性 500;since 7.139.0 = 本版新上 wire)"
98
+ },
99
+ {
100
+ "id": "A14",
101
+ "source": "selfMinted.endpointFaceStatus",
102
+ "member": "POST /v1/tasks|/v1/tasks/stream|/v1/runs#rewindFiles(新提交;体 request.body_shape + unknownKeys [rewindFiles])",
103
+ "text": "自铸 逐端点应答面 → 状态(<端点>#<面> → 状态;只登记本版改了状态的面) 新增 `POST /v1/tasks|/v1/tasks/stream|/v1/runs#rewindFiles(新提交;体 request.body_shape + unknownKeys [rewindFiles])`(属性 400;since 7.139.0 = 本版新上 wire)"
104
+ },
105
+ {
106
+ "id": "A15",
107
+ "source": "selfMinted.fieldConflictKind",
108
+ "member": "fork_target",
109
+ "text": "自铸 400 request.field_conflict detail.kind 新增 `fork_target`(属性 -;since 7.139.0 = 本版新上 wire)"
110
+ },
111
+ {
112
+ "id": "A16",
113
+ "source": "selfMinted.refusalSentenceForm",
114
+ "member": "400 request.body_shape#PATCH /v1/sessions/:id",
115
+ "text": "自铸 拒体 message 的句型(<码>#<座> → 句型骨架;码 / 状态 / 机读位不变) 新增 `400 request.body_shape#PATCH /v1/sessions/:id`(属性 the body must be a JSON object carrying at least one of `title` and `pinned` (and, optionally, `expectedRowTag`), and nothing else;since 7.139.0 = 本版新上 wire)"
116
+ },
117
+ {
118
+ "id": "A17",
119
+ "source": "selfMinted.refusalSentenceForm",
120
+ "member": "400 request.field_invalid#PATCH /v1/sessions/:id.expectedRowTag",
121
+ "text": "自铸 拒体 message 的句型(<码>#<座> → 句型骨架;码 / 状态 / 机读位不变) 新增 `400 request.field_invalid#PATCH /v1/sessions/:id.expectedRowTag`(属性 expectedRowTag must be the `rowTag` string a session list row carries (43 characters: letters, digits, `-` and `_`);since 7.139.0 = 本版新上 wire)"
122
+ },
123
+ {
124
+ "id": "A18",
125
+ "source": "selfMinted.refusalSentenceForm",
126
+ "member": "409 conflict.session_mirror#PATCH /v1/sessions/:id",
127
+ "text": "自铸 拒体 message 的句型(<码>#<座> → 句型骨架;码 / 状态 / 机读位不变) 新增 `409 conflict.session_mirror#PATCH /v1/sessions/:id`(属性 this session is a read-only mirror of a session whose writer is elsewhere — it cannot be renamed or pinned here; fork it (forkPath) to continue here; nothing was written;since 7.139.0 = 本版新上 wire)"
128
+ },
129
+ {
130
+ "id": "A19",
131
+ "source": "selfMinted.refusalSentenceForm",
132
+ "member": "409 conflict.session_row_changed#PATCH /v1/sessions/:id",
133
+ "text": "自铸 拒体 message 的句型(<码>#<座> → 句型骨架;码 / 状态 / 机读位不变) 新增 `409 conflict.session_row_changed#PATCH /v1/sessions/:id`(属性 the session row changed since the rowTag you sent was read — nothing was written; currentRow is the row as it stands now: decide again, then send its rowTag;since 7.139.0 = 本版新上 wire)"
134
+ },
135
+ {
136
+ "id": "A20",
137
+ "source": "selfMinted.sessionBackgroundRowKey",
138
+ "member": "sessionId",
139
+ "text": "自铸 GET /v1/sessions/:id/background rows[] 行键(<键> → 在场律) 新增 `sessionId`(属性 present-iff background agent row bound to a child session;since 7.139.0 = 本版新上 wire)"
140
+ },
141
+ {
142
+ "id": "A21",
143
+ "source": "selfMinted.sessionRowWriteKey",
144
+ "member": "409 conflict.session_mirror#forkPath",
145
+ "text": "自铸 PATCH /v1/sessions/:id 体受理键与 409 拒体键(<面>#<键> → 读法 / 在场律;只登本版新增的) 新增 `409 conflict.session_mirror#forkPath`(属性 always;since 7.139.0 = 本版新上 wire)"
146
+ },
147
+ {
148
+ "id": "A22",
149
+ "source": "selfMinted.sessionRowWriteKey",
150
+ "member": "409 conflict.session_row_changed#currentRow",
151
+ "text": "自铸 PATCH /v1/sessions/:id 体受理键与 409 拒体键(<面>#<键> → 读法 / 在场律;只登本版新增的) 新增 `409 conflict.session_row_changed#currentRow`(属性 always;since 7.139.0 = 本版新上 wire)"
152
+ },
153
+ {
154
+ "id": "A23",
155
+ "source": "selfMinted.sessionRowWriteKey",
156
+ "member": "body#expectedRowTag",
157
+ "text": "自铸 PATCH /v1/sessions/:id 体受理键与 409 拒体键(<面>#<键> → 读法 / 在场律;只登本版新增的) 新增 `body#expectedRowTag`(属性 optional;43×[A-Za-z0-9_-] else 400 request.field_invalid;alone 400 request.body_shape;stale⇒409 conflict.session_row_changed;since 7.139.0 = 本版新上 wire)"
158
+ },
159
+ {
160
+ "id": "A24",
161
+ "source": "selfMinted.sessionsListRowKey",
162
+ "member": "rowTag",
163
+ "text": "自铸 GET /v1/sessions sessions[] 行键 = PATCH /v1/sessions/:id 200 体 = 409 conflict.session_row_changed currentRow(<键> → 在场律) 新增 `rowTag`(属性 present-iff the row can be written conditionally (the store has the row write primitive and the row carries an incarnation);since 7.139.0 = 本版新上 wire)"
164
+ },
165
+ {
166
+ "id": "A25",
167
+ "source": "selfMinted.wireValueRule",
168
+ "member": "GET /v1/config/catalog#rows[CONFIG_PROVIDER].semantics",
169
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[CONFIG_PROVIDER].semantics`(属性 remote-without-center-url-refuses-boot;since 7.139.0 = 本版新上 wire)"
170
+ },
171
+ {
172
+ "id": "A26",
173
+ "source": "selfMinted.wireValueRule",
174
+ "member": "GET /v1/config/catalog#rows[DOCKER_SANDBOX_ENV].semantics",
175
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[DOCKER_SANDBOX_ENV].semantics`(属性 own-credential-name-refuses-boot;since 7.139.0 = 本版新上 wire)"
176
+ },
177
+ {
178
+ "id": "A27",
179
+ "source": "selfMinted.wireValueRule",
180
+ "member": "GET /v1/config/catalog#rows[E2B_SANDBOX_ENV].semantics",
181
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[E2B_SANDBOX_ENV].semantics`(属性 own-credential-name-refuses-boot;since 7.139.0 = 本版新上 wire)"
182
+ },
183
+ {
184
+ "id": "A28",
185
+ "source": "selfMinted.wireValueRule",
186
+ "member": "GET /v1/config/catalog#rows[K8S_NAMESPACE].semantics",
187
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[K8S_NAMESPACE].semantics`(属性 required-no-default;absent-or-blank-refuses-boot;since 7.139.0 = 本版新上 wire)"
188
+ },
189
+ {
190
+ "id": "A29",
191
+ "source": "selfMinted.wireValueRule",
192
+ "member": "GET /v1/config/catalog#rows[RETENTION_MODE].semantics",
193
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[RETENTION_MODE].semantics`(属性 enforce-without-horizon-or-cadence-refuses-boot;since 7.139.0 = 本版新上 wire)"
194
+ },
195
+ {
196
+ "id": "A30",
197
+ "source": "selfMinted.wireValueRule",
198
+ "member": "GET /v1/config/catalog#rows[RETENTION_SWEEP_INTERVAL_SEC].semantics",
199
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) 新增 `GET /v1/config/catalog#rows[RETENTION_SWEEP_INTERVAL_SEC].semantics`(属性 cadence-without-horizon-refuses-boot;since 7.139.0 = 本版新上 wire)"
200
+ },
201
+ {
202
+ "id": "A31",
203
+ "source": "wireFace.coreKey",
204
+ "member": "status.seat",
205
+ "text": "投影面 status 新投 core 新键 seat(core 7.60.0 新增,面表没有把它登记进 excluded ⇒ 默认上 wire)"
206
+ }
207
+ ],
208
+ "registered": [],
209
+ "excluded": [],
210
+ "removed": [],
211
+ "changed": [
212
+ {
213
+ "id": "C1",
214
+ "source": "engineNotice",
215
+ "member": "delegation.ask_unresolvable",
216
+ "text": "附录 D.3 engine_notice 码 `delegation.ask_unresolvable` 的detail:`{ sessionId, toolName, toolCallId, cause, parkLaneExisted }` —— `sessionId` 在 core 侧是 **REQUIRED** typed 键(委派子代上是**子代**的 session,归属标按 `fromSubagent`/`sourceTaskId` 同路);🔴 **`cause`(7.74.0 / core 7.17.0 [ref]② 起;旧名 `settlementKind` 已随该版**退役**,读它恒 `undefined`,无别名无双读)闭三词** `approver_unavailable`(被咨询的席答了 unavailable,其后无 park 接住)/ `no_approver_wired`(这条腿压根没接审批席或问答面,含 headless 的 `\"deny\"` 姿态)/ `mandate_unreconstructible`(祖先绑的 durable mandate 在这条腿上没有 park 设施可兑现 ⇒ 委派子代折内拒),逐字透传不窄化(词表属主在 core);`toolCallId` 与 `tool_approval` 卡帧同值可 join。🔴 **`remedies`(core 7.56.0;server 7.137.0 起过境)= 出路的数据形**:闭集 `approver` / `permission_mode` 上的非空表,恰在 `remedy`(无人可问的那一句)在场时带 —— `{ kind: \"approver\" }`(句子已说的那条:接一个审批席 / 让接着的那个能答)与 `{ kind: \"permission_mode\", value: \"bypassPermissions\", disclosedOn: \"gate.disposition.released\" }`(只在两臂上:模式放行这一问,放行披露在那只调用的 `tool_end.gate.disposition.released`)。`detail.remedies` 由宿主按 `kind` 渲染(或不渲染;`permission_mode` 是宿主只在运维放开该模式时才可提的出路,旁边带上 `disclosedOn` 指的披露),**server 只透传、不改写、不补句**;闭集外的 `kind` 属于更新的引擎,忽略。用户读的 `message` / `remedy` 自 core 7.56.0 起**不再教** `bypassPermissions`(那条出路只在 `remedies` 里) → `{ sessionId, toolName, toolCallId, cause, parkLaneExisted }` —— `sessionId` 在 core 侧是 **REQUIRED** typed 键 = 被拒那只调用**所在腿**的会话(委派子代上是**子代自己的** session);本服务按这一个键投给该会话**当前登记的腿**,不经 `fromSubagent` / `sourceTaskId`(那两键属于审批卡帧,不在本码 `detail` 上)转投父会话 —— 同步委派子代的会话本服务不登记腿,于是子代上的这一条今天**不上任何会话流**,只落运维日志行;父会话可见要等引擎为本码另铸父会话副本(`detail.sessionId` = 父会话 + `childSessionId`,`task.user_steer_undrained` 的同形先例),届时本服务零改动承载;🔴 **`cause`(7.74.0 / core 7.17.0 [ref]② 起;旧名 `settlementKind` 已随该版**退役**,读它恒 `undefined`,无别名无双读)闭三词** `approver_unavailable`(被咨询的席答了 unavailable,其后无 park 接住)/ `no_approver_wired`(这条腿压根没接审批席或问答面,含 headless 的 `\"deny\"` 姿态)/ `mandate_unreconstructible`(祖先绑的 durable mandate 在这条腿上没有 park 设施可兑现 ⇒ 委派子代折内拒),逐字透传不窄化(词表属主在 core);`toolCallId` 与 `tool_approval` 卡帧同值可 join。🔴 **`remedies`(core 7.56.0;server 7.137.0 起过境)= 出路的数据形**:闭集 `approver` / `permission_mode` 上的非空表,恰在 `remedy`(无人可问的那一句)在场时带 —— `{ kind: \"approver\" }`(句子已说的那条:接一个审批席 / 让接着的那个能答)与 `{ kind: \"permission_mode\", value: \"bypassPermissions\", disclosedOn: \"gate.disposition.released\" }`(只在两臂上:模式放行这一问,放行披露在那只调用的 `tool_end.gate.disposition.released`)。`detail.remedies` 由宿主按 `kind` 渲染(或不渲染;`permission_mode` 是宿主只在运维放开该模式时才可提的出路,旁边带上 `disclosedOn` 指的披露),**server 只透传、不改写、不补句**;闭集外的 `kind` 属于更新的引擎,忽略。用户读的 `message` / `remedy` 自 core 7.56.0 起**不再教** `bypassPermissions`(那条出路只在 `remedies` 里)"
217
+ },
218
+ {
219
+ "id": "C2",
220
+ "source": "selfMinted.wireValueRule",
221
+ "member": "GET /v1/config/catalog#rows[K8S_SANDBOX_ENV].semantics",
222
+ "text": "自铸 出口值变换(<端点>#<键> → 变换) `GET /v1/config/catalog#rows[K8S_SANDBOX_ENV].semantics` 的属性:values-only-in-the-pod-own-secret;role-needs-secrets-create;denied-refuses-boot → values-only-in-the-pod-own-secret;role-needs-secrets-create;denied-refuses-boot;own-credential-name-refuses-boot(since 7.139.0)"
223
+ }
224
+ ],
225
+ "narrowed": [],
226
+ "closedSetMembers": [
227
+ {
228
+ "set": "errorCode",
229
+ "at": [
230
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1",
231
+ "docs/ASSISTANT-WIRE-CONTRACT.md#A.1b"
232
+ ],
233
+ "added": [
234
+ "conflict.fork_id_taken",
235
+ "conflict.fork_in_progress",
236
+ "conflict.session_mirror",
237
+ "conflict.session_row_changed",
238
+ "conflict.session_writer",
239
+ "execution_lane.not_served",
240
+ "execution_lane.tree_bound",
241
+ "state.fork_target_unsettled"
242
+ ],
243
+ "registered": [],
244
+ "removed": [],
245
+ "breaking": false
246
+ },
247
+ {
248
+ "set": "selfMinted.endpointFaceStatus",
249
+ "at": [
250
+ "src/trace/self-minted-wire.ts#endpointFaceStatus"
251
+ ],
252
+ "added": [
253
+ "PATCH /v1/sessions/:id#expectedRowTag_current(行仍在那只标签上;体 = 列表行)",
254
+ "PATCH /v1/sessions/:id#expectedRowTag_stale(行已不在那只标签上;体 conflict.session_row_changed + currentRow)",
255
+ "PATCH /v1/sessions/:id#mirror_row(只读镜像行上的写,带不带 expectedRowTag;体 conflict.session_mirror + forkPath)",
256
+ "PATCH /v1/sessions/:id#owner_changed_after_gate(门那一读之后同一会话的属主被改;体 not_found.session)",
257
+ "POST /v1/side-query#uncoded_error_with_preflight_prefix(没有引擎码、英文开头与前缀表同形的错误;体 internal.error)",
258
+ "POST /v1/tasks|/v1/tasks/stream|/v1/runs#rewindFiles(新提交;体 request.body_shape + unknownKeys [rewindFiles])"
259
+ ],
260
+ "registered": [],
261
+ "removed": [],
262
+ "breaking": false
263
+ },
264
+ {
265
+ "set": "selfMinted.fieldConflictKind",
266
+ "at": [
267
+ "src/trace/self-minted-wire.ts#fieldConflictKind"
268
+ ],
269
+ "added": [
270
+ "fork_target"
271
+ ],
272
+ "registered": [],
273
+ "removed": [],
274
+ "breaking": false
275
+ },
276
+ {
277
+ "set": "selfMinted.refusalSentenceForm",
278
+ "at": [
279
+ "src/trace/self-minted-wire.ts#refusalSentenceForm"
280
+ ],
281
+ "added": [
282
+ "400 request.body_shape#PATCH /v1/sessions/:id",
283
+ "400 request.field_invalid#PATCH /v1/sessions/:id.expectedRowTag",
284
+ "409 conflict.session_mirror#PATCH /v1/sessions/:id",
285
+ "409 conflict.session_row_changed#PATCH /v1/sessions/:id"
286
+ ],
287
+ "registered": [],
288
+ "removed": [],
289
+ "breaking": false
290
+ },
291
+ {
292
+ "set": "selfMinted.sessionBackgroundRowKey",
293
+ "at": [
294
+ "src/trace/self-minted-wire.ts#sessionBackgroundRowKey"
295
+ ],
296
+ "added": [
297
+ "sessionId"
298
+ ],
299
+ "registered": [],
300
+ "removed": [],
301
+ "breaking": false
302
+ },
303
+ {
304
+ "set": "selfMinted.sessionRowWriteKey",
305
+ "at": [
306
+ "src/trace/self-minted-wire.ts#sessionRowWriteKey"
307
+ ],
308
+ "added": [
309
+ "409 conflict.session_mirror#forkPath",
310
+ "409 conflict.session_row_changed#currentRow",
311
+ "body#expectedRowTag"
312
+ ],
313
+ "registered": [],
314
+ "removed": [],
315
+ "breaking": false
316
+ },
317
+ {
318
+ "set": "selfMinted.sessionsListRowKey",
319
+ "at": [
320
+ "src/trace/self-minted-wire.ts#sessionsListRowKey"
321
+ ],
322
+ "added": [
323
+ "rowTag"
324
+ ],
325
+ "registered": [],
326
+ "removed": [],
327
+ "breaking": false
328
+ },
329
+ {
330
+ "set": "selfMinted.wireValueRule",
331
+ "at": [
332
+ "src/trace/self-minted-wire.ts#wireValueRule"
333
+ ],
334
+ "added": [
335
+ "GET /v1/config/catalog#rows[CONFIG_PROVIDER].semantics",
336
+ "GET /v1/config/catalog#rows[DOCKER_SANDBOX_ENV].semantics",
337
+ "GET /v1/config/catalog#rows[E2B_SANDBOX_ENV].semantics",
338
+ "GET /v1/config/catalog#rows[K8S_NAMESPACE].semantics",
339
+ "GET /v1/config/catalog#rows[RETENTION_MODE].semantics",
340
+ "GET /v1/config/catalog#rows[RETENTION_SWEEP_INTERVAL_SEC].semantics"
341
+ ],
342
+ "registered": [],
343
+ "removed": [],
344
+ "breaking": false
345
+ }
346
+ ],
347
+ "breaking": 0
348
+ }
@@ -1,175 +0,0 @@
1
- /**
2
- * device lane **首绑写协议**(design `device-executor-lane-v2` §4.3.2)—— 两阶段 placement 的
3
- * server 半场:`resolveDevicePlacementIntent`(**只校验、不写库**)+ {@link commitPlacement}
4
- * (**唯一**写入属主)。
5
- *
6
- * ── 两阶段的**分界在哪**(codex R1 两条 finding 判真后的正形)────────────────────────────────────
7
- * 设计同段给了两条等价路(「同一 DB 事务原子提交,**或** commit 失败时以 taskId/rev CAS 终结并释放已建的
8
- * run」)。本仓取**后者**,理由是结构性的:run 行住在 `RunStore`(tidb / pg / **file**),绑定行住在
9
- * `DeviceStore`(tidb / pg)—— 要它们共享一个事务席,就等于要求「凡 device 车道,两只店必须是同一个
10
- * SQL 连接池」。那会把 file / memory 形态的 run 店整个排除在外,而「本地与云无缝、TOC 面 backend 可插」
11
- * 是本仓的铁律。
12
- *
13
- * 🔴 **分界的判据只有一句话:凡需要「这条会话已经归我」才成立的事,排在 claim 之后;其余全排在建任何
14
- * 东西之前。** claim 之后只剩两件,而且是同一条不变量的两条臂 —— **离开 commit 的那一刻,绑定就是准入
15
- * 批准的那一台**:首绑那一次 CAS(写),或对已有绑定的**再断言**(零写;codex 轮 2 [high] 的类修)。
16
- * ⚠️ 「那一刻」是字面义,**不是「此后不变」** —— 论证与残余见 {@link commitPlacement} 顶注。
17
- 首绑那一次 CAS 必须在 claim 之后 —— 否则两条并发提交里输掉 claim 的那个会先把绑定写成**它**要的设备,
18
- * 赢家的 run 于是落到别人挑的机器上。而准入链的三步(绑定解出 / devices active / presence)**全是读**,
19
- * 它们一个字节都不写,所以整段挪到 `resolveDevicePlacementIntent` 里、在 `createRun` **之前**判
20
- *(意图把批准的那台设备**带上**,commit 才有东西可断言 —— 见 `DevicePlacementIntent.admittedDeviceId`)。
21
- * 这条收法同时关掉 codex 轮 1 的两条(都判真):
22
- * · **[medium] 幂等键被常规拒绝烧掉**:`POST /v1/runs` 的自带 `body.taskId` 重放腿读的是 durable run 行
23
- * (`routes/runs.ts` 的 `getRun(clientTaskId)` 臂),行在**哪怕是 failed** 也直接回 `202 {status:"failed"}`
24
- * ⇒ 「设备离线」这种**常规**拒绝若先建了行,网关按同一个 taskId 的正常重试从此永远拿不到一次真准入。
25
- * 读排在前面 ⇒ 常规拒绝的读面代价为零(零 run 行、零 claim、零补偿)。
26
- * · **[high] claim 与 placement 写之间的无界窗**:claim 之后的**每一次**店往返都带
27
- * {@link placementWriteDeadlineMs} 派生的**硬时限**(远小于 `runStaleSec`)⇒ 「挂得比 stale 回收还久、
28
- * 回来以后仍然放行」这条竞态被时限从结构上关掉;超时 = 拒(fail-closed)+ 释放,绝不放行。
29
- * 残余(如实):`createRun` 之后到心跳起来之前**本来**就有若干 await(`putCtx`、SSE 前导),那个窗是
30
- * 存量形,本文件只负责**不加宽它**(本层的写有界),不假装把它关掉了。
31
- *
32
- * ── 为什么 commit 只许有一个属主函数 ───────────────────────────────────────────────────────────────
33
- * 真码有**四个** `runStore.createRun(` 成功点(流式提交 / 同步提交 / durable 提交腿 / wake 续跑腿),
34
- * 而「建了 run 行之后要不要绑设备」这件事对它们是同一句话。四份手抄 = 第五个入口出现时漏接一份,
35
- * 而漏接的症状是「run 跑起来了但没有绑定」⇒ 执行期才 `device.not_bound`,账面上是一条已收费的失败 run。
36
- * 类级机器门钉住这条:`test/device-first-bind.test.ts` 按 AST 找 `src/http/**` 里每一处 `createRun(`,
37
- * 要求同一函数体内可见地走到 {@link commitPlacement}(漏接 = 当场红)。
38
- *
39
- * ── 准入链(§4.3.2 提交期三步,全 fail-closed)─────────────────────────────────────────────────────
40
- * 1. 绑定解出 deviceId —— 解不出 = `device.not_bound`;
41
- * 2. devices 行 `active` —— 行不在 / 不是你的 = `not_found.device`(反枚举同形),吊销 = `device.revoked`;
42
- * 3. presence 在线 —— 否 = `device.offline`(**只在提交期**校验;执行期离线走 §5.4/§8)。
43
- * 三步的属主是 `device-enrollment.ts` 的 `admitSession`,本文件一个判据都不自建,而且**整段在建 run 之前**跑
44
- * (见上一段的分界判据)。任何查表故障 = 拒([ref]:安全轴上没有静默 fail-open 臂)。
45
- *
46
- * ── 便利度不变(clay [ref] 硬约束)────────────────────────────────────────────────────────────────
47
- * 本文件**不产生任何审批**:它只做「这条 session 该落在哪台设备上」的查表与一次 CAS。device 车道上
48
- * `permissionMode: "bypassPermissions"` 的 run 与 host 车道同构造同读数(判据钉在 device-first-bind
49
- * 测试的「零额外审批」格)——「因为是 device 车道所以多问一次」在本层结构上不存在。
50
- */
51
- import type { IncomingMessage } from "node:http";
52
- import { type DeviceOwner } from "../device-store.js";
53
- import { type DeviceEnrollment, type DeviceRejection } from "../device-enrollment.js";
54
- import type { ServiceConfig } from "../config.js";
55
- import type { RunStore } from "../plugins/store-backend.js";
56
- import { type RefusalBody } from "./refusal-body.js";
57
- /**
58
- * 调用方 device 域的**唯一铸造点**。`undefined` = 判不出域(无 principal,或凭据不带 tenant claim)——
59
- * 消费点必须响亮拒,禁静默空视图。
60
- *
61
- * 🔴 位置即契约:`{owner_tenant, owner_subject}` 是 O11 的 device-lane-local 复合身份(全局 principal
62
- * 一个字节不动)。subject = `gatedPrincipal`(verified 链),tenant = `ssoVerifiedScope`(registry
63
- * auth-bridge JWT 的 `scope` claim)—— **两者都是签名真源,不是自报头**。管理面三读三写与首绑写协议
64
- * 全部从这一只函数取域;派生第二份就是把 O11 的判据本体复制成一份会漂的孪生。
65
- */
66
- export declare function deviceOwnerDomainOf(req: IncomingMessage, config: ServiceConfig): DeviceOwner | undefined;
67
- /**
68
- * **已校验、未写库**的 placement 意图(§4.3.2 ①)。
69
- *
70
- * 它的存在本身就是那条设计裁定:`resolveSpec` / `prepareSpec` 那一刻**还不知道**哪个并发请求会赢下
71
- * session 的 active-run claim,所以它不能写绑定行 —— 只能把「如果我赢了,该写什么」算好交出去。
72
- * 而**除了那一次写**,别的都已经在这一刻判完了(见文件头注的分界判据)。
73
- */
74
- export interface DevicePlacementIntent {
75
- /** 绑定键 = **根**会话(后代无条件继承;core 为 subagent/cascade/verify 另铸 sessionId,不另绑)。 */
76
- readonly rootSessionId: string;
77
- /** 验证过的复合身份(§4.3.2:恒取 verified 链,不取自可伪造头)。 */
78
- readonly owner: DeviceOwner;
79
- /**
80
- * **准入链批准的那台设备** —— 意图阶段判完的那一台,也是 {@link commitPlacement} 的**断言对象**。
81
- *
82
- * 🔴 这一位是 codex 轮 2 [high] 的类修(病:已绑路径的意图**丢掉了设备身份**,于是一条明确写了
83
- * `deviceId: A` 的提交在「准入过后、claim 之前」被换绑到 B 时会**静默地在 B 上跑完** —— 执行环境
84
- * 工厂读的是**当下**的绑定,它根本不知道调用方点过名,`plugins/remote-env-device.ts` 的工厂段亲读坐实)。
85
- * 身份留在意图里,commit 才有东西可断言。
86
- */
87
- readonly admittedDeviceId: string;
88
- /**
89
- * `true` = 这条根会话在意图阶段**还没有绑定** ⇒ commit 要做那一次首绑 CAS(写);
90
- * `false` = 已有绑定 ⇒ commit **不写**,只把 {@link admittedDeviceId} 对着活绑定**再断言一次**。
91
- * 两条臂的共同不变量只有一句:**离开 commitPlacement 时,这条会话的绑定就是准入批准的那一台。**
92
- */
93
- readonly firstBind: boolean;
94
- }
95
- /**
96
- * §4.3.2 ① —— 产出**已校验、不写库**的意图,或响亮拒。**准入链整段在这里跑**(它全是读),所以
97
- * 常规拒绝(未绑定 / 离线 / 已吊销 / 不是你的设备)的读面代价是零:没有 run 行、没有会话占用、
98
- * 没有补偿要做,调用方自带的幂等 taskId 一个都不会被烧掉(codex R1-[medium] 的类修)。
99
- *
100
- * 判据(逐条,fail-closed):
101
- * · 车道不是 device 而体携 `deviceId` ⇒ **400**(不静默忽略 —— 安全轴禁 quiet fallback:调用方以为
102
- * 自己指定了执行设备,而那条声明从未存在);
103
- * · 车道是 device 而装配缺件 ⇒ **501**(boot 的 `device-lane-unwired` 不变量本应先拒启,这里是消费点自卫);
104
- * · 判不出调用方域 ⇒ **403 响亮**(O11:准入等值比对没有真源时放行 = 把绑定写成任何人的);
105
- * · 没有根会话 ⇒ **400**(绑定键不存在,绑无可绑);
106
- * · 其余全部交给准入链属主 `admitSession`,**唯一的分叉**是它答 `device.not_bound` 那一支 ——
107
- * 那正是「还没有绑定」,于是本函数看提交体有没有携首绑目标:没携 ⇒ 把 `device.not_bound` 原样交回;
108
- * 携了 ⇒ 形门 + devices 行(active ∧ 是本域的 ∧ **在线**)三条读判完,产出首绑意图。
109
- *
110
- * 返回 `undefined` = 本部署不是 device 车道 ⇒ 整条 placement 面不存在(既有行为逐字节不变)。
111
- */
112
- export declare function resolveDevicePlacementIntent(args: {
113
- config: ServiceConfig;
114
- req: IncomingMessage | undefined;
115
- rootSessionId: string | undefined;
116
- deviceId: unknown;
117
- store: import("../device-store.js").DeviceStore | undefined;
118
- enrollment: DeviceEnrollment | undefined;
119
- }): Promise<DevicePlacementIntent | undefined>;
120
- /** {@link commitPlacement} 的依赖 —— 逐字取自 `ServiceDeps` 的同名键(同一只 deps 对象喂进来,所以
121
- * 「意图在 ⟹ 准入链在」是**同对象不变量**,不是一句祈愿)。 */
122
- export interface PlacementCommitCtx {
123
- deviceEnrollment?: DeviceEnrollment | undefined;
124
- config?: {
125
- runStaleSec?: number;
126
- } | undefined;
127
- logger?: {
128
- warn(msg: string, fields?: Record<string, unknown>): void;
129
- } | undefined;
130
- metrics?: {
131
- inc(name: string, labels?: Record<string, string>): void;
132
- } | undefined;
133
- }
134
- /**
135
- * claim 之后那一次写的**硬时限**(codex R1-[high] 的类修)。
136
- *
137
- * 界从 `runStaleSec` **派生**而不是新铸一个旋钮(operator-knob 纪律:没人要求过的旋钮不铸):它要回答的
138
- * 问题只有一个 —— 「这次写会不会挂到 stale 回收把我的会话占用收走」。取四分之一并夹在 `[1s, 15s]`:
139
- * 上夹是因为一次 CAS 写挂过 15 秒已经不是慢而是坏,下夹是因为运维把 `runStaleSec` 配得极小时,时限
140
- * 不该短到把正常的库往返判成故障。
141
- */
142
- export declare function placementWriteDeadlineMs(runStaleSec: number | undefined): number;
143
- /**
144
- * §4.3.2 ②③ —— placement 的**唯一**提交点(写 + 断言都只在这里发生)。四个 `createRun` 成功点全部经它。
145
- *
146
- * 到这一刻为止,该判的读已经判完(见文件头注的分界判据),而本函数拿到了一样意图阶段拿不到的东西:
147
- * **这条会话的 active-run claim 已经归我们了**。两件事因此才成立:
148
- * · **首绑臂**(`firstBind`)—— 做那一次 INSERT-if-absent CAS(赢 = 成立;输且同设备 = 幂等成功;
149
- * 输且异设备 = `device.claim_conflict`);
150
- * · **已绑臂** —— **不写**,但拿同一只 `admitSession` 对着活绑定把 {@link DevicePlacementIntent.admittedDeviceId}
151
- * **再断言一次**(codex 轮 2 [high] 的类修)。判据属主仍是准入链那一只函数,本文件一个新判据都没造。
152
- *
153
- * 不变量(一句话):**离开本函数的那一刻,这条会话的绑定就是准入批准的那一台;否则本请求刚建的 run
154
- * 已被终结并释放,调用方拿到的是一个 typed 拒绝。**
155
- *
156
- * 🔴 **这条不变量到此为止,它不说「此后不变」——一次如实改口(codex 轮 3 驳回了我方轮 2 的论证)。**
157
- * 我方轮 2 写过「claim 一归我们,换绑动词的『无活跃 run』门就把并发换绑拒掉 ⇒ 断言之后绑定不可能再动」。
158
- * **那句话是错的**,codex 轮 3 给的交错成立、亲读坐标复核无误:换绑腿的那道门是 check→act
159
- * (`http/routes/devices.ts` 的「🔴 成文残留(设计裁定,非疏漏)」那一段逐字写着这个窗),它可以在本次
160
- * `createRun` **之前**读到「无活跃 run」而在本函数**之后**才提交 CAS —— run claim 不推进绑定 `rev`,
161
- * 那条 CAS 照样赢。于是:
162
- * · 本断言**关掉**的是「换绑在本函数读之前已可见」那一半(较大的一半);
163
- * · **剩下**的一半是那条**存量**的 check→act 窗,它的既有处置逐字在那段注里:①赢窗的 run 在换绑提交
164
- * **后**铸 env ⇒ 读到新绑定;②在提交前铸(或已 connect)⇒ 投递门 `expectedDeviceId` 围栏按铸造时
165
- * 设备恒拒,零指令落到任何一台设备。**对本批新增的「体里点了名」这一形,臂 ① 的『合法』口径不再成立**
166
- * (调用方点了 A,却在 B 上跑),这条**登记为未闭环**:要真正关掉它,得把 `admittedDeviceId` 一路钉进
167
- * 执行环境工厂与投递围栏(那是一条跨 core seam 的**新能力**,按本仓复审纪律不在复审环里加),或按
168
- * 稿 §6 的候门段做跨店互斥 claim。两条都是独立的车与设计,不是本层的一个补丁。
169
- *
170
- * 返回 `null` = 放行(含「本部署不是 device 车道」)。
171
- */
172
- export declare function commitPlacement(ctx: PlacementCommitCtx, runStore: RunStore, taskId: string, intent: DevicePlacementIntent | undefined): Promise<DeviceRejection | null>;
173
- /** 拒绝的**唯一** wire 体铸点(四个消费点各自用自己协议的发送姿势,但体的键集只有这一份)。 */
174
- export declare function devicePlacementErrorBody(rej: DeviceRejection): RefusalBody;
175
- //# sourceMappingURL=device-placement.d.ts.map