@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
@@ -0,0 +1,155 @@
1
+ /**
2
+ * 随包的引擎部署事实(npm 包内 `deploy/facts/`)—— 成员集、Schema 方言、形变登记表的**唯一定义处**,以及其中两份成员(车道 / 钥匙保管目录)的投影与 Schema。
3
+ *
4
+ * ## 成员律
5
+ * `deploy/facts/` 只装**引擎自己的部署要求**:引擎发出的 API 调用、引擎按名读的键与目录、引擎要求先存在的条件。每一份都有引擎属主,都是生成物
6
+ * (唯一生成器 `scripts/gen-deploy-lanes.ts`,`--check` 与 `test/deploy-lane-projections.test.ts` 钉「入库 ≡ 生成物」),从不手写。
7
+ * 部署方拥有的策略实例(引擎读来诊断、不据以发调用的东西,例如沙箱出网的 NetworkPolicy)不是成员。
8
+ * 每个成员 `<m>` = 数据 `<m>.json` + 一份机器可读 Schema `<m>.schema.json`;另有一份形变登记 `CHANGES.json`。三类文件都是 npm 子路径
9
+ * `@sema-agent/server/deploy/facts/<文件>`(子路径 = 包内文件路径)。
10
+ * · `lanes`:每条执行车道的租户档、隔离位、必需键 —— 投影自 settings-schema 车道表与执行环境能力块({@link LANE_FACTS_SCHEMA};行由生成器从同一个车道模型渲出,
11
+ * 安装器那张旧车道表的 `users` / `isolation` 两列也从这些行派生,同源零双写);
12
+ * · `sandbox-rbac`:k8s 沙箱服务账号的 RBAC 规则表 —— 表与 Schema 都在 `src/sandbox-rbac-rules.ts`(和表放一起);
13
+ * · `sealed-key`:钥匙保管目录的安装契约 —— 投影自 `src/sealed-key-layout.ts` 的布局常量与配置读法「`SEALED_KEY_DIR` 须是绝对路径」({@link SEALED_KEY_FACTS})。
14
+ *
15
+ * ## 契约:「未登记的加性形变,或未抬版的破坏性形变 ⇒ 红」
16
+ * 发车链对**上一个已发 tag** 里的同名 Schema 求差(`scripts/deploy-facts-gate.ts`;CI 浅克隆读不到 tag,这道判据在发车链跑),
17
+ * 差异逐条分成加性 / 破坏性,与 {@link FACTS_SCHEMA_CHANGES} 里本版新登记的条目对账。**加性只有一种:新增一个可选属性**;其余任何形变
18
+ * (删属性、改类型、可选 ⇄ 必有、新增必有属性、`items` 形变、闭集增 / 删词、`const` 变、`minItems` / `uniqueItems` / `x-uniqueKey` 变)都是破坏性。
19
+ * 值的含义变了而 Schema 不变(例如重新定义某个闭集词)门判不出 —— 改动者登记一条 `breaking` 并写明 `why`,复审按这一条问。
20
+ *
21
+ * ## 版本
22
+ * 每个成员的 `schemaVersion` **从登记表派生**({@link factsSchemaVersion}):首发那一版 = 1,此后每个登记了 `breaking` 的版本 +1。不另写常量 ——
23
+ * 登记一条破坏性形变就抬了版,「改了形忘了抬版」只剩「改了形没登记」一种,门对着已发 tag 抓它。
24
+ * 读方义务:用**同一个包里**那份 Schema 校验;不认识的 `schemaVersion` 整份拒读;同一版本内的未知键忽略。
25
+ */
26
+ import { TENANT_SEPARATION_WORDS } from "@sema-agent/settings-schema/execution-lanes";
27
+ /** 包内目录(npm 子路径前缀 `@sema-agent/server/deploy/facts/`)。 */
28
+ export declare const DEPLOY_FACTS_DIR = "deploy/facts";
29
+ /** 成员闭集。加一个成员 = 这里加一个词 + 生成器给它数据与 Schema + 登记表一条 `introduced`(缺任一处 ⇒ 编译错或生成抛)。 */
30
+ export declare const DEPLOY_FACTS_MEMBERS: readonly ["lanes", "sandbox-rbac", "sealed-key"];
31
+ export type DeployFactsMember = (typeof DEPLOY_FACTS_MEMBERS)[number];
32
+ /** 形变登记表的文件名(与成员同目录;不是成员,没有自己的 Schema)。 */
33
+ export declare const DEPLOY_FACTS_CHANGES_FILE = "CHANGES.json";
34
+ /** 方言 = JSON Schema 2020-12 的一个闭子集;根上的 `$schema` 恒为它。 */
35
+ export declare const FACTS_SCHEMA_DIALECT = "https://json-schema.org/draft/2020-12/schema";
36
+ /**
37
+ * 方言的节点形(类型就是方言:多写一个关键字 = 编译错;`scripts/deploy-facts-gate.ts` 在 JSON 面再判一次,拿到的是入库文件与已发 tag 上的文件)。
38
+ * · 标量:`string`(可带 `enum` 闭集或 `const`)/ `integer`(可带 `const`)/ `boolean`;
39
+ * · 对象:`properties` + `required`(⊆ properties)+ `additionalProperties: false`(恒关:未登记的键不许出现);
40
+ * · 数组:`items`(必有)+ 可选 `minItems`;标量元素可声明 `uniqueItems: true`,对象元素可声明 `x-uniqueKey`(这几个属性的值组合在数组里唯一;
41
+ * 成员必须是元素的必有属性、且是标量或标量数组 —— 对象成员里加可选属性按上面的判法是加性,却会让旧读方算出的唯一性失真;
42
+ * 标准校验器把它当注解忽略,本仓的校验器执行它)。
43
+ * · JSON 键一律只认自有的(`toString` / `constructor` / `__proto__` 这类原型链上的名字不算「在」)。
44
+ * · `description` 任何节点都可带,差异判法不看它(值含义的变化走人工登记)。
45
+ */
46
+ export type FactsScalarSchema = {
47
+ readonly type: "string";
48
+ readonly enum?: readonly string[];
49
+ readonly const?: string;
50
+ readonly description?: string;
51
+ } | {
52
+ readonly type: "integer";
53
+ readonly const?: number;
54
+ readonly description?: string;
55
+ } | {
56
+ readonly type: "boolean";
57
+ readonly description?: string;
58
+ };
59
+ export interface FactsObjectSchema {
60
+ readonly type: "object";
61
+ readonly properties: {
62
+ readonly [key: string]: FactsNodeSchema;
63
+ };
64
+ readonly required: readonly string[];
65
+ readonly additionalProperties: false;
66
+ readonly description?: string;
67
+ }
68
+ export interface FactsArraySchema {
69
+ readonly type: "array";
70
+ readonly items: FactsNodeSchema;
71
+ readonly minItems?: number;
72
+ readonly uniqueItems?: true;
73
+ readonly "x-uniqueKey"?: readonly string[];
74
+ readonly description?: string;
75
+ }
76
+ export type FactsNodeSchema = FactsScalarSchema | FactsObjectSchema | FactsArraySchema;
77
+ /**
78
+ * 每种节点允许的关键字(运行期闭集;`scripts/deploy-facts-gate.ts` 的方言判读它,对入库文件与已发 tag 上的文件都判)。
79
+ * `satisfies` 让这张表只列类型里有的键;类型里多出来而表里没列的键,生成器在渲 Schema 时当场抛「方言外的关键字」。根节点另多一个 `$schema`。
80
+ */
81
+ export declare const FACTS_SCHEMA_KEYWORDS: {
82
+ readonly string: readonly ["type", "enum", "const", "description"];
83
+ readonly integer: readonly ["type", "const", "description"];
84
+ readonly boolean: readonly ["type", "description"];
85
+ readonly object: readonly ["type", "properties", "required", "additionalProperties", "description"];
86
+ readonly array: readonly ["type", "items", "minItems", "uniqueItems", "x-uniqueKey", "description"];
87
+ };
88
+ /** 根:一个对象节点 + `$schema`;`schemaVersion` 必有且形恒为 `{ type: "integer", const: <版本> }`(门把这一处当版本通道,不当形变)。 */
89
+ export interface FactsRootSchema extends FactsObjectSchema {
90
+ readonly $schema: typeof FACTS_SCHEMA_DIALECT;
91
+ readonly properties: {
92
+ readonly schemaVersion: {
93
+ readonly type: "integer";
94
+ readonly const: number;
95
+ readonly description?: string;
96
+ };
97
+ readonly [key: string]: FactsNodeSchema;
98
+ };
99
+ }
100
+ export declare const FACTS_SCHEMA_CHANGE_KINDS: readonly ["introduced", "additive", "breaking"];
101
+ export type FactsSchemaChangeKind = (typeof FACTS_SCHEMA_CHANGE_KINDS)[number];
102
+ /**
103
+ * 一条形变登记。`pointer` = 实例路径:`""` 是整份,`/lanes/[]/isolation` 是 `lanes` 数组每一行的 `isolation`(`[]` = 数组元素)。
104
+ * `version` = 这条形变随哪个 server 版本发出;已发版本的条目只读(门:基线 tag 上的每一条在本树里原样还在)。
105
+ */
106
+ export interface FactsSchemaChange {
107
+ readonly version: string;
108
+ readonly file: DeployFactsMember;
109
+ readonly kind: FactsSchemaChangeKind;
110
+ readonly pointer: string;
111
+ readonly why: string;
112
+ }
113
+ /**
114
+ * 形变登记表(只追加;生成器把它写成随包 `CHANGES.json` 与 README 的变更节)。
115
+ * 新条目的 `version` 写下一个要发的 server 版本;发车链在版本号抬起后核「本版新登记的条目都是这个版本」。
116
+ */
117
+ export declare const FACTS_SCHEMA_CHANGES: readonly FactsSchemaChange[];
118
+ /**
119
+ * 成员当前的 `schemaVersion`:登记表里恰一条 `introduced`(那一版 = 1),此后每个登记了 `breaking` 的**不同**版本 +1
120
+ * (同一版本里登记几条破坏性形变都只抬一次;首发那一版里的 `breaking` 不算 —— 那时还没有发出去的形)。
121
+ * 登记表不合这个形(零条 / 多条 `introduced`)⇒ 抛:版本号无从派生,不猜。
122
+ */
123
+ export declare function factsSchemaVersion(member: DeployFactsMember, changes?: readonly FactsSchemaChange[]): number;
124
+ /** 隔离位闭集:手跑在不在 OS 级隔离边界里(执行环境能力块的 `isolation` 位;安装器旧车道表的 `isolation` 列也读这两个词)。 */
125
+ export declare const LANE_ISOLATION_WORDS: readonly ["supported", "unsupported"];
126
+ export type LaneIsolationWord = (typeof LANE_ISOLATION_WORDS)[number];
127
+ /** `lanes.json` 的一行(行序 = settings-schema 车道词序)。 */
128
+ export interface LaneFactsRow {
129
+ readonly lane: string;
130
+ readonly tenantSeparation: (typeof TENANT_SEPARATION_WORDS)[number];
131
+ readonly isolation: LaneIsolationWord;
132
+ readonly requiredEnv: readonly string[];
133
+ readonly requiredSecretEnv: readonly string[];
134
+ }
135
+ export declare const LANE_FACTS_SCHEMA: FactsRootSchema;
136
+ /** 钥匙保管目录对安装器的要求(闭集;每个词的意思写在 Schema 的 `description` 里)。 */
137
+ export declare const SEALED_KEY_REQUIREMENTS: readonly ["persist-across-restart", "shared-by-all-replicas", "writable", "whole-directory"];
138
+ export type SealedKeyRequirement = (typeof SEALED_KEY_REQUIREMENTS)[number];
139
+ /** 保管目录路径形的闭集:只收绝对路径(相对路径起服拒)。 */
140
+ export declare const SEALED_KEY_DIR_PATH_FORMS: readonly ["absolute"];
141
+ /**
142
+ * `sealed-key.json` 的内容:安装契约要求**显式设一个绝对路径的 `SEALED_KEY_DIR`**,安装器据此挂卷。
143
+ * 没设它时引擎回落到数据根下的 `sealed-key/`(数据根自身还有一条回落链)—— 那是引擎内部行为,安装器不依赖它,所以不在这份事实里。
144
+ */
145
+ export declare const SEALED_KEY_FACTS: {
146
+ readonly schemaVersion: number;
147
+ readonly dirEnv: "SEALED_KEY_DIR";
148
+ readonly dirPath: "absolute";
149
+ readonly subdirs: readonly ["checkpoint-ctx-keys"];
150
+ readonly dirMode: string;
151
+ readonly fileMode: string;
152
+ readonly requirements: readonly ["persist-across-restart", "shared-by-all-replicas", "writable", "whole-directory"];
153
+ };
154
+ export declare const SEALED_KEY_FACTS_SCHEMA: FactsRootSchema;
155
+ //# sourceMappingURL=deploy-facts.d.ts.map
@@ -0,0 +1,95 @@
1
+ import { TENANT_SEPARATION_WORDS } from "@sema-agent/settings-schema/execution-lanes";
2
+ import { CHECKPOINT_CTX_KEY_SUBDIR, SEALED_KEY_DIR_MODE } from "./sealed-key-layout.js";
3
+ import { OWNER_ONLY_FILE_MODE } from "./plugins/owner-only-file-mode.js";
4
+ export const DEPLOY_FACTS_DIR = "deploy/facts";
5
+ export const DEPLOY_FACTS_MEMBERS = ["lanes", "sandbox-rbac", "sealed-key"];
6
+ export const DEPLOY_FACTS_CHANGES_FILE = "CHANGES.json";
7
+ export const FACTS_SCHEMA_DIALECT = "https://json-schema.org/draft/2020-12/schema";
8
+ export const FACTS_SCHEMA_KEYWORDS = {
9
+ string: ["type", "enum", "const", "description"],
10
+ integer: ["type", "const", "description"],
11
+ boolean: ["type", "description"],
12
+ object: ["type", "properties", "required", "additionalProperties", "description"],
13
+ array: ["type", "items", "minItems", "uniqueItems", "x-uniqueKey", "description"],
14
+ };
15
+ export const FACTS_SCHEMA_CHANGE_KINDS = ["introduced", "additive", "breaking"];
16
+ export const FACTS_SCHEMA_CHANGES = [
17
+ { version: "7.146.0", file: "lanes", kind: "introduced", pointer: "", why: "首发:每条执行车道的租户档、隔离位与必需键,行集 = 所依 settings-schema 的全部车道词" },
18
+ { version: "7.146.0", file: "sandbox-rbac", kind: "introduced", pointer: "", why: "首发:k8s 沙箱服务账号的 RBAC 规则表(每条规则何时授、引擎真调还是兼容保留)" },
19
+ { version: "7.146.0", file: "sealed-key", kind: "introduced", pointer: "", why: "首发:钥匙保管目录的安装契约(显式绝对 SEALED_KEY_DIR、整个目录跨重启持久且各副本共享、目录与文件的权限位)" },
20
+ ];
21
+ export function factsSchemaVersion(member, changes = FACTS_SCHEMA_CHANGES) {
22
+ const own = changes.filter((c) => c.file === member);
23
+ const intro = own.filter((c) => c.kind === "introduced");
24
+ const [first] = intro;
25
+ if (intro.length !== 1 || first === undefined)
26
+ throw new Error(`deploy-facts: member "${member}" needs exactly one "introduced" entry in FACTS_SCHEMA_CHANGES (found ${intro.length}) — its schemaVersion cannot be derived`);
27
+ return 1 + new Set(own.filter((c) => c.kind === "breaking" && c.version !== first.version).map((c) => c.version)).size;
28
+ }
29
+ export const LANE_ISOLATION_WORDS = ["supported", "unsupported"];
30
+ const envNames = (description) => ({ type: "array", uniqueItems: true, items: { type: "string" }, description });
31
+ export const LANE_FACTS_SCHEMA = {
32
+ $schema: FACTS_SCHEMA_DIALECT,
33
+ description: "引擎的执行车道事实:每条车道分不分租户、手跑在不在 OS 级隔离边界里、选它时引擎起服必须读到的键。行集 = 本包所依 settings-schema 车道表的全部车道词(含没有安装器接线的车道)。",
34
+ type: "object",
35
+ additionalProperties: false,
36
+ required: ["schemaVersion", "lanes"],
37
+ properties: {
38
+ schemaVersion: { type: "integer", const: factsSchemaVersion("lanes"), description: "本份数据的形版本;读方不认识的版本整份拒读。" },
39
+ lanes: {
40
+ type: "array",
41
+ minItems: 1,
42
+ "x-uniqueKey": ["lane"],
43
+ description: "每条车道一行,行序 = 车道表次序。",
44
+ items: {
45
+ type: "object",
46
+ additionalProperties: false,
47
+ required: ["lane", "tenantSeparation", "isolation", "requiredEnv", "requiredSecretEnv"],
48
+ properties: {
49
+ lane: { type: "string", description: "车道词,即 REMOTE_EXEC 的取值。" },
50
+ tenantSeparation: { type: "string", enum: TENANT_SEPARATION_WORDS, description: "supported = 可在多租户部署(REQUIRE_PRINCIPAL=true)上用;single-user-only = 只给单用户部署,多租户部署选它起服即拒。" },
51
+ isolation: { type: "string", enum: LANE_ISOLATION_WORDS, description: "supported = 手跑在 OS 级隔离边界里(独立沙箱);unsupported = 手跑在没有 OS 级隔离的地方(服务容器本身、远端主机、设备)。" },
52
+ requiredEnv: envNames("选这条车道时引擎起服必须读到的非密键(缺任一 ⇒ 起服拒)。"),
53
+ requiredSecretEnv: envNames("选这条车道时引擎起服必须读到的密钥键(缺任一 ⇒ 起服拒;值由运维自备)。"),
54
+ },
55
+ },
56
+ },
57
+ },
58
+ };
59
+ export const SEALED_KEY_REQUIREMENTS = ["persist-across-restart", "shared-by-all-replicas", "writable", "whole-directory"];
60
+ export const SEALED_KEY_DIR_PATH_FORMS = ["absolute"];
61
+ const octal = (mode) => mode.toString(8).padStart(4, "0");
62
+ const SEALED_KEY_DIR_ENV = "SEALED_KEY_DIR";
63
+ export const SEALED_KEY_FACTS = {
64
+ schemaVersion: factsSchemaVersion("sealed-key"),
65
+ dirEnv: SEALED_KEY_DIR_ENV,
66
+ dirPath: SEALED_KEY_DIR_PATH_FORMS[0],
67
+ subdirs: [CHECKPOINT_CTX_KEY_SUBDIR],
68
+ dirMode: octal(SEALED_KEY_DIR_MODE),
69
+ fileMode: octal(OWNER_ONLY_FILE_MODE),
70
+ requirements: SEALED_KEY_REQUIREMENTS,
71
+ };
72
+ export const SEALED_KEY_FACTS_SCHEMA = {
73
+ $schema: FACTS_SCHEMA_DIALECT,
74
+ description: "引擎钥匙保管目录的安装契约:sealed 形模型钥匙的 X25519 钥匙对与停驻行凭据封签的钥匙都在这个目录里,私钥只存在这里。",
75
+ type: "object",
76
+ additionalProperties: false,
77
+ required: ["schemaVersion", "dirEnv", "dirPath", "subdirs", "dirMode", "fileMode", "requirements"],
78
+ properties: {
79
+ schemaVersion: { type: "integer", const: SEALED_KEY_FACTS.schemaVersion, description: "本份数据的形版本;读方不认识的版本整份拒读。" },
80
+ dirEnv: { type: "string", const: SEALED_KEY_FACTS.dirEnv, description: "安装器必须给引擎设的环境变量:值 = 保管目录的挂载位。" },
81
+ dirPath: { type: "string", enum: SEALED_KEY_DIR_PATH_FORMS, description: "absolute = 值必须是绝对路径(相对路径起服即拒;设了而目录建不了保管店也起服拒)。" },
82
+ subdirs: { type: "array", uniqueItems: true, items: { type: "string" }, description: "引擎在保管目录之下自建的子目录(随目录一起持久、一起共享)。" },
83
+ dirMode: { type: "string", const: SEALED_KEY_FACTS.dirMode, description: "引擎每次起服把保管目录设成的权限位(四位八进制);目录必须允许引擎进程改它的权限。" },
84
+ fileMode: { type: "string", const: SEALED_KEY_FACTS.fileMode, description: "引擎写钥匙文件时设的权限位(四位八进制)。" },
85
+ requirements: {
86
+ type: "array",
87
+ minItems: 1,
88
+ uniqueItems: true,
89
+ items: { type: "string", enum: SEALED_KEY_REQUIREMENTS },
90
+ description: "persist-across-restart = 目录跨进程重启保留(不然重启后封给旧钥匙的密文与停驻行凭据开不开);shared-by-all-replicas = 同一部署的每个副本挂同一份目录(多副本要支持多处读写的存储;不然 A 副本封的东西 B 副本开不开);" +
91
+ "writable = 引擎对目录可写(空目录起服时生成一把钥匙;只读挂载 ⇒ 建不了保管店);whole-directory = 持久与共享的单位是整个目录,含 subdirs 列出的子目录。",
92
+ },
93
+ },
94
+ };
95
+ //# sourceMappingURL=deploy-facts.js.map
@@ -9,7 +9,7 @@
9
9
  * ## 两根轴,每根轴一个读口(原始配置键只在这两个函数里被读)
10
10
  * · `principal` —— 运维的 `REQUIRE_PRINCIPAL` 声明({@link readPrincipalAxis})。
11
11
  * · `lane` —— `REMOTE_EXEC` 的归一车道词(`executionLaneOf`,认不出 ⇒ `undefined`,行必须 fail-closed)+ 那条车道的能力表行 +
12
- * 这份部署上执行环境的能力块(唯一作者 `capabilitiesFor`;k8s 的快照店是它的输入)+ 车道子旋钮(k8s 运行时类、隐式 host 尾臂记号)({@link readLaneAxis})。
12
+ * 这份部署上执行环境的能力块(唯一作者 `capabilitiesFor`;k8s 的快照店是它的输入)+ 车道子旋钮(k8s 运行时类)({@link readLaneAxis})。
13
13
  *
14
14
  * ## 轴列不是注释,是型
15
15
  * 每行的判官只收到它**声明**的那几根轴的事实({@link DeploymentShapeFacts}),读不到配置本身 —— 判官碰一根没声明的轴 = 编译红;
@@ -34,14 +34,14 @@ export interface PrincipalAxisFacts {
34
34
  /** 运维声明了 `REQUIRE_PRINCIPAL=true`。 */
35
35
  readonly declared: boolean;
36
36
  }
37
- /** `lane` 轴读的配置键:已装配的 `remoteExec` 里本表用得到的那几键(`ServiceConfig` 的判别联合每一臂结构上都满足)。 */
37
+ /** `lane` 轴读的配置键:**已合成**的 `remoteExec` 里本表用得到的那几键(`ServiceConfig` 的判别联合每一臂结构上都满足;车道必在 ——
38
+ * 没有声明的部署在执行车道合成步拒启)。`provider` 收开放串:手搓的部署形 / 外部输入上认不出的词 ⇒ 行在 `lane` 那一格 fail-closed。 */
38
39
  export interface LaneAxisInput {
39
- readonly remoteExec?: {
40
- readonly provider?: string | undefined;
40
+ readonly remoteExec: {
41
+ readonly provider: string;
41
42
  readonly runtimeClass?: string | undefined;
42
43
  readonly s3Snapshot?: unknown;
43
- readonly singleMachineDefault?: boolean | undefined;
44
- } | undefined;
44
+ };
45
45
  }
46
46
  /** `lane` 轴的事实。 */
47
47
  export interface LaneAxisFacts {
@@ -53,8 +53,6 @@ export interface LaneAxisFacts {
53
53
  readonly block: ExecutionEnvCapabilities | undefined;
54
54
  /** k8s 的 `runtimeClass`(别的车道 `undefined`)。 */
55
55
  readonly k8sRuntimeClass: string | undefined;
56
- /** host 车道值上带「单机形缺省」记号(唯一写者 = `config.ts` 三元链的隐式 host 尾臂;显式 `REMOTE_EXEC=host` 与文件覆写都不带)。 */
57
- readonly singleMachineDefault: boolean;
58
56
  }
59
57
  /** 轴全集(闭集)→ 读入形与事实型。加一根轴 = 在这里加一键 + {@link readAxis} 的穷举 switch 加一臂(漏一处即编译红)。 */
60
58
  interface AxisShapes {
@@ -99,8 +97,8 @@ export declare const DEPLOYMENT_SHAPE_PREDICATES: Readonly<{
99
97
  callerOwnsWorkerDisk: DeploymentShapePredicate<"lane" | "principal">;
100
98
  /** wire `executionLane.toolsOnThisHost` 与出厂 / 中心技能的 `baseDir`:只问文件系统同一性,与租户无关(出厂内容每个租户拿到同一份)。 */
101
99
  toolsOnThisHost: DeploymentShapePredicate<"lane">;
102
- /** `REMOTE_EXEC` 未设的进程内形(没有手)且单主:进程级消费者(hooks 命令、项目上下文本机读、卡批规则 root)看到的就是引擎自己的进程 cwd / env。 */
103
- inProcessSingleUser: DeploymentShapePredicate<"lane" | "principal">;
100
+ /** 无手形(声明 `none`;判据读执行环境块 `io`,不点名车道词)且单主:进程级消费者(hooks 命令、项目上下文本机读、卡批规则 root)看到的就是引擎自己的进程 cwd / env。 */
101
+ noHandsSingleUser: DeploymentShapePredicate<"lane" | "principal">;
104
102
  /** 任务层替部署声明宿主姿态(bypassPermissions 开写面 / host shell 继承整份环境)的射程:device 车道上跨租户宿主穿越结构性不存在(clay 裁定③)。 */
105
103
  taskHostPostureDeclarations: DeploymentShapePredicate<"lane" | "principal">;
106
104
  /** 写门走代理裁决(执行环境块 `hostLocalPaths` 为假:路径不是本 worker 盘上的文件);认不出的词 ⇒ 走代理(代理 slot 空 ⇒ 写门 fail-closed)。 */
@@ -121,8 +119,19 @@ export declare const DEPLOYMENT_SHAPE_PREDICATES: Readonly<{
121
119
  * 读者:boot `remote_exec_enabled.suspendable`。
122
120
  */
123
121
  suspendableHands: DeploymentShapePredicate<"lane">;
124
- /** 读者两处:`config.ts` 车道落点一行的 `source`(覆写之前)与 `boot/execution-env.ts` 的 `remote_exec_real_system.note`(覆写之后)—— 同一个记号、两个时刻。 */
125
- singleMachineDefaultLane: DeploymentShapePredicate<"lane">;
122
+ /**
123
+ * 即时回退的工作区是否活过一次执行 —— run 外回退口(`POST /v1/sessions/:id/rewind-files`)写下的文件要落在一棵下一次执行就从它开始的工作区里;
124
+ * 工作区随执行结束一起没了(或下一次执行从别处重建它)的部署上,引擎照样恢复、台账照样报「恢复了」,结果却到不了任何人手里(静默的写面 fail-open)。
125
+ * 按车道穷举(新车道 = 编译红;认不出的车道 ⇒ 不成立):
126
+ * · `host`:调用方声明的项目目录 ⇔ 车道能力 `callerCwd` 在这台部署上成立(单主;多租形上每个任务一只用完即删的目录)。单只会话还要本进程登记过它的 cwd、且那只目录实在 —— 那一半是口的 409,不是部署形;
127
+ * · `device` / `ssh` / `adb`:一台常驻的真机器,环境拆毁 = 断连,不删文件;
128
+ * · `local-docker`(拆毁 = `docker rm -f`)/ `e2b`(拆毁 = 杀 VM):每个任务一只新环境;
129
+ * · `k8s`:不开工作区持久化 ⇒ 一次性 pod;开了 ⇒ 下一次执行从快照店恢复工作区,而工作区填充链(恢复后的附件填充)与拆毁时的快照持久化都还没纳入回退用途
130
+ * (回退那一次取环境照样填充附件、存新快照,存失败也进不了回退的应答)⇒ 本版不成立,重开另票(用途感知的填充 + 持久化结果进回退应答);
131
+ * · `none`:没有执行环境(能力事实先判无手车道,这里照样表态)。
132
+ * 读者:能力事实 `sessionRewindFiles`(能力位与该口的 501 同读这一行)。
133
+ */
134
+ rewindableWorkspace: DeploymentShapePredicate<"lane" | "principal">;
126
135
  }>;
127
136
  export {};
128
137
  //# sourceMappingURL=deployment-shape.d.ts.map
@@ -1,16 +1,15 @@
1
- import { capabilitiesFor, executionLaneCaps, executionLaneOf, handsOnWorkerFilePlane } from "./execution-lane-caps.js";
1
+ import { capabilitiesFor, executionLaneCaps, executionLaneOf, handsOnWorkerFilePlane, laneWiresExecutionEnv } from "./execution-lane-caps.js";
2
2
  function readPrincipalAxis(deployment) {
3
3
  return { declared: deployment.requirePrincipal === true };
4
4
  }
5
5
  function readLaneAxis(deployment) {
6
6
  const declaration = deployment.remoteExec;
7
- const lane = executionLaneOf(declaration?.provider);
7
+ const lane = executionLaneOf(declaration.provider);
8
8
  return {
9
9
  lane,
10
10
  caps: lane === undefined ? undefined : executionLaneCaps(lane),
11
11
  block: capabilitiesFor(deployment),
12
- k8sRuntimeClass: lane === "k8s" ? declaration?.runtimeClass : undefined,
13
- singleMachineDefault: lane === "host" && declaration?.singleMachineDefault === true,
12
+ k8sRuntimeClass: lane === "k8s" ? declaration.runtimeClass : undefined,
14
13
  };
15
14
  }
16
15
  function readAxis(axis, deployment) {
@@ -52,7 +51,7 @@ export const DEPLOYMENT_SHAPE_PREDICATES = Object.freeze({
52
51
  callerCwd: createPredicate(["lane", "principal"], "车道 × 租户 / 设备归属:调用方送来的 cwd(与 settings.env)被尊重 —— host 车道且单主,或 device 车道。", ({ lane, principal }) => lane.caps !== undefined && capabilityHolds(lane.caps.callerCwd, principal)),
53
52
  callerOwnsWorkerDisk: createPredicate(["lane", "principal"], "车道 × 租户:手就在本 worker 的盘上且部署只有一个主人 —— 这块盘上的路径就是调用方自己的。", ({ lane, principal }) => lane.lane !== undefined && handsOnWorkerFilePlane(lane.lane) && !principal.declared),
54
53
  toolsOnThisHost: createPredicate(["lane"], "车道:工具跑的那台机器就是本进程这台(手挂上了且文件平面在本 worker 盘上;车道列 handsOnWorkerFilePlane)。", ({ lane }) => lane.lane !== undefined && handsOnWorkerFilePlane(lane.lane)),
55
- inProcessSingleUser: createPredicate(["lane", "principal"], "车道 × 租户:进程内车道(REMOTE_EXEC 未设)且部署只有一个主人。", ({ lane, principal }) => lane.lane === "in-process" && !principal.declared),
54
+ noHandsSingleUser: createPredicate(["lane", "principal"], "车道 × 租户:无手车道(声明 none;车道列 laneWiresExecutionEnv 为假)且部署只有一个主人。", ({ lane, principal }) => lane.lane !== undefined && !laneWiresExecutionEnv(lane.lane) && !principal.declared),
56
55
  taskHostPostureDeclarations: createPredicate(["lane", "principal"], "车道 × 租户 / 设备归属:任务层可以替部署声明宿主姿态 —— device 车道(发起者自己的设备),或单主部署。", ({ lane, principal }) => lane.lane === "device" || !principal.declared),
57
56
  sandboxPathAdjudication: createPredicate(["lane"], "车道:写门的路径事实要经代理到执行环境里取(文件平面不在本 worker 盘上;认不出的车道也走代理)。", ({ lane }) => lane.block === undefined || !lane.block.hostLocalPaths),
58
57
  sandboxSendUserFile: createPredicate(["lane", "principal"], "车道 × 租户:SendUserFile 的沙箱直传腿可以挂(沙箱盘 = 租户自己的任务工作区,或共享真机上的单主部署)。", ({ lane, principal }) => lane.caps !== undefined && capabilityHolds(lane.caps.sandboxSendUserFile, principal)),
@@ -67,6 +66,25 @@ export const DEPLOYMENT_SHAPE_PREDICATES = Object.freeze({
67
66
  return runtimeClass.startsWith("kata") || VM_ISOLATION_RUNTIME_CLASSES.has(runtimeClass);
68
67
  }),
69
68
  suspendableHands: createPredicate(["lane"], "车道:执行环境可挂起(e2b;k8s 以配了 S3 工作区快照店为前提)。", ({ lane }) => lane.block?.suspendable === true),
70
- singleMachineDefaultLane: createPredicate(["lane"], "车道:host 车道是单机形缺省落点(REMOTE_EXEC 未设 ∧ CONFIG_PROVIDER=local,没人点名)。", ({ lane }) => lane.singleMachineDefault),
69
+ rewindableWorkspace: createPredicate(["lane", "principal"], "车道 × 租户:即时回退的工作区活过一次执行 —— 单主 host、device、ssh、adb 成立;多租 host、local-docker、e2b 每个任务重建工作区;k8s 的工作区填充与快照持久化尚未纳入回退。", ({ lane, principal }) => {
70
+ switch (lane.lane) {
71
+ case "host":
72
+ return lane.caps !== undefined && capabilityHolds(lane.caps.callerCwd, principal);
73
+ case "device":
74
+ case "ssh":
75
+ case "adb":
76
+ return true;
77
+ case "k8s":
78
+ case "local-docker":
79
+ case "e2b":
80
+ case "none":
81
+ case undefined:
82
+ return false;
83
+ default: {
84
+ const unhandled = lane.lane;
85
+ throw new Error(`rewindableWorkspace: no ruling for lane ${String(unhandled)}`);
86
+ }
87
+ }
88
+ }),
71
89
  });
72
90
  //# sourceMappingURL=deployment-shape.js.map
@@ -38,6 +38,7 @@
38
38
  import http from "node:http";
39
39
  import { type DeviceOwner, type DeviceStore } from "./device-store.js";
40
40
  import type { DeviceEnrollment, DeviceRejection } from "./device-enrollment.js";
41
+ import { type CidrSet } from "./net-address.js";
41
42
  import { type DeviceChunkKind, type DeviceInstructionArgsByKind, type DeviceInstructionKind, type DeviceInstructionOutcome } from "./device-ws-protocol.js";
42
43
  /** 交给调用方的一片上行流(`data` 已从 base64 解回字节)。 */
43
44
  export interface DeviceChunkDelivery {
@@ -159,10 +160,14 @@ export interface DeviceWsHubOptions {
159
160
  chunkBufferMaxBytes?: number;
160
161
  /** codex R1-F3:本副本**未鉴权**连接的并发帽(超额在 upgrade 阶段就 503 拒)。 */
161
162
  maxPreAuthConnections?: number;
162
- /** codex R1-F3:单来源地址的未鉴权连接并发帽。[ref]([ref]):字面 `off` = 显式停用该层——
163
- * 帽键是裸 remoteAddress,XFF 反代 / 公司 NAT 部署形把全员折叠成单键,这层从公平层退化成
164
- * 「全员共享一份预算」;停层后全局帽(`maxPreAuthConnections`)照常兜底。 */
163
+ /** codex R1-F3:单来源地址的未鉴权连接并发帽。[ref]([ref]):字面 `off` = 显式停用该层;停层后全局帽
164
+ * (`maxPreAuthConnections`)照常兜底。帽键 = 真实对端的规范形({@link readPreAuthRemoteKey}):名单
165
+ * {@link trustedProxyCidrs} 空时就是 socket 对端 —— 反代 / 公司 NAT 后全员同一 socket 对端,这层是「全员共享一份预算」;
166
+ * 把自己的反代写进名单,这层就按反代转来的真实来源计。 */
165
167
  maxPreAuthConnectionsPerRemote?: number | "off";
168
+ /** [ref]:可信代理名单(CIDR 闭集;env `DEVICE_TRUSTED_PROXY_CIDRS`,配置层逐项校验)。缺省空 = 不读任何代理头(帽键 =
169
+ * socket 对端,今日行为)。socket 对端落在名单内才读 `X-Forwarded-For`。坏项构造时抛(装配缝,与 helloAck 界同姿势)。 */
170
+ trustedProxyCidrs?: readonly string[];
166
171
  }
167
172
  export interface DeviceWsHub {
168
173
  /** 把 `GET /v1/device/ws` 的 upgrade 处理器挂到裸 `http.Server` 上。 */
@@ -204,5 +209,45 @@ export interface DeviceWsHub {
204
209
  declaredSupports(deviceId: string): ReadonlySet<DeviceInstructionKind> | undefined;
205
210
  close(): Promise<void>;
206
211
  }
212
+ /** per-remote 帽键的来源(闭集;指标 `device_preauth_key_total{source}` 与 cap-hit 行 `keySource` 同一张表)。 */
213
+ export declare const DEVICE_PREAUTH_KEY_SOURCES: readonly ["socket", "xff", "fallback"];
214
+ export type DevicePreAuthKeySource = (typeof DEVICE_PREAUTH_KEY_SOURCES)[number];
215
+ /** 对端是可信代理而转发头展不开的缘由(闭集;warn `device_preauth_forwarded_unusable{reason}`)。 */
216
+ export declare const DEVICE_FORWARDED_UNUSABLE_REASONS: readonly ["absent", "malformed", "all_trusted", "too_many_headers"];
217
+ export type DeviceForwardedUnusableReason = (typeof DEVICE_FORWARDED_UNUSABLE_REASONS)[number];
218
+ export type DevicePreAuthKey = {
219
+ readonly key: string;
220
+ readonly source: "socket" | "xff";
221
+ } | {
222
+ readonly key: string;
223
+ readonly source: "fallback";
224
+ readonly reason: DeviceForwardedUnusableReason;
225
+ };
226
+ /**
227
+ * 可信对端的升级请求最多带几行头,汇聚端还认它的 `X-Forwarded-For`。node 对头行数超过它的上限(`server.maxHeadersCount`,缺省约 1000 行)
228
+ * 的请求要么**静默**丢掉多余的头、要么直接答 431(版本行为)。丢头那一形里,反代追加在末尾的那一行 XFF 正在尾部,丢了它,剩下的就只有
229
+ * 客户端自己垫在前面的那一行 —— 所以行数到这个数(或运维给 server 设的更低上限)⇒ 不采 XFF(回落 `too_many_headers`);答 431 那一形里
230
+ * 请求到不了这里。两形下垫在前面的 XFF 都不会成为帽键。一次设备握手连同反代自己加的头远不到 100 行;这个数刻意远低于 node 的缺省上限,
231
+ * 不随 node 版本漂。
232
+ */
233
+ export declare const DEVICE_PREAUTH_FORWARDED_HEADER_LINES_MAX = 100;
234
+ /** 转发头的一次读数(只在对端可信时取):`header` = node 合并后的 `X-Forwarded-For`;`complete` = 请求头行数低于可信读数上限。 */
235
+ export interface ForwardedForReading {
236
+ readonly header: string | readonly string[] | undefined;
237
+ readonly complete: boolean;
238
+ }
239
+ /**
240
+ * [ref]:per-remote 帽键 = **本连接真实对端的规范形**(`canonicalAddress`;IPv4-mapped 折成点分 IPv4 —— 同一台主机直连与经代理
241
+ * 是同一个键,不是两份名额)。
242
+ *
243
+ * 真实对端只有一个来源 = socket 对端;唯一的展开:socket 对端落在可信代理名单内 ⇒ 读 `X-Forwarded-For`(node 把重复头按到达序
244
+ * 以 `, ` 合并 = 同一张列表),**自右向左**逐项:名单内 = 又一层自己的代理,继续左移;第一个名单外的地址 = 键。选中项**以左**是
245
+ * 客户端自己写的段,不解析 —— 往那里塞什么都改不了键,也逼不出回落。
246
+ *
247
+ * 展不开(头行数到顶 / 头缺席 / 某项不是地址 / 全在名单内)⇒ 键 = socket 对端,`source=fallback`。🔴 这不是 fail-open,**不走 `recordFailOpen`**:
248
+ * 回落键把整只代理折成一个键,比展开更严(收紧方向),与名单空的今日行为同键;调用方另打一行带 reason 的 warn 指路。
249
+ * 名单外的对端:转发头读口一次都不调用(惰性 `readForwardedFor`;伪造 XFF 零效果)。不读 `Forwarded` / `X-Real-IP` / PROXY protocol —— 对端只有这一种展开。
250
+ */
251
+ export declare function readPreAuthRemoteKey(peer: string | undefined, readForwardedFor: () => ForwardedForReading, trusted: CidrSet): DevicePreAuthKey;
207
252
  export declare function createDeviceWsHub(options: DeviceWsHubOptions): DeviceWsHub;
208
253
  //# sourceMappingURL=device-ws-hub.d.ts.map
@@ -1,8 +1,10 @@
1
1
  import http from "node:http";
2
2
  import { createHash } from "node:crypto";
3
+ import { isIP } from "node:net";
3
4
  import { WebSocketServer } from "ws";
4
5
  import { DEVICE_DRAINING_CODE, DEVICE_ERROR_CODES, DEVICE_ERROR_STATUS, assertDeviceIdShape, } from "./device-store.js";
5
6
  import { MAX_TIMER_DELAY_MS } from "./config-types.js";
7
+ import { canonicalAddress, createTrustedProxySet } from "./net-address.js";
6
8
  import { DEVICE_HELLO_ACK_BOUNDS, DEVICE_MIN_PROTOCOL_VERSION, DEVICE_WS_LIMITS, DEVICE_WS_PATH, DEVICE_PROTOCOL_VERSION, asInstructionKind, buildHelloSignaturePayload, deviceHelloAckNumberFlaw, formatGeneration, mintChallengeNonce, mintInstructionId, parseDeviceFrameText, verifyHelloSignature, } from "./device-ws-protocol.js";
7
9
  const OUTCOME_UNKNOWN_SENTENCE = "outcome unknown — the command may have already executed on the device; verify its effect before re-running";
8
10
  const SETTLED_MEMO_MAX = 512;
@@ -63,6 +65,41 @@ function assertHelloAckNumbersInBounds(values) {
63
65
  }
64
66
  }
65
67
  }
68
+ export const DEVICE_PREAUTH_KEY_SOURCES = ["socket", "xff", "fallback"];
69
+ export const DEVICE_FORWARDED_UNUSABLE_REASONS = ["absent", "malformed", "all_trusted", "too_many_headers"];
70
+ export const DEVICE_PREAUTH_FORWARDED_HEADER_LINES_MAX = 100;
71
+ export function readPreAuthRemoteKey(peer, readForwardedFor, trusted) {
72
+ const raw = peer ?? "unknown";
73
+ const socketKey = canonicalAddress(raw) ?? raw;
74
+ if (!trusted.has(socketKey))
75
+ return { key: socketKey, source: "socket" };
76
+ const reading = readForwardedFor();
77
+ if (!reading.complete)
78
+ return { key: socketKey, source: "fallback", reason: "too_many_headers" };
79
+ const header = typeof reading.header === "string" ? reading.header : reading.header?.join(",");
80
+ if (header === undefined || header.replace(/[ \t]/g, "") === "")
81
+ return { key: socketKey, source: "fallback", reason: "absent" };
82
+ const hops = header.split(",");
83
+ for (let i = hops.length - 1; i >= 0; i--) {
84
+ const hop = forwardedHopAddress(hops[i]);
85
+ if (hop === undefined)
86
+ return { key: socketKey, source: "fallback", reason: "malformed" };
87
+ if (!trusted.has(hop))
88
+ return { key: hop, source: "xff" };
89
+ }
90
+ return { key: socketKey, source: "fallback", reason: "all_trusted" };
91
+ }
92
+ function forwardedHopAddress(hop) {
93
+ const t = hop.replace(/^[ \t]+|[ \t]+$/g, "");
94
+ if (t.startsWith("[")) {
95
+ const m = /^\[([^\]]*)\](?::\d{1,5})?$/.exec(t);
96
+ return m === null || isIP(m[1]) !== 6 ? undefined : canonicalAddress(m[1]);
97
+ }
98
+ const withPort = /^([^:]+):\d{1,5}$/.exec(t);
99
+ if (withPort !== null)
100
+ return isIP(withPort[1]) === 4 ? withPort[1] : undefined;
101
+ return canonicalAddress(t);
102
+ }
66
103
  export function createDeviceWsHub(options) {
67
104
  const { store, enrollment, replicaId, logger, metrics } = options;
68
105
  const heartbeatIntervalMs = options.heartbeatIntervalMs ?? 15_000;
@@ -81,6 +118,7 @@ export function createDeviceWsHub(options) {
81
118
  const chunkBufferMaxBytes = options.chunkBufferMaxBytes ?? 2 * 1024 * 1024;
82
119
  const maxPreAuthConnections = options.maxPreAuthConnections ?? 64;
83
120
  const maxPreAuthConnectionsPerRemote = options.maxPreAuthConnectionsPerRemote ?? 8;
121
+ const trustedProxies = createTrustedProxySet(options.trustedProxyCidrs ?? []);
84
122
  const wss = new WebSocketServer({ noServer: true, maxPayload: DEVICE_WS_LIMITS.maxFrameBytes });
85
123
  const conns = new Map();
86
124
  const allConns = new Set();
@@ -757,6 +795,10 @@ export function createDeviceWsHub(options) {
757
795
  }, DEVICE_WS_LIMITS.handshakeDeadlineMs);
758
796
  sendServerFrame(conn, { t: "challenge", nonce: conn.nonce, protocolVersion: DEVICE_PROTOCOL_VERSION });
759
797
  }
798
+ function forwardedHeaderLineCeiling(server) {
799
+ const cap = server.maxHeadersCount;
800
+ return typeof cap === "number" && cap > 0 ? Math.min(DEVICE_PREAUTH_FORWARDED_HEADER_LINES_MAX, cap) : DEVICE_PREAUTH_FORWARDED_HEADER_LINES_MAX;
801
+ }
760
802
  function attach(server) {
761
803
  server.on("upgrade", (req, socket, head) => {
762
804
  const path = (req.url ?? "/").split("?")[0];
@@ -764,7 +806,11 @@ export function createDeviceWsHub(options) {
764
806
  return refuseUpgrade(socket, 404);
765
807
  if (draining || closed)
766
808
  return refuseUpgrade(socket, 503);
767
- const remoteKey = req.socket.remoteAddress ?? "unknown";
809
+ const keyed = readPreAuthRemoteKey(req.socket.remoteAddress, () => ({ header: req.headers["x-forwarded-for"], complete: req.rawHeaders.length / 2 < forwardedHeaderLineCeiling(server) }), trustedProxies);
810
+ const remoteKey = keyed.key;
811
+ metrics?.inc("device_preauth_key_total", { source: keyed.source });
812
+ if (keyed.source === "fallback")
813
+ logger?.warn("device_preauth_forwarded_unusable", { reason: keyed.reason });
768
814
  const perRemoteCount = preAuthByRemote.get(remoteKey) ?? 0;
769
815
  const globalHit = preAuthCount >= maxPreAuthConnections;
770
816
  const perRemoteHit = maxPreAuthConnectionsPerRemote !== "off" && perRemoteCount >= maxPreAuthConnectionsPerRemote;
@@ -772,7 +818,7 @@ export function createDeviceWsHub(options) {
772
818
  const arm = globalHit ? (perRemoteHit ? "both" : "global") : "per_remote";
773
819
  metrics?.inc("device_preauth_refused_total", { arm });
774
820
  logger?.warn("device_preauth_cap_hit", {
775
- remoteKey, arm, preAuthCount, cap: maxPreAuthConnections, perRemoteCount, perRemoteCap: maxPreAuthConnectionsPerRemote,
821
+ remoteKey, keySource: keyed.source, arm, preAuthCount, cap: maxPreAuthConnections, perRemoteCount, perRemoteCap: maxPreAuthConnectionsPerRemote,
776
822
  });
777
823
  return refuseUpgrade(socket, 503);
778
824
  }
@@ -1,5 +1,5 @@
1
1
  import type { ImageCapabilities } from "./plugins/store-contracts.js";
2
- import type { RemoteExecProvider } from "./execution-lane-caps.js";
2
+ import type { ExecutionLane } from "./execution-lane-caps.js";
3
3
  export interface SandboxEnvFacts {
4
4
  profile?: string;
5
5
  capabilities?: string[];
@@ -54,7 +54,7 @@ export declare function buildEnvFacts(opts: {
54
54
  * codex 复审 medium:k8s 必须按**有效快照能力**分叉,不能只看车道名——s3Snapshot 未配=park-only,
55
55
  * resume 是全新 pod 且**工作区不恢复**,「文件已从快照恢复」那句会让模型信赖不存在的文件(比缺席
56
56
  * 更糟的谎)。 */
57
- export declare function resumeFactsForLane(provider: RemoteExecProvider | undefined, // 车道词 = settings-schema 词表正本(经本仓读口取型,不手抄;表加词 ⇒ 下方穷举 switch 编译红)
57
+ export declare function resumeFactsForLane(provider: ExecutionLane, // 车道词 = settings-schema 词表正本(经本仓读口取型,不手抄;表加词 ⇒ 下方穷举 switch 编译红)
58
58
  caps?: {
59
59
  k8sSnapshot?: boolean;
60
60
  }): SandboxEnvFacts["resumeFacts"] | undefined;
@@ -73,6 +73,8 @@ export declare function scratchpadSessionSegment(sessionId: string): string;
73
73
  * intermediate artifacts survive across turns/resume legs). Exported as the single source both the envFacts
74
74
  * composer (below) and the future createFsWriteGatePolicy `exemptDirs` wiring ([ref]①, 1.290) must use. */
75
75
  export declare function scratchpadDirFor(localDataRoot: string, sessionId: string): string;
76
+ /** 所有会话段的父目录 `<localDataRoot>/scratchpad`(段路径、过期清扫与一次性迁移 M39 的名册同读这一只)。 */
77
+ export declare function scratchpadRootFor(localDataRoot: string): string;
76
78
  /** Resolve + CREATE the session scratchpad dir (mkdir -p, idempotent). Returns the path, or undefined when
77
79
  * creation fails (honest-facts posture: never advertise a directory that does not exist — same class as
78
80
  * egress/pkgSource "don't declare what you don't know"). Lifecycle: the reaper primitives live below —
@@ -149,7 +151,7 @@ export declare function screenShellScratchpadDir(raw: unknown, opts: {
149
151
  * 就是凭空多一条 400)。只判其一会留一条**跨请求**的洞:一条请求供一只合法壳 scratchpad 把判据引开、
150
152
  * 同时把 cwd 指进自算那只,放行后 cwd 坐进会话表,下一条不带路径字段的请求回落自算形、死在引擎构造期,
151
153
  * 而它根本没送过 cwd(codex r2 [medium] 实证);
152
- * · **`in-process` 车道(provider 未设)不在射程**:那条腿的门根是**进程自己的 cwd**,与请求字段无关 ——
154
+ * · **无手的 `none` 车道不在射程**:那条腿的门根是**进程自己的 cwd**,与请求字段无关 ——
153
155
  * 对着一个请求字段拒一件不是它造成的事,是把诊断指向错的地方(如实登记,不假装覆盖)。
154
156
  */
155
157
  export declare function scratchpadCoveringTaskRoot(args: {
@@ -183,7 +185,7 @@ export declare function sweepStaleScratchpads(localDataRoot: string, opts: {
183
185
  }): Promise<number>;
184
186
  /** Map the exec-lane posture to the egress fact (the model must know when downloads can't work). */
185
187
  export declare function egressForRemoteExec(remoteExec: {
186
- provider?: string;
188
+ provider: string;
187
189
  allowInternetAccess?: boolean;
188
- } | undefined): "none" | "full" | undefined;
190
+ }): "none" | "full" | undefined;
189
191
  //# sourceMappingURL=env-facts.d.ts.map