@sema-agent/server 7.132.0 → 7.134.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 (473) hide show
  1. package/MIGRATION.md +353 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +301 -64
  5. package/deploy/sema-up/README.md +35 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
  11. package/deploy/sema-up/chart/templates/server.yaml +19 -2
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/deploy/sema-up/stack/compose.yaml +3 -0
  15. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  16. package/dist/adoption/plan.d.ts +3 -2
  17. package/dist/adoption/plan.js +7 -5
  18. package/dist/adoption/runner.js +3 -10
  19. package/dist/adoption/sql.d.ts +3 -2
  20. package/dist/adoption/sql.js +3 -5
  21. package/dist/adoption/wire.d.ts +4 -1
  22. package/dist/adoption/wire.js +1 -0
  23. package/dist/approval-ask-audit-store.d.ts +32 -14
  24. package/dist/approval-ask-audit-store.js +272 -74
  25. package/dist/approval-ask-machine.d.ts +15 -0
  26. package/dist/approval-ask-machine.js +6 -0
  27. package/dist/approval-ask-retention.d.ts +136 -0
  28. package/dist/approval-ask-retention.js +102 -0
  29. package/dist/approval-card.d.ts +83 -23
  30. package/dist/approval-card.js +45 -15
  31. package/dist/approval-content-kind.d.ts +5 -2
  32. package/dist/approval-content-kind.js +16 -3
  33. package/dist/approval-deny-reasons.d.ts +1 -1
  34. package/dist/approval-gate-currency.d.ts +72 -0
  35. package/dist/approval-gate-currency.js +94 -0
  36. package/dist/approval.d.ts +15 -0
  37. package/dist/approval.js +55 -17
  38. package/dist/audit.d.ts +27 -10
  39. package/dist/audit.js +12 -16
  40. package/dist/bake-runner/main.js +3 -2
  41. package/dist/boot/coordinators.d.ts +6 -1
  42. package/dist/boot/coordinators.js +6 -3
  43. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  44. package/dist/boot/execution-env.js +9 -7
  45. package/dist/boot/execution-lane.js +11 -0
  46. package/dist/boot/leader.d.ts +2 -0
  47. package/dist/boot/leader.js +4 -1
  48. package/dist/boot/memory-boundary.js +2 -2
  49. package/dist/boot/memory-consolidation.d.ts +5 -4
  50. package/dist/boot/memory-consolidation.js +7 -6
  51. package/dist/boot/org-delivery.d.ts +28 -0
  52. package/dist/boot/org-delivery.js +20 -0
  53. package/dist/boot/read-deny-anchor-audit.js +2 -2
  54. package/dist/boot/reapers.d.ts +3 -0
  55. package/dist/boot/reapers.js +21 -1
  56. package/dist/boot/resolve-spec.d.ts +3 -0
  57. package/dist/boot/resolve-spec.js +60 -81
  58. package/dist/boot/runner-deps.d.ts +18 -5
  59. package/dist/boot/runner-deps.js +10 -0
  60. package/dist/boot/session-faces.d.ts +1 -0
  61. package/dist/boot/session-faces.js +4 -2
  62. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  63. package/dist/boot/stage-06-runners.d.ts +6 -3
  64. package/dist/boot/stage-06-runners.js +20 -4
  65. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  66. package/dist/boot/stage-07-capability-layer.js +24 -3
  67. package/dist/boot/stage-08-reapers.d.ts +4 -1
  68. package/dist/boot/stage-08-reapers.js +2 -2
  69. package/dist/boot/stage-09-leader.d.ts +5 -1
  70. package/dist/boot/stage-09-leader.js +2 -2
  71. package/dist/boot/stage-10-http-server.d.ts +5 -1
  72. package/dist/boot/stage-10-http-server.js +6 -6
  73. package/dist/boot/stores.d.ts +8 -0
  74. package/dist/boot/stores.js +10 -14
  75. package/dist/boot/web-admin.d.ts +10 -0
  76. package/dist/boot/web-admin.js +162 -65
  77. package/dist/boot/workflow-orchestration.d.ts +2 -0
  78. package/dist/boot/workflow-orchestration.js +2 -1
  79. package/dist/brain.js +8 -3
  80. package/dist/breaker-key.d.ts +6 -0
  81. package/dist/breaker-key.js +29 -0
  82. package/dist/budget.js +5 -1
  83. package/dist/caller-text-echo.d.ts +11 -6
  84. package/dist/caller-text-echo.js +10 -12
  85. package/dist/canonical-json.d.ts +2 -41
  86. package/dist/canonical-json.js +2 -13
  87. package/dist/capabilities/center-plugins.d.ts +7 -0
  88. package/dist/capabilities/center-plugins.js +1 -1
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +21 -0
  93. package/dist/capabilities/hands-lane.js +10 -0
  94. package/dist/capabilities/mcp-probe.d.ts +36 -4
  95. package/dist/capabilities/mcp-probe.js +29 -6
  96. package/dist/capabilities/scenarios.d.ts +63 -7
  97. package/dist/capabilities/scenarios.js +39 -7
  98. package/dist/capability-facts.d.ts +36 -4
  99. package/dist/capability-facts.js +30 -4
  100. package/dist/center-config-tier.d.ts +69 -0
  101. package/dist/center-config-tier.js +42 -0
  102. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  103. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  104. package/dist/checkpoint-identity.d.ts +16 -0
  105. package/dist/checkpoint-identity.js +19 -0
  106. package/dist/config-catalog.d.ts +17 -10
  107. package/dist/config-catalog.js +43 -28
  108. package/dist/config-d-migration.d.ts +3 -1
  109. package/dist/config-d-migration.js +2 -2
  110. package/dist/config-dir-trust.d.ts +114 -0
  111. package/dist/config-dir-trust.js +388 -0
  112. package/dist/config-invariants.d.ts +18 -5
  113. package/dist/config-invariants.js +35 -3
  114. package/dist/config-provider.d.ts +6 -1
  115. package/dist/config-provider.js +6 -2
  116. package/dist/config-types.d.ts +71 -14
  117. package/dist/config-types.js +8 -0
  118. package/dist/config.d.ts +13 -0
  119. package/dist/config.js +121 -59
  120. package/dist/delegated-session-owner.d.ts +185 -0
  121. package/dist/delegated-session-owner.js +119 -0
  122. package/dist/device-protocol.d.ts +5 -3
  123. package/dist/device-protocol.js +1 -1
  124. package/dist/device-ws-hub.js +21 -2
  125. package/dist/device-ws-protocol.d.ts +70 -6
  126. package/dist/device-ws-protocol.js +50 -23
  127. package/dist/elicitation.js +3 -2
  128. package/dist/entry-problems.d.ts +34 -0
  129. package/dist/entry-problems.js +14 -0
  130. package/dist/execution-lane-caps.d.ts +49 -10
  131. package/dist/execution-lane-caps.js +43 -4
  132. package/dist/field-conflict.d.ts +44 -0
  133. package/dist/field-conflict.js +21 -0
  134. package/dist/file-history-disclosure.d.ts +34 -5
  135. package/dist/file-history-disclosure.js +2 -2
  136. package/dist/fleet/fleet-bus.d.ts +84 -6
  137. package/dist/fleet/fleet-bus.js +42 -9
  138. package/dist/hooks/classic-stations.d.ts +10 -5
  139. package/dist/hooks/classic-stations.js +4 -4
  140. package/dist/hooks/command-spawn.d.ts +57 -0
  141. package/dist/hooks/command-spawn.js +139 -0
  142. package/dist/hooks/hook-llm.js +2 -2
  143. package/dist/hooks/hook-runner.d.ts +127 -25
  144. package/dist/hooks/hook-runner.js +668 -287
  145. package/dist/hooks/hook-source.d.ts +44 -0
  146. package/dist/hooks/hook-source.js +40 -0
  147. package/dist/http/active-run-conflict.d.ts +5 -13
  148. package/dist/http/active-run-conflict.js +17 -27
  149. package/dist/http/admission.js +111 -60
  150. package/dist/http/approval-sweeps.js +58 -19
  151. package/dist/http/caller-trust.d.ts +77 -0
  152. package/dist/http/caller-trust.js +143 -0
  153. package/dist/http/checkpoint-ctx.d.ts +173 -18
  154. package/dist/http/checkpoint-ctx.js +171 -12
  155. package/dist/http/claimed-run.d.ts +4 -3
  156. package/dist/http/device-placement.d.ts +2 -4
  157. package/dist/http/device-placement.js +2 -1
  158. package/dist/http/dispatch.js +13 -7
  159. package/dist/http/durable-run-leg.d.ts +4 -32
  160. package/dist/http/durable-run-leg.js +37 -12
  161. package/dist/http/idempotency.d.ts +2 -2
  162. package/dist/http/idempotency.js +2 -2
  163. package/dist/http/owner-access.d.ts +56 -0
  164. package/dist/http/owner-access.js +42 -0
  165. package/dist/http/principal-gate.d.ts +78 -27
  166. package/dist/http/principal-gate.js +64 -14
  167. package/dist/http/readiness.d.ts +11 -5
  168. package/dist/http/readiness.js +10 -3
  169. package/dist/http/refusal-body.d.ts +12 -0
  170. package/dist/http/refusal-body.js +11 -0
  171. package/dist/http/request-guards.d.ts +16 -32
  172. package/dist/http/request-guards.js +31 -30
  173. package/dist/http/resume-ctx-read.d.ts +50 -6
  174. package/dist/http/resume-ctx-read.js +33 -7
  175. package/dist/http/resume-legs.d.ts +5 -5
  176. package/dist/http/resume-legs.js +163 -91
  177. package/dist/http/retired-service-deps.d.ts +43 -0
  178. package/dist/http/retired-service-deps.js +18 -0
  179. package/dist/http/route-ctx.d.ts +44 -37
  180. package/dist/http/route-ctx.js +4 -0
  181. package/dist/http/route-table.js +2 -0
  182. package/dist/http/routes/a2a-serve.js +3 -4
  183. package/dist/http/routes/admin-config-refresh.js +1 -1
  184. package/dist/http/routes/admin-drain.js +1 -1
  185. package/dist/http/routes/admin-memory-optout.js +5 -1
  186. package/dist/http/routes/adoption.js +2 -9
  187. package/dist/http/routes/agents-roster.js +2 -3
  188. package/dist/http/routes/approvals-assistant.js +91 -56
  189. package/dist/http/routes/background.js +3 -2
  190. package/dist/http/routes/capabilities.js +20 -4
  191. package/dist/http/routes/config-catalog.d.ts +3 -3
  192. package/dist/http/routes/config-catalog.js +1 -1
  193. package/dist/http/routes/devices.js +3 -17
  194. package/dist/http/routes/diagnostics.d.ts +3 -3
  195. package/dist/http/routes/diagnostics.js +6 -2
  196. package/dist/http/routes/fleet.js +4 -4
  197. package/dist/http/routes/images.js +6 -7
  198. package/dist/http/routes/leader.js +1 -8
  199. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  200. package/dist/http/routes/mcp-reconnect.js +3 -2
  201. package/dist/http/routes/memory-bundle.js +1 -1
  202. package/dist/http/routes/memory-compliance.js +1 -1
  203. package/dist/http/routes/memory-consolidation.js +1 -1
  204. package/dist/http/routes/memory-origin.d.ts +1 -1
  205. package/dist/http/routes/memory-origin.js +1 -1
  206. package/dist/http/routes/memory-policy.d.ts +1 -1
  207. package/dist/http/routes/memory-policy.js +3 -2
  208. package/dist/http/routes/notify-wake.js +8 -21
  209. package/dist/http/routes/observability.js +2 -2
  210. package/dist/http/routes/principal-inbox.d.ts +39 -0
  211. package/dist/http/routes/principal-inbox.js +76 -0
  212. package/dist/http/routes/retention-ops.js +2 -9
  213. package/dist/http/routes/rules.js +9 -22
  214. package/dist/http/routes/runs.d.ts +5 -0
  215. package/dist/http/routes/runs.js +63 -115
  216. package/dist/http/routes/session-sync.d.ts +3 -2
  217. package/dist/http/routes/session-sync.js +53 -48
  218. package/dist/http/routes/sessions-list.d.ts +1 -1
  219. package/dist/http/routes/sessions-list.js +3 -4
  220. package/dist/http/routes/sessions.js +33 -43
  221. package/dist/http/routes/side-query.js +6 -4
  222. package/dist/http/routes/tasks.js +71 -30
  223. package/dist/http/routes/trace-usage.js +7 -9
  224. package/dist/http/routes/workflows.d.ts +351 -0
  225. package/dist/http/routes/workflows.js +153 -119
  226. package/dist/http/run-declared-families.d.ts +16 -0
  227. package/dist/http/run-declared-families.js +12 -0
  228. package/dist/http/send.d.ts +24 -3
  229. package/dist/http/send.js +14 -2
  230. package/dist/http/server.d.ts +23 -18
  231. package/dist/http/server.js +20 -15
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +4 -3
  234. package/dist/http/submit-ctx.js +23 -6
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +17 -10
  238. package/dist/index.d.ts +3 -1
  239. package/dist/index.js +1 -1
  240. package/dist/lane-home-probe.d.ts +78 -9
  241. package/dist/lane-home-probe.js +78 -12
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/leader/wire.d.ts +4 -0
  245. package/dist/leader/wire.js +8 -7
  246. package/dist/limit-refusal.d.ts +17 -5
  247. package/dist/limit-refusal.js +4 -1
  248. package/dist/main.js +1 -1
  249. package/dist/mcp-assertion-header.d.ts +31 -10
  250. package/dist/mcp-assertion-header.js +10 -3
  251. package/dist/memory-origin-fence.js +2 -2
  252. package/dist/memory-project-layer.d.ts +37 -0
  253. package/dist/memory-project-layer.js +46 -0
  254. package/dist/memory-scope.d.ts +23 -16
  255. package/dist/memory-scope.js +24 -8
  256. package/dist/memory-sync-client.d.ts +27 -13
  257. package/dist/memory-sync-client.js +107 -18
  258. package/dist/model-compat.d.ts +1 -1
  259. package/dist/model-entry-refusal.d.ts +9 -1
  260. package/dist/model-entry-refusal.js +6 -1
  261. package/dist/model-plane-face.d.ts +51 -0
  262. package/dist/model-plane-face.js +24 -0
  263. package/dist/model-provider.d.ts +5 -0
  264. package/dist/model-provider.js +4 -2
  265. package/dist/model-route-endpoint.d.ts +8 -11
  266. package/dist/model-route-endpoint.js +4 -7
  267. package/dist/model-route-env.d.ts +22 -0
  268. package/dist/model-route-env.js +2 -0
  269. package/dist/model-route-gap.d.ts +60 -30
  270. package/dist/model-route-gap.js +21 -15
  271. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  272. package/dist/observability/corrupt-read-seat.js +9 -0
  273. package/dist/observability/err-text.d.ts +6 -0
  274. package/dist/observability/err-text.js +18 -4
  275. package/dist/observability/fail-open.d.ts +35 -9
  276. package/dist/observability/fail-open.js +35 -9
  277. package/dist/observability/metrics.js +1 -0
  278. package/dist/observability/prompt-manifest.d.ts +22 -25
  279. package/dist/observability/prompt-manifest.js +54 -50
  280. package/dist/observability/tool-trace.js +9 -10
  281. package/dist/operator-ask.d.ts +10 -0
  282. package/dist/operator-ask.js +3 -0
  283. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  284. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  285. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  286. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  287. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  288. package/dist/orchestration/workflow-notify-journal.js +27 -34
  289. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  290. package/dist/orchestration/workflow-park-decision.js +119 -0
  291. package/dist/org-delivery-gate.d.ts +81 -0
  292. package/dist/org-delivery-gate.js +59 -0
  293. package/dist/panel-tool-names.d.ts +23 -0
  294. package/dist/panel-tool-names.js +8 -0
  295. package/dist/parked-decide.d.ts +43 -11
  296. package/dist/parked-decide.js +100 -51
  297. package/dist/parked-revive-surface.d.ts +9 -2
  298. package/dist/parked-revive-surface.js +11 -8
  299. package/dist/permission-rule-list.d.ts +1 -1
  300. package/dist/permission-rule-list.js +2 -2
  301. package/dist/permission-rule-vocab.d.ts +1 -23
  302. package/dist/permission-rule-vocab.js +0 -13
  303. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  304. package/dist/plugins/approval-ask-store-file.js +21 -0
  305. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  306. package/dist/plugins/approval-ask-store-memory.js +34 -2
  307. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  308. package/dist/plugins/approval-ask-store-sql.js +37 -1
  309. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  310. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  311. package/dist/plugins/blob-backend.d.ts +38 -25
  312. package/dist/plugins/blob-backend.js +29 -19
  313. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  314. package/dist/plugins/breaker-state-sql.js +4 -4
  315. package/dist/plugins/caching-session-store.d.ts +4 -1
  316. package/dist/plugins/caching-session-store.js +7 -3
  317. package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
  318. package/dist/plugins/checkpoint-store-sql.js +65 -3
  319. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  320. package/dist/plugins/file-history-store-sql.js +3 -1
  321. package/dist/plugins/file-run-store.d.ts +5 -13
  322. package/dist/plugins/file-run-store.js +9 -0
  323. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  324. package/dist/plugins/fork-routing-session-store.js +12 -1
  325. package/dist/plugins/host-platform.d.ts +2 -0
  326. package/dist/plugins/host-platform.js +2 -1
  327. package/dist/plugins/local-checkpoint-store.d.ts +15 -2
  328. package/dist/plugins/local-checkpoint-store.js +32 -1
  329. package/dist/plugins/local-session-store.d.ts +13 -10
  330. package/dist/plugins/local-session-store.js +23 -14
  331. package/dist/plugins/local-session-window.d.ts +45 -0
  332. package/dist/plugins/local-session-window.js +38 -0
  333. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  334. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  335. package/dist/plugins/mailbox-store-sql.js +77 -52
  336. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  337. package/dist/plugins/memory-run-store.d.ts +5 -13
  338. package/dist/plugins/memory-run-store.js +8 -0
  339. package/dist/plugins/one-time-migrations.d.ts +121 -5
  340. package/dist/plugins/one-time-migrations.js +332 -8
  341. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  342. package/dist/plugins/org-delivery-quota-store.js +228 -0
  343. package/dist/plugins/permission-rule-store-file.js +10 -6
  344. package/dist/plugins/permission-rule-store-sql.js +8 -8
  345. package/dist/plugins/pg-pool.js +39 -7
  346. package/dist/plugins/pg-session-storage.d.ts +18 -5
  347. package/dist/plugins/pg-session-storage.js +68 -23
  348. package/dist/plugins/remote-env-adb.d.ts +6 -12
  349. package/dist/plugins/remote-env-adb.js +12 -2
  350. package/dist/plugins/remote-env-device.d.ts +14 -7
  351. package/dist/plugins/remote-env-device.js +23 -15
  352. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  353. package/dist/plugins/remote-env-k8s.js +23 -5
  354. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  355. package/dist/plugins/remote-env-local-docker.js +12 -9
  356. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  357. package/dist/plugins/remote-env-ssh.js +17 -11
  358. package/dist/plugins/run-store-sql.d.ts +16 -14
  359. package/dist/plugins/run-store-sql.js +22 -2
  360. package/dist/plugins/schema-indexes.js +2 -0
  361. package/dist/plugins/send-user-file.js +2 -2
  362. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  363. package/dist/plugins/session-epoch-anchor.js +2 -3
  364. package/dist/plugins/session-ownership.d.ts +11 -0
  365. package/dist/plugins/session-ownership.js +11 -0
  366. package/dist/plugins/session-placement.d.ts +12 -14
  367. package/dist/plugins/session-placement.js +2 -15
  368. package/dist/plugins/session-store.d.ts +18 -8
  369. package/dist/plugins/session-store.js +15 -4
  370. package/dist/plugins/sql-driver.d.ts +74 -11
  371. package/dist/plugins/sql-driver.js +210 -12
  372. package/dist/plugins/sql-errors.d.ts +23 -0
  373. package/dist/plugins/sql-errors.js +21 -0
  374. package/dist/plugins/store-backend.d.ts +36 -1
  375. package/dist/plugins/store-backend.js +40 -14
  376. package/dist/plugins/store-contracts.d.ts +42 -0
  377. package/dist/plugins/store-contracts.js +1 -0
  378. package/dist/plugins/tidb-pool.d.ts +6 -1
  379. package/dist/plugins/tidb-pool.js +44 -10
  380. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  381. package/dist/plugins/tidb-session-storage.js +2 -2
  382. package/dist/plugins/tidb-session-store.d.ts +25 -5
  383. package/dist/plugins/tidb-session-store.js +67 -21
  384. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  385. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  386. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  387. package/dist/plugins/workflow-run-store-sql.js +50 -9
  388. package/dist/posture-source.d.ts +18 -10
  389. package/dist/posture-source.js +4 -1
  390. package/dist/project-identity.d.ts +45 -6
  391. package/dist/project-identity.js +162 -8
  392. package/dist/project-layer-key.d.ts +28 -0
  393. package/dist/project-layer-key.js +29 -0
  394. package/dist/question.js +3 -2
  395. package/dist/read-deny-entry.d.ts +25 -0
  396. package/dist/read-deny-entry.js +12 -0
  397. package/dist/read-face-posture.d.ts +37 -11
  398. package/dist/read-face-posture.js +32 -3
  399. package/dist/request-key-closure.d.ts +7 -0
  400. package/dist/request-key-closure.js +9 -1
  401. package/dist/request-tool-axes.d.ts +12 -0
  402. package/dist/request-tool-axes.js +20 -0
  403. package/dist/request-value-closure.d.ts +5 -0
  404. package/dist/request-value-closure.js +11 -3
  405. package/dist/rule-entry-list.d.ts +26 -2
  406. package/dist/rule-entry-list.js +72 -12
  407. package/dist/rules-consent.js +3 -4
  408. package/dist/run-acceptance.d.ts +19 -3
  409. package/dist/run-acceptance.js +13 -1
  410. package/dist/run-local.js +37 -6
  411. package/dist/runs.d.ts +12 -10
  412. package/dist/runs.js +25 -6
  413. package/dist/runtime-caps-resolver.d.ts +16 -6
  414. package/dist/runtime-caps-resolver.js +18 -5
  415. package/dist/sandbox-pkg-source.d.ts +19 -1
  416. package/dist/sandbox-pkg-source.js +29 -7
  417. package/dist/sealed-key.d.ts +32 -0
  418. package/dist/sealed-key.js +55 -1
  419. package/dist/security.d.ts +95 -15
  420. package/dist/security.js +52 -9
  421. package/dist/session-error-wire.d.ts +31 -7
  422. package/dist/session-error-wire.js +9 -2
  423. package/dist/session-sync-kernel.d.ts +37 -10
  424. package/dist/session-sync-kernel.js +10 -0
  425. package/dist/session-titled-frame.d.ts +33 -0
  426. package/dist/session-titled-frame.js +4 -0
  427. package/dist/session-titler.d.ts +9 -1
  428. package/dist/session-titler.js +15 -4
  429. package/dist/spec-fields.js +21 -2
  430. package/dist/sql-engine-posture.d.ts +3 -1
  431. package/dist/task-a2a.js +4 -3
  432. package/dist/task-cwd.d.ts +1 -1
  433. package/dist/task-mcp.d.ts +5 -5
  434. package/dist/task-mcp.js +27 -74
  435. package/dist/task-settings.d.ts +93 -88
  436. package/dist/task-settings.js +71 -63
  437. package/dist/text-bidi.d.ts +0 -4
  438. package/dist/text-bidi.js +1 -3
  439. package/dist/tighten-only-seats.d.ts +150 -0
  440. package/dist/tighten-only-seats.js +196 -0
  441. package/dist/tool-approval.d.ts +451 -136
  442. package/dist/tool-approval.js +733 -256
  443. package/dist/tool-rule-names.d.ts +6 -0
  444. package/dist/trace/core-keyset-guard.d.ts +108 -25
  445. package/dist/trace/exit-seat.d.ts +40 -0
  446. package/dist/trace/exit-seat.js +130 -0
  447. package/dist/trace/ledger-events.d.ts +6 -3
  448. package/dist/trace/project.d.ts +98 -13
  449. package/dist/trace/project.js +57 -32
  450. package/dist/trace/projection-table.d.ts +100 -0
  451. package/dist/trace/projection-table.js +130 -0
  452. package/dist/trace/redact.d.ts +57 -0
  453. package/dist/trace/redact.js +962 -168
  454. package/dist/trace/self-minted-wire.d.ts +349 -1
  455. package/dist/trace/self-minted-wire.js +118 -1
  456. package/dist/trace/wire-projection-faces.d.ts +304 -2
  457. package/dist/trace/wire-projection-faces.js +160 -13
  458. package/dist/url-refusal.js +2 -0
  459. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  460. package/dist/web-admin-client/apply-effective.js +56 -5
  461. package/dist/web-admin-client/facade.d.ts +1 -1
  462. package/dist/web-admin-client/facade.js +1 -1
  463. package/dist/web-admin-client/read-face.js +5 -9
  464. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  465. package/dist/web-admin-client/skills-mcp.js +6 -8
  466. package/dist/web-admin-client/types.d.ts +1 -1
  467. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  468. package/package.json +8 -4
  469. package/scripts/drain-check-local.mjs +34 -2
  470. package/scripts/drain-check.mysql.sql +20 -2
  471. package/scripts/drain-check.pg.sql +20 -2
  472. package/dist/mcp-tool-faces.d.ts +0 -69
  473. package/dist/mcp-tool-faces.js +0 -106
package/dist/index.js CHANGED
@@ -20,11 +20,11 @@ export { createTaskListLane, taskListKeyFor, MAX_TASK_LIST_SESSIONS } from "./bo
20
20
  export { ensureTiDBTaskListSchema, ensurePgTaskListSchema } from "./plugins/task-list-store-sql.js";
21
21
  export { createAuthorizer, principalFrom, HttpError, } from "./security.js";
22
22
  export { memoryScopeFor, memoryEngineBackendFor } from "./memory-scope.js";
23
+ export { ensureCheckpointCtxSealing } from "./sealed-key.js";
23
24
  export { createHttpServer, } from "./http/server.js";
24
25
  export { createSideQueryLane } from "./boot/side-query-lane.js";
25
26
  export { createKeyResolver, resolveModelApiKey } from "./key-resolver.js";
26
27
  export { isModelKeyPoison, ModelKeyPoisonedError } from "./key-resolver.js";
27
28
  export { CATALOG_ENTRY_HEADER_LANES, CATALOG_ENTRY_HEADER_NAMES } from "./model-entry-headers.js";
28
- export { judgeModelRouteGap } from "./model-route-gap.js";
29
29
  export { judgeServedModelRoute } from "./model-route-endpoint.js";
30
30
  //# sourceMappingURL=index.js.map
@@ -1,17 +1,23 @@
1
1
  /**
2
- * 执行环境的家目录:**声明 × 实测**的唯一判官(纯叶:零值依赖)。
2
+ * 执行环境的家目录:**声明 × 实测**的唯一判官与唯一的座(纯叶:零值依赖)。
3
3
  *
4
- * ## 病
4
+ * ## 病(一)—— 声明了却对不上
5
5
  * `REMOTE_EXEC_HOME_DIR` 是运维对「执行环境以哪个用户的家目录运行」的声明,它是 `~/` 形权限规则的基、引擎家锚拒读行(`~/.ssh` / `~/.npmrc` …)
6
- * 的落点(`execution-lane-caps.ts` `executionLaneHomeDir` 一只属主,四个消费面同读)。k8s / local-docker / ssh 三条车道的家目录是镜像 / 目标机
6
+ * 的落点(`execution-lane-caps.ts` `executionLaneHomeDir` 一只属主,几个消费面同读)。k8s / local-docker / ssh 三条车道的家目录是镜像 / 目标机
7
7
  * 登录用户的属性,boot 期不可知 —— 声明了就照单全收。声明 `/home/y` 而车道真实家目录是 `/home/x` 时,`Edit(~/.ssh/**)` 守的是 `/home/y`,
8
8
  * `/home/x/.ssh` 照读照写,运维与用户零告警:限制写了不生效且无人知。
9
9
  *
10
- * ## 律(一句)
11
- * 家目录只有一只真源:声明在场、车道能问的,**开环境那一拍问一次**(与命令同一条 shell、同一份 env:`printf %s "$HOME"`),两者不一致 ⇒
12
- * 这只执行环境不开(拒句点名两值与两条改法),环境答了的判定记在环境上(同一镜像 / 同一目标机再问也是同一个答案,不重试成风暴);问不出答案同样不开
13
- * (证不了声明 = 不拿一个没证过的目录去守),但不记 —— 与任何一次建连失败同,下一次重问。车道问不了的(adb / device)声明照单全收 —— 那是声明唯一的用处。
14
- * 没声明的车道不问:规则基与 422 门在下单那一刻就要家目录,而那一刻执行环境还没开(把实测值接进规则基要引擎的座,见收车档)。
10
+ * ## 病(二)—— 没声明就恒问人
11
+ * 执行环境不声明家目录时,引擎的家锚拒读行放不下 ⇒ 每一次泄内容的递归读(`grep -r` / `rg` / `git grep` / `tar c`)在全 shell 面恒问人、只读面直接拒。
12
+ * 家目录是执行环境自己的事实,车道开环境那一拍问一次就知道 —— 不必要运维手填。
13
+ *
14
+ * ## 律(一只座、两个来源、一条取值律 —— {@link LaneHomeSeat},四条会问的车道各持一只,不各写一份)
15
+ * · **声明在场 ⇒ 声明**(座 = 声明原样)。车道对证与否是车道的姿势(`verifiesDeclared`):对证的车道在开环境那一拍问一次(与命令同一条 shell、同一份 env:
16
+ * `printf %s "$HOME"`),两者不一致 ⇒ 这只执行环境不开(拒句点名两值与两条改法),环境答了的判定记在环境上(同一镜像 / 同一目标机再问也是同一个答案,不重试成风暴);
17
+ * 问不出答案同样不开(证不了声明 = 不拿一个没证过的目录去守),但不记 —— 与任何一次建连失败同,下一次重问;不对证的车道(adb:Android 没有 POSIX 登录家目录,声明是运维的断言)声明照单全收。
18
+ * · **没声明 ⇒ 实测**:同一拍问同一句;答出绝对路径 ⇒ 座 = 它,之后不再问;
19
+ * · **实测也缺席**(问不出 / 答的不是绝对路径,含空串)⇒ 座缺席(引擎失败关闭,不猜、不补 `/`),环境照开(没声明就没有声明可拒),一行 warn(点名读到了什么与出路)。
20
+ * 规则基与 422 门在下单那一刻就要家目录,而那一刻执行环境还没开 —— 它们仍只读声明(`executionLaneHomeDir`);实测值只填引擎手里的这一只座。
15
21
  */
16
22
  /** 探针答案的行首标记:登录脚本 / profile 往 stdout 打的横幅不会被读成家目录 —— 只认带这个标记的那一行(取最后一行)。 */
17
23
  export declare const LANE_HOME_PROBE_MARKER = "sema-lane-home=";
@@ -37,7 +43,70 @@ export type LaneHomeVerdict = {
37
43
  readonly answered: boolean;
38
44
  } | undefined;
39
45
  /**
40
- * 声明 × 实测的唯一判官。`lane` 只进句子。拒句三形:实测与声明不一致 / 实测不是绝对路径(含空)/ 没问到。每一形都点名声明值与改法,不回显任何别的东西。
46
+ * 声明 × 实测的判官。`lane` 只进句子。拒句三形:实测与声明不一致 / 实测不是绝对路径(含空)/ 没问到。每一形都点名声明值与改法,不回显任何别的东西。
41
47
  */
42
48
  export declare function judgeLaneHome(lane: string, declared: string, probe: LaneHomeProbe): LaneHomeVerdict;
49
+ /** 起服与每只环境「家目录答不出」那一行 warn 的事件名 —— 一只 code,起服(车道读不了)与环境(实测缺席)共用。 */
50
+ export declare const LANE_HOME_UNDECLARED_EVENT = "execution_lane_home_undeclared";
51
+ /**
52
+ * 「这条车道的执行环境没有家目录」的一句(纯字符串 ⇒ `build*`):`cause` 说为什么(没声明 + 车道读不了 / 读了没读到),`remedy` 说出路。
53
+ * 起服那一行(车道没有读数办法)与每只环境那一行(实测缺席)都走它 —— 代价那一半只有一份文字。
54
+ */
55
+ export declare function buildHomeAbsentNote(lane: string, cause: string, remedy: string): string;
56
+ /** 车道读不了家目录时的出路(起服那一行):声明它。 */
57
+ export declare const DECLARE_HOME_REMEDY = "Declare the home: REMOTE_EXEC_HOME_DIR=<the absolute path the environment's $HOME reads>";
58
+ /** 一行「这只环境没有家目录」的事实:交给运维的那一行 warn 的两个字段。 */
59
+ export interface LaneHomeAbsence {
60
+ readonly provider: string;
61
+ readonly note: string;
62
+ }
63
+ /** 这条车道的座怎么长出来:`declared` = 运维声明(`REMOTE_EXEC_HOME_DIR`,boot 期的唯一属主 `executionLaneHomeDir` 的答案);`verifiesDeclared` = 车道对声明对证。 */
64
+ export interface LaneHomeSeatOptions {
65
+ readonly lane: string;
66
+ readonly declared: string | undefined;
67
+ readonly verifiesDeclared: boolean;
68
+ /** 实测缺席时交出那一行 warn(缺席 = 不交;生产装配由 boot 递一只带去重的报告座,见 {@link createLaneHomeAbsenceReporter})。 */
69
+ readonly onAbsent?: ((absence: LaneHomeAbsence) => void) | undefined;
70
+ }
71
+ /**
72
+ * 四条会问家目录的车道(k8s / local-docker / ssh / adb)的适配器配置里与家目录有关的两个键 —— 文字只写这一处,四个配置接口 `extends` 它。
73
+ */
74
+ export interface LaneHomeConfig {
75
+ /**
76
+ * S-213④ / core [ref] —— 运维声明的执行环境 **home 目录**(绝对路径,本环境自己的命名空间里;`REMOTE_EXEC_HOME_DIR`)。`~/…` 形权限规则(`Edit(~/.ssh/**)`)对**跑在本 env 里的调用**
77
+ * 就以它为基。值由 `boot/execution-env.ts` 从**唯一属主** `execution-lane-caps.ts` 的 `executionLaneHomeDir` 递进来;adapter 不自算(两处各算一份 = 422 门与引擎对同一条规则给相反答案)。
78
+ * 缺席 ⇒ 不声明:车道建环境时自己问执行环境的 `$HOME`({@link LaneHomeSeat});实测也缺席 ⇒ 本 env 的 `homeDir` 座缺席,core 对 `~/` 规则判 `unreadable`
79
+ * (fail-closed 的 ask),绝不回落引擎进程自己的 home(那在远端腿上是另一个用户的另一个目录 —— 静默守错目录正是 [ref] 的病)。
80
+ */
81
+ homeDir?: string;
82
+ /** 实测缺席(没声明、也没问到绝对路径)时交出那一行 warn;缺席 = 不交。生产装配由 boot 递一只带去重的报告座({@link createLaneHomeAbsenceReporter})。 */
83
+ onHomeAbsent?: (absence: LaneHomeAbsence) => void;
84
+ }
85
+ /**
86
+ * 一只执行环境的家目录座 —— `ExecutionEnv.homeDir` 的**唯一取值律**:声明在场 ⇒ 声明;否则 ⇒ 车道开环境时实测到的绝对路径;实测也缺席 ⇒ `undefined`(引擎失败关闭)。
87
+ * 车道只做两件事:`asks` 为真时经自己的命令通道跑一次 {@link LANE_HOME_PROBE_COMMAND},把读数交给 {@link settle};`homeDir` 读 {@link home}。
88
+ */
89
+ export declare class LaneHomeSeat {
90
+ private measured;
91
+ private readonly lane;
92
+ private readonly declared;
93
+ private readonly verifiesDeclared;
94
+ private readonly onAbsent;
95
+ constructor(options: LaneHomeSeatOptions);
96
+ /** 座:声明胜,否则实测,否则缺席。 */
97
+ get home(): string | undefined;
98
+ /** 这一拍还要不要问:声明在场 ⇒ 只有对证的车道问(每次连接);没声明 ⇒ 问到量出绝对路径为止。 */
99
+ get asks(): boolean;
100
+ /**
101
+ * 收一次读数。声明在场(且车道对证)⇒ {@link judgeLaneHome}:`undefined` = 一致,否则这只环境不开(拒句 + 记不记见 {@link LaneHomeVerdict});
102
+ * 没声明 ⇒ 读到绝对路径就记下;读不到 / 不是绝对路径 ⇒ 座缺席、交一行 warn、**不拒环境**(`undefined`)—— 没声明就没有声明可拒,引擎对缺席座失败关闭。
103
+ * 不对证的车道声明在场时不该来问(`asks` 为假),来了照单全收。
104
+ */
105
+ settle(probe: LaneHomeProbe): LaneHomeVerdict;
106
+ }
107
+ /**
108
+ * 每个部署一只的「家目录实测缺席」报告座(闭包 ⇒ `create*`):同一(车道, 句子)只响一行 `execution_lane_home_undeclared`(同一镜像每个 run 的环境都读到同一个缺席,
109
+ * 每只环境各响一行 = 刷屏),不同的句子各响一次。`warn` 是服务日志的 warn。
110
+ */
111
+ export declare function createLaneHomeAbsenceReporter(warn: (event: string, fields: Record<string, unknown>) => void): (absence: LaneHomeAbsence) => void;
43
112
  //# sourceMappingURL=lane-home-probe.d.ts.map
@@ -4,32 +4,98 @@ const SHOWN_MAX = 256;
4
4
  const shown = (raw) => JSON.stringify(raw.length > SHOWN_MAX ? `${raw.slice(0, SHOWN_MAX)}…` : raw);
5
5
  const comparable = (p) => (p.length > 1 ? p.replace(/\/+$/, "") : p);
6
6
  function markedHome(stdout) {
7
- const lines = stdout.split("\n").filter((l) => l.startsWith(LANE_HOME_PROBE_MARKER));
8
- const last = lines[lines.length - 1];
9
- return last === undefined ? undefined : last.slice(LANE_HOME_PROBE_MARKER.length).replace(/\r$/, "");
7
+ const lines = stdout.split("\n").map((l) => l.replace(/\r$/, ""));
8
+ const marked = lines.flatMap((l, i) => (l.startsWith(LANE_HOME_PROBE_MARKER) ? [i] : []));
9
+ if (marked.length === 0)
10
+ return { why: "the probe printed no home line" };
11
+ const at = marked[0];
12
+ if (marked.length > 1 || lines.slice(at + 1).some((l) => l !== ""))
13
+ return { why: "the probe output holds more than one home line or text after it, so it cannot be read as one path" };
14
+ return { home: lines[at].slice(LANE_HOME_PROBE_MARKER.length) };
15
+ }
16
+ function readLaneHome(probe) {
17
+ if (!probe.ok)
18
+ return { kind: "unread", reason: probe.reason };
19
+ const marked = markedHome(probe.stdout);
20
+ if ("why" in marked)
21
+ return { kind: "unread", reason: marked.why };
22
+ return marked.home.startsWith("/") ? { kind: "home", home: marked.home } : { kind: "not_absolute", value: marked.home };
10
23
  }
11
24
  export function judgeLaneHome(lane, declared, probe) {
12
25
  const head = `REMOTE_EXEC_HOME_DIR=${shown(declared)} is the home "~/" permission rules and the engine's home-anchored read-deny rows are placed under on the ${lane} execution lane`;
13
- const measured = probe.ok ? markedHome(probe.stdout) : undefined;
14
- if (measured === undefined) {
15
- const reason = probe.ok ? "the probe printed no home line" : probe.reason;
26
+ const reading = readLaneHome(probe);
27
+ if (reading.kind === "unread") {
16
28
  return {
17
- refusal: `${head}, but the home of this execution environment could not be read (${reason}) — the declaration cannot be confirmed, so this environment is not started. Fix the lane, or unset REMOTE_EXEC_HOME_DIR (home-relative rules are then refused at submission instead).`,
29
+ refusal: `${head}, but the home of this execution environment could not be read (${reading.reason}) — the declaration cannot be confirmed, so this environment is not started. Fix the lane, or unset REMOTE_EXEC_HOME_DIR (home-relative rules are then refused at submission instead).`,
18
30
  answered: false,
19
31
  };
20
32
  }
21
- if (!measured.startsWith("/")) {
33
+ if (reading.kind === "not_absolute") {
22
34
  return {
23
- refusal: `${head}, but this execution environment reports HOME=${shown(measured)}, not an absolute path — the declaration cannot be confirmed, so this environment is not started. Give the environment's user a home (HOME), or unset REMOTE_EXEC_HOME_DIR.`,
35
+ refusal: `${head}, but this execution environment reports HOME=${shown(reading.value)}, not an absolute path — the declaration cannot be confirmed, so this environment is not started. Give the environment's user a home (HOME), or unset REMOTE_EXEC_HOME_DIR.`,
24
36
  answered: true,
25
37
  };
26
38
  }
27
- if (comparable(measured) === comparable(declared))
39
+ if (comparable(reading.home) === comparable(declared))
28
40
  return undefined;
29
41
  return {
30
- refusal: `${head}, but its commands run with HOME=${shown(measured)} — rules would guard ${shown(declared)} while ${shown(measured)} stays readable and writable, ` +
31
- `so this environment is not started. Set REMOTE_EXEC_HOME_DIR to ${shown(measured)}, or run the environment as the user whose home is ${shown(declared)}.`,
42
+ refusal: `${head}, but its commands run with HOME=${shown(reading.home)} — rules would guard ${shown(declared)} while ${shown(reading.home)} stays readable and writable, ` +
43
+ `so this environment is not started. Set REMOTE_EXEC_HOME_DIR to ${shown(reading.home)}, or run the environment as the user whose home is ${shown(declared)}.`,
32
44
  answered: true,
33
45
  };
34
46
  }
47
+ export const LANE_HOME_UNDECLARED_EVENT = "execution_lane_home_undeclared";
48
+ const HOME_ABSENT_COST = "the engine cannot place its home-anchored read-deny rows, so every contents-disclosing recursive read (grep -r, rg, git grep, tar c, …) asks a person on the full shell — " +
49
+ "no allow rule, mode or bypass releases that question — and is refused on the read-only face, so unattended tasks cannot search code; \"~/\" permission rules are refused at submission.";
50
+ export function buildHomeAbsentNote(lane, cause, remedy) {
51
+ return `the ${lane} lane declares no home for its execution environment (${cause}): ${HOME_ABSENT_COST} ${remedy}`;
52
+ }
53
+ const DECLARE_ARG = "REMOTE_EXEC_HOME_DIR=<the absolute path the environment's $HOME reads>";
54
+ export const DECLARE_HOME_REMEDY = `Declare the home: ${DECLARE_ARG}`;
55
+ export class LaneHomeSeat {
56
+ measured;
57
+ lane;
58
+ declared;
59
+ verifiesDeclared;
60
+ onAbsent;
61
+ constructor(options) {
62
+ this.lane = options.lane;
63
+ this.declared = options.declared;
64
+ this.verifiesDeclared = options.verifiesDeclared;
65
+ this.onAbsent = options.onAbsent;
66
+ }
67
+ get home() {
68
+ return this.declared ?? this.measured;
69
+ }
70
+ get asks() {
71
+ return this.declared === undefined ? this.measured === undefined : this.verifiesDeclared;
72
+ }
73
+ settle(probe) {
74
+ if (this.declared !== undefined)
75
+ return this.verifiesDeclared ? judgeLaneHome(this.lane, this.declared, probe) : undefined;
76
+ const reading = readLaneHome(probe);
77
+ if (reading.kind === "home") {
78
+ this.measured = reading.home;
79
+ return undefined;
80
+ }
81
+ const because = reading.kind === "unread" ? `could not be read (${reading.reason})` : `reads ${shown(reading.value)}, not an absolute path`;
82
+ const remedy = this.verifiesDeclared
83
+ ? "Give the environment's user an absolute HOME (a declared REMOTE_EXEC_HOME_DIR is checked against it, so declaring cannot stand in for it)."
84
+ : `Give the environment's user an absolute HOME, or declare it: ${DECLARE_ARG}.`;
85
+ this.onAbsent?.({ provider: this.lane, note: buildHomeAbsentNote(this.lane, `REMOTE_EXEC_HOME_DIR is unset and the environment's own $HOME ${because}`, remedy) });
86
+ return undefined;
87
+ }
88
+ }
89
+ const ABSENCE_SEEN_MAX = 64;
90
+ export function createLaneHomeAbsenceReporter(warn) {
91
+ const seen = new Set();
92
+ return (absence) => {
93
+ const key = `${absence.provider}\u0000${absence.note}`;
94
+ if (seen.has(key))
95
+ return;
96
+ if (seen.size < ABSENCE_SEEN_MAX)
97
+ seen.add(key);
98
+ warn(LANE_HOME_UNDECLARED_EVENT, { provider: absence.provider, note: absence.note });
99
+ };
100
+ }
35
101
  //# sourceMappingURL=lane-home-probe.js.map
@@ -59,7 +59,7 @@ export interface LeaderEndpoint {
59
59
  * With a store in place this Map holds only the runs THIS replica is driving. Exposed for tests. */
60
60
  runs: Map<string, LeaderRun>;
61
61
  }
62
- export declare function createLeaderEndpoint(runLeader: (body: LeaderRequestBody) => Promise<LeaderResult>, opts?: {
62
+ export declare function createLeaderEndpoint(runLeader: (body: LeaderRequestBody) => Promise<LeaderResult>, opts: {
63
63
  logger?: {
64
64
  info?: (m: string, x?: Record<string, unknown>) => void;
65
65
  error?: (m: string, x?: Record<string, unknown>) => void;
@@ -73,5 +73,8 @@ export declare function createLeaderEndpoint(runLeader: (body: LeaderRequestBody
73
73
  requiredFields?: readonly string[];
74
74
  /** [ref] 车4 件1:durable 登记表。缺席 ⇒ 显式的单副本内存降级臂(见文件头注)。 */
75
75
  store?: LeaderRunStore;
76
+ /** S-487 RH-3:「这个调用方读得到这一行 leader run 吗」—— 属主存取器的判官形(`http/owner-access.ts` 的 `createLeaderRunVisibility`,boot 装一次)。
77
+ * 必填:本模块不自判属主(修前手抄 `owner == null || owner === requester`,缺 [ref] C8 窄互认臂而注称 mirrors runOwnerOk),读面与幂等重放同读它。 */
78
+ ownerVisible: (principal: string | null | undefined, owner: string | null | undefined) => boolean;
76
79
  }): LeaderEndpoint;
77
80
  //# sourceMappingURL=endpoint.d.ts.map
@@ -3,6 +3,7 @@ import { redactErrorMessage, redactHead, redactLeaderResult, redactLeaderResultW
3
3
  import { withPrincipal } from "../observability/principal-context.js";
4
4
  import {} from "../plugins/leader-run-store-sql.js";
5
5
  import { idemKeyOf } from "../http/idempotency.js";
6
+ import { refusalBody } from "../http/refusal-body.js";
6
7
  function statusForLeaderResult(result) {
7
8
  if (result.conflict)
8
9
  return "needs_human";
@@ -28,7 +29,7 @@ function idemShapeError(raw) {
28
29
  }
29
30
  return undefined;
30
31
  }
31
- export function createLeaderEndpoint(runLeader, opts = {}) {
32
+ export function createLeaderEndpoint(runLeader, opts) {
32
33
  const runs = new Map();
33
34
  const memIdem = new Map();
34
35
  function reap() {
@@ -126,19 +127,19 @@ export function createLeaderEndpoint(runLeader, opts = {}) {
126
127
  function getBody(run) {
127
128
  return { status: 200, body: { id: run.id, status: run.status, ...redactedView(run) } };
128
129
  }
129
- const NOT_FOUND = { status: 404, body: { error: "leader run not found", errorCode: "not_found.leader_run" } };
130
+ const NOT_FOUND = { status: 404, body: refusalBody({ errorCode: "not_found.leader_run", message: "leader run not found" }) };
130
131
  async function handle(method, url, body, caller, idempotencyKey) {
131
132
  const requester = caller?.principal ?? null;
132
133
  const idemCaller = caller ?? { principal: null, source: null };
133
134
  if (method === "POST" && url === "/v1/leader") {
134
135
  const b = body;
135
136
  if (!b || typeof b.objective !== "string" || b.objective.trim() === "") {
136
- return { status: 400, body: { error: "missing 'objective' string", errorCode: "request.body_shape" } };
137
+ return { status: 400, body: refusalBody({ errorCode: "request.body_shape", message: "missing 'objective' string" }) };
137
138
  }
138
139
  if (opts.requiredFields) {
139
140
  const missing = opts.requiredFields.filter((f) => typeof b[f] !== "string" || b[f].trim() === "");
140
141
  if (missing.length > 0) {
141
- return { status: 400, body: { error: `missing required field(s): ${missing.join(", ")}`, errorCode: "request.body_shape" } };
142
+ return { status: 400, body: refusalBody({ errorCode: "request.body_shape", message: `missing required field(s): ${missing.join(", ")}` }) };
142
143
  }
143
144
  }
144
145
  const owner = requester;
@@ -146,15 +147,15 @@ export function createLeaderEndpoint(runLeader, opts = {}) {
146
147
  if (idempotencyKey != null) {
147
148
  const bad = idemShapeError(idempotencyKey);
148
149
  if (bad)
149
- return { status: 400, body: { error: bad, errorCode: "request.body_shape" } };
150
+ return { status: 400, body: refusalBody({ errorCode: "request.body_shape", message: bad }) };
150
151
  scopedIdem = idemKeyOf(idempotencyKey, idemCaller, "leader");
151
152
  }
152
153
  reap();
153
154
  if (opts.store) {
154
155
  const { created, run } = await opts.store.createRun({ objective: b.objective, owner, idemKey: scopedIdem });
155
156
  if (!created) {
156
- if (run.owner != null && run.owner !== owner) {
157
- return { status: 409, body: { error: "idempotency key already used by another principal", errorCode: "conflict.leader_run_exists" } };
157
+ if (!opts.ownerVisible(requester, run.owner)) {
158
+ return { status: 409, body: refusalBody({ errorCode: "conflict.leader_run_exists", message: "idempotency key already used by another principal" }) };
158
159
  }
159
160
  return { status: 202, body: { leaderRunId: run.id, status: run.status } };
160
161
  }
@@ -175,13 +176,13 @@ export function createLeaderEndpoint(runLeader, opts = {}) {
175
176
  drive(id, b, owner);
176
177
  return { status: 202, body: { leaderRunId: id, status: "running" } };
177
178
  }
178
- const ownerOk = (owner) => owner == null || owner === requester;
179
+ const ownerOk = (owner) => opts.ownerVisible(requester, owner);
179
180
  if (method === "GET" && url === "/v1/leader") {
180
181
  if (idempotencyKey == null)
181
- return { status: 400, body: { error: "idempotencyKey is required: pass the raw Idempotency-Key the submission was sent with", errorCode: "request.query_invalid" } };
182
+ return { status: 400, body: refusalBody({ errorCode: "request.query_invalid", message: "idempotencyKey is required: pass the raw Idempotency-Key the submission was sent with" }) };
182
183
  const bad = idemShapeError(idempotencyKey);
183
184
  if (bad)
184
- return { status: 400, body: { error: bad, errorCode: "request.query_invalid" } };
185
+ return { status: 400, body: refusalBody({ errorCode: "request.query_invalid", message: bad }) };
185
186
  const key = idemKeyOf(idempotencyKey, idemCaller, "leader");
186
187
  if (opts.store) {
187
188
  const run = await opts.store.getByIdem(key);
@@ -1,5 +1,6 @@
1
1
  import { type Brain, type Model, type ModelRoles, type ModelPricing, type TaskSpec, type ExecutionEnvFactory, type RemoteExecutionEnv, type ToolResultStore, type SessionStore, type ExecutionEnv, type RunnerDeps } from "@sema-agent/core";
2
2
  import type { Autonomy } from "../runtime-governance.js";
3
+ import { type CheckpointCtxSealer } from "../http/checkpoint-ctx.js";
3
4
  import type { CheckpointStoreFull } from "../plugins/store-backend.js";
4
5
  import { type LeaderDeps, type LeaderResult } from "./leader.js";
5
6
  import { type DeploymentPostureSeats } from "../boot/runner-deps.js";
@@ -7,6 +8,9 @@ import type { LeaderRequestBody } from "./endpoint.js";
7
8
  /** leader worker 的 durable 审批座(`LeaderWireConfig.durable` 函数席每次产出的一份)。 */
8
9
  export interface LeaderDurableSeat {
9
10
  readonly checkpointStore: CheckpointStoreFull;
11
+ /** S-1907:写 worker 续跑上下文的封口(`ServiceDeps.checkpointCtxSealing` 同一只;规则属主 `http/checkpoint-ctx.ts` 末段「凭据位密封」)。
12
+ * worker 的续跑体只有入口词 + 子任务 objective、不带凭据位 ⇒ 实际不封任何值,但写 ctx 的每一笔都经同一只封口(没有不封的第二种写法)。 */
13
+ readonly ctxSealer: CheckpointCtxSealer | undefined;
10
14
  readonly requireApproval: string[];
11
15
  readonly deny?: string[];
12
16
  readonly ttlMs?: number;
@@ -274,9 +274,10 @@ export function createLeaderRunner(cfg) {
274
274
  const provisionWorker = async (sub) => {
275
275
  const sessionId = `leader-${sub.workerId}-${Date.now()}`;
276
276
  const durable = cfg.durable?.();
277
- const resumeCtx = buildCheckpointCtx({ body: { ...entry, objective: sub.spec.objective }, unattendedLeg: true, writerVersion: serviceVersion() });
277
+ const resumeBody = { ...entry, objective: sub.spec.objective };
278
+ const storedResumeCtx = durable !== undefined ? buildCheckpointCtx({ body: resumeBody, unattendedLeg: true, writerVersion: serviceVersion() }, durable.ctxSealer, sessionId) : undefined;
278
279
  let durableSpec = {};
279
- if (durable) {
280
+ if (durable && storedResumeCtx !== undefined) {
280
281
  const d = durable;
281
282
  durableSpec = {
282
283
  toolPolicy: combinePolicies(createDurableQuestionPolicy(), createDurableAskPolicy({ requireApproval: d.requireApproval, ...(d.deny ? { deny: d.deny } : {}), ...(d.autoBudget ? { autoBudget: d.autoBudget } : {}), ...(d.neverAuto ? { neverAuto: d.neverAuto } : {}) })),
@@ -284,7 +285,7 @@ export function createLeaderRunner(cfg) {
284
285
  durableApproval: { scope: "_leader", ...(d.ttlMs ? { ttlMs: d.ttlMs } : {}) },
285
286
  onQuestion: QUESTION_AWAITS_RESUME,
286
287
  };
287
- await d.checkpointStore.putCtx(sessionId, resumeCtx).catch((e) => {
288
+ await d.checkpointStore.putCtx(sessionId, storedResumeCtx).catch((e) => {
288
289
  cfg.logger?.warn?.("leader_putctx_failed", { workerId: sub.workerId, err: redactHead(e instanceof Error ? e.message : String(e), 2000) });
289
290
  });
290
291
  }
@@ -313,13 +314,13 @@ export function createLeaderRunner(cfg) {
313
314
  }
314
315
  const keepCtxWarm = (runner) => {
315
316
  const d = durable;
316
- if (!d)
317
+ if (!d || storedResumeCtx === undefined)
317
318
  return runner;
318
319
  const orig = runner.runTaskStream.bind(runner);
319
320
  runner.runTaskStream = (spec, resume) => {
320
321
  const stream = orig(spec, resume);
321
322
  const iv = setInterval(() => {
322
- void d.checkpointStore.putCtx(sessionId, resumeCtx).catch(() => { });
323
+ void d.checkpointStore.putCtx(sessionId, storedResumeCtx).catch(() => { });
323
324
  }, 45_000);
324
325
  iv.unref?.();
325
326
  void stream.result().then(() => clearInterval(iv), () => clearInterval(iv));
@@ -359,7 +360,7 @@ export function createLeaderRunner(cfg) {
359
360
  },
360
361
  })),
361
362
  fetchDiff: () => fetchUploadedDiff(getUrl),
362
- spec: withLeaderLeg({ ...workerLimits, ...sub.spec, ...durableSpec, ...resourceSpec, ...principalSpec(), objective: `${sub.spec.objective}${uploadStepSuffix(W)}` }, resumeCtx.body),
363
+ spec: withLeaderLeg({ ...workerLimits, ...sub.spec, ...durableSpec, ...resourceSpec, ...principalSpec(), objective: `${sub.spec.objective}${uploadStepSuffix(W)}` }, resumeBody),
363
364
  };
364
365
  }
365
366
  if (!cfg.e2bApiKey)
@@ -374,7 +375,7 @@ export function createLeaderRunner(cfg) {
374
375
  runner: keepCtxWarm(new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, ...onNoticeSeat, ...governanceSeat, ...deploymentPostureSeat(), ...tracerSeat, ...usageWindowSeat, ...promptSourceSeat, ...onErrorSeat, ...(cfg.toolResultStore ? { toolResultStore: cfg.toolResultStore } : {}), ...(cfg.sessionStore ? { sessionStore: cfg.sessionStore } : {}), executionEnv: env })),
375
376
  diffEnv: env,
376
377
  destroy: () => env.destroy().then(() => { }),
377
- spec: withLeaderLeg({ ...workerLimits, ...sub.spec, ...durableSpec, ...resourceSpec, ...principalSpec() }, resumeCtx.body),
378
+ spec: withLeaderLeg({ ...workerLimits, ...sub.spec, ...durableSpec, ...resourceSpec, ...principalSpec() }, resumeBody),
378
379
  };
379
380
  };
380
381
  const provisionIntegrationSandbox = async () => {
@@ -3,10 +3,12 @@
3
3
  *
4
4
  * 律:请求体上任何一处撞了帽,拒体带同一组机读位 ——
5
5
  * · `field` = 撞帽的那一处在请求体里的坐标(`skills[1].allowedTools`、`agents[0].denyTools[3]`、`settings.permissions.allow`);
6
- * · `reason` = 帽的量纲,闭集两词:`over_cap`(条数:数组的条目数)/ `too_long`(字符数:一段文字的长度);
7
- * · `count` = 送来的量(条数或字符数,量纲由 `reason` 定);
6
+ * · `reason` = 帽的量纲,闭集三词:`over_cap`(条数:数组的条目数)/ `too_long`(字符数:一段文字的长度)/ `too_large`(字节数:一份载荷的体积);
7
+ * · `count` = 送来的量(条数、字符数或字节数,量纲由 `reason` 定);
8
8
  * · `cap` = 帽。
9
- * 句子的头一句同一句:`<field> has <count> entries|characters — at most <cap> are accepted`;之后各面可以接自己的出路句(为什么拒而不截、怎么改)。
9
+ * 句子的头一句同一句:`<field> has <count> entries|characters|bytes — at most <cap> are accepted`;之后各面可以接自己的出路句(为什么拒而不截、怎么改)。
10
+ * 唯一的缺量形:读体读到帽就停 / 库只说「一行装不下」时量不出送来多少 ⇒ {@link limitFactsUnmeasured}(`count` 缺席,`cap` 只在帽已知时在;不编数)。
11
+ * 已有句子的面(上限早于本模块定下来的受理口各处)句子逐字不变、只加机读位 —— 用 {@link limitFacts} 铸,不改写句子。
10
12
  * 帽本身(数字)归各面的属主;本模块只管「撞了帽怎么说、怎么机读」。
11
13
  *
12
14
  * 量纲 → `reason` 是一张闭表({@link LIMIT_REASONS}):加一种量纲 ⇒ 这里加一行,`reason` 的词随之进闭集,读者穷举读。
@@ -15,10 +17,11 @@
15
17
  export declare const LIMIT_REASONS: {
16
18
  readonly entries: "over_cap";
17
19
  readonly characters: "too_long";
20
+ readonly bytes: "too_large";
18
21
  };
19
- /** 帽的量纲:条数 / 字符数(句子里就是这个词)。 */
22
+ /** 帽的量纲:条数 / 字符数 / 字节数(句子里就是这个词)。 */
20
23
  export type LimitMeasure = keyof typeof LIMIT_REASONS;
21
- /** 机读 `reason`:`over_cap`(条数)/ `too_long`(字符数)。 */
24
+ /** 机读 `reason`:`over_cap`(条数)/ `too_long`(字符数)/ `too_large`(字节数)。 */
22
25
  export type LimitReason = (typeof LIMIT_REASONS)[LimitMeasure];
23
26
  /** 一处撞帽的机读位(原样进拒体:`refusalBody` 的 facts / `HttpError.extra`;型别名而不是接口 —— 要能直接当 `Record<string, unknown>` 用)。 */
24
27
  export type LimitFacts = {
@@ -27,6 +30,13 @@ export type LimitFacts = {
27
30
  readonly count: number;
28
31
  readonly cap: number;
29
32
  };
33
+ /**
34
+ * 撞了帽、却**量不出**送来多少的机读位:读体读到帽就停(体没读完 —— 不为量一个数把 8 MiB 之外的字节再读进内存),或库只说「一行装不下」、不说多大。
35
+ * 同一组键的缺量形:`field` / `reason`(量纲定)恒在,`cap` 只在帽已知时在,`count` 恒缺席 —— 缺席就是「量不出」,不编数。
36
+ */
37
+ export type UnmeasuredLimitFacts = Pick<LimitFacts, "field" | "reason"> & {
38
+ readonly cap?: number;
39
+ };
30
40
  /** 一处撞帽的拒:句子 + 机读位。 */
31
41
  export interface LimitRefusal {
32
42
  readonly message: string;
@@ -36,6 +46,8 @@ export interface LimitRefusal {
36
46
  export declare function describeLimit(field: string, measure: LimitMeasure, count: number, cap: number): string;
37
47
  /** 机读位:`reason` 由量纲定。 */
38
48
  export declare function limitFacts(field: string, measure: LimitMeasure, count: number, cap: number): LimitFacts;
49
+ /** 缺量形的机读位({@link UnmeasuredLimitFacts}):`reason` 仍由量纲定;`cap` 只在帽已知时给。 */
50
+ export declare function limitFactsUnmeasured(field: string, measure: LimitMeasure, cap?: number): UnmeasuredLimitFacts;
39
51
  /**
40
52
  * 一处撞帽的拒:句子 = {@link describeLimit}(+ `tail`:该面的出路句,接在头一句之后),机读位 = {@link limitFacts}(`field` 同一个坐标)。
41
53
  * `sentenceField` 只在该面的句子沿用另一种点名写法时给(子代定义的句子写作 `agents[0]: agent.name`,机读位仍是体内坐标 `agents[0].name`)。
@@ -1,10 +1,13 @@
1
- export const LIMIT_REASONS = { entries: "over_cap", characters: "too_long" };
1
+ export const LIMIT_REASONS = { entries: "over_cap", characters: "too_long", bytes: "too_large" };
2
2
  export function describeLimit(field, measure, count, cap) {
3
3
  return `${field} has ${count} ${measure} — at most ${cap} are accepted`;
4
4
  }
5
5
  export function limitFacts(field, measure, count, cap) {
6
6
  return { field, reason: LIMIT_REASONS[measure], count, cap };
7
7
  }
8
+ export function limitFactsUnmeasured(field, measure, cap) {
9
+ return cap === undefined ? { field, reason: LIMIT_REASONS[measure] } : { field, reason: LIMIT_REASONS[measure], cap };
10
+ }
8
11
  export function limitRefusal(field, measure, count, cap, opts = {}) {
9
12
  const head = describeLimit(opts.sentenceField ?? field, measure, count, cap);
10
13
  return { message: opts.tail === undefined ? head : `${head}. ${opts.tail}`, facts: limitFacts(field, measure, count, cap) };
package/dist/main.js CHANGED
@@ -17,7 +17,7 @@ async function main() {
17
17
  const s04 = await runStage04(s03);
18
18
  const s05 = await runStage05(s04);
19
19
  await settleHostLaneShell(s05.config, s05.logger);
20
- const s06 = runStage06(s05);
20
+ const s06 = await runStage06(s05);
21
21
  const s07 = await runStage07(s06);
22
22
  const s08 = runStage08(s07);
23
23
  const s09 = runStage09(s08);
@@ -18,13 +18,16 @@
18
18
  * 所以读器(契约包的 `readMcpIdentityHeaders`,`normalizeServer` 的 http 传输读两个身份头用它)的处置是**降级到升级前的读法**:`principalHeader` 胜(照挂,与升级前逐字相同),`assertionHeader` 不生效;
19
19
  * 不静默 —— 真挂上的这类条目由 {@link noteMcpAssertionHeaderIgnored} 说一行 warn(部署声明面没有这一格:配置不是被重放的存量任务,契约包解析期那一刀直接丢这一条)。
20
20
  *
21
- * ## 发送归引擎座(本版只承载,不发送)
22
- * core 的 http 传输只有 `url` / `headers` / `principalHeader`,**没有**断言头座。所以本键承载到「铸 core 规格」为止:
23
- * 请求面在 {@link toCoreMcpServerSpec} 剥掉它,settings 面的 `resolveMcpServers` 不投它;两处都用同一只
24
- * {@link noteMcpAssertionHeaderNotSent} 说出一行 info(声明在、发送未接)—— 披露,不是兜底:server 照常挂载、不带断言头,
25
- * 要求断言的托管连接器会拒这些调用,运维据这一行知道原因在哪。
26
- *
27
- * ## 退役(编译期自动逼,零人工记忆)
21
+ * ## 发送归引擎座(本版只承载,不发送)—— 「发不发」只有一只开关
22
+ core 的 http 传输只有 `url` / `headers` / `principalHeader`,**没有**断言头座。所以本键承载到「铸 core 规格」为止:
23
+ 请求面在 {@link toCoreMcpServerSpec} 剥掉它,settings 面的 `resolveMcpServers` 不投它;两处都用同一只
24
+ {@link noteMcpAssertionHeaderNotSent} 说出一行 info(声明在、发送未接)—— 披露,不是兜底:server 照常挂载、不带断言头,
25
+ 要求断言的托管连接器会拒这些调用,运维据这一行知道原因在哪。
26
+ 「这台 server 发不发」是**一个事实**,只有一只开关 {@link MCP_ASSERTION_HEADER_SENT} 说它;读它的地方共五处,全经 {@link withholdsMcpAssertionHeader} 这一只谓词
27
+ (能力位 `GET /v1/capabilities` 的 `mcpAssertionHeaderSent` 直读开关本人):请求面剥键、settings 面不投、一行 info、探测口整条拒、能力位。所以「位为真」与「还在说发送未接」
28
+ 结构上不可能同时成立,消费方按位分支、位真时不再看到任何披露句;发送座到货的那天翻的就是这一行(与下面的退役门同批)。
29
+
30
+ ## 退役(编译期自动逼,零人工记忆)
28
31
  * 引擎的 http 传输一旦长出同名座,{@link _CoreHasNoAssertionSeat} 当场编译红:届时删本文件里的 {@link RequestMcpServerSpec}
29
32
  * 扩展与 {@link toCoreMcpServerSpec} 的剥键、两处 info,把键直接投进引擎规格(发送由引擎座兑现)。
30
33
  */
@@ -60,9 +63,27 @@ export declare function mcpIdentityHeadersIssue(transport: Record<string, unknow
60
63
  export declare function describeMcpIdentityHeadersConflict(server: string): string;
61
64
  /** `assertionHeader` 值不是字符串的**原因句**(不带条目名与键路径:点名由请求面统一的拒形 `entryFieldRefusal` 负责;值的形状只说种类,不回显值本身:它是一个调用方写的头名位置,可能是任何东西)。 */
62
65
  export declare function describeMcpAssertionHeaderNotAString(value: unknown): string;
63
- /** 这一条请求面条目是否声明了 `assertionHeader`(= 铸 core 规格时会被剥掉、需要说一行的那一类)。 */
64
- export declare function declaresMcpAssertionHeader(spec: RequestMcpServerSpec): boolean;
65
- /** 请求面条目 → 交给引擎的规格:剥掉 `assertionHeader`(引擎无座);其余逐字不动。声明过它的条目由调用方另说一行 info。 */
66
+ /**
67
+ * 引擎的 http 传输有没有断言头发送座 —— **全仓唯一的开关**。今天没有(core 的 http 传输无同名座,见头注与退役门)⇒ `false`:声明在、发送未接。
68
+ * 翻真 = 这一行 + 删退役门 + 把 {@link RequestHttpMcpTransport} 并进引擎型;剥键、披露、探测口拒、settings 面投影、能力位 `mcpAssertionHeaderSent` 随它一起翻
69
+ * (五处都读 {@link withholdsMcpAssertionHeader} / 本常量,没有第六处)。声明成 `boolean` 而不是字面 `false`:谓词里的真臂是活代码(单测传 `sent=true` 钉它),不是被收窄掉的死分支。
70
+ */
71
+ export declare const MCP_ASSERTION_HEADER_SENT: boolean;
72
+ /**
73
+ * 这一份 `assertionHeader` 声明是不是「被扣下」的那一类(需要剥键、需要说一行 info、探测口要拒的那一类)—— 即**声明了,而发送座不在**。
74
+ * 三处消费(剥键 / 披露 / 探测口拒)与 settings 面的投影共读这一只;`sent` 缺省读开关,单测传显式值钉另一臂。
75
+ */
76
+ export declare function withholdsMcpAssertionHeader(assertionHeader: unknown, sent?: boolean): boolean;
77
+ /** {@link withholdsMcpAssertionHeader} 在请求面条目上的读法:只有 http 传输有这个键(stdio 形上它不存在)。 */
78
+ export declare function specWithholdsMcpAssertionHeader(spec: RequestMcpServerSpec): boolean;
79
+ /**
80
+ * settings 面铸 spec 时「这个键投不投进引擎规格」:发送座在(`sent` 真)且声明了字符串 ⇒ 投,否则整键缺席。今天恒为空对象(开关假);
81
+ * 开关翻真的那天 settings 面因此自动跟着投,不会出现「位说发了、部署声明面却没投」。
82
+ */
83
+ export declare function sentMcpAssertionHeaderMember(assertionHeader: unknown, sent?: boolean): {
84
+ assertionHeader?: string;
85
+ };
86
+ /** 请求面条目 → 交给引擎的规格:被扣下的 `assertionHeader` 剥掉(引擎无座);其余逐字不动。被扣下的条目由调用方另说一行 info。 */
66
87
  export declare function toCoreMcpServerSpec(spec: RequestMcpServerSpec): McpServerSpec;
67
88
  /** `noteMcpAssertionHeaderNotSent` 的日志行名(运维 grep 用;请求面与 settings 面同一个名字)。 */
68
89
  export declare const MCP_ASSERTION_HEADER_NOT_SENT = "mcp_assertion_header_not_sent";
@@ -14,11 +14,18 @@ export function describeMcpAssertionHeaderNotAString(value) {
14
14
  const kind = value === null ? "null" : Array.isArray(value) ? "an array" : `a ${typeof value}`;
15
15
  return `must be a string (the HTTP header NAME the connector assertion travels in) — got ${kind}; omit the key to send no assertion header`;
16
16
  }
17
- export function declaresMcpAssertionHeader(spec) {
18
- return spec.transport.kind === "http" && spec.transport.assertionHeader !== undefined;
17
+ export const MCP_ASSERTION_HEADER_SENT = false;
18
+ export function withholdsMcpAssertionHeader(assertionHeader, sent = MCP_ASSERTION_HEADER_SENT) {
19
+ return !sent && assertionHeader !== undefined;
20
+ }
21
+ export function specWithholdsMcpAssertionHeader(spec) {
22
+ return spec.transport.kind === "http" && withholdsMcpAssertionHeader(spec.transport.assertionHeader);
23
+ }
24
+ export function sentMcpAssertionHeaderMember(assertionHeader, sent = MCP_ASSERTION_HEADER_SENT) {
25
+ return sent && typeof assertionHeader === "string" ? { assertionHeader } : {};
19
26
  }
20
27
  export function toCoreMcpServerSpec(spec) {
21
- if (spec.transport.kind !== "http" || spec.transport.assertionHeader === undefined)
28
+ if (spec.transport.kind !== "http" || !withholdsMcpAssertionHeader(spec.transport.assertionHeader))
22
29
  return spec;
23
30
  const { assertionHeader: _declaredNotSent, ...transport } = spec.transport;
24
31
  return { ...spec, transport };
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { committedOriginOf } from "@sema-agent/core";
3
- import { canonicalJson } from "./canonical-json.js";
3
+ import { canonicalJsonStringify } from "@sema-agent/core";
4
4
  export const ORIGIN_AWARE_QUERY = "originAware";
5
5
  export function readOriginAware(params) {
6
6
  return params.get(ORIGIN_AWARE_QUERY) === "1";
@@ -47,7 +47,7 @@ export function buildOriginFencedBundle(bundle, originAware) {
47
47
  integrity: {
48
48
  entryCount: kept.length,
49
49
  revs: Object.fromEntries(kept.map((e) => [e.id, e.rev])),
50
- sectionHashes: { ...bundle.integrity.sectionHashes, entries: sha256Line(canonicalJson(kept)) },
50
+ sectionHashes: { ...bundle.integrity.sectionHashes, entries: sha256Line(canonicalJsonStringify(kept)) },
51
51
  },
52
52
  withheldOriginTagged: withheld,
53
53
  };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * S-640(S-512 片二)—— 一个任务的**项目层准备一步**:求键 → 把同一 checkout 的旧层折进当前层 → 交给同步腿跟踪。
3
+ * HTTP 腿(`boot/resolve-spec.ts`)与 run-local 腿共用这一只;键的规则只在 `memory-scope.ts` `memoryProjectLayerFor`(本模块不判让位、不铸键)。
4
+ *
5
+ * ## 折叠(`foldFrom`,由 `project-identity.ts` `projectLayerForTaskRoot` 给出,按序)
6
+ * · 退役 `repo:<sha256(根)[:24]>` 层 —— **一次性迁移**(7.98.0–7.132.x 的项目键;窗、删法见 `plugins/one-time-migrations.ts` 登记表 M25);
7
+ * · 当前档为 `r`(origin 远端)时本 checkout 的 `p` 档 —— **常设律**(先 `git init` 后加远端的项目,加远端那一刻不丢项目记忆)。
8
+ * 折 = core `migrateScope`(id 保留、rev 按新 scope 重算、逐条 CAS;冲突留原地,下一个任务再折)。**不记「已折」**:每个任务先读一眼旧层
9
+ * (`listHeaders`,空就不动),旧层之后又来了条目(仍在跑的旧任务 harvest、同步把别处的改动拉回旧层)下一个任务照折。
10
+ * 🔴 **与同步轮串行**:旧层若是被同步的层(`p` 档),在飞的那一轮的应答(拉回的改动 / 删除)按 id 落盘 —— 折在它前面,应答会把刚折走的条目改回旧层
11
+ * 或在新层上删掉它。所以有东西要折时,折叠排进同步腿的串行链(`MemorySyncRunner.exclusive`):等在飞的那一轮落定再折,折的时候没有轮在飞。
12
+ * 折在 spec 返回之前完成(`await`)⇒ 这一任务挂载时就看得见折进来的条目(代价如实:有东西要折又恰有一轮在飞时,任务起步等那一轮)。
13
+ * 折叠失败不挡任务(响亮 warn,条目原地不动、下次再折):项目层记忆暂时少了旧层那几条,比任务起不来更接近用户要的东西。
14
+ *
15
+ * ## 跟踪
16
+ * 当前层在复制覆盖面里(否则规则已让位、根本走不到这里)且有同步腿 ⇒ `track(scope)`:本地还没有条目也每轮拉它 —— 第二台设备第一次进这个项目
17
+ * 就拉得到第一台写的(拉回来可能晚于本任务挂载:第一个任务看不见,下一个任务看得见,如实)。
18
+ */
19
+ import { type MemoryBackend } from "@sema-agent/core";
20
+ import type { ServiceConfig } from "./config-types.js";
21
+ import type { MemorySyncRunner } from "./memory-sync-client.js";
22
+ import type { MemoryProjectKey } from "./project-identity.js";
23
+ export interface MemoryProjectLayers {
24
+ /** 这一任务的项目层声明(`TaskSpec.memory.projectKey`);`undefined` 的三形同 `memoryProjectKeyFor`。 */
25
+ prepare(config: Pick<ServiceConfig, "requirePrincipal" | "memorySync">, scope: string | undefined, taskRoot: string | undefined): Promise<MemoryProjectKey | undefined>;
26
+ }
27
+ export declare function createMemoryProjectLayers(deps: {
28
+ /** 本部署的记忆引擎 backend(File 或 SQL 孪生);缺席 ⇒ 没有可折的盘(记忆暗时调用方根本不会问)。 */
29
+ backend: MemoryBackend | undefined;
30
+ /** 同步腿(开同步时在场):跟踪当前层;有东西要折时折叠排进它的串行链。 */
31
+ syncRunner: Pick<MemorySyncRunner, "track" | "exclusive"> | undefined;
32
+ log: {
33
+ info(msg: string, fields?: Record<string, unknown>): void;
34
+ warn(msg: string, fields?: Record<string, unknown>): void;
35
+ };
36
+ }): MemoryProjectLayers;
37
+ //# sourceMappingURL=memory-project-layer.d.ts.map