@sema-agent/server 7.141.0 → 7.143.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 +657 -0
  2. package/USAGE.md +102 -30
  3. package/dist/adoption/plan.js +22 -0
  4. package/dist/approval-ask-audit-store.d.ts +61 -43
  5. package/dist/approval-ask-audit-store.js +69 -44
  6. package/dist/approval-ask-machine.d.ts +15 -7
  7. package/dist/approval-ask-machine.js +10 -4
  8. package/dist/approval-card.d.ts +126 -27
  9. package/dist/approval-card.js +103 -23
  10. package/dist/approval-crash-convergence.d.ts +17 -7
  11. package/dist/approval-crash-convergence.js +94 -22
  12. package/dist/approval-deny-reasons.d.ts +34 -30
  13. package/dist/approval-deny-reasons.js +21 -6
  14. package/dist/approval-policy-settlement.d.ts +1 -1
  15. package/dist/approval-queue-kind.d.ts +27 -0
  16. package/dist/approval-queue-kind.js +6 -0
  17. package/dist/approval-reconciler.d.ts +41 -9
  18. package/dist/approval-reconciler.js +45 -42
  19. package/dist/audit.js +4 -2
  20. package/dist/auth-bridge.d.ts +9 -6
  21. package/dist/auth-bridge.js +9 -3
  22. package/dist/boot/adoption.js +2 -1
  23. package/dist/boot/budget-tracing.d.ts +17 -1
  24. package/dist/boot/budget-tracing.js +10 -6
  25. package/dist/boot/device-lane.d.ts +1 -1
  26. package/dist/boot/execution-env.d.ts +24 -4
  27. package/dist/boot/execution-env.js +26 -23
  28. package/dist/boot/execution-lane.js +2 -1
  29. package/dist/boot/exit-boundary.js +5 -4
  30. package/dist/boot/governance-seams.d.ts +26 -41
  31. package/dist/boot/governance-seams.js +61 -28
  32. package/dist/boot/late-binds.d.ts +7 -4
  33. package/dist/boot/late-binds.js +3 -1
  34. package/dist/boot/leader.js +2 -4
  35. package/dist/boot/memory-consolidation.d.ts +0 -8
  36. package/dist/boot/memory-consolidation.js +5 -4
  37. package/dist/boot/parked-revive-gate.js +2 -1
  38. package/dist/boot/permission-rules-audit.d.ts +0 -28
  39. package/dist/boot/permission-rules-audit.js +2 -1
  40. package/dist/boot/read-deny-anchor-audit.js +2 -1
  41. package/dist/boot/reapers.js +9 -7
  42. package/dist/boot/resolve-spec.d.ts +1 -1
  43. package/dist/boot/resolve-spec.js +19 -10
  44. package/dist/boot/retention-lane.js +5 -3
  45. package/dist/boot/runner-deps.d.ts +10 -7
  46. package/dist/boot/runner-deps.js +20 -29
  47. package/dist/boot/runtime-caps.js +3 -2
  48. package/dist/boot/session-faces.js +4 -3
  49. package/dist/boot/shutdown.d.ts +9 -0
  50. package/dist/boot/shutdown.js +19 -4
  51. package/dist/boot/stage-02-web-admin-pull.js +3 -0
  52. package/dist/boot/stage-03-store-backend.d.ts +4 -1
  53. package/dist/boot/stage-03-store-backend.js +1 -2
  54. package/dist/boot/stage-04-stores.d.ts +5 -2
  55. package/dist/boot/stage-04-stores.js +6 -7
  56. package/dist/boot/stage-05-execution-env.d.ts +6 -3
  57. package/dist/boot/stage-05-execution-env.js +8 -6
  58. package/dist/boot/stage-06-runners.d.ts +6 -3
  59. package/dist/boot/stage-06-runners.js +3 -4
  60. package/dist/boot/stage-07-capability-layer.d.ts +6 -3
  61. package/dist/boot/stage-07-capability-layer.js +7 -2
  62. package/dist/boot/stage-08-reapers.d.ts +6 -3
  63. package/dist/boot/stage-08-reapers.js +3 -2
  64. package/dist/boot/stage-09-leader.d.ts +6 -3
  65. package/dist/boot/stage-10-http-server.d.ts +6 -3
  66. package/dist/boot/stage-10-http-server.js +14 -5
  67. package/dist/boot/stores.d.ts +5 -2
  68. package/dist/boot/stores.js +10 -9
  69. package/dist/boot/web-admin.d.ts +5 -1
  70. package/dist/boot/web-admin.js +48 -36
  71. package/dist/boot/webfetch-summarize-lane.js +2 -1
  72. package/dist/boot/workflow-orchestration.js +3 -2
  73. package/dist/capabilities/builtin-tools.d.ts +2 -1
  74. package/dist/capabilities/builtin-tools.js +2 -4
  75. package/dist/capabilities/composite-members.d.ts +2 -1
  76. package/dist/capabilities/composite-members.js +2 -1
  77. package/dist/capabilities/hands-lane.d.ts +9 -39
  78. package/dist/capabilities/hands-lane.js +8 -13
  79. package/dist/capabilities/mcp-probe.d.ts +3 -2
  80. package/dist/capabilities/scenarios.d.ts +11 -1
  81. package/dist/capabilities/scenarios.js +1 -0
  82. package/dist/capabilities/skills.d.ts +1 -17
  83. package/dist/capabilities/skills.js +0 -8
  84. package/dist/capability-facts.d.ts +31 -7
  85. package/dist/capability-facts.js +27 -4
  86. package/dist/card-void.d.ts +6 -9
  87. package/dist/config-catalog.js +2 -1
  88. package/dist/config-dir-trust.js +58 -29
  89. package/dist/config-invariants.d.ts +7 -1
  90. package/dist/config-invariants.js +7 -0
  91. package/dist/config-provider.d.ts +10 -0
  92. package/dist/config-provider.js +15 -4
  93. package/dist/config-root-migration.d.ts +13 -0
  94. package/dist/config-root-migration.js +99 -0
  95. package/dist/config-types.d.ts +19 -8
  96. package/dist/config.d.ts +10 -3
  97. package/dist/config.js +18 -4
  98. package/dist/delegated-session-owner.d.ts +5 -3
  99. package/dist/delegated-session-owner.js +1 -1
  100. package/dist/device-ws-protocol.d.ts +1 -0
  101. package/dist/device-ws-protocol.js +2 -1
  102. package/dist/env-model-table-gate.d.ts +53 -0
  103. package/dist/env-model-table-gate.js +53 -0
  104. package/dist/execution-lane-caps.d.ts +2 -1
  105. package/dist/fleet/fleet-bus.d.ts +34 -55
  106. package/dist/fleet/fleet-bus.js +35 -100
  107. package/dist/fleet/fleet-reconciler.d.ts +4 -4
  108. package/dist/fleet/fleet-reconciler.js +1 -1
  109. package/dist/fleet/subagent-tail-bus.d.ts +14 -11
  110. package/dist/fleet/subagent-tail-bus.js +15 -28
  111. package/dist/hooks/hook-runner.d.ts +6 -0
  112. package/dist/hooks/hook-runner.js +58 -8
  113. package/dist/host-decision.d.ts +54 -20
  114. package/dist/host-decision.js +42 -14
  115. package/dist/http/admission.d.ts +1 -1
  116. package/dist/http/admission.js +7 -3
  117. package/dist/http/approval-sweeps.js +11 -8
  118. package/dist/http/caller-trust.d.ts +1 -1
  119. package/dist/http/dispatch.js +4 -2
  120. package/dist/http/durable-run-leg.js +2 -2
  121. package/dist/http/engine-refusal.d.ts +16 -0
  122. package/dist/http/engine-refusal.js +17 -0
  123. package/dist/http/execution-context.d.ts +2 -2
  124. package/dist/http/idempotency.d.ts +1 -1
  125. package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
  126. package/dist/http/memory-compliance-failure-reply.js +4 -6
  127. package/dist/http/owner-access.d.ts +11 -0
  128. package/dist/http/owner-access.js +13 -0
  129. package/dist/http/principal-gate.d.ts +3 -1
  130. package/dist/http/principal-gate.js +17 -8
  131. package/dist/http/resume-legs.d.ts +21 -7
  132. package/dist/http/resume-legs.js +76 -58
  133. package/dist/http/resume-restatement.d.ts +39 -0
  134. package/dist/http/resume-restatement.js +25 -0
  135. package/dist/http/route-ctx.d.ts +35 -10
  136. package/dist/http/route-ctx.js +1 -1
  137. package/dist/http/route-table.js +2 -0
  138. package/dist/http/routes/approvals-assistant.d.ts +9 -1
  139. package/dist/http/routes/approvals-assistant.js +142 -31
  140. package/dist/http/routes/attachments.js +18 -0
  141. package/dist/http/routes/capabilities.js +16 -4
  142. package/dist/http/routes/memory-policy.d.ts +2 -2
  143. package/dist/http/routes/memory-policy.js +27 -7
  144. package/dist/http/routes/notify-wake.js +23 -25
  145. package/dist/http/routes/rules.js +48 -13
  146. package/dist/http/routes/runs.js +12 -11
  147. package/dist/http/routes/session-memory-sync.d.ts +91 -0
  148. package/dist/http/routes/session-memory-sync.js +174 -0
  149. package/dist/http/routes/session-sync.js +13 -20
  150. package/dist/http/routes/sessions-list.d.ts +2 -1
  151. package/dist/http/routes/sessions.d.ts +2 -2
  152. package/dist/http/routes/sessions.js +22 -23
  153. package/dist/http/routes/tasks.js +34 -54
  154. package/dist/http/run-read-face.d.ts +7 -0
  155. package/dist/http/run-read-face.js +9 -3
  156. package/dist/http/send.d.ts +5 -0
  157. package/dist/http/send.js +9 -2
  158. package/dist/http/server.d.ts +27 -15
  159. package/dist/http/server.js +4 -6
  160. package/dist/http/stored-body-replay.js +15 -4
  161. package/dist/http/submit-replay.d.ts +4 -3
  162. package/dist/http/submit-replay.js +2 -2
  163. package/dist/http/sync-submit-body.d.ts +21 -4
  164. package/dist/http/sync-submit-body.js +13 -0
  165. package/dist/http/wire-types.d.ts +17 -7
  166. package/dist/identity-source.d.ts +21 -2
  167. package/dist/identity-source.js +6 -0
  168. package/dist/leader/leader.js +5 -2
  169. package/dist/leader/wire.d.ts +7 -1
  170. package/dist/leader/wire.js +6 -5
  171. package/dist/leg-facts.d.ts +37 -0
  172. package/dist/leg-facts.js +15 -0
  173. package/dist/memory-bundle-engine.d.ts +1 -4
  174. package/dist/memory-bundle-engine.js +2 -2
  175. package/dist/memory-incident-sink.d.ts +19 -6
  176. package/dist/memory-incident-sink.js +8 -4
  177. package/dist/memory-operator-faces.d.ts +30 -66
  178. package/dist/memory-operator-faces.js +17 -88
  179. package/dist/memory-scope-stores.d.ts +38 -40
  180. package/dist/memory-scope-stores.js +51 -36
  181. package/dist/memory-scope.d.ts +0 -9
  182. package/dist/memory-scope.js +0 -9
  183. package/dist/memory-sync-client.d.ts +21 -21
  184. package/dist/memory-sync-client.js +62 -43
  185. package/dist/memory-sync-identity.d.ts +24 -0
  186. package/dist/memory-sync-identity.js +57 -0
  187. package/dist/memory-sync.d.ts +27 -5
  188. package/dist/memory-sync.js +29 -7
  189. package/dist/model-plane-face.d.ts +13 -7
  190. package/dist/model-plane-face.js +2 -1
  191. package/dist/observability/fail-open.d.ts +47 -14
  192. package/dist/observability/fail-open.js +37 -11
  193. package/dist/observability/run-terminal.d.ts +92 -34
  194. package/dist/observability/run-terminal.js +171 -162
  195. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
  196. package/dist/orchestration/workflow-completion-inbox.js +0 -12
  197. package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
  198. package/dist/orchestration/workflow-park-decision.d.ts +8 -3
  199. package/dist/orchestration/workflow-park-decision.js +5 -3
  200. package/dist/org-delivery-gate.d.ts +11 -0
  201. package/dist/org-delivery-gate.js +19 -1
  202. package/dist/parked-decide.d.ts +13 -9
  203. package/dist/parked-decide.js +7 -7
  204. package/dist/parked-revive-surface.js +1 -1
  205. package/dist/peer-inbound-face.d.ts +127 -0
  206. package/dist/peer-inbound-face.js +158 -0
  207. package/dist/permission-rule-list.d.ts +13 -9
  208. package/dist/permission-rule-list.js +7 -3
  209. package/dist/plugins/approval-ask-store-file.d.ts +14 -4
  210. package/dist/plugins/approval-ask-store-file.js +64 -11
  211. package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
  212. package/dist/plugins/approval-ask-store-memory.js +17 -14
  213. package/dist/plugins/approval-ask-store-sql.d.ts +70 -23
  214. package/dist/plugins/approval-ask-store-sql.js +79 -30
  215. package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
  216. package/dist/plugins/checkpoint-store-sql.js +9 -7
  217. package/dist/plugins/file-history-store-sql.d.ts +24 -18
  218. package/dist/plugins/file-history-store-sql.js +24 -19
  219. package/dist/plugins/file-run-store.d.ts +35 -1
  220. package/dist/plugins/file-run-store.js +108 -9
  221. package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
  222. package/dist/plugins/imported-layer-root-retirement.js +96 -0
  223. package/dist/plugins/local-checkpoint-store.d.ts +1 -1
  224. package/dist/plugins/local-checkpoint-store.js +2 -2
  225. package/dist/plugins/local-session-store.d.ts +42 -9
  226. package/dist/plugins/local-session-store.js +83 -33
  227. package/dist/plugins/local-task-attachment-store.d.ts +12 -2
  228. package/dist/plugins/local-task-attachment-store.js +67 -43
  229. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
  230. package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
  231. package/dist/plugins/mailbox-store-sql.d.ts +12 -8
  232. package/dist/plugins/mailbox-store-sql.js +76 -7
  233. package/dist/plugins/memory-key-guards.d.ts +3 -3
  234. package/dist/plugins/memory-run-store.d.ts +6 -1
  235. package/dist/plugins/memory-run-store.js +11 -1
  236. package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
  237. package/dist/plugins/memory-sync-store-pg.js +21 -0
  238. package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
  239. package/dist/plugins/memory-sync-store-tidb.js +13 -1
  240. package/dist/plugins/one-time-migrations.d.ts +58 -2
  241. package/dist/plugins/one-time-migrations.js +161 -4
  242. package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
  243. package/dist/plugins/org-delivery-quota-store.js +2 -12
  244. package/dist/plugins/park-commit-watch.d.ts +1 -1
  245. package/dist/plugins/permission-rule-store-file.d.ts +10 -1
  246. package/dist/plugins/permission-rule-store-file.js +15 -2
  247. package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
  248. package/dist/plugins/permission-rule-store-sql.js +35 -2
  249. package/dist/plugins/remote-env-device.d.ts +8 -11
  250. package/dist/plugins/remote-env-device.js +6 -3
  251. package/dist/plugins/remote-env-e2b.d.ts +23 -4
  252. package/dist/plugins/remote-env-e2b.js +111 -28
  253. package/dist/plugins/remote-env-k8s.d.ts +61 -22
  254. package/dist/plugins/remote-env-k8s.js +133 -33
  255. package/dist/plugins/remote-env-local-docker.d.ts +15 -3
  256. package/dist/plugins/remote-env-local-docker.js +40 -12
  257. package/dist/plugins/retention-store-sql.d.ts +2 -2
  258. package/dist/plugins/run-store-sql.d.ts +9 -1
  259. package/dist/plugins/run-store-sql.js +9 -1
  260. package/dist/plugins/sandbox-read-floor.d.ts +5 -7
  261. package/dist/plugins/sandbox-read-floor.js +2 -7
  262. package/dist/plugins/sql-errors.d.ts +10 -1
  263. package/dist/plugins/sql-errors.js +13 -0
  264. package/dist/plugins/store-backend.d.ts +33 -35
  265. package/dist/plugins/store-backend.js +10 -1
  266. package/dist/plugins/store-contracts.d.ts +50 -1
  267. package/dist/plugins/store-contracts.js +6 -0
  268. package/dist/plugins/task-attachment-store.d.ts +112 -14
  269. package/dist/plugins/task-attachment-store.js +207 -29
  270. package/dist/plugins/tool-result-store-sql.d.ts +9 -8
  271. package/dist/plugins/tool-result-store-sql.js +23 -2
  272. package/dist/plugins/wiring-section-codec.d.ts +32 -0
  273. package/dist/plugins/wiring-section-codec.js +55 -0
  274. package/dist/plugins/workspace-fill.d.ts +60 -0
  275. package/dist/plugins/workspace-fill.js +106 -0
  276. package/dist/project-bundle.d.ts +38 -0
  277. package/dist/project-bundle.js +609 -0
  278. package/dist/rule-entry-list.d.ts +3 -2
  279. package/dist/rule-entry-list.js +5 -1
  280. package/dist/rules-consent.d.ts +28 -5
  281. package/dist/rules-consent.js +40 -28
  282. package/dist/run-local.js +11 -13
  283. package/dist/runs.d.ts +12 -8
  284. package/dist/runs.js +6 -8
  285. package/dist/runtime-governance.d.ts +1 -1
  286. package/dist/sandbox-egress-policy.d.ts +4 -1
  287. package/dist/sandbox-egress-policy.js +3 -1
  288. package/dist/sandbox-git-plane.d.ts +31 -12
  289. package/dist/sandbox-git-plane.js +24 -4
  290. package/dist/security.d.ts +9 -0
  291. package/dist/security.js +8 -0
  292. package/dist/server-secret-env.d.ts +4 -0
  293. package/dist/session-error-wire.d.ts +36 -0
  294. package/dist/session-error-wire.js +13 -0
  295. package/dist/session-incarnation.d.ts +1 -1
  296. package/dist/session-notify-door.d.ts +106 -0
  297. package/dist/session-notify-door.js +93 -0
  298. package/dist/session-sync.d.ts +9 -14
  299. package/dist/session-sync.js +5 -5
  300. package/dist/session-workspace.d.ts +3 -13
  301. package/dist/session-workspace.js +0 -9
  302. package/dist/standing-answer-grant.d.ts +5 -0
  303. package/dist/standing-answer-grant.js +10 -0
  304. package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
  305. package/dist/stores-sql/session-policy-store-sql.js +3 -13
  306. package/dist/task-mcp.d.ts +1 -1
  307. package/dist/task-settings.d.ts +21 -10
  308. package/dist/task-settings.js +46 -13
  309. package/dist/terminal.d.ts +39 -19
  310. package/dist/terminal.js +65 -22
  311. package/dist/tool-approval.d.ts +56 -37
  312. package/dist/tool-approval.js +78 -71
  313. package/dist/trace/core-keyset-guard.d.ts +134 -14
  314. package/dist/trace/engine-notice-wire.d.ts +9 -3
  315. package/dist/trace/engine-notice-wire.js +7 -3
  316. package/dist/trace/exit-seat.d.ts +9 -2
  317. package/dist/trace/exit-seat.js +1 -0
  318. package/dist/trace/ledger-sink.d.ts +10 -6
  319. package/dist/trace/ledger-sink.js +2 -2
  320. package/dist/trace/model-segment.d.ts +55 -25
  321. package/dist/trace/model-segment.js +101 -33
  322. package/dist/trace/project.d.ts +25 -5
  323. package/dist/trace/project.js +22 -0
  324. package/dist/trace/redact.d.ts +61 -9
  325. package/dist/trace/redact.js +1490 -468
  326. package/dist/trace/self-minted-wire.d.ts +745 -24
  327. package/dist/trace/self-minted-wire.js +239 -9
  328. package/dist/trace/wire-projection-faces.d.ts +2 -2
  329. package/dist/trace/wire-projection-faces.js +2 -2
  330. package/dist/verifier-pause-card.d.ts +33 -5
  331. package/dist/verifier-pause-card.js +15 -10
  332. package/dist/web-admin-client/apply-effective.d.ts +12 -16
  333. package/dist/web-admin-client/apply-effective.js +109 -9
  334. package/dist/web-admin-client/effective-keys.js +2 -0
  335. package/dist/web-admin-client/types.d.ts +4 -0
  336. package/dist/workspace-space.d.ts +19 -3
  337. package/dist/workspace-space.js +8 -4
  338. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
  339. package/package.json +3 -2
  340. package/wire-changes/server@7.142.0.json +639 -0
  341. package/wire-changes/server@7.143.0.json +1167 -0
@@ -21,7 +21,7 @@
21
21
  * 没有方法、没有捕获的行为。
22
22
  */
23
23
  import { z } from "zod";
24
- import { ALLOW_RULE_MEMBERS, READ_ROOT_CANDIDATE_DIR_MAX, type AskClass, type AskEvidenceAbsence, type CheckpointSummary as CoreCheckpointSummary, type PendingAction as CorePendingAction, type ReadRootGrantCandidate, type ResumeStartupCause, type RuleOffer, type RuleOffersAbsence as CoreRuleOffersAbsence, type SteerReplayFacet, type ToolApprovalCard } from "@sema-agent/core";
24
+ import { ALLOW_RULE_MEMBERS, READ_ROOT_CANDIDATE_DIR_MAX, type AskClass, type AskEvidenceAbsence, type AskReason as CoreAskReason, type HookQuestionCause, type CheckpointSummary as CoreCheckpointSummary, type PendingAction as CorePendingAction, type ReadRootGrantCandidate, type ResumeStartupCause, type RuleOffer, type RuleOffersAbsence as CoreRuleOffersAbsence, type SteerReplayFacet, type ToolApprovalCard } from "@sema-agent/core";
25
25
  import type { AskRow } from "./plugins/approval-ask-store-sql.js";
26
26
  import type { SettleCause, SettleOutcome } from "./approval-deny-reasons.js";
27
27
  import type { ToolApprovalFrame } from "./tool-approval.js";
@@ -87,8 +87,8 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
87
87
  name: "name";
88
88
  path: "path";
89
89
  tool: "tool";
90
- exact: "exact";
91
90
  pattern: "pattern";
91
+ exact: "exact";
92
92
  prefix: "prefix";
93
93
  wildcard: "wildcard";
94
94
  subpath: "subpath";
@@ -106,8 +106,8 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
106
106
  name: "name";
107
107
  path: "path";
108
108
  tool: "tool";
109
- exact: "exact";
110
109
  pattern: "pattern";
110
+ exact: "exact";
111
111
  prefix: "prefix";
112
112
  wildcard: "wildcard";
113
113
  subpath: "subpath";
@@ -210,8 +210,8 @@ export declare function readProbeCause(req: unknown): ProbeCauseProjection | und
210
210
  * `AskRequest.probeReason`(core 5.33.0 [ref]:`probeCause` 的**散文**兄弟 —— 探针对「为什么没清掉这一问」的一句话)的
211
211
  * **边界窄读**,活卡帧(`ToolApprovalFrame.probeReason`)的**唯一**铸造点。
212
212
  *
213
- * 🔴 **只有活卡帧**:`card_json` / 呈卡帧不携本键(`ApprovalCardSchema` 是 `.strict()` 的耐久信封,加键 = 回滚窗内旧二进制读不动新行,
214
- * 要另行裁定)。耐久面的对偶 = `gate.riskDescriptor.probeReason`(park 行整体透传,出门前过 `redactRiskDescriptor` 的 `text` 叶,
213
+ * 🔴 **不在卡上**:`ApprovalCardSchema`(`.strict()`)没有本键;呈卡帧 `approval_request` 顶层带它(活面事实座之一,{@link APPROVAL_REQUEST_LIVE_FACT_KEYS}),
214
+ * 7.143.0 起同一份值随卡落进卡信封的 `liveFacts` 座 ⇒ 断连重放帧与活铸帧同值({@link buildApprovalCardEnvelope})。耐久面的对偶 = `gate.riskDescriptor.probeReason`(park 行整体透传,出门前过 `redactRiskDescriptor` 的 `text` 叶,
215
215
  * 与本函数同一只脱敏规则 ⇒ 对同一句话两面同值)。
216
216
  *
217
217
  * 姿势逐条(与 {@link readProbeCause} / {@link readRuleEvidence} 同款分工):
@@ -431,6 +431,27 @@ export interface AskClassPair {
431
431
  askClass: NonNullable<ToolApprovalPark["askClass"]>;
432
432
  classes: Array<NonNullable<ToolApprovalPark["classes"]>[number]>;
433
433
  }
434
+ /**
435
+ * **谁问的、为什么问 —— `askReasons` 的唯一窄读**(core 7.61.0:一只座,`AskRequest.askReasons` 与寄存行 `PendingAction.tool_approval.askReasons`
436
+ * 是同一个值、一次铸)。一条 = 一位问者 + 它自己的话:策略链的问 `{ by, words }`(`by` = 引擎出身闭集 `ASK_ORIGINS` 除 `hook`),
437
+ * hook / 扩展的问 `{ by: "hook", registration?, cause, words? }`(`cause` = `HOOK_QUESTION_CAUSES`)。结构化审批面按它渲理由行,不渲 `message`
438
+ * (`message` 照旧逐字转给只读文本的消费方)。活卡帧、呈卡帧的卡、运维队列行三面读这一只。
439
+ * · 缺席 ⇒ 缺席(不计数):老引擎、老行、引擎自己铸的通用问句(写门默认问句 / 计划模式两句不铸条目)。
440
+ * · 在场 ⇒ 每条逐键窄读:`by` 在集、hook 条的 `cause` 在集、`words` / `registration` 是串;问者的话(部署策略 / hook / 扩展写的自由文本)过
441
+ * `redactSecrets` 再截长(与卡上 `message` 同一只帽),注册名截到标识帽。任一条形不合 ⇒ **整座不投**(卡上少一行理由 ≪ 卡上出现半条理由)
442
+ * + 计一次 `server.approval-card.closed-word-out-of-set`(detail 前缀 `askReasons=`)。
443
+ */
444
+ export declare function readAskReasons(carrier: unknown): AskReasonProjection[] | undefined;
445
+ /** 一条理由的投影形(帧 / 卡 / 队列行同一形)。值型取 core 的 `AskReason`(core 改形 ⇒ 下面的围栏编译红,读法就得重判)。 */
446
+ export type AskReasonProjection = {
447
+ by: "hook";
448
+ registration?: string;
449
+ cause: HookQuestionCause;
450
+ words?: string;
451
+ } | {
452
+ by: Exclude<CoreAskReason["by"], "hook">;
453
+ words: string;
454
+ };
434
455
  /**
435
456
  * 🔴 [ref] P1(client-core [ref] / cli [ref] 的根子;板 [ref] 订正 → [ref] 立案)—— **park 行事实**:
436
457
  * 运维队列行(`GET /v1/approvals` + `/stream`)顶层展开的那几位。型**从 core 寄存行派生,不手抄**([ref] 同一条
@@ -456,7 +477,7 @@ export interface AskClassPair {
456
477
  * (「本会话放行」可按工具记)。摘要读自停驻行本身 —— 不靠整行的检查点摘要,所以 SQL 腿那一次整行读失败也不丢这一臂;要 core 校验的清单与成因词走
457
478
  * 另一只投影 {@link skillCardFacts}。
458
479
  */
459
- export type ParkRowFacts = Pick<ToolApprovalPark, "requiresRealApproval" | "ruleOffersAbsence" | "mandated" | "mandate" | "origin" | "askClass" | "classes" | "boundGrantDigest" | "boundGrantAbsence">;
480
+ export type ParkRowFacts = Pick<ToolApprovalPark, "requiresRealApproval" | "ruleOffersAbsence" | "mandated" | "mandate" | "origin" | "askClass" | "classes" | "boundGrantDigest" | "boundGrantAbsence" | "askReasons">;
460
481
  /**
461
482
  * [ref] —— park 行事实的**唯一投影**(`pendingAction` 是寄存行上 core 铸的那一只,读自持久层 ⇒ `unknown`)。
462
483
  *
@@ -500,7 +521,7 @@ export declare function parkRowFacts(stored: unknown): ParkRowFacts;
500
521
  * 但投影只有这一只:OMIT 契约 —— 缺席即缺席,恒不铸 `undefined` 值的键。
501
522
  *
502
523
  * `boundGrants` 是**部署文本**(技能名、清单条目):本函数不脱敏、不转义,与收件箱行逐字同口径 —— 渲染按上下文转义是客户端的事(契约同句)。
503
- * 两位都不进 `card_json`(同步路铸点,另一条纪律)。
524
+ * 本投影的产物不进 `card_json`(它是停驻面的投影);问行卡信封的活面事实座(7.143.0)存的是呈卡帧上同名两位(活铸素材,与停驻孪生同一只工厂铸)。
504
525
  *
505
526
  * 🚧 清单校验读口 `readBoundBinding` 若成为 core 的公开导出,SQL 孪生那一次整行读与 {@link parkRowCarriesSkillCardFacts} 一并退役:`parkRowFacts` 直接读寄存行原值经 core 的读口投两位
506
527
  * (`grantBindingOf` 也改成它的薄包装 —— 那时 core 是绑定读法的唯一属主)。
@@ -571,12 +592,12 @@ export declare const ApprovalCardSchema: z.ZodObject<{
571
592
  question: "question";
572
593
  plan: "plan";
573
594
  skill: "skill";
574
- workflow: "workflow";
575
595
  "file-edit": "file-edit";
576
596
  "file-write": "file-write";
577
597
  "notebook-edit": "notebook-edit";
578
598
  shell: "shell";
579
599
  fetch: "fetch";
600
+ workflow: "workflow";
580
601
  generic: "generic";
581
602
  }>>;
582
603
  inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
@@ -599,8 +620,8 @@ export declare const ApprovalCardSchema: z.ZodObject<{
599
620
  name: "name";
600
621
  path: "path";
601
622
  tool: "tool";
602
- exact: "exact";
603
623
  pattern: "pattern";
624
+ exact: "exact";
604
625
  prefix: "prefix";
605
626
  wildcard: "wildcard";
606
627
  subpath: "subpath";
@@ -618,8 +639,8 @@ export declare const ApprovalCardSchema: z.ZodObject<{
618
639
  name: "name";
619
640
  path: "path";
620
641
  tool: "tool";
621
- exact: "exact";
622
642
  pattern: "pattern";
643
+ exact: "exact";
623
644
  prefix: "prefix";
624
645
  wildcard: "wildcard";
625
646
  subpath: "subpath";
@@ -687,8 +708,22 @@ export declare const ApprovalCardSchema: z.ZodObject<{
687
708
  askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
688
709
  classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
689
710
  fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
690
- sourceTaskId: z.ZodOptional<z.ZodString>;
711
+ sourceSessionId: z.ZodOptional<z.ZodString>;
712
+ agentId: z.ZodOptional<z.ZodString>;
691
713
  sourceAgentName: z.ZodOptional<z.ZodString>;
714
+ askReasons: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
715
+ by: z.ZodLiteral<"hook">;
716
+ registration: z.ZodOptional<z.ZodString>;
717
+ cause: z.ZodEnum<{
718
+ asked: "asked";
719
+ verdict_unreadable: "verdict_unreadable";
720
+ verdict_unfinished: "verdict_unfinished";
721
+ }>;
722
+ words: z.ZodOptional<z.ZodString>;
723
+ }, z.core.$strict>, z.ZodObject<{
724
+ by: z.ZodCustom<"org_rule" | "org_unavailable" | "content_question" | "plan_review" | "ancestor_marked" | "rule_store_unavailable" | "ask_rule" | "denial_limit_fallback" | "shell_gate_tighten" | "safety_tighten" | "policy", "org_rule" | "org_unavailable" | "content_question" | "plan_review" | "ancestor_marked" | "rule_store_unavailable" | "ask_rule" | "denial_limit_fallback" | "shell_gate_tighten" | "safety_tighten" | "policy">;
725
+ words: z.ZodString;
726
+ }, z.core.$strict>]>>>;
692
727
  delegation: z.ZodOptional<z.ZodObject<{
693
728
  parentToolCallId: z.ZodString;
694
729
  depth: z.ZodNumber;
@@ -704,6 +739,14 @@ export type ApprovalCard = z.infer<typeof ApprovalCardSchema>;
704
739
  * 应答口 / 读口)一律读行的键、不读这一格;写它是给滚动升级窗里上一版的副本(它们的 strict 信封 schema 要求这一格并照它重放)。
705
740
  * 唯一读这一格的是 local 车道的启动收敛 —— 拿它去审计账里查前世这只 ask 的成因:审计行记的就是当时呈出的那个 id
706
741
  * (更早写下的行上是当年的登记本地 id)。
742
+ *
743
+ * `liveFacts`(7.143.0)= 这只 ask 的**活面事实座**({@link APPROVAL_REQUEST_LIVE_FACT_KEYS}:卡外、只在呈卡帧顶层的那十一位),铸卡时与 `card` **同一条写**落下,
744
+ * 值就是活铸呈卡帧顶层那一份(同一只挑键函数从同一只帧对象挑,见 {@link buildApprovalCardEnvelope})。重放帧只读这一座 —— 不读停驻行孪生座、不重算、不从内存兜。
745
+ * 信封这一层只认「这一格在不在」(`unknown`);它的形由唯一读者 {@link readStoredCardEnvelope} 用 {@link ApprovalRequestLiveFactsSchema} 整座判:读不出 ⇒ 与这一格缺席
746
+ * (本版之前铸的行)同读 —— 「活面事实不在行上」,卡照常可读、重放帧带 `liveFactsUnknown`。信封层不判它的形,是为了一座读不出的事实不连带把卡也读丢
747
+ * (卡读丢 ⇒ 重放跳过 / 幂等重入走 park,比「不知道事实」的那一形更坏)。
748
+ * 回滚窗代价与卡上的 additive 键同族:`.strict()` 下上一版二进制读不动带这一格的新行 ⇒ 重放跳过 + 幂等重入走 park(fail-safe,`schemaVersion` 不动);
749
+ * 区别是这一格**每一行都带**(空座也写),所以混版窗里上一版副本读不动的是本版写下的每一行 —— 整队滚前,见 CHANGELOG 本条。
707
750
  */
708
751
  export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
709
752
  schemaVersion: z.ZodLiteral<1>;
@@ -725,12 +768,12 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
725
768
  question: "question";
726
769
  plan: "plan";
727
770
  skill: "skill";
728
- workflow: "workflow";
729
771
  "file-edit": "file-edit";
730
772
  "file-write": "file-write";
731
773
  "notebook-edit": "notebook-edit";
732
774
  shell: "shell";
733
775
  fetch: "fetch";
776
+ workflow: "workflow";
734
777
  generic: "generic";
735
778
  }>>;
736
779
  inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
@@ -753,8 +796,8 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
753
796
  name: "name";
754
797
  path: "path";
755
798
  tool: "tool";
756
- exact: "exact";
757
799
  pattern: "pattern";
800
+ exact: "exact";
758
801
  prefix: "prefix";
759
802
  wildcard: "wildcard";
760
803
  subpath: "subpath";
@@ -772,8 +815,8 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
772
815
  name: "name";
773
816
  path: "path";
774
817
  tool: "tool";
775
- exact: "exact";
776
818
  pattern: "pattern";
819
+ exact: "exact";
777
820
  prefix: "prefix";
778
821
  wildcard: "wildcard";
779
822
  subpath: "subpath";
@@ -841,14 +884,29 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
841
884
  askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
842
885
  classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "target_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "cross_boundary" | "operator_forced" | "shell_floor" | "probe" | "write_protection_on_disk" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
843
886
  fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
844
- sourceTaskId: z.ZodOptional<z.ZodString>;
887
+ sourceSessionId: z.ZodOptional<z.ZodString>;
888
+ agentId: z.ZodOptional<z.ZodString>;
845
889
  sourceAgentName: z.ZodOptional<z.ZodString>;
890
+ askReasons: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
891
+ by: z.ZodLiteral<"hook">;
892
+ registration: z.ZodOptional<z.ZodString>;
893
+ cause: z.ZodEnum<{
894
+ asked: "asked";
895
+ verdict_unreadable: "verdict_unreadable";
896
+ verdict_unfinished: "verdict_unfinished";
897
+ }>;
898
+ words: z.ZodOptional<z.ZodString>;
899
+ }, z.core.$strict>, z.ZodObject<{
900
+ by: z.ZodCustom<"org_rule" | "org_unavailable" | "content_question" | "plan_review" | "ancestor_marked" | "rule_store_unavailable" | "ask_rule" | "denial_limit_fallback" | "shell_gate_tighten" | "safety_tighten" | "policy", "org_rule" | "org_unavailable" | "content_question" | "plan_review" | "ancestor_marked" | "rule_store_unavailable" | "ask_rule" | "denial_limit_fallback" | "shell_gate_tighten" | "safety_tighten" | "policy">;
901
+ words: z.ZodString;
902
+ }, z.core.$strict>]>>>;
846
903
  delegation: z.ZodOptional<z.ZodObject<{
847
904
  parentToolCallId: z.ZodString;
848
905
  depth: z.ZodNumber;
849
906
  agentName: z.ZodOptional<z.ZodString>;
850
907
  }, z.core.$strip>>;
851
908
  }, z.core.$strict>;
909
+ liveFacts: z.ZodOptional<z.ZodUnknown>;
852
910
  }, z.core.$strict>;
853
911
  export type ApprovalCardEnvelope = z.infer<typeof ApprovalCardEnvelopeSchema>;
854
912
  /** 本车铸的信封形版本(写侧=刀 3b,读侧=本文件)。 */
@@ -892,7 +950,9 @@ export interface ApprovalCardSource {
892
950
  askClass?: AskClass;
893
951
  classes?: readonly AskClass[];
894
952
  fromSubagent?: true;
895
- sourceTaskId?: string;
953
+ sourceSessionId?: string;
954
+ /** core 7.61.0:委派腿的 agent id(见 `ApprovalCardSchema.agentId`)。 */
955
+ agentId?: string;
896
956
  /** 已 redactSecrets。 */
897
957
  sourceAgentName?: string;
898
958
  delegation?: {
@@ -912,8 +972,22 @@ export interface ApprovalCardSource {
912
972
  * 头注。)
913
973
  */
914
974
  export declare function buildApprovalCard(source: ApprovalCardSource, req: unknown, requiresRealApproval: boolean): ApprovalCard;
915
- /** 落库信封的纯构造(写侧;读侧 = {@link readStoredCardEnvelope},**同一个 schema**)。 */
916
- export declare function buildApprovalCardEnvelope(approvalId: string, card: ApprovalCard): ApprovalCardEnvelope;
975
+ /**
976
+ * 落库信封的纯构造(写侧;读侧 = {@link readStoredCardEnvelope},**同一个 schema**)。`liveFacts` = 活铸呈卡帧顶层的那一份活面事实(调用点交的是**同一只帧对象**,
977
+ * 经与活铸帧同一只挑键函数 {@link pickApprovalRequestLiveFacts} 落座:只拷在场的位、缺席不铸 `undefined` 键)。座恒写 —— 一位事实都没有的问写空座 `{}`,
978
+ * 于是「行上有座」与「本版之前铸的行」在读侧是两形(后者读作「不知道」)。
979
+ * 🔴 唯一不落座的一形:这组事实里有 NUL / 孤代理(判官 `pgHasUnstorable`)。PG 问店的 `card_json` 走有损臂(那两类码点换成 U+FFFD,
980
+ * `plugins/pg-safe-json.ts`),落下去的就不是逐字的那一份 —— 而座是「与活铸帧逐字同」的记录(读根目录要原样回传)。这样的一组不落座,
981
+ * 行读作「不知道」(重放帧带 `liveFactsUnknown`),每只店同判;绝不落一份会被某个后端改写的「同值」。卡本身照旧(卡是展示投影,有损臂是它的既有读法)。
982
+ */
983
+ export declare function buildApprovalCardEnvelope(approvalId: string, card: ApprovalCard, liveFacts: ApprovalRequestLiveFacts): ApprovalCardEnvelope;
984
+ /**
985
+ * 存下的卡的**读数**({@link readStoredCardEnvelope} 的产出):卡与身份照信封;`liveFacts` = 行上那一座读得出时的活面事实,**缺席 = 不知道**
986
+ * (这一行是本版之前铸的,或那一座读不出 —— 两形同读,见 {@link ApprovalCardEnvelopeSchema} 的 `liveFacts` 注)。
987
+ */
988
+ export type StoredApprovalCard = Omit<ApprovalCardEnvelope, "liveFacts"> & {
989
+ liveFacts?: ApprovalRequestLiveFacts;
990
+ };
917
991
  /**
918
992
  * 🔴 **存下的卡的唯一读者入口**([ref])—— `approval_ask.card_json` 的每一个读点(断连重放 {@link buildReplayFrame}、回决口的「要不要人」
919
993
  * {@link storedCardDemandsAPerson}、幂等重入与规则兑付两处(`tool-approval.ts`)、local 车道的启动收敛(`approval-crash-convergence.ts`))都经这一只,
@@ -924,8 +998,10 @@ export declare function buildApprovalCardEnvelope(approvalId: string, card: Appr
924
998
  * (`retired-card-words.ts`),**响亮**:每改写一次计一次 `server.approval-card.retired-card-word-read`(计数 + probe + 一次 warn,detail 只报座名)。
925
999
  * 窗关(登记表 M18)后读侧半场随起服改写一起删,本函数回到「只 `safeParse`」。读不出(真坏形)⇒ `undefined`,各读点的处置不变(跳过 + warn / park /
926
1000
  * 按要人 / 素材缺席 / 收敛成因按缺省)。
1001
+ * 7.143.0 起信封上的活面事实座也只在这里读(整座过 {@link ApprovalRequestLiveFactsSchema}):读得出 ⇒ 读数带 `liveFacts`;缺席或读不出 ⇒ 不带(= 不知道),卡照读。
1002
+ * 同一入口还有一次性迁移 M37 的读侧({@link renameRetiredSourceKey}):本版之前铸的卡上的委派出处旧键先改名,再过 M18 与 schema。
927
1003
  */
928
- export declare function readStoredCardEnvelope(cardJson: unknown): ApprovalCardEnvelope | undefined;
1004
+ export declare function readStoredCardEnvelope(cardJson: unknown): StoredApprovalCard | undefined;
929
1005
  /**
930
1006
  * 🔴 **停驻行 `tool_approval` 臂的读侧入口**([ref];一次性迁移 M18 的读侧半场)—— 读它两座的两个读者(运维队列行 {@link parkRowFacts}、
931
1007
  * 耐久 `/decide` 的 remember 判据 `tool-approval.ts` `parkRowStandingAnswerFacts`)先经这一只:7.50.x 停驻的行上两座的退役词按 M18 那一只改写读,
@@ -935,8 +1011,9 @@ export declare function readStoredCardEnvelope(cardJson: unknown): ApprovalCardE
935
1011
  */
936
1012
  export declare function currentParkArm<T>(pendingAction: T): T;
937
1013
  /**
938
- * [ref] §3.1 的呈卡帧(设计稿 §4.1)—— **live 铸造**形(重放形见 {@link buildReplayFrame},
939
- * 两者投的是同一种帧,区别只在 `card` 的来源:这里是刚投影出来的,那里是从行上回读的)。
1014
+ * [ref] §3.1 的呈卡帧(设计稿 §4.1)—— **唯一构造**:活铸(`tool-approval.ts` 的 `askBroadcast`)与重放({@link buildReplayFrame})投的是同一种帧、
1015
+ * 经同一只函数,区别只在素材的来源:活铸的卡与活面事实是刚铸的那一份,重放的是行上卡信封回读的那一份(同一次写落下的)。
1016
+ * `live` 缺席 ⇒ 帧带 `liveFactsUnknown: true`、不带任何一位活面事实 —— 只有重放会交缺席(行上没有那一座 / 读不出);活铸恒交帧对象。
940
1017
  *
941
1018
  * `expiresAtMs` **入参**而不是在这里现算:同一只 ask 的窗**只铸一次**(§3.1「永不赋新 deadline」),
942
1019
  * 调用点已经算好了它(既是定时器时长的来源,也是落库 `expires_at_ms` 的值)——在这里重算会铸出第二个
@@ -949,7 +1026,7 @@ export declare function buildApprovalRequestFrame(input: {
949
1026
  card: ApprovalCard;
950
1027
  expiresAtMs: number;
951
1028
  nowMs: number;
952
- live: ApprovalRequestLiveFacts;
1029
+ live: ApprovalRequestLiveFacts | undefined;
953
1030
  }): ApprovalRequestFrame;
954
1031
  /**
955
1032
  * 🔴 **呈卡帧的活面事实座**(呈卡腿上旧族退役之后,开卡帧的全部事实都由本族承载)。
@@ -959,31 +1036,51 @@ export declare function buildApprovalRequestFrame(input: {
959
1036
  * 卡外的事实此前只骑活卡帧,呈卡腿的消费方靠「两帧按 approvalId 合读」拿到它们。呈卡腿自此只发本族帧 ⇒ 它们挪到**活铸**的
960
1037
  * 呈卡帧顶层,同名同型同值 —— 值取自同一只帧对象(活卡帧的那一次铸定,`tool-approval.ts` 的 `askBroadcast`),本仓不另算一遍。
961
1038
  *
962
- * 在场面与它们在活卡帧上的在场面**逐字相同**:只在活铸的帧上,断连重放帧({@link buildReplayFrame},从 `card_json` 回读)上恒缺席 ——
963
- * 活卡帧从来不重放,卡外事实也从来不在重放面上;是否把其中某几位收进卡(耐久、随重放)是另一件事,各自要过 `.strict()` 信封的回滚窗判断
964
- * (`readRootCandidate` 有不进卡的硬理由:耐久面兑现不了它,见活卡帧该座顶注)。
1039
+ * 🔴 **一只 ask 一份事实,活铸帧与重放帧同读(7.143.0)**:铸卡时同一只帧对象经同一只挑键函数落进问行卡信封的 `liveFacts` 座(与 `card` 同一条写,
1040
+ * {@link buildApprovalCardEnvelope});断连重放帧({@link buildReplayFrame}:断流续读、开流 preamble、只经 preamble 到达的后台子代的问、起服接管的列表行、按问读口)
1041
+ * 只读这一座 ⇒ 在场的每一位与活铸帧逐字同,缺席即缺席。行上没有这一座(本版之前铸的行)或它读不出 ⇒ 重放帧带 `liveFactsUnknown: true`、一位都不带
1042
+ * (不伪造,不回填,不从停驻行孪生座 join —— 那是另一份店、另一个写者)。同一只问被另一腿再问(幂等命中既有行)时,重入那一腿的活铸帧也读这一座
1043
+ * ({@link adoptStoredLiveFacts};行 = 真源)。带 NUL / 孤代理的一组不落座(某个后端存不下逐字的那一份,见 {@link buildApprovalCardEnvelope})。
1044
+ * 卡面(`ApprovalCardSchema`)照旧不带这十一位(`approvalCard` 除外,见本注末段):
1045
+ * 它们在帧顶层、不在 `card` 里,信封上是卡旁边的一座,不是卡的键。
1046
+ * `readRootCandidate` 随重放的射程与卡上 `ruleOffers` 同一句(`ApprovalCardSchema.ruleOffers` 顶注):回授经重放帧自己的 `approvalId` 走活应答口,
1047
+ * 有等待腿的副本兑得动;接管登记 / 耐久回决口上没有等待腿,应答照收、目录不加(没有 `approval.read_root_granted` 通告 = 什么都没加)。
965
1048
  *
966
1049
  * `requiresRealApproval` 不在表里:卡上 `risk.requiresRealApproval` 是同一个事实(铸卡第三参就是它),一个事实一个读法。
967
1050
  * ⚠️ **`approvalCard` 是表里唯一一位 7.136.0 起同时在卡上的座**(`ApprovalCardSchema.approvalCard`:断连重放的卡要渲回同一张专卡,卡词必须进卡;
968
1051
  * 同一次读定、同值)。按上一句的规矩它该离表(活铸帧顶层这一份退役 —— wire BREAKING,下游 sdk 的孪生表同改),本版按 additive 交付、未退役:
969
1052
  * 一个事实两处读,登记为待收的债,收法 = 离表 + 消费方改读 `card.approvalCard`,不是在这里加第三处。
1053
+ * 7.143.0 起卡信封的活面事实座按本表落座 ⇒ 这一位在信封上也是两份(`card.approvalCard` 与 `liveFacts.approvalCard`,同一次读、同值),仍是这一笔债、不是新的一笔:
1054
+ * 离表那一刻帧顶层(活铸 / 重放)与信封座里的这一份一起退;座的读形是 `.strict()` 的,离表那一版要让读者在窗内容下带着它的在飞行(否则那些行读作「不知道」)。
970
1055
  */
971
1056
  export declare const APPROVAL_REQUEST_LIVE_FACT_KEYS: readonly ["mandated", "mandate", "origin", "boundGrantDigest", "boundGrants", "classifierNoRuling", "boundGrantAbsence", "approvalCard", "readRootCandidate", "probeReason", "requestedBy"];
972
1057
  /** 呈卡帧活面事实座的类型面 = 活卡帧同名座的 `Pick`(同型由构造保证,不手抄)。 */
973
1058
  export type ApprovalRequestLiveFacts = Pick<ToolApprovalFrame, (typeof APPROVAL_REQUEST_LIVE_FACT_KEYS)[number]>;
1059
+ /**
1060
+ * 幂等重入采信行(「行 = 真源」家族,7.143.0):把一只活卡帧上的十一位换成行上卡信封那一座 —— 座里在场的照抄、座里缺席的删键。
1061
+ * 读者 = `tool-approval.ts` 的 `askBroadcast` 幂等命中既有行那一臂(行上有座才调;没有座 ⇒ 无可采信,不调)。于是重入那一腿的活铸帧
1062
+ * 与这只问的每一只重放帧是同一组事实;条目上的强制位 / 强制词 / 出身词随后从这只帧读,授予绑定读同一座(展示与判据同源)。
1063
+ */
1064
+ export declare function adoptStoredLiveFacts(frame: ApprovalRequestLiveFacts, seat: ApprovalRequestLiveFacts): void;
974
1065
  /**
975
1066
  * [ref] §3.1 的呈卡帧(设计稿 §4.1 逐字)。
976
1067
  *
977
1068
  * 🔴 **一条腿一个帧族**:呈卡协议在一条腿上场(腿的审批上下文接了 `emitCard`)⇒ 这条腿上一只 ask 的开卡 / 消卡 / 撤卡只走本族
978
1069
  * (`approval_request` / {@link ApprovalCompleteFrame} / {@link ApprovalRevokeFrame}),旧族 `tool_approval` / `tool_approval_complete`
979
1070
  * 一帧都不发;协议未上场的腿只发旧族。同一只 ask 在同一条腿上不再有两种开卡帧,消费方不再按 `approvalId` 去重。
980
- * 开卡的全部事实因此在本帧上:卡(`card`,耐久信封)+ 活面事实座({@link ApprovalRequestLiveFacts},只在活铸的帧上)。
1071
+ * 开卡的全部事实因此在本帧上:卡(`card`,耐久信封)+ 活面事实座({@link ApprovalRequestLiveFacts};活铸帧与重放帧同一份,见 {@link APPROVAL_REQUEST_LIVE_FACT_KEYS} 顶注)。
981
1072
  */
982
1073
  export interface ApprovalRequestFrame extends ApprovalRequestLiveFacts {
1074
+ /**
1075
+ * 7.143.0 **ADDITIVE**:**这只 ask 的活面事实不在它的行上** —— 只在重放帧上、只取字面 `true`:行是本版之前铸的(卡信封上没有那一座),或那一座读不出。
1076
+ * 在场时本帧一位活面事实都不带,它们的缺席**不是**断言:强制与否、出身、授予绑定……都按「不知道」读(强制与否不知道 ⇒ 按强制读,不让规则替人答)。
1077
+ * 活铸帧恒不带;行上有座的重放帧不带(座里缺的那一位就是真缺席)。不回填:存量行随窗到期收敛。
1078
+ */
1079
+ liveFactsUnknown?: true;
983
1080
  /** = SSE 具名事件名(与 `tool_approval` 同约定)。 */
984
1081
  type: "approval_request";
985
1082
  schemaVersion: 1;
986
- /** `deriveAskId` 派生(持久层主键;六元身份元组 —— [ref] / 7.109.0 起含这一问的类集 —— 见 approval-ask-machine.ts)。 */
1083
+ /** `deriveAskId` 派生(持久层主键;八元身份元组 —— 7.109.0 起含这一问的类集,7.143.0 起含展示的动作(工具名 + 入参摘要) —— 见 approval-ask-machine.ts)。 */
987
1084
  askId: string;
988
1085
  /** wire run id(= 协调器 ctx 的 taskId)。 */
989
1086
  taskId: string;
@@ -1092,6 +1189,8 @@ export declare function buildRevokeFrame(batchId: string, askIds: readonly strin
1092
1189
  * - **零写**:本函数不碰 store —— 重放腿只读,不 `transitionAsk`、不改 `expires_at_ms`、不重挂定时器。
1093
1190
  * 过窗未收敛的行(`expiresInMs === 0`)**仍然重放**,不在这里代打 `expireAsk` CAS(那会制造第五个
1094
1191
  * 竞争者;收敛是车2 的窗到期竞争者与车5 恢复扫描的职责)。
1192
+ * - **与活铸帧同一份事实**(7.143.0):卡与活面事实座都取自行上的卡信封(同一次写落下的),经与活铸帧同一只构造 {@link buildApprovalRequestFrame};
1193
+ * 行上没有座 / 座读不出 ⇒ `liveFactsUnknown`(见帧型该键)。
1095
1194
  */
1096
1195
  export declare function buildReplayFrame(row: Pick<AskRow, "askId" | "taskId" | "expiresAtMs" | "cardJson">, nowMs: number): ApprovalRequestFrame | undefined;
1097
1196
  /**
@@ -1,10 +1,12 @@
1
1
  import { z } from "zod";
2
- import { ALLOW_RULE_MEMBERS, ASK_EVIDENCE_ABSENCE_VALUES, TOOL_APPROVAL_CARDS, BOUND_GRANT_ABSENCES, DENIAL_LIMIT_BOUNDS, MAX_RULE_TEXT_CHARS, PERSISTED_RULE_MATCHES, UNCOVERED_SEGMENT_REASONS, READ_ROOT_CANDIDATE_DIR_MAX, RESUME_STARTUP_CAUSES, RULE_OFFERS_ABSENCES, RULE_OFFER_KINDS, STEER_REPLAY_FACETS, isAskClass, readRuleOffers, isAskOrigin, isAutoModeFallbackCause, isMintableProbeReason, isPersistedRuleMandate, screenAskClassMembers } from "@sema-agent/core";
2
+ import { ALLOW_RULE_MEMBERS, ASK_EVIDENCE_ABSENCE_VALUES, TOOL_APPROVAL_CARDS, BOUND_GRANT_ABSENCES, DENIAL_LIMIT_BOUNDS, MAX_RULE_TEXT_CHARS, PERSISTED_RULE_MATCHES, UNCOVERED_SEGMENT_REASONS, READ_ROOT_CANDIDATE_DIR_MAX, RESUME_STARTUP_CAUSES, RULE_OFFERS_ABSENCES, RULE_OFFER_KINDS, STEER_REPLAY_FACETS, HOOK_QUESTION_CAUSES, isAskClass, readRuleOffers, isAskOrigin, isAutoModeFallbackCause, isMintableProbeReason, isPersistedRuleMandate, screenAskClassMembers } from "@sema-agent/core";
3
3
  import { redactSecrets } from "./trace/redact.js";
4
4
  import { recordFailOpen } from "./observability/fail-open.js";
5
5
  import { readApprovalCard } from "./approval-content-kind.js";
6
+ import { seatText } from "./trace/exit-seat.js";
6
7
  import { capText } from "./caller-text-echo.js";
7
8
  import { grantBindingArm, grantBindingOf } from "./standing-answer-grant.js";
9
+ import { pgHasUnstorable } from "./plugins/pg-safe-json.js";
8
10
  import { retireParkArmWords, retireStoredCardWords } from "./retired-card-words.js";
9
11
  export const MAX_AGENT_NAME = 200;
10
12
  const MAX_IDENT = 200;
@@ -332,6 +334,45 @@ export function readAskClassPair(carrier) {
332
334
  recordFailOpen("server.approval-card.closed-word-out-of-set", isAskClass(askClass) ? `classes=${outOfSetDetail(classes)}` : `askClass=${outOfSetDetail(askClass)}`);
333
335
  return undefined;
334
336
  }
337
+ export function readAskReasons(carrier) {
338
+ if (typeof carrier !== "object" || carrier === null || !("askReasons" in carrier))
339
+ return undefined;
340
+ const raw = carrier.askReasons;
341
+ if (raw === undefined)
342
+ return undefined;
343
+ const out = [];
344
+ if (Array.isArray(raw) && raw.length > 0) {
345
+ for (const e of raw) {
346
+ const entry = readAskReasonEntry(e);
347
+ if (entry === undefined)
348
+ break;
349
+ out.push(entry);
350
+ }
351
+ if (out.length === raw.length)
352
+ return out;
353
+ }
354
+ recordFailOpen("server.approval-card.closed-word-out-of-set", `askReasons=${outOfSetDetail(raw)}`);
355
+ return undefined;
356
+ }
357
+ function readAskReasonEntry(e) {
358
+ if (typeof e !== "object" || e === null)
359
+ return undefined;
360
+ const r = e;
361
+ const words = r.words === undefined ? undefined : typeof r.words === "string" ? capText(seatText("trace-frame-text", r.words), MAX_MESSAGE) : null;
362
+ if (words === null)
363
+ return undefined;
364
+ if (r.by === "hook") {
365
+ if (!HOOK_QUESTION_CAUSES.includes(r.cause))
366
+ return undefined;
367
+ const registration = r.registration === undefined ? undefined : typeof r.registration === "string" ? capText(seatText("trace-frame-text", r.registration), MAX_IDENT) : null;
368
+ if (registration === null)
369
+ return undefined;
370
+ return { by: "hook", cause: r.cause, ...(registration !== undefined ? { registration } : {}), ...(words !== undefined ? { words } : {}) };
371
+ }
372
+ if (!isAskOrigin(r.by) || r.by === "hook" || words === undefined)
373
+ return undefined;
374
+ return { by: r.by, words };
375
+ }
335
376
  export function parkRowFacts(stored) {
336
377
  if (typeof stored !== "object" || stored === null || !("kind" in stored) || stored.kind !== "tool_approval")
337
378
  return {};
@@ -340,6 +381,7 @@ export function parkRowFacts(stored) {
340
381
  const mandate = readClosedWordSeat(pendingAction, "mandate");
341
382
  const origin = readClosedWordSeat(pendingAction, "origin");
342
383
  const askClassPair = readAskClassPair(pendingAction);
384
+ const askReasons = readAskReasons(pendingAction);
343
385
  return {
344
386
  ...(readParkRowTrueSeat(pendingAction, "requiresRealApproval") ? { requiresRealApproval: true } : {}),
345
387
  ...(readParkRowTrueSeat(pendingAction, "mandated") ? { mandated: true } : {}),
@@ -347,6 +389,7 @@ export function parkRowFacts(stored) {
347
389
  ...(origin !== undefined ? { origin } : {}),
348
390
  ...(ruleOffersAbsence !== undefined ? { ruleOffersAbsence } : {}),
349
391
  ...(askClassPair ?? {}),
392
+ ...(askReasons !== undefined ? { askReasons } : {}),
350
393
  ...grantBindingArm(grantBindingOf(pendingAction)),
351
394
  };
352
395
  }
@@ -416,8 +459,16 @@ export const ApprovalCardSchema = z
416
459
  askClass: z.custom((v) => isAskClass(v)).optional(),
417
460
  classes: z.array(z.custom((v) => isAskClass(v))).min(1).optional(),
418
461
  fromSubagent: z.literal(true).optional(),
419
- sourceTaskId: z.string().max(MAX_IDENT).optional(),
462
+ sourceSessionId: z.string().max(MAX_IDENT).optional(),
463
+ agentId: z.string().max(MAX_IDENT).optional(),
420
464
  sourceAgentName: z.string().max(MAX_AGENT_NAME).optional(),
465
+ askReasons: z
466
+ .array(z.union([
467
+ z.object({ by: z.literal("hook"), registration: z.string().max(MAX_IDENT).optional(), cause: z.enum(HOOK_QUESTION_CAUSES), words: z.string().max(MAX_MESSAGE).optional() }).strict(),
468
+ z.object({ by: z.custom((v) => isAskOrigin(v) && v !== "hook"), words: z.string().max(MAX_MESSAGE) }).strict(),
469
+ ]))
470
+ .min(1)
471
+ .optional(),
421
472
  delegation: z
422
473
  .object({
423
474
  parentToolCallId: z.string().max(MAX_IDENT),
@@ -439,6 +490,7 @@ export const ApprovalCardEnvelopeSchema = z
439
490
  schemaVersion: z.literal(1),
440
491
  approvalId: z.string(),
441
492
  card: ApprovalCardSchema,
493
+ liveFacts: z.unknown().optional(),
442
494
  })
443
495
  .strict();
444
496
  export const APPROVAL_CARD_SCHEMA_VERSION = 1;
@@ -459,8 +511,10 @@ export function buildApprovalCard(source, req, requiresRealApproval) {
459
511
  const denialLimitFallback = readDenialLimitFallback(req);
460
512
  const askClassPair = readAskClassPair(source);
461
513
  const toolCallId = capText(source.toolCallId, MAX_IDENT);
462
- const sourceTaskId = capText(source.sourceTaskId, MAX_IDENT);
514
+ const sourceSessionId = capText(source.sourceSessionId, MAX_IDENT);
515
+ const agentId = capText(source.agentId, MAX_IDENT);
463
516
  const sourceAgentName = capText(source.sourceAgentName, MAX_AGENT_NAME);
517
+ const askReasons = readAskReasons(req);
464
518
  const allowRuleShadowed = readAllowRuleShadowed(req);
465
519
  const approvalCard = readApprovalCard(source.approvalCard);
466
520
  return {
@@ -485,8 +539,10 @@ export function buildApprovalCard(source, req, requiresRealApproval) {
485
539
  ...(denialLimitFallback !== undefined ? { denialLimitFallback } : {}),
486
540
  ...(askClassPair !== undefined ? { askClass: askClassPair.askClass, classes: askClassPair.classes } : {}),
487
541
  ...(source.fromSubagent === true ? { fromSubagent: true } : {}),
488
- ...(sourceTaskId !== undefined ? { sourceTaskId } : {}),
542
+ ...(sourceSessionId !== undefined ? { sourceSessionId } : {}),
543
+ ...(agentId !== undefined ? { agentId } : {}),
489
544
  ...(sourceAgentName !== undefined ? { sourceAgentName } : {}),
545
+ ...(askReasons !== undefined ? { askReasons } : {}),
490
546
  ...(source.delegation
491
547
  ? {
492
548
  delegation: {
@@ -498,15 +554,20 @@ export function buildApprovalCard(source, req, requiresRealApproval) {
498
554
  : {}),
499
555
  };
500
556
  }
501
- export function buildApprovalCardEnvelope(approvalId, card) {
502
- return { schemaVersion: APPROVAL_CARD_SCHEMA_VERSION, approvalId, card };
557
+ export function buildApprovalCardEnvelope(approvalId, card, liveFacts) {
558
+ const seat = pickApprovalRequestLiveFacts(liveFacts);
559
+ return { schemaVersion: APPROVAL_CARD_SCHEMA_VERSION, approvalId, card, ...(pgHasUnstorable(seat) ? {} : { liveFacts: seat }) };
503
560
  }
504
561
  export function readStoredCardEnvelope(cardJson) {
505
- const stored = retireStoredCardWords(cardJson);
562
+ const stored = retireStoredCardWords(renameRetiredSourceKey(cardJson));
506
563
  if (stored.seats.length > 0)
507
564
  noteRetiredCardWordRead("card_json", stored.seats);
508
565
  const parsed = ApprovalCardEnvelopeSchema.safeParse(stored.value);
509
- return parsed.success ? parsed.data : undefined;
566
+ if (!parsed.success)
567
+ return undefined;
568
+ const { liveFacts: seat, ...envelope } = parsed.data;
569
+ const liveFacts = seat === undefined ? undefined : ApprovalRequestLiveFactsSchema.safeParse(seat);
570
+ return liveFacts?.success === true ? { ...envelope, liveFacts: liveFacts.data } : envelope;
510
571
  }
511
572
  export function currentParkArm(pendingAction) {
512
573
  const arm = retireParkArmWords(pendingAction);
@@ -514,6 +575,16 @@ export function currentParkArm(pendingAction) {
514
575
  noteRetiredCardWordRead("parked row", arm.seats);
515
576
  return arm.value;
516
577
  }
578
+ function renameRetiredSourceKey(envelope) {
579
+ if (envelope === null || typeof envelope !== "object" || Array.isArray(envelope))
580
+ return envelope;
581
+ const card = envelope.card;
582
+ if (card === null || typeof card !== "object" || Array.isArray(card) || !Object.hasOwn(card, "sourceTaskId") || Object.hasOwn(card, "sourceSessionId"))
583
+ return envelope;
584
+ const { sourceTaskId, ...rest } = card;
585
+ recordFailOpen("server.approval-card.retired-card-key-read", "card_json: sourceTaskId");
586
+ return { ...envelope, card: { ...rest, sourceSessionId: sourceTaskId } };
587
+ }
517
588
  function noteRetiredCardWordRead(carrier, seats) {
518
589
  recordFailOpen("server.approval-card.retired-card-word-read", `${carrier}: ${seats.join(" / ")}`);
519
590
  }
@@ -529,7 +600,7 @@ export function buildApprovalRequestFrame(input) {
529
600
  expiresInMs: Math.max(0, input.expiresAtMs - input.nowMs),
530
601
  serverNowMs: input.nowMs,
531
602
  approvalId: input.approvalId,
532
- ...pickApprovalRequestLiveFacts(input.live),
603
+ ...(input.live !== undefined ? pickApprovalRequestLiveFacts(input.live) : { liveFactsUnknown: true }),
533
604
  };
534
605
  }
535
606
  export const APPROVAL_REQUEST_LIVE_FACT_KEYS = [
@@ -554,6 +625,26 @@ function pickApprovalRequestLiveFacts(src) {
554
625
  }
555
626
  return out;
556
627
  }
628
+ export function adoptStoredLiveFacts(frame, seat) {
629
+ for (const key of APPROVAL_REQUEST_LIVE_FACT_KEYS)
630
+ delete frame[key];
631
+ Object.assign(frame, pickApprovalRequestLiveFacts(seat));
632
+ }
633
+ const ApprovalRequestLiveFactsSchema = z
634
+ .object({
635
+ mandated: z.literal(true).optional(),
636
+ mandate: z.custom((v) => isPersistedRuleMandate(v)).optional(),
637
+ origin: z.string().min(1).optional(),
638
+ boundGrantDigest: z.string().optional(),
639
+ boundGrants: z.object({ skill: z.string().nullable(), allowedTools: z.array(z.string()).readonly(), disallowedTools: z.array(z.string()).readonly() }).strict().optional(),
640
+ classifierNoRuling: z.custom((v) => isAutoModeFallbackCause(v)).optional(),
641
+ boundGrantAbsence: z.enum(BOUND_GRANT_ABSENCES).optional(),
642
+ approvalCard: z.enum(TOOL_APPROVAL_CARDS).optional(),
643
+ readRootCandidate: z.object({ dir: z.string().min(1).max(READ_ROOT_CANDIDATE_DIR_MAX), clearsThisAsk: z.literal(true), covers: z.literal("exact").optional() }).strict().optional(),
644
+ probeReason: z.string().min(1).optional(),
645
+ requestedBy: z.object({ kind: z.literal("extension"), name: z.string() }).strict().optional(),
646
+ })
647
+ .strict();
557
648
  export function buildApprovalCompleteFrame(input) {
558
649
  return {
559
650
  type: "approval_complete",
@@ -571,21 +662,10 @@ export function buildRevokeFrame(batchId, askIds, reason, serverNowMs, originTas
571
662
  return { type: "approval_revoke", schemaVersion: 1, batchId, askIds: [...askIds], reason, serverNowMs, taskId: originTaskId };
572
663
  }
573
664
  export function buildReplayFrame(row, nowMs) {
574
- const parsed = readStoredCardEnvelope(row.cardJson);
575
- if (parsed === undefined)
665
+ const stored = readStoredCardEnvelope(row.cardJson);
666
+ if (stored === undefined)
576
667
  return undefined;
577
- return {
578
- type: "approval_request",
579
- schemaVersion: 1,
580
- askId: row.askId,
581
- taskId: row.taskId,
582
- kind: "permission",
583
- card: parsed.card,
584
- expiresAtMs: row.expiresAtMs,
585
- expiresInMs: Math.max(0, row.expiresAtMs - nowMs),
586
- serverNowMs: nowMs,
587
- approvalId: row.askId,
588
- };
668
+ return buildApprovalRequestFrame({ askId: row.askId, taskId: row.taskId, approvalId: row.askId, card: stored.card, expiresAtMs: row.expiresAtMs, nowMs, live: stored.liveFacts });
589
669
  }
590
670
  export function storedCardDemandsAPerson(cardJson) {
591
671
  const parsed = readStoredCardEnvelope(cardJson);