@sema-agent/server 7.132.0 → 7.133.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 (402) hide show
  1. package/MIGRATION.md +266 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +174 -55
  5. package/deploy/sema-up/README.md +19 -1
  6. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
  7. package/deploy/sema-up/chart/templates/server.yaml +5 -2
  8. package/deploy/sema-up/stack/compose.yaml +3 -0
  9. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  10. package/dist/adoption/plan.d.ts +3 -2
  11. package/dist/adoption/plan.js +7 -5
  12. package/dist/adoption/runner.js +3 -10
  13. package/dist/adoption/sql.d.ts +3 -2
  14. package/dist/adoption/sql.js +3 -5
  15. package/dist/adoption/wire.d.ts +4 -1
  16. package/dist/adoption/wire.js +1 -0
  17. package/dist/approval-ask-audit-store.d.ts +31 -13
  18. package/dist/approval-ask-audit-store.js +272 -74
  19. package/dist/approval-ask-machine.d.ts +15 -0
  20. package/dist/approval-ask-machine.js +6 -0
  21. package/dist/approval-ask-retention.d.ts +136 -0
  22. package/dist/approval-ask-retention.js +102 -0
  23. package/dist/approval-card.d.ts +79 -19
  24. package/dist/approval-card.js +44 -13
  25. package/dist/approval-deny-reasons.d.ts +1 -1
  26. package/dist/approval.d.ts +9 -0
  27. package/dist/approval.js +24 -3
  28. package/dist/audit.d.ts +27 -10
  29. package/dist/audit.js +12 -16
  30. package/dist/bake-runner/main.js +3 -2
  31. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  32. package/dist/boot/execution-env.js +9 -7
  33. package/dist/boot/execution-lane.js +11 -0
  34. package/dist/boot/leader.js +2 -0
  35. package/dist/boot/memory-boundary.js +2 -2
  36. package/dist/boot/memory-consolidation.d.ts +5 -4
  37. package/dist/boot/memory-consolidation.js +7 -6
  38. package/dist/boot/org-delivery.d.ts +28 -0
  39. package/dist/boot/org-delivery.js +20 -0
  40. package/dist/boot/reapers.d.ts +3 -0
  41. package/dist/boot/reapers.js +21 -1
  42. package/dist/boot/resolve-spec.d.ts +3 -0
  43. package/dist/boot/resolve-spec.js +60 -81
  44. package/dist/boot/runner-deps.js +1 -0
  45. package/dist/boot/session-faces.d.ts +1 -0
  46. package/dist/boot/session-faces.js +4 -2
  47. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  48. package/dist/boot/stage-06-runners.d.ts +2 -0
  49. package/dist/boot/stage-06-runners.js +6 -3
  50. package/dist/boot/stage-07-capability-layer.d.ts +2 -0
  51. package/dist/boot/stage-07-capability-layer.js +24 -3
  52. package/dist/boot/stage-08-reapers.d.ts +2 -0
  53. package/dist/boot/stage-08-reapers.js +2 -2
  54. package/dist/boot/stage-09-leader.d.ts +3 -0
  55. package/dist/boot/stage-10-http-server.d.ts +3 -0
  56. package/dist/boot/stage-10-http-server.js +5 -6
  57. package/dist/boot/stores.js +2 -2
  58. package/dist/boot/web-admin.d.ts +4 -0
  59. package/dist/boot/web-admin.js +151 -63
  60. package/dist/boot/workflow-orchestration.d.ts +2 -0
  61. package/dist/boot/workflow-orchestration.js +2 -1
  62. package/dist/brain.js +8 -3
  63. package/dist/breaker-key.d.ts +6 -0
  64. package/dist/breaker-key.js +29 -0
  65. package/dist/caller-text-echo.d.ts +9 -6
  66. package/dist/caller-text-echo.js +8 -11
  67. package/dist/capabilities/center-plugins.d.ts +7 -0
  68. package/dist/capabilities/center-plugins.js +1 -1
  69. package/dist/capabilities/composite-members.d.ts +1 -1
  70. package/dist/capabilities/composite-members.js +1 -1
  71. package/dist/capabilities/execution-lane.js +2 -2
  72. package/dist/capabilities/hands-lane.d.ts +21 -0
  73. package/dist/capabilities/hands-lane.js +10 -0
  74. package/dist/capabilities/mcp-probe.d.ts +36 -4
  75. package/dist/capabilities/mcp-probe.js +27 -4
  76. package/dist/capabilities/scenarios.d.ts +63 -7
  77. package/dist/capabilities/scenarios.js +39 -7
  78. package/dist/capability-facts.d.ts +34 -4
  79. package/dist/capability-facts.js +28 -2
  80. package/dist/center-config-tier.d.ts +69 -0
  81. package/dist/center-config-tier.js +42 -0
  82. package/dist/checkpoint-identity.d.ts +16 -0
  83. package/dist/checkpoint-identity.js +19 -0
  84. package/dist/config-catalog.d.ts +17 -10
  85. package/dist/config-catalog.js +43 -28
  86. package/dist/config-d-migration.d.ts +3 -1
  87. package/dist/config-d-migration.js +2 -2
  88. package/dist/config-dir-trust.d.ts +114 -0
  89. package/dist/config-dir-trust.js +388 -0
  90. package/dist/config-invariants.d.ts +18 -5
  91. package/dist/config-invariants.js +35 -3
  92. package/dist/config-provider.d.ts +6 -1
  93. package/dist/config-provider.js +6 -2
  94. package/dist/config-types.d.ts +71 -14
  95. package/dist/config-types.js +8 -0
  96. package/dist/config.d.ts +13 -0
  97. package/dist/config.js +121 -59
  98. package/dist/delegated-session-owner.d.ts +185 -0
  99. package/dist/delegated-session-owner.js +119 -0
  100. package/dist/device-protocol.d.ts +5 -3
  101. package/dist/device-protocol.js +1 -1
  102. package/dist/device-ws-hub.js +21 -2
  103. package/dist/device-ws-protocol.d.ts +70 -6
  104. package/dist/device-ws-protocol.js +50 -23
  105. package/dist/elicitation.js +3 -2
  106. package/dist/entry-problems.d.ts +34 -0
  107. package/dist/entry-problems.js +14 -0
  108. package/dist/execution-lane-caps.d.ts +49 -10
  109. package/dist/execution-lane-caps.js +43 -4
  110. package/dist/field-conflict.d.ts +43 -0
  111. package/dist/field-conflict.js +20 -0
  112. package/dist/fleet/fleet-bus.d.ts +80 -6
  113. package/dist/fleet/fleet-bus.js +41 -9
  114. package/dist/hooks/classic-stations.d.ts +10 -5
  115. package/dist/hooks/classic-stations.js +4 -4
  116. package/dist/hooks/command-spawn.d.ts +57 -0
  117. package/dist/hooks/command-spawn.js +139 -0
  118. package/dist/hooks/hook-llm.js +2 -2
  119. package/dist/hooks/hook-runner.d.ts +127 -25
  120. package/dist/hooks/hook-runner.js +668 -287
  121. package/dist/hooks/hook-source.d.ts +44 -0
  122. package/dist/hooks/hook-source.js +40 -0
  123. package/dist/http/active-run-conflict.d.ts +5 -13
  124. package/dist/http/active-run-conflict.js +17 -27
  125. package/dist/http/admission.js +103 -60
  126. package/dist/http/approval-sweeps.js +55 -18
  127. package/dist/http/caller-trust.d.ts +77 -0
  128. package/dist/http/caller-trust.js +143 -0
  129. package/dist/http/checkpoint-ctx.d.ts +16 -16
  130. package/dist/http/checkpoint-ctx.js +13 -10
  131. package/dist/http/claimed-run.d.ts +4 -3
  132. package/dist/http/device-placement.d.ts +2 -4
  133. package/dist/http/device-placement.js +2 -1
  134. package/dist/http/dispatch.js +10 -4
  135. package/dist/http/durable-run-leg.d.ts +4 -32
  136. package/dist/http/durable-run-leg.js +34 -10
  137. package/dist/http/owner-access.d.ts +56 -0
  138. package/dist/http/owner-access.js +42 -0
  139. package/dist/http/principal-gate.d.ts +48 -23
  140. package/dist/http/principal-gate.js +39 -12
  141. package/dist/http/readiness.d.ts +11 -5
  142. package/dist/http/readiness.js +10 -3
  143. package/dist/http/request-guards.d.ts +16 -23
  144. package/dist/http/request-guards.js +30 -15
  145. package/dist/http/resume-ctx-read.d.ts +2 -5
  146. package/dist/http/resume-ctx-read.js +7 -4
  147. package/dist/http/resume-legs.d.ts +3 -4
  148. package/dist/http/resume-legs.js +126 -69
  149. package/dist/http/retired-service-deps.d.ts +43 -0
  150. package/dist/http/retired-service-deps.js +18 -0
  151. package/dist/http/route-ctx.d.ts +44 -28
  152. package/dist/http/route-ctx.js +4 -0
  153. package/dist/http/route-table.js +2 -0
  154. package/dist/http/routes/a2a-serve.js +3 -4
  155. package/dist/http/routes/admin-config-refresh.js +1 -1
  156. package/dist/http/routes/admin-drain.js +1 -1
  157. package/dist/http/routes/admin-memory-optout.js +5 -1
  158. package/dist/http/routes/adoption.js +2 -9
  159. package/dist/http/routes/approvals-assistant.js +49 -48
  160. package/dist/http/routes/background.js +3 -2
  161. package/dist/http/routes/capabilities.js +20 -4
  162. package/dist/http/routes/config-catalog.d.ts +3 -3
  163. package/dist/http/routes/config-catalog.js +1 -1
  164. package/dist/http/routes/devices.js +3 -17
  165. package/dist/http/routes/diagnostics.js +5 -1
  166. package/dist/http/routes/images.js +6 -7
  167. package/dist/http/routes/leader.js +1 -8
  168. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  169. package/dist/http/routes/mcp-reconnect.js +3 -2
  170. package/dist/http/routes/memory-bundle.js +1 -1
  171. package/dist/http/routes/memory-compliance.js +1 -1
  172. package/dist/http/routes/memory-consolidation.js +1 -1
  173. package/dist/http/routes/memory-origin.js +1 -1
  174. package/dist/http/routes/memory-policy.d.ts +1 -1
  175. package/dist/http/routes/memory-policy.js +3 -2
  176. package/dist/http/routes/notify-wake.js +8 -21
  177. package/dist/http/routes/observability.js +2 -2
  178. package/dist/http/routes/principal-inbox.d.ts +39 -0
  179. package/dist/http/routes/principal-inbox.js +76 -0
  180. package/dist/http/routes/retention-ops.js +2 -9
  181. package/dist/http/routes/rules.js +5 -18
  182. package/dist/http/routes/runs.d.ts +5 -0
  183. package/dist/http/routes/runs.js +33 -106
  184. package/dist/http/routes/session-sync.js +15 -28
  185. package/dist/http/routes/sessions.js +30 -40
  186. package/dist/http/routes/side-query.js +6 -4
  187. package/dist/http/routes/tasks.js +50 -14
  188. package/dist/http/routes/workflows.d.ts +351 -0
  189. package/dist/http/routes/workflows.js +153 -119
  190. package/dist/http/send.d.ts +24 -3
  191. package/dist/http/send.js +14 -2
  192. package/dist/http/server.d.ts +17 -18
  193. package/dist/http/server.js +15 -13
  194. package/dist/http/stored-body-replay.js +17 -4
  195. package/dist/http/submit-ctx.js +4 -3
  196. package/dist/http/submit-replay.d.ts +4 -3
  197. package/dist/http/submit-replay.js +5 -4
  198. package/dist/http/wire-types.d.ts +10 -7
  199. package/dist/index.d.ts +1 -1
  200. package/dist/index.js +0 -1
  201. package/dist/lane-home-probe.d.ts +78 -9
  202. package/dist/lane-home-probe.js +78 -12
  203. package/dist/leader/endpoint.d.ts +4 -1
  204. package/dist/leader/endpoint.js +11 -10
  205. package/dist/limit-refusal.d.ts +17 -5
  206. package/dist/limit-refusal.js +4 -1
  207. package/dist/mcp-assertion-header.d.ts +31 -10
  208. package/dist/mcp-assertion-header.js +10 -3
  209. package/dist/mcp-tool-faces.js +1 -3
  210. package/dist/memory-project-layer.d.ts +37 -0
  211. package/dist/memory-project-layer.js +46 -0
  212. package/dist/memory-scope.d.ts +23 -16
  213. package/dist/memory-scope.js +24 -8
  214. package/dist/memory-sync-client.d.ts +27 -13
  215. package/dist/memory-sync-client.js +107 -18
  216. package/dist/model-entry-refusal.d.ts +9 -1
  217. package/dist/model-entry-refusal.js +6 -1
  218. package/dist/model-plane-face.d.ts +51 -0
  219. package/dist/model-plane-face.js +24 -0
  220. package/dist/model-provider.d.ts +5 -0
  221. package/dist/model-provider.js +4 -2
  222. package/dist/model-route-endpoint.d.ts +8 -11
  223. package/dist/model-route-endpoint.js +4 -7
  224. package/dist/model-route-env.d.ts +22 -0
  225. package/dist/model-route-env.js +2 -0
  226. package/dist/model-route-gap.d.ts +60 -30
  227. package/dist/model-route-gap.js +21 -15
  228. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  229. package/dist/observability/corrupt-read-seat.js +9 -0
  230. package/dist/observability/err-text.d.ts +6 -0
  231. package/dist/observability/err-text.js +18 -4
  232. package/dist/observability/fail-open.d.ts +35 -9
  233. package/dist/observability/fail-open.js +35 -9
  234. package/dist/observability/metrics.js +1 -0
  235. package/dist/observability/prompt-manifest.d.ts +3 -17
  236. package/dist/observability/prompt-manifest.js +45 -42
  237. package/dist/observability/tool-trace.js +9 -9
  238. package/dist/operator-ask.d.ts +10 -0
  239. package/dist/operator-ask.js +3 -0
  240. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  241. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  242. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  243. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  244. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  245. package/dist/orchestration/workflow-notify-journal.js +27 -34
  246. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  247. package/dist/orchestration/workflow-park-decision.js +118 -0
  248. package/dist/org-delivery-gate.d.ts +81 -0
  249. package/dist/org-delivery-gate.js +59 -0
  250. package/dist/panel-tool-names.d.ts +23 -0
  251. package/dist/panel-tool-names.js +8 -0
  252. package/dist/parked-decide.d.ts +39 -6
  253. package/dist/parked-decide.js +98 -51
  254. package/dist/parked-revive-surface.d.ts +9 -2
  255. package/dist/parked-revive-surface.js +11 -8
  256. package/dist/permission-rule-list.d.ts +1 -1
  257. package/dist/permission-rule-list.js +2 -2
  258. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  259. package/dist/plugins/approval-ask-store-file.js +21 -0
  260. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  261. package/dist/plugins/approval-ask-store-memory.js +34 -2
  262. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  263. package/dist/plugins/approval-ask-store-sql.js +37 -1
  264. package/dist/plugins/blob-backend.d.ts +38 -25
  265. package/dist/plugins/blob-backend.js +29 -19
  266. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  267. package/dist/plugins/breaker-state-sql.js +4 -4
  268. package/dist/plugins/caching-session-store.d.ts +3 -0
  269. package/dist/plugins/caching-session-store.js +3 -0
  270. package/dist/plugins/checkpoint-store-sql.d.ts +14 -0
  271. package/dist/plugins/checkpoint-store-sql.js +20 -2
  272. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  273. package/dist/plugins/file-history-store-sql.js +3 -1
  274. package/dist/plugins/file-run-store.d.ts +5 -13
  275. package/dist/plugins/file-run-store.js +9 -0
  276. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  277. package/dist/plugins/fork-routing-session-store.js +12 -1
  278. package/dist/plugins/host-platform.d.ts +2 -0
  279. package/dist/plugins/host-platform.js +2 -1
  280. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  281. package/dist/plugins/local-checkpoint-store.js +6 -1
  282. package/dist/plugins/local-session-store.d.ts +1 -1
  283. package/dist/plugins/local-session-window.d.ts +39 -0
  284. package/dist/plugins/local-session-window.js +54 -0
  285. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  286. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  287. package/dist/plugins/mailbox-store-sql.js +77 -52
  288. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  289. package/dist/plugins/memory-run-store.d.ts +5 -13
  290. package/dist/plugins/memory-run-store.js +8 -0
  291. package/dist/plugins/one-time-migrations.d.ts +110 -5
  292. package/dist/plugins/one-time-migrations.js +320 -8
  293. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  294. package/dist/plugins/org-delivery-quota-store.js +228 -0
  295. package/dist/plugins/pg-pool.js +39 -7
  296. package/dist/plugins/pg-session-storage.d.ts +17 -4
  297. package/dist/plugins/pg-session-storage.js +29 -6
  298. package/dist/plugins/remote-env-adb.d.ts +6 -12
  299. package/dist/plugins/remote-env-adb.js +12 -2
  300. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  301. package/dist/plugins/remote-env-k8s.js +23 -5
  302. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  303. package/dist/plugins/remote-env-local-docker.js +12 -9
  304. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  305. package/dist/plugins/remote-env-ssh.js +17 -11
  306. package/dist/plugins/run-store-sql.d.ts +16 -14
  307. package/dist/plugins/run-store-sql.js +22 -2
  308. package/dist/plugins/schema-indexes.js +2 -0
  309. package/dist/plugins/send-user-file.js +2 -2
  310. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  311. package/dist/plugins/session-epoch-anchor.js +2 -3
  312. package/dist/plugins/session-store.d.ts +18 -8
  313. package/dist/plugins/session-store.js +15 -4
  314. package/dist/plugins/sql-driver.d.ts +74 -11
  315. package/dist/plugins/sql-driver.js +210 -12
  316. package/dist/plugins/sql-errors.d.ts +23 -0
  317. package/dist/plugins/sql-errors.js +21 -0
  318. package/dist/plugins/store-backend.d.ts +36 -1
  319. package/dist/plugins/store-backend.js +40 -14
  320. package/dist/plugins/store-contracts.d.ts +42 -0
  321. package/dist/plugins/store-contracts.js +1 -0
  322. package/dist/plugins/tidb-pool.d.ts +6 -1
  323. package/dist/plugins/tidb-pool.js +44 -10
  324. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  325. package/dist/plugins/tidb-session-storage.js +2 -2
  326. package/dist/plugins/tidb-session-store.d.ts +24 -4
  327. package/dist/plugins/tidb-session-store.js +28 -4
  328. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  329. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  330. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  331. package/dist/plugins/workflow-run-store-sql.js +50 -9
  332. package/dist/posture-source.d.ts +18 -10
  333. package/dist/posture-source.js +4 -1
  334. package/dist/project-identity.d.ts +45 -6
  335. package/dist/project-identity.js +162 -8
  336. package/dist/project-layer-key.d.ts +28 -0
  337. package/dist/project-layer-key.js +29 -0
  338. package/dist/question.js +3 -2
  339. package/dist/read-deny-entry.d.ts +25 -0
  340. package/dist/read-deny-entry.js +12 -0
  341. package/dist/read-face-posture.d.ts +37 -11
  342. package/dist/read-face-posture.js +32 -3
  343. package/dist/request-key-closure.d.ts +7 -0
  344. package/dist/request-key-closure.js +9 -1
  345. package/dist/request-value-closure.d.ts +5 -0
  346. package/dist/request-value-closure.js +11 -3
  347. package/dist/rule-entry-list.d.ts +26 -2
  348. package/dist/rule-entry-list.js +72 -12
  349. package/dist/rules-consent.js +3 -4
  350. package/dist/run-acceptance.d.ts +19 -3
  351. package/dist/run-acceptance.js +13 -1
  352. package/dist/run-local.js +36 -6
  353. package/dist/runs.d.ts +10 -9
  354. package/dist/runs.js +21 -3
  355. package/dist/runtime-caps-resolver.d.ts +16 -6
  356. package/dist/runtime-caps-resolver.js +18 -5
  357. package/dist/sandbox-pkg-source.d.ts +19 -1
  358. package/dist/sandbox-pkg-source.js +29 -7
  359. package/dist/security.d.ts +87 -9
  360. package/dist/security.js +52 -9
  361. package/dist/session-error-wire.d.ts +19 -2
  362. package/dist/session-error-wire.js +5 -1
  363. package/dist/session-titled-frame.d.ts +33 -0
  364. package/dist/session-titled-frame.js +4 -0
  365. package/dist/session-titler.d.ts +9 -1
  366. package/dist/session-titler.js +15 -4
  367. package/dist/spec-fields.js +21 -2
  368. package/dist/sql-engine-posture.d.ts +3 -1
  369. package/dist/task-cwd.d.ts +1 -1
  370. package/dist/task-mcp.d.ts +3 -3
  371. package/dist/task-mcp.js +7 -66
  372. package/dist/task-settings.d.ts +89 -88
  373. package/dist/task-settings.js +71 -63
  374. package/dist/text-bidi.d.ts +0 -4
  375. package/dist/text-bidi.js +1 -3
  376. package/dist/tighten-only-seats.d.ts +150 -0
  377. package/dist/tighten-only-seats.js +196 -0
  378. package/dist/tool-approval.d.ts +303 -87
  379. package/dist/tool-approval.js +623 -239
  380. package/dist/trace/core-keyset-guard.d.ts +104 -22
  381. package/dist/trace/exit-seat.d.ts +28 -0
  382. package/dist/trace/exit-seat.js +76 -0
  383. package/dist/trace/ledger-events.d.ts +3 -2
  384. package/dist/trace/project.d.ts +80 -12
  385. package/dist/trace/project.js +41 -28
  386. package/dist/trace/projection-table.d.ts +100 -0
  387. package/dist/trace/projection-table.js +130 -0
  388. package/dist/trace/redact.d.ts +54 -0
  389. package/dist/trace/redact.js +778 -152
  390. package/dist/trace/self-minted-wire.d.ts +345 -1
  391. package/dist/trace/self-minted-wire.js +117 -1
  392. package/dist/trace/wire-projection-faces.d.ts +298 -2
  393. package/dist/trace/wire-projection-faces.js +154 -13
  394. package/dist/url-refusal.js +2 -0
  395. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  396. package/dist/web-admin-client/apply-effective.js +56 -5
  397. package/dist/web-admin-client/facade.d.ts +1 -1
  398. package/dist/web-admin-client/facade.js +1 -1
  399. package/dist/web-admin-client/read-face.js +5 -9
  400. package/dist/web-admin-client/skills-mcp.js +4 -5
  401. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  402. package/package.json +7 -3
package/dist/task-mcp.js CHANGED
@@ -1,14 +1,11 @@
1
1
  import { mcpInjectionDroppedNotice, readMcpToolAxes, resolveComplianceDenies } from "@sema-agent/core";
2
- import { MCP_CONTENT_ORIGINS, describeNotStringArray, describeValueShape, isContentOriginWord, isStringArray, isUsableWireName, readMcpIdentityHeaders, } from "@sema-agent/settings-schema";
3
- import { describeBadContentOrigin, describeBadWireName } from "./caller-text-echo.js";
2
+ import { MCP_CONTENT_ORIGINS, describeBadContentOrigin, describeBadWireName, describeNotStringArray, describeValueShape, isContentOriginWord, isStringArray, isUsableWireName, readRequestMcpTransport, stripControlAndBidi, } from "@sema-agent/settings-schema";
4
3
  import { HttpError, createCodedHttpError } from "./security.js";
5
4
  import { GOVERNANCE_HTTP_STATUS } from "./governance-http-status.js";
6
5
  import { MCP_SOURCE_LABEL_MAX, isMcpSourceLabel, readMcpSourceLabel } from "./mcp-source-label.js";
7
- import { declaresMcpAssertionHeader, describeMcpAssertionHeaderNotAString, describeMcpIdentityHeadersConflict, mcpIdentityHeadersIssue, noteMcpAssertionHeaderIgnored, noteMcpAssertionHeaderNotSent, toCoreMcpServerSpec } from "./mcp-assertion-header.js";
6
+ import { describeMcpAssertionHeaderNotAString, describeMcpIdentityHeadersConflict, mcpIdentityHeadersIssue, noteMcpAssertionHeaderIgnored, noteMcpAssertionHeaderNotSent, specWithholdsMcpAssertionHeader, toCoreMcpServerSpec } from "./mcp-assertion-header.js";
8
7
  import { MAX_KEY_ECHO, echoKeyName, keyClosureClause, scanKeyClosure } from "./request-key-closure.js";
9
- import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
10
8
  import { readMcpToolFaces } from "./mcp-tool-faces.js";
11
- import { readPlainStringRecord } from "./plain-string-record.js";
12
9
  export const MAX_REQUEST_MCP_SERVERS = 32;
13
10
  export const MAX_REQUEST_MCP_DROP_NAMES = MAX_REQUEST_MCP_SERVERS;
14
11
  export const MCP_SERVER_ENTRY_KEYS = ["allowTools", "contentOrigin", "elicitation", "name", "source", "startupTimeoutMs", "toolAxes", "toolFaces", "transport"];
@@ -27,62 +24,6 @@ function isRecord(v) {
27
24
  function isElicitationFlag(v) {
28
25
  return typeof v === "boolean";
29
26
  }
30
- const transportBad = (path, reason) => ({ ok: false, issue: { path, reason } });
31
- function readRequestTransport(t) {
32
- if (!t || typeof t !== "object")
33
- return transportBad("transport", `must be an object with a "kind" of "stdio" or "http" — got ${describeValueShape(t)}`);
34
- const tr = t;
35
- const lost = [];
36
- if (tr.kind === "stdio") {
37
- if (typeof tr.command !== "string" || tr.command.length === 0)
38
- return transportBad("transport.command", `must be a non-empty string (the command to run) — got ${describeValueShape(tr.command)}`);
39
- if (tr.args !== undefined && !isStringArray(tr.args))
40
- lost.push({ path: "transport.args", reason: `must be an array of strings — got ${describeNotStringArray(tr.args)}` });
41
- const env = readTransportRecord("transport.env", tr.env, lost);
42
- return {
43
- ok: true,
44
- transport: {
45
- kind: "stdio",
46
- command: tr.command,
47
- ...(isStringArray(tr.args) ? { args: tr.args } : {}),
48
- ...(env !== undefined ? { env } : {}),
49
- },
50
- lost,
51
- };
52
- }
53
- if (tr.kind === "http") {
54
- if (typeof tr.url !== "string" || !/^https?:\/\//i.test(tr.url))
55
- return transportBad("transport.url", "must be an absolute http(s) URL (put credentials in transport.headers, never in the URL)");
56
- const ids = readMcpIdentityHeaders(tr);
57
- const headers = readTransportRecord("transport.headers", tr.headers, lost);
58
- if (tr.principalHeader !== undefined && ids.principalHeader === undefined) {
59
- lost.push({ path: "transport.principalHeader", reason: `must be a string (the HTTP header NAME the end-user principal is injected into) — got ${describeValueShape(tr.principalHeader)}` });
60
- }
61
- return {
62
- ok: true,
63
- transport: {
64
- kind: "http",
65
- url: tr.url,
66
- ...(headers !== undefined ? { headers } : {}),
67
- ...ids,
68
- },
69
- lost,
70
- };
71
- }
72
- return transportBad("transport.kind", `must be "stdio" or "http" — got ${describeValueShape(tr.kind)}`);
73
- }
74
- function readTransportRecord(path, raw, lost) {
75
- if (raw === undefined)
76
- return undefined;
77
- const read = readPlainStringRecord(raw);
78
- if (!read.ok) {
79
- lost.push({ path, reason: `must be a plain object of string values — ${read.member === undefined ? read.fault : `its member "${echoKeyName("", read.member)}" ${read.fault}`}` });
80
- return undefined;
81
- }
82
- for (const m of read.stripped)
83
- lost.push({ path: echoKeyName(`${path}.`, m.name), reason: m.fault });
84
- return read.record;
85
- }
86
27
  const bad = (field) => ({ ok: false, field });
87
28
  const MALFORMED_NAME = "<malformed>";
88
29
  function declaredName(e) {
@@ -96,7 +37,7 @@ function normalizeServer(e, noteBadOrigin, storedToolAxes) {
96
37
  const o = e;
97
38
  if (!isUsableWireName(o.name))
98
39
  return bad("name");
99
- const read = readRequestTransport(o.transport);
40
+ const read = readRequestMcpTransport(o.transport);
100
41
  if (!read.ok)
101
42
  return bad(read.issue.path);
102
43
  const spec = { name: o.name, transport: read.transport };
@@ -114,7 +55,7 @@ function normalizeServer(e, noteBadOrigin, storedToolAxes) {
114
55
  const again = readMcpToolAxes(storedToolAxes.mcp(o.toolAxes));
115
56
  if (again.ok) {
116
57
  judged = again;
117
- toolAxesReread = axes.problem.replace(CONTROL_AND_BIDI_STRIP_RE, "");
58
+ toolAxesReread = stripControlAndBidi(axes.problem);
118
59
  }
119
60
  }
120
61
  if (!judged.ok)
@@ -257,7 +198,7 @@ const ENTRY_KEY_JUDGES = {
257
198
  return read.ok ? undefined : { path: "toolFaces", reason: read.problem };
258
199
  },
259
200
  transport: (o) => {
260
- const read = readRequestTransport(o.transport);
201
+ const read = readRequestMcpTransport(o.transport);
261
202
  return read.ok ? read.lost[0] : read.issue;
262
203
  },
263
204
  };
@@ -267,7 +208,7 @@ function entryFieldRefusal(entry, at, issue) {
267
208
  const server = echoKeyName("", declaredName(entry));
268
209
  return {
269
210
  errorCode: "request.field_invalid",
270
- message: `${at}.${issue.path} (server "${server}") is not a usable declaration — ${issue.reason.replace(CONTROL_AND_BIDI_STRIP_RE, "")}. ${ENTRY_REFUSAL_TAIL}`,
211
+ message: `${at}.${issue.path} (server "${server}") is not a usable declaration — ${stripControlAndBidi(issue.reason)}. ${ENTRY_REFUSAL_TAIL}`,
271
212
  };
272
213
  }
273
214
  function requestEntryRefusal(entry, at) {
@@ -341,7 +282,7 @@ function classifyHonored(baseline, entries, config, logger, storedToolAxes) {
341
282
  const closed = deploymentClosedMcpNames(baseline, reservedNames);
342
283
  const blocked = v.ok.filter((s) => closed.has(s.name)).map((s) => s.name);
343
284
  for (const s of v.ok)
344
- if (declaresMcpAssertionHeader(s) && !closed.has(s.name))
285
+ if (specWithholdsMcpAssertionHeader(s) && !closed.has(s.name))
345
286
  noteMcpAssertionHeaderNotSent(logger, s.name);
346
287
  const mounted = new Set(v.ok.filter((s) => !closed.has(s.name)).map((s) => s.name));
347
288
  for (const e of entries.slice(0, MAX_REQUEST_MCP_SERVERS)) {
@@ -27,12 +27,12 @@
27
27
  * `APPROVAL_REQUIRE` (an ask rule), `APPROVAL_NEVER_AUTO` (a person, mandated), `MANUAL_MODE_SHELL_GATE=always` (shell).
28
28
  * A request-carried skill's `allowedTools` is the same member's twin (same grammar, same predicate, same admission judge
29
29
  * `rule-entry-list.ts`). Pinned on the real assembly: `test/allow-layer-operator-knobs.test.ts`.
30
- * - permissionMode(轴B #2 注释保鲜,1.254——[ref]/[ref] 后的真实现):`defaultMode` 收 core `PERMISSION_MODES` **全集**
31
- * (default | acceptEdits | plan | auto | bypassPermissions | dontAsk),bypass/auto 被 HONOR 为 gate-shape 选择
32
- * ——但深层不变量未变:bypass=「不加 ask 门」,恒不越部署基线(tightenTaskSpec deny-wins,基线 deny/
33
- * ask 照压);精化语义见 :2xx 行内注释。旧头注的「NEVER honored/三模式白名单」是 pre-[ref] 拍照。
30
+ * - permissionMode:`defaultMode` 收 core `PERMISSION_MODES` **全集**(default | acceptEdits | plan | auto | bypassPermissions | dontAsk),
31
+ * 生效词原样过境 `TaskSpec.permissionMode`,模式**做什么**只在引擎里答(core `modePolicyOf` / `arbitrateByMode`)。本模块的折叠
32
+ * **不读**模式词:deny / ask 两张表在每一个词下编出同一只策略,部署基线照压(tightenTaskSpec deny-wins);bypass 放行的只是引擎
33
+ * 能放行的那几类问,部署 / 请求的 deny 与 ask 规则它一条都掀不掉。
34
34
  *
35
- * 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy + §6.4 permissionMode derive MIRRORS
35
+ * 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy compile MIRRORS
36
36
  * the shell's LOCAL-Runner resolver — both compose the SAME core primitives (`createAllowDenyPolicy` /
37
37
  * `combinePolicies` / `tightenTaskSpec`), so the deny-wins ENFORCEMENT is core-single-source. Only the COMPOSITION
38
38
  * is duplicated for the remote path; a proposed follow-up extracts it to `@sema-agent/sdk` for true
@@ -47,27 +47,29 @@
47
47
  * - (`hooks` NO LONGER deferred either — 轴B #2 注释保鲜:applied 形已接线(本文件 hooks 分片 +
48
48
  * main.ts 单用户闸),仅 malformed 才报 deferred;旧「需要 remote hook-runner」是接线前拍照。)
49
49
  */
50
- import { type PathRuleBases, type ExecutionEnv, type TaskSpec, type ThinkingLevel, type ToolPolicy, type PermissionMode } from "@sema-agent/core";
50
+ import { type PathRuleBases, type TaskSpec, type ThinkingLevel, type ToolPolicy, type PermissionMode } from "@sema-agent/core";
51
+ import { type EntryProblem } from "./entry-problems.js";
51
52
  import { type KeyClosureIssue } from "./request-key-closure.js";
52
53
  import { type RunnableHooksConfig } from "./hooks/hook-runner.js";
53
54
  import type { StoredHooksRereadM20 } from "./stored-request-hooks-m20.js";
54
55
  import { type EntryPermissionMode } from "./runtime-governance.js";
56
+ import { type TightenOnlySeatValues } from "./tighten-only-seats.js";
55
57
  /**
56
58
  * 请求面 `permissionMode` 的闭集 = core `PERMISSION_MODES` **全集**(顶层 `permissionMode` / `settings.permissions.defaultMode` /
57
59
  * `?permissionMode=` 查询串三处同读)。本仓不持有第二份词表,也不持有「收 / 不收」的表态:判据 = core 的 `isPermissionMode`,型 = core 的
58
- * `PermissionMode`,wire 句子里的词表只从这里取词({@link PERMISSION_MODE_WORDS})。core 加一个词 ⇒ 请求面自动收它,它在派生腿上的去向由
59
- * {@link deriveSettingsPolicy} 的穷举 `switch` 逼出来(缺一臂 ⇒ 编译红);core 删 / 改名一个词 ⇒ 本文件里按名写出它的那一臂编译红。
60
+ * `PermissionMode`,wire 句子里的词表只从这里取词({@link PERMISSION_MODE_WORDS})。core 加一个词 ⇒ 请求面自动收它、原样过境,本仓没有
61
+ * 按词分的臂要补;core 删 / 改名一个词 ⇒ 本仓按名写出它的地方(`PLAN_APPROVE_PERMISSION_MODES_AFTER` 等)编译红。
60
62
  * 生效模式原样过境 `TaskSpec.permissionMode`(S-877):引擎自己解释模式 —— 含 `dontAsk`(CC 的「自动拒」档:凡是要问的一律由模式拒,零卡,
61
- * 门记录 `deniedBy:"mode"`),本仓不另写判。
63
+ * 门记录 `deniedBy:"mode"`)与 acceptEdits 的免问写域(引擎的写根:任务根 + `additionalDirectories` + 宣告的可写目录),本仓不另写判。
62
64
  */
63
65
  /** 请求面闭集的 wire 文案形(`"a" | "b" | …`,core 序)—— 三处 400(顶层 / bundle / 查询串)的句子从这里取词,不再各抄一份。 */
64
66
  export declare const PERMISSION_MODE_WORDS: string;
65
67
  /**
66
68
  * R4: coerce a raw top-level `body.permissionMode` (the LIGHT per-turn wire — the shell sends
67
69
  * the CC permission mode RAW, axis-agnostic; the service interprets) to a service-honored mode, or undefined.
68
- * 🔴 TIGHTEN-ONLY vs the DEPLOYMENT baseline still holds for every value: the mode only selects the CLIENT-derived
69
- * gate ({@link deriveSettingsPolicy}); it can never subtract from the deployment/operator policy (applyTaskSettings
70
- * folds via tightenTaskSpec, deny-wins). The honored set is core's `PERMISSION_MODES` in full — every word passes
70
+ * 🔴 TIGHTEN-ONLY vs the DEPLOYMENT baseline still holds for every value: the word rides verbatim into `TaskSpec.permissionMode`
71
+ * and only the engine interprets it; no mode subtracts from the deployment/operator policy or from the request's own
72
+ * deny / ask rules (applyTaskSettings folds them via tightenTaskSpec, deny-wins, under every word alike). The honored set is core's `PERMISSION_MODES` in full — every word passes
71
73
  * through verbatim (`dontAsk` included: folding the auto-deny mode to `default`, the asking mode, would turn a refusal
72
74
  * into a card). An UNKNOWN string coerces to `default` (fail-safe: the most-asking mode).
73
75
  * [ref]-②: fresh submits can no longer REACH the unknown-word arm — the HTTP gate 400s a non-member value
@@ -147,19 +149,13 @@ export declare function storedBodyPermissionMode(body: {
147
149
  * (= "max"), never a hardcoded literal — so an explicit higher tier still wins (none exists above max today;
148
150
  * future-proof). Awareness rides for free: core composes ORCHESTRATION_AWARENESS from thinking∈{xhigh,max}, no field. */
149
151
  export declare function effectiveThinking(reasoningEffort: unknown, ultracode: boolean): ThinkingLevel | undefined;
150
- /** R4: fold a top-level `body.permissionMode` onto the parsed settings as `permissions.defaultMode` (the top-level
151
- * field is the explicit per-turn intent → it WINS over a bundle defaultMode). Creates a minimal settings object when
152
- * no `body.settings` bundle was sent. The result flows through {@link applyTaskSettings} (tighten-only). */
153
- export declare function withPermissionMode(settings: ParsedTaskSettings | undefined, mode: PermissionMode): ParsedTaskSettings;
154
152
  /**
155
- * [ref] §6-1 —— 本请求的**生效** permission mode,单点。优先序逐字同 {@link withPermissionMode}:
156
- * 顶层 `body.permissionMode`(本轮显式表态)赢过 bundle 的 `settings.permissions.defaultMode`;两处
157
- * 都没有 ⇒ `undefined` = **无表态**(调用点据此不写键,而不是替调用方选一个默认值)。
153
+ * [ref] §6-1 —— 本请求的**生效** permission mode,单点。优先序:顶层 `body.permissionMode`(本轮显式表态)赢过 bundle 的
154
+ * `settings.permissions.defaultMode`;两处都没有 ⇒ `undefined` = **无表态**(调用点据此不写键,而不是替调用方选一个默认值;引擎把缺席读成 `default`)。
158
155
  *
159
- * 🔴 为什么必须是一只函数:同一个「生效模式」此前在 resolve-spec 里被算了两次(hooks 腿的
160
- * `permission_mode` 载荷、settings 折叠腿的 `withPermissionMode`),三审同点判定翻译表**不得**成为
161
- * 第三个算点 —— 三处各算各的,任何一次优先序修订都会让三面分家,而分家在这条轴上的形态是
162
- * 「壳发的 bundle bypass 在 A 面生效、在 B 面没生效」这种最难被外部发现的静默偏差。
156
+ * 🔴 为什么必须是一只函数:同一个「生效模式」此前在 resolve-spec 里被算过两次(hooks 腿的 `permission_mode` 载荷、settings 折叠腿),
157
+ * 两处各算各的,任何一次优先序修订都会让两面分家,而分家在这条轴上的形态是「壳发的 bundle bypass 在 A 面生效、在 B 面没生效」这种
158
+ * 最难被外部发现的静默偏差。settings 折叠今天不再读模式词,这只函数的读者是 spec 过境点、托管天花板与存储体读法。
163
159
  */
164
160
  export declare function effectivePermissionMode(body: {
165
161
  permissionMode?: unknown;
@@ -225,6 +221,10 @@ export interface ParsedTaskSettings {
225
221
  skillListingBudgetFraction?: number;
226
222
  /** 同族第二键:每条技能描述在清单里的字符帽(正整数;CC 默认 1536)。超出由引擎**截断**,不是拒。 */
227
223
  skillListingMaxDescChars?: number;
224
+ /** S-1351 —— 「只收紧」座位族(`tighten-only-seats.ts` 的四座:读拒模式 / 写保护名的加法 / 合规额外禁项 / 永不自动放行名单)的归一值,**一个键**而不是四个散字段:
225
+ * wire 位置由座位表说(三座在 `settings` 顶层,`neverAuto` 在 `settings.permissions`),解析后与位置无关。空数组 ≡ 缺席(不铸键)。
226
+ * 去处:三座经 {@link applyTaskSettings} 落 core 任务层席;`neverAuto` 经 {@link deriveSettingsPolicy} 落请求叶策略。 */
227
+ tightenOnly?: TightenOnlySeatValues;
228
228
  }
229
229
  /** The result of parsing an untrusted `body.settings`: the applied subset + the names of present-but-deferred
230
230
  * fields (so the caller can log/advertise them — no silent drop). `null` settings ⇒ `{ settings: undefined }`. */
@@ -285,13 +285,17 @@ export declare function settingsPermissionBucketIssue(perms: unknown): SettingsP
285
285
  * {@link parseTaskSettings};`webSearch` 在 `capabilities/scenarios.ts`(判决 `judgeRequestWebSearch`,单用户闸;形错在受理面 400,S-199)。
286
286
  * 加键必须同时加消费点,否则就是往闭集里塞一个新的静默丢。
287
287
  *
288
+ * 🔴 `readDenyPatterns` / `writeProtectedExtra` / `complianceAdditionalDenies` 与 `permissions.neverAuto`(S-1351)= **「只收紧」座位族**:消费点 = `tighten-only-seats.ts`
289
+ * 的座位表(位置、条目律、去处都由那张表说),读入在 {@link parseTaskSettings},投影在 {@link applyTaskSettings} / {@link deriveSettingsPolicy}。这四个键不是 CC settings 键
290
+ * (sdk 的 `SemaSettings` 尚未声明 —— 对账门 `test/task-settings-sdk-key-parity.test.ts` 的「server 先于 sdk」登记表记着它们)。
291
+ *
288
292
  * 🔴 两个 `skillListing*`([ref],7.77.0)= **CC settings 同名键**,值域抄 CC 的 schema 声明
289
293
  * (`skillListingBudgetFraction` 是 `gt(0).lte(1)`、`skillListingMaxDescChars` 是 `int().positive()`);
290
294
  * 消费点 = 本文件的 parse + `boot/resolve-spec.ts` 的 `TaskSpec` 透传。语义(预算怎么花、描述怎么裁、
291
295
  * 溢出怎么退成 name-only)整个归引擎,本仓一个字节都不渲染,也**不复刻默认值**——缺席即整键不写。 */
292
- export declare const TASK_SETTINGS_KEYS: readonly ["env", "hooks", "model", "outputStyle", "permissions", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch"];
296
+ export declare const TASK_SETTINGS_KEYS: readonly ["complianceAdditionalDenies", "env", "hooks", "model", "outputStyle", "permissions", "readDenyPatterns", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch", "writeProtectedExtra"];
293
297
  /** 本 service 消费的 `settings.permissions` 子键 —— 闭集(值形校验另有既有门,本门只判键名)。 */
294
- export declare const TASK_SETTINGS_PERMISSION_KEYS: readonly ["allow", "ask", "defaultMode", "deny", "disableAutoMode"];
298
+ export declare const TASK_SETTINGS_PERMISSION_KEYS: readonly ["allow", "ask", "defaultMode", "deny", "disableAutoMode", "neverAuto"];
295
299
  /** CC/SDK 合约里合法、本 service **不接线**的顶层键。词表外的 CC 键落 `unknown` —— 两列都是 400,标签只影响
296
300
  * 文案,不影响判决。前三个的出处 = `@sema-agent/sdk` `SemaSettings` 尾注逐字点名的 deferred CC 键。
297
301
  *
@@ -354,53 +358,35 @@ export declare function parseTaskSettings(raw: unknown, seats?: ParseTaskSetting
354
358
  * A well-formed rider always mounts: the engine (core 7.52.0) lands it in its own task-append band whatever the role
355
359
  * text is — there is no "already-assembled" pass-through arm left that could drop it. */
356
360
  export declare function acceptAppendSystemPrompt(v: unknown, warn?: (detail: string) => void): string | undefined;
361
+ export declare function createWorkflowAskPolicy(isExempt?: WorkflowGateWiring["isExempt"]): ToolPolicy;
357
362
  /** [ref]②/codex F2 — what the workflow ask leg needs from the deployment, on EVERY lane. It is name-keyed and
358
- * fs-independent, so it never had the lane split {@link FsWriteGateWiring} carried (that split is itself gone
359
- * since [ref] — the sandbox lanes wire a gate of their own shape instead of no gate). */
363
+ * fs-independent: one shape on every execution lane. */
360
364
  export interface WorkflowGateWiring {
361
- /** The session "don't ask again" probe (approvalExemptionStore.has, canonical toolName key) — same store and
362
- * key space as the fs-write gate's probe; one remember="session" grant serves both. */
365
+ /** The session "don't ask again" probe (approvalExemptionStore.has, raw toolName key) — the same store and key space the
366
+ * approval seat's standing grants read; one remember="session" grant serves them all. */
363
367
  isExempt?: (toolName: string) => boolean | Promise<boolean>;
364
368
  }
365
- /** [ref]/[ref]① — everything the mode-derived fs-write ask gate needs from the deployment, provided by
366
- * `resolve-spec.ts`. Absent ⇒ no gate is derived (the pre-[ref] behavior).
367
- *
368
- * WHY the `env` matters: core's `createFsWriteGatePolicy` canonicalizes every target/dir through the given `env`
369
- * (real `exists`/`canonicalPath`/`readLink` fs access — read in dist, fs-write-gate-policy.js), so on a
370
- * HOST-SEMANTICS lane (`REMOTE_EXEC` unset or "host") the env MUST be the fs the hand tools write.
369
+ /**
370
+ * 请求的 deny / ask 两张表解析路径形规则用的**基**(`resolve-spec.ts` 每请求供)。只有这两件事:这条 task 的真根、执行环境的 home。
371
+ * 缺席 ⇒ 不声明(规则锚在装入这只策略的那条腿的真根,`~/` 形由 {@link rejectUnmatchableSettingsNames} 响亮拒)。
371
372
  *
372
- * [ref]/[ref] — the sandbox lanes (e2b/k8s/ssh/adb/local-docker) wire a gate TOO, but a different-shaped one: the
373
- * tools run OFF this box and the per-task sandbox env is minted inside core (executionEnvFactory) AFTER spec
374
- * build, so a worker-local env would adjudicate against the WRONG fs (a wrong ALLOW is worse than no gate — that
375
- * is why [ref] left those lanes gate-less). They supply a `DeferredSandboxPathEnv`
376
- * (`src/boot/deferred-sandbox-path-env.ts`) instead: a proxy that forwards the fs READ primitives to the task's
377
- * REAL sandbox env at adjudication time (a per-session slot the factory decorator fills), keeping only
378
- * `absolutePath` lexical so no relative path is resolved against the wrong base. Empty slot ⇒ fail-closed. */
373
+ * 修前本型还承运本仓自己的 acceptEdits cwd 域写门的四件(裁决 env / cwd / scratchpad 豁免域 / 会话豁免探针):acceptEdits 能免问写哪里
374
+ * 现在只由引擎的模式门答(写根 = 任务根 + `additionalDirectories` + 宣告的可写目录),本仓不再构造写门,那四件随之退役。
375
+ * 部署级旋钮(`SENSITIVE_WRITE_PATTERNS` 守卫集、`MANUAL_MODE_SHELL_GATE` 地板)早已不经本型:它们在治理层无条件施加
376
+ * (`runtime-governance.ts` `applyRuntimeGovernance`),client 表态掀不掉([ref] / [ref])。
377
+ */
379
378
  export interface FsWriteGateWiring {
380
- /** The env the gate canonicalizes against — the worker host env on the host lane, the
381
- * `DeferredSandboxPathEnv` proxy over the task's real sandbox env on the sandbox lanes ([ref]). */
382
- env: ExecutionEnv;
383
- /** The task's working directory: the factory's `rootPath` (relative-path base) AND the acceptEdits accept domain.
384
- * ABSENT on the sandbox lanes ([ref]/[ref]): the sandbox cwd is the ENGINE's tracked cwd, not the env's own, so
385
- * neither spec time nor the env proxy can supply the right base — inventing one would mint a bogus auto-allow
386
- * domain. With it absent the gate gets no `rootPath` and no `acceptDirs`, so relative paths fail to resolve
387
- * (⇒ ask) and `acceptEdits` degrades to the `default` arm — the same fail-safe direction as the host lane's
388
- * never-created sentinel dir (resolve-spec 修5). */
389
- cwd?: string;
390
379
  /**
391
- * 🔴 S-177 / codex r1 [high](验真后修)—— **权限规则**的路径基,与上面那个 `cwd` **刻意分成两个字段**。
380
+ * 🔴 S-177 / codex r1 [high](验真后修)—— **权限规则**的路径基(core `PathRuleBases.root`),**只在真任务根已知时**在场。
392
381
  *
393
- * 两者在 host 腿上常常同值,但它们回答的不是同一个问题,而混用一个字段会让其中一个静默失效:
394
- * · `cwd` 是**写门**的基。它在「有 remoteExec 但这条 session 还没登记工作目录」时取的是一个
395
- * **永不创建的哨兵目录**(`resolve-spec` 的 `fs-write-gate-unrooted`)。对写门那是 fail-SAFE 的:
396
- * 相对目标在哨兵下解析不出真身 ⇒ 落 ask。
397
- * · `taskRoot` 是**规则模式**的基(core `PathRuleBases.root`)。规则编译器按**词法**匹配,不问目录
398
- * 存不存在 ⇒ 把哨兵递给它,`deny Edit(src/**)` 会编译成功、指向一个谁也不会写的目录,对真实工作区
399
- * 的 `<工作区>/src/secret.ts` 这类目标判 allow —— 一条运维亲手写下的收紧规则**静默失效**,方向与写门那条正相反。
382
+ * host 腿上「这条 session 还没登记工作目录」时,`resolve-spec` 的路径裁决 env 落在一个**永不创建的哨兵目录**上
383
+ * (`fs-write-gate-unrooted`,治理层守卫集的 cwd)。那对守卫是 fail-SAFE 的(相对目标在哨兵下解析不出真身);但规则编译器按**词法**匹配、
384
+ * 不问目录存不存在 ⇒ 把哨兵当根递进来,`deny Edit(src/**)` 会编译成功、指向一个谁也不会写的目录,对真实工作区的
385
+ * `<工作区>/src/secret.ts` 判 allow —— 一条亲手写下的收紧规则**静默失效**。所以哨兵从不被声明成基。
400
386
  *
401
- * ⇒ 本字段**只在真任务根已知时**在场。缺席 ⇒ 不声明根 ⇒ 需要该基的拼法(`Edit(src/**)` / `Edit(/etc/**)`)锚在**装入这只策略的那条腿**
402
- * 的真根(core 7.46.0 #1383 车 B:锚装一次、在被装入处;`unsupported.path_base` 只剩「声明了一个用不了的基」)—— 哨兵从不被声明成基。
403
- * 修前(core ≤7.45)缺席 ⇒ 整表拒(→ 422):沙箱车道上相对 / `/x` 形规则恒 422。绝对形(`//abs`)不需要基;`~/` 形见下一字段。
387
+ * 缺席 ⇒ 不声明根 ⇒ 需要该基的拼法(`Edit(src/**)` / `Edit(/etc/**)`)锚在**装入这只策略的那条腿**的真根(core 7.46.0 #1383 车 B:
388
+ * 锚装一次、在被装入处;`unsupported.path_base` 只剩「声明了一个用不了的基」)。修前(core ≤7.45)缺席 ⇒ 整表拒(→ 422):沙箱车道上
389
+ * 相对 / `/x` 形规则恒 422。绝对形(`//abs`)不需要基;`~/` 形见下一字段。
404
390
  */
405
391
  taskRoot?: string;
406
392
  /**
@@ -430,29 +416,20 @@ export interface FsWriteGateWiring {
430
416
  * 运维在**下单那一刻**就知道这条规则这条车道读不了,而不是等到跑起来每次都弹一张 ask。
431
417
  */
432
418
  taskHome?: string;
433
- /** The session scratchpad dir (envFacts.scratchpadDir, [ref]③) — writes there are always auto-allowed. */
434
- scratchpadDir?: string;
435
- /** [ref]① / core 1.294 exemption seam: the session "don't ask again" probe (approvalExemptionStore.has),
436
- * called by core as `(canonicalToolName, canonicalPath)`. The host arm ignores the second argument (the key
437
- * comes from a real-fs canonicalize and the grant is deliberately name-keyed); the sandbox arm ([ref]) uses it
438
- * to confine the exemption to POSIX-absolute canonical keys — core's `canonicalizeTarget` short-circuits
439
- * backslash-UNC forms to `ok:true, key=raw` WITHOUT consulting the env, and an unconfined name-keyed grant
440
- * would turn those unresolvable forms into an allow (codex review 2026-08-05).
441
- * 🔴 **坐标刷新(7.74.0 / core 7.17.0 [ref];结论不变,前提收窄了)**:那条短路现在**只在 `win` 家族上**
442
- * (`dist/tools/fs/safety.js` 的 `canonicalizeTarget`:`family === "win" && isUncSpelling(...)` 才折 UNC
443
- * 并直接返回);在 `posix` 家族上,同一个反斜杠 UNC 拼法在更早一步的 `win32NamespaceScreen` 上就被
444
- * **拒**(`unc_on_posix_tree`),压根到不了短路。⇒ 今日部署形(posix 树)这条腿的暴露面比当年更小,
445
- * 而本臂的 POSIX-absolute 收敛**继续是对的**:它挡的是「未经 env 解析的 key 拿到 name-keyed 放行」,
446
- * 在两个家族上都成立,且方向仍是 fail-closed。不改实现。
447
- * The probe is consulted by the gate RIGHT BEFORE it would ask (after the exempt/accept dir layering — dist 亲读:true ⇒
448
- * allow with decisionReason "rule", a THROWN probe ⇒ not exempt = fail-closed to ask). Same canonical
449
- * toolName key space as the ask-policy layer's exemption probe — ONE grant serves both layers; the gate-level
450
- * check is what makes "allow all session" bite SAME-TURN for the parent and inherited child tasks (the ask
451
- * path is never re-entered). (codex M1 的边界注记:sensitive-path DENY 腿与本探针的「豁免越不过 deny」
452
- * 保证仍成立——但那条腿已随 [ref] 搬到 governance 层,deny-wins 是 tightenTaskSpec 折叠给的,不再依赖
453
- * 本 wiring 的组合点。) */
454
- isExempt?: (toolName: string, canonicalPath: string) => boolean | Promise<boolean>;
455
419
  }
420
+ /**
421
+ * 请求的 `settings.permissions.deny` / `ask` 有永远不生效的条目 ⇒ 拒点({@link rejectUnmatchableSettingsNames})抛的错:句子(`message`)与这一遍判下来的**全部**问题(`problems`,机读位的原料)。
422
+ * `resolveSpec` 的折叠口把它装成 422 体(句子照旧、码 {@link SETTINGS_RULE_REFUSAL_CODE}、体带 `field` + `detail.problems`);其余出口(收紧不得放宽)仍抛普通 `Error`。
423
+ */
424
+ export declare class SettingsRuleRefusalError extends Error {
425
+ readonly problems: readonly EntryProblem[];
426
+ constructor(message: string, problems: readonly EntryProblem[]);
427
+ }
428
+ /**
429
+ * 请求设置里 deny / ask 规则拒的**码**:422 在折叠口上的状态派生粗码(`http/send.ts` 的 `httpErrorCode(422)`;`test/entry-problems.test.ts` 钉两者同值)。拒点铸 422 体、存体预判铸 409 的 `blockedBy`、
430
+ * 机读位每条问题的 `code` 三处读这一只常量,不各写一份字面量。
431
+ */
432
+ export declare const SETTINGS_RULE_REFUSAL_CODE = "request.unprocessable";
456
433
  /**
457
434
  * deny / ask 两桶(core 规则编译器读的收紧表)的**问序,单表**:{@link rulePolicyBucketsRefusal} 的两段循环(名字层 + 文法 · `~/` 要 home)都迭代它 ——
458
435
  * 两桶都有坏条目时,拒点与存体预判点名同一个桶、说同一句。表里每个词同时是 core 规则的 `behavior`。
@@ -461,7 +438,8 @@ export declare const RULE_POLICY_BUCKETS: readonly ["ask", "deny"];
461
438
  export type RulePolicyBucket = (typeof RULE_POLICY_BUCKETS)[number];
462
439
  /**
463
440
  * deny / ask 两桶的**完整规则判**,唯一一只(拒点 {@link rejectUnmatchableSettingsNames} 与存体预判 `http/stored-body-replay.ts` 同调):
464
- * ② 按 {@link RULE_POLICY_BUCKETS} 的序逐桶问 `unmatchableToolNamesRefusal`(名字层 + core 规则文法);③ 都过了,再逐桶判 `~/` 形要 home 的那一拒。第一个坏处答 `{ bucket, message }`。
441
+ * ② 按 {@link RULE_POLICY_BUCKETS} 的序逐桶问 `judgeUnmatchableToolNames`(名字层 + core 规则文法);③ 再逐桶判 `~/` 形要 home 的那一拒。答 `{ bucket, message, problems }`:`bucket` 与 `message` 是**第一处**坏处的
442
+ * (句子冻结,先撞上的那一条),`problems` 是**两段、两只桶判下来的全部**坏条目(机读位的原料,形的属主 `entry-problems.ts`)。
465
443
  * 入参:桶、{@link RulePolicyBases}。**home 同源**:拒点的 home 是 `resolve-spec.ts` 的 `laneHomeBase()` 经 `executionLaneHomeDir(config)` 算出的,预判传同一个函数对同一份部署配置算出的。
466
444
  * **声明给文法的基**只有拒点有(根 + home 的并集,执行车道才知道根):core 的规则文法对**没声明**的基不下判词(见 `config.ts` `uncompilableRuleGuidance`),所以预判什么也不声明、两腿逐字同句;
467
445
  * 预判不能把 home 当「半个基」声明给文法 —— core 的路径族只从根推,缺根时一个合法的 Windows 形 home 会按默认族被判 `unsupported.path_base`(V6-k)。
@@ -476,12 +454,35 @@ export interface RulePolicyBases {
476
454
  export declare function rulePolicyBucketsRefusal(permissions: Readonly<Partial<Record<RulePolicyBucket, readonly string[]>>>, bases: RulePolicyBases): {
477
455
  readonly bucket: RulePolicyBucket;
478
456
  readonly message: string;
457
+ readonly problems: readonly EntryProblem[];
479
458
  } | undefined;
480
459
  /** 请求的 settings 编不成生效的规则 / 有永远不生效的条目 ⇒ 422 的句首(三只桶同一个出口;`resolveSpec` 的拒点与存体重放预判的 409 句子同用这一个,不各写一份)。 */
481
460
  export declare const REQUEST_SETTINGS_REFUSAL_PREFIX = "request settings cannot be applied as written: ";
482
- export declare function deriveSettingsPolicy(settings: ParsedTaskSettings, gate?: FsWriteGateWiring, workflowGate?: WorkflowGateWiring): {
461
+ /**
462
+ * Build the per-request permission ToolPolicy from the parsed settings: the two **rule lists** (`deny` / `ask`) through ONE compiler
463
+ * ({@link createRuleListPolicy} → core `createPermissionRulePolicy`) — a `deny` rule hard-blocks, an `ask` rule forces an approval
464
+ * gate, `deny` > `ask` on overlap. 两表的 **covering 语义同源**([ref]):底下是 core 的同一只 `namespacedRuleNameCovers`,本仓不持第二套 glob。
465
+ * The `allow` bucket is not here: a policy says deny / ask only (core 7.42.0); the list rides into `TaskSpec.allowedTools` at
466
+ * {@link applyTaskSettings}, the one write point.
467
+ *
468
+ * 🔴 **本函数不读模式词**:两张表在六个词与缺席下编出同一只策略(`test/settings-fold-mode-arms.test.ts` A2)。模式做什么只在引擎里答 ——
469
+ * 写门(`default` / `auto` / `dontAsk`:每次写先问;`acceptEdits`:写根内免问;`plan`:写与非只读调用以计划句问;`bypassPermissions`:不设门)
470
+ * 是引擎的模式门,`Workflow` 的问句腿在 `resolve-spec.ts` 按「这条 run 挂不挂得出 Workflow」装、由引擎的仲裁按模式处置({@link createWorkflowAskPolicy})。
471
+ * 修前这里按模式分四臂(acceptEdits 另铸一只 cwd 域写门、bypass / 缺席不装问句腿):本仓对模式的第二份解释,随之退役。
472
+ * Returns `{}` when there is no permission rule (nothing to project).
473
+ */
474
+ export declare function deriveSettingsPolicy(settings: ParsedTaskSettings, bases?: FsWriteGateWiring): {
483
475
  toolPolicy?: ToolPolicy;
484
476
  };
477
+ /**
478
+ * 请求的 `settings.permissions.neverAuto` 有永远不生效的名字 ⇒ 拒因(句子 + 机读位),与 {@link rulePolicyBucketsRefusal} 同形 —— 拒点({@link deriveSettingsPolicy},422)与存体预判
479
+ * (`http/stored-body-replay.ts`)调这一只。判据与部署 `APPROVAL_NEVER_AUTO` 的 env 腿是**同一只**(`unmatchableToolNamesRefusal` 的名表消费者:退役名 / 无协议前缀的短名 / 缺段协议名 /
480
+ * 近似名 …),一条规则一种读法;机读位的 `field` = 座位在体内的坐标。无名字 / 全合法 ⇒ `undefined`。
481
+ */
482
+ export declare function neverAutoNamesRefusal(names: readonly string[]): {
483
+ readonly message: string;
484
+ readonly problems: readonly EntryProblem[];
485
+ } | undefined;
485
486
  /**
486
487
  * Apply a client's parsed per-request settings onto a base `TaskSpec`, TIGHTEN-ONLY, in a SINGLE {@link
487
488
  * tightenTaskSpec} pass (so the permission override composes deny-wins onto the baseline — TRAP #1). `tightenTaskSpec`
@@ -492,5 +493,5 @@ export declare function deriveSettingsPolicy(settings: ParsedTaskSettings, gate?
492
493
  *
493
494
  * Returns `base` untouched when the parsed settings project nothing onto the spec.
494
495
  */
495
- export declare function applyTaskSettings(base: TaskSpec, settings: ParsedTaskSettings, gate?: FsWriteGateWiring, workflowGate?: WorkflowGateWiring): TaskSpec;
496
+ export declare function applyTaskSettings(base: TaskSpec, settings: ParsedTaskSettings, bases?: FsWriteGateWiring): TaskSpec;
496
497
  //# sourceMappingURL=task-settings.d.ts.map