@sema-agent/server 7.131.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 (509) hide show
  1. package/MIGRATION.md +575 -0
  2. package/README.md +12 -9
  3. package/README.zh-CN.md +9 -6
  4. package/USAGE.md +326 -98
  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 +82 -20
  24. package/dist/approval-card.js +46 -16
  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 +33 -19
  29. package/dist/audit.js +12 -16
  30. package/dist/auth-bridge.d.ts +4 -0
  31. package/dist/auth-bridge.js +10 -11
  32. package/dist/bake-runner/main.js +3 -2
  33. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  34. package/dist/boot/deployment-mods.d.ts +31 -0
  35. package/dist/boot/deployment-mods.js +26 -0
  36. package/dist/boot/execution-env.d.ts +1 -1
  37. package/dist/boot/execution-env.js +27 -12
  38. package/dist/boot/execution-lane.js +11 -0
  39. package/dist/boot/leader.js +2 -0
  40. package/dist/boot/memory-boundary.d.ts +2 -2
  41. package/dist/boot/memory-boundary.js +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +5 -4
  43. package/dist/boot/memory-consolidation.js +7 -6
  44. package/dist/boot/org-delivery.d.ts +28 -0
  45. package/dist/boot/org-delivery.js +20 -0
  46. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  47. package/dist/boot/read-deny-anchor-audit.js +36 -0
  48. package/dist/boot/reapers.d.ts +3 -0
  49. package/dist/boot/reapers.js +21 -1
  50. package/dist/boot/resolve-spec.d.ts +4 -5
  51. package/dist/boot/resolve-spec.js +74 -123
  52. package/dist/boot/runner-deps.d.ts +19 -8
  53. package/dist/boot/runner-deps.js +15 -2
  54. package/dist/boot/session-faces.d.ts +2 -7
  55. package/dist/boot/session-faces.js +4 -2
  56. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  57. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  58. package/dist/boot/stage-03-store-backend.js +2 -2
  59. package/dist/boot/stage-04-stores.d.ts +1 -1
  60. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  61. package/dist/boot/stage-05-execution-env.js +7 -10
  62. package/dist/boot/stage-06-runners.d.ts +4 -2
  63. package/dist/boot/stage-06-runners.js +11 -7
  64. package/dist/boot/stage-07-capability-layer.d.ts +4 -2
  65. package/dist/boot/stage-07-capability-layer.js +27 -6
  66. package/dist/boot/stage-08-reapers.d.ts +4 -2
  67. package/dist/boot/stage-08-reapers.js +2 -2
  68. package/dist/boot/stage-09-leader.d.ts +6 -9
  69. package/dist/boot/stage-10-http-server.d.ts +6 -9
  70. package/dist/boot/stage-10-http-server.js +7 -9
  71. package/dist/boot/stores.d.ts +1 -1
  72. package/dist/boot/stores.js +7 -8
  73. package/dist/boot/web-admin.d.ts +4 -3
  74. package/dist/boot/web-admin.js +186 -98
  75. package/dist/boot/workflow-orchestration.d.ts +2 -0
  76. package/dist/boot/workflow-orchestration.js +2 -1
  77. package/dist/brain.js +25 -25
  78. package/dist/breaker-key.d.ts +6 -0
  79. package/dist/breaker-key.js +29 -0
  80. package/dist/budget.js +5 -4
  81. package/dist/caller-text-echo.d.ts +23 -0
  82. package/dist/caller-text-echo.js +21 -0
  83. package/dist/capabilities/brand-identity.d.ts +26 -0
  84. package/dist/capabilities/brand-identity.js +27 -0
  85. package/dist/capabilities/center-plugins.d.ts +7 -0
  86. package/dist/capabilities/center-plugins.js +1 -1
  87. package/dist/capabilities/center-prompts.d.ts +32 -59
  88. package/dist/capabilities/center-prompts.js +18 -32
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/engine-capabilities.js +2 -1
  92. package/dist/capabilities/execution-lane.js +2 -2
  93. package/dist/capabilities/hands-lane.d.ts +30 -6
  94. package/dist/capabilities/hands-lane.js +11 -1
  95. package/dist/capabilities/mcp-probe.d.ts +48 -3
  96. package/dist/capabilities/mcp-probe.js +47 -135
  97. package/dist/capabilities/scenarios.d.ts +95 -45
  98. package/dist/capabilities/scenarios.js +53 -38
  99. package/dist/capabilities/skills.d.ts +19 -4
  100. package/dist/capabilities/skills.js +30 -10
  101. package/dist/capability-facts.d.ts +34 -4
  102. package/dist/capability-facts.js +28 -2
  103. package/dist/center-config-tier.d.ts +69 -0
  104. package/dist/center-config-tier.js +42 -0
  105. package/dist/checkpoint-identity.d.ts +16 -0
  106. package/dist/checkpoint-identity.js +19 -0
  107. package/dist/config-catalog.d.ts +17 -10
  108. package/dist/config-catalog.js +47 -32
  109. package/dist/config-d-migration.d.ts +3 -1
  110. package/dist/config-d-migration.js +2 -2
  111. package/dist/config-dir-trust.d.ts +114 -0
  112. package/dist/config-dir-trust.js +388 -0
  113. package/dist/config-invariants.d.ts +18 -5
  114. package/dist/config-invariants.js +35 -3
  115. package/dist/config-lkg.d.ts +9 -9
  116. package/dist/config-lkg.js +20 -4
  117. package/dist/config-provider.d.ts +9 -2
  118. package/dist/config-provider.js +18 -6
  119. package/dist/config-types.d.ts +75 -20
  120. package/dist/config-types.js +8 -0
  121. package/dist/config.d.ts +13 -0
  122. package/dist/config.js +137 -62
  123. package/dist/delegated-session-owner.d.ts +185 -0
  124. package/dist/delegated-session-owner.js +119 -0
  125. package/dist/device-protocol.d.ts +5 -3
  126. package/dist/device-protocol.js +1 -1
  127. package/dist/device-ws-hub.js +21 -2
  128. package/dist/device-ws-protocol.d.ts +70 -6
  129. package/dist/device-ws-protocol.js +50 -22
  130. package/dist/elicitation.js +3 -2
  131. package/dist/entry-problems.d.ts +34 -0
  132. package/dist/entry-problems.js +14 -0
  133. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  134. package/dist/env-name-allowlist-knobs.js +5 -4
  135. package/dist/exec-bounds.d.ts +15 -3
  136. package/dist/exec-bounds.js +4 -0
  137. package/dist/execution-lane-caps.d.ts +56 -10
  138. package/dist/execution-lane-caps.js +50 -0
  139. package/dist/field-conflict.d.ts +43 -0
  140. package/dist/field-conflict.js +20 -0
  141. package/dist/fleet/fleet-bus.d.ts +80 -6
  142. package/dist/fleet/fleet-bus.js +41 -9
  143. package/dist/hooks/classic-stations.d.ts +91 -0
  144. package/dist/hooks/classic-stations.js +27 -0
  145. package/dist/hooks/command-spawn.d.ts +57 -0
  146. package/dist/hooks/command-spawn.js +139 -0
  147. package/dist/hooks/hook-llm.d.ts +8 -5
  148. package/dist/hooks/hook-llm.js +79 -36
  149. package/dist/hooks/hook-runner.d.ts +349 -95
  150. package/dist/hooks/hook-runner.js +855 -568
  151. package/dist/hooks/hook-source.d.ts +44 -0
  152. package/dist/hooks/hook-source.js +40 -0
  153. package/dist/http/active-run-conflict.d.ts +5 -13
  154. package/dist/http/active-run-conflict.js +17 -27
  155. package/dist/http/admission.d.ts +8 -2
  156. package/dist/http/admission.js +188 -101
  157. package/dist/http/approval-sweeps.js +99 -21
  158. package/dist/http/caller-trust.d.ts +77 -0
  159. package/dist/http/caller-trust.js +143 -0
  160. package/dist/http/checkpoint-ctx.d.ts +41 -24
  161. package/dist/http/checkpoint-ctx.js +23 -16
  162. package/dist/http/claimed-run.d.ts +14 -0
  163. package/dist/http/claimed-run.js +15 -0
  164. package/dist/http/device-placement.d.ts +2 -4
  165. package/dist/http/device-placement.js +7 -11
  166. package/dist/http/dispatch.d.ts +0 -4
  167. package/dist/http/dispatch.js +15 -13
  168. package/dist/http/durable-run-leg.d.ts +6 -33
  169. package/dist/http/durable-run-leg.js +36 -10
  170. package/dist/http/health-self-report.d.ts +7 -5
  171. package/dist/http/health-self-report.js +4 -18
  172. package/dist/http/owner-access.d.ts +56 -0
  173. package/dist/http/owner-access.js +42 -0
  174. package/dist/http/principal-gate.d.ts +70 -28
  175. package/dist/http/principal-gate.js +61 -15
  176. package/dist/http/readiness.d.ts +11 -5
  177. package/dist/http/readiness.js +10 -3
  178. package/dist/http/refusal-body.d.ts +21 -0
  179. package/dist/http/refusal-body.js +4 -0
  180. package/dist/http/request-guards.d.ts +43 -23
  181. package/dist/http/request-guards.js +53 -17
  182. package/dist/http/resume-ctx-read.d.ts +2 -5
  183. package/dist/http/resume-ctx-read.js +7 -4
  184. package/dist/http/resume-legs.d.ts +28 -4
  185. package/dist/http/resume-legs.js +169 -91
  186. package/dist/http/retired-service-deps.d.ts +43 -0
  187. package/dist/http/retired-service-deps.js +18 -0
  188. package/dist/http/route-ctx.d.ts +44 -28
  189. package/dist/http/route-ctx.js +4 -0
  190. package/dist/http/route-table.js +2 -0
  191. package/dist/http/routes/a2a-serve.js +3 -4
  192. package/dist/http/routes/admin-config-refresh.js +1 -1
  193. package/dist/http/routes/admin-drain.js +1 -1
  194. package/dist/http/routes/admin-memory-optout.js +5 -1
  195. package/dist/http/routes/adoption.js +2 -9
  196. package/dist/http/routes/approvals-assistant.js +49 -48
  197. package/dist/http/routes/background.js +3 -2
  198. package/dist/http/routes/capabilities.js +21 -5
  199. package/dist/http/routes/config-catalog.d.ts +3 -3
  200. package/dist/http/routes/config-catalog.js +1 -1
  201. package/dist/http/routes/devices.js +3 -17
  202. package/dist/http/routes/diagnostics.js +6 -2
  203. package/dist/http/routes/images.js +6 -7
  204. package/dist/http/routes/leader.js +1 -8
  205. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  206. package/dist/http/routes/mcp-reconnect.js +3 -2
  207. package/dist/http/routes/memory-bundle.js +1 -1
  208. package/dist/http/routes/memory-compliance.js +1 -1
  209. package/dist/http/routes/memory-consolidation.js +1 -1
  210. package/dist/http/routes/memory-origin.js +1 -1
  211. package/dist/http/routes/memory-policy.d.ts +1 -1
  212. package/dist/http/routes/memory-policy.js +3 -2
  213. package/dist/http/routes/notify-wake.js +8 -21
  214. package/dist/http/routes/observability.js +2 -2
  215. package/dist/http/routes/principal-inbox.d.ts +39 -0
  216. package/dist/http/routes/principal-inbox.js +76 -0
  217. package/dist/http/routes/retention-ops.js +2 -9
  218. package/dist/http/routes/rules.js +5 -18
  219. package/dist/http/routes/runs.d.ts +5 -0
  220. package/dist/http/routes/runs.js +34 -107
  221. package/dist/http/routes/session-sync.js +15 -26
  222. package/dist/http/routes/sessions.js +30 -40
  223. package/dist/http/routes/shared-memory.js +2 -13
  224. package/dist/http/routes/side-query.js +8 -7
  225. package/dist/http/routes/tasks.js +67 -21
  226. package/dist/http/routes/workflows.d.ts +351 -0
  227. package/dist/http/routes/workflows.js +153 -119
  228. package/dist/http/send.d.ts +33 -10
  229. package/dist/http/send.js +21 -4
  230. package/dist/http/server.d.ts +27 -18
  231. package/dist/http/server.js +34 -6
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +25 -0
  234. package/dist/http/submit-ctx.js +40 -0
  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 +11 -8
  238. package/dist/index.d.ts +2 -2
  239. package/dist/index.js +1 -2
  240. package/dist/lane-home-probe.d.ts +112 -0
  241. package/dist/lane-home-probe.js +101 -0
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/limit-refusal.d.ts +59 -0
  245. package/dist/limit-refusal.js +15 -0
  246. package/dist/main.js +1 -1
  247. package/dist/mcp-assertion-header.d.ts +32 -19
  248. package/dist/mcp-assertion-header.js +10 -9
  249. package/dist/mcp-tool-faces.d.ts +5 -0
  250. package/dist/mcp-tool-faces.js +6 -4
  251. package/dist/memory-project-layer.d.ts +37 -0
  252. package/dist/memory-project-layer.js +46 -0
  253. package/dist/memory-scope.d.ts +24 -17
  254. package/dist/memory-scope.js +24 -8
  255. package/dist/memory-sync-client.d.ts +27 -13
  256. package/dist/memory-sync-client.js +107 -18
  257. package/dist/model-entry-refusal.d.ts +9 -1
  258. package/dist/model-entry-refusal.js +6 -1
  259. package/dist/model-plane-face.d.ts +51 -0
  260. package/dist/model-plane-face.js +24 -0
  261. package/dist/model-provider.d.ts +44 -12
  262. package/dist/model-provider.js +21 -2
  263. package/dist/model-route-endpoint.d.ts +9 -12
  264. package/dist/model-route-endpoint.js +8 -11
  265. package/dist/model-route-env.d.ts +22 -0
  266. package/dist/model-route-env.js +2 -0
  267. package/dist/model-route-gap.d.ts +60 -30
  268. package/dist/model-route-gap.js +21 -15
  269. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  270. package/dist/observability/corrupt-read-seat.js +9 -0
  271. package/dist/observability/cost-taxonomy.d.ts +7 -7
  272. package/dist/observability/err-text.d.ts +6 -0
  273. package/dist/observability/err-text.js +18 -4
  274. package/dist/observability/fail-open.d.ts +76 -14
  275. package/dist/observability/fail-open.js +76 -14
  276. package/dist/observability/metrics.js +4 -1
  277. package/dist/observability/prompt-manifest.d.ts +33 -82
  278. package/dist/observability/prompt-manifest.js +122 -17
  279. package/dist/observability/run-terminal.js +14 -6
  280. package/dist/observability/secret-env-scrub.d.ts +13 -1
  281. package/dist/observability/secret-env-scrub.js +13 -1
  282. package/dist/observability/tool-trace.d.ts +16 -21
  283. package/dist/observability/tool-trace.js +58 -49
  284. package/dist/operator-ask.d.ts +10 -0
  285. package/dist/operator-ask.js +3 -0
  286. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  287. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  288. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  289. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  290. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  291. package/dist/orchestration/workflow-notify-journal.js +27 -34
  292. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  293. package/dist/orchestration/workflow-park-decision.js +118 -0
  294. package/dist/org-delivery-gate.d.ts +81 -0
  295. package/dist/org-delivery-gate.js +59 -0
  296. package/dist/panel-tool-names.d.ts +23 -0
  297. package/dist/panel-tool-names.js +8 -0
  298. package/dist/parked-decide.d.ts +39 -6
  299. package/dist/parked-decide.js +98 -51
  300. package/dist/parked-revive-surface.d.ts +9 -2
  301. package/dist/parked-revive-surface.js +11 -8
  302. package/dist/per-task-image.d.ts +7 -1
  303. package/dist/per-task-image.js +3 -3
  304. package/dist/permission-rule-list.d.ts +1 -1
  305. package/dist/permission-rule-list.js +2 -2
  306. package/dist/plain-string-record.d.ts +25 -0
  307. package/dist/plain-string-record.js +32 -0
  308. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  309. package/dist/plugins/approval-ask-store-file.js +21 -0
  310. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  311. package/dist/plugins/approval-ask-store-memory.js +34 -2
  312. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  313. package/dist/plugins/approval-ask-store-sql.js +37 -1
  314. package/dist/plugins/blob-backend.d.ts +83 -15
  315. package/dist/plugins/blob-backend.js +68 -15
  316. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  317. package/dist/plugins/breaker-state-sql.js +4 -4
  318. package/dist/plugins/caching-session-store.d.ts +3 -0
  319. package/dist/plugins/caching-session-store.js +3 -0
  320. package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
  321. package/dist/plugins/checkpoint-store-sql.js +59 -28
  322. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  323. package/dist/plugins/file-history-store-sql.js +3 -1
  324. package/dist/plugins/file-run-store.d.ts +5 -13
  325. package/dist/plugins/file-run-store.js +9 -0
  326. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  327. package/dist/plugins/fork-routing-session-store.js +12 -1
  328. package/dist/plugins/host-platform.d.ts +2 -0
  329. package/dist/plugins/host-platform.js +2 -1
  330. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  331. package/dist/plugins/k8s-bg-scripts.js +22 -0
  332. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  333. package/dist/plugins/local-checkpoint-store.js +11 -3
  334. package/dist/plugins/local-session-store.d.ts +1 -1
  335. package/dist/plugins/local-session-store.js +1 -1
  336. package/dist/plugins/local-session-window.d.ts +39 -0
  337. package/dist/plugins/local-session-window.js +54 -0
  338. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  340. package/dist/plugins/mailbox-store-sql.js +77 -52
  341. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  342. package/dist/plugins/memory-run-store.d.ts +5 -13
  343. package/dist/plugins/memory-run-store.js +8 -0
  344. package/dist/plugins/one-time-migrations.d.ts +245 -93
  345. package/dist/plugins/one-time-migrations.js +668 -207
  346. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  347. package/dist/plugins/org-delivery-quota-store.js +228 -0
  348. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  349. package/dist/plugins/permission-rule-store-sql.js +4 -18
  350. package/dist/plugins/pg-pool.js +39 -7
  351. package/dist/plugins/pg-session-storage.d.ts +20 -8
  352. package/dist/plugins/pg-session-storage.js +34 -21
  353. package/dist/plugins/remote-env-adb.d.ts +12 -12
  354. package/dist/plugins/remote-env-adb.js +21 -6
  355. package/dist/plugins/remote-env-device.js +3 -0
  356. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  357. package/dist/plugins/remote-env-e2b.js +21 -9
  358. package/dist/plugins/remote-env-host.d.ts +9 -9
  359. package/dist/plugins/remote-env-host.js +10 -32
  360. package/dist/plugins/remote-env-k8s.d.ts +103 -38
  361. package/dist/plugins/remote-env-k8s.js +288 -95
  362. package/dist/plugins/remote-env-local-docker.d.ts +27 -13
  363. package/dist/plugins/remote-env-local-docker.js +82 -11
  364. package/dist/plugins/remote-env-ssh.d.ts +21 -12
  365. package/dist/plugins/remote-env-ssh.js +117 -5
  366. package/dist/plugins/remote-shell.d.ts +0 -1
  367. package/dist/plugins/remote-shell.js +1 -2
  368. package/dist/plugins/retention-store-sql.js +6 -2
  369. package/dist/plugins/run-store-sql.d.ts +16 -14
  370. package/dist/plugins/run-store-sql.js +22 -2
  371. package/dist/plugins/schema-consistency.d.ts +54 -0
  372. package/dist/plugins/schema-consistency.js +52 -0
  373. package/dist/plugins/schema-indexes.js +2 -0
  374. package/dist/plugins/send-user-file.js +2 -2
  375. package/dist/plugins/session-epoch-anchor.d.ts +39 -0
  376. package/dist/plugins/session-epoch-anchor.js +22 -0
  377. package/dist/plugins/session-store.d.ts +18 -8
  378. package/dist/plugins/session-store.js +15 -4
  379. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  380. package/dist/plugins/shared-memory-store-sql.js +5 -16
  381. package/dist/plugins/sql-driver.d.ts +205 -1
  382. package/dist/plugins/sql-driver.js +325 -13
  383. package/dist/plugins/sql-errors.d.ts +64 -0
  384. package/dist/plugins/sql-errors.js +57 -0
  385. package/dist/plugins/store-backend.d.ts +36 -1
  386. package/dist/plugins/store-backend.js +42 -15
  387. package/dist/plugins/store-contracts.d.ts +42 -0
  388. package/dist/plugins/store-contracts.js +1 -0
  389. package/dist/plugins/tidb-pool.d.ts +6 -1
  390. package/dist/plugins/tidb-pool.js +44 -10
  391. package/dist/plugins/tidb-session-storage.d.ts +8 -11
  392. package/dist/plugins/tidb-session-storage.js +6 -16
  393. package/dist/plugins/tidb-session-store.d.ts +24 -4
  394. package/dist/plugins/tidb-session-store.js +29 -5
  395. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  396. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  397. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  398. package/dist/plugins/workflow-run-store-sql.js +50 -9
  399. package/dist/posture-source.d.ts +18 -10
  400. package/dist/posture-source.js +4 -1
  401. package/dist/project-identity.d.ts +45 -6
  402. package/dist/project-identity.js +162 -8
  403. package/dist/project-layer-key.d.ts +28 -0
  404. package/dist/project-layer-key.js +29 -0
  405. package/dist/prompts-domain-validate.d.ts +17 -61
  406. package/dist/prompts-domain-validate.js +9 -119
  407. package/dist/question.js +3 -2
  408. package/dist/read-deny-entry.d.ts +25 -0
  409. package/dist/read-deny-entry.js +12 -0
  410. package/dist/read-face-posture.d.ts +37 -11
  411. package/dist/read-face-posture.js +32 -3
  412. package/dist/request-key-closure.d.ts +9 -2
  413. package/dist/request-key-closure.js +11 -5
  414. package/dist/request-value-closure.d.ts +5 -0
  415. package/dist/request-value-closure.js +11 -3
  416. package/dist/rule-entry-list.d.ts +38 -11
  417. package/dist/rule-entry-list.js +106 -30
  418. package/dist/rules-consent.js +3 -4
  419. package/dist/run-acceptance.d.ts +19 -3
  420. package/dist/run-acceptance.js +13 -1
  421. package/dist/run-local.js +54 -24
  422. package/dist/runs.d.ts +15 -8
  423. package/dist/runs.js +35 -1
  424. package/dist/runtime-caps-resolver.d.ts +16 -6
  425. package/dist/runtime-caps-resolver.js +18 -5
  426. package/dist/sandbox-pkg-source.d.ts +19 -1
  427. package/dist/sandbox-pkg-source.js +29 -7
  428. package/dist/security.d.ts +87 -9
  429. package/dist/security.js +52 -9
  430. package/dist/server-secret-env.d.ts +44 -18
  431. package/dist/server-secret-env.js +49 -8
  432. package/dist/session-error-wire.d.ts +19 -2
  433. package/dist/session-error-wire.js +5 -1
  434. package/dist/session-incarnation.d.ts +15 -5
  435. package/dist/session-incarnation.js +16 -9
  436. package/dist/session-titled-frame.d.ts +33 -0
  437. package/dist/session-titled-frame.js +4 -0
  438. package/dist/session-titler.d.ts +9 -1
  439. package/dist/session-titler.js +27 -6
  440. package/dist/spec-fields.d.ts +28 -16
  441. package/dist/spec-fields.js +66 -54
  442. package/dist/sql-engine-posture.d.ts +31 -4
  443. package/dist/sql-engine-posture.js +36 -1
  444. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  445. package/dist/stored-request-tool-axes-m19.js +30 -2
  446. package/dist/task-a2a.d.ts +9 -1
  447. package/dist/task-a2a.js +73 -47
  448. package/dist/task-cwd.d.ts +1 -1
  449. package/dist/task-mcp.d.ts +46 -58
  450. package/dist/task-mcp.js +82 -107
  451. package/dist/task-settings.d.ts +95 -108
  452. package/dist/task-settings.js +77 -98
  453. package/dist/text-bidi.d.ts +1 -48
  454. package/dist/text-bidi.js +3 -5
  455. package/dist/tighten-only-seats.d.ts +150 -0
  456. package/dist/tighten-only-seats.js +196 -0
  457. package/dist/tool-approval.d.ts +304 -88
  458. package/dist/tool-approval.js +623 -239
  459. package/dist/trace/core-keyset-guard.d.ts +122 -20
  460. package/dist/trace/engine-notice-wire.d.ts +11 -3
  461. package/dist/trace/engine-notice-wire.js +8 -1
  462. package/dist/trace/exit-seat.d.ts +28 -0
  463. package/dist/trace/exit-seat.js +76 -0
  464. package/dist/trace/ledger-events.d.ts +6 -3
  465. package/dist/trace/ledger-sink.js +4 -1
  466. package/dist/trace/model-segment.js +1 -1
  467. package/dist/trace/project.d.ts +98 -17
  468. package/dist/trace/project.js +98 -50
  469. package/dist/trace/projection-table.d.ts +100 -0
  470. package/dist/trace/projection-table.js +130 -0
  471. package/dist/trace/redact.d.ts +54 -0
  472. package/dist/trace/redact.js +778 -152
  473. package/dist/trace/self-minted-wire.d.ts +345 -1
  474. package/dist/trace/self-minted-wire.js +117 -1
  475. package/dist/trace/wire-projection-faces.d.ts +377 -3
  476. package/dist/trace/wire-projection-faces.js +164 -1
  477. package/dist/url-refusal.js +2 -0
  478. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  479. package/dist/web-admin-client/apply-effective.js +56 -5
  480. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  481. package/dist/web-admin-client/candidate-gate.js +3 -3
  482. package/dist/web-admin-client/facade.d.ts +1 -1
  483. package/dist/web-admin-client/facade.js +1 -1
  484. package/dist/web-admin-client/http-client.js +0 -6
  485. package/dist/web-admin-client/read-face.js +5 -9
  486. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  487. package/dist/web-admin-client/read-warnings.js +10 -0
  488. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  489. package/dist/web-admin-client/skills-mcp.js +11 -9
  490. package/dist/web-admin-client/types.d.ts +2 -3
  491. package/dist/workspace-cache.d.ts +35 -0
  492. package/dist/workspace-cache.js +36 -0
  493. package/dist/workspace-space.d.ts +3 -2
  494. package/dist/workspace-space.js +2 -0
  495. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
  496. package/package.json +8 -4
  497. package/scripts/drain-check-local.mjs +34 -1
  498. package/scripts/drain-check.mysql.sql +30 -2
  499. package/scripts/drain-check.pg.sql +29 -2
  500. package/dist/capabilities/memory-notice.d.ts +0 -138
  501. package/dist/capabilities/memory-notice.js +0 -64
  502. package/dist/capabilities/prompt.d.ts +0 -17
  503. package/dist/capabilities/prompt.js +0 -6
  504. package/dist/mcp-content-origin.d.ts +0 -34
  505. package/dist/mcp-content-origin.js +0 -10
  506. package/dist/tool-axis-words.d.ts +0 -27
  507. package/dist/tool-axis-words.js +0 -9
  508. package/dist/wire-name-bound.d.ts +0 -14
  509. package/dist/wire-name-bound.js +0 -13
@@ -17,9 +17,14 @@
17
17
  * ② 运维面:`GET /v1/diagnostics/wiring` 报 `{face, source, note}`,「为什么这台机器是 open」有答案
18
18
  * (裁定的补偿项:升级即放开,得让运维看得见并知道怎么钉回)。
19
19
  *
20
- * ## 优先序(三态,与 `config.ts` 的 `postureOn` 同形)
21
- * `env 显式` > `center 发布` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `web-admin-client/read-face.ts`
20
+ * ## 优先序(与 `config.ts` 的 `postureOn` 同形)
21
+ * `env 显式` > `center 发布` > `lane 声明` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `web-admin-client/read-face.ts`
22
22
  * 头注①(READ 容纳面描述的是**这台机器的磁盘上有什么**,组织的下发面不知道)。
23
+ * 🔴 **`lane` 一臂(S-1492,clay 裁 [ref])**:隔离型执行车道(`e2b` / `k8s` / `local-docker`)的契约行**显式声明**读面缺省 `open`
24
+ * (`execution-lane-caps.ts` 的 `laneReadFaceDefault`;沙箱内部就是模型的整个世界)。运维没写 `READ_FACE` 时,车道声明比整机 posture 更具体 ⇒ 排在它前面;
25
+ * 声明 `roots` 的车道(`host` / `ssh` / `adb` / `device` / 未设车道)不替运维声明缺省,回到既有的 posture 派生,**一个字节不变**。
26
+ * 缺席这一态的派生**只有一只函数**({@link readFaceDefaultFor}),且读的是**最终生效的车道**(`loadConfig` 装配完 `remoteExec` 之后一次;
27
+ * local 形 `config.d/remote-exec.json` 覆写之后由车道合成步再派一次 —— 同一只 {@link settleDerivedReadFace})。
23
28
  *
24
29
  * ## 定界
25
30
  * 本模块**只**管 `face` 一档。内建读拒表(`readDenyPatterns` / `readDenyBuiltinTiers` /
@@ -31,13 +36,14 @@
31
36
  * 本模块的定界不变:并列的那一侧开着哪几档,是那张表自己的缺省说了算。core 的 `config.read_face_deployment_clamped`
32
37
  * (只读挂载钳制)同样不受本件影响。
33
38
  */
39
+ import { type LaneReadFaceDefault, type RemoteExecProvider } from "./execution-lane-caps.js";
34
40
  import { type PostureSource } from "./posture-source.js";
35
41
  /**
36
42
  * 档位来源的闭集词表 —— **S-178 起转 `posture-source.ts` 的共享件**(本模块只是给这一档取个本地名字,
37
43
  * 不再持第二份词表:同一张四词表抄两遍的那天,两份会在加词时分家)。
38
44
  */
39
- export declare const READ_FACE_SOURCE_WORDS: readonly ["env", "center", "posture", "engine-default"];
40
- /** 档位的来源(闭集四词)。加词 ⇒ {@link postureSourceNote} 的穷举 switch 编译红。 */
45
+ export declare const READ_FACE_SOURCE_WORDS: readonly ["env", "center", "lane", "posture", "engine-default"];
46
+ /** 档位的来源(闭集五词)。加词 ⇒ {@link postureSourceNote} 的穷举 switch 编译红。 */
41
47
  export type ReadFaceSource = PostureSource;
42
48
  /** 一台 worker 的 READ 面档位事实(值 + 来源)。`ServiceConfigFlat` 结构上满足本形。 */
43
49
  export interface ReadFacePostureFacts {
@@ -45,10 +51,29 @@ export interface ReadFacePostureFacts {
45
51
  readonly readFaceSource: ReadFaceSource;
46
52
  }
47
53
  /**
48
- * 缺席 `READ_FACE` 时的 posture 派生(`config.ts` 的铸点调用;显式值不经此口)。
49
- * 单用户 turnkey ⇒ `open`;多租户 ⇒ 不铸(引擎默认 `roots`,server 不复制上游默认)。
54
+ * 缺席 `READ_FACE` 时读面缺省的**唯一派生函数**(显式 env 值不经此口):
55
+ * · 车道声明 `open`(隔离型车道)⇒ `open`,来源 `lane`(不论单用户还是多租户 —— 更具体的出处胜 posture);
56
+ * · 车道声明 `roots` ⇒ 既有 posture 派生,逐字不变。
50
57
  */
51
- export declare function readFaceForPosture(singleUserTurnkey: boolean): ReadFacePostureFacts;
58
+ export declare function readFaceDefaultFor(input: {
59
+ readonly laneDefault: LaneReadFaceDefault;
60
+ readonly singleUserTurnkey: boolean;
61
+ }): ReadFacePostureFacts;
62
+ /** {@link settleDerivedReadFace} 动的那几格(`ServiceConfig` 结构上满足本形)。 */
63
+ export interface ReadFaceDeploymentSeat {
64
+ readFace?: "open" | "roots" | undefined;
65
+ readFaceSource: ReadFaceSource;
66
+ remoteExec?: {
67
+ readonly provider: RemoteExecProvider;
68
+ } | undefined;
69
+ }
70
+ /**
71
+ * 把**派生的**读面缺省按这台部署**最终生效的车道**落到配置上(显式 env / center 发布的值与来源原样不动)。返回值 = 这一次有没有改动。
72
+ * 两个调用点,同一只函数:`loadConfig` 装配完 `remoteExec` 之后(env 三元链定的车道);车道合成步在 local 形文件覆写之后
73
+ * (`config.d/remote-exec.json` 能把车道换成 `host` / `local-docker`,读面缺省随最终车道重派 —— 否则它停在已作废的车道上)。
74
+ * 幂等:同一份配置再调一次不改。值与来源**同一处写**(`readFace` 缺席 ⟺ 来源 `engine-default`)。
75
+ */
76
+ export declare function settleDerivedReadFace(seat: ReadFaceDeploymentSeat, singleUserTurnkey: boolean): boolean;
52
77
  /** 本档的运维指路句 —— 骨架由共享件 {@link postureSourceNote} 给(四词穷举在那里,加词即编译红);
53
78
  * 本函数提供两条**键专属**臂(`center` / `posture`)的事实句。
54
79
  *
@@ -67,13 +92,14 @@ export declare function buildReadFaceWiring(facts: ReadFacePostureFacts): {
67
92
  note: string;
68
93
  };
69
94
  /**
70
- * S-176 —— posture 派生的档位在 **boot 期推送面**的那一行(`config.ts` 经既有 `CONFIG_NOTICES` 以 info 级排空)。
95
+ * S-176 —— 派生的档位(`posture` 单机 ⇒ open,或 S-1492 的 `lane` 隔离车道 ⇒ open)在 **boot 期推送面**的那一行(`config.ts` 经既有 `CONFIG_NOTICES` 以 info 级排空)。
71
96
  *
72
97
  * 为什么要有:S-167 的补偿项是「升级即放开,得让运维看得见并知道怎么钉回」,可此前唯一看得见的是**拉取**面
73
- * (`GET /v1/diagnostics/wiring`)—— 只对会去拉的人成立。单机 boot 日志里零字。
74
- * 为什么只在 `posture` 一词上说:另外三词都不是「没人表态、服务替它选了一个更宽的档」——`env` 是运维自己写的,
98
+ * (`GET /v1/diagnostics/wiring`)—— 只对会去拉的人成立。单机 boot 日志里零字。S-1492 的 `lane` 臂同一个补偿:多租户沙箱部署升级后读面从 `roots` 变 `open`,
99
+ * 指路句带挂载告诫与钉回出路。
100
+ * 为什么只在 `posture` / `lane` 两词上说:另外三词都不是「没人表态、服务替它选了一个更宽的档」——`env` 是运维自己写的,
75
101
  * `engine-default` 是本服务没铸(引擎默认接管),`center` 在 boot 这一拍还没到货(它有自己的换席通告)。
76
- * 为什么是 info 不是 warn:每一台照常配置的单机每次启动都成立,是常态事实不是异常(与执行车道落点同级)。
102
+ * 为什么是 info 不是 warn:每一台照常配置的部署每次启动都成立,是常态事实不是异常(与执行车道落点同级)。
77
103
  *
78
104
  * 字段与极性表的 posture 行同名(`knob` / `value` / `source`),另带指路句;三格由 {@link buildReadFaceWiring} 投影出 ——
79
105
  * 拉取面与推送面**同一只函数**,不各算一次。`value` 是字符串:只有 `face` 在场的那一形才会走到这里。
@@ -1,13 +1,42 @@
1
+ import { LANE_OPEN_READ_FACE_CAUTION, executionLaneOf, laneReadFaceDefault } from "./execution-lane-caps.js";
1
2
  import { POSTURE_SOURCE_WORDS, postureSourceNote } from "./posture-source.js";
2
3
  export const READ_FACE_SOURCE_WORDS = POSTURE_SOURCE_WORDS;
3
- export function readFaceForPosture(singleUserTurnkey) {
4
+ function readFaceForPosture(singleUserTurnkey) {
4
5
  return singleUserTurnkey ? { readFace: "open", readFaceSource: "posture" } : { readFaceSource: "engine-default" };
5
6
  }
7
+ export function readFaceDefaultFor(input) {
8
+ return input.laneDefault === "open" ? { readFace: "open", readFaceSource: "lane" } : readFaceForPosture(input.singleUserTurnkey);
9
+ }
10
+ function isDerivedSource(source) {
11
+ switch (source) {
12
+ case "env":
13
+ case "center":
14
+ return false;
15
+ case "lane":
16
+ case "posture":
17
+ case "engine-default":
18
+ return true;
19
+ }
20
+ }
21
+ export function settleDerivedReadFace(seat, singleUserTurnkey) {
22
+ if (!isDerivedSource(seat.readFaceSource))
23
+ return false;
24
+ const next = readFaceDefaultFor({ laneDefault: laneReadFaceDefault(executionLaneOf(seat.remoteExec?.provider)), singleUserTurnkey });
25
+ if (next.readFace === seat.readFace && next.readFaceSource === seat.readFaceSource)
26
+ return false;
27
+ if (next.readFace === undefined)
28
+ delete seat.readFace;
29
+ else
30
+ seat.readFace = next.readFace;
31
+ seat.readFaceSource = next.readFaceSource;
32
+ return true;
33
+ }
6
34
  export function readFaceSourceNote(source) {
7
35
  return postureSourceNote({
8
36
  knob: "READ_FACE",
9
37
  source,
10
38
  centerMeaning: "published by the web-admin and applied HOT — the containment FACE is a swappable engine seat (core 7.10.0), so the next refresh (or POST /v1/admin/config/refresh) swaps it into every Runner with NO restart; set READ_FACE on this machine to take the key back",
39
+ laneMeaning: `declared by the isolated execution lane this deployment runs on (REMOTE_EXEC=e2b|k8s|local-docker): the sandbox is the model's whole world, so reads are not fenced to the workspace roots by default; ${LANE_OPEN_READ_FACE_CAUTION}`,
11
40
  postureMeaning: "derived from the single-user turnkey posture (REQUIRE_PRINCIPAL is not set): reads outside the workspace roots are allowed by default — set READ_FACE=roots to pin the containing posture back",
12
41
  });
13
42
  }
@@ -15,11 +44,11 @@ export function buildReadFaceWiring(facts) {
15
44
  return { face: facts.readFace ?? null, source: facts.readFaceSource, note: readFaceSourceNote(facts.readFaceSource) };
16
45
  }
17
46
  export function buildReadFacePostureNotice(facts) {
18
- if (facts.readFaceSource !== "posture")
47
+ if (facts.readFaceSource !== "posture" && facts.readFaceSource !== "lane")
19
48
  return undefined;
20
49
  const wiring = buildReadFaceWiring(facts);
21
50
  if (wiring.face === null) {
22
- throw new Error("read-face posture notice: source is `posture` but no face was minted — readFaceForPosture's invariant broke");
51
+ throw new Error(`read-face derived notice: source is \`${facts.readFaceSource}\` but no face was minted — readFaceDefaultFor's invariant broke`);
23
52
  }
24
53
  return { event: "config_knob_posture_derived", fields: { knob: "READ_FACE", value: wiring.face, source: wiring.source, note: wiring.note } };
25
54
  }
@@ -1,8 +1,8 @@
1
1
  /** 拒体里逐字回显的键名条数上限。键名原样回显(不猜语义),但**条数有界** —— 一个塞满键的体不许把 400 响应
2
2
  * 放大成流量面。超出部分只报数。 */
3
3
  export declare const MAX_KEY_ECHO = 20;
4
- /** 键名回显的清洗:剥控制/双向字符(键名进的是 JSON 错误体与运维日志,一个 RLO 能把两行字读反),
5
- * 再按 {@link MAX_KEY_ECHO_CHARS} 截断。清洗之外**逐字**,不做大小写/近似猜测。 */
4
+ /** 键名回显 = 前缀 + 调用方串的唯一回显口径(`caller-text-echo.ts`:剥控制 / 双向字符、截到 64 字 + …;键名进的是 JSON 错误体与运维日志,
5
+ * 一个 RLO 能把两行字读反)。清洗之外**逐字**,不做大小写/近似猜测。 */
6
6
  export declare function echoKeyName(prefix: string, key: string): string;
7
7
  /** 一次键闭集裁决的产物:一句 wire 文案 + 两张分类键名表(消费端可机读,不必解析文案)。 */
8
8
  export interface KeyClosureIssue {
@@ -58,5 +58,12 @@ export type InterruptSteerBody = {
58
58
  export type SteerBodyForm = "run" | "content" | "interrupt";
59
59
  /** 送话口的顶层键裁决(各形同一只;`form` 选受理集)。 */
60
60
  export declare function steerBodyKeyIssue(raw: unknown, form: SteerBodyForm): KeyClosureIssue | null;
61
+ declare const PRINCIPAL_INBOX_BODY_KEYS: readonly ["to", "content", "urgent"];
62
+ /** 受理口的体形(键 = 受理集,值形由路由逐键判)。 */
63
+ export type PrincipalInboxBody = {
64
+ readonly [K in (typeof PRINCIPAL_INBOX_BODY_KEYS)[number]]?: unknown;
65
+ };
66
+ /** 受理口的顶层键裁决(与提交口 / 送话口同一只组句器)。 */
67
+ export declare function principalInboxBodyKeyIssue(raw: unknown): KeyClosureIssue | null;
61
68
  export {};
62
69
  //# sourceMappingURL=request-key-closure.d.ts.map
@@ -1,9 +1,8 @@
1
- import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
1
+ import { echoCallerText } from "./caller-text-echo.js";
2
+ import { tightenOnlySeatField } from "./tighten-only-seats.js";
2
3
  export const MAX_KEY_ECHO = 20;
3
- const MAX_KEY_ECHO_CHARS = 64;
4
4
  export function echoKeyName(prefix, key) {
5
- const clean = key.replace(CONTROL_AND_BIDI_STRIP_RE, "");
6
- return `${prefix}${clean.length > MAX_KEY_ECHO_CHARS ? `${clean.slice(0, MAX_KEY_ECHO_CHARS)}…` : clean}`;
5
+ return `${prefix}${echoCallerText(key)}`;
7
6
  }
8
7
  export function scanKeyClosure(bag, prefix, accepted, tolerated, into) {
9
8
  for (const k of Object.keys(bag)) {
@@ -33,6 +32,7 @@ const TASK_BODY_DECLARED_KEYS = [
33
32
  const TASK_BODY_SCENARIO_KEYS = ["repo"];
34
33
  const ACCEPTED_BODY = new Set([...TASK_BODY_DECLARED_KEYS, ...TASK_BODY_SCENARIO_KEYS]);
35
34
  const UNSUPPORTED_BODY_KEYS = ["handsReadOnly", "readDenyPatterns", "readFace", "shellGate", "writeFace"];
35
+ const BODY_KEY_SETTINGS_SEAT = { readDenyPatterns: tightenOnlySeatField("readDenyPatterns") };
36
36
  const UNSUPPORTED_BODY = {
37
37
  keys: new Set(UNSUPPORTED_BODY_KEYS),
38
38
  label: "unsupported (an engine seat this door does not read from the request body — set by the deployment)",
@@ -51,9 +51,10 @@ function closedBodyKeyIssue(raw, accepted, unsupported, door) {
51
51
  ...(buckets.unknown.length > 0 ? [keyClosureClause(buckets.unknown, `unknown (not ${door} key — check the spelling)`)] : []),
52
52
  ...(buckets.unsupported.length > 0 ? [keyClosureClause(buckets.unsupported, unsupported.label)] : []),
53
53
  ];
54
+ const seatHints = buckets.unsupported.flatMap((key) => (Object.hasOwn(BODY_KEY_SETTINGS_SEAT, key) ? [` \`${key}\` rides ${BODY_KEY_SETTINGS_SEAT[key]} instead.`] : []));
54
55
  return {
55
56
  message: `body: unrecognized top-level key(s) — refused rather than dropped, because a dropped key reads as "in effect" to the caller. ` +
56
- `${parts.join("; ")}. ` +
57
+ `${parts.join("; ")}.${seatHints.join("")} ` +
57
58
  `Accepted: ${[...accepted].sort().join(",")}`,
58
59
  unknownKeys: buckets.unknown.slice(0, MAX_KEY_ECHO),
59
60
  unsupportedKeys: buckets.unsupported.slice(0, MAX_KEY_ECHO),
@@ -77,4 +78,9 @@ const STEER_UNSUPPORTED = {
77
78
  export function steerBodyKeyIssue(raw, form) {
78
79
  return closedBodyKeyIssue(raw, STEER_DOORS[form].accepted, STEER_UNSUPPORTED, STEER_DOORS[form].door);
79
80
  }
81
+ const PRINCIPAL_INBOX_BODY_KEYS = ["to", "content", "urgent"];
82
+ const PRINCIPAL_INBOX_UNSUPPORTED = { keys: new Set(), label: "unsupported" };
83
+ export function principalInboxBodyKeyIssue(raw) {
84
+ return closedBodyKeyIssue(raw, new Set(PRINCIPAL_INBOX_BODY_KEYS), PRINCIPAL_INBOX_UNSUPPORTED, "a principal-inbox message");
85
+ }
80
86
  //# sourceMappingURL=request-key-closure.js.map
@@ -71,6 +71,11 @@ export declare const FILE_HISTORY_DISABLED_NO_RESTORE = "fileHistory: 'disabled'
71
71
  * 正是这个词关掉的记录 —— 两义都与关断词矛盾)。调用前值形已由上面的单成员表与既有布尔门判过。
72
72
  */
73
73
  export declare function fileHistoryRestoreConflict(body: Pick<TaskRequestBody, "fileHistory" | "restoreFiles" | "rewindFiles" | "rewindFilesTo">): boolean;
74
+ /**
75
+ * 还原键里请求**真带了的**那几个(顺序固定:`restoreFiles` · `rewindFilesTo` · 退役的 `rewindFiles`)。{@link fileHistoryRestoreConflict} 的「还原」一半就是它非空 ——
76
+ * 判据只有这一份,拒体的 `detail.fields` 点名的也是它(判与点名不会各读各的)。
77
+ */
78
+ export declare function fileHistoryRestoreKeysInBody(body: Pick<TaskRequestBody, "restoreFiles" | "rewindFiles" | "rewindFilesTo">): Array<"restoreFiles" | "rewindFilesTo" | "rewindFiles">;
74
79
  /**
75
80
  * **单成员闭集键表** —— 每键合法值只有它自己那一个关断词(`word`),缺席=照常,没有「开」的拼法。
76
81
  *
@@ -3,9 +3,17 @@ export const MEMORY_OFF_SPELLING_MESSAGE = "memory must be the string 'off' when
3
3
  export const FILE_HISTORY_OFF_SPELLING_MESSAGE = "fileHistory must be the string 'disabled' when present (the request-level declaration that this run records no file history — no backup of an edited file, and no file restore in the same request; absent = the deployment's setting — there is no 'enabled' spelling)";
4
4
  export const FILE_HISTORY_DISABLED_NO_RESTORE = "fileHistory: 'disabled' cannot ride with a file restore (restoreFiles, rewindFilesTo, or the retired rewindFiles) — the request turns this run's file history off and asks to restore files from it in the same breath; the engine would refuse it (rewind.capture_disabled) only after the session had already been branched at resumeAt, which it does not undo, so it is refused here, before any side effect. Drop fileHistory to restore, or drop the restore to run without file history";
5
5
  export function fileHistoryRestoreConflict(body) {
6
- if (body.fileHistory !== "disabled")
7
- return false;
8
- return body.restoreFiles === true || body.rewindFiles === true || (typeof body.rewindFilesTo === "string" && body.rewindFilesTo.length > 0);
6
+ return body.fileHistory === "disabled" && fileHistoryRestoreKeysInBody(body).length > 0;
7
+ }
8
+ export function fileHistoryRestoreKeysInBody(body) {
9
+ const out = [];
10
+ if (body.restoreFiles === true)
11
+ out.push("restoreFiles");
12
+ if (typeof body.rewindFilesTo === "string" && body.rewindFilesTo.length > 0)
13
+ out.push("rewindFilesTo");
14
+ if (body.rewindFiles === true)
15
+ out.push("rewindFiles");
16
+ return out;
9
17
  }
10
18
  const SINGLE_MEMBER_OFF_FIELDS = [
11
19
  { field: "memoryCapture", word: "off", message: MEMORY_CAPTURE_SPELLING_MESSAGE },
@@ -17,7 +17,7 @@
17
17
  * 运维 / 中心的审批名单读同一份,没有「这一处空名册、那一处带名册」的两种读法。
18
18
  * **读成空的哪些原因词是拒面,按方向定**:**限制侧**(读成空 = 静默放行:技能 `disallowedTools`、`excludeTools` / 子代 `denyTools`、`settings.permissions.deny` / `ask`、运维 / 中心的审批名单)四类全拒 ——
19
19
  * 近似名 · 退役名 · 文法读不出 · 不带内容形的工具带内容;**放行侧**(读成空 = 想放的什么也没放:`settings.permissions.allow`、根 / 子代 `allowTools`、技能 `allowedTools`)**只拒近似名**
20
- * ({@link allowSideReadsAsNothing}):近似名现名唯一、确定是笔误;退役名 / 内容形 / 文法读不出 / 协议名对端段通配照 7.130.0 受理、交引擎既有通告(引擎侧的终形是把退役名归一到现名并在用户面点名,到货前放行侧不拒 ——
20
+ * ({@link allowSideReadsAsNothing}):近似名现名唯一、确定是笔误;退役名 / 内容形 / 文法读不出 / 协议名对端段通配照 7.130.0 受理、交引擎既有通告(其中选择器清单 `allowTools` 里**有后继**的退役名〔`Task` ⇒ `Agent`、`bash` ⇒ `Bash`〕core 7.52.0 起由引擎开跑前拒,不在本仓拒面;规则表上的退役名引擎照旧告运维 ——
21
21
  * 壳转投的 CC 用户 settings 里这些极常见,尤其内容形里的 `$VAR`(`Bash(echo $HOME)`)读成 `grammar`,拒了 = 每次提交 400)。运维的 `APPROVAL_GRANT` 是运维自己的配置:任何读成空都拒启(写错了当场改)。
22
22
  * 技能拒侧那一拒与引擎 #1372(core 7.43.0:那只技能不激活)是同一件事的两处 —— 7.118.0 重估过、本版**不退**:本仓的续跑腿把引擎的
23
23
  * `checkpoint.config_refused`(`config.skill_deny_unreadable`)答得不一(资源停车续跑腿 500、`/decide` 先结了卡、`/wake` 先铸了 run 行),先统一那一层再退
@@ -27,8 +27,13 @@
27
27
  * **真未知名**(拼写合法、没有近似也没有退役对应 —— 懒挂载的合法形,例如一台之后才连上的 MCP 服务器的工具)不是读成空:原样保留、运维行告知一次,不拒。
28
28
  * 选择器读一条条目 = 引擎 `judgeToolNameList` 的读法({@link selectorEntryName}):先取工具名那一段再只判名字(限制侧 `Tool(content)` ⇒ 整只工具,内容里写什么都不读;放行侧内容形引擎告「什么也不授」,受理口不拒);
29
29
  * `*` 在放行侧是「本层不设名单」、在限制侧读成空;限制侧 `mcp__*` / `a2a__*`(整个协议的拒)合法。
30
+ * ⑤ **机读位**:拒体的码与句子是第一处命中的清单的(句子冻结),体另带这一遍判下来的**全部**读成空的条目(`entry-problems.ts` 的 `detail.problems`,{@link inertToolListEntryOf} 铸);
31
+ * 放行侧选择器清单里受理口没拒、却什么也不放的条目随受理应答的 `warnings` 交回({@link allowSelectorWarningsOf})—— 两处读同一次条目读法({@link selectorReadings}),不另判。
30
32
  */
33
+ import type { TightenOnlySeatField } from "./tighten-only-seats.js";
31
34
  import { compileAllowList } from "@sema-agent/core";
35
+ import { type LimitRefusal } from "./limit-refusal.js";
36
+ import { type EntryProblem } from "./entry-problems.js";
32
37
  /** ① 形:字符串数组(空串也是字符串 —— 引擎把它读成 `grammar` 并通告 / 拒,见 ③)。 */
33
38
  export declare const ruleEntryListShapeOk: (v: unknown) => v is readonly string[];
34
39
  /**
@@ -42,14 +47,10 @@ export declare const ruleEntryListShapeOk: (v: unknown) => v is readonly string[
42
47
  * 没有真实用法需要上千条」。抬不抬这个数是产品判断,不随提货改。
43
48
  */
44
49
  export declare const MAX_ALLOW_LAYER_ENTRIES = 1000;
45
- /** 超帽的拒句(不截:截掉的尾项读起来像「在生效」)—— 句子的唯一铸点(请求 allow 桶的 wire 拒体按字段重铸也调它)。 */
50
+ /** 超帽的拒句({@link allowLayerOverCap} 的句子;请求 allow 桶的拒句按字段重铸时读它)。 */
46
51
  export declare function describeAllowLayerOverCap(field: string, count: number): string;
47
- /** 一张条目表超了 {@link MAX_ALLOW_LAYER_ENTRIES} ⇒ 拒句 + 机读两数;没超 ⇒ `undefined`。四张表同调这一只。 */
48
- export declare function allowLayerEntryCountIssue(field: string, list: readonly unknown[]): {
49
- readonly message: string;
50
- readonly count: number;
51
- readonly cap: number;
52
- } | undefined;
52
+ /** 一张条目表超了 {@link MAX_ALLOW_LAYER_ENTRIES} ⇒ 拒(句子 + 机读位 `field` / `reason: "over_cap"` / `count` / `cap`);没超 ⇒ `undefined`。四张表同调这一只。 */
53
+ export declare function allowLayerEntryCountIssue(field: string, list: readonly unknown[]): LimitRefusal | undefined;
53
54
  /** 一条引擎读成空的条目(引擎的形:原因词,名字层另带判词 / 1:1 现名;包根不导出这只具名型 ⇒ 从 `compileAllowList` 的返回型取,不手抄)。 */
54
55
  export type InertRuleEntry = ReturnType<typeof compileAllowList>["inert"][number];
55
56
  /**
@@ -130,9 +131,9 @@ export type ToolListLayer = keyof typeof TOOL_LIST_FACES;
130
131
  /**
131
132
  * 请求体 `settings.permissions.deny` / `ask`(规则编译器读的收紧表)所在的层 —— **不在** {@link toolListsOf} 的扫描里:它们的判与句子的唯一铸点在 `config.ts` 的
132
133
  * `unmatchableToolNamesRefusal`(经 `task-settings.ts` 的 `rulePolicyBucketsRefusal`,单表桶序;拒点是 `applyTaskSettings`,422),存体预判(`http/stored-body-replay.ts`)调同一只函数(home 同源于部署配置),把命中装成本型。
133
- * 层名进这个联合只为让命中能带坐标进 409 体与运维日志。
134
+ * 层名进这个联合只为让命中能带坐标进 409 体与运维日志。S-1351 起「只收紧」座位族的四座(`tighten-only-seats.ts`,坐标由座位表派生)同走这条路:座位门命中(形 / 超帽 / 条目)与 `permissions.neverAuto` 的名字层。
134
135
  */
135
- export type RulePolicyLayer = "settings.permissions.deny" | "settings.permissions.ask";
136
+ export type RulePolicyLayer = "settings.permissions.deny" | "settings.permissions.ask" | TightenOnlySeatField;
136
137
  /** 一份提交体里第一处「工具名清单里有引擎读成空的条目」:在哪一层、哪个方向、拒码、拒句(超帽时另带机读字段,同 `settings.permissions.*` 桶超帽的形)。 */
137
138
  export interface InertToolListEntry {
138
139
  readonly layer: ToolListLayer | RulePolicyLayer;
@@ -150,6 +151,12 @@ export declare function replayInertEntry(layer: ToolListLayer | RulePolicyLayer,
150
151
  export interface SkillDenyInertEntry extends InertToolListEntry {
151
152
  readonly layer: SkillListLayer;
152
153
  }
154
+ /**
155
+ * 一条技能(顶层 `skills[k]` / 子代 `agents[i].skills[j]`,`at` = 它的体内坐标)两只清单的**条数帽**:先 `allowedTools` 后 `disallowedTools`(与 7.131.0 的判序同)。
156
+ * 判与句子就是 {@link overCapOfList} 那一只(拒点 `resolveSpec` 两腿同经的 {@link inertToolListEntryOf} 先过的也是它):受理口在技能的两道形门处调它
157
+ * (`http/admission.ts` 的 `validateUserSkills` 与 `spec-fields.ts` 的 `validateTaskAgents`:两道门都逐条先形、后帽 —— 与 7.131.0 的拒点与判序同,码与先后不变),句子与机读位点体内坐标。
158
+ */
159
+ export declare function skillToolListsOverCap(skill: unknown, at: string, scope: "top" | "agent"): InertToolListEntry | undefined;
153
160
  /**
154
161
  * ③ 的拒侧在**提交体**上的判,技能那两层(顶层 `skills[]` 与子代 `agents[].skills[]`;第一处命中即答)。全部工具名清单的判是 {@link inertToolListEntryOf}(调用点两处都调它);
155
162
  * 本函数单独导出是给随包排空脚本:那条判据(`skill-deny-inert`)只数技能这两层,SQL 车道的孪生也只看技能的清单。
@@ -167,7 +174,7 @@ export declare function skillDenyInertEntryOf(body: unknown): SkillDenyInertEntr
167
174
  * 本函数只是「在体的哪几处取清单」;句子只有一个有界的组句器({@link describeInertRuleEntries}),清单先过条数帽({@link allowLayerEntryCountIssue})。
168
175
  *
169
176
  * 为什么限制侧四类全拒、放行侧只拒近似名:引擎 7.51.x 把「没有任何工具答应的名字」改成条目原样保留 + 运维行告知一次。限制侧读成空 = **静默放行**(`denyTools:["BASH"]` 以为禁了 `Bash`,子代照用);
170
- * 放行侧读成空 = 想放的什么也没放 —— 其中**近似名**(现名唯一)是确定的笔误,拒并点名现名;**退役名**、**内容形**与**文法读不出**在放行侧照 7.130.0 受理、交引擎既有通告(见头注 ③)。
177
+ * 放行侧读成空 = 想放的什么也没放 —— 其中**近似名**(现名唯一)是确定的笔误,拒并点名现名;**退役名**(选择器清单里有后继的由引擎开跑前拒)、**内容形**与**文法读不出**在放行侧照 7.130.0 受理、交引擎既有通告(见头注 ③)。
171
178
  * **真未知名**(没有近似也没有退役对应)不在读成空之列,原样保留、告运维一次(之后挂上同名工具即生效)。请求的 `settings.permissions.deny` / `ask`
172
179
  * 与运维 / 中心的审批名单读同一张名册,走另一只入口({@link unmatchableToolNamesRefusal},`config.ts`),不在本函数(存体预判调同一只判据、home 同源于部署配置,见 `http/stored-body-replay.ts`)。
173
180
  *
@@ -180,5 +187,25 @@ export declare function skillDenyInertEntryOf(body: unknown): SkillDenyInertEntr
180
187
  * `checkpoint-ctx.ts` `resumeBlockedByPolicyAnswer`),拒在认领之前,行 / 卡 / ctx 不动。
181
188
  */
182
189
  export declare function inertToolListEntryOf(body: unknown, sides?: readonly ToolListSide[]): InertToolListEntry | undefined;
190
+ /**
191
+ * 一个调用方工具的名字面(结构型,`ToolSpec` 满足它):主名、别名、委派工具声明的子代工具池里的行(主名与别名)—— 引擎认这些名字是「这条 run 挂着的工具」。
192
+ */
193
+ export interface CallerToolNames {
194
+ readonly name: string;
195
+ readonly aliases?: readonly string[] | undefined;
196
+ readonly agentToolPool?: ReadonlyArray<{
197
+ readonly name: string;
198
+ readonly aliases?: readonly string[] | undefined;
199
+ }> | undefined;
200
+ }
201
+ /**
202
+ * **放行侧选择器清单的受理告知**(根 `allowTools`、子代定义的 `allowTools`)—— 这两张清单没有面向用户的通告通道(规则表与技能的放行清单读成空,引擎有受众 = 用户的通告
203
+ * `permission.allowed_tool_not_granted`;选择器清单上引擎只告运维一行),壳转投的 `.claude/agents` 文件里的 `tools:` 恰落在这两张表上。受理口**不拒**(引擎是这一面的判官,#1736 起
204
+ * 没有任何工具答应的名字保留、只告),把「这几条什么也不放」作为 `warnings` 随受理应答交回:每条 `{ code, field, entry, reason }`(形的属主 `entry-problems.ts`),`code` = 这张清单被拒时的码。
205
+ * 限制侧不告(`denyTools` / `excludeTools` 的近似名 / 退役名 / 文法读不出已是 400)。
206
+ *
207
+ * 在 `resolveSpec` **之后**问(近似名那一类已先 400):`tools` 是这一请求装配出的调用方工具(`spec.tools`,名字面见 {@link CallerToolNames})。超帽 / 形不对的清单不读(受理门先拒)。
208
+ */
209
+ export declare function allowSelectorWarningsOf(body: unknown, tools: readonly CallerToolNames[]): readonly EntryProblem[];
183
210
  export {};
184
211
  //# sourceMappingURL=rule-entry-list.d.ts.map
@@ -1,16 +1,19 @@
1
1
  import { PROTOCOL_TABLE, compileAllowList, parsePermissionRule } from "@sema-agent/core";
2
2
  import { displayListEntry } from "./list-entry-display.js";
3
+ import { limitRefusal } from "./limit-refusal.js";
3
4
  import { TOOL_NAME_ROSTER } from "./namespaced-rule-name.js";
5
+ import { NOT_IN_ROSTER, entryProblem, entryProblemsFacts } from "./entry-problems.js";
4
6
  export const ruleEntryListShapeOk = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
5
7
  export const MAX_ALLOW_LAYER_ENTRIES = 1_000;
8
+ const ALLOW_LAYER_OVER_CAP_TAIL = "Refused rather than truncated: a truncated list silently drops the entries past the cap. Merge entries into broader ones (mcp__<server>__*, Bash(<prefix>:*), Read(//<dir>/**)) or trim the list";
9
+ function allowLayerOverCap(field, count) {
10
+ return limitRefusal(field, "entries", count, MAX_ALLOW_LAYER_ENTRIES, { tail: ALLOW_LAYER_OVER_CAP_TAIL });
11
+ }
6
12
  export function describeAllowLayerOverCap(field, count) {
7
- return (`${field} has ${count} entries — at most ${MAX_ALLOW_LAYER_ENTRIES} are accepted. Refused rather than truncated: a truncated list silently drops the entries past the cap. ` +
8
- `Merge entries into broader ones (mcp__<server>__*, Bash(<prefix>:*), Read(//<dir>/**)) or trim the list`);
13
+ return allowLayerOverCap(field, count).message;
9
14
  }
10
15
  export function allowLayerEntryCountIssue(field, list) {
11
- if (list.length <= MAX_ALLOW_LAYER_ENTRIES)
12
- return undefined;
13
- return { message: describeAllowLayerOverCap(field, list.length), count: list.length, cap: MAX_ALLOW_LAYER_ENTRIES };
16
+ return list.length <= MAX_ALLOW_LAYER_ENTRIES ? undefined : allowLayerOverCap(field, list.length);
14
17
  }
15
18
  export function inertRuleEntriesOf(list, behavior) {
16
19
  return compileAllowList(list, behavior, TOOL_NAME_ROSTER).inert;
@@ -74,14 +77,17 @@ function selectorEntryName(entry) {
74
77
  }
75
78
  const isProtocolWideName = (name) => PROTOCOL_TABLE.some((e) => name === `${e.prefix}*`);
76
79
  function selectorInertEntriesOf(list, side) {
80
+ const readings = selectorReadings(list, side);
81
+ return side === "allow" ? readings.filter((i) => allowSideReadsAsNothing(i.reason)) : readings;
82
+ }
83
+ function selectorReadings(list, side) {
77
84
  return list.flatMap((entry) => {
78
85
  if (entry === "*" && side === "allow")
79
86
  return [];
80
87
  const name = selectorEntryName(entry);
81
88
  if (side === "deny" && isProtocolWideName(name))
82
89
  return [];
83
- const inert = compileAllowList([name], "deny", TOOL_NAME_ROSTER).inert.map((i) => ({ ...i, entry }));
84
- return side === "allow" ? inert.filter((i) => allowSideReadsAsNothing(i.reason)) : inert;
90
+ return compileAllowList([name], "deny", TOOL_NAME_ROSTER).inert.map((i) => ({ ...i, entry }));
85
91
  });
86
92
  }
87
93
  function allowSideReadsAsNothing(reason) {
@@ -114,14 +120,16 @@ function inertEntriesOfList(list, layer) {
114
120
  function* toolListsOf(body) {
115
121
  const skills = body["skills"];
116
122
  if (Array.isArray(skills)) {
117
- for (const skill of skills) {
123
+ for (let k = 0; k < skills.length; k++) {
124
+ const skill = skills[k];
118
125
  if (!isPlainRecord(skill))
119
126
  continue;
120
- yield { layer: "skills", field: "skill.disallowedTools", prefix: "", list: skill["disallowedTools"] };
127
+ yield { layer: "skills", field: "skill.disallowedTools", prefix: "", at: `skills[${k}].disallowedTools`, list: skill["disallowedTools"] };
121
128
  }
122
- for (const skill of skills) {
129
+ for (let k = 0; k < skills.length; k++) {
130
+ const skill = skills[k];
123
131
  if (isPlainRecord(skill))
124
- yield { layer: "skills.allowedTools", field: "skill.allowedTools", prefix: "", list: skill["allowedTools"] };
132
+ yield { layer: "skills.allowedTools", field: "skill.allowedTools", prefix: "", at: `skills[${k}].allowedTools`, list: skill["allowedTools"] };
125
133
  }
126
134
  }
127
135
  const agents = body["agents"];
@@ -134,7 +142,7 @@ function* toolListsOf(body) {
134
142
  for (let j = 0; j < agentSkills.length; j++) {
135
143
  const skill = agentSkills[j];
136
144
  if (isPlainRecord(skill))
137
- yield { layer: "agents.skills", field: "skill.disallowedTools", prefix: `agents[${i}]: skills[${j}]: `, list: skill["disallowedTools"] };
145
+ yield { layer: "agents.skills", field: "skill.disallowedTools", prefix: `agents[${i}]: skills[${j}]: `, at: `agents[${i}].skills[${j}].disallowedTools`, list: skill["disallowedTools"] };
138
146
  }
139
147
  }
140
148
  for (let i = 0; i < agents.length; i++) {
@@ -145,51 +153,72 @@ function* toolListsOf(body) {
145
153
  for (let j = 0; j < agentSkills.length; j++) {
146
154
  const skill = agentSkills[j];
147
155
  if (isPlainRecord(skill))
148
- yield { layer: "agents.skills.allowedTools", field: "skill.allowedTools", prefix: `agents[${i}]: skills[${j}]: `, list: skill["allowedTools"] };
156
+ yield { layer: "agents.skills.allowedTools", field: "skill.allowedTools", prefix: `agents[${i}]: skills[${j}]: `, at: `agents[${i}].skills[${j}].allowedTools`, list: skill["allowedTools"] };
149
157
  }
150
158
  }
151
159
  for (let i = 0; i < agents.length; i++) {
152
160
  const agent = agents[i];
153
161
  if (!isPlainRecord(agent))
154
162
  continue;
155
- yield { layer: "agents.denyTools", field: `agents[${i}].denyTools`, prefix: "", list: agent["denyTools"] };
156
- yield { layer: "agents.allowTools", field: `agents[${i}].allowTools`, prefix: "", list: agent["allowTools"] };
163
+ yield { layer: "agents.denyTools", field: `agents[${i}].denyTools`, prefix: "", at: `agents[${i}].denyTools`, list: agent["denyTools"] };
164
+ yield { layer: "agents.allowTools", field: `agents[${i}].allowTools`, prefix: "", at: `agents[${i}].allowTools`, list: agent["allowTools"] };
157
165
  }
158
166
  }
159
- yield { layer: "excludeTools", field: "excludeTools", prefix: "", list: body["excludeTools"] };
160
- yield { layer: "allowTools", field: "allowTools", prefix: "", list: body["allowTools"] };
167
+ yield { layer: "excludeTools", field: "excludeTools", prefix: "", at: "excludeTools", list: body["excludeTools"] };
168
+ yield { layer: "allowTools", field: "allowTools", prefix: "", at: "allowTools", list: body["allowTools"] };
161
169
  const settings = body["settings"];
162
170
  const permissions = isPlainRecord(settings) ? settings["permissions"] : undefined;
163
171
  if (isPlainRecord(permissions))
164
- yield { layer: "settings.permissions.allow", field: "settings.permissions.allow", prefix: "", list: permissions["allow"] };
172
+ yield { layer: "settings.permissions.allow", field: "settings.permissions.allow", prefix: "", at: "settings.permissions.allow", list: permissions["allow"] };
165
173
  }
166
- function entryOfList(l) {
174
+ function inertReadingOfList(l) {
167
175
  const face = TOOL_LIST_FACES[l.layer];
168
- if (Array.isArray(l.list)) {
169
- const over = allowLayerEntryCountIssue(l.field, l.list);
170
- if (over !== undefined)
171
- return { layer: l.layer, side: face.side, code: LIST_OVER_CAP_CODE, message: `${l.prefix}${over.message}`, extra: { field: l.field, reason: "over_cap", count: over.count, cap: over.cap } };
172
- }
173
176
  if (!ruleEntryListShapeOk(l.list))
174
177
  return undefined;
175
178
  const inert = inertEntriesOfList(l.list, l.layer);
176
179
  if (inert.length === 0)
177
180
  return undefined;
178
- return { layer: l.layer, side: face.side, code: face.code, message: `${l.prefix}${describeInertRuleEntries(l.field, inert)} — ${REFUSAL_TAIL[face.side]}` };
181
+ return { inert, entry: { layer: l.layer, side: face.side, code: face.code, message: `${l.prefix}${describeInertRuleEntries(l.field, inert)} — ${REFUSAL_TAIL[face.side]}` } };
182
+ }
183
+ function inertProblemsOf(l, inert) {
184
+ const face = TOOL_LIST_FACES[l.layer];
185
+ return inert.map((i) => entryProblem(face.code, l.at, i.entry, i.reason));
186
+ }
187
+ function overCapOfList(l) {
188
+ if (!Array.isArray(l.list))
189
+ return undefined;
190
+ const over = allowLayerEntryCountIssue(l.at, l.list);
191
+ return over === undefined ? undefined : { layer: l.layer, side: TOOL_LIST_FACES[l.layer].side, code: LIST_OVER_CAP_CODE, message: over.message, extra: over.facts };
192
+ }
193
+ export function skillToolListsOverCap(skill, at, scope) {
194
+ if (!isPlainRecord(skill))
195
+ return undefined;
196
+ const allowLayer = scope === "top" ? "skills.allowedTools" : "agents.skills.allowedTools";
197
+ const denyLayer = scope === "top" ? "skills" : "agents.skills";
198
+ return (overCapOfList({ layer: allowLayer, field: "skill.allowedTools", prefix: "", at: `${at}.allowedTools`, list: skill["allowedTools"] }) ??
199
+ overCapOfList({ layer: denyLayer, field: "skill.disallowedTools", prefix: "", at: `${at}.disallowedTools`, list: skill["disallowedTools"] }));
179
200
  }
180
201
  function firstInertEntry(body, acceptLayer, acceptSide) {
181
202
  if (!isPlainRecord(body))
182
203
  return undefined;
204
+ let first;
205
+ const problems = [];
183
206
  for (const l of toolListsOf(body)) {
184
207
  if (!acceptLayer(l.layer))
185
208
  continue;
186
- const entry = entryOfList(l);
187
- if (entry === undefined)
209
+ const over = overCapOfList(l);
210
+ if (over !== undefined) {
211
+ if (first === undefined)
212
+ return over;
188
213
  continue;
189
- if (entry.extra !== undefined || acceptSide(entry.side))
190
- return entry;
214
+ }
215
+ const reading = inertReadingOfList(l);
216
+ if (reading === undefined || !acceptSide(reading.entry.side))
217
+ continue;
218
+ first ??= reading.entry;
219
+ problems.push(...inertProblemsOf(l, reading.inert));
191
220
  }
192
- return undefined;
221
+ return first === undefined ? undefined : { ...first, extra: { ...entryProblemsFacts(problems) } };
193
222
  }
194
223
  export function skillDenyInertEntryOf(body) {
195
224
  return firstInertEntry(body, (layer) => layer === "skills" || layer === "agents.skills", () => true);
@@ -197,4 +226,51 @@ export function skillDenyInertEntryOf(body) {
197
226
  export function inertToolListEntryOf(body, sides = ["allow", "deny"]) {
198
227
  return firstInertEntry(body, () => true, (side) => sides.includes(side));
199
228
  }
229
+ function callerToolNameSet(tools) {
230
+ const names = new Set();
231
+ for (const t of tools) {
232
+ names.add(t.name);
233
+ for (const a of t.aliases ?? [])
234
+ names.add(a);
235
+ for (const row of t.agentToolPool ?? []) {
236
+ names.add(row.name);
237
+ for (const a of row.aliases ?? [])
238
+ names.add(a);
239
+ }
240
+ }
241
+ return names;
242
+ }
243
+ const isProtocolNamespacedName = (name) => PROTOCOL_TABLE.some((e) => name.startsWith(e.prefix));
244
+ function allowSelectorEntryWarning(entry, callerNames) {
245
+ if (entry === "*")
246
+ return undefined;
247
+ if (callerNames.has(selectorEntryName(entry)))
248
+ return undefined;
249
+ const read = selectorReadings([entry], "allow")[0];
250
+ if (read !== undefined)
251
+ return read.reason;
252
+ const name = selectorEntryName(entry);
253
+ if (isProtocolNamespacedName(name))
254
+ return undefined;
255
+ return TOOL_NAME_ROSTER.has(name) ? undefined : NOT_IN_ROSTER;
256
+ }
257
+ export function allowSelectorWarningsOf(body, tools) {
258
+ if (!isPlainRecord(body))
259
+ return [];
260
+ const callerNames = callerToolNameSet(tools);
261
+ const out = [];
262
+ for (const l of toolListsOf(body)) {
263
+ if (l.layer !== "allowTools" && l.layer !== "agents.allowTools")
264
+ continue;
265
+ if (!ruleEntryListShapeOk(l.list) || l.list.length > MAX_ALLOW_LAYER_ENTRIES)
266
+ continue;
267
+ const code = TOOL_LIST_FACES[l.layer].code;
268
+ for (const entry of l.list) {
269
+ const reason = allowSelectorEntryWarning(entry, callerNames);
270
+ if (reason !== undefined)
271
+ out.push(entryProblem(code, l.at, entry, reason));
272
+ }
273
+ }
274
+ return out;
275
+ }
200
276
  //# sourceMappingURL=rule-entry-list.js.map
@@ -2,9 +2,9 @@ import { randomUUID } from "node:crypto";
2
2
  import { z } from "zod";
3
3
  import { recordFailOpen } from "./observability/fail-open.js";
4
4
  import { createLogger } from "./observability/logger.js";
5
- import { ABSOLUTE_HOST_PATH_MAX } from "@sema-agent/settings-schema";
5
+ import { ABSOLUTE_HOST_PATH_MAX, hasControlOrBidi } from "@sema-agent/settings-schema";
6
6
  import { isDirectWritableRuleBehavior } from "./permission-rule-vocab.js";
7
- import { CONTROL_AND_BIDI_CHARS, hasBidiControls } from "./text-bidi.js";
7
+ import { hasBidiControls } from "./text-bidi.js";
8
8
  import { confirmRuleApproval, RULE_BEHAVIORS, parseRuleText, ruleReachesProgramRun, ruleToolGrammarOf, precheckEditedRuleText, prepareCardApproval, prepareCcImport, redeemRuleBatch, redeemRuleTicket, addPersistedRule, removePersistedRule, isValidDurableScope, effectiveOrThrow, readRowBehavior, } from "@sema-agent/core";
9
9
  import { buildRulePayloadHash } from "./plugins/permission-rule-store-sql.js";
10
10
  export const RULE_IMPORT_TICKET_TTL_MS = 10 * 60_000;
@@ -178,7 +178,7 @@ function screenLocalImportRow(row) {
178
178
  detail: "this project root carries bidirectional control characters — the directory a reader sees is not the directory the matcher would use",
179
179
  };
180
180
  }
181
- if (scope.kind === "project" && CONTROL_AND_BIDI_DETECT_RE.test(scope.root)) {
181
+ if (scope.kind === "project" && hasControlOrBidi(scope.root)) {
182
182
  return {
183
183
  reason: "scope_control_chars",
184
184
  detail: "this project root carries control bytes (C0/DEL) — it is not a path, one SQL dialect refuses to store it at all, and it breaks the separator assumption this lane's comparison keys rest on",
@@ -220,7 +220,6 @@ function screenLocalImportRow(row) {
220
220
  return consistent(written.rule);
221
221
  }
222
222
  const LOCAL_IMPORT_LAYER_PATH = "local-import:rules";
223
- const CONTROL_AND_BIDI_DETECT_RE = new RegExp(`[${CONTROL_AND_BIDI_CHARS}]`);
224
223
  const LOCAL_IMPORT_KEY_SEP = "\u0000";
225
224
  function buildLocalImportLayers(candidates) {
226
225
  const byRoot = new Map();