@sema-agent/server 7.150.0 → 7.151.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 (341) hide show
  1. package/MIGRATION.md +185 -0
  2. package/USAGE.md +53 -25
  3. package/deploy/sema-up/README.md +7 -1
  4. package/deploy/sema-up/chart/Chart.yaml +1 -1
  5. package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
  6. package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
  7. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
  8. package/deploy/sema-up/chart/templates/server.yaml +5 -3
  9. package/deploy/sema-up/chart/values-full-single.yaml +3 -1
  10. package/deploy/sema-up/chart/values.yaml +8 -1
  11. package/deploy/sema-up/cluster-up.sh +1 -0
  12. package/deploy/sema-up/kube-up.sh +1 -1
  13. package/deploy/sema-up/lib/flagshape.sh +1 -1
  14. package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
  15. package/deploy/sema-up/lib/helm-values-kube.py +2 -0
  16. package/dist/adoption/import.js +3 -3
  17. package/dist/approval-ask-machine.d.ts +1 -1
  18. package/dist/approval-card.d.ts +2 -2
  19. package/dist/approval-gate-currency.d.ts +1 -1
  20. package/dist/auth-bridge.d.ts +20 -0
  21. package/dist/auth-bridge.js +9 -0
  22. package/dist/background-session-reap.d.ts +1 -1
  23. package/dist/bake-runner/main.d.ts +4 -2
  24. package/dist/bind-host.d.ts +2 -3
  25. package/dist/bind-host.js +2 -4
  26. package/dist/boot/budget-tracing.js +1 -1
  27. package/dist/boot/engine-lease.d.ts +5 -0
  28. package/dist/boot/engine-lease.js +1 -0
  29. package/dist/boot/execution-env.d.ts +8 -14
  30. package/dist/boot/execution-env.js +54 -17
  31. package/dist/boot/execution-lane.js +32 -5
  32. package/dist/boot/late-binds.d.ts +8 -4
  33. package/dist/boot/late-binds.js +7 -1
  34. package/dist/boot/memory-consolidation.d.ts +3 -2
  35. package/dist/boot/memory-consolidation.js +6 -6
  36. package/dist/boot/reapers.d.ts +5 -0
  37. package/dist/boot/reapers.js +12 -1
  38. package/dist/boot/resolve-spec.d.ts +3 -3
  39. package/dist/boot/resolve-spec.js +31 -22
  40. package/dist/boot/runner-deps.d.ts +9 -2
  41. package/dist/boot/runner-deps.js +3 -3
  42. package/dist/boot/session-age-out.d.ts +36 -0
  43. package/dist/boot/session-age-out.js +101 -0
  44. package/dist/boot/session-faces.d.ts +5 -14
  45. package/dist/boot/session-faces.js +9 -5
  46. package/dist/boot/stage-01-config.js +2 -0
  47. package/dist/boot/stage-05-execution-env.d.ts +5 -3
  48. package/dist/boot/stage-05-execution-env.js +2 -2
  49. package/dist/boot/stage-06-runners.d.ts +7 -4
  50. package/dist/boot/stage-06-runners.js +15 -6
  51. package/dist/boot/stage-07-capability-layer.d.ts +7 -4
  52. package/dist/boot/stage-07-capability-layer.js +2 -1
  53. package/dist/boot/stage-08-reapers.d.ts +7 -4
  54. package/dist/boot/stage-08-reapers.js +4 -2
  55. package/dist/boot/stage-09-leader.d.ts +11 -5
  56. package/dist/boot/stage-09-leader.js +12 -3
  57. package/dist/boot/stage-10-http-server.d.ts +11 -5
  58. package/dist/boot/stage-10-http-server.js +3 -6
  59. package/dist/boot/web-admin.js +3 -1
  60. package/dist/boot/workflow-orchestration.d.ts +7 -2
  61. package/dist/boot/workflow-orchestration.js +24 -7
  62. package/dist/bounded-rotation.d.ts +29 -0
  63. package/dist/bounded-rotation.js +24 -0
  64. package/dist/capability-facts.d.ts +22 -13
  65. package/dist/capability-facts.js +28 -18
  66. package/dist/center-credential.d.ts +25 -6
  67. package/dist/center-credential.js +25 -5
  68. package/dist/config-catalog.d.ts +26 -7
  69. package/dist/config-catalog.js +14 -11
  70. package/dist/config-invariants.d.ts +2 -1
  71. package/dist/config-invariants.js +4 -4
  72. package/dist/config-types.d.ts +10 -4
  73. package/dist/config.d.ts +51 -2
  74. package/dist/config.js +35 -24
  75. package/dist/deployment-shape.d.ts +9 -1
  76. package/dist/deployment-shape.js +2 -1
  77. package/dist/device-protocol.d.ts +5 -4
  78. package/dist/device-protocol.js +1 -1
  79. package/dist/device-ws-hub.js +3 -2
  80. package/dist/device-ws-protocol.d.ts +63 -10
  81. package/dist/device-ws-protocol.js +56 -25
  82. package/dist/engine-identity.d.ts +19 -7
  83. package/dist/engine-identity.js +10 -2
  84. package/dist/entry-mode-clamp-notice.d.ts +2 -1
  85. package/dist/execution-env-refusal.d.ts +23 -0
  86. package/dist/execution-env-refusal.js +5 -0
  87. package/dist/execution-lane-caps.d.ts +3 -1
  88. package/dist/field-conflict.d.ts +1 -1
  89. package/dist/file-history-capture.d.ts +11 -4
  90. package/dist/file-history-capture.js +9 -6
  91. package/dist/file-history-disclosure.d.ts +7 -5
  92. package/dist/file-history-disclosure.js +7 -5
  93. package/dist/fleet/drain-entry.d.ts +4 -0
  94. package/dist/hooks/hook-runner.js +2 -2
  95. package/dist/host-lsp-manager.d.ts +2 -2
  96. package/dist/http/admission.js +17 -2
  97. package/dist/http/approval-sweeps.js +5 -5
  98. package/dist/http/checkpoint-ctx.d.ts +2 -0
  99. package/dist/http/checkpoint-ctx.js +1 -0
  100. package/dist/http/dispatch.d.ts +2 -1
  101. package/dist/http/dispatch.js +34 -27
  102. package/dist/http/durable-run-leg.js +16 -16
  103. package/dist/http/health-self-report.d.ts +9 -1
  104. package/dist/http/health-self-report.js +2 -0
  105. package/dist/http/owner-access.d.ts +31 -11
  106. package/dist/http/owner-access.js +37 -6
  107. package/dist/http/resume-ctx-read.js +25 -3
  108. package/dist/http/resume-legs.d.ts +2 -1
  109. package/dist/http/resume-legs.js +259 -79
  110. package/dist/http/route-ctx.d.ts +18 -8
  111. package/dist/http/route-table.d.ts +1 -1
  112. package/dist/http/routes/admin-memory-optout.d.ts +1 -1
  113. package/dist/http/routes/agents-roster.js +2 -3
  114. package/dist/http/routes/approvals-assistant.js +4 -3
  115. package/dist/http/routes/background.d.ts +3 -3
  116. package/dist/http/routes/capabilities.js +8 -5
  117. package/dist/http/routes/fleet.js +10 -8
  118. package/dist/http/routes/projects.d.ts +3 -2
  119. package/dist/http/routes/projects.js +4 -5
  120. package/dist/http/routes/runs.js +102 -36
  121. package/dist/http/routes/session-sync.d.ts +4 -3
  122. package/dist/http/routes/session-sync.js +172 -77
  123. package/dist/http/routes/sessions-list.js +13 -7
  124. package/dist/http/routes/sessions.js +10 -6
  125. package/dist/http/routes/tasks.js +30 -16
  126. package/dist/http/routes/trace-usage.js +2 -2
  127. package/dist/http/server.d.ts +21 -27
  128. package/dist/http/server.js +2 -2
  129. package/dist/http/submit-ctx.js +5 -4
  130. package/dist/http/wire-types.d.ts +14 -4
  131. package/dist/identity-source.d.ts +20 -3
  132. package/dist/identity-source.js +14 -0
  133. package/dist/index.d.ts +4 -0
  134. package/dist/lane-home-probe.d.ts +3 -7
  135. package/dist/lane-home-probe.js +0 -1
  136. package/dist/leader/leader.d.ts +2 -1
  137. package/dist/leg-facts.d.ts +13 -5
  138. package/dist/leg-facts.js +2 -1
  139. package/dist/memory-scope.d.ts +5 -4
  140. package/dist/memory-scope.js +4 -4
  141. package/dist/memory-sync-client.d.ts +30 -2
  142. package/dist/memory-sync-client.js +16 -9
  143. package/dist/observability/err-text.d.ts +7 -0
  144. package/dist/observability/err-text.js +5 -0
  145. package/dist/observability/fail-open.d.ts +7 -3
  146. package/dist/observability/fail-open.js +7 -3
  147. package/dist/observability/metrics.js +1 -0
  148. package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
  149. package/dist/orchestration/workflow-notify-journal.js +12 -1
  150. package/dist/orchestration/workflow-park-decision.d.ts +70 -18
  151. package/dist/orchestration/workflow-park-decision.js +49 -10
  152. package/dist/orchestration/workflow-park-holder.d.ts +65 -0
  153. package/dist/orchestration/workflow-park-holder.js +98 -0
  154. package/dist/orchestration/workflow-record-fence.d.ts +36 -0
  155. package/dist/orchestration/workflow-record-fence.js +42 -0
  156. package/dist/owner-faces.d.ts +1 -1
  157. package/dist/parked-decide.d.ts +104 -53
  158. package/dist/parked-decide.js +153 -117
  159. package/dist/peer-directory.d.ts +2 -2
  160. package/dist/peer-inbound-face.d.ts +2 -6
  161. package/dist/peer-inbound-face.js +0 -3
  162. package/dist/permission-mode-admission.d.ts +41 -5
  163. package/dist/permission-mode-admission.js +29 -3
  164. package/dist/plugins/adoption-log-sql.d.ts +3 -1
  165. package/dist/plugins/adoption-log-sql.js +7 -1
  166. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  167. package/dist/plugins/approval-ask-store-file.js +8 -0
  168. package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
  169. package/dist/plugins/approval-ask-store-memory.js +28 -9
  170. package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
  171. package/dist/plugins/approval-ask-store-sql.js +34 -5
  172. package/dist/plugins/approval-exemption-store.js +3 -0
  173. package/dist/plugins/approval-nonce-store.js +2 -0
  174. package/dist/plugins/breaker-state-sql.js +2 -0
  175. package/dist/plugins/caching-session-store.d.ts +9 -15
  176. package/dist/plugins/caching-session-store.js +6 -0
  177. package/dist/plugins/device-store-sql.js +6 -0
  178. package/dist/plugins/error-origin.d.ts +18 -0
  179. package/dist/plugins/error-origin.js +10 -0
  180. package/dist/plugins/execution-placement-sql.js +6 -6
  181. package/dist/plugins/image-bake-store-sql.js +6 -0
  182. package/dist/plugins/image-index-sql.js +4 -0
  183. package/dist/plugins/landed-attendants.d.ts +212 -0
  184. package/dist/plugins/landed-attendants.js +161 -0
  185. package/dist/plugins/leader-run-store-sql.js +4 -0
  186. package/dist/plugins/local-session-live-reference.d.ts +40 -0
  187. package/dist/plugins/local-session-live-reference.js +39 -0
  188. package/dist/plugins/local-session-store.d.ts +71 -33
  189. package/dist/plugins/local-session-store.js +129 -27
  190. package/dist/plugins/memory-engine-pg.js +4 -0
  191. package/dist/plugins/memory-engine-sql-apply.js +5 -2
  192. package/dist/plugins/memory-engine-tidb.js +4 -0
  193. package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
  194. package/dist/plugins/memory-sync-store-pg.js +5 -0
  195. package/dist/plugins/memory-sync-store-tidb.js +5 -0
  196. package/dist/plugins/one-time-migrations.d.ts +57 -63
  197. package/dist/plugins/one-time-migrations.js +162 -90
  198. package/dist/plugins/org-delivery-quota-store.js +4 -1
  199. package/dist/plugins/outcome-ledger-sql.js +2 -0
  200. package/dist/plugins/permission-rule-store-sql.js +11 -4
  201. package/dist/plugins/pg-cost-quota.js +4 -0
  202. package/dist/plugins/pg-pool.js +24 -1
  203. package/dist/plugins/pg-rate-limiter.js +2 -0
  204. package/dist/plugins/posix-shell-fs.d.ts +6 -1
  205. package/dist/plugins/posix-shell-fs.js +4 -1
  206. package/dist/plugins/remote-env-adb.d.ts +19 -15
  207. package/dist/plugins/remote-env-adb.js +41 -15
  208. package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
  209. package/dist/plugins/remote-env-connect-seat.js +72 -0
  210. package/dist/plugins/remote-env-device.d.ts +22 -5
  211. package/dist/plugins/remote-env-device.js +106 -8
  212. package/dist/plugins/remote-env-e2b.d.ts +15 -6
  213. package/dist/plugins/remote-env-e2b.js +42 -32
  214. package/dist/plugins/remote-env-file-error.js +6 -2
  215. package/dist/plugins/remote-env-host.d.ts +17 -0
  216. package/dist/plugins/remote-env-host.js +30 -38
  217. package/dist/plugins/remote-env-k8s.d.ts +41 -39
  218. package/dist/plugins/remote-env-k8s.js +53 -30
  219. package/dist/plugins/remote-env-local-docker.d.ts +13 -8
  220. package/dist/plugins/remote-env-local-docker.js +34 -41
  221. package/dist/plugins/remote-env-ssh.d.ts +18 -12
  222. package/dist/plugins/remote-env-ssh.js +60 -59
  223. package/dist/plugins/remote-shell.d.ts +98 -1
  224. package/dist/plugins/remote-shell.js +218 -0
  225. package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
  226. package/dist/plugins/resume-anchor-store-sql.js +12 -5
  227. package/dist/plugins/retention-lane-store-sql.js +4 -0
  228. package/dist/plugins/retention-sql.d.ts +20 -2
  229. package/dist/plugins/retention-sql.js +11 -0
  230. package/dist/plugins/run-store-sql.d.ts +21 -2
  231. package/dist/plugins/run-store-sql.js +31 -7
  232. package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
  233. package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
  234. package/dist/plugins/schema-consistency.d.ts +4 -2
  235. package/dist/plugins/schema-consistency.js +19 -2
  236. package/dist/plugins/send-file-ledger.js +3 -0
  237. package/dist/plugins/serving-requirement.d.ts +26 -7
  238. package/dist/plugins/serving-requirement.js +11 -4
  239. package/dist/plugins/session-birth.d.ts +6 -2
  240. package/dist/plugins/session-capture-record-store-sql.js +2 -0
  241. package/dist/plugins/session-ext-table.d.ts +14 -1
  242. package/dist/plugins/session-ext-table.js +5 -1
  243. package/dist/plugins/session-row-sql.d.ts +49 -2
  244. package/dist/plugins/session-row-sql.js +56 -13
  245. package/dist/plugins/session-store-sql.d.ts +34 -18
  246. package/dist/plugins/session-store-sql.js +98 -17
  247. package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
  248. package/dist/plugins/shared-memory-store-sql.js +6 -2
  249. package/dist/plugins/sql-driver.d.ts +2 -1
  250. package/dist/plugins/sql-driver.js +18 -3
  251. package/dist/plugins/sql-errors.d.ts +11 -6
  252. package/dist/plugins/sql-errors.js +5 -6
  253. package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
  254. package/dist/plugins/stop-then-start-sentence.js +14 -10
  255. package/dist/plugins/stop-then-start.d.ts +109 -0
  256. package/dist/plugins/stop-then-start.js +104 -0
  257. package/dist/plugins/store-backend.d.ts +40 -13
  258. package/dist/plugins/store-backend.js +169 -27
  259. package/dist/plugins/store-boundary.d.ts +57 -0
  260. package/dist/plugins/store-boundary.js +139 -0
  261. package/dist/plugins/store-contracts.d.ts +17 -0
  262. package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
  263. package/dist/plugins/store-fault-sentence-m53.js +25 -0
  264. package/dist/plugins/store-fault.d.ts +26 -7
  265. package/dist/plugins/store-fault.js +18 -2
  266. package/dist/plugins/task-attachment-store.js +9 -0
  267. package/dist/plugins/task-list-store-sql.d.ts +2 -2
  268. package/dist/plugins/task-list-store-sql.js +10 -8
  269. package/dist/plugins/tidb-cost-quota.js +4 -0
  270. package/dist/plugins/tidb-pool.js +2 -1
  271. package/dist/plugins/tidb-rate-limiter.js +4 -0
  272. package/dist/plugins/user-input-ledger-sql.js +4 -0
  273. package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
  274. package/dist/plugins/workflow-run-store-sql.js +64 -4
  275. package/dist/plugins/workspace-fill.d.ts +4 -7
  276. package/dist/plugins/workspace-fill.js +2 -1
  277. package/dist/plugins/write-behind-counter.js +5 -0
  278. package/dist/project-context.d.ts +0 -2
  279. package/dist/project-context.js +4 -8
  280. package/dist/project-registry.d.ts +46 -0
  281. package/dist/project-registry.js +44 -0
  282. package/dist/request-key-closure.js +1 -1
  283. package/dist/request-value-closure.d.ts +4 -0
  284. package/dist/request-value-closure.js +10 -0
  285. package/dist/run-acceptance.d.ts +3 -2
  286. package/dist/run-acceptance.js +4 -6
  287. package/dist/run-local.js +1 -0
  288. package/dist/runs.d.ts +37 -8
  289. package/dist/runs.js +53 -12
  290. package/dist/runtime-governance.d.ts +5 -4
  291. package/dist/security.d.ts +30 -32
  292. package/dist/security.js +41 -7
  293. package/dist/server-secret-env.d.ts +12 -10
  294. package/dist/server-secret-env.js +24 -15
  295. package/dist/session-bindings.d.ts +82 -0
  296. package/dist/session-bindings.js +18 -0
  297. package/dist/session-children-retire.d.ts +2 -2
  298. package/dist/session-children-retire.js +2 -6
  299. package/dist/session-deletion.d.ts +16 -1
  300. package/dist/session-error-wire.d.ts +3 -3
  301. package/dist/session-error-wire.js +3 -3
  302. package/dist/session-incarnation.d.ts +10 -0
  303. package/dist/session-incarnation.js +10 -1
  304. package/dist/session-kind.d.ts +57 -0
  305. package/dist/session-kind.js +22 -0
  306. package/dist/session-row.d.ts +21 -1
  307. package/dist/session-row.js +7 -1
  308. package/dist/session-sync-kernel.d.ts +24 -14
  309. package/dist/session-sync-kernel.js +3 -6
  310. package/dist/session-sync.d.ts +4 -98
  311. package/dist/session-sync.js +1 -71
  312. package/dist/session-titler.d.ts +10 -3
  313. package/dist/session-titler.js +19 -6
  314. package/dist/ssh-host-key.d.ts +5 -0
  315. package/dist/ssh-host-key.js +3 -0
  316. package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
  317. package/dist/stores-sql/file-history-store-sql.js +108 -70
  318. package/dist/stores-sql/pg-session-storage.d.ts +34 -7
  319. package/dist/stores-sql/pg-session-storage.js +37 -13
  320. package/dist/stores-sql/retention-store-sql.d.ts +1 -9
  321. package/dist/stores-sql/retention-store-sql.js +2 -10
  322. package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
  323. package/dist/stores-sql/session-policy-store-sql.js +61 -44
  324. package/dist/stores-sql/session-write-hooks.d.ts +11 -0
  325. package/dist/stores-sql/tidb-session-store.d.ts +58 -7
  326. package/dist/stores-sql/tidb-session-store.js +37 -13
  327. package/dist/submission-exit.d.ts +3 -2
  328. package/dist/submission-exit.js +9 -1
  329. package/dist/task-cwd.d.ts +2 -2
  330. package/dist/task-settings.d.ts +6 -5
  331. package/dist/terminal.d.ts +33 -2
  332. package/dist/terminal.js +139 -9
  333. package/dist/tool-approval.d.ts +140 -6
  334. package/dist/tool-approval.js +165 -72
  335. package/dist/trace/self-minted-wire.d.ts +290 -27
  336. package/dist/trace/self-minted-wire.js +101 -13
  337. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +78 -27
  338. package/package.json +2 -2
  339. package/wire-changes/server@7.151.0.json +762 -0
  340. package/dist/http/session-inherit-env.d.ts +0 -36
  341. package/dist/http/session-inherit-env.js +0 -6
package/dist/terminal.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { writeLogText } from "./observability/logger.js";
2
2
  import { terminalProjection } from "@sema-agent/core";
3
- import { errorCodeOf } from "./observability/err-text.js";
3
+ import { errorCodeOf, errorMemberOf } from "./observability/err-text.js";
4
4
  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
- import { storeFaultSentenceOfCode } from "./plugins/store-fault.js";
7
+ import { STORE_FAULT_CLASSES, StoreBoundaryFault, outwardStoreSentence, storeFaultClassOf } from "./plugins/store-fault.js";
8
+ import { errorOriginOf } from "./plugins/error-origin.js";
8
9
  import { readDenyFloorRefusalMessage, readDenyFloorSummaryOf } from "./read-deny-floor-notice.js";
9
10
  export function failureCodeOf(terminal) {
10
11
  return terminal.kind === "failed" ? terminal.code : undefined;
@@ -93,10 +94,13 @@ function foldCauseCode(terminal, at) {
93
94
  function outwardStoreFailure(code, message, at) {
94
95
  const outward = outwardFailureCode(code);
95
96
  reportFold(code, outward, message, at);
96
- return { code: outward, message: outwardStoreMessage(code) };
97
+ return { code: outward, message: outwardStoreMessageOf(code, message) };
97
98
  }
98
- function outwardStoreMessage(code) {
99
- return `${storeFaultSentenceOfCode(code)} [original code: ${code}]`;
99
+ export function outwardStoreMessageOf(code, message) {
100
+ return isOutwardStoreSentence(message, code) ? message : outwardStoreSentence(storeFaultClassOf({ code }), code);
101
+ }
102
+ function isOutwardStoreSentence(message, code) {
103
+ return typeof message === "string" && STORE_FAULT_CLASSES.some((cls) => message === outwardStoreSentence(cls, code));
100
104
  }
101
105
  export function outwardThrownMessage(err, message) {
102
106
  const code = errorCodeOf(err);
@@ -104,6 +108,123 @@ export function outwardThrownMessage(err, message) {
104
108
  return message;
105
109
  return outwardStoreFailure(code, message, "exit").message;
106
110
  }
111
+ export function storeBoundaryFault(err, site) {
112
+ if (err instanceof StoreBoundaryFault)
113
+ return err;
114
+ const origin = errorOriginOf(err);
115
+ switch (origin) {
116
+ case "caller":
117
+ return err;
118
+ case "driver":
119
+ case undefined:
120
+ break;
121
+ default: {
122
+ const unhandled = origin;
123
+ throw new Error(`store boundary: unknown error origin ${String(unhandled)}`);
124
+ }
125
+ }
126
+ if (isTypedFailure(err))
127
+ return rewriteDriverCause(err, site) ? err : reportedBoundaryForm(err, site);
128
+ if (!carriesDriverFault(err))
129
+ return err;
130
+ return reportedBoundaryForm(err, site);
131
+ }
132
+ const CAUSE_CHAIN_DEPTH = 8;
133
+ function boundaryFormOf(err) {
134
+ const coded = driverCodeOf(err);
135
+ return new StoreBoundaryFault(storeFaultClassOf(err), coded.code, coded.errno);
136
+ }
137
+ function reportBoundary(err, fault, site) {
138
+ reportFold(fault.code, fault.code === undefined ? "-" : outwardFailureCode(fault.code), errorMemberOf(err, "message"), { at: "store", site, faultClass: fault.faultClass, layers: chainSentences(err) });
139
+ }
140
+ function reportedBoundaryForm(err, site) {
141
+ const fault = boundaryFormOf(err);
142
+ reportBoundary(err, fault, site);
143
+ return fault;
144
+ }
145
+ function isTypedFailure(err) {
146
+ const code = errorMemberOf(err, "code");
147
+ return typeof code === "string" && code !== "" && outwardFailureCode(code) === code && errorOriginOf(err) !== "driver";
148
+ }
149
+ function carriesDriverFault(err) {
150
+ const coded = driverCodeOf(err);
151
+ return (coded.code !== undefined && outwardFailureCode(coded.code) !== coded.code) || driverOriginOnChain(err) || causeChainBeyondDepth(err);
152
+ }
153
+ function causeChainBeyondDepth(err) {
154
+ let cur = err;
155
+ for (let depth = 0; depth < CAUSE_CHAIN_DEPTH; depth++) {
156
+ if (cur === null || typeof cur !== "object")
157
+ return false;
158
+ cur = errorMemberOf(cur, "cause");
159
+ }
160
+ return cur !== null && typeof cur === "object";
161
+ }
162
+ function rewriteDriverCause(top, site) {
163
+ let parent = top;
164
+ for (let depth = 0; depth < CAUSE_CHAIN_DEPTH; depth++) {
165
+ const cur = errorMemberOf(parent, "cause");
166
+ if (cur === null || typeof cur !== "object" || cur instanceof StoreBoundaryFault || errorOriginOf(cur) === "caller")
167
+ return true;
168
+ if (isTypedFailure(cur)) {
169
+ parent = cur;
170
+ continue;
171
+ }
172
+ if (!carriesDriverFault(cur))
173
+ return true;
174
+ const fault = boundaryFormOf(cur);
175
+ if (!Reflect.defineProperty(parent, "cause", { value: fault, writable: true, configurable: true, enumerable: false }))
176
+ return false;
177
+ reportBoundary(cur, fault, site);
178
+ return true;
179
+ }
180
+ return false;
181
+ }
182
+ let storeBoundaryObserver;
183
+ export function setStoreBoundaryObserver(fn) {
184
+ storeBoundaryObserver = fn;
185
+ }
186
+ function driverCodeOf(err) {
187
+ let cur = err;
188
+ let fallback;
189
+ let errnoLink;
190
+ for (let depth = 0; cur !== null && typeof cur === "object" && depth < CAUSE_CHAIN_DEPTH; depth++) {
191
+ const code = errorMemberOf(cur, "code");
192
+ const errno = errorMemberOf(cur, "errno");
193
+ const integerErrno = typeof errno === "number" && Number.isInteger(errno) ? errno : undefined;
194
+ if (typeof code === "string" && code !== "") {
195
+ const link = { code, ...(integerErrno !== undefined ? { errno: integerErrno } : {}) };
196
+ if (code !== "unknown")
197
+ return link;
198
+ fallback ??= link;
199
+ }
200
+ if (integerErrno !== undefined)
201
+ errnoLink ??= { code: String(integerErrno), errno: integerErrno };
202
+ cur = errorMemberOf(cur, "cause");
203
+ }
204
+ return fallback ?? errnoLink ?? {};
205
+ }
206
+ function driverOriginOnChain(err) {
207
+ let cur = err;
208
+ for (let depth = 0; cur !== null && typeof cur === "object" && depth < CAUSE_CHAIN_DEPTH; depth++) {
209
+ if (errorOriginOf(cur) === "driver")
210
+ return true;
211
+ cur = errorMemberOf(cur, "cause");
212
+ }
213
+ return false;
214
+ }
215
+ function chainSentences(err) {
216
+ const layers = [];
217
+ let cur = err;
218
+ for (let depth = 0; cur !== null && typeof cur === "object" && depth < CAUSE_CHAIN_DEPTH; depth++) {
219
+ const message = errorMemberOf(cur, "message");
220
+ if (typeof message === "string" && message !== "")
221
+ layers.push(seatText("operator-log-text", message));
222
+ cur = errorMemberOf(cur, "cause");
223
+ }
224
+ if (layers.length === 0 && typeof err === "string" && err !== "")
225
+ layers.push(seatText("operator-log-text", err));
226
+ return layers.join(" | cause: ");
227
+ }
107
228
  function foldAttemptCodes(attempts, at) {
108
229
  if (!Array.isArray(attempts))
109
230
  return attempts;
@@ -123,15 +244,24 @@ function foldAttemptCodes(attempts, at) {
123
244
  return folded ?? attempts;
124
245
  }
125
246
  const STORED_RESULT_FOLD_TAG = "server.terminal.stored-result-code-folded";
126
- function reportFold(code, outward, message, at) {
247
+ function reportFold(code, outward, message, sighting) {
127
248
  const messageBytes = typeof message === "string" ? Buffer.byteLength(message, "utf8") : 0;
128
- const fields = `original=${isCodeToken(code) ? code : "<not-a-code>"} outward=${outward} messageBytes=${messageBytes} at=${at}`;
249
+ const at = typeof sighting === "string" ? sighting : sighting.at;
250
+ const original = code === undefined ? "<uncoded>" : isCodeToken(code) ? code : "<not-a-code>";
251
+ const fields = `original=${original} outward=${outward} messageBytes=${messageBytes} at=${at}`;
129
252
  switch (at) {
130
253
  case "exit": {
131
254
  const sentence = typeof message === "string" && message !== "" ? ` message=${JSON.stringify(seatText("operator-log-text", message))}` : "";
132
255
  writeLogText("stderr", `[terminal] outward_failure_code_folded ${fields}${sentence}`);
133
256
  return;
134
257
  }
258
+ case "store": {
259
+ const where = sighting;
260
+ const layers = where.layers !== "" ? ` message=${JSON.stringify(where.layers)}` : "";
261
+ writeLogText("stderr", `[terminal] outward_failure_code_folded ${fields} site=${where.site} class=${where.faultClass}${layers}`);
262
+ storeBoundaryObserver?.(where.site, where.faultClass);
263
+ return;
264
+ }
135
265
  case "run.result":
136
266
  case "ev.done.result":
137
267
  recordFailOpen(STORED_RESULT_FOLD_TAG, fields);
@@ -160,7 +290,7 @@ function outwardProjection(terminal, at) {
160
290
  const presented = at === "exit" && plane.status === "failed" ? readDenyFloorRefusalMessage(plane.errorCode) : undefined;
161
291
  return presented === undefined ? plane : { ...plane, errorMessage: presented };
162
292
  }
163
- return plane.status === "failed" ? { ...plane, errorCode: outward, errorMessage: outwardStoreMessage(plane.errorCode) } : { ...plane, errorCode: outward };
293
+ return plane.status === "failed" ? { ...plane, errorCode: outward, errorMessage: outwardStoreMessageOf(plane.errorCode, plane.errorMessage) } : { ...plane, errorCode: outward };
164
294
  }
165
295
  export function nestedPauseOf(terminal) {
166
296
  return terminal.kind === "failed" ? terminal.nestedPause : undefined;
@@ -200,7 +330,7 @@ export function persistedPlaneOf(result) {
200
330
  return {
201
331
  ...(typeof r.status === "string" ? { status: r.status } : {}),
202
332
  ...(typeof r.errorCode === "string" ? { errorCode: outwardFailureCode(r.errorCode) } : {}),
203
- ...(typeof r.errorMessage === "string" ? { errorMessage: flatFolded && typeof r.errorCode === "string" ? outwardStoreMessage(r.errorCode) : r.errorMessage } : {}),
333
+ ...(typeof r.errorMessage === "string" ? { errorMessage: flatFolded && typeof r.errorCode === "string" ? outwardStoreMessageOf(r.errorCode, r.errorMessage) : r.errorMessage } : {}),
204
334
  ...(typeof r.blockedReason === "string" ? { blockedReason: r.blockedReason } : {}),
205
335
  };
206
336
  }
@@ -6,7 +6,7 @@ import { type CardRulePersisted, type RuleConsentLane } from "./rules-consent.js
6
6
  import type { GateCurrencyStore } from "./approval-gate-currency.js";
7
7
  import { type HitlTransport } from "./hitl-delivery.js";
8
8
  import { type AllowRuleShadowProjection, type DenialLimitFallback, type RuleOffersAbsence, type ApprovalRequestFrame, type ApprovalRevokeFrame, type ApprovalCardLegFrame, type ApprovalCompleteFrame, type RuleEvidenceProjection } from "./approval-card.js";
9
- import { type ApprovalAskStore, type AskRow } from "./plugins/approval-ask-store-sql.js";
9
+ import { type ApprovalAskStore, type AskDecision, type AskDecisionRecord, type AskRow, type DecideResult, type RecordParkedDecisionResult } from "./plugins/approval-ask-store-sql.js";
10
10
  import type { ApprovalAskAuditSink } from "./approval-ask-audit-store.js";
11
11
  import { type AskRowEndingCause, type SettleCause, type SettleOutcome } from "./approval-deny-reasons.js";
12
12
  import type { ParkCommitWatch } from "./plugins/park-commit-watch.js";
@@ -36,7 +36,7 @@ export declare const MAX_ALLOW_SESSIONS = 4096;
36
36
  export declare function approvalDecidePath(sessionId: string): string;
37
37
  /**
38
38
  * 一只转停驻的问**去哪只会话决** —— 它的停车行(检查点卡)落在哪只会话上,耐久回决口 `POST /v1/approvals/:sessionId/decide` 就按这只会话找卡(卡自己的会话,
39
- * 决断口的地址;不是卡归属的 run 会话 —— cascade 级上的卡归调用方的 run,却只能在级自己的会话上决)。三处同读这一只:决断口对 PARKED 行的 `410 gone.ask_parked`
39
+ * 决断口的地址;不是卡归属的 run 会话 —— cascade 级上的卡归调用方的 run,却只能在级自己的会话上决)。三处同读这一只:决断口对 PARKED 行在这台部署交不了停驻赎回时(直连门)的 `410 gone.ask_parked`
40
40
  * 回显、迟到回决口对 PARKING 行的 `202` 与按问读口 `parked` 的 `decidePath`。
41
41
  * 停车行落在**铸它那条腿**的会话上 = 行上的发起会话 `sourceSessionId`(core 铸停车行的 `sessionId` 与铸这一问的发起会话是同一只变量;根腿 = 行上的会话,
42
42
  * 委派 / 后台子代腿 = 子代自己的会话,不是行上记的投递会话):
@@ -93,6 +93,14 @@ export type ToolApprovalReadBody = ({
93
93
  state: "void";
94
94
  cause?: AskRowEndingCause;
95
95
  } & AskRowReadProjection);
96
+ /** 一条行的**可读决议**(权威四合取:二值 ∧ 非 provisional ∧ 有 `decidedAtMs` ∧ 态确为 DECIDED;四合取各自的来由见耐久决断口 `decidedRowIsAuthoritative`
97
+ * 的顶注)。**这是那只判据的唯一读法** —— 读口、晚答口、唯一写者的迟到臂、耐久决断口的守卫都读它。读不出 ⇒ `undefined`(各口按「不是一条可用的人的决议」
98
+ * 处置,绝不把坏行包装成首决交出去)。 */
99
+ export declare function decidedRowFacts(row: AskRow): {
100
+ decision: "allow" | "deny";
101
+ decidedAtMs: number;
102
+ decisionNote?: string;
103
+ } | undefined;
96
104
  /**
97
105
  * 结算一张卡的**判决** —— 判别联合,逼每个调用点说清「这次等待是怎么结束的」:
98
106
  * · `by:"human"` —— 一次**决议**到了(人答,或从问账行读回来的决议,含部署政策拒落成的 `DECIDED` 行,`hostSource` 记它的来源词与机器座位):`allowed` 说方向;审计 settle 行
@@ -169,10 +177,71 @@ export interface ParkedAskRedeemRequest {
169
177
  * **checkpoint 当下的 scope** 对一次(codex R1-[high] 一:收编改写身份之后,任何缓存的属主判据都
170
178
  * 过期;门必须贴在当下的持久事实上)。 */
171
179
  principal?: string;
180
+ /** 调用方的**运维身份**(交来这一问的那扇门已判过的那一格;[ref] α):席复核 checkpoint 当下的 scope、续跑腿复核载入行时按它读面表 `scope.decide` 的运维列。
181
+ * 耐久决断口 = 它的面表 `ask.decide` 运维列读到的那位(显式运维代决别人的卡,live 与停驻两形同放);应答口恒 `false`(面表 `ask.answer` 没有运维列)。
182
+ * 必填:缺省等于替门作答「不是运维」或「是运维」—— 两个方向都是同一扇门对两形说两种话。 */
183
+ operator: boolean;
172
184
  /** 发起本次 respond 的真实 HTTP 请求。赎回腿据它做准入解析与舰队 scope(与 `/decide` 腿同姿势);
173
185
  * 缺席 ⇒ 那条腿按「无请求」形处置(它自己的成文语义,本席不替它决定)。 */
174
186
  httpReq?: IncomingMessage;
175
187
  }
188
+ /**
189
+ * 一次对停驻卡的决定 —— 两扇门(应答口 PARKED 臂、耐久决断口)交给**同一只**赎回(`ToolApprovalCoordinator` 的 `runParkedFlight`)的那一份。
190
+ * 门各自已过属主门、把自己的词映进来:`write` = 这次决定的记录(决议向 · 出处 · 理由 · 署名 · 键 —— 停驻门受理之后落在问行上的就是它),其余是停驻门要的余项。
191
+ */
192
+ export interface ParkedDecisionRequest {
193
+ readonly write: AskDecisionWrite;
194
+ /** 「本会话放行」(应答口的 `allow_session`;与 `/decide` 的 `remember:"session"` 同一只请求、同一个铸点)。耐久决断口的体今天没有这一位(随 live 词表一起收)。 */
195
+ readonly remember?: "session";
196
+ /** 「不再询问」的规则位(应答口体上的 `persistRule`;素材取行,{@link ToolApprovalCoordinator} 的 `persistRuleFromRow`)。耐久决断口的体今天没有这一位。 */
197
+ readonly persistRule?: ParsedPersistRule;
198
+ /** ctrl+g 编辑实参(只 approve 交给门的绑定;不落问行)。 */
199
+ readonly updatedInput?: unknown;
200
+ readonly principal?: string;
201
+ /** 见 {@link ParkedAskRedeemRequest.operator}(同一格,原样交席)。 */
202
+ readonly operator: boolean;
203
+ /** 要人门([ref])的判词,由口按这张卡与决定者位判好交来(`true` ⇒ 这一形的放行不归策略答)。只在「这一次要写」时读:门上已站着决定 ⇒ 先回放 / 冲突。 */
204
+ readonly policyMayNotApprove?: boolean;
205
+ readonly httpReq?: IncomingMessage;
206
+ }
207
+ /** 耐久决断口对一只停驻的问拿到的答案(`ToolApprovalCoordinator.decideParkedAsk`;口按自己的 wire 律渲染,与 `DECIDED` 行同一条回放 / 冲突律)。 */
208
+ export type ParkedAskAnswer =
209
+ /** 本次请求被停驻门受理(赎回席的受理恒是 `200`:`acceptedResumingReceipt` 一只铸点;`body` = 那只受理体;`recorded` = 受理之后落了记录的那一行,没落成 ⇒ 缺席)。 */
210
+ {
211
+ readonly kind: "accepted";
212
+ readonly body: Record<string, unknown>;
213
+ readonly recorded?: AskRow;
214
+ }
215
+ /** 没生效(门 / 席 / 准入的拒,原样)。 */
216
+ | {
217
+ readonly kind: "refused";
218
+ readonly status: number;
219
+ readonly body: Record<string, unknown>;
220
+ }
221
+ /** 门上已站着一次决定(向 / 时刻 / 理由取门;署名取行上的记录 —— 只在记录说的就是门上这一向时;`byThisRequest` = 本次请求的键就是记录上那把)。 */
222
+ | {
223
+ readonly kind: "standing";
224
+ readonly decision: AskDecision;
225
+ readonly decidedAtMs: number;
226
+ readonly decisionNote?: string;
227
+ readonly actor?: unknown;
228
+ readonly byThisRequest: boolean;
229
+ }
230
+ /**
231
+ * 这台部署上停驻形**只有耐久审批门收**:赎回席没接(直连门部署 —— 停驻门的决定要签名信封,而这扇口没有决策证明;fail-closed,接线处 `boot/late-binds.ts`),
232
+ * 或行上没有门坐标(受损行,没有门可交)。口按自己的词指路那道门。
233
+ */
234
+ | {
235
+ readonly kind: "gate_only";
236
+ }
237
+ /** 重判那一读读不出 / 行已不在门判过的属主域(门读之后被收编改写)⇒ 与查无同答(口按自己的词)。 */
238
+ | {
239
+ readonly kind: "gone";
240
+ }
241
+ /** 要写的是一次策略对要人的卡的放行(`ParkedDecisionRequest.policyMayNotApprove`)⇒ 写之前拒(口按自己的词;与 live 形同一道门、同一个位置)。 */
242
+ | {
243
+ readonly kind: "policy_refused";
244
+ };
176
245
  /** [ref]:赎回席的结局 = 赎回腿的原始 HTTP 结果面 + 请求带了 `remember` 时铸点的真答(`rememberApplied`:落没落;不进 `body` —— 首次受理的回执挂它,
177
246
  * 受理回执(幂等回放的那一份)不存它)。 */
178
247
  export interface ParkedAskRedeemResult {
@@ -1017,6 +1086,35 @@ export declare function parseToolApprovalResponse(body: unknown): ParsedToolAppr
1017
1086
  ok: false;
1018
1087
  error: string;
1019
1088
  } & Partial<RetiredDecisionKeyFacts["extra"]>);
1089
+ /**
1090
+ * **一次人对一张卡的决定** —— 两扇门(live 应答口 `POST /v1/tool-approvals/:id/respond`、耐久决断口 `POST /v1/tasks/:taskId/asks/:askId/decision`)
1091
+ * 两形(live / 停驻)落行的唯一入参形;{@link ToolApprovalCoordinator.writeAskDecision} 是它唯一的写者,{@link askDecisionRecordOf} 是它到店记录的唯一映射。
1092
+ * `actor` = 耐久决断口铸的署名(审计投影,恒由已验证主体派生;应答口不铸,列 NULL);`idempotencyKey` = 耐久决断口的回决幂等键(应答口没有这一位)。
1093
+ */
1094
+ export interface AskDecisionWrite {
1095
+ readonly decision: AskDecision;
1096
+ readonly decider: ApprovalDecider;
1097
+ readonly note?: string;
1098
+ readonly actor?: unknown;
1099
+ readonly idempotencyKey?: string;
1100
+ }
1101
+ /** live 形的决定另带 ctrl+g 编辑实参(`undefined` = 没带;**`null` 是值**,语义三态的属主 = `AskRow.updatedInput`):随决议同一条 CAS 落列、交给在等的那条腿。
1102
+ * 停驻形的编辑走停驻门的绑定(`DecideBinding.updatedInput`),不落问行。 */
1103
+ export interface LiveAskDecisionWrite extends AskDecisionWrite {
1104
+ readonly updatedInput?: unknown;
1105
+ }
1106
+ /** 一张卡的人决落在哪一形上:live = `STREAM_PENDING → DECIDED` 的单赢者 CAS(带批维);停驻 = 停驻门受理之后落在仍 `PARKED` 的行上。 */
1107
+ export type AskDecisionForm = {
1108
+ readonly kind: "live";
1109
+ readonly batchId: string;
1110
+ } | {
1111
+ readonly kind: "parked";
1112
+ };
1113
+ /**
1114
+ * {@link AskDecisionWrite} → 店的那份记录({@link AskDecisionRecord})—— **唯一映射**(两形同读)。出处两格经同步座映射 {@link liveHostSource}
1115
+ * (`person` ⇒ 不写 = 列 NULL = 人决;`policy` ⇒ `"policy"` + 座位),理由空 ⇒ NULL,署名 / 键缺席 ⇒ NULL。
1116
+ */
1117
+ export declare function askDecisionRecordOf(write: AskDecisionWrite): AskDecisionRecord;
1020
1118
  /**
1021
1119
  * [ref] R-13 C —— `UNATTENDED_APPROVAL_POLICY` 的**闭集**词表([ref]Q1「裁2:A+C」/[ref] 裁②)。
1022
1120
  *
@@ -1378,9 +1476,9 @@ export declare class ToolApprovalCoordinator {
1378
1476
  /** [ref] F4:悬挂决议轮询腿的**轮转游标**(整数偏移,与集合成员无关 —— 理由见
1379
1477
  * `pollSuspendedDecisions` 里那段:按 askId 记的形会在「上一拍最后碰的那条被结算掉」时塌回队首,
1380
1478
  * 构造出永久饥饿的前缀)。只回答「上一拍扫到第几个」,单调推进、按当前长度取模。 */
1381
- private suspendedPollOffset;
1382
- /** [ref]:悬挂轮询腿第二层(接管登记)的轮转游标 —— 与 {@link suspendedPollOffset} 同一条理由,两层各一只。 */
1383
- private adoptedPollOffset;
1479
+ private readonly suspendedPollCursor;
1480
+ /** [ref]:悬挂轮询腿第二层(接管登记)的轮转游标 —— 与 {@link suspendedPollCursor} 同一条理由,两层各一只。 */
1481
+ private readonly adoptedPollCursor;
1384
1482
  /** [ref] + codex R3-[critical]:askId → **此刻正带着 `updatedInput` 决它的请求数**(见
1385
1483
  * {@link markEditedDecisionInFlight} 顶注)。只在 `decideAsk` 那一次调用期间非空,故天然有界。 */
1386
1484
  private readonly editedDecisionsInFlight;
@@ -2158,7 +2256,7 @@ export declare class ToolApprovalCoordinator {
2158
2256
  * 同向迟到答与**反向**迟到答同判:都是 200 回放**首决**。反向不是 409、不是报错、更不改判 —— 那是
2159
2257
  * 一个 CAS 败者的诚实答:决议早已由首决落定,这次请求只是晚到,响应体把首决交回去,消费端自判向。
2160
2258
  *
2161
- * 权威性四合取与 durable 回决腿的 `decidedRowIsAuthoritative` **同判据**(那处顶注是唯一真源):
2259
+ * 权威性四合取 = {@link decidedRowFacts}(唯一读法;四合取的来由见 durable 回决腿 `decidedRowIsAuthoritative` 的顶注):
2162
2260
  * 决议二值 ∧ 非 provisional ∧ 有 `decidedAtMs` ∧ 态确为 DECIDED。不合形 ⇒ 退回修前 404(绝不把一条
2163
2261
  * 坏行包装成「人的首决」交出去);此处比那条腿更保守地不铸 500,理由是本腿的客户端是壳上那张卡,
2164
2262
  * 它对 404 有成文处置(消卡),对 500 没有。
@@ -2175,6 +2273,27 @@ export declare class ToolApprovalCoordinator {
2175
2273
  * 非 2xx 原样透出(gate 被别人收走 ⇒ 409 等),绝不粉饰成受理。
2176
2274
  */
2177
2275
  private redeemParkedAsk;
2276
+ /**
2277
+ * 🔴 **停驻卡的那一只赎回**(两扇门同一只;[ref] α):准入 → 开格(单飞句柄)→ 一飞(赎回席 → 落行 → 规则位)→ 收格 / 留回执。
2278
+ * 两扇门各自先过自己的属主门、把这一问的词映成 {@link ParkedDecisionRequest},然后都交这里 —— 计费 / 就绪 / 服务凭据三道门、checkpoint 当下的 scope 复核、
2279
+ * 「本会话放行」的铸点、规则位的兑付、决定的落行,一处一份。
2280
+ *
2281
+ * 句柄内的序是硬的(与 live 腿同一条纪律):赎回席非 2xx ⇒ 什么都不落(一次没生效的决定不留记录、不留规则);2xx ⇒ **先**落行(停驻卡的决定记在它的问行上,
2282
+ * 唯一写者 {@link writeAskDecision} 的停驻形),**再**兑规则位。两件都在句柄之内:单飞的后到者 `await` 的就是这枚句柄,它拿到的答案与行上的记录同时成立。
2283
+ * 落行失败(店错 / 超时 / 键被同 task 另一只问抢先占了)不改判:这次决定已经被停驻门受理、续跑已经开始 —— 记一笔 fail-open(登记 tag),回执照常;
2284
+ * 代价是这一问的耐久回放(同键重发)读不到这把键,重发不是回放(店错 ⇒ 首决回显的冲突句;键被另一只问占着 ⇒ 决断口幂等预查的跨问冲突句)。
2285
+ */
2286
+ private runParkedFlight;
2287
+ /** 停驻门受理之后落行(唯一写者的停驻形)。落成 ⇒ 落后的行;没落成 ⇒ `undefined` + 一笔 fail-open(这次决定照常生效,见 {@link runParkedFlight} 顶注)。 */
2288
+ private recordParkedOutcome;
2289
+ /**
2290
+ * 🔴 **耐久决断口对一只停驻的问**([ref] α:留下的那扇口吃下停驻形;此前这里答 `410 gone.ask_parked` 指路 `/decide`)。属主门 `ask.decide` 与体门在调用方
2291
+ * (`routes/runs.ts`)已过;要人门的判词由调用方判好交进来({@link ParkedDecisionRequest.policyMayNotApprove}),这里在「这一次要写」时用。停驻形的两件:
2292
+ * ① **门上已站着一次决定吗**({@link standingParkedDecision}:读停驻门 + 行上的记录)⇒ 站着 ⇒ 交回它(调用方按与 `DECIDED` 行同一条律答:同键 ⇒ 200 回放;否则 409 首决回显)。
2293
+ * ② 没站着(门仍开着 —— 从没被决过,或被引擎重开过)⇒ 交**同一只**赎回({@link runParkedFlight}),受理后决定落行。
2294
+ * 判只在本副本上没有这只问的赎回在飞时做(有 ⇒ 等它落定、从头再读再判);赎回没生效而门此刻已决 ⇒ 也从头再判(答案是门上那一次)。不读应答口的进程内回执:本口的回放律读行 + 门。
2295
+ */
2296
+ decideParkedAsk(store: ApprovalAskStore, row: AskRow, request: ParkedDecisionRequest, idempotencyKey: string | undefined): Promise<ParkedAskAnswer>;
2178
2297
  /**
2179
2298
  * [ref] —— **durable 回决腿的规则位**:PARKED 行的迟到决议携 `persistRule` 时,用**行上**的素材兑付。
2180
2299
  *
@@ -2223,6 +2342,21 @@ export declare class ToolApprovalCoordinator {
2223
2342
  * 放行凭空消失。诚实的形是 200 + `rulePersisted:false`(壳据它告诉人「这次放行了,但『不再询问』没存上」)。
2224
2343
  */
2225
2344
  private persistRuleAfterDecision;
2345
+ /**
2346
+ * 🔴 **一张卡的人决的唯一写者**(两扇门 × 两形同一只;店上两只动词 `decideAsk` / `recordParkedDecision` 在 src 里只有这里调 —— 钉 `test/ask-decision-single-writer.test.ts`)。
2347
+ * · live 形:`STREAM_PENDING → DECIDED` 的单赢者 CAS(批维 + [ref] 属主维),套墙钟上限;**迟到的成功**(这次调用报了超时,决议其实落了盘)⇒
2348
+ * 行过了权威四合取({@link decidedRowFacts})才把同 askId 下还挂着的本地条目按**行**结清(结算取行,[ref]),不让它们等自己的窗再绕一圈。应答口(`respondWithCas`)与耐久决断口(`routes/runs.ts`)都经这里 ——
2349
+ * 此前两口各自拼一份入参、各打一次 `decideAsk`,出处 / 编辑 / 理由的映射是两份,超时与迟到收尾只有一口有。
2350
+ * · 停驻形:停驻门(续跑腿的门 CAS)**已经受理**之后把记录落在仍 `PARKED` 的行上(态不变,终局恒是那道门);只由停驻赎回的那一飞调({@link runParkedFlight})。
2351
+ * 入参映射只有一只({@link askDecisionRecordOf} / {@link liveDecideInputOf})。抛 = 店错 / 超时(调用方各自的歧义臂接)。
2352
+ */
2353
+ writeAskDecision(store: ApprovalAskStore, askId: string, form: {
2354
+ readonly kind: "live";
2355
+ readonly batchId: string;
2356
+ }, owner: string | null, write: LiveAskDecisionWrite): Promise<DecideResult>;
2357
+ writeAskDecision(store: ApprovalAskStore, askId: string, form: {
2358
+ readonly kind: "parked";
2359
+ }, owner: string | null, write: AskDecisionWrite): Promise<RecordParkedDecisionResult>;
2226
2360
  /** store 在场时的回决 CAS 门(D2)——`respond()` 的异步分支,拆出以保持 `respond()` 本身在 store 缺席
2227
2361
  * 时仍是纯同步函数(D1)。`askStore`/`askId`/`batchId` 由调用方在已窄化的分支里传入(避免非空断言)。 */
2228
2362
  private respondWithCas;