@sema-agent/server 7.148.0 → 7.150.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 (360) hide show
  1. package/MIGRATION.md +551 -9
  2. package/README.md +17 -2
  3. package/README.zh-CN.md +5 -1
  4. package/USAGE.md +126 -68
  5. package/dist/adoption/wire.d.ts +3 -3
  6. package/dist/approval-card.d.ts +33 -33
  7. package/dist/approval-gate-currency.d.ts +1 -1
  8. package/dist/approval-leg-origin.d.ts +33 -0
  9. package/dist/approval-leg-origin.js +4 -0
  10. package/dist/audit.d.ts +1 -1
  11. package/dist/audit.js +2 -2
  12. package/dist/auth-bridge.d.ts +9 -1
  13. package/dist/auth-bridge.js +4 -4
  14. package/dist/auth-keys.d.ts +10 -1
  15. package/dist/auth-keys.js +8 -0
  16. package/dist/background-session-reap.d.ts +1 -1
  17. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  18. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  19. package/dist/boot/execution-env.js +10 -11
  20. package/dist/boot/execution-lane.d.ts +6 -4
  21. package/dist/boot/execution-lane.js +3 -1
  22. package/dist/boot/org-delivery.d.ts +3 -2
  23. package/dist/boot/parked-revive-gate.d.ts +5 -5
  24. package/dist/boot/parked-revive-gate.js +2 -3
  25. package/dist/boot/resolve-spec.d.ts +4 -5
  26. package/dist/boot/resolve-spec.js +66 -28
  27. package/dist/boot/retention-lane.d.ts +1 -1
  28. package/dist/boot/runner-deps.js +3 -1
  29. package/dist/boot/session-faces.js +21 -21
  30. package/dist/boot/stage-01-config.d.ts +1 -0
  31. package/dist/boot/stage-01-config.js +4 -3
  32. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  33. package/dist/boot/stage-02-web-admin-pull.js +10 -2
  34. package/dist/boot/stage-03-store-backend.d.ts +1 -0
  35. package/dist/boot/stage-03-store-backend.js +4 -4
  36. package/dist/boot/stage-04-stores.d.ts +1 -0
  37. package/dist/boot/stage-05-execution-env.d.ts +1 -0
  38. package/dist/boot/stage-06-runners.d.ts +2 -1
  39. package/dist/boot/stage-06-runners.js +1 -2
  40. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  41. package/dist/boot/stage-07-capability-layer.js +1 -1
  42. package/dist/boot/stage-08-reapers.d.ts +2 -1
  43. package/dist/boot/stage-09-leader.d.ts +2 -1
  44. package/dist/boot/stage-10-http-server.d.ts +35 -2
  45. package/dist/boot/stage-10-http-server.js +9 -4
  46. package/dist/boot/stores.d.ts +3 -0
  47. package/dist/boot/stores.js +22 -19
  48. package/dist/boot/web-admin.d.ts +1 -1
  49. package/dist/capabilities/tool-defer.d.ts +1 -1
  50. package/dist/capability-facts.d.ts +70 -60
  51. package/dist/capability-facts.js +45 -49
  52. package/dist/card-settle-stored-scope.d.ts +56 -0
  53. package/dist/card-settle-stored-scope.js +27 -0
  54. package/dist/card-void.d.ts +7 -12
  55. package/dist/card-void.js +2 -7
  56. package/dist/config-catalog.d.ts +12 -0
  57. package/dist/config-catalog.js +37 -33
  58. package/dist/config-invariants.d.ts +5 -4
  59. package/dist/config-invariants.js +4 -4
  60. package/dist/config-types.d.ts +49 -16
  61. package/dist/config.d.ts +6 -5
  62. package/dist/config.js +35 -24
  63. package/dist/context-window-notice.d.ts +31 -0
  64. package/dist/context-window-notice.js +28 -0
  65. package/dist/deployment-governance.d.ts +7 -28
  66. package/dist/deployment-governance.js +1 -14
  67. package/dist/deployment-shape.d.ts +20 -11
  68. package/dist/deployment-shape.js +1 -0
  69. package/dist/device-ws-hub.d.ts +1 -0
  70. package/dist/device-ws-hub.js +64 -28
  71. package/dist/device-ws-protocol.d.ts +20 -6
  72. package/dist/device-ws-protocol.js +9 -2
  73. package/dist/engine-identity.d.ts +7 -1
  74. package/dist/engine-identity.js +5 -0
  75. package/dist/env-name-allowlist-knobs.d.ts +6 -5
  76. package/dist/env-name-allowlist-knobs.js +5 -0
  77. package/dist/execution-lane-caps.d.ts +20 -5
  78. package/dist/execution-lane-caps.js +18 -4
  79. package/dist/field-conflict.d.ts +2 -2
  80. package/dist/fleet/engine-signal.d.ts +14 -1
  81. package/dist/fleet/engine-signal.js +5 -1
  82. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  83. package/dist/fleet/serving-lease.d.ts +18 -3
  84. package/dist/fleet/serving-lease.js +81 -35
  85. package/dist/fleet-client.d.ts +13 -11
  86. package/dist/fleet-client.js +53 -33
  87. package/dist/history-anchor.js +1 -1
  88. package/dist/hitl-delivery.d.ts +1 -3
  89. package/dist/hitl-delivery.js +1 -1
  90. package/dist/hooks/command-spawn.d.ts +7 -2
  91. package/dist/hooks/command-spawn.js +13 -6
  92. package/dist/hooks/hook-runner.d.ts +5 -0
  93. package/dist/hooks/hook-runner.js +11 -7
  94. package/dist/http/active-run-conflict.d.ts +3 -7
  95. package/dist/http/active-run-conflict.js +2 -2
  96. package/dist/http/admission.js +5 -5
  97. package/dist/http/approval-sweeps.js +5 -3
  98. package/dist/http/caller-trust.d.ts +2 -2
  99. package/dist/http/caller-trust.js +3 -3
  100. package/dist/http/checkpoint-ctx.d.ts +18 -63
  101. package/dist/http/checkpoint-ctx.js +1 -24
  102. package/dist/http/claim-heartbeat.d.ts +6 -6
  103. package/dist/http/claim-heartbeat.js +6 -6
  104. package/dist/http/claimed-run.d.ts +16 -9
  105. package/dist/http/claimed-run.js +8 -0
  106. package/dist/http/dispatch.js +7 -5
  107. package/dist/http/durable-run-leg.d.ts +8 -1
  108. package/dist/http/durable-run-leg.js +34 -15
  109. package/dist/http/execution-context.d.ts +115 -14
  110. package/dist/http/execution-context.js +130 -40
  111. package/dist/http/owner-access.d.ts +246 -21
  112. package/dist/http/owner-access.js +186 -8
  113. package/dist/http/principal-gate.d.ts +18 -11
  114. package/dist/http/principal-gate.js +3 -1
  115. package/dist/http/readiness.d.ts +4 -2
  116. package/dist/http/resume-ctx-read.d.ts +14 -3
  117. package/dist/http/resume-ctx-read.js +24 -3
  118. package/dist/http/resume-legs.d.ts +35 -3
  119. package/dist/http/resume-legs.js +262 -106
  120. package/dist/http/route-ctx.d.ts +29 -11
  121. package/dist/http/routes/a2a-serve.js +17 -14
  122. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  123. package/dist/http/routes/approvals-assistant.js +11 -11
  124. package/dist/http/routes/capabilities.js +5 -4
  125. package/dist/http/routes/config-catalog.d.ts +1 -1
  126. package/dist/http/routes/diagnostics.d.ts +3 -1
  127. package/dist/http/routes/diagnostics.js +30 -5
  128. package/dist/http/routes/mcp-reconnect.js +2 -2
  129. package/dist/http/routes/memory-origin.d.ts +1 -1
  130. package/dist/http/routes/notify-wake.js +2 -3
  131. package/dist/http/routes/principal-inbox.d.ts +3 -1
  132. package/dist/http/routes/principal-inbox.js +3 -2
  133. package/dist/http/routes/projects.d.ts +1 -0
  134. package/dist/http/routes/projects.js +5 -3
  135. package/dist/http/routes/retention-ops.d.ts +1 -1
  136. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  137. package/dist/http/routes/run-permission-mode.js +2 -2
  138. package/dist/http/routes/runs.d.ts +1 -1
  139. package/dist/http/routes/runs.js +33 -37
  140. package/dist/http/routes/session-memory-sync.js +4 -5
  141. package/dist/http/routes/session-sync.d.ts +24 -5
  142. package/dist/http/routes/session-sync.js +45 -37
  143. package/dist/http/routes/sessions-list.d.ts +1 -1
  144. package/dist/http/routes/sessions.d.ts +1 -1
  145. package/dist/http/routes/sessions.js +18 -44
  146. package/dist/http/routes/tasks.js +136 -101
  147. package/dist/http/routes/trace-usage.js +14 -14
  148. package/dist/http/routes/workflows.d.ts +1 -0
  149. package/dist/http/routes/workflows.js +20 -38
  150. package/dist/http/server.d.ts +12 -9
  151. package/dist/http/server.js +35 -6
  152. package/dist/http/stored-body-replay.d.ts +3 -24
  153. package/dist/http/stored-body-replay.js +2 -12
  154. package/dist/http/submit-ctx.d.ts +2 -2
  155. package/dist/http/submit-ctx.js +5 -5
  156. package/dist/http/submit-replay.d.ts +15 -2
  157. package/dist/http/submit-replay.js +10 -4
  158. package/dist/http/wire-types.d.ts +6 -3
  159. package/dist/index.d.ts +3 -1
  160. package/dist/index.js +1 -0
  161. package/dist/leader/endpoint.js +9 -8
  162. package/dist/leg-facts.d.ts +13 -2
  163. package/dist/leg-facts.js +2 -0
  164. package/dist/local-store-declaration.d.ts +54 -0
  165. package/dist/local-store-declaration.js +59 -0
  166. package/dist/mcp-assertion-header.d.ts +1 -1
  167. package/dist/mcp-assertion-header.js +1 -1
  168. package/dist/mcp-authorization-face.d.ts +18 -14
  169. package/dist/mcp-authorization-face.js +3 -2
  170. package/dist/memory-project-layer.js +1 -1
  171. package/dist/memory-scope.d.ts +4 -4
  172. package/dist/memory-scope.js +4 -4
  173. package/dist/memory-store-refusal.d.ts +1 -1
  174. package/dist/memory-sync-client.js +2 -2
  175. package/dist/model-context-window.d.ts +50 -11
  176. package/dist/model-context-window.js +20 -1
  177. package/dist/model-entry-refusal.d.ts +5 -4
  178. package/dist/model-entry-refusal.js +17 -3
  179. package/dist/model-reach-scope.d.ts +2 -1
  180. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  181. package/dist/observability/fail-open.d.ts +19 -7
  182. package/dist/observability/fail-open.js +19 -7
  183. package/dist/observability/logger.d.ts +7 -0
  184. package/dist/observability/logger.js +3 -1
  185. package/dist/observability/metrics.js +1 -1
  186. package/dist/observability/run-terminal.d.ts +1 -1
  187. package/dist/observability/run-terminal.js +1 -0
  188. package/dist/observability/secret-env-scrub.d.ts +1 -1
  189. package/dist/observability/secret-env-scrub.js +1 -1
  190. package/dist/org-delivery-gate.d.ts +31 -6
  191. package/dist/org-delivery-gate.js +7 -4
  192. package/dist/owner-faces.d.ts +30 -5
  193. package/dist/owner-faces.js +2 -0
  194. package/dist/park-row-commit.d.ts +67 -0
  195. package/dist/park-row-commit.js +76 -0
  196. package/dist/parked-decide.d.ts +9 -7
  197. package/dist/parked-decide.js +25 -6
  198. package/dist/peer-directory.d.ts +1 -1
  199. package/dist/peer-seat.d.ts +1 -1
  200. package/dist/peer-seat.js +52 -59
  201. package/dist/plugins/adoption-log-sql.d.ts +3 -3
  202. package/dist/plugins/adoption-log-sql.js +19 -19
  203. package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
  204. package/dist/plugins/approval-ask-store-sql.js +3 -5
  205. package/dist/plugins/approval-exemption-skill-cutoff.d.ts +64 -0
  206. package/dist/plugins/approval-exemption-skill-cutoff.js +122 -0
  207. package/dist/plugins/approval-exemption-skill-m46.d.ts +0 -6
  208. package/dist/plugins/approval-exemption-skill-m46.js +6 -10
  209. package/dist/plugins/approval-exemption-store.d.ts +26 -1
  210. package/dist/plugins/approval-exemption-store.js +28 -19
  211. package/dist/plugins/ensure-schema-lock-policy.d.ts +36 -3
  212. package/dist/plugins/ensure-schema-lock-policy.js +75 -9
  213. package/dist/plugins/exec-path-law.d.ts +34 -0
  214. package/dist/plugins/exec-path-law.js +13 -0
  215. package/dist/plugins/file-run-store.d.ts +22 -9
  216. package/dist/plugins/file-run-store.js +51 -23
  217. package/dist/plugins/local-checkpoint-store.d.ts +8 -1
  218. package/dist/plugins/local-checkpoint-store.js +5 -1
  219. package/dist/plugins/local-data-root-admission.d.ts +52 -0
  220. package/dist/plugins/local-data-root-admission.js +100 -0
  221. package/dist/plugins/local-engine-high-water.d.ts +28 -7
  222. package/dist/plugins/local-engine-high-water.js +27 -22
  223. package/dist/plugins/local-session-store.d.ts +134 -49
  224. package/dist/plugins/local-session-store.js +149 -108
  225. package/dist/plugins/memory-run-store.d.ts +14 -9
  226. package/dist/plugins/memory-run-store.js +48 -22
  227. package/dist/plugins/one-time-migration-marker.d.ts +19 -3
  228. package/dist/plugins/one-time-migration-marker.js +7 -1
  229. package/dist/plugins/one-time-migrations.d.ts +110 -59
  230. package/dist/plugins/one-time-migrations.js +224 -136
  231. package/dist/plugins/org-delivery-quota-store.d.ts +34 -11
  232. package/dist/plugins/org-delivery-quota-store.js +29 -14
  233. package/dist/plugins/permission-rule-store-sql.d.ts +1 -1
  234. package/dist/plugins/permission-rule-store-sql.js +5 -9
  235. package/dist/plugins/pg-pool.d.ts +1 -1
  236. package/dist/plugins/pg-pool.js +14 -12
  237. package/dist/plugins/posix-shell-fs.js +4 -2
  238. package/dist/plugins/remote-env-adb.js +3 -2
  239. package/dist/plugins/remote-env-device.d.ts +3 -2
  240. package/dist/plugins/remote-env-device.js +8 -6
  241. package/dist/plugins/remote-env-e2b.d.ts +4 -8
  242. package/dist/plugins/remote-env-e2b.js +21 -15
  243. package/dist/plugins/remote-env-host.d.ts +51 -10
  244. package/dist/plugins/remote-env-host.js +97 -31
  245. package/dist/plugins/remote-env-k8s.js +7 -4
  246. package/dist/plugins/remote-env-local-docker.d.ts +6 -3
  247. package/dist/plugins/remote-env-local-docker.js +11 -25
  248. package/dist/plugins/remote-env-ssh.js +4 -3
  249. package/dist/plugins/remote-shell.d.ts +3 -1
  250. package/dist/plugins/remote-shell.js +3 -3
  251. package/dist/plugins/replica-registration.d.ts +35 -0
  252. package/dist/plugins/replica-registration.js +48 -0
  253. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  254. package/dist/plugins/run-store-sql.d.ts +27 -8
  255. package/dist/plugins/run-store-sql.js +46 -18
  256. package/dist/plugins/scenario-prefix-switch-m42.d.ts +8 -12
  257. package/dist/plugins/scenario-prefix-switch-m42.js +9 -6
  258. package/dist/plugins/schema-consistency.d.ts +91 -5
  259. package/dist/plugins/schema-consistency.js +189 -7
  260. package/dist/plugins/schema-drift-sentence.d.ts +6 -5
  261. package/dist/plugins/schema-drift-sentence.js +13 -5
  262. package/dist/plugins/serving-requirement.d.ts +49 -0
  263. package/dist/plugins/serving-requirement.js +53 -0
  264. package/dist/plugins/session-placement.d.ts +5 -4
  265. package/dist/plugins/shell-sentinel-owner-m48.d.ts +22 -0
  266. package/dist/plugins/shell-sentinel-owner-m48.js +6 -0
  267. package/dist/plugins/stop-then-start-sentence.d.ts +55 -0
  268. package/dist/plugins/stop-then-start-sentence.js +51 -0
  269. package/dist/plugins/store-backend.d.ts +23 -9
  270. package/dist/plugins/store-backend.js +58 -24
  271. package/dist/plugins/store-contracts.d.ts +45 -5
  272. package/dist/plugins/store-contracts.js +19 -0
  273. package/dist/plugins/tidb-pool.d.ts +11 -6
  274. package/dist/plugins/tidb-pool.js +22 -12
  275. package/dist/plugins/workspace-custody.d.ts +44 -0
  276. package/dist/plugins/workspace-custody.js +47 -0
  277. package/dist/process-instance.d.ts +3 -0
  278. package/dist/process-instance.js +7 -0
  279. package/dist/project-context.d.ts +66 -0
  280. package/dist/project-context.js +70 -0
  281. package/dist/project-identity.d.ts +8 -7
  282. package/dist/project-identity.js +40 -17
  283. package/dist/project-layer-key.d.ts +13 -2
  284. package/dist/project-layer-key.js +9 -1
  285. package/dist/question.d.ts +9 -21
  286. package/dist/question.js +28 -19
  287. package/dist/read-deny-floor-notice.d.ts +36 -0
  288. package/dist/read-deny-floor-notice.js +40 -0
  289. package/dist/{plain-string-record.d.ts → request-declaration-disposition.d.ts} +9 -23
  290. package/dist/request-declaration-disposition.js +39 -0
  291. package/dist/run-cancel-card.d.ts +28 -0
  292. package/dist/run-cancel-card.js +20 -0
  293. package/dist/run-cancel-context.d.ts +10 -0
  294. package/dist/run-cancel-context.js +1 -0
  295. package/dist/run-local.js +28 -13
  296. package/dist/runs.d.ts +31 -7
  297. package/dist/runs.js +34 -16
  298. package/dist/security.d.ts +3 -3
  299. package/dist/server-secret-env.d.ts +34 -20
  300. package/dist/server-secret-env.js +61 -18
  301. package/dist/session-agent.d.ts +4 -12
  302. package/dist/session-agent.js +0 -6
  303. package/dist/session-children-retire.d.ts +6 -3
  304. package/dist/session-children-retire.js +2 -5
  305. package/dist/session-incarnation.d.ts +18 -4
  306. package/dist/session-incarnation.js +4 -1
  307. package/dist/session-notify-door.d.ts +4 -4
  308. package/dist/session-notify-door.js +5 -6
  309. package/dist/session-rules-seat.d.ts +4 -3
  310. package/dist/session-rules-seat.js +3 -11
  311. package/dist/session-sync.js +3 -3
  312. package/dist/session-workspace.d.ts +3 -3
  313. package/dist/store-admission.d.ts +33 -0
  314. package/dist/store-admission.js +49 -0
  315. package/dist/store-posture.d.ts +5 -0
  316. package/dist/store-posture.js +18 -1
  317. package/dist/stores-sql/checkpoint-store-sql.d.ts +22 -3
  318. package/dist/stores-sql/checkpoint-store-sql.js +109 -23
  319. package/dist/stores-sql/file-history-store-sql.d.ts +1 -1
  320. package/dist/stores-sql/file-history-store-sql.js +3 -5
  321. package/dist/stores-sql/retention-store-sql.d.ts +1 -1
  322. package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
  323. package/dist/stores-sql/tool-result-store-sql.js +4 -6
  324. package/dist/task-a2a.d.ts +3 -8
  325. package/dist/task-a2a.js +25 -27
  326. package/dist/task-cwd.d.ts +27 -10
  327. package/dist/task-cwd.js +3 -0
  328. package/dist/task-mcp.d.ts +3 -3
  329. package/dist/task-mcp.js +1 -1
  330. package/dist/task-settings.d.ts +13 -0
  331. package/dist/task-settings.js +14 -7
  332. package/dist/terminal.d.ts +2 -0
  333. package/dist/terminal.js +21 -6
  334. package/dist/tool-approval.d.ts +50 -41
  335. package/dist/tool-approval.js +96 -73
  336. package/dist/trace/engine-notice-wire.d.ts +38 -21
  337. package/dist/trace/engine-notice-wire.js +25 -4
  338. package/dist/trace/ledger-sink.d.ts +3 -1
  339. package/dist/trace/project.d.ts +8 -5
  340. package/dist/trace/project.js +11 -9
  341. package/dist/trace/projection-table.d.ts +33 -2
  342. package/dist/trace/redact.d.ts +12 -0
  343. package/dist/trace/redact.js +5 -1
  344. package/dist/trace/self-minted-wire.d.ts +268 -56
  345. package/dist/trace/self-minted-wire.js +110 -40
  346. package/dist/trace/tool-card.d.ts +3 -0
  347. package/dist/trace/tool-card.js +24 -0
  348. package/dist/trace/tool-output-media.d.ts +2 -1
  349. package/dist/unattended-permission-mode.d.ts +1 -1
  350. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  351. package/dist/web-admin-client/apply-effective.js +22 -9
  352. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  353. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  354. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
  355. package/docs/error-text-lexicon.json +317 -0
  356. package/package.json +4 -2
  357. package/scripts/embed-minimal.mjs +183 -0
  358. package/wire-changes/server@7.149.0.json +372 -0
  359. package/wire-changes/server@7.150.0.json +335 -0
  360. package/dist/plain-string-record.js +0 -70
@@ -1,13 +1,15 @@
1
1
  import { type DeploymentShapeInput } from "./deployment-shape.js";
2
+ import type { RunInternals } from "@sema-agent/core";
2
3
  /**
3
4
  * 词法归一:纯字符串运算,折 `.` / `..` / 重复分隔符,**不碰 fs**。
4
5
  * `posix.normalize` 把 `..` 在根部截断(`/../x` → `/x`),与「根之上没有东西」的语义一致;尾部分隔符
5
6
  * 统一剥掉(根 `/` 除外),让同一目标只有一个 key —— 前缀判域(见 {@link dirCoversPath})靠的就是
6
7
  * key 的唯一性。
7
8
  *
8
- * 🔴 **单点**([ref] 起):此前它的一份私有副本住在 `boot/deferred-sandbox-path-env.ts`(沙箱代理的
9
- * `absolutePath` 词法臂),而写门豁免域与任务根的判域现在读的是同一条律 —— 两份各自归一就是两个 key
10
- * 空间,而「豁免域盖没盖住任务根」这种判断在两个 key 空间里可以同时答是和否。
9
+ * 🔴 **单点**([ref] 起):写门豁免域与任务根的判域读的是同一条律 —— 两份各自归一就是两个 key
10
+ * 空间,而「豁免域盖没盖住任务根」这种判断在两个 key 空间里可以同时答是和否。它只答**配置座**上的判域
11
+ * (env-facts 的 cwd / scratchpad 事实、{@link dirCoversPath});执行环境方法读路径不经它 —— 那一面是执行缝路径律
12
+ * (`plugins/exec-path-law.ts`,只锚不折,沙箱写门代理的 `absolutePath` 也读那一只)。
11
13
  * (core 内部有同形的 `normalizeAbsPathLexically`,但未从包根导出;此处是 Node 标准库的等价运算,
12
14
  * 不是它的抄本——若日后 core 导出,这里应改为直接复用。)
13
15
  */
@@ -85,23 +87,38 @@ export declare function parseAdditionalDirectories(raw: unknown): string[] | und
85
87
  * sandbox — "当前工作目录为空"): resolve the HOST lane's effective workspace for a task. Precedence:
86
88
  * 1. the session's explicitly-registered `cwd` (the caller's own launch dir, the cwd seam) — an explicit
87
89
  * per-session choice always wins;
88
- * 2. the TRUSTED `ctx.parentCwd` (core threads the PARENT task's working root via `RunInternals` when this
89
- * task is a delegated child — never a TaskSpec field), UNLESS the child asked for `isolation:"worktree"`
90
- * (an isolated fan-out child must not share the parent's mutable dir) — then `undefined`;
91
- * 3. undefined → the factory's ephemeral per-task dir (top-level task with no registered cwd).
90
+ * 2. the TRUSTED `ctx.parentCwd` — the working root of the run that handed this leg its work, via `RunInternals`
91
+ * (never a TaskSpec field): a delegating parent (core threads it to a delegated child) or a composition host (the
92
+ * submission whose cascade ladder / verification gate this leg belongs to: those legs run in sessions the engine
93
+ * mints, which arm 1 cannot read, so the composition entries hand them the submission's registered cwd —
94
+ * {@link compositionLegRoot}) — UNLESS the leg asked for `isolation:"worktree"` (an isolated fan-out child must
95
+ * not share the parent's mutable dir) — then `undefined`;
96
+ * 3. undefined → the factory's ephemeral per-task dir (no registered cwd anywhere up the chain).
92
97
  * The `isolation:"worktree"` ⇒ `undefined` rule is this function's own and holds by itself (the child never inherits the
93
98
  * parent's dir). It is NOT what answers a worktree ask on the host lane: `boot/execution-env.ts` never reaches here with one —
94
99
  * the worktree wrapper (one layer out) mints the tree and does not call the base factory, and without the wrapper the base
95
100
  * factory REFUSES (`isolation.unavailable`) instead of minting the empty ephemeral dir rule 3 would give. That refusal arm is
96
101
  * revoked when engine 7.61.0 refuses by itself; this function's rule then goes on keeping the child off the parent's dir.
97
- * CC parity: a Task sub-agent inherits the main session's cwd. Trust: `parentCwd` comes from core's trusted
98
- * run-internals channel (same posture as `isolation`), so no tenancy gate is needed here — but the HOST lane
99
- * itself is single-user by deployment shape, and container lanes (k8s/e2b/local-docker) never consult this.
102
+ * CC parity: a Task sub-agent inherits the main session's cwd. Trust: `parentCwd` comes from the trusted
103
+ * run-internals channel (same posture as `isolation`) — written by core's delegation callers, or by this service's
104
+ * composition entries from a cwd the registration gate (`callerCwd`) already admitted — so no tenancy gate is needed
105
+ * here; the HOST lane itself is single-user by deployment shape, and container lanes (k8s/e2b/local-docker) never consult this.
100
106
  */
101
107
  export declare function effectiveHostWorkspace(sessionCwd: string | undefined, ctx: {
102
108
  isolation?: string;
103
109
  parentCwd?: string;
104
110
  }): string | undefined;
111
+ /**
112
+ * 组合入口(`runCascade` / `resumeCascade` / `runWithVerification` / `resumeWithVerification`)交给它驱动的**每一条腿**的那一格:这次提交登记的工作目录,
113
+ * 作交活方的工作目录(`RunInternals.parentCwd`)—— {@link effectiveHostWorkspace} 的第 2 臂,委派子代用的同一臂(device 车道的 `effectiveDeviceCwd` 同序)。
114
+ *
115
+ * 为什么组合腿要它:梯子的每一级是在引擎**现铸的会话**里冷跑(core `runCascade` 剥掉 spec 的 `sessionId`),验证门的验证器腿的 spec 不带会话 ——
116
+ * 工厂按腿的会话查登记表(第 1 臂)查不到提交登记在根会话上的那一枚,不交就落第 3 臂(临时目录):用户让梯子在项目里改文件,改到了别处;验证器验的是一只空目录。
117
+ * 跑在根会话上的腿(验证门的实现腿 / 修复腿)第 1 臂先命中,同一个值。
118
+ * 没登记(`registeredCwd` 缺席:非 host / device 车道、多租户、根会话的提交从没带过 `cwd`、嵌入方装配器没铸事实)⇒ 空对象 —— 每一条腿照旧落临时目录、收场由托管表删。
119
+ * 登记粘在会话上(`setSessionCwd` 只在请求带 `cwd` 时写):同一会话之前带过、这次不带 ⇒ 交的仍是那一枚 —— 与第 1 臂对同一会话上普通 run 的读法一致。
120
+ */
121
+ export declare function compositionLegRoot(registeredCwd: string | undefined): Pick<RunInternals, "parentCwd">;
105
122
  /** {@link launchWorkspaceOf} 读到的那一格出自哪里(闭集;起服那一行日志与随包文档的 `workspaceFrom` 词)。 */
106
123
  export type LaunchWorkspaceFrom = "workspace-flag" | "host-workspace-base" | "process-cwd";
107
124
  /** 起服时的「工作区」:目录 + 它读自哪一格。 */
package/dist/task-cwd.js CHANGED
@@ -46,6 +46,9 @@ export function parseAdditionalDirectories(raw) {
46
46
  export function effectiveHostWorkspace(sessionCwd, ctx) {
47
47
  return sessionCwd ?? (ctx.isolation !== "worktree" ? ctx.parentCwd : undefined);
48
48
  }
49
+ export function compositionLegRoot(registeredCwd) {
50
+ return registeredCwd !== undefined ? { parentCwd: registeredCwd } : {};
51
+ }
49
52
  export function launchWorkspaceOf(config, explicit, cwd = process.cwd) {
50
53
  if (explicit !== undefined)
51
54
  return { dir: explicit, from: "workspace-flag" };
@@ -69,9 +69,9 @@ export declare const MAX_REQUEST_MCP_DROP_NAMES = 32;
69
69
  */
70
70
  export declare const MCP_SERVER_ENTRY_KEYS: readonly ["allowTools", "contentOrigin", "elicitation", "name", "sessionMetaKey", "source", "startupTimeoutMs", "toolAxes", "toolFaces", "transport"];
71
71
  /** `transport.kind:"stdio"` 的键闭集 = stdio 臂处置表的键(`env` 是件,其余进声明)。 */
72
- export declare const STDIO_MCP_TRANSPORT_KEYS: readonly ("env" | "kind" | "args" | "command")[];
72
+ export declare const STDIO_MCP_TRANSPORT_KEYS: readonly ("kind" | "env" | "args" | "command")[];
73
73
  /** `transport.kind:"http"` 的键闭集 = http 臂处置表的键(`headers` 是件,`assertionHeader` 承载不发送,其余进声明)。 */
74
- export declare const HTTP_MCP_TRANSPORT_KEYS: readonly ("url" | "headers" | "kind" | "principalHeader" | "assertionHeader")[];
74
+ export declare const HTTP_MCP_TRANSPORT_KEYS: readonly ("url" | "kind" | "headers" | "principalHeader" | "assertionHeader")[];
75
75
  /**
76
76
  * Does THIS deployment honor caller-supplied per-request MCP servers? TRUE for a SINGLE-USER deployment
77
77
  * (deployment-shape row `multiTenant` does not hold) — the requester is the super-admin of their own worker, so their `.mcp.json` is
@@ -189,7 +189,7 @@ export declare function requestMcpDeclarationRefusal(list: unknown): Declaration
189
189
  * 重放腿走读器({@link normalizeServer} / {@link classifyRequestMcp}),处置:整只不是数组 ⇒ 整只忽略 + 运维 warn `mcp_injection_ignored`;条目不是对象 / 坏硬键
190
190
  * (`name` / `transport` 硬字段 / `allowTools` / `toolAxes` / `toolFaces`)⇒ 这一条 server 整条不进 + 运维 warn `mcp_injection_dropped` + 用户面通告 `mcp.injection_dropped` 点名 `field`
191
191
  * (`toolAxes` 在一次性迁移 M19 的窗开着时先按升级前读法重读一次,过了就挂,见读器的注);超上限的尾项 ⇒ `over_cap` 点名;坏软键(`contentOrigin` / `elicitation` / `source`)
192
- * 与词表外的键 ⇒ 丢键、server 照挂(`contentOrigin` 另有 `mcp_content_class_dropped` 留声);`transport` 软字段有几处读器不交(`env` / `headers` 不是纯数据的串记录、其中名叫 `__proto__` 的成员、
192
+ * 与词表外的键 ⇒ 丢键、server 照挂(`contentOrigin` 另有 `mcp_content_class_dropped` 留声);`transport` 软字段有几处读器不交(`env` / `headers` 不是纯数据的串记录、其中名叫保留名(`__proto__` / `constructor` / `prototype`)的成员、
193
193
  * `args` / `principalHeader` 坏形)⇒ 这份请求不重放(「请求成员读不出」那一只判据,`unread-request-members.ts`,经 {@link requestMcpTransportUnread} 读这一座;续跑腿折 409)。
194
194
  */
195
195
  export declare function assertRequestMcpEntries(bodyMcp: unknown): void;
package/dist/task-mcp.js CHANGED
@@ -5,7 +5,7 @@ import { GOVERNANCE_HTTP_STATUS } from "./governance-http-status.js";
5
5
  import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
6
6
  import { MCP_SOURCE_LABEL_MAX, isMcpSourceLabel, readMcpSourceLabel } from "./mcp-source-label.js";
7
7
  import { MCP_HTTP_TRANSPORT_DISPOSITION, MCP_STDIO_TRANSPORT_DISPOSITION, describeMcpAssertionHeaderNotAString, describeMcpIdentityHeadersConflict, mcpIdentityHeadersIssue, noteMcpAssertionHeaderIgnored, noteMcpAssertionHeaderNotSent, specWithholdsMcpAssertionHeader, toMcpDraft, } from "./mcp-assertion-header.js";
8
- import { declarationKeys } from "./plain-string-record.js";
8
+ import { declarationKeys } from "./request-declaration-disposition.js";
9
9
  import { mintDeclaration, peerSentence } from "./peer-seat.js";
10
10
  import { MAX_KEY_ECHO, echoKeyName, keyClosureClause, scanKeyClosure } from "./request-key-closure.js";
11
11
  import { readRequestToolAxes } from "./request-tool-axes.js";
@@ -463,6 +463,19 @@ export declare function taskHooksHonored(config: {
463
463
  * 在 `server.ts` prepareSpec 里 400 响亮拒 + 逐字列名。双层姿势与 outputStyle / permissionMode 两处逐字相同。
464
464
  */
465
465
  export declare function parseTaskSettings(raw: unknown, seats?: ParseTaskSettingsSeats): ParseTaskSettingsResult;
466
+ /** The one reading of `settings.outputStyle`: a non-empty string within {@link MAX_SETTINGS_OUTPUT_STYLE_CHARS} ⇒ it; anything else ⇒ absent.
467
+ * Readers: the settings parser above and the system-prompt fold judgment at the head of `resolveSpec` (which runs before the parser's stage). */
468
+ export declare function acceptOutputStyle(v: unknown): string | undefined;
469
+ /**
470
+ * **系统提示追加折叠的唯一读法**(一个 spec 字段 `TaskSpec.appendSystemPrompt` 里折进几段):段按序、缺席 / 空段不出、`\n\n` 连接;`chars` = 折出来的字符数(含连接符)。
471
+ * 段序恒为 请求 `appendSystemPrompt` → 项目简报(`project-context.ts`)→ `settings.outputStyle`(字节稳定,前缀缓存靠它);三段共一只上限 16384。
472
+ * 读者四位,同读这一只:受理口的两段合计判(`http/admission.ts`)、装配器头部的三段判(`boot/resolve-spec.ts`,只在简报在场时)、装配合成(本文件 `applyTaskSettings` 接 style)、
473
+ * 续跑镜像(`resolve-spec.ts` 阶段⑤:存量体合计超帽 ⇒ 丢 style + warn)。
474
+ */
475
+ export declare function appendFold(segments: readonly (string | undefined)[]): {
476
+ readonly text: string | undefined;
477
+ readonly chars: number;
478
+ };
466
479
  /** Defensive acceptance of the `appendSystemPrompt` rider ([ref] R2 + codex F2): the HTTP 400 gate (prepareSpec,
467
480
  * MAX_SYSTEM_PROMPT_CHARS) only covers FRESH submits — every resume family re-enters resolveSpec on a STORED body,
468
481
  * and a pre-1.243 store preserved unknown request keys verbatim (the field was INERT then), so an over-cap legacy
@@ -135,6 +135,7 @@ export function settingsEnvCredentialIssue(reaching, credentialNames) {
135
135
  message: `settings.env carries credentials: ${named.join(", ")}${more}. A credential reaches the engine only through the environment its process starts from, never through a request's settings.env — ` +
136
136
  "that block comes from a settings file the model can read, and the request hands it to the session's shell and hooks. Move these out of settings.env into the engine's environment " +
137
137
  "(a sema shell that keeps credentials in its credentials.env file does this; upgrade a shell that still writes them into settings.json). " +
138
+ "A settings hook reads a variable from the engine's environment only when the deployment names it in HOOK_ENV_ALLOW; this engine's own credential variables (the entries matched by name) reach no hook at all. " +
138
139
  "If an entry is not a credential: rename a variable that matched by name, or keep a value that matched by shape out of settings.env the same way (the shape scan is deliberately coarse)",
139
140
  fields: { field: "settings.env", entries },
140
141
  keys: hits.map((h) => h.key),
@@ -359,9 +360,9 @@ export function parseTaskSettings(raw, seats = {}) {
359
360
  }
360
361
  if (typeof s.model === "string" && s.model.length > 0)
361
362
  out.model = s.model;
362
- if (typeof s.outputStyle === "string" && s.outputStyle.length > 0 && s.outputStyle.length <= MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
363
- out.outputStyle = s.outputStyle;
364
- }
363
+ const outputStyle = acceptOutputStyle(s.outputStyle);
364
+ if (outputStyle !== undefined)
365
+ out.outputStyle = outputStyle;
365
366
  if (shellEnv)
366
367
  out.shellEnv = shellEnv;
367
368
  if (s.ultracode === true)
@@ -387,6 +388,14 @@ export function parseTaskSettings(raw, seats = {}) {
387
388
  out.httpHookAllowlist = httpHookAllowlist;
388
389
  return { settings: Object.keys(out).length > 0 ? out : undefined, deferred, ...(hooksReread !== undefined ? { hooksReread } : {}) };
389
390
  }
391
+ export function acceptOutputStyle(v) {
392
+ return typeof v === "string" && v.length > 0 && v.length <= MAX_SETTINGS_OUTPUT_STYLE_CHARS ? v : undefined;
393
+ }
394
+ export function appendFold(segments) {
395
+ const present = segments.filter((segment) => segment !== undefined && segment.length > 0);
396
+ const text = present.length > 0 ? present.join("\n\n") : undefined;
397
+ return { text, chars: text?.length ?? 0 };
398
+ }
390
399
  export function acceptAppendSystemPrompt(v, warn) {
391
400
  if (v === undefined)
392
401
  return undefined;
@@ -592,10 +601,8 @@ export function applyTaskSettings(base, settings, bases) {
592
601
  const allow = settings.permissions?.allow;
593
602
  if (allow !== undefined)
594
603
  next = { ...next, allowedTools: allow.map((entry) => allowMemberOf(entry, bases?.configRoot)) };
595
- if (settings.outputStyle) {
596
- const appended = next.appendSystemPrompt ? `${next.appendSystemPrompt}\n\n${settings.outputStyle}` : settings.outputStyle;
597
- next = { ...next, appendSystemPrompt: appended };
598
- }
604
+ if (settings.outputStyle)
605
+ next = { ...next, appendSystemPrompt: appendFold([next.appendSystemPrompt, settings.outputStyle]).text };
599
606
  return next;
600
607
  }
601
608
  //# sourceMappingURL=task-settings.js.map
@@ -105,6 +105,8 @@ export declare function mapPauseSeats<T>(result: T, f: (seat: SeatObject, keys:
105
105
  * ①摘掉**耐久恢复能力凭据**(`CheckpointToken`)—— 座表 {@link PAUSE_SEATS} 上的每一座;②把**域外的失败码**折成本仓的
106
106
  * `internal.store_error`({@link outwardFailureCode},[ref])—— 码座两只:因由的 `terminal.code` 与 cascade 每一级的 `attempts[].errorCode`(同一类码,见 {@link foldOutwardFailureCodes});
107
107
  * 因由上折码时**失败句同时换成对外句**(类别句 + 原码尾注,库驱动原句不上 wire,{@link outwardStoreFailure})。
108
+ * 同一处还接上本仓对**读拒字节地板不守**的说法(属主 `read-deny-floor-notice.ts`):拒起的失败句是本仓那一句(码不变),照跑的结果按 `runId` 挂 `readDenyFloor`
109
+ * ({@link withReadDenyFloorSummary})—— 结果离开引擎的每个出口都经这里,说法一处接上。
108
110
  *
109
111
  * 🔴 为什么两件事合在一只函数里而不是并列两只(7.92.2 改名 `stripResumeToken` → `sealResultForExit`):
110
112
  * 它们是**同一个出口上的同一件事** —— 「这条结果可以见人了吗」。并列两只 = 六个结算点各自要记得调两次,
package/dist/terminal.js CHANGED
@@ -5,6 +5,7 @@ import { recordFailOpen } from "./observability/fail-open.js";
5
5
  import { redactSecrets } from "./trace/redact.js";
6
6
  import { seatText } from "./trace/exit-seat.js";
7
7
  import { storeFaultSentenceOfCode } from "./plugins/store-fault.js";
8
+ import { readDenyFloorRefusalMessage, readDenyFloorSummaryOf } from "./read-deny-floor-notice.js";
8
9
  export function failureCodeOf(terminal) {
9
10
  return terminal.kind === "failed" ? terminal.code : undefined;
10
11
  }
@@ -59,7 +60,14 @@ export function sealStoredResult(result, seat) {
59
60
  function seal(result, at) {
60
61
  if (result === null || typeof result !== "object")
61
62
  return result;
62
- return foldOutwardFailureCodes(mapPauseSeats(result, dropCapability), at);
63
+ const sealed = foldOutwardFailureCodes(mapPauseSeats(result, dropCapability), at);
64
+ return at === "exit" ? withReadDenyFloorSummary(sealed) : sealed;
65
+ }
66
+ function withReadDenyFloorSummary(result) {
67
+ if (result.readDenyFloor !== undefined)
68
+ return result;
69
+ const summary = readDenyFloorSummaryOf(result.runId);
70
+ return summary === undefined ? result : { ...result, readDenyFloor: summary };
63
71
  }
64
72
  function foldOutwardFailureCodes(result, at) {
65
73
  const terminal = foldCauseCode(result.terminal, at);
@@ -75,8 +83,10 @@ function foldCauseCode(terminal, at) {
75
83
  const t = failedCauseWithCode(terminal);
76
84
  if (t === undefined)
77
85
  return terminal;
78
- if (outwardFailureCode(t.code) === t.code)
79
- return terminal;
86
+ if (outwardFailureCode(t.code) === t.code) {
87
+ const presented = at === "exit" ? readDenyFloorRefusalMessage(t.code) : undefined;
88
+ return presented === undefined || presented === t.message ? terminal : { ...t, message: presented };
89
+ }
80
90
  const folded = outwardStoreFailure(t.code, t.message, at);
81
91
  return { ...t, code: folded.code, message: folded.message };
82
92
  }
@@ -139,12 +149,17 @@ function failedCauseWithCode(t) {
139
149
  return kind === "failed" && typeof code === "string" ? { ...t, kind, code } : undefined;
140
150
  }
141
151
  export function outwardPlane(terminal) {
152
+ return outwardProjection(terminal, "exit");
153
+ }
154
+ function outwardProjection(terminal, at) {
142
155
  const plane = terminalProjection(terminal);
143
156
  if (plane.errorCode === undefined)
144
157
  return plane;
145
158
  const outward = outwardFailureCode(plane.errorCode);
146
- if (outward === plane.errorCode)
147
- return plane;
159
+ if (outward === plane.errorCode) {
160
+ const presented = at === "exit" && plane.status === "failed" ? readDenyFloorRefusalMessage(plane.errorCode) : undefined;
161
+ return presented === undefined ? plane : { ...plane, errorMessage: presented };
162
+ }
148
163
  return plane.status === "failed" ? { ...plane, errorCode: outward, errorMessage: outwardStoreMessage(plane.errorCode) } : { ...plane, errorCode: outward };
149
164
  }
150
165
  export function nestedPauseOf(terminal) {
@@ -166,7 +181,7 @@ export function persistedPlaneOf(result) {
166
181
  if (r.terminal !== null && typeof r.terminal === "object") {
167
182
  let projected;
168
183
  try {
169
- projected = outwardPlane(r.terminal);
184
+ projected = outwardProjection(r.terminal, "stored");
170
185
  }
171
186
  catch (e) {
172
187
  recordFailOpen("server.terminal.persisted-plane-malformed", e instanceof Error ? e.message : String(e));
@@ -1,4 +1,4 @@
1
- import type { ExecutionLane } from "./execution-lane-caps.js";
1
+ import type { ApprovalLegOrigin } from "./approval-leg-origin.js";
2
2
  import { type ApprovalDecider, type HostSettledBy, type HostSource, type RetiredDecisionKeyFacts } from "./host-decision.js";
3
3
  import type { IncomingMessage } from "node:http";
4
4
  import { type AskClass, type AskRequest, type AskOutcome, type PermissionResult, type CheckpointGate, type PendingAction, type PersistedRuleMandate, type ReadRootGrantCandidate, type RuleOffer, type AutoModeFallbackCause, type BoundGrantAbsence, type BoundSkillGrants, type ToolApprovalCard, type ReopenReason } from "@sema-agent/core";
@@ -26,6 +26,8 @@ interface OpenAskAdoption {
26
26
  /** 待决行多于 {@link ADOPT_OPEN_ASKS_MAX}:只接管了最先的那么多只。 */
27
27
  readonly capped: boolean;
28
28
  }
29
+ /** Bound on the remembered allow-all grants (insertion-order evict — a long-lived worker must not grow unbounded). */
30
+ export declare const MAX_ALLOW_SESSIONS = 4096;
29
31
  /**
30
32
  * 耐久回决口 `POST /v1/approvals/:sessionId/decide` 的路径串 —— [ref]:迟到回决口 PARKING 臂 202 体的机读指路 `decidePath`。
31
33
  * 路由表那一行(`http/routes/approvals-assistant.ts` 的 `approval-decide`)按 pattern 匹配它;两者同形由往返钉守
@@ -298,9 +300,9 @@ export type StandingAnswerHome = "none" | "seat" | "server_store";
298
300
  /**
299
301
  * 🔴 **[ref] —— 会话级放行的唯一判据:站着的答案能不能退掉这一问,能的话它记在哪({@link StandingAnswerHome})。** 纯函数,读者:
300
302
  * · **读侧**(`askBroadcast` 的会话授权短路 {@link ToolApprovalCoordinator.standingGrantSettles}):`seat` 才可能由既有授权代答,否则往下走真出卡;
301
- * · **写侧**(`finishRespond` 的 `grantable` 与 `recordDeploymentListAnswer`):`seat` 把 `allow_session` 铸成进程内授权;`server_store` 落 server 的会话豁免店;
303
+ * · **写侧**(`finishRespond` 与 `recordDeploymentListAnswer`,经 {@link liveSessionAnswer}):`seat` 把 `allow_session` 铸成进程内授权;`server_store` 落 server 的会话豁免店;
302
304
  * `none` 只放行这一次、`rememberApplied:false`;
303
- * · **卡面提示位**(活卡帧 / 条目 / `livePending` 行的 `rememberRefused`):在场 ⇔ `none`;
305
+ * · **卡面提示位**(活卡帧 / 条目 / `livePending` 行的 `rememberRefused`):在场 ⇔ 本函数答 `none` 或这条腿记不下(读的是 {@link liveSessionAnswer},它先问本函数);
304
306
  * · **耐久可记性**({@link standingAnswerDurablyRecordable}:`/decide` 的 remember、运维队列行、策略层两只豁免读面)。
305
307
  * 各读者读同一份事实、说同一句话:一问若不许被记住的放行答掉,它的应答也不许变成一条记住的放行 —— 否则
306
308
  * 同一只卡「重跑一遍」就被自己上一次的回答代答(test [ref] U1s-off 的真形)。读者侧没有任何按「问的属主」另判的臂:属主只在本函数里读一次。
@@ -467,11 +469,12 @@ export interface ToolApprovalFrame {
467
469
  mandated?: true;
468
470
  /**
469
471
  * **7.116.0(审计修复批 S4;ADDITIVE,`"tool_approval"` only)—— 这张卡上的「本会话放行」只放行这一次、不会被记住。**
470
- * 在场 ⇔ 同一只判据 {@link standingAnswerHome} 答 `none`(治理强制 / 必须真人 / 强制 / 应答还授予别的东西 / 类集清不掉),回决侧写授权
471
- * (`finishRespond`)读的是同一份事实 ⇒ 帧说不可记 ⇔ 点了 `allow_session` 回执 `rememberApplied:false`。壳读这一位决定渲不渲
472
+ * 在场 ⇔ 同一只判官 {@link liveSessionAnswer} 答 `none`(问本身记不住:治理强制 / 必须真人 / 强制 / 应答还授予别的东西 / 类集清不掉;或这条腿记不下:
473
+ * 没有会话 / 读不出会话住客),回决侧写授权(`finishRespond`)读的是同一只 ⇒ 帧说不可记 ⇔ 点了 `allow_session` 回执 `rememberApplied:false`。壳读这一位决定渲不渲
472
474
  * 「本会话放行」,不再从 `requiresRealApproval` / `mandated` / `governanceForced` 三位自己推断(那一推断漏掉第四个理由:core 7.41.0
473
475
  * 的 `Skill` 卡批准即授予清单,三位全无)。`card_json` 卡面、`livePending` 行、运维队列行同名同义。
474
- * 🔴 **真才带,缺席绝不编 `false`**:缺席 = 可记(有会话时)或老服务端。没有会话的腿上点了照样只放行一次(回执说明),本位不管那一形。
476
+ * 判官是 {@link liveSessionAnswer}(这一问的事实 + 这条腿记不记得下:没有会话的腿、读不出会话住客的腿同样在场),回决写侧读同一只。
477
+ * 🔴 **真才带,缺席绝不编 `false`**:缺席 = 在这条腿上记得住,或老服务端。
475
478
  */
476
479
  rememberRefused?: true;
477
480
  /**
@@ -526,7 +529,7 @@ export interface ToolApprovalFrame {
526
529
  * **[ref] ②(core 7.37.0 [ref];ADDITIVE,`"tool_approval"` only)** —— 这一问的**类**:`classes` 的首员(core `ASK_CLASSES` 序),
527
530
  * `MODE_ARBITRATION` 的行键(权限模式读的就是它 / 它们)。引擎在每一个铸 `origin` 的站盖章(策略自报的值在盖章处被替换),本仓经
528
531
  * `approval-card.ts` 的 `readAskClassPair(req)` 窄读(判法 = core 屏 `screenAskClassMembers`,[ref] ⑥ / [ref],本仓零自写对判;屏拒 ⇒ 两键都不投 + 计一次
529
- * [ref] 集外 tag)。**与 {@link classes} 同在同缺**;缺席 = 老引擎 / 不盖类的站(共享制品读确认,core KL-1214-a),不是「无类」。
532
+ * [ref] 集外 tag)。**与 {@link classes} 同在同缺**;缺席 = 老引擎 / 不盖类的站(共享制品读确认,core [ref]),不是「无类」。
530
533
  * display:壳按类渲卡(cli 卡面、client-core [ref]),durable 审批席按类答;**本仓不按它裁决**(无人值守腿的按类作答读 core 交来的
531
534
  * `AskRequest.classes` 本身)。同一对的其余面:`card_json` 卡面 / `approval_request` 呈卡帧 / 断连重放帧(同一份素材)、运维队列行
532
535
  * (`parkRowFacts`,读停车行孪生座 `PendingAction.tool_approval.askClass`);inbox 行不带(core `CheckpointSummary` 不回显)。
@@ -890,12 +893,10 @@ export type ApprovalLegFamily = {
890
893
  readonly transport: HitlTransport<ToolApprovalFrame>;
891
894
  };
892
895
  /** 两族共有的腿身份与腿轴。 */
893
- interface ToolApprovalRunContextBase {
896
+ interface ToolApprovalRunContextBase extends ApprovalLegOrigin {
894
897
  taskId: string;
895
898
  sessionId?: string;
896
899
  owner: string | null;
897
- /** 这条腿的执行车道 —— 装配点写所在边界执行上下文的 `ctx.lane`(`http/execution-context.ts`)。出处带车道:这只席造的问在铸行时记下它。 */
898
- executionLane: ExecutionLane;
899
900
  abortSignal?: AbortSignal;
900
901
  /** [ref]([ref] §3.1 askId 派生的腿轴;车3 刀 3a 换轴:原 `leg?: number` → `legKey?: string`)。
901
902
  * = `sha256(resume checkpoint token)` 的 hex,**首腿缺席折空串**(空串是首腿的真值,不是「未知」)。
@@ -1342,7 +1343,7 @@ export declare class ToolApprovalCoordinator {
1342
1343
  private readonly pendingByAskId;
1343
1344
  /** preamble 呈出的卡的消卡订阅(键 = askId;见 {@link watchPresentedCards})。只订本副本上此刻在等的 ask,落定即清 ⇒ 有界于活登记数。 */
1344
1345
  private readonly presentedCardWatchers;
1345
- /** Per-capability session grants — keys = sessionAllowKey(owner, sessionId, category, grant binding) (修2; bounded). */
1346
+ /** Per-capability session grants — keys = sessionAllowKey(owner, sessionId, session incarnation, category, grant binding) (修2; bounded). */
1346
1347
  private readonly allowAllSessions;
1347
1348
  /** [ref] HIGH-1(broker)→[ref]四 core 产品裁定「多活集合+广播+首决胜出」:per-(owner, host-session)
1348
1349
  * 的**当前活跃连接集合**——boundAsk 闭包只携身份,emit 时广播给该 key 下**全部**活连接(宿主重连/
@@ -1777,8 +1778,7 @@ export declare class ToolApprovalCoordinator {
1777
1778
  owner: string | null;
1778
1779
  taskId: string;
1779
1780
  sessionId?: string;
1780
- executionLane: ExecutionLane;
1781
- }, why: LegUnattended) => ((req: AskRequest) => Promise<AskOutcome>);
1781
+ } & ApprovalLegOrigin, why: LegUnattended) => ((req: AskRequest) => Promise<AskOutcome>);
1782
1782
  /**
1783
1783
  * 🔴 session grant 短路前的**持久出处复核**([ref] 的 codex R1-[high] 补丁;[ref] 换判据;[ref] / SN-C1 换读口)。
1784
1784
  *
@@ -1966,7 +1966,7 @@ export declare class ToolApprovalCoordinator {
1966
1966
  * emit 时经 broker 取该 (owner, session) 的「当前」活跃流(宿主重连/续聊的新 SSE 自动接卡;
1967
1967
  * internalsSnapshot 冻结的闭包因此永不携死流)。查无活流 = "unavailable"(G1 回路:durable 部署
1968
1968
  * park;inherited plain-ask 的 park 回路 = core [ref]①,落地前该臂 = deny,与 1.257 前行为一致)。 */
1969
- boundAsk: (identity: {
1969
+ boundAsk: (identity: ApprovalLegOrigin & {
1970
1970
  owner: string | null;
1971
1971
  taskId: string;
1972
1972
  sessionId?: string;
@@ -1974,8 +1974,6 @@ export declare class ToolApprovalCoordinator {
1974
1974
  /** [ref] 车3 刀 3b(§7.3):本腿的 walltime deadline —— 与 `legKey` 同源同理由,随**出处**走
1975
1975
  * (子代经继承链拿到的是宿主腿的闭包,窗必须按宿主腿的剩余 walltime 算)。 */
1976
1976
  legDeadlineMonotonic?: number;
1977
- /** 宿主腿的执行车道(装配点写执行上下文的 `ctx.lane`);子代经继承链冻同一闭包 ⇒ 子代的问记宿主腿的车道。 */
1978
- executionLane: ExecutionLane;
1979
1977
  }) => ((req: AskRequest, signal?: AbortSignal) => Promise<AskOutcome>);
1980
1978
  /** 广播版裁决路径——`ask()`(ALS,恒单元素数组)与 `boundAsk`([ref]四多活集合,可能多元素)共用。
1981
1979
  * 全体 `ctxs` 保证同一 (owner, sessionId)(streamKey 分组不变式;单元素数组平凡成立)。
@@ -2068,10 +2066,10 @@ export declare class ToolApprovalCoordinator {
2068
2066
  /**
2069
2067
  * `GET /v1/tool-approvals/:approvalId` —— **按问读口**:一只 ask 此刻在哪一态({@link TOOL_APPROVAL_READ_STATES})。与 {@link respond} 同根同门
2070
2068
  * (HTTP 层的鉴权 / 属主身份同一只 `gatedSubject`;看不见这只问 —— 属主不过 / 查无 / 行读不出 / 没有问账 —— 与应答口同答 404 `not_found.ask`({@link askNotVisible}),
2071
- * 无存在性 / 状态谕示),读法与应答口逐条同源:
2072
- * 本副本上在等它的活登记({@link liveEntryFor})⇒ `pending`(行投影 = 列表面 `livePending[]` 的同一只投影);否则按 id 读行
2073
- * ({@link askRowFor} + {@link askRowVisibleTo}),行态 → 读态与晚答口的分派同一张表;行仍 `STREAM_PENDING` 而本副本没有在等它的登记 ⇒ 它活在别的副本上,
2074
- * 与晚答口同答 404 `tool_approval.not_pending` + `unknown_or_other_replica`(那里才有兑现它的闭包;属主看得见的态)。
2069
+ * 无存在性 / 状态谕示)。看不看得见只有一个来源:有行的问 = 店答出的行上当下的属主(按 id 读行,{@link askRowFor} + {@link askRowVisibleTo});
2070
+ * 店答不出 ⇒ 看不见,本副本登记上记下的那一位(行上属主的读缓存)不替店作答。没有行的问(问账没上场 / 旧族腿)= 登记记下的那一位(唯一可读的属主事实)。
2071
+ * 读到的行仍 `STREAM_PENDING`:本副本有在等它的登记 ⇒ `pending`(行投影 = 列表面 `livePending[]` 的同一只投影);没有 ⇒ 它活在别的副本上,
2072
+ * 与晚答口同答 404 `tool_approval.not_pending` + `unknown_or_other_replica`(那里才有兑现它的闭包;属主看得见的态);其余行态 → 读态与晚答口的分派同一张表。
2075
2073
  * 纯读:零写、零结算、不碰本地登记(晚答口的 DECIDED 臂会顺手同步本副本的活登记,读口不做)。
2076
2074
  */
2077
2075
  readApproval(id: string, principal: string | undefined): {
@@ -2082,10 +2080,9 @@ export declare class ToolApprovalCoordinator {
2082
2080
  body: unknown;
2083
2081
  }>;
2084
2082
  /**
2085
- * [ref]:有行的登记的按问读口 —— 行可见且仍 `STREAM_PENDING` ⇒ `pending`(列表面同一只行投影);否则按行的态答(与读行半场同一张表)。
2086
- * 🔴 行**读不出**(店抛 / 超时)⇒ 只有**本协调器自己铸的活登记**回落:登记记下的属主认调用方 ⇒ `pending`,否则与未知 id 同答 —— 与同一刻的应答口同答
2087
- * (活登记的应答拿登记属主当候选、不多读一次店,店抖动不挡真实回决,D5),也与 7.135.x 的读口同答。**接管登记**([ref],起服从问账接管、没有引擎腿在等)的
2088
- * 属主跟着行走,登记上那一格不是权威 —— 应答口对它恒读行判、读不出 ⇒ 404,读口同样 404(两口同答;7.135.x 两口都 404)。读得出的「没有这一行」不回落(那是行的真相)。
2083
+ * 有行的登记的按问读口 —— 行可见且仍 `STREAM_PENDING` ⇒ `pending`(列表面同一只行投影);否则按行的态答(与读行半场同一张表)。
2084
+ * 行读不出(店抛 / 超时)与查无同答 404 —— 活登记与接管登记一样:登记上那一格只是行上属主的读缓存,店答不出时它不替店说「你看得见」
2085
+ * (应答口同律:属主门那一读读不出 ⇒ 同一句 404;决议写失败之后读不回行 ⇒ 500,那是「不知道落没落」,不是看得见)。
2089
2086
  */
2090
2087
  private readByRow;
2091
2088
  /** {@link readApproval} 的读行半场。 */
@@ -2136,12 +2133,15 @@ export declare class ToolApprovalCoordinator {
2136
2133
  /** {@link respondLate} 的读行:按 id 读出行,交 {@link dispatchRowTruth}。 */
2137
2134
  private dispatchLateByRow;
2138
2135
  /**
2139
- * 按 wire 身份(= 行的键)读行 —— 三态分开交回({@link AskRowRead}):读到了 / 读得出的「没有这一行」/ 读不出(店抛或超时,记账)。
2140
- * 「读不出」与「不在」不折成一个值:调用点各自表态 —— 应答口与晚答口按「查无」答(读不出 = **不知道**这只 ask 落在哪一态,而受理臂都在对客户端做承诺,
2141
- * 不知道 ⇒ 回那句 404,绝不把未知说成受理;D5 的 fail-open 只覆盖「不挡人的真实回决」那一面,这条腿方向相反),按问读口对本协调器自己铸的活登记回落那一份登记
2142
- * (接管登记不回落,{@link readByRow})。
2136
+ * 按 wire 身份(= 行的键)读行,给属主门用(应答口 / 晚答口 / 按问读口):读到了 ⇒ 那一行;读得出的「没有这一行」与读不出(店抛或超时,记账)同答 `null`。
2137
+ * 读不出 = **不知道**属主是谁、这只 ask 落在哪一态 ⇒ 调用方看不见它(与查无同答 404):属主门 fail-closed,受理臂不把未知说成受理,读口不把未知说成待决。
2143
2138
  */
2144
2139
  private askRowFor;
2140
+ /**
2141
+ * 一只有行的问**此刻的行** —— 应答口 / 按问读口 / 列表面读行的**唯一**入口:{@link askRowFor} 点读(读不出 ⇒ `null` ⇒ 看不见),读到仍待决的行就把这只问在本副本上的登记
2142
+ * 对齐到行上当下的属主([ref];先于各口的门判:门判的是调用方,不是这次对齐)。读序号在**发起读之前**取({@link nextRowReadSeq}):晚回来的旧读盖不掉之后发起的读。
2143
+ */
2144
+ private askRowFollowingOwner;
2145
2145
  /**
2146
2146
  * 一条行(的此刻真相)→ 应答口的答案:属主门 + 受理回执 + 六态穷举分派(闭集:新增 `AskState` 而不在此表态 = **编译错**)。两个入口:本副本没有在等
2147
2147
  * 这只 ask 的登记({@link dispatchLateByRow} 读出行),以及有登记但回决的 CAS 干净地输(行已有终局,`decideAsk` 带回的那条行)—— 一只 ask 的
@@ -2229,20 +2229,10 @@ export declare class ToolApprovalCoordinator {
2229
2229
  /** 回决收尾(D1 现行为逐字不变的那一半)——session allow-all 记账 + settle + 200 响应体。原 `respond()`
2230
2230
  * 方法体的逐字搬运([ref] 车2 拆分,行为零改动)。 */
2231
2231
  private finishRespond;
2232
- /** [ref]([ref] 案):live pending 的**列表读面**——`GET /v1/approvals` 响应第二顶层键 `livePending`
2233
- * 的唯一数据源,**同时**是 `/v1/approvals/stream` 的 live 半场 diff 源(推与拉必须同源:feed 收到
2234
- * `live_pending` 事件就会去 `list()`,两处各读各的会给出一条列不出来的事件)。纯读投影,零锁/零结算
2235
- * 语义。
2236
- * 🔴 **[ref] 起行上带整只活卡帧**(`frame`,见 {@link LivePendingRow.frame}):旧文那句「input/args
2237
- * 不上列表,详情走流帧」对**悬挂 ask 结构上不成立**(它永远没有流帧),而 `frame` 是 `askBroadcast`
2238
- * 那一处构造的同一个对象 ⇒ 仍然只有**一个**脱敏属主、零第二投影。`scope` 与 durable 面同一个值(checkpoint scope):`undefined` = operator 全量(含 owner null 的
2239
- * 条目),`_`(`CHECKPOINT_PUBLIC_SCOPE`)= 匿名那一组 = owner null 的条目(R7:不带主体的调用方列得出它答得了的那几张),
2240
- * 其余串 = 只见 `owner === scope` 的条目(null-owner 行对具名主体不列,宁少列不超范围)。行的 `approvalId` 就是 `respond()` 收的 id
2241
- * (同源可达,[ref] 判据);`expiresAtMs` 照抄登记时单点铸定的窗死线([ref] 三键同一个数)。 */
2242
2232
  /**
2243
2233
  * 🔴 [ref] —— **起服接管**:把问账里仍 `STREAM_PENDING` 的问接进本审批机的活集合,让 `livePending[]`(及 `/v1/approvals/stream` 的 live 半场、
2244
- * 按问读口、应答口)在重启之后不重开流也看得见、答得了它们。审批机仍是这些读面**唯一**的读源:读问账的只有这里(起服一次),之后列表行由
2245
- * 同一只 {@link livePendingRowOf} 投影,卡帧 = `buildReplayFrame`(开流 preamble 同一只构造)—— 不是 GET 上加一只读表的第二 reader。
2234
+ * 按问读口、应答口)在重启之后不重开流也看得见、答得了它们。审批机仍是这些读面**唯一**的候选源(哪些问在本副本上有登记):扫问账找待决行的只有这里(起服一次),之后列表行由
2235
+ * 同一只 {@link livePendingRowOf} 投影,卡帧 = `buildReplayFrame`(开流 preamble 同一只构造)—— 不是 GET 上按属主扫表的第二 reader;列表面对候选逐只点读行(见 {@link listLivePending}),候选集之外的问它不认识。
2246
2236
  *
2247
2237
  * 律(设计稿 `design-[ref].md` §2):接管登记**没有引擎腿在等它**(铸它的进程没了,或它活在别的副本上),与活登记同一只状态机 ——
2248
2238
  * 应答 = 同一把 `decideAsk` CAS({@link answerRegistration}),收敛 = 同一条悬挂轮询腿读行({@link pollSuspendedDecisions});它活多久只由行说了算,
@@ -2290,7 +2280,26 @@ export declare class ToolApprovalCoordinator {
2290
2280
  }>;
2291
2281
  /** 这只 askId 在本副本上有几条**有引擎腿在等**的登记(接管登记不算)—— 轮询腿的「被唤醒数」读它。 */
2292
2282
  private waitingRegistrationCount;
2293
- listLivePending(scope: string | undefined): LivePendingRow[];
2283
+ /**
2284
+ * [ref]([ref] 案):live pending 的**列表读面** —— `GET /v1/approvals` 响应第二顶层键 `livePending` 的唯一数据源,**同时**是 `/v1/approvals/stream` 的 live 半场 diff 源
2285
+ * (推与拉必须同源:feed 收到 `live_pending` 事件就会去 `list()`,两处各读各的会给出一条列不出来的事件)。纯读投影,零锁 / 零结算语义。
2286
+ * 🔴 **[ref] 起行上带整只活卡帧**(`frame`,见 {@link LivePendingRow.frame}):旧文那句「input/args 不上列表,详情走流帧」对**悬挂 ask 结构上不成立**(它永远没有流帧),
2287
+ * 而 `frame` 是 `askBroadcast` 那一处构造的同一个对象 ⇒ 仍然只有**一个**脱敏属主、零第二投影。
2288
+ * `scope` 与 durable 面同一个值(checkpoint scope):`undefined` = operator 全量(含 owner null 的条目),`_`(`CHECKPOINT_PUBLIC_SCOPE`)= 匿名那一组 = owner null 的条目
2289
+ * (R7:不带主体的调用方列得出它答得了的那几张),其余串 = 只见 `owner === scope` 的条目(null-owner 行对具名主体不列,宁少列不超范围)。
2290
+ * 行的 `approvalId` 就是 `respond()` 收的 id(同源可达,[ref] 判据);`expiresAtMs` 照抄登记时单点铸定的窗死线([ref] 三键同一个数)。
2291
+ *
2292
+ * 🔴 **有行的问,列表只列按问读口会答 `pending` 的**(看不看得见只有一个来源,{@link readApproval} 同一条律):本副本此刻的登记只是**候选**(哪些问在本副本上有登记);
2293
+ * 有行的问,列不列它、列给谁只由店答出的行说了算 —— 对每只候选点读行({@link askRowFollowingOwner},与读口 / 应答口同一只 {@link askRowFor}):行读不出(店抛 / 超时)⇒ 看不见 ⇒ 不列
2294
+ * (与读口的 `404 not_found.ask` 同隐;店恢复后下一次列表即回),行已离开 `STREAM_PENDING`(别处答了 / 收走了,本副本的登记还没闻讯)⇒ 不列(读口答的是它此刻的态),
2295
+ * 行上当下的属主不在 `scope` 内 ⇒ 不列(登记上记下的那一位只是行上属主的读缓存,不替店作答)。没有行的问(问账没上场 / 旧族腿)登记记下的属主是唯一可读的属主事实 ⇒ 照登记列。
2296
+ * 读行并发发起、各自带 {@link DURABLE_CONVERGE_READ_TIMEOUT_MS} 的墙钟 ⇒ 一次列表至多等一个期限;行体的投影取在读完之后、对每个列出的 wire 身份重取此刻代表它的那条登记
2297
+ * ({@link liveEntryFor}):读行期间已结算的不列,读行期间被活登记接替的接管登记按活登记的样子列。
2298
+ * 读行的次数 = 本副本此刻**有行的不同 ask 数**(重复登记共用一次读,没有行的问不读),**不按 `scope` 先筛**(登记上的属主只是读缓存,不替店判谁看得见 —— scope 之外的卡也要读一次行才判得出);
2299
+ * 登记数的上界是每个任务 / 每个属主各一个未决帽(`STREAM_APPROVAL_ADMIT_MAX_PER_TASK` / `_PER_OWNER`)加起服接管上限 {@link ADOPT_OPEN_ASKS_MAX},本副本的总数没有全局帽。
2300
+ * 列表行 ⊆ 按问读口对同一调用方答 `pending` 的那些;反过来不然 —— `scope` 比读口窄:具名主体的列表不含无主的卡(宁少列),运维列表按 `?owner=` / 全量列、含读口对运维不放行的卡。
2301
+ */
2302
+ listLivePending(scope: string | undefined): Promise<LivePendingRow[]>;
2294
2303
  /**
2295
2304
  * [ref]:某只委派子代此刻有没有**待决**的活卡 —— fleet 对账腿「子代活性由属主说了算」的属主②读口(另一只是
2296
2305
  * bg registry 账)。子代卡在一张没人答的卡上时当然不出帧,只看「静默」就会把它当孤儿扫下面板(报案的真形)。