@sema-agent/server 7.133.0 → 7.135.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/MIGRATION.md +221 -0
  2. package/README.md +2 -2
  3. package/README.zh-CN.md +2 -2
  4. package/USAGE.md +222 -36
  5. package/deploy/sema-up/README.md +16 -0
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +14 -0
  11. package/deploy/sema-up/chart/templates/server.yaml +14 -0
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/dist/adoption/plan.d.ts +1 -1
  15. package/dist/approval-ask-audit-store.d.ts +25 -25
  16. package/dist/approval-ask-machine.d.ts +2 -2
  17. package/dist/approval-card.d.ts +66 -154
  18. package/dist/approval-card.js +33 -52
  19. package/dist/approval-content-kind.d.ts +26 -6
  20. package/dist/approval-content-kind.js +23 -3
  21. package/dist/approval-deny-reasons.d.ts +1 -1
  22. package/dist/approval-gate-currency.d.ts +91 -0
  23. package/dist/approval-gate-currency.js +120 -0
  24. package/dist/approval-hmac.d.ts +7 -7
  25. package/dist/approval-policy-settlement.d.ts +2 -2
  26. package/dist/approval-reconciler.d.ts +3 -3
  27. package/dist/approval.d.ts +14 -8
  28. package/dist/approval.js +35 -16
  29. package/dist/auth-bridge.d.ts +1 -1
  30. package/dist/auto-mode-face.d.ts +4 -4
  31. package/dist/background-session-reap.d.ts +2 -2
  32. package/dist/bake-runner/main.d.ts +2 -2
  33. package/dist/bake-runner/runner.d.ts +4 -4
  34. package/dist/bench/s1/live-deps.d.ts +1 -1
  35. package/dist/bench/s1/run-firm.d.ts +1 -1
  36. package/dist/boot/coordinators.d.ts +7 -2
  37. package/dist/boot/coordinators.js +8 -5
  38. package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
  39. package/dist/boot/deferred-sandbox-path-env.js +0 -5
  40. package/dist/boot/engine-lease.d.ts +5 -5
  41. package/dist/boot/execution-env.d.ts +16 -15
  42. package/dist/boot/execution-env.js +19 -21
  43. package/dist/boot/fatal-exit.d.ts +2 -2
  44. package/dist/boot/late-binds.d.ts +1 -1
  45. package/dist/boot/leader.d.ts +2 -0
  46. package/dist/boot/leader.js +2 -1
  47. package/dist/boot/memory-boundary.d.ts +2 -2
  48. package/dist/boot/memory-consolidation.d.ts +15 -15
  49. package/dist/boot/parked-revive-gate.d.ts +3 -3
  50. package/dist/boot/parked-revive-gate.js +3 -2
  51. package/dist/boot/read-deny-anchor-audit.js +2 -2
  52. package/dist/boot/reapers.d.ts +4 -4
  53. package/dist/boot/resolve-spec.d.ts +1 -1
  54. package/dist/boot/resolve-spec.js +28 -24
  55. package/dist/boot/runner-deps.d.ts +29 -16
  56. package/dist/boot/runner-deps.js +12 -2
  57. package/dist/boot/session-faces.d.ts +3 -3
  58. package/dist/boot/session-faces.js +11 -30
  59. package/dist/boot/shutdown.d.ts +5 -5
  60. package/dist/boot/side-query-lane.d.ts +2 -2
  61. package/dist/boot/stage-05-execution-env.js +4 -4
  62. package/dist/boot/stage-06-runners.d.ts +4 -3
  63. package/dist/boot/stage-06-runners.js +15 -4
  64. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  65. package/dist/boot/stage-08-reapers.d.ts +2 -1
  66. package/dist/boot/stage-09-leader.d.ts +2 -1
  67. package/dist/boot/stage-09-leader.js +2 -2
  68. package/dist/boot/stage-10-http-server.d.ts +2 -1
  69. package/dist/boot/stage-10-http-server.js +2 -1
  70. package/dist/boot/stores.d.ts +8 -0
  71. package/dist/boot/stores.js +10 -13
  72. package/dist/boot/web-admin.d.ts +21 -15
  73. package/dist/boot/web-admin.js +16 -12
  74. package/dist/boot/workflow-orchestration.js +2 -9
  75. package/dist/brain.d.ts +11 -11
  76. package/dist/budget.d.ts +4 -4
  77. package/dist/budget.js +5 -1
  78. package/dist/caller-text-echo.d.ts +2 -0
  79. package/dist/caller-text-echo.js +2 -1
  80. package/dist/canonical-json.d.ts +2 -41
  81. package/dist/canonical-json.js +2 -13
  82. package/dist/capabilities/approvals-push.d.ts +4 -4
  83. package/dist/capabilities/builtin-tools.d.ts +5 -5
  84. package/dist/capabilities/center-plugins.d.ts +5 -5
  85. package/dist/capabilities/center-plugins.js +1 -1
  86. package/dist/capabilities/center-prompts.d.ts +1 -1
  87. package/dist/capabilities/center-wiring.d.ts +1 -1
  88. package/dist/capabilities/composite-members.d.ts +2 -2
  89. package/dist/capabilities/composite-members.js +1 -1
  90. package/dist/capabilities/execution-lane.d.ts +5 -5
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +5 -5
  93. package/dist/capabilities/mcp-probe.d.ts +10 -7
  94. package/dist/capabilities/mcp-probe.js +2 -2
  95. package/dist/capabilities/sandbox-file-send.d.ts +1 -18
  96. package/dist/capabilities/sandbox-file-send.js +0 -7
  97. package/dist/capabilities/scenarios.d.ts +28 -10
  98. package/dist/capabilities/scenarios.js +15 -5
  99. package/dist/capabilities/send-user-file-tool.d.ts +1 -1
  100. package/dist/capabilities/skills.d.ts +31 -12
  101. package/dist/capabilities/skills.js +23 -17
  102. package/dist/capabilities/tool-defer.d.ts +1 -1
  103. package/dist/capability-facts.d.ts +27 -24
  104. package/dist/capability-facts.js +18 -20
  105. package/dist/center-config-tier.d.ts +1 -1
  106. package/dist/center-credential.d.ts +4 -4
  107. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  108. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  109. package/dist/checkpoint-identity.d.ts +5 -0
  110. package/dist/checkpoint-identity.js +14 -0
  111. package/dist/config-catalog.d.ts +12 -12
  112. package/dist/config-invariants.d.ts +4 -4
  113. package/dist/config-invariants.js +3 -2
  114. package/dist/config-lkg.d.ts +1 -1
  115. package/dist/config-provider.d.ts +13 -13
  116. package/dist/config-provider.js +2 -1
  117. package/dist/config-types.d.ts +83 -83
  118. package/dist/config.d.ts +26 -24
  119. package/dist/config.js +12 -10
  120. package/dist/cross-session-settings.d.ts +1 -1
  121. package/dist/delegated-session-owner.d.ts +16 -13
  122. package/dist/delegated-session-owner.js +9 -10
  123. package/dist/deployment-governance.d.ts +16 -16
  124. package/dist/deployment-shape.d.ts +127 -0
  125. package/dist/deployment-shape.js +72 -0
  126. package/dist/device-store.d.ts +1 -1
  127. package/dist/device-ws-hub.d.ts +1 -1
  128. package/dist/egress-redirect.d.ts +1 -1
  129. package/dist/entry-mode-clamp-notice.d.ts +2 -2
  130. package/dist/env-facts.d.ts +10 -9
  131. package/dist/env-facts.js +1 -1
  132. package/dist/env-name-allowlist-knobs.d.ts +5 -5
  133. package/dist/exec-bounds.d.ts +2 -2
  134. package/dist/execution-lane-caps.d.ts +31 -43
  135. package/dist/execution-lane-caps.js +0 -13
  136. package/dist/field-conflict.d.ts +2 -1
  137. package/dist/field-conflict.js +1 -0
  138. package/dist/file-history-capture.d.ts +9 -9
  139. package/dist/file-history-disclosure.d.ts +50 -9
  140. package/dist/file-history-disclosure.js +8 -13
  141. package/dist/fleet/drain-entry.d.ts +2 -2
  142. package/dist/fleet/fleet-bus.d.ts +26 -14
  143. package/dist/fleet/fleet-bus.js +6 -5
  144. package/dist/fleet/fleet-reconciler.d.ts +9 -9
  145. package/dist/fleet/subagent-tail-bus.d.ts +4 -4
  146. package/dist/fleet-client.d.ts +13 -13
  147. package/dist/fleet-lease.d.ts +16 -16
  148. package/dist/governance-http-status.d.ts +2 -2
  149. package/dist/hooks/hook-llm.d.ts +7 -7
  150. package/dist/hooks/hook-runner.d.ts +57 -30
  151. package/dist/hooks/hook-runner.js +38 -20
  152. package/dist/host-decision.d.ts +5 -5
  153. package/dist/host-lsp-manager.d.ts +5 -5
  154. package/dist/hosted-posture.d.ts +23 -13
  155. package/dist/hosted-posture.js +4 -9
  156. package/dist/http/admission.d.ts +2 -2
  157. package/dist/http/admission.js +28 -5
  158. package/dist/http/approval-sweeps.d.ts +1 -1
  159. package/dist/http/approval-sweeps.js +5 -2
  160. package/dist/http/checkpoint-ctx.d.ts +183 -2
  161. package/dist/http/checkpoint-ctx.js +197 -2
  162. package/dist/http/dispatch.d.ts +3 -3
  163. package/dist/http/dispatch.js +3 -3
  164. package/dist/http/durable-run-leg.js +7 -5
  165. package/dist/http/idempotency.d.ts +4 -4
  166. package/dist/http/idempotency.js +2 -2
  167. package/dist/http/mcp-dial-deadline.d.ts +7 -5
  168. package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
  169. package/dist/http/owner-access.d.ts +4 -6
  170. package/dist/http/owner-access.js +1 -1
  171. package/dist/http/principal-gate.d.ts +39 -13
  172. package/dist/http/principal-gate.js +30 -6
  173. package/dist/http/readiness.d.ts +1 -1
  174. package/dist/http/refusal-body.d.ts +12 -0
  175. package/dist/http/refusal-body.js +11 -0
  176. package/dist/http/request-guards.d.ts +4 -13
  177. package/dist/http/request-guards.js +4 -17
  178. package/dist/http/resume-ctx-read.d.ts +53 -6
  179. package/dist/http/resume-ctx-read.js +26 -3
  180. package/dist/http/resume-legs.d.ts +5 -4
  181. package/dist/http/resume-legs.js +47 -29
  182. package/dist/http/route-ctx.d.ts +29 -38
  183. package/dist/http/route-table.d.ts +9 -9
  184. package/dist/http/routes/agents-roster.d.ts +1 -1
  185. package/dist/http/routes/agents-roster.js +2 -3
  186. package/dist/http/routes/approvals-assistant.d.ts +5 -5
  187. package/dist/http/routes/approvals-assistant.js +91 -17
  188. package/dist/http/routes/background.d.ts +3 -3
  189. package/dist/http/routes/background.js +2 -2
  190. package/dist/http/routes/capabilities.d.ts +1 -1
  191. package/dist/http/routes/capabilities.js +16 -8
  192. package/dist/http/routes/config-catalog.d.ts +1 -1
  193. package/dist/http/routes/devices.d.ts +1 -1
  194. package/dist/http/routes/diagnostics.d.ts +6 -6
  195. package/dist/http/routes/diagnostics.js +1 -1
  196. package/dist/http/routes/fleet.d.ts +1 -1
  197. package/dist/http/routes/fleet.js +5 -4
  198. package/dist/http/routes/mcp-reconnect.d.ts +4 -4
  199. package/dist/http/routes/mcp-reconnect.js +3 -3
  200. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  201. package/dist/http/routes/memory-origin.d.ts +1 -1
  202. package/dist/http/routes/notify-wake.d.ts +1 -1
  203. package/dist/http/routes/notify-wake.js +2 -2
  204. package/dist/http/routes/rules.d.ts +1 -1
  205. package/dist/http/routes/rules.js +4 -4
  206. package/dist/http/routes/runs.js +44 -11
  207. package/dist/http/routes/session-sync.d.ts +3 -2
  208. package/dist/http/routes/session-sync.js +109 -62
  209. package/dist/http/routes/sessions-list.d.ts +1 -1
  210. package/dist/http/routes/sessions-list.js +4 -5
  211. package/dist/http/routes/sessions.js +34 -48
  212. package/dist/http/routes/tasks.d.ts +1 -1
  213. package/dist/http/routes/tasks.js +21 -16
  214. package/dist/http/routes/trace-usage.d.ts +1 -1
  215. package/dist/http/routes/trace-usage.js +7 -9
  216. package/dist/http/routes/workflows.d.ts +3 -0
  217. package/dist/http/routes/workflows.js +31 -28
  218. package/dist/http/send.d.ts +5 -5
  219. package/dist/http/server.d.ts +39 -33
  220. package/dist/http/server.js +5 -2
  221. package/dist/http/session-inherit-env.d.ts +3 -3
  222. package/dist/http/sse-lifecycle.d.ts +1 -1
  223. package/dist/http/sse-log.d.ts +2 -2
  224. package/dist/http/submit-ctx.d.ts +4 -3
  225. package/dist/http/submit-ctx.js +19 -3
  226. package/dist/http/sync-submit-body.d.ts +1 -1
  227. package/dist/http/verify-rounds.d.ts +1 -1
  228. package/dist/http/wire-types.d.ts +35 -24
  229. package/dist/index.d.ts +2 -0
  230. package/dist/index.js +1 -0
  231. package/dist/instruction-source-notice.d.ts +2 -2
  232. package/dist/key-resolver.d.ts +3 -3
  233. package/dist/lane-home-probe.d.ts +1 -1
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/leader/diffup.d.ts +2 -2
  236. package/dist/leader/endpoint.d.ts +1 -1
  237. package/dist/leader/fanout.d.ts +1 -1
  238. package/dist/leader/leader.d.ts +4 -4
  239. package/dist/leader/merge.d.ts +3 -3
  240. package/dist/leader/repair-wire.d.ts +1 -1
  241. package/dist/leader/wire.d.ts +9 -5
  242. package/dist/leader/wire.js +8 -7
  243. package/dist/list-entry-display.d.ts +1 -1
  244. package/dist/lsp-evict.d.ts +1 -1
  245. package/dist/main.js +1 -1
  246. package/dist/mcp-assertion-header.d.ts +1 -1
  247. package/dist/memory-layer-legacy-lock.d.ts +1 -1
  248. package/dist/memory-operator-faces.d.ts +1 -1
  249. package/dist/memory-origin-fence.js +2 -2
  250. package/dist/memory-posture.js +4 -2
  251. package/dist/memory-project-layer.d.ts +1 -1
  252. package/dist/memory-scope.d.ts +19 -19
  253. package/dist/memory-store-refusal.d.ts +4 -4
  254. package/dist/model-compat.d.ts +1 -1
  255. package/dist/model-entry-headers.d.ts +2 -2
  256. package/dist/model-entry-refusal.d.ts +17 -17
  257. package/dist/model-provider.d.ts +10 -10
  258. package/dist/model-reach-scope.d.ts +1 -1
  259. package/dist/model-route-endpoint.d.ts +6 -6
  260. package/dist/model-route-url.d.ts +5 -5
  261. package/dist/model-select.d.ts +15 -6
  262. package/dist/model-select.js +5 -0
  263. package/dist/model-unreachable-notice.d.ts +3 -3
  264. package/dist/namespaced-rule-name.d.ts +15 -5
  265. package/dist/namespaced-rule-name.js +3 -2
  266. package/dist/observability/corrupt-read-seat.d.ts +9 -9
  267. package/dist/observability/cost-taxonomy.d.ts +1 -1
  268. package/dist/observability/err-text.d.ts +1 -1
  269. package/dist/observability/fail-open.d.ts +12 -8
  270. package/dist/observability/fail-open.js +12 -8
  271. package/dist/observability/metrics.d.ts +3 -3
  272. package/dist/observability/prompt-manifest.d.ts +19 -8
  273. package/dist/observability/prompt-manifest.js +9 -8
  274. package/dist/observability/run-terminal.d.ts +36 -36
  275. package/dist/observability/secret-env-scrub.d.ts +3 -3
  276. package/dist/observability/tool-trace.d.ts +1 -1
  277. package/dist/observability/tool-trace.js +8 -9
  278. package/dist/operator-ask.d.ts +4 -4
  279. package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
  280. package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
  281. package/dist/orchestration/workflow-completion-inbox.js +29 -7
  282. package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
  283. package/dist/orchestration/workflow-notify-journal.js +17 -0
  284. package/dist/orchestration/workflow-park-decision.d.ts +1 -1
  285. package/dist/orchestration/workflow-park-decision.js +1 -0
  286. package/dist/outbound-dispatcher.d.ts +4 -4
  287. package/dist/parent-watch.d.ts +4 -4
  288. package/dist/parked-decide.d.ts +20 -20
  289. package/dist/parked-decide.js +8 -5
  290. package/dist/parked-revive-surface.d.ts +7 -7
  291. package/dist/parked-revive-surface.js +2 -3
  292. package/dist/peer-directory.d.ts +3 -3
  293. package/dist/peer-directory.js +1 -1
  294. package/dist/permission-rule-list.d.ts +10 -1
  295. package/dist/permission-rule-list.js +7 -5
  296. package/dist/permission-rule-vocab.d.ts +3 -25
  297. package/dist/permission-rule-vocab.js +0 -13
  298. package/dist/plugins/adoption-log-sql.d.ts +1 -1
  299. package/dist/plugins/approval-ask-store-file.d.ts +8 -1
  300. package/dist/plugins/approval-ask-store-file.js +6 -3
  301. package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
  302. package/dist/plugins/approval-ask-store-memory.js +11 -7
  303. package/dist/plugins/approval-ask-store-sql.d.ts +34 -15
  304. package/dist/plugins/approval-ask-store-sql.js +18 -5
  305. package/dist/plugins/approval-exemption-store.d.ts +3 -3
  306. package/dist/plugins/approval-nonce-store.d.ts +3 -3
  307. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  308. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  309. package/dist/plugins/background-agent-store-sql.d.ts +1 -1
  310. package/dist/plugins/background-shell-support.d.ts +2 -2
  311. package/dist/plugins/blob-backend.d.ts +1 -1
  312. package/dist/plugins/caching-session-store.d.ts +24 -33
  313. package/dist/plugins/caching-session-store.js +8 -19
  314. package/dist/plugins/checkpoint-index-columns.d.ts +81 -0
  315. package/dist/plugins/checkpoint-index-columns.js +62 -0
  316. package/dist/plugins/checkpoint-store-sql.d.ts +66 -67
  317. package/dist/plugins/checkpoint-store-sql.js +100 -103
  318. package/dist/plugins/device-store-sql.d.ts +7 -6
  319. package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
  320. package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
  321. package/dist/plugins/file-history-store-sql.d.ts +9 -7
  322. package/dist/plugins/file-history-store-sql.js +27 -15
  323. package/dist/plugins/file-run-store.d.ts +8 -8
  324. package/dist/plugins/fork-routing-session-store.d.ts +2 -2
  325. package/dist/plugins/fork-routing-session-store.js +1 -1
  326. package/dist/plugins/host-platform.d.ts +10 -10
  327. package/dist/plugins/image-bake-store-sql.d.ts +1 -1
  328. package/dist/plugins/image-index-sql.d.ts +1 -1
  329. package/dist/plugins/leader-run-store-sql.d.ts +1 -1
  330. package/dist/plugins/local-checkpoint-store.d.ts +23 -12
  331. package/dist/plugins/local-checkpoint-store.js +29 -4
  332. package/dist/plugins/local-session-store.d.ts +44 -45
  333. package/dist/plugins/local-session-store.js +42 -52
  334. package/dist/plugins/local-session-window.d.ts +12 -6
  335. package/dist/plugins/local-session-window.js +1 -17
  336. package/dist/plugins/mailbox-store-sql.d.ts +2 -2
  337. package/dist/plugins/memory-engine-pg.d.ts +1 -1
  338. package/dist/plugins/memory-run-store.d.ts +4 -4
  339. package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
  340. package/dist/plugins/one-time-migrations.d.ts +76 -39
  341. package/dist/plugins/one-time-migrations.js +127 -34
  342. package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
  343. package/dist/plugins/park-commit-watch.d.ts +3 -3
  344. package/dist/plugins/permission-rule-store-file.d.ts +5 -5
  345. package/dist/plugins/permission-rule-store-file.js +16 -19
  346. package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
  347. package/dist/plugins/permission-rule-store-sql.js +74 -31
  348. package/dist/plugins/pg-cost-quota.d.ts +1 -1
  349. package/dist/plugins/pg-pool.d.ts +2 -2
  350. package/dist/plugins/pg-pool.js +5 -2
  351. package/dist/plugins/pg-rate-limiter.d.ts +1 -1
  352. package/dist/plugins/pg-session-storage.d.ts +9 -21
  353. package/dist/plugins/pg-session-storage.js +51 -42
  354. package/dist/plugins/remote-env-adb.d.ts +10 -10
  355. package/dist/plugins/remote-env-device.d.ts +22 -14
  356. package/dist/plugins/remote-env-device.js +28 -16
  357. package/dist/plugins/remote-env-e2b.d.ts +3 -3
  358. package/dist/plugins/remote-env-host.d.ts +16 -16
  359. package/dist/plugins/remote-env-k8s.d.ts +8 -8
  360. package/dist/plugins/remote-env-local-docker.d.ts +2 -2
  361. package/dist/plugins/remote-env-ssh.d.ts +4 -4
  362. package/dist/plugins/remote-scratchpad.d.ts +2 -3
  363. package/dist/plugins/remote-scratchpad.js +0 -4
  364. package/dist/plugins/remote-shell.d.ts +6 -6
  365. package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
  366. package/dist/plugins/retention-store-sql.d.ts +4 -4
  367. package/dist/plugins/roster-store-sql.d.ts +1 -1
  368. package/dist/plugins/run-store-sql.d.ts +8 -8
  369. package/dist/plugins/schema-consistency.d.ts +2 -2
  370. package/dist/plugins/schema-ensure-legs.d.ts +3 -3
  371. package/dist/plugins/schema-indexes.d.ts +1 -1
  372. package/dist/plugins/schema-live-columns.d.ts +1 -1
  373. package/dist/plugins/session-event-payload.d.ts +4 -4
  374. package/dist/plugins/session-fork.d.ts +34 -0
  375. package/dist/plugins/session-fork.js +29 -0
  376. package/dist/plugins/session-ownership.d.ts +11 -0
  377. package/dist/plugins/session-ownership.js +11 -0
  378. package/dist/plugins/session-placement.d.ts +12 -14
  379. package/dist/plugins/session-placement.js +2 -15
  380. package/dist/plugins/session-policy-store-sql.d.ts +12 -12
  381. package/dist/plugins/session-store.d.ts +2 -2
  382. package/dist/plugins/session-store.js +2 -2
  383. package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
  384. package/dist/plugins/sql-driver.d.ts +8 -8
  385. package/dist/plugins/sql-errors.d.ts +1 -1
  386. package/dist/plugins/sql-json-column.d.ts +21 -21
  387. package/dist/plugins/sql-row-helpers.d.ts +2 -2
  388. package/dist/plugins/store-backend.d.ts +17 -16
  389. package/dist/plugins/store-backend.js +3 -3
  390. package/dist/plugins/store-contracts.d.ts +21 -21
  391. package/dist/plugins/task-attachment-store.d.ts +2 -2
  392. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  393. package/dist/plugins/tidb-pool.d.ts +2 -2
  394. package/dist/plugins/tidb-pool.js +9 -2
  395. package/dist/plugins/tidb-session-store.d.ts +17 -27
  396. package/dist/plugins/tidb-session-store.js +52 -42
  397. package/dist/plugins/tool-result-store-sql.d.ts +1 -1
  398. package/dist/plugins/usage-window-store-sql.d.ts +3 -3
  399. package/dist/plugins/user-input-ledger-file.d.ts +1 -1
  400. package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
  401. package/dist/plugins/web-search.d.ts +19 -5
  402. package/dist/plugins/web-search.js +19 -4
  403. package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
  404. package/dist/plugins/workflow-journal-payload.js +32 -0
  405. package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
  406. package/dist/plugins/workflow-journal-store-sql.js +34 -15
  407. package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
  408. package/dist/posture-source.d.ts +11 -11
  409. package/dist/principal-jwt.d.ts +6 -6
  410. package/dist/project-identity.d.ts +3 -3
  411. package/dist/project-memory.d.ts +4 -4
  412. package/dist/read-face-posture.d.ts +7 -7
  413. package/dist/request-key-closure.d.ts +1 -1
  414. package/dist/request-key-closure.js +1 -1
  415. package/dist/request-tool-axes.d.ts +12 -0
  416. package/dist/request-tool-axes.js +20 -0
  417. package/dist/request-value-closure.d.ts +15 -8
  418. package/dist/request-value-closure.js +2 -0
  419. package/dist/router/route-orchestration.d.ts +11 -16
  420. package/dist/router/route-orchestration.js +2 -12
  421. package/dist/rule-entry-list.d.ts +8 -7
  422. package/dist/rule-entry-list.js +2 -9
  423. package/dist/rules-consent.d.ts +6 -6
  424. package/dist/rules-consent.js +2 -0
  425. package/dist/run-cancel-context.d.ts +5 -5
  426. package/dist/run-local.d.ts +10 -10
  427. package/dist/run-local.js +1 -0
  428. package/dist/runs.d.ts +15 -12
  429. package/dist/runs.js +19 -4
  430. package/dist/runtime-caps-resolver.d.ts +6 -6
  431. package/dist/runtime-governance.d.ts +9 -9
  432. package/dist/sandbox-pkg-source.d.ts +9 -31
  433. package/dist/sandbox-pkg-source.js +14 -8
  434. package/dist/sealed-key.d.ts +34 -2
  435. package/dist/sealed-key.js +55 -1
  436. package/dist/security.d.ts +31 -32
  437. package/dist/security.js +12 -9
  438. package/dist/server-secret-env.d.ts +10 -10
  439. package/dist/session-children-retire.d.ts +1 -1
  440. package/dist/session-error-wire.d.ts +19 -12
  441. package/dist/session-error-wire.js +4 -1
  442. package/dist/session-incarnation.d.ts +52 -35
  443. package/dist/session-incarnation.js +23 -8
  444. package/dist/session-policy-wire.d.ts +27 -5
  445. package/dist/session-policy-wire.js +15 -1
  446. package/dist/session-records-skipped-notice.d.ts +1 -1
  447. package/dist/session-sync-kernel.d.ts +38 -11
  448. package/dist/session-sync-kernel.js +10 -0
  449. package/dist/session-sync.d.ts +49 -6
  450. package/dist/session-sync.js +52 -10
  451. package/dist/session-titler.d.ts +7 -6
  452. package/dist/session-titler.js +8 -13
  453. package/dist/session-watch.d.ts +3 -3
  454. package/dist/session-watch.js +4 -4
  455. package/dist/sighup-idle.d.ts +2 -2
  456. package/dist/spec-fields.d.ts +4 -4
  457. package/dist/sql-engine-posture.d.ts +3 -3
  458. package/dist/store-posture.d.ts +2 -2
  459. package/dist/stored-request-tool-axes-m19.d.ts +1 -1
  460. package/dist/task-a2a.d.ts +3 -1
  461. package/dist/task-a2a.js +38 -5
  462. package/dist/task-cwd.d.ts +7 -88
  463. package/dist/task-cwd.js +2 -15
  464. package/dist/task-mcp.d.ts +14 -10
  465. package/dist/task-mcp.js +39 -12
  466. package/dist/task-settings.d.ts +34 -18
  467. package/dist/task-settings.js +34 -4
  468. package/dist/task-workflow.d.ts +0 -24
  469. package/dist/task-workflow.js +2 -1
  470. package/dist/terminal.d.ts +5 -5
  471. package/dist/tighten-only-seats.d.ts +7 -6
  472. package/dist/tighten-only-seats.js +1 -1
  473. package/dist/tool-approval.d.ts +273 -228
  474. package/dist/tool-approval.js +125 -47
  475. package/dist/tool-rule-names.d.ts +7 -1
  476. package/dist/trace/core-keyset-guard.d.ts +15 -9
  477. package/dist/trace/engine-notice-wire.d.ts +5 -5
  478. package/dist/trace/engine-notice-wire.js +1 -0
  479. package/dist/trace/exit-seat.d.ts +40 -1
  480. package/dist/trace/exit-seat.js +46 -14
  481. package/dist/trace/ledger-events.d.ts +6 -4
  482. package/dist/trace/ledger-sink.d.ts +1 -1
  483. package/dist/trace/model-segment.d.ts +3 -3
  484. package/dist/trace/project.d.ts +65 -46
  485. package/dist/trace/project.js +49 -5
  486. package/dist/trace/redact.d.ts +44 -27
  487. package/dist/trace/redact.js +343 -73
  488. package/dist/trace/self-minted-wire.d.ts +39 -14
  489. package/dist/trace/self-minted-wire.js +9 -0
  490. package/dist/trace/sema-provenance.d.ts +1 -1
  491. package/dist/trace/task-notification-facets.d.ts +4 -4
  492. package/dist/trace/wire-projection-faces.d.ts +9 -3
  493. package/dist/trace/wire-projection-faces.js +7 -1
  494. package/dist/unattended-permission-mode.d.ts +5 -5
  495. package/dist/url-credential.d.ts +52 -0
  496. package/dist/url-credential.js +49 -0
  497. package/dist/url-refusal.d.ts +6 -2
  498. package/dist/url-refusal.js +8 -1
  499. package/dist/usage-analytics.d.ts +2 -2
  500. package/dist/user-input-ledger.d.ts +23 -23
  501. package/dist/web-admin-client/apply-effective.d.ts +5 -5
  502. package/dist/web-admin-client/apply-effective.js +2 -1
  503. package/dist/web-admin-client/apply-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/center-request.d.ts +2 -2
  505. package/dist/web-admin-client/facade.d.ts +5 -5
  506. package/dist/web-admin-client/facade.js +1 -1
  507. package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
  508. package/dist/web-admin-client/http-client.d.ts +4 -4
  509. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  510. package/dist/web-admin-client/pull-state.d.ts +1 -1
  511. package/dist/web-admin-client/read-face.d.ts +2 -2
  512. package/dist/web-admin-client/read-warnings.d.ts +5 -5
  513. package/dist/web-admin-client/restart-signal.d.ts +6 -6
  514. package/dist/web-admin-client/skills-mcp.d.ts +29 -4
  515. package/dist/web-admin-client/skills-mcp.js +31 -4
  516. package/dist/web-admin-client/types.d.ts +17 -10
  517. package/dist/workspace-space.d.ts +5 -3
  518. package/dist/write-protection.d.ts +2 -2
  519. package/package.json +4 -3
  520. package/scripts/drain-check-local.mjs +35 -2
  521. package/scripts/drain-check.mysql.sql +22 -2
  522. package/scripts/drain-check.pg.sql +22 -2
  523. package/skills/loop.md +1 -1
  524. package/dist/mcp-tool-faces.d.ts +0 -69
  525. package/dist/mcp-tool-faces.js +0 -104
  526. package/dist/orchestration/workflow-journal-entry.js +0 -27
@@ -1,7 +1,7 @@
1
1
  /**
2
- * S-481 —— **无 run 可读的逐台 MCP 状态面**的 server 半场(设计稿 `2026-09-19-s481-mcp-status-face-v1`)。
2
+ * [ref] —— **无 run 可读的逐台 MCP 状态面**的 server 半场(设计稿 `2026-09-19-s481-mcp-status-face-v1`)。
3
3
  *
4
- * ## 病(deploy 报案 I-1 / cli L-303)
4
+ * ## 病(deploy 报案 I-1 / cli [ref])
5
5
  * 壳的一次性命令(`sema mcp list`)与交互会话对同一台 MCP 服务器给出**相反**的答案:命令行报 Failed、
6
6
  * 会话里那台 server 的工具却能用。根因不是判定不同,而是**没有面** —— 一个从未起过 run 的会话在本服务上
7
7
  * 只有 `GET /v1/capabilities.mcp` 那一枚布尔,壳只能自己去拨号、自己造词。
@@ -33,6 +33,7 @@
33
33
  * 在 core 那边没有任何期限(core `docs/KNOWN-LIMITS.md`)—— 那一形上本面同样没有期限,补偿只有限速与缓存。
34
34
  */
35
35
  import { type McpServerSpec } from "@sema-agent/core";
36
+ import type { UrlCredentialFacts } from "../url-credential.js";
36
37
  /**
37
38
  * 本面的**拒码闭集**(设计稿 §2 的四枚)。闭集写成型,是为了让 {@link MCP_PROBE_HTTP_STATUS} 那张表
38
39
  * 「漏一枚 = 编译红」—— [ref] 的安全轴纪律:词表是闭集,未处置的成员必须是编译错误而不是运行期惊喜。
@@ -40,7 +41,7 @@ import { type McpServerSpec } from "@sema-agent/core";
40
41
  export declare const MCP_PROBE_REFUSAL_CODES: readonly ["capability.mcp_injection_required", "limit.rate_exceeded", "request.body_shape", "request.field_invalid", "state.mcp_probe_incomplete"];
41
42
  export type McpProbeRefusalCode = (typeof MCP_PROBE_REFUSAL_CODES)[number];
42
43
  /**
43
- * 🔴 **状态档取单表**(`GOVERNANCE_HTTP_STATUS` 的同族形,S-201② 的那条律):一个码在本服务上只有**一个**
44
+ * 🔴 **状态档取单表**(`GOVERNANCE_HTTP_STATUS` 的同族形,[ref]② 的那条律):一个码在本服务上只有**一个**
44
45
  * 状态,而路由层**一个字面量都不许手写**。写成 `as const satisfies` 两头都占:格是字面量型(直接当
45
46
  * `sendError` 的状态参数用,零 `?? 400` 兜底 —— 兜底就是第二份真源),`satisfies` 保住闭集门。
46
47
  */
@@ -52,7 +53,7 @@ export declare const MCP_PROBE_HTTP_STATUS: {
52
53
  readonly "state.mcp_probe_incomplete": 503;
53
54
  };
54
55
  /**
55
- * 每 principal 的固定窗限速。**刻意不挂任何无关旋钮**(S-470 的同一条教训,`DEVICE_ENROLL_RATE_POLICY`
56
+ * 每 principal 的固定窗限速。**刻意不挂任何无关旋钮**([ref] 的同一条教训,`DEVICE_ENROLL_RATE_POLICY`
56
57
  * 先例):全局 `RATE_LIMIT_RPM` 缺省是 `0` = 关断,把一条真拨号的面挂在它上面 = 出厂形不限速。
57
58
  * 12/60s 是**安全地板**,不是可调参数;窗是**每副本**的(多副本部署上有效上界 = 12 × 副本数,如实记)。
58
59
  */
@@ -157,6 +158,8 @@ export interface McpProbeRefusal {
157
158
  readonly message: string;
158
159
  /** `request.body_shape` 专用:词表外 / 本面不接线的键,全路径形(已清洗+截断+排序+封顶)。 */
159
160
  readonly unknownKeys?: readonly string[];
161
+ /** [ref]:申报的 `transport.url` 带凭据 ⇒ `field` + `reason`(与提交腿同一只回答者交回的同一组机读位,原样转述)。 */
162
+ readonly facts?: UrlCredentialFacts;
160
163
  }
161
164
  /**
162
165
  * `POST …/probe` 的体读器:闭形、逐条点名、零静默丢。成功 ⇒ 交给 core 的 `specs`(**原样**转发被读出来的
@@ -164,7 +167,7 @@ export interface McpProbeRefusal {
164
167
  *
165
168
  * ## 申报「能不能原样用」:问提交腿 fresh 门**同一只**回答者,不另判
166
169
  * 本面只判自己那一层(体是对象、顶层只受理 `mcpServers`、这个键必填);`mcpServers` 本身 —— 列表的形、上限、每条的键名与键值 —— 全部交给
167
- * `task-mcp.ts` 的 `requestMcpDeclarationRefusal`,拒(码 + 句 + `unknownKeys`)原样转述:同一份申报在两扇门上只有一个答案,零拨号之前就给。
170
+ * `task-mcp.ts` 的 `requestMcpDeclarationRefusal`,拒(码 + 句 + `unknownKeys` + url 带凭据那一形的 `field` / `reason`)原样转述:同一份申报在两扇门上只有一个答案,零拨号之前就给。
168
171
  * 回答者受理的申报由**同一只**读器(`validateRequestMcp`)交回,读器的产物就是申报本身(只差判官自己的合法归一),经 `toCoreMcpServerSpec`
169
172
  * 得到的就是一条任务提交会交给引擎的那一份 —— 本面拨的正是它。读器只在回答者受理之后才跑,所以它对重放存量 body 才有的降级留痕
170
173
  * (`source` 写坏的 F 类丢弃)不会在一次被拒的探测上虚记。
@@ -237,7 +240,7 @@ export interface McpProbeLocal {
237
240
  /** 带行为的东西 ⇒ `create*`(工厂命名律:`build*` 出纯数据,`create*` 出活对象)。 */
238
241
  export declare function createMcpProbeLocal(): McpProbeLocal;
239
242
  /**
240
- * S-1734 —— 一行的**本面独有**两键:`toolNames` / `toolNamesTruncated`。两条口走同一只 {@link createMcpProbeWalk},
243
+ * [ref] —— 一行的**本面独有**两键:`toolNames` / `toolNamesTruncated`。两条口走同一只 {@link createMcpProbeWalk},
241
244
  * 所以这是它们**唯一**的铸点。
242
245
  *
243
246
  * ## 来源只有一个
@@ -308,7 +311,7 @@ export declare function buildMcpInjectionRefusal(): McpProbeRefusal;
308
311
  *
309
312
  * ⚠️ **如实交代一条覆盖边界**:全仓的 `api-error-text-freeze` 门锚的是 `sendError(res, <字面三位数>,
310
313
  * "<字面码>", …)`,而本面刻意**不在调用点写字面状态**(状态从 {@link MCP_PROBE_HTTP_STATUS} 单表取,
311
- * S-201② 那条律),于是这四句结构上够不着那道门。⇒ 它们由 `test/mcp-status-face-s481.test.ts` 的
314
+ * [ref]② 那条律),于是这四句结构上够不着那道门。⇒ 它们由 `test/mcp-status-face-s481.test.ts` 的
312
315
  * 「四句逐字节」那一格钉住(改一个字当场红)。把那道全局门扩到「常量表出站」形是另一台车。
313
316
  */
314
317
  export declare function buildMcpProbeRateRefusal(): McpProbeRefusal;
@@ -1,7 +1,7 @@
1
1
  import { probeMcpServers } from "@sema-agent/core";
2
2
  import { createHash } from "node:crypto";
3
3
  import { createFixedWindowRateLimiter } from "../device-enrollment.js";
4
- import { canonicalJson } from "../canonical-json.js";
4
+ import { canonicalJsonStringify } from "@sema-agent/core";
5
5
  import { keyClosureClause, scanKeyClosure } from "../request-key-closure.js";
6
6
  import { requestMcpDeclarationRefusal, validateRequestMcp } from "../task-mcp.js";
7
7
  import { specWithholdsMcpAssertionHeader, toCoreMcpServerSpec } from "../mcp-assertion-header.js";
@@ -86,7 +86,7 @@ export function buildMcpProbeIdentity(principal) {
86
86
  return principal !== undefined && principal.length > 0 ? principal : "local";
87
87
  }
88
88
  export function buildMcpProbeCacheKey(principal, specs) {
89
- return `${buildMcpProbeIdentity(principal)}::${createHash("sha256").update(canonicalJson(specs), "utf8").digest("hex")}`;
89
+ return `${buildMcpProbeIdentity(principal)}::${createHash("sha256").update(canonicalJsonStringify(specs), "utf8").digest("hex")}`;
90
90
  }
91
91
  export function buildMcpProbeRateKey(principal) {
92
92
  return `mcp-probe:${buildMcpProbeIdentity(principal)}`;
@@ -21,7 +21,7 @@
21
21
  * silently). But the TENANT judgment INVERTS: an ssh peer is ONE persistent real machine shared by every
22
22
  * task (sshExecutionEnvFactory ignores ctx — same host + same mountPath for all tasks; destroy() only
23
23
  * disconnects, files persist; capabilities.isolation:false). "Scoped read = tenant boundary" does NOT
24
- * hold there, so the ssh lane is SINGLE-USER ONLY (same gate as host) — see `sandboxSendLaneEnabled`.
24
+ * hold there, so the ssh lane is SINGLE-USER ONLY (same gate as host) — the deployment-shape row `sandboxSendUserFile`.
25
25
  *
26
26
  * The presigned PUT URL is a capability secret: it never enters model context (the tool returns delivery
27
27
  * metadata only) and is REDACTED from every error surfaced from here (curl stderr may echo the URL).
@@ -74,23 +74,6 @@ export declare class TaskEnvRegistry {
74
74
  * here forever; the bounded-size backstop covers any remaining no-destroy crash path. */
75
75
  wrapFactory(factory: ExecutionEnvFactory): ExecutionEnvFactory;
76
76
  }
77
- /**
78
- * Which REMOTE_EXEC lanes may register the sandbox-send TaskEnvRegistry (and thus mount the sandbox-lane
79
- * SendUserFile source), under which tenancy gate. The judgment per lane (2026-07-14 ssh backfill review):
80
- *
81
- * - e2b / k8s: one task = one disposable sandbox; the sandbox filesystem IS the tenant's task workspace,
82
- * so a sandbox-scoped read is tenant-scoped by construction → open to any tenant.
83
- * - ssh: the peer is ONE persistent real machine SHARED across tasks (factory ignores ctx: every task
84
- * gets the same host+mountPath; destroy=disconnect only, files persist). Tenant A's task can read the
85
- * residue of tenant B's task → the isolation premise FAILS. Multi-tenant here would be an
86
- * arbitrary-host-path-read → public-URL exfil face, so the lane opens ONLY single-user
87
- * (`requirePrincipal !== true`), the exact gate the host lane uses. NOT a lane to "fix later with a
88
- * per-task workspace": tasks legitimately operate outside any workspace on a real host ([ref] —
89
- * batch deployment), so per-task dirs would not restore the boundary anyway.
90
- * - adb / local-docker / host / unset: no registry (host+unset use the local-fs source in main.ts;
91
- * adb/local-docker remain a follow-on).
92
- */
93
- export declare function sandboxSendLaneEnabled(provider: string | undefined, requirePrincipal: boolean): boolean;
94
77
  /** Strip the capability URL (and any SigV4 signature) from text before it reaches an error/log — including
95
78
  * the percent-encoded forms an adapter may echo (the k8s exec transport carries the command in a request
96
79
  * URI, so an error can quote the URL re-encoded; codex review MED). */
@@ -79,13 +79,6 @@ export class TaskEnvRegistry {
79
79
  };
80
80
  }
81
81
  }
82
- export function sandboxSendLaneEnabled(provider, requirePrincipal) {
83
- if (provider === "e2b" || provider === "k8s")
84
- return true;
85
- if (provider === "ssh")
86
- return requirePrincipal !== true;
87
- return false;
88
- }
89
82
  export function redactPutUrl(text, url) {
90
83
  return text
91
84
  .split(url)
@@ -2,7 +2,7 @@ import { type WebFetchConfig, type BackgroundAgentStore, type CheckpointStore, t
2
2
  import type { Logger } from "../observability/logger.js";
3
3
  import { type SubagentExtraToolSet } from "./builtin-tools.js";
4
4
  import { type RepoReadClient } from "./repo-tools.js";
5
- import { type LoadedSkill } from "./skills.js";
5
+ import { type LoadedSkill, type ScenarioSkillEntry } from "./skills.js";
6
6
  import { type ScenarioHands } from "./hands-lane.js";
7
7
  import type { DelegationRootWitness } from "../delegated-session-owner.js";
8
8
  /**
@@ -28,7 +28,7 @@ export interface ScenarioBundle {
28
28
  */
29
29
  hands: ScenarioHands;
30
30
  /**
31
- * S-1376:本场景从 roster 里**真卸载**的工具名(`TaskSpec.excludeTools`:per-scenario 的 roster 移除,schema 不进 `tools[]`;不是策略 deny)。缺席 = 不卸。
31
+ * [ref]:本场景从 roster 里**真卸载**的工具名(`TaskSpec.excludeTools`:per-scenario 的 roster 移除,schema 不进 `tools[]`;不是策略 deny)。缺席 = 不卸。
32
32
  * 经 {@link buildExcludeToolsSeat} 与调用方自己的 `excludeTools` 取并后写进 `TaskSpec`(HTTP 腿与 run-local 腿同一只写点)—— 场景只能多卸,调用方也只能多卸。
33
33
  * 与 `hands` 正交:`hands: "none"` 是整只手不挂(scan / code-review),本键是挂手之后卸掉其中一部分(cowork 卸编码类工具、留文件读)。
34
34
  */
@@ -83,7 +83,7 @@ export interface ScenarioContext {
83
83
  */
84
84
  sessionId?: string;
85
85
  /**
86
- * S-1770 / S-1808:**委派树根的见证**(停驻挂点的属主来源)—— 根会话 id + 调用方判断那一刻读到的根行住客(`delegated-session-owner.ts` 的 `DelegationRootWitness`)。
86
+ * [ref] / [ref]:**委派树根的见证**(停驻挂点的属主来源)—— 根会话 id + 调用方判断那一刻读到的根行住客(`delegated-session-owner.ts` 的 `DelegationRootWitness`)。
87
87
  * 由**每一个**接了停驻挂点的取用方显式交出(一条读法,没有回落):请求腿 = 本请求经鉴权解析的会话与受理时那一读(`boot/resolve-spec.ts`);`/decide` 赎回面 = 行上的
88
88
  * `rootSessionId` 与赎回腿 claim 前后两读的那一位住客(`parked-revive-surface.ts`,交不交座都交)。它**只**喂停驻挂点,不挂任何会话级设施(那是 {@link sessionId} 的事,
89
89
  * 判据是「这只 bundle 是不是在那只会话上取用的」,与属主来源是两个独立判据)。缺席 = 没有根可交(boot 期探针、run-local、行上没有根)⇒ 律给哨兵。
@@ -104,7 +104,7 @@ export interface ScenarioDeps {
104
104
  * could exfil via an arbitrary public URL; the SSRF floor only blocks internal). Single-user TOC keeps WebFetch. */
105
105
  requirePrincipal?: boolean;
106
106
  /**
107
- * S-1652:这台部署的执行车道**有没有手**(`laneWiresExecutionEnv`;`REMOTE_EXEC` 未设 = `in-process` = 没有)。场景详情读面据它与场景自己的 `hands` 表态一起答
107
+ * [ref]:这台部署的执行车道**有没有手**(`laneWiresExecutionEnv`;`REMOTE_EXEC` 未设 = `in-process` = 没有)。场景详情读面据它与场景自己的 `hands` 表态一起答
108
108
  * 「这个场景的 run 有没有工作区」({@link runHasWorkspace}),进而给出附件可受理供给集。**缺席按没有手读**(宁少说不多说:不广告一个会撞 400 的 `path`)。
109
109
  */
110
110
  handsLane?: boolean;
@@ -123,7 +123,7 @@ export interface ScenarioDeps {
123
123
  * execute-time late-bound via ctx.taskId → TaskEnvRegistry, so ONE spec serves every spawn) cannot ride the
124
124
  * ASSEMBLY-time static `subagent.tools` pool; core evaluates the factory at each spawn and merges its product into the
125
125
  * pool, then it goes through core's `resolveToolSubset` whitelist like any other tool (agent-def allowTools/denyTools
126
- * still govern — no extra gate needed on our side). A SET, not a bare factory (core 7.46.0 #1432): its `tools` are both
126
+ * still govern — no extra gate needed on our side). A SET, not a bare factory (core 7.46.0 [ref]): its `tools` are both
127
127
  * what a spawn can be handed and the roster the delegation tool declares (`extraToolNames`), so the factory cannot hand
128
128
  * out a tool the roster does not name. Absent ⇒ the delegation tool injects `Now` alone.
129
129
  */
@@ -152,7 +152,7 @@ export interface ScenarioDeps {
152
152
  */
153
153
  checkpointStore?: CheckpointStore;
154
154
  /**
155
- * S-1770:比 core 挂点多一个参数 —— `root` = **委派树根的见证,由取用这只 bundle 的调用方交出**({@link ScenarioContext.delegationRoot};缺席 = 没有根可交)。
155
+ * [ref]:比 core 挂点多一个参数 —— `root` = **委派树根的见证,由取用这只 bundle 的调用方交出**({@link ScenarioContext.delegationRoot};缺席 = 没有根可交)。
156
156
  * core 的挂点只给子代 id,停驻写下 / 定夺的宿主行属主却要按委派继承律取委派树根的属主;场景工厂把见证绑进交给 core 的那只闭包,同一棵树里任何深度的后台子代
157
157
  * 停驻都经它(子代沿用父的委派工具实例)。
158
158
  */
@@ -217,12 +217,18 @@ export interface ScenarioDetail {
217
217
  /** 机读原因键;仅 `available:false` 时在场(缺席=没有理由)。消费方按键分支,禁匹配英文文案。 */
218
218
  unavailableReason?: ScenarioUnavailableReason;
219
219
  /**
220
- * S-1652:**这个场景在本部署上受理的附件供给**(顶层能力位 `userAttachments.supplies` 的子集,保持席位序;键恒在场,不是 `null`)。
220
+ * [ref]:**这个场景在本部署上受理的附件供给**(顶层能力位 `userAttachments.supplies` 的子集,保持席位序;键恒在场,不是 `null`)。
221
221
  * 顶层能力位说的是引擎席位**能承载**的三种供给(常量);`path` 读的是这一 run 的工作区,只有「场景挂手 ∧ 部署的执行车道有手」的 run 才有
222
222
  * (判官 {@link runHasWorkspace}),其余整条 `path` 条目由引擎 prepare 拒 `config.user_attachment_invalid` —— 宿主发之前读这一格,不靠撞 400。
223
223
  * `content_text` / `content_image` 与工作区无关,恒在。
224
224
  */
225
225
  attachmentSupplies: UserAttachmentSupplyWord[];
226
+ /**
227
+ * [ref]:**这个场景交进每一个 run 的部署技能**(本部署技能目录 + 配置源交来的;不含请求体自带的 `skills`)—— 名字 / 描述 / 来处,不带正文。
228
+ * 与工厂交进 `TaskSpec` 的那一份是**同一只过滤**(技能范围 + `skills.ts` 的 `skillsInScope`)的两个投影:同一组、同一个序。名字就是 `userInvokedSkills` 点名用的串。
229
+ * 键恒在场;没有技能 ⇒ `[]`。
230
+ */
231
+ skills: ScenarioSkillEntry[];
226
232
  }
227
233
  /** 引擎附件席位的供给词(`USER_ATTACHMENT_SEAT.supplies` 的成员;取型,不手抄)。 */
228
234
  export type UserAttachmentSupplyWord = (typeof USER_ATTACHMENT_SEAT)["supplies"][number];
@@ -249,14 +255,26 @@ export declare const BUILTIN_SCENARIO_HANDS: {
249
255
  readonly scan: "none";
250
256
  readonly cowork: "full";
251
257
  };
258
+ /**
259
+ * [ref]:内建场景的**技能范围**(技能 `scenarios` 标签按哪个名字匹配)—— **全仓唯一声明处**:各场景工厂交进 `TaskSpec` 的技能与场景卡上的技能清单都按这张表取范围,
260
+ * 再过同一只过滤(`skills.ts` 的 `skillsInScope`),两边因此恒为同一组技能。按 {@link BuiltinScenarioName} 键控 ⇒ 加 / 删一个内建场景而这里没跟 = 编译红。
261
+ * `code` 的范围是 `default`:它与 default 共用一只工厂(工具 / 技能面恒等由构造保证),打了 `scenarios: code` 的技能不进 code 的 run。center 场景的范围是它自己的名字。
262
+ */
263
+ export declare const BUILTIN_SCENARIO_SKILL_SCOPE: {
264
+ readonly code: "default";
265
+ readonly default: "default";
266
+ readonly "code-review": "code-review";
267
+ readonly scan: "scan";
268
+ readonly cowork: "cowork";
269
+ };
252
270
  /**
253
271
  * `branded` = 这台部署是不是品牌部署 —— 部署座挂品牌行读的同一只判官(`brand-identity.ts` `isBrandedDeployment`)交进来;没有默认值:每个调用点说出这件事实。
254
272
  * 品牌部署上,品牌行 `when.binding` 那张表里的场景(`BRAND_IDENTITY_SCENARIOS`)的 `promptSummary` 点名 Sema 产品身份 —— 读面说的就是模型收到的。
255
273
  */
256
- export declare function builtinScenarioDetails(scenarios: Record<string, Scenario>, deps: Pick<ScenarioDeps, "repoClient" | "handsLane">, branded: boolean): Record<string, ScenarioDetail>;
274
+ export declare function builtinScenarioDetails(scenarios: Record<string, Scenario>, deps: Pick<ScenarioDeps, "repoClient" | "handsLane" | "skills">, branded: boolean): Record<string, ScenarioDetail>;
257
275
  /** center 条目详情(有效性判定与 centerScenarios 完全同款:无效条目既不进 overlay 也不进详情——
258
276
  * 保证约定①「详情显示的来源=运行实际用的定义」永不错位)。 */
259
- export declare function centerScenarioDetails(specs: CenterScenarioSpec[] | undefined, builtinNames: string[], deps: Pick<ScenarioDeps, "repoClient" | "handsLane">): Record<string, ScenarioDetail>;
277
+ export declare function centerScenarioDetails(specs: CenterScenarioSpec[] | undefined, builtinNames: string[], deps: Pick<ScenarioDeps, "repoClient" | "handsLane" | "skills">): Record<string, ScenarioDetail>;
260
278
  export interface CenterScenarioSpec {
261
279
  name: string;
262
280
  toolset: string;
@@ -300,7 +318,7 @@ export declare function centerScenarios(deps: ScenarioDeps, specs: CenterScenari
300
318
  * Personalization seam: merge the caller's own skills AFTER the scenario's, with
301
319
  * SCENARIO-WINS on a name clash — the scenario / center skills own the name (they are the deployment's baseline
302
320
  * wording, not an enforcement face: permissions / write gates / hooks do not ride on skills, and a caller may
303
- * unload the whole set with `disableSkills`, S-946); user content never shadows them. Duplicate names within the user list keep the first. Clashes are logged for audit
321
+ * unload the whole set with `disableSkills`, [ref]); user content never shadows them. Duplicate names within the user list keep the first. Clashes are logged for audit
304
322
  * (silent drops would make "my skill didn't fire" undebuggable). Input is already shape/size-validated
305
323
  * by the HTTP layer (validateUserSkills); this stays pure merge policy.
306
324
  */
@@ -4,7 +4,7 @@ import { createSubagentExtraTools, extraToolsErrorFields, nowTool } from "./buil
4
4
  import { parseRepo, repoToolsFor } from "./repo-tools.js";
5
5
  import { NOW_TOOL_NAME, REPO_PULL_DIFF_TOOL_NAME, REPO_READ_FILE_TOOL_NAME, REPO_TREE_TOOL_NAME } from "./host-tool-names.js";
6
6
  import { createWebSearchBackend, judgeRequestWebSearch } from "../plugins/web-search.js";
7
- import { skillsForScenario } from "./skills.js";
7
+ import { scenarioSkillEntries, skillsForScenario } from "./skills.js";
8
8
  import { OFFICE_EXCLUDED_TOOL_NAMES, runHasWorkspace } from "./hands-lane.js";
9
9
  import { BRAND_IDENTITY_SCENARIOS } from "./brand-identity.js";
10
10
  export function buildPromptSeats(scenarioName, prompt, callerSystemPrompt) {
@@ -69,7 +69,7 @@ export function buildScenarios(deps) {
69
69
  }).filter((t) => t.name !== WEB_FETCH_TOOL_NAME || deps.requirePrincipal !== true),
70
70
  ],
71
71
  hands: BUILTIN_SCENARIO_HANDS.default,
72
- skills: skillsForScenario(deps.skills, "default"),
72
+ skills: skillsForScenario(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE.default),
73
73
  };
74
74
  };
75
75
  return {
@@ -77,6 +77,7 @@ export function buildScenarios(deps) {
77
77
  code: (req, principal, ctx) => ({
78
78
  ...defaultScenario(req, principal, ctx),
79
79
  hands: BUILTIN_SCENARIO_HANDS.code,
80
+ skills: skillsForScenario(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE.code),
80
81
  prompt: { role: "code" },
81
82
  }),
82
83
  "code-review": (req) => codeReview(deps, req),
@@ -88,13 +89,13 @@ export function buildScenarios(deps) {
88
89
  return {
89
90
  tools: [...repoToolsFor(repoClient, parseRepo(req.repo)), nowTool()],
90
91
  hands: BUILTIN_SCENARIO_HANDS.scan,
91
- skills: skillsForScenario(deps.skills, "scan"),
92
+ skills: skillsForScenario(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE.scan),
92
93
  };
93
94
  },
94
95
  cowork: (req, principal, ctx) => ({
95
96
  ...defaultScenario(req, principal, ctx),
96
97
  hands: BUILTIN_SCENARIO_HANDS.cowork,
97
- skills: skillsForScenario(deps.skills, "cowork"),
98
+ skills: skillsForScenario(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE.cowork),
98
99
  excludeTools: OFFICE_EXCLUDED_TOOL_NAMES,
99
100
  prompt: { role: "cowork" },
100
101
  }),
@@ -124,6 +125,13 @@ export const BUILTIN_SCENARIO_HANDS = {
124
125
  scan: "none",
125
126
  cowork: "full",
126
127
  };
128
+ export const BUILTIN_SCENARIO_SKILL_SCOPE = {
129
+ code: "default",
130
+ default: "default",
131
+ "code-review": "code-review",
132
+ scan: "scan",
133
+ cowork: "cowork",
134
+ };
127
135
  export function builtinScenarioDetails(scenarios, deps, branded) {
128
136
  const probe = (name, req, principal, fallback) => {
129
137
  try {
@@ -138,6 +146,7 @@ export function builtinScenarioDetails(scenarios, deps, branded) {
138
146
  name, source: "builtin", builtin: true, summary, toolset, tools, promptSummary, enabled: true,
139
147
  ...availabilityFields(deps, toolset),
140
148
  attachmentSupplies: attachmentSuppliesFor(BUILTIN_SCENARIO_HANDS[name], deps.handsLane === true),
149
+ skills: scenarioSkillEntries(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE[name]),
141
150
  });
142
151
  const brandedScenario = (name) => branded && BRAND_IDENTITY_SCENARIOS.includes(name);
143
152
  const details = {
@@ -170,6 +179,7 @@ export function centerScenarioDetails(specs, builtinNames, deps) {
170
179
  enabled: true,
171
180
  ...availabilityFields(deps, spec.toolset),
172
181
  attachmentSupplies: attachmentSuppliesFor(toolset.hands, deps.handsLane === true),
182
+ skills: scenarioSkillEntries(deps.skills, spec.name),
173
183
  };
174
184
  }
175
185
  return out;
@@ -244,7 +254,7 @@ function codeReview(deps, req) {
244
254
  }
245
255
  const coords = parseRepo(req.repo);
246
256
  const repoTools = repoToolsFor(repoClient, coords);
247
- const skills = skillsForScenario(deps.skills, "code-review");
257
+ const skills = skillsForScenario(deps.skills, BUILTIN_SCENARIO_SKILL_SCOPE["code-review"]);
248
258
  const hands = BUILTIN_SCENARIO_HANDS["code-review"];
249
259
  return { tools: [...repoTools, nowTool()], hands, skills, prompt: { roleText: REVIEWER_ROLE_TEXT } };
250
260
  }
@@ -53,7 +53,7 @@ export declare function sendUserFileTool(deps: {
53
53
  * posture (their denyTools sets predate this tool, so core's resolveToolSubset would let it through). `ctx.agentType`
54
54
  * carries the spawned definition's name (core subagent.js); membership in core's builtin catalog ⇒ inject nothing.
55
55
  *
56
- * 🔴 S-1058(7.116.0):修前这里还有一道 **F1 部署策略预判** —— 部署审批面(`APPROVAL_DENY` / `REQUIRE` / `NEVER_AUTO`)点名 SendUserFile 就一只都
56
+ * 🔴 [ref](7.116.0):修前这里还有一道 **F1 部署策略预判** —— 部署审批面(`APPROVAL_DENY` / `REQUIRE` / `NEVER_AUTO`)点名 SendUserFile 就一只都
57
57
  * 不注入,前提是「subRunner 不带策略、core 的子代不继承父的 toolPolicy」(core 1.287 时的事实)。core 自 7.40.1 起顶层 run 解析后的调用方策略
58
58
  * (`spec.toolPolicy ?? deps.toolPolicy`)与它冻结的审批席经继承链(`InheritedGate.parentConstraints`)判子代的注入工具:deny ⇒ 零执行;ask ⇒ 顶层
59
59
  * 审批席被问一次;无审批席 ⇒ 拒(core 7.41.0 钉)。本仓在真实装配上亲跑十格(spec / deps 两槽 × deny / ask 允 / ask 拒 / 无审批席 / 耐久车道无活席,
@@ -36,8 +36,16 @@ export interface LoadedSkill {
36
36
  spec: SkillSpec;
37
37
  /** Scenarios this skill applies to; empty = global (every scenario). */
38
38
  scenarios: string[];
39
+ /**
40
+ * [ref] —— 这只技能的**来处**,由铸它的那条装载腿写下(唯一写点;之后谁都不改写,只投影):`factory` = 本部署的技能目录(`SKILLS_DIR`,{@link loadDeploymentSkills});
41
+ * `center` = 本部署的配置源交来的(中心 / 本地 `config.d` 的技能清单 `applySkillsManifest`,或配置声明的插件 `applyCenterPlugins`)。配置源按名盖掉出厂同名技能 ⇒ 盖上来的那只是 `center`。
42
+ * 场景卡的技能清单原样投这一位(`GET /v1/capabilities/scenarios/:name` 的 `skills[].source`)。
43
+ */
44
+ source: SkillSource;
39
45
  }
40
- /** 加载 lane 的信任级。缺席(受控 lane:烤制进镜像的 skills 目录)= 维持既有语义,symlink 照跟
46
+ /** 技能来处的闭集(见 {@link LoadedSkill.source})。 */
47
+ export type SkillSource = "factory" | "center";
48
+ /** 加载 lane 的事实:来处(`source`,必填)与信任级。`confineTo` 缺席(受控 lane:烤制进镜像的 skills 目录)= 维持既有语义,symlink 照跟
41
49
  * ——那个便利是有意的(`foo.md -> 共享文件`)。`confineTo` 在场(**不可信 lane**:第三方 git checkout,
42
50
  * 见 center-plugins 的 plugin 装载)= 每个被读条目 realpath 后必须仍在该根之内,逃逸即抛。
43
51
  * 🔴 为什么信任级必须是**参数**而不是注释里的假设:本函数的头注原写着「skills dir 全受控」,而
@@ -45,12 +53,13 @@ export interface LoadedSkill {
45
53
  * 于是 checkout 里某个 skill 条目(`任意 .md -> /宿主/任意文件`)会被读进 spec.files 进入提示词。resolvePluginSkillsRoot
46
54
  * 只 realpath 守了 skills **根**,根下逐条目没守。 */
47
55
  export interface LoadSkillsOptions {
56
+ /** [ref]:这条装载腿铸出的技能的来处({@link LoadedSkill.source})—— **必填**:装载器自己判断不了它读的是哪一种目录,由调用的那条腿说出这件事实。 */
57
+ source: SkillSource;
48
58
  /** 不可信 lane 的约束根(通常=clone root)。缺席=受控 lane,不做逐条目约束。 */
49
59
  confineTo?: string;
50
60
  /**
51
- * S-377 —— 「**工具跑的那台机器**的盘就是本进程这台盘吗」。真 ⇒ 目录形态技能带上自己的目录
52
- * (`SkillSpec.baseDir`);假/缺席 ⇒ **不带**。判据的单一属主 = `task-cwd.ts` 的
53
- * {@link import("../task-cwd.js").toolsRunOnThisHost}(调用方按它算,别在这里第二次判 lane)。
61
+ * [ref] —— 「**工具跑的那台机器**的盘就是本进程这台盘吗」。真 ⇒ 目录形态技能带上自己的目录
62
+ * (`SkillSpec.baseDir`);假/缺席 ⇒ **不带**。判据的单一属主 = 部署形表行 `toolsOnThisHost`(`deployment-shape.ts`;调用方按它算,别在这里第二次判 lane)。
54
63
  *
55
64
  * 🔴 **缺席 = 不带**,是**故意的 fail-closed 方向**:带了一条工具那边不存在的路径,伤是「模型按它去
56
65
  * 读、扑空,顺带看到本机目录布局」;不带的伤只是少一条线索(附件本来就随 invoke 全文内联投递,
@@ -64,13 +73,13 @@ export interface LoadSkillsOptions {
64
73
  * `/a/root` 前缀。目标不存在 ⇒ realpath 抛 ENOENT,同样是拒绝(悬空链接不该被读)。
65
74
  * `label` = 错误文本里的对象名(center-plugins 用它约束 manifest 本体,报错不该指成 skill entry)。 */
66
75
  export declare function assertConfined(p: string, rootReal: string, label?: string): void;
67
- export declare function loadSkills(dir: string, opts?: LoadSkillsOptions): LoadedSkill[];
76
+ export declare function loadSkills(dir: string, opts: LoadSkillsOptions): LoadedSkill[];
68
77
  /**
69
- * S-602 —— **出厂技能**的装载腿(`SKILLS_DIR` 自扫)。stage-07 与 run-local 两处装配点**都调这一只**:改前两处
70
- * 各写一遍 `loadSkills(config.skillsDir, { toolsShareThisFilesystem: toolsRunOnThisHost(config) })`,测试只能
78
+ * [ref] —— **出厂技能**的装载腿(`SKILLS_DIR` 自扫)。stage-07 与 run-local 两处装配点**都调这一只**:改前两处
79
+ * 各写一遍 `loadSkills(config.skillsDir, { toolsShareThisFilesystem: <车道判据>(config) })`,测试只能
71
80
  * 直传布尔去证 `loadSkills`(`baked-skills.test.ts`),证不到「config → 装配腿 → baseDir」这一段;收成一只
72
- * 之后,联合格从 config 走到 `baseDir`(`test/capabilities-http.test.ts` S-602 段)证的就是两处装配点本人。
73
- * 判据属主不变:`task-cwd.ts` 的 {@link toolsRunOnThisHost}(S-602 起 in-process ⇒ 假 ⇒ 目录形技能不带 `baseDir`)。
81
+ * 之后,联合格从 config 走到 `baseDir`(`test/capabilities-http.test.ts` [ref] 段)证的就是两处装配点本人。
82
+ * 判据属主:部署形表行 `toolsOnThisHost`([ref];[ref] 起 in-process ⇒ 假 ⇒ 目录形技能不带 `baseDir`)。
74
83
  */
75
84
  export declare function loadDeploymentSkills(config: {
76
85
  readonly skillsDir: string;
@@ -78,9 +87,19 @@ export declare function loadDeploymentSkills(config: {
78
87
  readonly provider: RemoteExecProvider;
79
88
  } | undefined;
80
89
  }, logger?: Logger): LoadedSkill[];
81
- /** Skills applicable to a scenario: those tagged with it, plus untagged (global) ones.
82
- * [ref]:alias 窗撤销,单键查询——退役旧名标签不再命中(迁移面在 7.44 发车帖/MIGRATION 记载)。 */
83
- export declare function skillsForScenario(loaded: LoadedSkill[], scenario: string): SkillSpec[];
90
+ /** 一个技能范围交进 `TaskSpec` 的技能(场景工厂的 `skills`)。范围从哪来见 `scenarios.ts` 的 `BUILTIN_SCENARIO_SKILL_SCOPE`(center 场景 = 它自己的名字)。 */
91
+ export declare function skillsForScenario(loaded: readonly LoadedSkill[], scope: string): SkillSpec[];
92
+ /**
93
+ * [ref] —— 场景卡技能清单的一条(`GET /v1/capabilities/scenarios/:name` 的 `skills[]`):名字 / 描述 / 来处,**不带正文**,也不带技能上的两只工具清单
94
+ * (`allowedTools` / `disallowedTools`)。名字就是提交体 `userInvokedSkills` 点名时用的那个串。
95
+ */
96
+ export interface ScenarioSkillEntry {
97
+ readonly name: string;
98
+ readonly description: string;
99
+ readonly source: SkillSource;
100
+ }
101
+ /** 一个技能范围的卡上清单 —— 与 {@link skillsForScenario} 同一只过滤、同一个序,只是投影不同。 */
102
+ export declare function scenarioSkillEntries(loaded: readonly LoadedSkill[], scope: string): ScenarioSkillEntry[];
84
103
  /** {@link parseFrontmatter} 的三种读数(闭集):`absent` = 第一行不是围栏,没有 frontmatter(正当的全局技能)· `block` = 围栏收好了的块 · `unclosed` = 第一行是围栏而块没收好(读不了 —— 调用方拒载)。 */
85
104
  export type FrontmatterRead = {
86
105
  readonly kind: "absent";
@@ -1,6 +1,6 @@
1
1
  import { readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
2
2
  import { join, resolve, sep } from "node:path";
3
- import { toolsRunOnThisHost } from "../task-cwd.js";
3
+ import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
4
4
  import { createLogger } from "../observability/logger.js";
5
5
  export function assertConfined(p, rootReal, label = "skill entry") {
6
6
  let real;
@@ -15,7 +15,7 @@ export function assertConfined(p, rootReal, label = "skill entry") {
15
15
  }
16
16
  }
17
17
  export function loadSkills(dir, opts) {
18
- const logger = opts?.logger ?? createLogger("warn");
18
+ const logger = opts.logger ?? createLogger("warn");
19
19
  let entries;
20
20
  try {
21
21
  entries = readdirSync(dir, { withFileTypes: true });
@@ -25,15 +25,15 @@ export function loadSkills(dir, opts) {
25
25
  }
26
26
  const out = [];
27
27
  const seen = new Map();
28
- const push = (skill, source) => {
28
+ const push = (skill, file) => {
29
29
  const prior = seen.get(skill.spec.name);
30
30
  if (prior !== undefined) {
31
- throw new Error(`duplicate skill name "${skill.spec.name}": ${prior} vs ${source}`);
31
+ throw new Error(`duplicate skill name "${skill.spec.name}": ${prior} vs ${file}`);
32
32
  }
33
- seen.set(skill.spec.name, source);
33
+ seen.set(skill.spec.name, file);
34
34
  out.push(skill);
35
35
  };
36
- const confineRoot = opts?.confineTo !== undefined ? realpathSync(opts.confineTo) : undefined;
36
+ const confineRoot = opts.confineTo !== undefined ? realpathSync(opts.confineTo) : undefined;
37
37
  const isFileLike = (entry, p) => entry.isFile() || (entry.isSymbolicLink() && statSync(p).isFile());
38
38
  const isDirLike = (entry, p) => entry.isDirectory() || (entry.isSymbolicLink() && statSync(p).isDirectory());
39
39
  for (const entry of entries.slice().sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))) {
@@ -43,10 +43,10 @@ export function loadSkills(dir, opts) {
43
43
  if (confineRoot !== undefined)
44
44
  assertConfined(join(dir, entry.name), confineRoot);
45
45
  const raw = readFileSync(join(dir, entry.name), "utf8");
46
- const source = join(dir, entry.name);
47
- const parsed = parseSkill(raw, entry.name.replace(/\.md$/, ""), source, logger);
46
+ const file = join(dir, entry.name);
47
+ const parsed = parseSkill(raw, entry.name.replace(/\.md$/, ""), file, opts.source, logger);
48
48
  if (parsed !== undefined)
49
- push(parsed, source);
49
+ push(parsed, file);
50
50
  }
51
51
  else if (isDirLike(entry, join(dir, entry.name))) {
52
52
  const skillDir = join(dir, entry.name);
@@ -61,13 +61,13 @@ export function loadSkills(dir, opts) {
61
61
  }
62
62
  if (confineRoot !== undefined)
63
63
  assertConfined(join(skillDir, "SKILL.md"), confineRoot);
64
- const skill = parseSkill(raw, entry.name, join(skillDir, "SKILL.md"), logger);
64
+ const skill = parseSkill(raw, entry.name, join(skillDir, "SKILL.md"), opts.source, logger);
65
65
  if (skill === undefined)
66
66
  continue;
67
67
  const files = collectAttachments(skillDir, "", confineRoot);
68
68
  if (files.length > 0)
69
69
  skill.spec.files = files;
70
- if (opts?.toolsShareThisFilesystem === true)
70
+ if (opts.toolsShareThisFilesystem === true)
71
71
  skill.spec.baseDir = resolve(skillDir);
72
72
  push(skill, join(skillDir, "SKILL.md"));
73
73
  }
@@ -75,7 +75,7 @@ export function loadSkills(dir, opts) {
75
75
  return out;
76
76
  }
77
77
  export function loadDeploymentSkills(config, logger) {
78
- return loadSkills(config.skillsDir, { toolsShareThisFilesystem: toolsRunOnThisHost(config), ...(logger !== undefined ? { logger } : {}) });
78
+ return loadSkills(config.skillsDir, { source: "factory", toolsShareThisFilesystem: DEPLOYMENT_SHAPE_PREDICATES.toolsOnThisHost.holds(config), ...(logger !== undefined ? { logger } : {}) });
79
79
  }
80
80
  function collectAttachments(skillDir, rel, confineRoot) {
81
81
  const files = [];
@@ -100,12 +100,12 @@ function collectAttachments(skillDir, rel, confineRoot) {
100
100
  }
101
101
  return files;
102
102
  }
103
- function parseSkill(raw, fallbackName, source, logger) {
103
+ function parseSkill(raw, fallbackName, file, origin, logger) {
104
104
  const fm = parseFrontmatter(raw);
105
105
  if (fm.kind === "unclosed") {
106
106
  logger.warn("skill_refused", {
107
107
  skill: fallbackName,
108
- source,
108
+ source: file,
109
109
  reason: "frontmatter_unclosed",
110
110
  note: "the file opens a frontmatter fence (`---`) that is never closed, so its `scenarios` restriction cannot be read — this skill is NOT loaded (it is not demoted to a global skill); close the fence or remove the opening line",
111
111
  });
@@ -119,10 +119,16 @@ function parseSkill(raw, fallbackName, source, logger) {
119
119
  .split(",")
120
120
  .map((s) => s.trim())
121
121
  .filter(Boolean);
122
- return { spec: { name, description, content: body.trim() }, scenarios };
122
+ return { spec: { name, description, content: body.trim() }, scenarios, source: origin };
123
123
  }
124
- export function skillsForScenario(loaded, scenario) {
125
- return loaded.filter((k) => k.scenarios.length === 0 || k.scenarios.includes(scenario)).map((k) => k.spec);
124
+ function skillsInScope(loaded, scope) {
125
+ return loaded.filter((k) => k.scenarios.length === 0 || k.scenarios.includes(scope));
126
+ }
127
+ export function skillsForScenario(loaded, scope) {
128
+ return skillsInScope(loaded, scope).map((k) => k.spec);
129
+ }
130
+ export function scenarioSkillEntries(loaded, scope) {
131
+ return skillsInScope(loaded, scope).map((k) => ({ name: k.spec.name, description: k.spec.description, source: k.source }));
126
132
  }
127
133
  const FRONTMATTER_OPENS_RE = /^---[ \t]*\r?(?:\n|$)/;
128
134
  const FRONTMATTER_BLOCK_RE = /^---[ \t]*\r?\n(?:---[ \t]*\r?(?:\n|$)|([\s\S]*?)\r?\n---[ \t]*\r?(?:\n|$))([\s\S]*)$/;
@@ -19,7 +19,7 @@
19
19
  * 🔴 该判断在 core 5.40.0 / 7.15.0 上**逐字仍成立**(亲验):两次收窄动的都是「候选集是谁」,而
20
20
  * Agent / Task 四件是 **caller spec 工具**,收窄后照样在候选池里 —— 不开 auto 的理由没有被消解。
21
21
  * 我方**从不接线**这个座:全树零 `RunnerDeps.deferMode` 赋值(web-admin 曾有同形近名 `deferModelPlane`,
22
- * 与本轴无关,已于 S-668 波 0 退役)。机器钉见 test/tool-defer.test.ts 的 [ref] 件⑤ 格 —— 这条「零接线」正是本仓
22
+ * 与本轴无关,已于 [ref] 波 0 退役)。机器钉见 test/tool-defer.test.ts 的 [ref] 件⑤ 格 —— 这条「零接线」正是本仓
23
23
  * 在两个 core 世代之间行为逐字不变的**全部**依据,所以它值一根钉而不只是一句注。
24
24
  * - per-tool `ToolSpec.defer:true` 是本 helper 施加的那一位。**7.15.0 起它是一次「进候选集」的声明,
25
25
  * 不再是「一定占位」的保证** —— 长尾集单独一只(下面实测 ≈842 字符)远在阈值之下,于是这根旋钮在