@sema-agent/server 7.132.0 → 7.134.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/MIGRATION.md +353 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +301 -64
  5. package/deploy/sema-up/README.md +35 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
  11. package/deploy/sema-up/chart/templates/server.yaml +19 -2
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/deploy/sema-up/stack/compose.yaml +3 -0
  15. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  16. package/dist/adoption/plan.d.ts +3 -2
  17. package/dist/adoption/plan.js +7 -5
  18. package/dist/adoption/runner.js +3 -10
  19. package/dist/adoption/sql.d.ts +3 -2
  20. package/dist/adoption/sql.js +3 -5
  21. package/dist/adoption/wire.d.ts +4 -1
  22. package/dist/adoption/wire.js +1 -0
  23. package/dist/approval-ask-audit-store.d.ts +32 -14
  24. package/dist/approval-ask-audit-store.js +272 -74
  25. package/dist/approval-ask-machine.d.ts +15 -0
  26. package/dist/approval-ask-machine.js +6 -0
  27. package/dist/approval-ask-retention.d.ts +136 -0
  28. package/dist/approval-ask-retention.js +102 -0
  29. package/dist/approval-card.d.ts +83 -23
  30. package/dist/approval-card.js +45 -15
  31. package/dist/approval-content-kind.d.ts +5 -2
  32. package/dist/approval-content-kind.js +16 -3
  33. package/dist/approval-deny-reasons.d.ts +1 -1
  34. package/dist/approval-gate-currency.d.ts +72 -0
  35. package/dist/approval-gate-currency.js +94 -0
  36. package/dist/approval.d.ts +15 -0
  37. package/dist/approval.js +55 -17
  38. package/dist/audit.d.ts +27 -10
  39. package/dist/audit.js +12 -16
  40. package/dist/bake-runner/main.js +3 -2
  41. package/dist/boot/coordinators.d.ts +6 -1
  42. package/dist/boot/coordinators.js +6 -3
  43. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  44. package/dist/boot/execution-env.js +9 -7
  45. package/dist/boot/execution-lane.js +11 -0
  46. package/dist/boot/leader.d.ts +2 -0
  47. package/dist/boot/leader.js +4 -1
  48. package/dist/boot/memory-boundary.js +2 -2
  49. package/dist/boot/memory-consolidation.d.ts +5 -4
  50. package/dist/boot/memory-consolidation.js +7 -6
  51. package/dist/boot/org-delivery.d.ts +28 -0
  52. package/dist/boot/org-delivery.js +20 -0
  53. package/dist/boot/read-deny-anchor-audit.js +2 -2
  54. package/dist/boot/reapers.d.ts +3 -0
  55. package/dist/boot/reapers.js +21 -1
  56. package/dist/boot/resolve-spec.d.ts +3 -0
  57. package/dist/boot/resolve-spec.js +60 -81
  58. package/dist/boot/runner-deps.d.ts +18 -5
  59. package/dist/boot/runner-deps.js +10 -0
  60. package/dist/boot/session-faces.d.ts +1 -0
  61. package/dist/boot/session-faces.js +4 -2
  62. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  63. package/dist/boot/stage-06-runners.d.ts +6 -3
  64. package/dist/boot/stage-06-runners.js +20 -4
  65. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  66. package/dist/boot/stage-07-capability-layer.js +24 -3
  67. package/dist/boot/stage-08-reapers.d.ts +4 -1
  68. package/dist/boot/stage-08-reapers.js +2 -2
  69. package/dist/boot/stage-09-leader.d.ts +5 -1
  70. package/dist/boot/stage-09-leader.js +2 -2
  71. package/dist/boot/stage-10-http-server.d.ts +5 -1
  72. package/dist/boot/stage-10-http-server.js +6 -6
  73. package/dist/boot/stores.d.ts +8 -0
  74. package/dist/boot/stores.js +10 -14
  75. package/dist/boot/web-admin.d.ts +10 -0
  76. package/dist/boot/web-admin.js +162 -65
  77. package/dist/boot/workflow-orchestration.d.ts +2 -0
  78. package/dist/boot/workflow-orchestration.js +2 -1
  79. package/dist/brain.js +8 -3
  80. package/dist/breaker-key.d.ts +6 -0
  81. package/dist/breaker-key.js +29 -0
  82. package/dist/budget.js +5 -1
  83. package/dist/caller-text-echo.d.ts +11 -6
  84. package/dist/caller-text-echo.js +10 -12
  85. package/dist/canonical-json.d.ts +2 -41
  86. package/dist/canonical-json.js +2 -13
  87. package/dist/capabilities/center-plugins.d.ts +7 -0
  88. package/dist/capabilities/center-plugins.js +1 -1
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +21 -0
  93. package/dist/capabilities/hands-lane.js +10 -0
  94. package/dist/capabilities/mcp-probe.d.ts +36 -4
  95. package/dist/capabilities/mcp-probe.js +29 -6
  96. package/dist/capabilities/scenarios.d.ts +63 -7
  97. package/dist/capabilities/scenarios.js +39 -7
  98. package/dist/capability-facts.d.ts +36 -4
  99. package/dist/capability-facts.js +30 -4
  100. package/dist/center-config-tier.d.ts +69 -0
  101. package/dist/center-config-tier.js +42 -0
  102. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  103. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  104. package/dist/checkpoint-identity.d.ts +16 -0
  105. package/dist/checkpoint-identity.js +19 -0
  106. package/dist/config-catalog.d.ts +17 -10
  107. package/dist/config-catalog.js +43 -28
  108. package/dist/config-d-migration.d.ts +3 -1
  109. package/dist/config-d-migration.js +2 -2
  110. package/dist/config-dir-trust.d.ts +114 -0
  111. package/dist/config-dir-trust.js +388 -0
  112. package/dist/config-invariants.d.ts +18 -5
  113. package/dist/config-invariants.js +35 -3
  114. package/dist/config-provider.d.ts +6 -1
  115. package/dist/config-provider.js +6 -2
  116. package/dist/config-types.d.ts +71 -14
  117. package/dist/config-types.js +8 -0
  118. package/dist/config.d.ts +13 -0
  119. package/dist/config.js +121 -59
  120. package/dist/delegated-session-owner.d.ts +185 -0
  121. package/dist/delegated-session-owner.js +119 -0
  122. package/dist/device-protocol.d.ts +5 -3
  123. package/dist/device-protocol.js +1 -1
  124. package/dist/device-ws-hub.js +21 -2
  125. package/dist/device-ws-protocol.d.ts +70 -6
  126. package/dist/device-ws-protocol.js +50 -23
  127. package/dist/elicitation.js +3 -2
  128. package/dist/entry-problems.d.ts +34 -0
  129. package/dist/entry-problems.js +14 -0
  130. package/dist/execution-lane-caps.d.ts +49 -10
  131. package/dist/execution-lane-caps.js +43 -4
  132. package/dist/field-conflict.d.ts +44 -0
  133. package/dist/field-conflict.js +21 -0
  134. package/dist/file-history-disclosure.d.ts +34 -5
  135. package/dist/file-history-disclosure.js +2 -2
  136. package/dist/fleet/fleet-bus.d.ts +84 -6
  137. package/dist/fleet/fleet-bus.js +42 -9
  138. package/dist/hooks/classic-stations.d.ts +10 -5
  139. package/dist/hooks/classic-stations.js +4 -4
  140. package/dist/hooks/command-spawn.d.ts +57 -0
  141. package/dist/hooks/command-spawn.js +139 -0
  142. package/dist/hooks/hook-llm.js +2 -2
  143. package/dist/hooks/hook-runner.d.ts +127 -25
  144. package/dist/hooks/hook-runner.js +668 -287
  145. package/dist/hooks/hook-source.d.ts +44 -0
  146. package/dist/hooks/hook-source.js +40 -0
  147. package/dist/http/active-run-conflict.d.ts +5 -13
  148. package/dist/http/active-run-conflict.js +17 -27
  149. package/dist/http/admission.js +111 -60
  150. package/dist/http/approval-sweeps.js +58 -19
  151. package/dist/http/caller-trust.d.ts +77 -0
  152. package/dist/http/caller-trust.js +143 -0
  153. package/dist/http/checkpoint-ctx.d.ts +173 -18
  154. package/dist/http/checkpoint-ctx.js +171 -12
  155. package/dist/http/claimed-run.d.ts +4 -3
  156. package/dist/http/device-placement.d.ts +2 -4
  157. package/dist/http/device-placement.js +2 -1
  158. package/dist/http/dispatch.js +13 -7
  159. package/dist/http/durable-run-leg.d.ts +4 -32
  160. package/dist/http/durable-run-leg.js +37 -12
  161. package/dist/http/idempotency.d.ts +2 -2
  162. package/dist/http/idempotency.js +2 -2
  163. package/dist/http/owner-access.d.ts +56 -0
  164. package/dist/http/owner-access.js +42 -0
  165. package/dist/http/principal-gate.d.ts +78 -27
  166. package/dist/http/principal-gate.js +64 -14
  167. package/dist/http/readiness.d.ts +11 -5
  168. package/dist/http/readiness.js +10 -3
  169. package/dist/http/refusal-body.d.ts +12 -0
  170. package/dist/http/refusal-body.js +11 -0
  171. package/dist/http/request-guards.d.ts +16 -32
  172. package/dist/http/request-guards.js +31 -30
  173. package/dist/http/resume-ctx-read.d.ts +50 -6
  174. package/dist/http/resume-ctx-read.js +33 -7
  175. package/dist/http/resume-legs.d.ts +5 -5
  176. package/dist/http/resume-legs.js +163 -91
  177. package/dist/http/retired-service-deps.d.ts +43 -0
  178. package/dist/http/retired-service-deps.js +18 -0
  179. package/dist/http/route-ctx.d.ts +44 -37
  180. package/dist/http/route-ctx.js +4 -0
  181. package/dist/http/route-table.js +2 -0
  182. package/dist/http/routes/a2a-serve.js +3 -4
  183. package/dist/http/routes/admin-config-refresh.js +1 -1
  184. package/dist/http/routes/admin-drain.js +1 -1
  185. package/dist/http/routes/admin-memory-optout.js +5 -1
  186. package/dist/http/routes/adoption.js +2 -9
  187. package/dist/http/routes/agents-roster.js +2 -3
  188. package/dist/http/routes/approvals-assistant.js +91 -56
  189. package/dist/http/routes/background.js +3 -2
  190. package/dist/http/routes/capabilities.js +20 -4
  191. package/dist/http/routes/config-catalog.d.ts +3 -3
  192. package/dist/http/routes/config-catalog.js +1 -1
  193. package/dist/http/routes/devices.js +3 -17
  194. package/dist/http/routes/diagnostics.d.ts +3 -3
  195. package/dist/http/routes/diagnostics.js +6 -2
  196. package/dist/http/routes/fleet.js +4 -4
  197. package/dist/http/routes/images.js +6 -7
  198. package/dist/http/routes/leader.js +1 -8
  199. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  200. package/dist/http/routes/mcp-reconnect.js +3 -2
  201. package/dist/http/routes/memory-bundle.js +1 -1
  202. package/dist/http/routes/memory-compliance.js +1 -1
  203. package/dist/http/routes/memory-consolidation.js +1 -1
  204. package/dist/http/routes/memory-origin.d.ts +1 -1
  205. package/dist/http/routes/memory-origin.js +1 -1
  206. package/dist/http/routes/memory-policy.d.ts +1 -1
  207. package/dist/http/routes/memory-policy.js +3 -2
  208. package/dist/http/routes/notify-wake.js +8 -21
  209. package/dist/http/routes/observability.js +2 -2
  210. package/dist/http/routes/principal-inbox.d.ts +39 -0
  211. package/dist/http/routes/principal-inbox.js +76 -0
  212. package/dist/http/routes/retention-ops.js +2 -9
  213. package/dist/http/routes/rules.js +9 -22
  214. package/dist/http/routes/runs.d.ts +5 -0
  215. package/dist/http/routes/runs.js +63 -115
  216. package/dist/http/routes/session-sync.d.ts +3 -2
  217. package/dist/http/routes/session-sync.js +53 -48
  218. package/dist/http/routes/sessions-list.d.ts +1 -1
  219. package/dist/http/routes/sessions-list.js +3 -4
  220. package/dist/http/routes/sessions.js +33 -43
  221. package/dist/http/routes/side-query.js +6 -4
  222. package/dist/http/routes/tasks.js +71 -30
  223. package/dist/http/routes/trace-usage.js +7 -9
  224. package/dist/http/routes/workflows.d.ts +351 -0
  225. package/dist/http/routes/workflows.js +153 -119
  226. package/dist/http/run-declared-families.d.ts +16 -0
  227. package/dist/http/run-declared-families.js +12 -0
  228. package/dist/http/send.d.ts +24 -3
  229. package/dist/http/send.js +14 -2
  230. package/dist/http/server.d.ts +23 -18
  231. package/dist/http/server.js +20 -15
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +4 -3
  234. package/dist/http/submit-ctx.js +23 -6
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +17 -10
  238. package/dist/index.d.ts +3 -1
  239. package/dist/index.js +1 -1
  240. package/dist/lane-home-probe.d.ts +78 -9
  241. package/dist/lane-home-probe.js +78 -12
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/leader/wire.d.ts +4 -0
  245. package/dist/leader/wire.js +8 -7
  246. package/dist/limit-refusal.d.ts +17 -5
  247. package/dist/limit-refusal.js +4 -1
  248. package/dist/main.js +1 -1
  249. package/dist/mcp-assertion-header.d.ts +31 -10
  250. package/dist/mcp-assertion-header.js +10 -3
  251. package/dist/memory-origin-fence.js +2 -2
  252. package/dist/memory-project-layer.d.ts +37 -0
  253. package/dist/memory-project-layer.js +46 -0
  254. package/dist/memory-scope.d.ts +23 -16
  255. package/dist/memory-scope.js +24 -8
  256. package/dist/memory-sync-client.d.ts +27 -13
  257. package/dist/memory-sync-client.js +107 -18
  258. package/dist/model-compat.d.ts +1 -1
  259. package/dist/model-entry-refusal.d.ts +9 -1
  260. package/dist/model-entry-refusal.js +6 -1
  261. package/dist/model-plane-face.d.ts +51 -0
  262. package/dist/model-plane-face.js +24 -0
  263. package/dist/model-provider.d.ts +5 -0
  264. package/dist/model-provider.js +4 -2
  265. package/dist/model-route-endpoint.d.ts +8 -11
  266. package/dist/model-route-endpoint.js +4 -7
  267. package/dist/model-route-env.d.ts +22 -0
  268. package/dist/model-route-env.js +2 -0
  269. package/dist/model-route-gap.d.ts +60 -30
  270. package/dist/model-route-gap.js +21 -15
  271. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  272. package/dist/observability/corrupt-read-seat.js +9 -0
  273. package/dist/observability/err-text.d.ts +6 -0
  274. package/dist/observability/err-text.js +18 -4
  275. package/dist/observability/fail-open.d.ts +35 -9
  276. package/dist/observability/fail-open.js +35 -9
  277. package/dist/observability/metrics.js +1 -0
  278. package/dist/observability/prompt-manifest.d.ts +22 -25
  279. package/dist/observability/prompt-manifest.js +54 -50
  280. package/dist/observability/tool-trace.js +9 -10
  281. package/dist/operator-ask.d.ts +10 -0
  282. package/dist/operator-ask.js +3 -0
  283. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  284. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  285. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  286. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  287. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  288. package/dist/orchestration/workflow-notify-journal.js +27 -34
  289. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  290. package/dist/orchestration/workflow-park-decision.js +119 -0
  291. package/dist/org-delivery-gate.d.ts +81 -0
  292. package/dist/org-delivery-gate.js +59 -0
  293. package/dist/panel-tool-names.d.ts +23 -0
  294. package/dist/panel-tool-names.js +8 -0
  295. package/dist/parked-decide.d.ts +43 -11
  296. package/dist/parked-decide.js +100 -51
  297. package/dist/parked-revive-surface.d.ts +9 -2
  298. package/dist/parked-revive-surface.js +11 -8
  299. package/dist/permission-rule-list.d.ts +1 -1
  300. package/dist/permission-rule-list.js +2 -2
  301. package/dist/permission-rule-vocab.d.ts +1 -23
  302. package/dist/permission-rule-vocab.js +0 -13
  303. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  304. package/dist/plugins/approval-ask-store-file.js +21 -0
  305. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  306. package/dist/plugins/approval-ask-store-memory.js +34 -2
  307. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  308. package/dist/plugins/approval-ask-store-sql.js +37 -1
  309. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  310. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  311. package/dist/plugins/blob-backend.d.ts +38 -25
  312. package/dist/plugins/blob-backend.js +29 -19
  313. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  314. package/dist/plugins/breaker-state-sql.js +4 -4
  315. package/dist/plugins/caching-session-store.d.ts +4 -1
  316. package/dist/plugins/caching-session-store.js +7 -3
  317. package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
  318. package/dist/plugins/checkpoint-store-sql.js +65 -3
  319. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  320. package/dist/plugins/file-history-store-sql.js +3 -1
  321. package/dist/plugins/file-run-store.d.ts +5 -13
  322. package/dist/plugins/file-run-store.js +9 -0
  323. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  324. package/dist/plugins/fork-routing-session-store.js +12 -1
  325. package/dist/plugins/host-platform.d.ts +2 -0
  326. package/dist/plugins/host-platform.js +2 -1
  327. package/dist/plugins/local-checkpoint-store.d.ts +15 -2
  328. package/dist/plugins/local-checkpoint-store.js +32 -1
  329. package/dist/plugins/local-session-store.d.ts +13 -10
  330. package/dist/plugins/local-session-store.js +23 -14
  331. package/dist/plugins/local-session-window.d.ts +45 -0
  332. package/dist/plugins/local-session-window.js +38 -0
  333. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  334. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  335. package/dist/plugins/mailbox-store-sql.js +77 -52
  336. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  337. package/dist/plugins/memory-run-store.d.ts +5 -13
  338. package/dist/plugins/memory-run-store.js +8 -0
  339. package/dist/plugins/one-time-migrations.d.ts +121 -5
  340. package/dist/plugins/one-time-migrations.js +332 -8
  341. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  342. package/dist/plugins/org-delivery-quota-store.js +228 -0
  343. package/dist/plugins/permission-rule-store-file.js +10 -6
  344. package/dist/plugins/permission-rule-store-sql.js +8 -8
  345. package/dist/plugins/pg-pool.js +39 -7
  346. package/dist/plugins/pg-session-storage.d.ts +18 -5
  347. package/dist/plugins/pg-session-storage.js +68 -23
  348. package/dist/plugins/remote-env-adb.d.ts +6 -12
  349. package/dist/plugins/remote-env-adb.js +12 -2
  350. package/dist/plugins/remote-env-device.d.ts +14 -7
  351. package/dist/plugins/remote-env-device.js +23 -15
  352. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  353. package/dist/plugins/remote-env-k8s.js +23 -5
  354. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  355. package/dist/plugins/remote-env-local-docker.js +12 -9
  356. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  357. package/dist/plugins/remote-env-ssh.js +17 -11
  358. package/dist/plugins/run-store-sql.d.ts +16 -14
  359. package/dist/plugins/run-store-sql.js +22 -2
  360. package/dist/plugins/schema-indexes.js +2 -0
  361. package/dist/plugins/send-user-file.js +2 -2
  362. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  363. package/dist/plugins/session-epoch-anchor.js +2 -3
  364. package/dist/plugins/session-ownership.d.ts +11 -0
  365. package/dist/plugins/session-ownership.js +11 -0
  366. package/dist/plugins/session-placement.d.ts +12 -14
  367. package/dist/plugins/session-placement.js +2 -15
  368. package/dist/plugins/session-store.d.ts +18 -8
  369. package/dist/plugins/session-store.js +15 -4
  370. package/dist/plugins/sql-driver.d.ts +74 -11
  371. package/dist/plugins/sql-driver.js +210 -12
  372. package/dist/plugins/sql-errors.d.ts +23 -0
  373. package/dist/plugins/sql-errors.js +21 -0
  374. package/dist/plugins/store-backend.d.ts +36 -1
  375. package/dist/plugins/store-backend.js +40 -14
  376. package/dist/plugins/store-contracts.d.ts +42 -0
  377. package/dist/plugins/store-contracts.js +1 -0
  378. package/dist/plugins/tidb-pool.d.ts +6 -1
  379. package/dist/plugins/tidb-pool.js +44 -10
  380. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  381. package/dist/plugins/tidb-session-storage.js +2 -2
  382. package/dist/plugins/tidb-session-store.d.ts +25 -5
  383. package/dist/plugins/tidb-session-store.js +67 -21
  384. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  385. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  386. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  387. package/dist/plugins/workflow-run-store-sql.js +50 -9
  388. package/dist/posture-source.d.ts +18 -10
  389. package/dist/posture-source.js +4 -1
  390. package/dist/project-identity.d.ts +45 -6
  391. package/dist/project-identity.js +162 -8
  392. package/dist/project-layer-key.d.ts +28 -0
  393. package/dist/project-layer-key.js +29 -0
  394. package/dist/question.js +3 -2
  395. package/dist/read-deny-entry.d.ts +25 -0
  396. package/dist/read-deny-entry.js +12 -0
  397. package/dist/read-face-posture.d.ts +37 -11
  398. package/dist/read-face-posture.js +32 -3
  399. package/dist/request-key-closure.d.ts +7 -0
  400. package/dist/request-key-closure.js +9 -1
  401. package/dist/request-tool-axes.d.ts +12 -0
  402. package/dist/request-tool-axes.js +20 -0
  403. package/dist/request-value-closure.d.ts +5 -0
  404. package/dist/request-value-closure.js +11 -3
  405. package/dist/rule-entry-list.d.ts +26 -2
  406. package/dist/rule-entry-list.js +72 -12
  407. package/dist/rules-consent.js +3 -4
  408. package/dist/run-acceptance.d.ts +19 -3
  409. package/dist/run-acceptance.js +13 -1
  410. package/dist/run-local.js +37 -6
  411. package/dist/runs.d.ts +12 -10
  412. package/dist/runs.js +25 -6
  413. package/dist/runtime-caps-resolver.d.ts +16 -6
  414. package/dist/runtime-caps-resolver.js +18 -5
  415. package/dist/sandbox-pkg-source.d.ts +19 -1
  416. package/dist/sandbox-pkg-source.js +29 -7
  417. package/dist/sealed-key.d.ts +32 -0
  418. package/dist/sealed-key.js +55 -1
  419. package/dist/security.d.ts +95 -15
  420. package/dist/security.js +52 -9
  421. package/dist/session-error-wire.d.ts +31 -7
  422. package/dist/session-error-wire.js +9 -2
  423. package/dist/session-sync-kernel.d.ts +37 -10
  424. package/dist/session-sync-kernel.js +10 -0
  425. package/dist/session-titled-frame.d.ts +33 -0
  426. package/dist/session-titled-frame.js +4 -0
  427. package/dist/session-titler.d.ts +9 -1
  428. package/dist/session-titler.js +15 -4
  429. package/dist/spec-fields.js +21 -2
  430. package/dist/sql-engine-posture.d.ts +3 -1
  431. package/dist/task-a2a.js +4 -3
  432. package/dist/task-cwd.d.ts +1 -1
  433. package/dist/task-mcp.d.ts +5 -5
  434. package/dist/task-mcp.js +27 -74
  435. package/dist/task-settings.d.ts +93 -88
  436. package/dist/task-settings.js +71 -63
  437. package/dist/text-bidi.d.ts +0 -4
  438. package/dist/text-bidi.js +1 -3
  439. package/dist/tighten-only-seats.d.ts +150 -0
  440. package/dist/tighten-only-seats.js +196 -0
  441. package/dist/tool-approval.d.ts +451 -136
  442. package/dist/tool-approval.js +733 -256
  443. package/dist/tool-rule-names.d.ts +6 -0
  444. package/dist/trace/core-keyset-guard.d.ts +108 -25
  445. package/dist/trace/exit-seat.d.ts +40 -0
  446. package/dist/trace/exit-seat.js +130 -0
  447. package/dist/trace/ledger-events.d.ts +6 -3
  448. package/dist/trace/project.d.ts +98 -13
  449. package/dist/trace/project.js +57 -32
  450. package/dist/trace/projection-table.d.ts +100 -0
  451. package/dist/trace/projection-table.js +130 -0
  452. package/dist/trace/redact.d.ts +57 -0
  453. package/dist/trace/redact.js +962 -168
  454. package/dist/trace/self-minted-wire.d.ts +349 -1
  455. package/dist/trace/self-minted-wire.js +118 -1
  456. package/dist/trace/wire-projection-faces.d.ts +304 -2
  457. package/dist/trace/wire-projection-faces.js +160 -13
  458. package/dist/url-refusal.js +2 -0
  459. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  460. package/dist/web-admin-client/apply-effective.js +56 -5
  461. package/dist/web-admin-client/facade.d.ts +1 -1
  462. package/dist/web-admin-client/facade.js +1 -1
  463. package/dist/web-admin-client/read-face.js +5 -9
  464. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  465. package/dist/web-admin-client/skills-mcp.js +6 -8
  466. package/dist/web-admin-client/types.d.ts +1 -1
  467. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  468. package/package.json +8 -4
  469. package/scripts/drain-check-local.mjs +34 -2
  470. package/scripts/drain-check.mysql.sql +20 -2
  471. package/scripts/drain-check.pg.sql +20 -2
  472. package/dist/mcp-tool-faces.d.ts +0 -69
  473. package/dist/mcp-tool-faces.js +0 -106
@@ -50,7 +50,7 @@
50
50
  * — same posture as question/elicit. The frame's model-authored surfaces (message + args) are secret-REDACTED
51
51
  * before they are streamed; the SIZE bound is per-surface: args ride a byte cap (`MAX_APPROVAL_ARGS_BYTES`,
52
52
  * over-cap ⇒ `argsOmitted`), while the legacy frame's `message` is redacted but NOT length-capped — the char
53
- * cap (`MAX_MESSAGE`, approval-card.ts `clip`) lives on the card/`approval_request` projection only (same
53
+ * cap (`MAX_MESSAGE`, approval-card.ts `capText`) lives on the card/`approval_request` projection only (same
54
54
  * redact-at-write contract as question; the args are shown to a human,
55
55
  * never re-fed to a model). No throttle (unlike question): an approval breach-default would be a DENY (task failure),
56
56
  * and asks are turn-blocking by construction — the TTL bounds the human-side exposure instead.
@@ -60,7 +60,8 @@ import { type ApprovalDecidedBy, type HostSettledBy, type RetiredDecisionKeyFact
60
60
  import type { IncomingMessage } from "node:http";
61
61
  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 } from "@sema-agent/core";
62
62
  import { type CardRulePersisted, type RuleConsentLane } from "./rules-consent.js";
63
- import { type AllowRuleShadowProjection, type DenialLimitFallback, type RuleOffersAbsence, type ApprovalRequestFrame, type ApprovalRevokeFrame, type RuleEvidenceProjection } from "./approval-card.js";
63
+ import type { GateCurrencyStore } from "./approval-gate-currency.js";
64
+ import { type AllowRuleShadowProjection, type DenialLimitFallback, type RuleOffersAbsence, type ApprovalRequestFrame, type ApprovalRevokeFrame, type ApprovalCardLegFrame, type ApprovalCompleteFrame, type RuleEvidenceProjection } from "./approval-card.js";
64
65
  import { type ApprovalAskStore, type AskRow } from "./plugins/approval-ask-store-sql.js";
65
66
  import type { ApprovalAskAuditSink } from "./approval-ask-audit-store.js";
66
67
  import { type AskRowEndingCause, type SettleCause, type SettleOutcome } from "./approval-deny-reasons.js";
@@ -83,6 +84,17 @@ export declare function isApprovalGateKind(k: string | undefined): k is Approval
83
84
  export declare function denySweepOwns(gate: ParkedGateFace | undefined): boolean;
84
85
  /** 两方言同形的 SQL IN 片段(值为闭集常量字面,无注入面)。 */
85
86
  export declare const APPROVAL_GATE_KINDS_SQL_IN: string;
87
+ /** {@link ToolApprovalCoordinator.adoptOpenAsks} 的读数(装配点进启动日志)。 */
88
+ interface OpenAskAdoption {
89
+ /** 本次接管进活集合的问数。 */
90
+ readonly adopted: number;
91
+ /** 本副本已有这只问的登记(活登记或先前接管过)而跳过的问数 —— 幂等的那一半。 */
92
+ readonly alreadyLive: number;
93
+ /** 行上卡信封读不出(唯一信封读者不认)而没接管的问数 —— 列不出卡就不列(开流 preamble 跳坏行同判)。 */
94
+ readonly cardUnreadable: number;
95
+ /** 待决行多于 {@link ADOPT_OPEN_ASKS_MAX}:只接管了最先的那么多只。 */
96
+ readonly capped: boolean;
97
+ }
86
98
  /**
87
99
  * 耐久回决口 `POST /v1/approvals/:sessionId/decide` 的路径串 —— S-1280:迟到回决口 PARKING 臂 202 体的机读指路 `decidePath`。
88
100
  * 路由表那一行(`http/routes/approvals-assistant.ts` 的 `approval-decide`)按 pattern 匹配它;两者同形由往返钉守
@@ -94,12 +106,45 @@ export declare function approvalDecidePath(sessionId: string): string;
94
106
  * DECIDED/PARKED 已从 404 分流(DECIDED ⇒ 200 回放首决,回执带 `decidedBy`,**不是**成因;PARKED ⇒ 赎回席),残余两类:
95
107
  * · 行 `VOID` / `DENIED`(没有人决过它)—— `cause` = **行上记的那个成因词**(问账 `denied_reason` 列;与决断口 410 `gone.ask` 体的 `cause`、审计 settle 行
96
108
  * 的 `cause` 同一个词,闭集 {@link SettleCause});行上没写归因(存量行)⇒ 缺席,不替没写的行编一个词;
97
- * · {@link NOT_PENDING_UNKNOWN_CAUSE} —— 无墓碑 / 无行 / 行仍在别处活着:换副本或换端点重试才有意义(这个词只属于 404 面,不是结局成因)。
109
+ * · {@link NOT_PENDING_UNKNOWN_CAUSE} —— 无行 / 行不是调用方的 / 行仍在别处活着:换副本或换端点重试才有意义(这个词只属于 404 面,不是结局成因)。
98
110
  * 对齐 [ref] 反枚举语义:cause 只在**已过属主门**的面上出,不扩枚举面(属主门不过 = 与未知 id 同形)。
99
111
  * **无持久店的部署上恒不带**:那台机器压根没有行可判,编一个 cause 是撒谎(D1 体逐字不变)。
100
112
  */
101
113
  export declare const NOT_PENDING_UNKNOWN_CAUSE: "unknown_or_other_replica";
102
114
  export type NotPendingCause = AskRowEndingCause | typeof NOT_PENDING_UNKNOWN_CAUSE;
115
+ /**
116
+ * `GET /v1/tool-approvals/:approvalId` 应答体 `state` 的**闭集**(一只 ask 此刻在哪一态;读法与应答口逐条同源):
117
+ * · `pending` —— 本副本上有在等它的活登记(应答口此刻收得下);
118
+ * · `decided` —— 行 `DECIDED`(有人 / 有策略决过;回执三键同晚答回放体),**或**行 `PARKED` 而它的门已被决(S-1915:checkpoint 已结算,见 {@link ParkedGateReading});
119
+ * · `parked` —— 行 `PARKING`,或行 `PARKED` 且门仍是该会话当前待决的审批门(转后台候批;应答口走迟到受理,耐久回决口照收);
120
+ * · `void` —— 行 `DENIED` / `VOID`(没有人决过它,答案无处兑现;`cause` 同晚答 404),**或**行 `PARKED` 而它的门已过期 / 被取代(含停驻 run 被取消;此时 `cause` 缺席)。
121
+ */
122
+ export declare const TOOL_APPROVAL_READ_STATES: readonly ["pending", "decided", "parked", "void"];
123
+ export type ToolApprovalReadState = (typeof TOOL_APPROVAL_READ_STATES)[number];
124
+ /** 行 → 读口的行投影:键名是列表面 {@link LivePendingRow} 的同名子集(一个读者一套键);`frame` = 断连重放的那一只呈卡帧(卡读不出 ⇒ 缺席)。 */
125
+ export interface AskRowReadProjection {
126
+ approvalId: string;
127
+ ts: number;
128
+ expiresAtMs: number;
129
+ sessionId?: string;
130
+ toolName?: string;
131
+ frame?: ApprovalRequestFrame;
132
+ }
133
+ /** `GET /v1/tool-approvals/:approvalId` 的 200 体:列表面同一只行投影 + `state` + 各态附键。 */
134
+ export type ToolApprovalReadBody = ({
135
+ state: "pending";
136
+ } & LivePendingRow) | ({
137
+ state: "decided";
138
+ decision: "allow" | "deny";
139
+ decidedAtMs: number;
140
+ decisionNote?: string;
141
+ } & AskRowReadProjection) | ({
142
+ state: "parked";
143
+ decidePath?: string;
144
+ } & AskRowReadProjection) | ({
145
+ state: "void";
146
+ cause?: AskRowEndingCause;
147
+ } & AskRowReadProjection);
103
148
  /**
104
149
  * 结算一张卡的**判决** —— 判别联合,逼每个调用点说清「这次等待是怎么结束的」:
105
150
  * · `by:"human"` —— 一次**决议**到了(人答,或从问账行读回来的决议,含部署政策拒落成的 `DECIDED` 行,`hostSettledBy` 记它的来源词):`allowed` 说方向;审计 settle 行
@@ -140,6 +185,9 @@ export type SettleVerdict = {
140
185
  *
141
186
  * 语义边界(禁扩读):它答的是「本副本此刻有没有活体消费者」,**不是**「这条 run 还活着吗」——持有
142
187
  * 悬挂 promise 的可能是另一个副本(F4 的轮询腿会在它自己的下一拍续跑)。run 的生死读 run 面。
188
+ *
189
+ * S-247 起**同一个词、同一句语义**也出现在 live 面:审批机起服时从问账接管的登记(没有引擎腿在等)在 `livePending` 行上带它,
190
+ * 在 live 应答口的 200 回执上按同一判据(本副本被唤醒的等待腿数 = 0)带它。一个事实,各面一个读法。
143
191
  */
144
192
  export declare const ASK_DECISION_CONSUMER_ABSENT = "absent";
145
193
  /**
@@ -179,6 +227,37 @@ export type ParkedAskRedeem = (req: ParkedAskRedeemRequest) => Promise<{
179
227
  status: number;
180
228
  body: Record<string, unknown>;
181
229
  }>;
230
+ /**
231
+ * 按问读口对一张 `PARKED` 卡的**门读法**(S-1915;判官的唯一属主 = `approval-gate-currency.ts`,协调器本身不认识 checkpoint 的形):
232
+ * · `open` —— 这张卡的门仍是该会话当前待决的审批门(应答口收得下)⇒ 读口说 `parked`;
233
+ * · `decided` —— 门已被决:方向 / 时刻 / 理由取自 checkpoint 上的结算赢家 ⇒ 读口说 `decided`;
234
+ * · `void` —— 门已过期 / 被取代(含停驻 run 被取消:取消先把门 expire)⇒ 读口说 `void`(没有人决过它,答案无处兑现);
235
+ * · `unknown` —— 说不出可信的话:`row_absent` = checkpoint 行没了;`decision_unreadable` = 门已结算却读不出可用的决议(行的 status 词或结算种类不在闭集表里 / 结算记录过不了 core 的
236
+ * 门记录筛 / 方向或时刻读不出)⇒ 读口答 404 `tool_approval.not_pending`(坏行不包装成首决;应答口并不同判:它的 PARKED 臂只对 checkpoint 行没了答 404,已结算的门答 409 `approval_stale`),
237
+ * 并记一行 error:`defects` 是读不出的那几处(非空),日志带首句 + 计数。
238
+ */
239
+ export type ParkedGateReading = {
240
+ readonly kind: "open";
241
+ } | {
242
+ readonly kind: "decided";
243
+ readonly decision: "allow" | "deny";
244
+ readonly decidedAtMs: number;
245
+ readonly decisionNote?: string;
246
+ } | {
247
+ readonly kind: "void";
248
+ } | {
249
+ readonly kind: "unknown";
250
+ readonly why: "row_absent";
251
+ } | {
252
+ readonly kind: "unknown";
253
+ readonly why: "decision_unreadable";
254
+ readonly defects: readonly [string, ...string[]];
255
+ };
256
+ /** 门读席:入参 = 问账行上的 gate 坐标(PARKED 行恒带 `gateToken`)。读不出(店抛错)⇒ 抛,协调器按店故障姿势处置(见 `readParkedGate`)。 */
257
+ export type ParkedGateRead = (row: {
258
+ readonly gateToken: string;
259
+ readonly gateBoundCallId: string | null;
260
+ }) => Promise<ParkedGateReading>;
182
261
  /** 阶梯里**重发**一把 claim 的墙钟上限(ms;首把用 `DURABLE_CALL_TIMEOUT_MS`)。🔴 codex 交叉复审 C5
183
262
  * (2026-08-06 真缺陷):只数重试次数是**不够**的 —— 次数只约束「已经返回或已经 reject 的调用」,一次
184
263
  * **挂住不返回**的店调用(DB 连接黑洞、池饿死)会让整个退避循环连一格都走不完,`onAsk` 的 promise 于是永久
@@ -315,7 +394,9 @@ export declare function parkRowStandingAnswerFacts(stored: Extract<PendingAction
315
394
  deploymentListAsks: boolean): StandingAnswerFacts;
316
395
  /** A live approval frame delivered to whoever tails this run's stream. `type` IS the SSE event name (named-event
317
396
  * convention, same as question). The shell renders `tool_approval` as the CC three-choice card and dismisses on
318
- * `tool_approval_complete`. */
397
+ * `tool_approval_complete`.
398
+ * 🔴 **旧族**:只投给呈卡协议未上场的腿(一条腿一个帧族,见 {@link ToolApprovalRunContext});呈卡腿上同一次铸定的这只对象仍是
399
+ * 卡外开卡事实的来源(`ApprovalRequestLiveFacts` 取自它)与 `livePending` 行的 `frame`。 */
319
400
  export interface ToolApprovalFrame {
320
401
  type: "tool_approval" | "tool_approval_complete";
321
402
  approvalId: string;
@@ -539,7 +620,7 @@ export interface ToolApprovalFrame {
539
620
  * `approval_request` 帧([ref] 呈卡帧)同名同义:`expiresAtMs` = 本 ask 的绝对到期墙钟
540
621
  * (有店=行上一次铸定的 `expiresAtMs`,与卡帧/落库同值;无店 D1=注册时刻算定的同名初值),
541
622
  * `serverNowMs` = **帧铸造时刻**(cli [ref] 锚定语义:倒计时锚=帧到手时刻的服务器钟),
542
- * `expiresInMs` = `max(0, expiresAtMs - serverNowMs)` 现算。三键同生同缺(windowZero 腿不发帧,
623
+ * `expiresInMs` = `max(0, expiresAtMs - serverNowMs)` 现算。三键同生同缺(没有活审批通道的腿不发帧,
543
624
  * 发出的帧恒带);旧消费端无感,新壳借此给旧族帧补倒计时([ref] Q2 那类 77 分钟死卡的根治半场)。 */
544
625
  expiresAtMs?: number;
545
626
  expiresInMs?: number;
@@ -684,10 +765,8 @@ export interface ToolApprovalFrame {
684
765
  * 真才带)——`outcome:"expired"` 一词三义(park / 当场 deny / 无设施 deny,见 outcome 注)里 **park
685
766
  * 那一义的显式判别位**:在场 ⇔ **这条 ask 本身**按 park 路由收尾(`parkRouted`,settle 咽喉里置位;
686
767
  * [ref] F1/F3:首版读政策口〔unattendedPolicy+askStore 在场〕,对批内被连坐 VOID 的兄弟、取消/断连、
687
- * D5 fail-open 等非 park 终局全撒谎)。⚠️ **判据是路由,不是墓碑**([ref] 起 `recordParkTombstone`
688
- * 在两种容量拒新形下不落墓碑,置位与落墓碑可不同步;取舍全文见 settle 咽喉那段注):常态墓碑同拍
689
- * 已落 ⇒ 同一把 `approvalId` 仍可打 `respond` 走迟到受理兑现(wire 契约迟到受理段);拒新两形下
690
- * live 迟到腿如实 404(unknown_or_other_replica),壳按既有协议回落 durable gate([ref] Q3)。
768
+ * D5 fail-open 等非 park 终局全撒谎)。同一把 `approvalId`(= 行的键)仍可打 `respond` 走迟到受理兑现
769
+ * (wire 契约迟到受理段;迟到腿直接读行,任一副本可达)。
691
770
  * 壳据此把「卡失效」改渲「已转后台候批」。缺席**禁**读作
692
771
  * 「真 deny」:无店部署 / deny 政策 / VOID 兄弟都发不出这个键,缺席只是「无 park 证据」。 */
693
772
  parked?: true;
@@ -720,7 +799,7 @@ export interface ToolApprovalFrame {
720
799
  * ——两族行形与决议路由不同:本族行的决议口=`POST /v1/tool-approvals/:approvalId/respond`,durable 行
721
800
  * =decide 口;数组名即路由判据)。可选位全部「只记真、缺席不编」。 */
722
801
  export interface LivePendingRow {
723
- /** = `respond()` 收的 wire id(pending Map 的 uuidv7 键;同源可达)。 */
802
+ /** = `respond()` / `GET /v1/tool-approvals/:id` 收的 wire id:有行的 ask = 行的键 `askId`,无行的 ask = 登记本地键(见 {@link PendingApproval.approvalId})。 */
724
803
  approvalId: string;
725
804
  toolName: string;
726
805
  /** 登记时刻(ms epoch)。 */
@@ -772,24 +851,48 @@ export interface LivePendingRow {
772
851
  * (规则集不因 `suspended` 分叉:有活流的 ask 多带一份它自己那张卡的副本无害)。
773
852
  *
774
853
  * 缺席 = 老 server(7.86.0 及以前);本服务自 7.87.0 起**恒在场**(条目上是必填格)。恒不铸 `null`。
854
+ *
855
+ * 🔴 **一只 ask 一个帧族(7.133.0 起)**:呈卡族的 ask(有行 —— 呈卡协议上场的 worker)⇒ 呈卡帧 `approval_request`(卡内事实在 `card` 里,
856
+ * 卡外的活面事实在帧顶层);旧族的 ask(无行)⇒ 活卡帧 `tool_approval`。按 `frame.type` 判别。
775
857
  */
776
- frame?: ToolApprovalFrame;
858
+ frame?: ToolApprovalFrame | ApprovalRequestFrame;
859
+ /**
860
+ * S-247:**本副本上没有引擎腿在等这只问** —— 与耐久决断口 200 体同名同值同义的那一位({@link ASK_DECISION_CONSUMER_ABSENT})。
861
+ * 在场 ⇔ 这一行是审批机起服时从问账接管的问(前一个进程 / 别的副本铸下、行仍 `STREAM_PENDING`;见 {@link ToolApprovalCoordinator.adoptOpenAsks}):
862
+ * 它照常列得出、照常应答得了(行落 `DECIDED`,应答回执同带这一位),但这一决不会让本副本上任何在跑的东西续跑 —— 续没续跑读 run 面。
863
+ * 只记真:缺席 = 本副本有引擎腿在等它(或老 server)。
864
+ */
865
+ consumerState?: typeof ASK_DECISION_CONSUMER_ABSENT;
777
866
  }
778
- export interface ToolApprovalRunContext {
779
- taskId: string;
780
- sessionId?: string;
781
- owner: string | null;
867
+ /**
868
+ * 一条执行腿的审批上下文 = 腿的身份三位 + 腿轴 + **恰一个帧族的投递口**。
869
+ *
870
+ * 🔴 **一条腿一个帧族**({@link ApprovalLegFamilyPorts}):呈卡协议在本腿上场(装配点按 `resolveApprovalLeg(...).active` 接
871
+ * `emitCard`)⇒ 本腿上一只 ask 的开卡 / 消卡 / 撤卡只走呈卡族(`approval_request` / `approval_complete` / `approval_revoke`),
872
+ * 旧族帧一帧不发;协议未上场 ⇒ 只走旧族(`tool_approval` / `tool_approval_complete`,经 `emit`)。两族的口在类型上互斥,
873
+ * 「同一只 ask 在同一条腿上发两种开卡帧」不可构造。消费方在 wire 上判别本腿是哪一族:`GET /v1/capabilities` 的 `streamApproval`
874
+ * (与装配点同一只判据 `resolveStreamApprovalGate`,按 worker 求值;为真 ⇒ 本 worker 每条呈卡的腿都是呈卡族)。
875
+ */
876
+ export type ToolApprovalRunContext = ToolApprovalRunContextBase & ApprovalLegFamilyPorts;
877
+ /** 帧族投递口的二选一(见 {@link ToolApprovalRunContext} 顶注)。 */
878
+ export type ApprovalLegFamilyPorts = LegacyApprovalFamilyPorts | CardApprovalFamilyPorts;
879
+ /** 旧族腿(呈卡协议未上场):开卡 `tool_approval` 与消卡 `tool_approval_complete` 都经 `emit`。 */
880
+ export interface LegacyApprovalFamilyPorts {
782
881
  emit: (frame: ToolApprovalFrame) => void | Promise<void>;
882
+ emitCard?: never;
883
+ emitRevoke?: never;
884
+ }
885
+ /** 呈卡族腿(呈卡协议上场):开卡 / 消卡经 `emitCard`,批级撤卡经 `emitRevoke`。 */
886
+ export interface CardApprovalFamilyPorts {
887
+ emit?: never;
783
888
  /**
784
889
  * [ref] 车6:**批级撤卡帧**(`approval_revoke`,语义与发射面见 approval-card.ts 的
785
890
  * `ApprovalRevokeFrame` 顶注 —— [ref] 起 bg/resume durable 腿的钩子写本腿账本,sync 腿仍 live)
786
891
  * 的投递口。
787
892
  *
788
- * 🔴 为什么是**独立的可选钩子**而不是给 `emit` 的入参加宽:`emit` 是既有 `tool_approval` 活卡腿的
789
- * 通道,它的消费方(装配点 + 全部存量帧断言面)今天只认那两种帧;把入参改成联合会强迫每一个消费点
790
- * 立刻处理一个它还不认识的帧形(存量测试的 `ToolApprovalFrame[]` 收集器首当其冲)。撤卡帧属于**新
791
- * 协议**(`approval_request` 族)的一员,消费方是新壳 —— 分口投递是诚实的分层,装配点(车3 3b /
792
- * 车4 域)可以与 `approval_request` 的发射点**同批**接上。
893
+ * 与 {@link CardApprovalFamilyPorts.emitCard} 分口的理由是**失败语义**不同:开卡帧的投递结果参与「卡送到人手上没有」的判定
894
+ * (零 sink 接下 ⇒ 抛 ⇒ park 路由),撤卡帧是通知、行才是真源(失败由 `emitRevokeTo` 的 catch 如实吞);且 sync 腿的撤卡帧
895
+ * 刻意维持 live 单口(detach 账本撤帧是另一件行为面变更)。
793
896
  *
794
897
  * 缺席 ⇒ 本连接不收撤卡帧;壳侧的结构补偿恒是重连 preamble 的全量对账基准。
795
898
  * (接线现状:[ref] 起三腿全接 —— sync 腿 live 口(`routes/tasks.ts`),bg/resume 两腿 durable
@@ -797,19 +900,22 @@ export interface ToolApprovalRunContext {
797
900
  */
798
901
  emitRevoke?: (frame: ApprovalRevokeFrame) => void | Promise<void>;
799
902
  /**
800
- * [ref] 车3 刀 3b:**呈卡帧**(`approval_request`,[ref] §3.1)的投递口。
903
+ * 呈卡族的**单卡帧**投递口:开卡帧(`approval_request`,[ref] §3.1)与消卡帧(`approval_complete`)。
801
904
  *
802
- * 🔴 与 {@link ToolApprovalRunContext.emitRevoke} 同一条理由(见其顶注):新协议族的帧走**独立的可选
803
- * 钩子**,不把 `emit` 的入参加宽成联合 —— `emit` 是既有 `tool_approval` 活卡腿的通道,它的全部消费点
804
- * (三条装配腿 + 每一个存量 `ToolApprovalFrame[]` 收集器)今天只认那两种帧,加宽会强迫它们立刻处理一个
805
- * 还不认识的帧形。设计稿 §4.3(a)「新帧同走 `emitApproval`、不新增出口」讲的是**投递面**(同一条 SSE /
806
- * 同一条 durable tail),不是同一个 TS 字段:三条装配腿都把本钩子接到与 `emit` **同一个**写出口上,
807
- * 于是 wire 上确实是一条面、两种帧。
905
+ * 三条装配腿都把它接到本腿的投递面(sync 腿 live SSE + detach 车道账本,bg / resume 腿本腿账本;双 sink 的成败判定在唯一
906
+ * 属主 `createApprovalCardEmitter`)—— 卡帧在哪,消卡帧就在哪。开卡帧只在 `askId` **确认落盘**时铸(设计稿 §2.2(b) 硬条款一:
907
+ * 无持久身份不发帧);本腿没有旧族兜底 ⇒ 身份没落盘的 ask 在呈卡腿上**呈不出卡**,按无人可答收场(协调器 `askBroadcast`)。
808
908
  *
809
- * 缺席 ⇒ 本连接不收呈卡帧(旧壳照常靠 `tool_approval` 工作);`askId` 未确认落盘时**也不发**
810
- * (设计稿 §2.2(b) 硬条款一:无持久身份不发新帧)。发射序锚定在 `tool_approval` **之后**(§4.2)。
909
+ * 第二参 `registration` = 协调器这一次**登记**的本地 id(每次注册各一个,同一只 ask 的重复登记各不相同):同一次登记的开卡帧与消卡帧
910
+ * 带同一个值,投递口据它把开与合配对(帧上的 askId / approvalId 在重复登记之间相同,配不了对)。它不上 wire。
811
911
  */
812
- emitCard?: (frame: ApprovalRequestFrame) => void | Promise<void>;
912
+ emitCard: (frame: ApprovalCardLegFrame, registration: string) => void | Promise<void>;
913
+ }
914
+ /** 两族共有的腿身份与腿轴。 */
915
+ interface ToolApprovalRunContextBase {
916
+ taskId: string;
917
+ sessionId?: string;
918
+ owner: string | null;
813
919
  abortSignal?: AbortSignal;
814
920
  /** [ref]([ref] §3.1 askId 派生的腿轴;车3 刀 3a 换轴:原 `leg?: number` → `legKey?: string`)。
815
921
  * = `sha256(resume checkpoint token)` 的 hex,**首腿缺席折空串**(空串是首腿的真值,不是「未知」)。
@@ -895,9 +1001,20 @@ export declare const PERSIST_RULE_BATCH_EXCLUSIVE_ERROR = "persistRule.batchOffe
895
1001
  /** S-720(core 7.32.0 #1093)—— `readRootGrant` 只随 `decision:"allow"`(CC 卡的第三选项「Yes, and add directory」= 放行这一次
896
1002
  * + 加目录;`allow_session` 不是那一个选项,`deny` 上它没有意义)。裁决之前响亮拒,不静默丢。 */
897
1003
  export declare const READ_ROOT_GRANT_ALLOW_ONLY = "readRootGrant is only meaningful with decision \"allow\" \u2014 it is the card's \"Yes, and add directory\" answer (allow this call and add the card's readRootCandidate.dir to this run's read directories)";
1004
+ /**
1005
+ * S-765:这台部署不受理读根授权时,带 `readRootGrant` 的应答的拒句。受理与否是**部署姿态**(能力事实 `readRootGrant`,位 `approvalReadRootGrant`;
1006
+ * 判据的唯一属主在 `capability-facts.ts`,回决路由把它读来交给 {@link ToolApprovalCoordinator.respond}):不受理 ⇒ 裁决**之前**响亮 400,
1007
+ * 这只 ask 没被结算,同一张卡不带该键的 `allow` 照常成。不静默丢键 —— 壳以为加上了目录而引擎只看到一次普通放行,是 S-720 修过的那一种病。
1008
+ */
1009
+ export declare const READ_ROOT_GRANT_NOT_ACCEPTED = "readRootGrant is not accepted on this deployment \u2014 a read-directory grant is honored only on a single-user host-lane deployment (GET /v1/capabilities approvalReadRootGrant is false here); answer with plain decision \"allow\" instead";
898
1010
  /** S-720:`readRootGrant` 的形 —— 卡上 `readRootCandidate.dir` 的原串(非空,≤ core `READ_ROOT_CANDIDATE_DIR_MAX`;超限整只拒,不截:截过的目录是另一个目录)。 */
899
1011
  export declare const READ_ROOT_GRANT_SHAPE = "readRootGrant must be the card's readRootCandidate.dir sent back byte for byte \u2014 a non-empty string of at most 1024 characters";
900
1012
  export declare const PERSIST_RULE_SCOPE_REFUSED = "this endpoint does not accept a rule scope \u2014 the server mints it from where the approval happened (send neither `scope` nor `persistRule.scope`)";
1013
+ /** S-765:`respond()` 要的**部署事实**(由回决路由从能力事实交进;协调器不读 config,也不自判姿态)。 */
1014
+ export interface ToolApprovalRespondDeployment {
1015
+ /** 这台部署受理不受理应答体里的 `readRootGrant` —— 能力事实 `readRootGrant` 的 `.available`(位 `approvalReadRootGrant` 的同一个值)。 */
1016
+ readonly readRootGrantAccepted: boolean;
1017
+ }
901
1018
  /** {@link parseToolApprovalResponse} 的成功分支形(`respond()` 拆分出的私有收尾方法复用,避免裸内联匿名类型重复三处)。 */
902
1019
  type ParsedToolApproval = {
903
1020
  ok: true;
@@ -993,16 +1110,17 @@ export type SessionGrantStore = Pick<ApprovalExemptionStore, "has" | "grant">;
993
1110
  * `StoreBackend.approvalAsk()` 的接口契约上(那条注 + `wiring-governance-operator.test.ts` 的三腿机器钉)——
994
1111
  * 它是**装配面**的事实,而本谓词能看见的只有 `kind`,拿 `kind` 当持久性的代理正是这次要拆掉的那层间接。
995
1112
  */
996
- export type StreamApprovalGate = {
1113
+ export type StreamApprovalGate<TStore extends GateCurrencyStore = GateCurrencyStore> = {
997
1114
  active: true;
998
1115
  askStore: ApprovalAskStore;
1116
+ checkpointStore: TStore;
999
1117
  } | {
1000
1118
  active: false;
1001
1119
  reason: "no_tool_approval" | "protocol_disabled" | "no_backend" | "no_park_facility";
1002
1120
  };
1003
1121
  /** {@link resolveStreamApprovalGate} 的入参。`backend` 用**结构形**(不 import `StoreBackend`):本模块是
1004
1122
  * 协调器的家,不该为一个布尔判据把整棵 store 依赖树拖进类型面。 */
1005
- export interface StreamApprovalGateInput {
1123
+ export interface StreamApprovalGateInput<TStore extends GateCurrencyStore = GateCurrencyStore> {
1006
1124
  toolApprovalEnabled: boolean;
1007
1125
  /** 协议总开关。⚠️ 调用点一律写 `config.streamApproval?.enabled === true` —— **可选链的缺席臂折算
1008
1126
  * false**(段整段缺席 ⇒ 协议不上场)。
@@ -1016,14 +1134,86 @@ export interface StreamApprovalGateInput {
1016
1134
  readonly kind: "mysql" | "pg" | "local";
1017
1135
  approvalAsk(): ApprovalAskStore;
1018
1136
  } | undefined;
1019
- /** park 设施在场性。本仓真码里 `checkpointStore` 的构造条件本身就是
1020
- * `backend?.checkpoint !== undefined && config.durableApproval`(main.ts),所以设计 §8.4 那条析取式的
1137
+ /** park 设施 = checkpoint 店本身:在场(非 `undefined`)即设施在场,上场时它随 `active` 臂交出去(与 `askStore` 同形)—— 在场性与实例是一个事实,调用点不必另持一份布尔再断言实例非空。
1138
+ * 类型只收店的形({@link GateCurrencyStore}:协调器读它的那两个口),`backend.checkpoint` 这种工厂方法过不了 tsc —— 全进程的店只有 stage-06 铸的那一只,装配点喂的是它,不是再造一只。
1139
+ * 本仓真码里 `checkpointStore` 的构造条件本身就是
1140
+ * `backend?.checkpoint !== undefined && config.durableApproval`,所以设计 §8.4 那条析取式的
1021
1141
  * 「safety 词表非空」一支在**装配时刻**结构上不可达(core 的 irreversible/egress 集合来自 **per-task**
1022
1142
  * 的 `spec.tools[].irreversibility/egress`,composition root 看不到)——两条缺失形因此在本仓收敛成
1023
1143
  * 同一个 `no_park_facility`(D-5/D-6 两钉打的是两种**输入**形,不是两个 reason)。 */
1024
- parkFacility: boolean;
1144
+ checkpointStore: TStore | undefined;
1145
+ }
1146
+ export declare function resolveStreamApprovalGate<TStore extends GateCurrencyStore>(input: StreamApprovalGateInput<TStore>): StreamApprovalGate<TStore>;
1147
+ /**
1148
+ * 审批开卡帧的**帧族词表**(闭集)—— wire 上一只 ask 的开卡帧可能属于的族:
1149
+ * · `tool_approval`:旧族(活卡帧 `tool_approval` / 消卡帧 `tool_approval_complete`);
1150
+ * · `approval_request`:呈卡族(开卡帧 `approval_request` / 消卡帧 `approval_complete` / 批级撤卡帧 `approval_revoke`)。
1151
+ *
1152
+ * 一条腿选哪个族只由上面 {@link resolveStreamApprovalGate} 的 `active` 定(为真 ⇒ 接呈卡族的口 `emitCard` / `emitRevoke`;为假 ⇒ 只接旧族的口 `emit`,
1153
+ * 见 {@link ToolApprovalRunContext});`GET /v1/capabilities` 的 `approvalFrameFamilies` 把**同一份**判据结果(能力事实 `streamApproval` 的那一次求值)
1154
+ * 译成本词表里的词(`capability-facts.ts` 的 `approvalFrameFamilies`,对判据拒因的穷举 switch:拒因多一个 ⇒ 编译红)。
1155
+ * 腿选口的规则与能力位的映射是同一条,由 `test/stream-approval-on-e2e.test.ts` 在同一台 worker 上拿真腿发出的开卡帧族对拍能力位,不靠注释互相提醒。
1156
+ * 词表只有这一份(元组即类型);加一族而没有逐处跟进 ⇒ `test/capability-facts.test.ts` 的 `satisfies Record<ApprovalFrameFamily, true>` 编译红。
1157
+ */
1158
+ export declare const APPROVAL_FRAME_FAMILIES: readonly ["tool_approval", "approval_request"];
1159
+ export type ApprovalFrameFamily = (typeof APPROVAL_FRAME_FAMILIES)[number];
1160
+ /**
1161
+ * 这台 worker **呈卡用的那一个族**(活卡协调器在场时)—— 全仓唯一的映射,两个读者:能力位 `approvalFrameFamilies`(`capability-facts.ts`,
1162
+ * 壳读它决定声明什么)与 {@link resolveApprovalLeg}(腿判「这条 run 声明了没有」)。两处各写一份三元式 = 壳照一份声明、服务端照另一份判,
1163
+ * 那正是 S-1914 要封的「两边各说各话」。入参 = {@link resolveStreamApprovalGate} 的 `active`。
1164
+ */
1165
+ export declare function presentedApprovalFrameFamily(streamApprovalOn: boolean): ApprovalFrameFamily;
1166
+ /** 坏声明的拒体(fresh 受理面 400 `request.field_invalid`):一句话 + 机读位,形与 S-1351 座位族 / S-904 三桶的 `bad_entry` 同。 */
1167
+ export interface ApprovalFrameFamiliesIssue {
1168
+ readonly message: string;
1169
+ readonly fields: {
1170
+ readonly field: "settings.approvalFrameFamilies";
1171
+ readonly reason: "bad_entry";
1172
+ readonly index?: number;
1173
+ };
1174
+ }
1175
+ /**
1176
+ * S-1914 —— 请求面声明 `settings.approvalFrameFamilies` 的**唯一判官**:这条 run 的客户端渲染得了哪些审批开卡帧族。
1177
+ * 合法 = 数组,每项是 {@link APPROVAL_FRAME_FAMILIES} 里的词、各出现一次(空数组合法 = 一个族都不渲染,与缺席同读)。非数组 / 词表外 / 重复 ⇒ 拒体点名坐标。
1178
+ * 两个读者:fresh 受理门(`http/admission.ts`,400)与宽容读者 {@link declaredApprovalFrameFamilies}(续跑重放读存体)。入参是 `body.settings`
1179
+ * 本身(非对象 / 缺席 ⇒ 本判官不判,留给 `settings` 自己的形门)。拒句不回显调用方的字节,只报坐标与词表。
1180
+ */
1181
+ export declare function approvalFrameFamiliesIssue(settings: unknown): ApprovalFrameFamiliesIssue | null;
1182
+ /**
1183
+ * S-1914 —— 一条 run 声明的帧族集合(三条执行腿读的**唯一**读者;读的是这条 run 的请求体 `settings`:sync = 本次请求、bg = 受理过的提交体、
1184
+ * resume / wake = 持久化体 —— 声明随体重放,不另存)。缺席 ⇒ 空集。判官说不合法 ⇒ 空集:只有绕过受理门的存体走得到这一形,
1185
+ * 空集 = 这条腿没有活审批通道(问当场交无人值守政策口)—— 失效方向是不呈卡,不是猜一个族去呈。
1186
+ */
1187
+ export declare function declaredApprovalFrameFamilies(settings: unknown): ReadonlySet<ApprovalFrameFamily>;
1188
+ /** 一条腿**没有活审批通道**的成因(见 {@link ApprovalLegAssembly.unattended});`frame_family_undeclared` 带上缺的那个族。 */
1189
+ export type LegUnattended = {
1190
+ readonly arm: "window_zero";
1191
+ } | {
1192
+ readonly arm: "frame_family_undeclared";
1193
+ readonly family: ApprovalFrameFamily;
1194
+ };
1195
+ /** {@link resolveApprovalLeg} 的入参(sync / bg / resume 三腿 + 开流 preamble 共用一份形)。 */
1196
+ export interface ApprovalLegInput {
1197
+ /** = `resolveStreamApprovalGate(...).active`(协议在本 worker 上场没有)。 */
1198
+ streamApprovalOn: boolean;
1199
+ /** `config.streamApproval.windowMs`(`STREAM_ASK_WINDOW_MS`)。
1200
+ * 🔴 [ref]:`undefined` = **这份装配没有 `streamApproval` 段**(只出现在只填被测键的 stub-harness ——
1201
+ * 真实 boot 无条件铸该段,见 `config.ts`)。此前三个调用点各写 `?? 0` 把这一形折成「0」,在旧语义下
1202
+ * 是死代码(`windowZero` 那时挂在 `streamApprovalOn` 后面,协议关就恒 false);[ref] 让 `0` 在协议关的
1203
+ * 腿上也真生效之后,那个折算会把一台**什么都没配**的 harness 判成「运维显式关窗」。故本字段收成
1204
+ * `number | undefined`,由每个调用点如实交出「有没有这个值」,不许再就地编一个。 */
1205
+ windowMs: number | undefined;
1206
+ /** `config.streamAskWindowMarginMs`(`STREAM_ASK_WINDOW_MARGIN_MS`)。 */
1207
+ windowMarginMs: number;
1208
+ /** `spec.limits.maxWalltimeMs`。缺席 = 没有 walltime 墙 ⇒ 第三源不参与(**缺席 ≠ 0**)。 */
1209
+ legWalltimeMs?: number;
1210
+ /** 本腿**开始执行的时刻**的 `performance.now()`。取值点绝不能挪到腿启动之后:误差方向必须是
1211
+ * 「窗偏短」(安全侧,§7.3 的误差方向论证)。 */
1212
+ nowMonotonicMs: number;
1213
+ /** S-1914:这条 run 声明的帧族(唯一读者 {@link declaredApprovalFrameFamilies},读本 run 的请求体 / 存体)。必填 —— 漏传的装配点编译红,
1214
+ * 不许有「没传 ⇒ 当作声明了」的默认。 */
1215
+ declaredFamilies: ReadonlySet<ApprovalFrameFamily>;
1025
1216
  }
1026
- export declare function resolveStreamApprovalGate(input: StreamApprovalGateInput): StreamApprovalGate;
1027
1217
  /**
1028
1218
  * [ref] 车3 刀 3b —— **一条执行腿的审批装配裁定**(sync / bg / resume **三腿共用**)。
1029
1219
  *
@@ -1042,14 +1232,19 @@ export declare function resolveStreamApprovalGate(input: StreamApprovalGateInput
1042
1232
  * `prepare-task.js` 的 durableMandate/contentMandate 与 durableQuestionFace 等),
1043
1233
  * 故不在本函数内。
1044
1234
  *
1045
- * 🔴 **[ref](半接线旋钮族)**:`windowZero` 的第一源(`STREAM_ASK_WINDOW_MS=0`)自此**不再挂在
1235
+ * 🔴 **[ref](半接线旋钮族)**:关窗的第一源(`STREAM_ASK_WINDOW_MS=0`)自此**不再挂在
1046
1236
  * `streamApprovalOn` 后面** —— 那是部署级旋钮,它的语义不该因为这台机器有没有 durable ask 账而改变
1047
- * (`ApprovalLegAssembly.windowZero` 顶注写了那条病)。第三源(贴 deadline)照旧只在协议上场时参与。
1237
+ * (`ApprovalLegAssembly.unattended` 顶注写了那条病)。第三源(贴 deadline)照旧只在协议上场时参与。
1048
1238
  *
1049
- * **`windowZero` 的两件事必须同时做**(调用方契约):不包 ALS **且**注入 immediate-unavailable 闭包。
1050
- * 只做一件另一条路仍会呈卡。⚠️ [ref] 起**三腿都有** per-task `spec.onAsk` 装配点(sync=routes/tasks.ts,
1051
- * bg=runs.ts,resume=server.ts driveResumeLeg),windowZero 的第二件在三腿都是显式闭包 —— 旧文「bg/
1052
- * resume 无装配点,不包 ALS 即等价」的缺席论证已退役,别再据它推断「少装一件也行」。
1239
+ * 🔴 **S-1914**:「这条腿有没有活审批通道」多一个成因 —— 这条 run 没声明本 worker 呈卡用的族。它与关窗是**同一件事**(不呈卡、问当场交政策口),
1240
+ * 所以进同一个字段(`unattended` 的成因词),三条腿零新分支;判据读 {@link presentedApprovalFrameFamily}(能力位读同一只)。
1241
+ * 判据**不**放进 {@link resolveStreamApprovalGate}:那是 worker 级谓词(协调器注入 / 能力位 / 回决 501 都没有 run),且它为假时腿退回旧族 `emit` ——
1242
+ * 正是「回退发 `tool_approval`」。
1243
+ *
1244
+ * **没有活审批通道的两件事必须同时做**(调用方契约):不包 ALS **且** `spec.onAsk` = {@link ToolApprovalCoordinator.boundUnattendedAsk}(带成因)。
1245
+ * 只做一件另一条路仍会呈卡(ALS 腿是 `deps.onAsk` 的到达路;不包 ALS 也让这条腿不进 broker 活流集合 = 不是别的腿的卡的投递目标)。
1246
+ * ⚠️ [ref] 起**三腿都有** per-task `spec.onAsk` 装配点(sync=routes/tasks.ts,bg=runs.ts,resume=http/resume-legs.ts),第二件在三腿都是显式闭包 ——
1247
+ * 旧文「bg/resume 无装配点,不包 ALS 即等价」的缺席论证已退役,别再据它推断「少装一件也行」。
1053
1248
  */
1054
1249
  export interface ApprovalLegAssembly {
1055
1250
  /** 协议在本腿上是否上场。false ⇒ **既不包 ALS、也不接** `emitCard`/`emitRevoke`/`legKey`/
@@ -1059,57 +1254,54 @@ export interface ApprovalLegAssembly {
1059
1254
  * 同 (owner, session) 活流呈活卡(sync 腿 [ref] 起本就如此;bg/resume 的这条行为差 = [ref] CHANGELOG
1060
1255
  * 披露的行为面变更)。旧文「本腿逐字保持协议之前的行为」只对协议件成立,别再把它读成「协议关 = 零呈卡」。 */
1061
1256
  active: boolean;
1062
- /** §8.3 窗=0 恒 park。
1063
- * 🔴 **[ref] 起它与 `active` 解耦**(旧文「`active` 为假时恒 false —— 协议都没上场,谈不上关窗」已
1064
- * 作废):`STREAM_ASK_WINDOW_MS` 是**部署级**旋钮,`0` 的语义(运维显式关窗 ⇒ 恒走
1065
- * {@link ToolApprovalCoordinator.unattendedAskOutcome},连卡都不发)在两条车道上必须是同一个意思。
1066
- * 旧形下 local 车道(S-384 之前的「账不持久」臂)/ 无 park 设施 / 显式关协议的部署配了 `0`,拿到的是一张
1067
- * 等满 5min 的活卡 —— 与它自己的域注正好相反,且没有任何一行说出来。
1068
- * ⚠️ 「窗**缺席**」(`windowMs: undefined` = 这份装配根本没有 streamApproval 段,只出现在 stub-harness)
1069
- * **不是**关窗:那时逐字保持活卡腿。 */
1070
- windowZero: boolean;
1071
- /** §7.3 本 leg 的 walltime deadline(`performance.now()` 单调基)。只在 `active ∧ ¬windowZero ∧
1257
+ /** **这条腿没有活审批通道**(在场 ⇒ 不包 ALS、不是任何卡的投递目标、`spec.onAsk` 是 {@link ToolApprovalCoordinator.boundUnattendedAsk}
1258
+ * 席 —— 每只问当场交无人值守政策口,臂 = 本值)。缺席 ⇒ 这条腿按 {@link presentedApprovalFrameFamily} 的族呈卡。成因闭集两个,先后即判序:
1259
+ * · `window_zero`(§8.3)—— 运维关窗(`STREAM_ASK_WINDOW_MS=0`),或协议上场时本腿剩余 walltime 撑不住安全余量。
1260
+ * 🔴 [ref] 起与 `active` 解耦:`0` 是**部署级**旋钮,在两条车道上是同一个意思(旧形下关协议的部署配了 `0` 拿到的是等满 5min 的活卡)。
1261
+ * ⚠️ 「窗**缺席**」(`windowMs: undefined` = 这份装配根本没有 streamApproval 段,只出现在 stub-harness)**不是**关窗。
1262
+ * 排在声明之前:那时谁都不呈卡,缺的不是客户端的声明。
1263
+ * · `frame_family_undeclared`(S-1914)—— 这条 run 的请求没有声明本 worker 呈卡用的族(`settings.approvalFrameFamilies`)。判据对两个族同一条:
1264
+ * 不回退发另一族、不双发、没有「键缺席 ⇒ 视作旧族」的默认。
1265
+ * 三条腿只问「在场没有」,成因随席交给唯一铸点(遥测臂 + deny 政策的拒因句)。 */
1266
+ unattended?: LegUnattended;
1267
+ /** §7.3 本 leg 的 walltime deadline(`performance.now()` 单调基)。只在 `active ∧ 有活审批通道 ∧
1072
1268
  * 有 walltime 墙` 时在场 —— 关着时供值会把既有 5min 活卡窗按三元公式缩短(§7.2 真行为变更)。 */
1073
1269
  legDeadlineMonotonic?: number;
1074
1270
  }
1075
1271
  /**
1076
- * [ref] 车3 刀 3b(codex 交叉复审 round2 R2-1,2026-08-06 真 finding)—— 呈卡帧的**双写投递口**。
1272
+ * [ref] 车3 刀 3b(codex 交叉复审 round2 R2-1,2026-08-06 真 finding)—— 呈卡腿的**双 sink 投递口**(开卡帧 + 消卡帧)。
1273
+ *
1274
+ * 🔴 为什么必须收成一个有属主的工厂:「呈卡帧送达」决定「卡到底有没有送到人手上」(见 `emitOne` 顶注;S-1683 起呈卡腿只有这一族)。
1275
+ * sync 腿原来那个内联闭包把两个 sink 的失败都吞掉、然后**正常返回** —— 于是「账本写失败 ∧ socket 已死」这种**真的一路都没送到**的
1276
+ * 情形被上报成成功,`anySucceeded` 因此压住了 park 路由。诚实的形只有一个:**至少一个 sink 真的接下了才算送达**,一个都没接下就抛 ——
1277
+ * 调用点(`emitOne`)的 catch 会把它如实记成没送到。
1077
1278
  *
1078
- * 🔴 为什么必须收成一个有属主的工厂:round1 之后「新帧送达」开始**参与**「卡到底有没有送到人手上」的
1079
- * 判定(见 `emitOne` 顶注)。而 sync 腿原来那个内联闭包把两个 sink 的失败都吞掉、然后**正常返回** ——
1080
- * 于是「账本写失败 ∧ socket 已死」这种**真的一路都没送到**的情形被上报成成功,`anySucceeded` 因此压住了
1081
- * park 路由,ask 会一直挂到窗到期而**没有任何人可能回答它**。诚实的形只有一个:**至少一个 sink 真的接下
1082
- * 了才算送达**,一个都没接下就抛 —— 调用点(`emitOne`)的 catch 会把它如实记成 `card: false`。
1279
+ * 🔴 **两只 sink 各自推进、各自配对**(S-1683 codex 一轮 F1 / F2,红先钉在 `test/approval-leg-frame-family.test.ts`):
1280
+ * · 开卡帧同时交两只 sink,**任一只接下即算送达**(不按序串行 —— 旧族退场后 live 面只剩呈卡族这一条路,一只挂住的账本写不能挡住
1281
+ * 健康的 live 出口;修前先 await 账本再写 live)。两只都失败才抛。
1282
+ * · 消卡帧只交给**接下过本卡开卡帧**的那只 sink,且排在该 sink 自己的开卡写之后(每只 sink 内开在合前;没接下开卡的 sink 不收消卡 =
1283
+ * 不留孤儿消卡行)。没有任何 sink 接下过开卡 ⇒ 不投(调用点本就只对送达过开卡的连接发消卡)。
1284
+ * · 配对按**登记**记(第二参 `registration` = 协调器那一次登记的本地 id;codex 修复验证轮 V1:按 askId 先进先出会让第二次登记的消卡取走
1285
+ * 第一次失败 / 挂起的开卡记录)。开卡全失败的登记当场清账(它不会有消卡);消卡取走即清;挂住的开卡留账到本腿闭包结束。
1083
1286
  *
1084
- * 顺序 = **先账本后 live**(与 file_link 的先例相反,理由是本帧的用武之地恰好在 live 面已死的时候):
1085
- * detach 断连后 live 写被丢弃,而壳换道 events tail 必须还能看到这张未决卡(§4.3(c) 的案A)。
1287
+ * detach 车道的用武之地仍是「live 面已死、账本还在」(§4.3(c) 的案A):那一形里 live 抛、账本接下 ⇒ 送达;消卡只进账本。
1086
1288
  *
1087
- * 命名(CLAUDE.md 工厂命名律):`create*` —— 返回的是**捕获了两个 sink 的闭包**,不是纯数据。
1289
+ * 命名(CLAUDE.md 工厂命名律):`create*` —— 返回的是**捕获了两个 sink 与配对账的闭包**,不是纯数据。
1088
1290
  */
1089
1291
  export declare function createApprovalCardEmitter(sinks: {
1090
1292
  /** durable 账本口(bg/resume 腿恒有;sync 腿只有 detach 车道有)。抛 = 这一路没接下。 */
1091
- appendDurable?: (frame: ApprovalRequestFrame) => Promise<void>;
1293
+ appendDurable?: (frame: ApprovalCardLegFrame) => Promise<void>;
1092
1294
  /** live SSE 口。**已死的流应当由调用方判成缺席或让它抛**,不要写一个静默 no-op —— 那正是本 finding。 */
1093
- writeLive?: (frame: ApprovalRequestFrame) => void | Promise<void>;
1094
- }): (frame: ApprovalRequestFrame) => Promise<void>;
1095
- export declare function resolveApprovalLeg(input: {
1096
- /** = `resolveStreamApprovalGate(...).active`(协议在本 worker 上场没有)。 */
1097
- streamApprovalOn: boolean;
1098
- /** `config.streamApproval.windowMs`(`STREAM_ASK_WINDOW_MS`)。
1099
- * 🔴 [ref]:`undefined` = **这份装配没有 `streamApproval` 段**(只出现在只填被测键的 stub-harness ——
1100
- * 真实 boot 无条件铸该段,见 `config.ts`)。此前三个调用点各写 `?? 0` 把这一形折成「0」,在旧语义下
1101
- * 是死代码(`windowZero` 那时挂在 `streamApprovalOn` 后面,协议关就恒 false);[ref] 让 `0` 在协议关的
1102
- * 腿上也真生效之后,那个折算会把一台**什么都没配**的 harness 判成「运维显式关窗」。故本字段收成
1103
- * `number | undefined`,由每个调用点如实交出「有没有这个值」,不许再就地编一个。 */
1104
- windowMs: number | undefined;
1105
- /** `config.streamAskWindowMarginMs`(`STREAM_ASK_WINDOW_MARGIN_MS`)。 */
1106
- windowMarginMs: number;
1107
- /** `spec.limits.maxWalltimeMs`。缺席 = 没有 walltime 墙 ⇒ 第三源不参与(**缺席 ≠ 0**)。 */
1108
- legWalltimeMs?: number;
1109
- /** 本腿**开始执行的时刻**的 `performance.now()`。取值点绝不能挪到腿启动之后:误差方向必须是
1110
- * 「窗偏短」(安全侧,§7.3 的误差方向论证)。 */
1111
- nowMonotonicMs: number;
1112
- }): ApprovalLegAssembly;
1295
+ writeLive?: (frame: ApprovalCardLegFrame) => void | Promise<void>;
1296
+ }): (frame: ApprovalCardLegFrame, registration: string) => Promise<void>;
1297
+ export declare function resolveApprovalLeg(input: ApprovalLegInput): ApprovalLegAssembly;
1298
+ /**
1299
+ * 🔴 **开流 preamble 往本连接投卡与否的唯一判据**(S-1914 / H5)—— 两条 preamble 共用:sync 腿(`routes/tasks.ts`,入参的声明读本次请求的 `settings`)与耐久事件流
1300
+ * (`routes/runs.ts`,声明读这条 run 的持久化体,见 `http/run-declared-families.ts`)。preamble 也是往本连接投卡:只在本腿**有活审批通道**时重放、订消卡 ——
1301
+ * 协议在本 worker 上场、没关窗、这条 run 声明了本 worker 呈卡用的族;与本腿呈不呈卡是同一只装配({@link resolveApprovalLeg}),不在 preamble 一侧另写一份合取式。
1302
+ * 为假 ⇒ 零帧且零 ask 账读(与「协议未上场」同形)。时钟不参与这一判:`nowMonotonicMs` 只喂 `legDeadlineMonotonic`(窗长三元),不进 `unattended` 的三个成因。
1303
+ */
1304
+ export declare function approvalPreambleReplays(input: Omit<ApprovalLegInput, "nowMonotonicMs">): boolean;
1113
1305
  /** 一条 **DECIDED 行**能交还给引擎的全部形(`AskOutcome` 减掉 park 路由那一臂 —— 一条有决议的行
1114
1306
  * 从定义上不是「投递面拿走了它」)。{@link ToolApprovalCoordinator.notifyExternalDecision} 收的就是它。 */
1115
1307
  export type DecidedAskOutcome = Exclude<AskOutcome, "unavailable">;
@@ -1179,6 +1371,8 @@ export declare class ToolApprovalCoordinator {
1179
1371
  * askId 下全部本地条目(自己 + 兄弟 + 重复注册),直接调用它们各自的 `settle`,而不是被动等一个永远
1180
1372
  * 不会来的本地信号。 */
1181
1373
  private readonly pendingByAskId;
1374
+ /** preamble 呈出的卡的消卡订阅(键 = askId;见 {@link watchPresentedCards})。只订本副本上此刻在等的 ask,落定即清 ⇒ 有界于活登记数。 */
1375
+ private readonly presentedCardWatchers;
1182
1376
  /** Per-capability session grants — keys = sessionAllowKey(owner, sessionId, category, grant binding) (修2; bounded). */
1183
1377
  private readonly allowAllSessions;
1184
1378
  /** [ref] HIGH-1(broker)→[ref]四 core 产品裁定「多活集合+广播+首决胜出」:per-(owner, host-session)
@@ -1215,6 +1409,8 @@ export declare class ToolApprovalCoordinator {
1215
1409
  * `pollSuspendedDecisions` 里那段:按 askId 记的形会在「上一拍最后碰的那条被结算掉」时塌回队首,
1216
1410
  * 构造出永久饥饿的前缀)。只回答「上一拍扫到第几个」,单调推进、按当前长度取模。 */
1217
1411
  private suspendedPollOffset;
1412
+ /** S-247:悬挂轮询腿第二层(接管登记)的轮转游标 —— 与 {@link suspendedPollOffset} 同一条理由,两层各一只。 */
1413
+ private adoptedPollOffset;
1218
1414
  /** [ref] + codex R3-[critical]:askId → **此刻正带着 `updatedInput` 决它的请求数**(见
1219
1415
  * {@link markEditedDecisionInFlight} 顶注)。只在 `decideAsk` 那一次调用期间非空,故天然有界。 */
1220
1416
  private readonly editedDecisionsInFlight;
@@ -1241,17 +1437,20 @@ export declare class ToolApprovalCoordinator {
1241
1437
  * core 的 global 缺省(= 现行为,恒不更宽;也绝不错铸一个坐标系不对的 root)。装配见 main.ts:
1242
1438
  * registry cwd(host lane 显式注册的 launch dir)?? in-process 单用户形的 `process.cwd()`。 */
1243
1439
  private readonly ruleScopeRootFor;
1244
- /** [ref]:park 路由墓碑表(键 = wire `approvalId`,插入序 = 逐出序)。语义与有界理由见
1245
- * {@link ParkTombstone} 顶注。 */
1246
- private readonly parkTombstones;
1247
- private readonly parkTombstoneMax;
1248
- private readonly parkTombstoneTtlMs;
1249
- /** [ref]:per-principal 子帽(语义与取值理由见 {@link DEFAULT_PARK_TOMBSTONE_PER_PRINCIPAL_MAX})。 */
1250
- private readonly parkTombstonePerPrincipalMax;
1440
+ /** [ref]:停驻行迟到决议的受理回执表(键 = 行的键 `askId`,插入序 = 逐出序)。语义与有界理由见
1441
+ * {@link ParkRedemption} 顶注。 */
1442
+ private readonly parkRedemptions;
1443
+ private readonly parkRedemptionMax;
1444
+ private readonly parkRedemptionTtlMs;
1445
+ /** [ref]:per-principal 子帽(语义与取值理由见 {@link DEFAULT_PARK_REDEMPTION_PER_PRINCIPAL_MAX})。 */
1446
+ private readonly parkRedemptionPerPrincipalMax;
1251
1447
  /** [ref]:PARKED 臂的赎回席**取值口**(晚绑 —— 赎回腿要 checkpoint/bg 店与裸 Agent 工具,它们在协调器
1252
1448
  * 构造之后才装配;同款 holder 先例 = main.ts 的 `getRunDenySweep`)。取到 undefined ⇒ 该臂逐字回落
1253
1449
  * 修前 404,partial 部署安全。 */
1254
1450
  private readonly parkedRedeem;
1451
+ /** S-1915:按问读口对 `PARKED` 卡的门读席(见 {@link ParkedGateRead})。缺席(没有 checkpoint 店的部署 / 只装 ask 账的嵌入)⇒ 读口只能说行说的话(`parked`)。
1452
+ * 不是晚绑取值口:checkpoint 店在协调器构造之前就装好了(`boot/stage-06`),与 `parkCommits` 同一只店。 */
1453
+ private readonly parkedGate;
1255
1454
  /** [ref] 裁 (c):local 车道的 File ask **审计** sink(在场 ⇔ `DB_BACKEND=local` ∧ 审批面开着,装配点
1256
1455
  * `boot/coordinators.ts`)。三个挂线点:铸造(askBroadcast register 后)/ 决议(`settle()` 公共咽喉)/
1257
1456
  * 腿闭(`runWithContext` finally)。**纯观察面**:sink 自己吞写失败并 `recordFailOpen`,任何一次审计
@@ -1293,12 +1492,14 @@ export declare class ToolApprovalCoordinator {
1293
1492
  ruleScopeRootFor?: (sessionId: string | undefined) => string | undefined;
1294
1493
  /** [ref]:PARKED 臂赎回席的**晚绑取值口**(见 {@link ToolApprovalCoordinator.parkedRedeem})。 */
1295
1494
  parkedRedeem?: () => ParkedAskRedeem | undefined;
1296
- /** [ref]:墓碑表两道界(缺省见 {@link DEFAULT_PARK_TOMBSTONE_MAX}/{@link DEFAULT_PARK_TOMBSTONE_TTL_MS})。
1495
+ /** S-1915:按问读口的门读席(见 {@link ToolApprovalCoordinator.parkedGate})。 */
1496
+ parkedGate?: ParkedGateRead;
1497
+ /** [ref]:受理回执表两道界(缺省见 {@link DEFAULT_PARK_REDEMPTION_MAX}/{@link DEFAULT_PARK_REDEMPTION_TTL_MS})。
1297
1498
  * 不是部署旋钮(不接 env),可注入只为让「有界」这件事被判据观测得到。 */
1298
- parkTombstoneMax?: number;
1299
- parkTombstoneTtlMs?: number;
1300
- /** [ref]:per-principal 子帽(同上不接 env;生效值恒 `min(本值, parkTombstoneMax)`)。 */
1301
- parkTombstonePerPrincipalMax?: number;
1499
+ parkRedemptionMax?: number;
1500
+ parkRedemptionTtlMs?: number;
1501
+ /** [ref]:per-principal 子帽(同上不接 env;生效值恒 `min(本值, parkRedemptionMax)`)。 */
1502
+ parkRedemptionPerPrincipalMax?: number;
1302
1503
  /** [ref] (c):local 车道审计 sink(见 {@link ToolApprovalCoordinator.askAudit})。 */
1303
1504
  askAudit?: ApprovalAskAuditSink;
1304
1505
  /** S-877 候裁 16:耐久会话授权店(见 {@link ToolApprovalCoordinator.sessionGrants})。 */
@@ -1320,7 +1521,7 @@ export declare class ToolApprovalCoordinator {
1320
1521
  * 五臂(设计稿 §1 的表)全部读它,`unattendedPolicy` 因此是一处施加、五处消费:
1321
1522
  * (a) 有店窗到期 `expireAsk` 赢 CAS / (b) 无店窗到期(D1)/ (c) 有店但 `expireAsk` 报错
1322
1523
  * —— 三条走 `windowRouteUnavailable` 标志,在 {@link shapeOutcome}(askBroadcast 内)成形;
1323
- * (d) `windowZero`(装配层短路)与无 ALS 上下文的 headless 腿 —— 走本方法/{@link ask};
1524
+ * (d) 没有活审批通道的腿(装配层短路:关窗 / 未声明呈卡族,S-1914)与无 ALS 上下文的 headless 腿 —— 走本方法/{@link ask};
1324
1525
  * (e) 断连 `forceParkNow` / emit 全灭 / 写侧准入超限 —— 走本方法。
1325
1526
  *
1326
1527
  * **持久回放的两个口也归它管**(codex R1-F1 验真后收口,红先钉在
@@ -1353,7 +1554,7 @@ export declare class ToolApprovalCoordinator {
1353
1554
  private unattendedOutcome;
1354
1555
  /** 政策**读**口(不是终局铸口)—— 回答「这台部署把无人可答翻成 park 吗」。
1355
1556
  *
1356
- * 🔴 与 {@link unattendedOutcome} 分家是 S-187 的一半:此前两件事共用一只方法,于是墓碑腿那次
1557
+ * 🔴 与 {@link unattendedOutcome} 分家是 S-187 的一半:此前两件事共用一只方法,于是 park 路由判别那次
1357
1558
  * 纯粹的**政策查询**(`unattendedOutcome() !== false`)会和同一只 ask 的真终局各记一条遥测 ——
1358
1559
  * 「一只 ask 一条线」当场不成立。读口不落日志,铸口落;谁也不兼职。 */
1359
1560
  private get unattendedRoutesToPark();
@@ -1365,10 +1566,9 @@ export declare class ToolApprovalCoordinator {
1365
1566
  * 读的是政策**读**口(不落遥测)。
1366
1567
  */
1367
1568
  private batchIdFor;
1368
- /** {@link unattendedOutcome} 的**公开**口:`windowZero` 的 immediate-unavailable 闭包长在装配层
1369
- * (`http/routes/tasks.ts` 的 sync 腿),它必须与协调器内五臂读**同一个**旋钮值,而不是各算一遍。
1370
- * 出处随调用方给(那条腿知道自己是哪一只 ask)。 */
1371
- unattendedAskOutcome(site: {
1569
+ /** {@link unattendedOutcome} 的**公开**口:没有活审批通道的腿({@link ApprovalLegAssembly.unattended})的席长在装配层,它必须与协调器内
1570
+ * 五臂读**同一个**政策值,而不是各算一遍。成因(`why`)与出处随调用方给(那条腿知道自己为什么不呈卡、是哪一只 ask)。 */
1571
+ unattendedAskOutcome(site: LegUnattended & {
1372
1572
  taskId?: string;
1373
1573
  owner?: string | null;
1374
1574
  toolName?: string;
@@ -1440,7 +1640,7 @@ export declare class ToolApprovalCoordinator {
1440
1640
  *
1441
1641
  * 两个座两种处置,**刻意不同**:
1442
1642
  * · `segment` = **纯渲染座**(core 明写「never adjudication input」)⇒ 截长是诚实省略,与
1443
- * `toolName`/`message` 的 `clip` 同待遇,也与耐久腿 `boundedRuleOffers` 的同名处置同形。
1643
+ * `toolName`/`message` 的 `capText` 同待遇,也与耐久腿 `boundedRuleOffers` 的同名处置同形。
1444
1644
  * · `rule`/`command` = **兑付等式的左边**(回决 `persistRule.rule` 按文本在引擎重铸的 offer 表里定位)
1445
1645
  * ⇒ 截一个字就恒 `rule_not_offered`,所以**绝不截**;真超尺(= core 放宽了自己的 512 或本仓与 core
1446
1646
  * 版本不同步)⇒ **整条车道撤回**(返回 `undefined`),与本文件既有的治理撤回 / 漂移撤回逐字同形:
@@ -1561,8 +1761,8 @@ export declare class ToolApprovalCoordinator {
1561
1761
  * 读失败 ⇒ 不命中 = fail-closed,人多看一张卡而不是被静默代答)∧ ④ 行上没有与本地 peek 矛盾的出处({@link sessionGrantUncontestedByRow})。
1562
1762
  *
1563
1763
  * **两个读位、一只店、按问句的作者分**(收车档 ⑩ 16):本席兑现**引擎自装的问**(模式写门 / 形状层 —— core 7.34.0 起它们是引擎
1564
- * 自己的层、不读任何豁免,折叠 ask 赢 ⇒ 策略层探针对它们恒无效,codex F2);**本仓自己的问**(durable 名单门、workflow 问句门、
1565
- * acceptEdits 的 cwd 域写门)照旧在各自的层上读同一只店「不问」。为什么两处都要:子代经父约束链继承到的问到达祖先审批席时 core
1764
+ * 自己的层、不读任何豁免,折叠 ask 赢 ⇒ 策略层探针对它们恒无效,codex F2;7.133.0 起 acceptEdits 的写也只有引擎模式门这一问);
1765
+ * **本仓自己的问**(durable 名单门、workflow 问句门)照旧在各自的层上读同一只店「不问」。为什么两处都要:子代经父约束链继承到的问到达祖先审批席时 core
1566
1766
  * 盖 `mandated`(`ruleClearanceOf` 的 inheritedUnresolved / ancestorResolved 门),本席依约不退役 —— 只有策略层的「不问」够得着继承链
1567
1767
  * (主会话裁定原想退役那三只探针,施工中被 test/parked-decide-leg.test.ts「[候裁② 修]remember 全链行为」证伪,收车档 ⑩ 16-⑤)。
1568
1768
  * 本席的两个入口(`askBroadcast` 开头、窗 0 / 无活流身份席 {@link boundUnattendedAsk})都只调这一只。
@@ -1577,8 +1777,9 @@ export declare class ToolApprovalCoordinator {
1577
1777
  * 问已经发出去了)。 */
1578
1778
  private durableGrantHas;
1579
1779
  /**
1580
- * 🔴 **S-877 候裁 16 —— 窗 0 席**:本席**不呈卡**,但在报「无人可答」之前先问站着的答案。装配点 = 三条腿的 `windowZero` 席
1581
- * (sync `http/routes/tasks.ts`、bg `runs.ts`、resume `http/resume-legs.ts`)。修前三处是装配层的就地闭包 `() => unattendedAskOutcome(...)`
1780
+ * 🔴 **S-877 候裁 16 —— 无通道席**(旧名「窗 0 席」):本席**不呈卡**,但在报「无人可答」之前先问站着的答案。装配点 = 三条腿上没有活审批通道
1781
+ * 的那一支({@link ApprovalLegAssembly.unattended} 在场;sync `http/routes/tasks.ts`、bg `runs.ts`、resume `http/resume-legs.ts`),成因 `why`
1782
+ * 随席交给唯一铸点(遥测臂 + deny 政策的拒因句;S-1914 起两个成因:关窗 / 这条 run 没声明呈卡族)。修前三处是装配层的就地闭包 `() => unattendedAskOutcome(...)`
1582
1783
  * —— 不读授权,引擎那一问(模式写门 / 形状层)在窗 0 部署上 remember 恒无效。改形后:授权命中 ⇒ `true`;否则逐字走
1583
1784
  * {@link unattendedAskOutcome} 这**一个**政策口(五臂一处施加,[ref] R-13 C 不变)。
1584
1785
  * parked 赎回腿的继承条目席**不**改:那条腿上到席的问全是继承问(core 盖 `mandated`),本席依约不退役,改了也兑现不了任何东西 ——
@@ -1589,7 +1790,7 @@ export declare class ToolApprovalCoordinator {
1589
1790
  owner: string | null;
1590
1791
  taskId: string;
1591
1792
  sessionId?: string;
1592
- }) => ((req: AskRequest) => Promise<AskOutcome>);
1793
+ }, why: LegUnattended) => ((req: AskRequest) => Promise<AskOutcome>);
1593
1794
  /**
1594
1795
  * 🔴 session grant 短路前的**持久出处复核**([ref] 的 codex R1-[high] 补丁;[ref] 换判据;S-944 / SN-C1 换读口)。
1595
1796
  *
@@ -1684,24 +1885,34 @@ export declare class ToolApprovalCoordinator {
1684
1885
  * 单赢者卫兵,对已落的恒无操作。absent / 编辑在飞没有可分发的真相。
1685
1886
  */
1686
1887
  private dispatchClaimTruth;
1687
- /** [ref]:落一条 park 墓碑(容量帽按**插入序**逐出最旧,与 `allowAllSessions` 同款有界纪律)。
1688
- * 调用点唯一 = `settle` 里的 park 路由支(见那处注);真终局绝不调它。
1689
- *
1690
- * 🔴 **同键第二次调用 = 整个无操作**([ref] 二轮重扫,双 opus confirmed 的修法后半;红先钉
1691
- * `test/parked-late-decision.test.ts` 的 [ref]-④)。键换成 wire `approvalId` 之后,「同一把
1692
- * approvalId 落两次墓碑」从不可能变成**常态**(同 askId 的重复本地注册各自按 park 路由收尾)。
1693
- * 两件事因此必须同时成立:
1694
- * · **不占第二格、不动插入序** —— 帽与逐出序是按「对外可见的 ask」记的;兄弟刷新插入序会把一条
1695
- * 早该轮到逐出的墓碑一次次续命,同样是记账失真。
1696
- * · **不覆写既有条目** —— `redeemed`/`inflight` 是本副本**已经对客户端做出的受理承诺**(见
1697
- * {@link ParkTombstone});覆写等于把一次已受理的决议重新打开,200 丢包后的重试会去动一张
1698
- * **已被消费**的 checkpoint(409/404),与本口承诺的「幂等回放首决」相反。
1699
- * 代价如实登记:`parkedAtMs` 保留**首次** park 的时刻 ⇒ TTL 从首次起算(晚到的兄弟不给续期)。
1700
- * 方向安全(墓碑早退 = 回落修前的 404,不会错兑),且与「一只 ask 一格」的记账口径自洽。 */
1701
- private recordParkTombstone;
1702
- /** [ref]:取墓碑(**惰性清扫**:过期条目读到即删,不另起定时器 —— 这张表只在迟到回决那一刻被读)。
1703
- * 属主门在调用方(与 live 腿同一句判据:`owner === null` 或逐字相等,否则按不存在处置)。 */
1704
- private lookupParkTombstone;
1888
+ /**
1889
+ * [ref]:为一次**赎回**开一格(单飞句柄的座位)。调用点唯一 = {@link redeemParkedAsk} 开飞之前。在飞的格不受容量帽约束 ——
1890
+ * 它们有界于此刻在飞的赎回请求数,且开飞即受理承诺之前的那一段(逐它会撕正在进行的兑付);容量帽只管落定之后留下的**回执**
1891
+ * ({@link retainParkRedemption})。
1892
+ */
1893
+ /**
1894
+ * 受理回执表的**准入**半场:在飞的格(赎回腿还没回来)永不被逐 —— 单飞靠它 —— 所以表的两道界对它们只能在开格之前判。
1895
+ * 本 principal 在飞的格已到生效子帽,或全表在飞的格已到全局帽 ⇒ 拒新(`429 limit.rate_exceeded` + `retryAfterSec`,路由据体铸 `Retry-After` 头),
1896
+ * 不开格、不进赎回腿;已在飞的那几只照常落定,之后同一只卡的受理照常。回 `undefined` = 放行。
1897
+ * 两道界与回执半场({@link retainParkRedemption})同一组数:表里每一格都有界 —— 回执靠逐出,在飞的格靠准入。
1898
+ */
1899
+ private parkRedemptionAdmission;
1900
+ private openParkRedemption;
1901
+ /**
1902
+ * [ref] / [ref]:一次赎回**受理成功**之后,它的回执留不留(容量帽按**插入序**逐出最旧,与 `allowAllSessions` 同款有界纪律)。回 `false` = 容量拒新:
1903
+ * 这一格当场收回(那一次受理照旧生效,只是没有本副本的回执可依 —— 200 丢包后的重试再进赎回腿,终局由它的 CAS 定)。
1904
+ *
1905
+ * 两道界**只数回执**(已受理、不在飞的格;在飞的格永不被逐),且**只看本 principal 的那一段**(理由与两条臂的方向差见
1906
+ * {@link DEFAULT_PARK_REDEMPTION_PER_PRINCIPAL_MAX}),生效子帽对全局帽取小。记账用开格那一刻行上的 owner —— 要的是「压力来自谁」这个近似,
1907
+ * 不是「谁有权决这只 ask」(权威属主门恒按行上当下的 `owner` 复判)。
1908
+ * · 本 principal 的回执数已到子帽 ⇒ 逐本 principal 最旧的那张(过期的优先)—— 量产者自伤;
1909
+ * · 全表回执已到全局帽 ⇒ 先收全表第一张过期回执(清扫是惰性的,若干租户各自远低于子帽却把全局填满时,TTL 过后没人再来查那些旧 id,
1910
+ * 不回收就永远满 —— 回收过期条目不是「挤他人」,是收垃圾);一张过期的都没有 ⇒ 拒新,一格都不挤别人([ref] Q3)。
1911
+ */
1912
+ private retainParkRedemption;
1913
+ /** [ref]:取受理回执(**惰性清扫**:过期回执读到即删,不另起定时器 —— 这张表只在迟到回决那一刻被读)。**在飞的格不随 TTL 过期**:重叠的请求
1914
+ * (哪怕晚于 TTL 才到)照样等它、回放它的结果,绝不另起第二次赎回。 */
1915
+ private lookupParkRedemption;
1705
1916
  /**
1706
1917
  * [ref] 车4 §12-E(F29/F30 裁定形):外部回决(车4 端点或本类 respond 腿)**赢下持久 CAS 之后**,把同
1707
1918
  * askId 下全部本地悬挂条目按**真实决议**结算——端点已是唯一权威(CAS 已落),本地只是同步终局;查无
@@ -1804,13 +2015,25 @@ export declare class ToolApprovalCoordinator {
1804
2015
  /** [ref]:发起本次回决的真实 HTTP 请求。**只**沿 PARKED 臂透传给赎回席(那条腿要它做准入解析与
1805
2016
  * 舰队 scope,与 `/decide` 腿同姿势);live 命中路径一个字节都不看它。缺席 = 非 HTTP 调用点
1806
2017
  * (测试/内部),赎回席按「无请求」形处置。 */
1807
- httpReq?: IncomingMessage): {
2018
+ httpReq?: IncomingMessage,
2019
+ /** S-765:本次回决的**部署事实**(协调器自己不读 config;回决路由从能力事实读来交进)。缺席 ⇒ 按「不受理读根授权」读(失败方向 = 拒)。 */
2020
+ deployment?: ToolApprovalRespondDeployment): {
1808
2021
  status: number;
1809
2022
  body: unknown;
1810
2023
  } | Promise<{
1811
2024
  status: number;
1812
2025
  body: unknown;
1813
2026
  }>;
2027
+ /**
2028
+ * S-247:**接管登记**的应答。接管登记是行的投影(没有引擎腿在等它),所以它的属主门读**行当下的** owner —— 接管时记下的那一格可能已被
2029
+ * `/v1/adoption` 改写(契约:应答口的授权判据取当下的持久事实,收编之后旧属主手里的卡作废)。行仍 `STREAM_PENDING` ⇒ 与活登记同一条应答路
2030
+ * ({@link answerRegistration}:同一把 `decideAsk` CAS);行已有终局(别处答了 / 对账器收了,本副本的轮询还没到)⇒ 按行的真相答(与晚答口同一张表)。
2031
+ */
2032
+ private respondAdopted;
2033
+ /** 一条已过属主门的登记(活登记或接管登记)的应答 —— 两者同一条路:规则文本前门 → 要人门 → CAS → 兑付。 */
2034
+ private answerRegistration;
2035
+ /** 一次 live 回决**落定之后**的两件兑付(部署名单那一问的豁免、「不再询问」的规则)—— 两件都只在 200 那一支、都读同一只资格。 */
2036
+ private afterLiveDecision;
1814
2037
  /**
1815
2038
  * **部署名单(`APPROVAL_REQUIRE`)那一问的「本会话放行」只落 server 的会话豁免店**(谁问的,谁的站着的答案算数):名单的问是 server 铸的,
1816
2039
  * 名单门在出问之前读这只店(键 = 会话 × wire 工具名,与耐久 `/decide` 的 `remember:"session"` 写下的同形),命中就不出问 —— 引擎看到的
@@ -1842,17 +2065,73 @@ export declare class ToolApprovalCoordinator {
1842
2065
  /** [ref]:`tool_approval.not_pending` 的**唯一**成形口。文案逐字不变(存量壳/SDK 按它认这条 404),
1843
2066
  * 只 additive 加判别位;`cause` 缺席 = 这台部署没有行可判(D1 无店)或行形不可信(见各调用点)。 */
1844
2067
  private notPending;
2068
+ /**
2069
+ * `GET /v1/tool-approvals/:approvalId` —— **按问读口**:一只 ask 此刻在哪一态({@link TOOL_APPROVAL_READ_STATES})。与 {@link respond} 同根同门
2070
+ * (HTTP 层的鉴权 / 属主身份同一只 `gatedPrincipal`;属主不过与未知同形 404,无存在性谕示),读法与应答口逐条同源:
2071
+ * 本副本上在等它的活登记({@link liveEntryFor})⇒ `pending`(行投影 = 列表面 `livePending[]` 的同一只投影);否则按 id 读行
2072
+ * ({@link askRowFor} + {@link askRowVisibleTo}),行态 → 读态与晚答口的分派同一张表;行仍 `STREAM_PENDING` 而本副本没有在等它的登记 ⇒ 它活在别的副本上,
2073
+ * 与晚答口同答 404 `unknown_or_other_replica`(那里才有兑现它的闭包)。没有 ask 账的部署 ⇒ 晚答口那句 404,不带 `cause`。
2074
+ * 纯读:零写、零结算、不碰本地登记(晚答口的 DECIDED 臂会顺手同步本副本的活登记,读口不做)。
2075
+ */
2076
+ readApproval(id: string, principal: string | undefined): {
2077
+ status: number;
2078
+ body: unknown;
2079
+ } | Promise<{
2080
+ status: number;
2081
+ body: unknown;
2082
+ }>;
2083
+ /** S-247:接管登记的按问读口 —— 行可见且仍 `STREAM_PENDING` ⇒ `pending`(列表面同一只行投影);否则按行的态答(与读行半场同一张表)。 */
2084
+ private readAdopted;
2085
+ /** {@link readApproval} 的读行半场。 */
2086
+ private readAskRowState;
2087
+ /**
2088
+ * `PARKED` 行的门读法(S-1915):问判官「这张卡的门此刻还是不是该会话当前待决的审批门」。行是终态、不随赎回 / 取消改写,所以只有 checkpoint 知道。
2089
+ * 没有门读席 / 行上没有 gate token ⇒ `open`(读口只能说行说的话;应答口对同一张卡的 PARKED 臂此时也答不了受理,不另有第二个答案)。
2090
+ * 读不出(店故障 / 超时)⇒ 按本协调器的店故障姿势(D5:记账 + 一次 warn)退回 `open` —— 这一臂只影响**展示**,应答口对同一张卡仍按自己的判官 fail-closed。
2091
+ */
2092
+ private readParkedGate;
2093
+ /** 一条行 → 按问读口的答案(行态六态穷举:新增 `AskState` 而不在此表态 = **编译错**)。 */
2094
+ private readStateOfRow;
1845
2095
  /**
1846
2096
  * [ref] —— live 未命中之后的**状态感知分派**(设计 §三的那张表)。
1847
2097
  *
1848
- * 门两道,都在读行之前:①持久店在场(协议上场才有行可读;缺席 ⇒ D1 体逐字不变);②本副本留过
1849
- * park 墓碑且属主门过(墓碑是 wire id ↔ 店内 askId 的唯一桥,见 {@link ParkTombstone})。任一不过 ⇒
1850
- * 与修前逐字同形的 404(店在场时带 `unknown_or_other_replica` 判别位 —— 那正是「换副本/换端点重试才
1851
- * 有意义」的那一因)。
2098
+ * 有行的 ask 的 wire 身份就是行的键 ⇒ 按 id **直接读行**(任一副本、重启前后都读得到;不再经任何进程内的桥)。持久店缺席 ⇒ D1 体逐字不变
2099
+ * (没有行可判,编一个 cause 是撒谎);店在场而行不在 / 不是调用方的 ⇒ 404 `unknown_or_other_replica`(那正是「换副本/换端点重试才
2100
+ * 有意义」的那一因;属主不过与未知同形,无存在性谕示)。
1852
2101
  */
1853
2102
  private respondLate;
1854
- /** {@link respondLate} 的读行 + 六态穷举分派(闭集:新增 `AskState` 而不在此表态 = **编译错**)。 */
2103
+ /**
2104
+ * 新开的 sync 连接经 **preamble** 呈出的卡 → 登记进这条连接的**消卡订阅**(连接的 `approval_complete` 只投给接下过开卡帧的连接 —— 这些卡的开卡帧
2105
+ * 就是 preamble 那一帧)。这几只 ask 在本副本上的最后一条活登记落定时,`deliver` 收一帧 `approval_complete`(与那次 settle 的判决同值)。
2106
+ * · 只订本副本上**此刻在等**的 ask(`pendingByAskId` 有登记):活在别的副本上的 / 订阅之前已经落定的,本副本无从得知它何时落定 ——
2107
+ * 那几形的结构补偿仍是下一次 preamble 的全量对账基准(不在基准内的卡一律清)。
2108
+ * · 投递是 live-only 的通知:`deliver` 抛错 / 连接已死 ⇒ 吞掉(卡的终局是行上的事实,不因通知没送到而改变)。
2109
+ * 返回退订口(连接收场时调;投递一次之后自动退订)。
2110
+ */
2111
+ watchPresentedCards(askIds: readonly string[], deliver: (frame: ApprovalCompleteFrame) => void): () => void;
2112
+ private dropPresentedCardWatcher;
2113
+ /** settle 咽喉调:一只 ask 在本副本上的最后一条活登记落定 ⇒ 给订了它的每条连接投一帧消卡,随即退订。 */
2114
+ private notifyPresentedCardWatchers;
2115
+ /**
2116
+ * 一个 wire 身份 → 本副本上**此刻在等它**的那一条活登记(应答口与读口共用这一只读法)。
2117
+ * · 有行的 ask:wire 身份 = 行的键 ⇒ 同一只 ask 的活登记(重复登记各一条)里**最早**的那一条(插入序;CAS 单赢,赢后其余登记经
2118
+ * 同 askId 的广播口按同一份行真相结清);
2119
+ * · 无行的 ask:wire 身份 = 登记本地键 ⇒ 直接取那一条。登记本地键对有行的 ask 不是 wire 身份(它从不上 wire),拿它来问 ⇒ 查无。
2120
+ */
2121
+ private liveEntryFor;
2122
+ /** {@link respondLate} 的读行:按 id 读出行,交 {@link dispatchRowTruth}。 */
1855
2123
  private dispatchLateByRow;
2124
+ /**
2125
+ * 按 wire 身份(= 行的键)读行。读不出 ⇒ 记账并按「查无」交回:读不出 = **不知道**这只 ask 落在哪一态,而晚答口的三条受理臂(200/200/202)
2126
+ * 都在对客户端做承诺 —— 不知道 ⇒ 回那句 404,绝不把未知说成受理(D5 的 fail-open 只覆盖「不挡人的真实回决」那一面,这条腿方向相反)。
2127
+ */
2128
+ private askRowFor;
2129
+ /**
2130
+ * 一条行(的此刻真相)→ 应答口的答案:属主门 + 受理回执 + 六态穷举分派(闭集:新增 `AskState` 而不在此表态 = **编译错**)。两个入口:本副本没有在等
2131
+ * 这只 ask 的登记({@link dispatchLateByRow} 读出行),以及有登记但回决的 CAS 干净地输(行已有终局,`decideAsk` 带回的那条行)—— 一只 ask 的
2132
+ * 应答只看行的真相,与本副本有没有残留登记无关。
2133
+ */
2134
+ private dispatchRowTruth;
1856
2135
  /** [ref]:迟到腿上的 `persistRule` 兑付面 —— 本地条目(规则车道素材的载体)早已随 park 路由散场,
1857
2136
  * 没有任何可对的候选表 ⇒ 如实拒(裁决本身照常受理,与 {@link persistRuleAfterDecision} 的
1858
2137
  * 「失败不翻转裁决」同判)。用既有词 `rule_lane_unavailable`,不为这一支新造词。 */
@@ -1889,7 +2168,7 @@ export declare class ToolApprovalCoordinator {
1889
2168
  *
1890
2169
  * ## 素材从哪来(这是本方法存在的全部理由)
1891
2170
  * live 腿的等式左边是**进程内条目** `PendingApproval.ruleLane`,而 park 路由把条目连同素材一起散场
1892
- * 了([ref] 的墓碑只桥身份,不携素材)。本腿因此从**行**取,一件一件对着 live 腿的入参:
2171
+ * 了(行之外不留任何进程内素材)。本腿因此从**行**取,一件一件对着 live 腿的入参:
1893
2172
  * · `command` = `rule_command` 列(**[ref] 新列**;缺席即本方法唯一的新拒因,见下);
1894
2173
  * · `scope` = `rule_scope_root` 列 ⇒ `{kind:"project", root}`,缺席则**不铸 scope**(core 落 global,
1895
2174
  * = live 腿 `material.scopeRoot` 缺席时逐字同形 —— 绝不在坐标系不明时编一个 root);
@@ -1940,10 +2219,44 @@ export declare class ToolApprovalCoordinator {
1940
2219
  * 语义。
1941
2220
  * 🔴 **S-454 起行上带整只活卡帧**(`frame`,见 {@link LivePendingRow.frame}):旧文那句「input/args
1942
2221
  * 不上列表,详情走流帧」对**悬挂 ask 结构上不成立**(它永远没有流帧),而 `frame` 是 `askBroadcast`
1943
- * 那一处构造的同一个对象 ⇒ 仍然只有**一个**脱敏属主、零第二投影。`scope` 与 durable 面同一表达式:`undefined` = operator 全量(含 owner null 的
1944
- * 条目),串 = 只见 `owner === scope` 的条目(null-owner 行对 principal 不可见,fail-closed——
1945
- * 宁少列不超范围;`"__none__"` 未鉴权哨兵自然恒空)。行的 `approvalId` 就是 `respond()` 收的 id
2222
+ * 那一处构造的同一个对象 ⇒ 仍然只有**一个**脱敏属主、零第二投影。`scope` 与 durable 面同一个值(checkpoint scope):`undefined` = operator 全量(含 owner null 的
2223
+ * 条目),`_`(`CHECKPOINT_PUBLIC_SCOPE`)= 匿名那一组 = owner null 的条目(R7:不带主体的调用方列得出它答得了的那几张),
2224
+ * 其余串 = 只见 `owner === scope` 的条目(null-owner 行对具名主体不列,宁少列不超范围)。行的 `approvalId` 就是 `respond()` 收的 id
1946
2225
  * (同源可达,[ref] 判据);`expiresAtMs` 照抄登记时单点铸定的窗死线([ref] 三键同一个数)。 */
2226
+ /**
2227
+ * 🔴 S-247 —— **起服接管**:把问账里仍 `STREAM_PENDING` 的问接进本审批机的活集合,让 `livePending[]`(及 `/v1/approvals/stream` 的 live 半场、
2228
+ * 按问读口、应答口)在重启之后不重开流也看得见、答得了它们。审批机仍是这些读面**唯一**的读源:读问账的只有这里(起服一次),之后列表行由
2229
+ * 同一只 {@link livePendingRowOf} 投影,卡帧 = `buildReplayFrame`(开流 preamble 同一只构造)—— 不是 GET 上加一只读表的第二 reader。
2230
+ *
2231
+ * 律(设计稿 `design-S-247.md` §2):接管登记**没有引擎腿在等它**(铸它的进程没了,或它活在别的副本上),与活登记同一只状态机 ——
2232
+ * 应答 = 同一把 `decideAsk` CAS({@link answerRegistration}),收敛 = 同一条悬挂轮询腿读行({@link pollSuspendedDecisions});它活多久只由行说了算,
2233
+ * 没有自己的窗(无等待腿的行的到期写者已经存在:对账器段二,同一只政策感知终态 claim,窗 + 宽限 —— 接管不新增竞争者)。
2234
+ * 「本副本没有引擎腿在等它」机读披露:列表行与应答回执带 `consumerState:"absent"`({@link ASK_DECISION_CONSUMER_ABSENT})。
2235
+ *
2236
+ * 装配点 = `boot/stage-07` 起服收敛之后、reaper / HTTP 之前(local 车道上收敛先把前世问收成 `VOID` ⇒ 这里读到零行,车道无分叉)。
2237
+ * 幂等:本副本已有这只 askId 的登记就跳过;每次起服由行重新推导。读失败 ⇒ **拒启**(抛;与起服收敛同一拍、同姿态 —— 照常起来等于让
2238
+ * 仍待决的问在列表面上消失,而审批中心只读列表)。
2239
+ * ⚠️ 射程:接管的是**起服那一刻**问账里的待决行;之后别的副本新铸的问不接管(`livePending` 是本副本投影、多副本要会话粘性 —— 契约原句不变)。
2240
+ */
2241
+ adoptOpenAsks(): Promise<OpenAskAdoption>;
2242
+ /**
2243
+ * S-247:由一条待决行铸一条接管登记并放进活集合(唯一铸点;读法见 {@link AdoptedRegistrationPart})。事实全部取自行与行上的卡:属主 / 会话(adhoc 替身
2244
+ * = taskId 时不投,与按问读口的行投影同读)/ 子代出身(卡 `fromSubagent` ⇒ 行 `sourceTaskId`)/ 窗死线 / 铸造时刻取行;工具名、要人位、治理位、类集取卡;
2245
+ * 授予绑定卡上没有 ⇒ `unreadable`(于是站着的答案判据答 `none`:`rememberRefused`,`allow_session` 只放行这一次 —— 既有律);规则素材不在 ⇒ `persistRule`
2246
+ * 答 `rule_lane_unavailable`(晚答腿同一个词)。卡面的 `rememberRefused` 与条目同一只判据(活登记那一处的同一条纪律)。
2247
+ */
2248
+ private registerAdopted;
2249
+ /** S-247:放掉这只 askId 的全部接管登记(不碰行、不发消卡帧)。两个读者:悬挂轮询读到行没了(接管登记没有窗,没有行就没有活着的依据);本副本来了这只问的活登记(它让位)。活登记不动。 */
2250
+ private releaseAdoptedRegistrations;
2251
+ /**
2252
+ * S-247:问账里**这只问的行没了**(行被删)⇒ 放掉它的接管登记;放完本副本若已没有这只问的任何登记,经 preamble 订了它的消卡订阅也一并撤掉
2253
+ * (不发帧 —— 问不是被谁答掉的,编一帧消卡就是撒谎;壳的结构补偿仍是下一次 preamble 的全量对账基准)。还有活登记 ⇒ 订阅留给它的结算。
2254
+ */
2255
+ private forgetAdoptedAsk;
2256
+ /** S-247:接管登记的属主跟行走 —— 悬挂轮询每读到一次仍待决的行就对齐一次(`/v1/adoption` 改写 `approval_ask.owner` 之后,列表面在一拍之内跟上;应答口与读口另读行当下的 owner)。 */
2257
+ private followAdoptedOwner;
2258
+ /** 这只 askId 在本副本上有几条**有引擎腿在等**的登记(接管登记不算)—— 轮询腿的「被唤醒数」读它。 */
2259
+ private waitingRegistrationCount;
1947
2260
  listLivePending(scope: string | undefined): LivePendingRow[];
1948
2261
  /**
1949
2262
  * S-751:某只委派子代此刻有没有**待决**的活卡 —— fleet 对账腿「子代活性由属主说了算」的属主②读口(另一只是
@@ -2031,8 +2344,10 @@ export declare class ToolApprovalCoordinator {
2031
2344
  /** [ref]:当前挂着的**悬挂**条目数(零投递集合铸的那一类)——运维/判据读它证「悬挂队列有多长」。 */
2032
2345
  suspendedCount(): number;
2033
2346
  sessionAllowedCount(): number;
2034
- /** [ref]:当前在场的 park 墓碑数(有界性的可观测面 —— 判据据它证「帽是硬的、过期会被清」)。 */
2035
- parkTombstoneCount(): number;
2347
+ /** S-247:当前在场的 preamble 消卡订阅(按 askId)数 —— 判据据它证「订阅有界于本副本的登记,没有登记、没有行的问不留订阅」。 */
2348
+ presentedCardWatcherCount(): number;
2349
+ /** [ref]:当前在场的受理回执数(有界性的可观测面 —— 判据据它证「帽是硬的、过期会被清」)。 */
2350
+ parkRedemptionCount(): number;
2036
2351
  }
2037
2352
  export {};
2038
2353
  //# sourceMappingURL=tool-approval.d.ts.map