@sema-agent/core 7.52.0 → 7.54.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 (357) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/LICENSE +3 -1
  3. package/README.md +3 -1
  4. package/dist/agents/cross-session-envelope.d.ts +8 -0
  5. package/dist/agents/cross-session-envelope.js +6 -0
  6. package/dist/agents/cross-session-judge.d.ts +21 -1
  7. package/dist/agents/cross-session-judge.js +8 -0
  8. package/dist/agents/cross-session-ref.d.ts +5 -0
  9. package/dist/agents/cross-session-ref.js +1 -0
  10. package/dist/agents/org-delivery-gate.d.ts +122 -0
  11. package/dist/agents/org-delivery-gate.js +69 -0
  12. package/dist/agents/peer-held-queue.d.ts +9 -4
  13. package/dist/agents/peer-held-queue.js +6 -5
  14. package/dist/agents/peer-session-drain.d.ts +35 -6
  15. package/dist/agents/peer-session-drain.js +271 -182
  16. package/dist/agents/read-inbox-tool.d.ts +7 -0
  17. package/dist/agents/read-inbox-tool.js +5 -1
  18. package/dist/agents/send-message-tool.js +3 -4
  19. package/dist/agents/subagent.d.ts +6 -5
  20. package/dist/agents/subagent.js +117 -83
  21. package/dist/agents/tool-filter.d.ts +25 -4
  22. package/dist/agents/tool-filter.js +13 -3
  23. package/dist/brain/anthropic.d.ts +6 -1
  24. package/dist/brain/anthropic.js +4 -4
  25. package/dist/brain/model-presets.js +2 -1
  26. package/dist/brain/route-adjudicator.d.ts +6 -0
  27. package/dist/brain/routing.d.ts +24 -1
  28. package/dist/brain/routing.js +54 -19
  29. package/dist/brain/timeout.js +5 -4
  30. package/dist/core/a2a.d.ts +5 -2
  31. package/dist/core/a2a.js +33 -14
  32. package/dist/core/allow-entry.d.ts +3 -1
  33. package/dist/core/allow-entry.js +3 -2
  34. package/dist/core/approval-object.d.ts +87 -0
  35. package/dist/core/approval-object.js +85 -0
  36. package/dist/core/arg-summary.d.ts +3 -2
  37. package/dist/core/arg-summary.js +17 -11
  38. package/dist/core/ask-origin.d.ts +43 -27
  39. package/dist/core/ask-origin.js +20 -11
  40. package/dist/core/ask-question.d.ts +0 -1
  41. package/dist/core/ask-question.js +4 -67
  42. package/dist/core/ask-unresolvable-notice.d.ts +3 -2
  43. package/dist/core/auto-compaction.d.ts +106 -50
  44. package/dist/core/auto-compaction.js +69 -53
  45. package/dist/core/auto-mode-prompt.d.ts +4 -2
  46. package/dist/core/auto-mode-prompt.js +4 -3
  47. package/dist/core/canonical-json.d.ts +69 -0
  48. package/dist/core/canonical-json.js +130 -8
  49. package/dist/core/checkpoint-requirements.d.ts +13 -7
  50. package/dist/core/checkpoint-requirements.js +4 -1
  51. package/dist/core/checkpoint-store.d.ts +60 -36
  52. package/dist/core/checkpoint-store.js +7 -6
  53. package/dist/core/child-clamp-seats.d.ts +45 -6
  54. package/dist/core/child-clamp-seats.js +56 -4
  55. package/dist/core/compliance.js +3 -1
  56. package/dist/core/consolidate-scope.d.ts +1 -1
  57. package/dist/core/cross-boundary-taint.d.ts +213 -0
  58. package/dist/core/cross-boundary-taint.js +196 -0
  59. package/dist/core/decision-receipt.d.ts +44 -1
  60. package/dist/core/decision-receipt.js +16 -0
  61. package/dist/core/effective-path-target.d.ts +28 -6
  62. package/dist/core/effective-path-target.js +28 -2
  63. package/dist/core/engine-notice.d.ts +47 -4
  64. package/dist/core/engine-notice.js +17 -1
  65. package/dist/core/engine-storage-backend.d.ts +73 -0
  66. package/dist/core/engine-storage-backend.js +1 -0
  67. package/dist/core/file-history-store.d.ts +6 -2
  68. package/dist/core/file-history-store.js +1 -0
  69. package/dist/core/gate-fold.js +13 -4
  70. package/dist/core/gate-lanes.js +41 -34
  71. package/dist/core/gate-outcome.d.ts +18 -9
  72. package/dist/core/governance-codes.d.ts +9 -2
  73. package/dist/core/governance-codes.js +9 -0
  74. package/dist/core/hands-band-screen.d.ts +7 -0
  75. package/dist/core/hands-band-screen.js +32 -0
  76. package/dist/core/hooks.d.ts +21 -19
  77. package/dist/core/hooks.js +6 -5
  78. package/dist/core/locked-config.d.ts +110 -31
  79. package/dist/core/locked-config.js +155 -42
  80. package/dist/core/lsp.d.ts +1 -1
  81. package/dist/core/mcp-probe.js +1 -1
  82. package/dist/core/mcp-server-spec.d.ts +152 -17
  83. package/dist/core/mcp-server-spec.js +223 -40
  84. package/dist/core/mcp.d.ts +21 -14
  85. package/dist/core/mcp.js +59 -54
  86. package/dist/core/memory-engine/engine.d.ts +14 -19
  87. package/dist/core/memory-engine/engine.js +9 -6
  88. package/dist/core/memory-engine/export-bundle.d.ts +1 -1
  89. package/dist/core/memory-engine/export-bundle.js +1 -1
  90. package/dist/core/memory-engine/file-backend.d.ts +2 -6
  91. package/dist/core/memory-engine/file-backend.js +1 -12
  92. package/dist/core/memory.d.ts +3 -3
  93. package/dist/core/mode-policy.d.ts +16 -26
  94. package/dist/core/mode-policy.js +5 -18
  95. package/dist/core/mods/kernel/dispatch.js +13 -15
  96. package/dist/core/mods/kernel/events.d.ts +9 -6
  97. package/dist/core/mods/kernel/events.js +2 -2
  98. package/dist/core/mods/kernel/receive.d.ts +41 -11
  99. package/dist/core/mods/kernel/receive.js +124 -54
  100. package/dist/core/mods/kernel/site-rules.d.ts +80 -15
  101. package/dist/core/mods/kernel/site-rules.js +232 -40
  102. package/dist/core/mods/stations.d.ts +0 -6
  103. package/dist/core/mods/stations.js +0 -7
  104. package/dist/core/mounted-mcp.d.ts +57 -0
  105. package/dist/core/mounted-mcp.js +71 -2
  106. package/dist/core/own-property-receipt.d.ts +13 -0
  107. package/dist/core/own-property-receipt.js +3 -1
  108. package/dist/core/parent-spec-seat.d.ts +12 -15
  109. package/dist/core/parent-spec-seat.js +14 -6
  110. package/dist/core/pause-registry.d.ts +35 -1
  111. package/dist/core/pause-registry.js +10 -0
  112. package/dist/core/permission-rule-consent.d.ts +18 -5
  113. package/dist/core/permission-rule-consent.js +13 -8
  114. package/dist/core/permission-rule-model.d.ts +87 -15
  115. package/dist/core/permission-rule-model.js +87 -8
  116. package/dist/core/permission-rule-org.d.ts +200 -33
  117. package/dist/core/permission-rule-org.js +217 -91
  118. package/dist/core/permission-rule-session.js +2 -2
  119. package/dist/core/permission-rule-store.d.ts +8 -0
  120. package/dist/core/permission-rule-store.js +1 -0
  121. package/dist/core/permission-rule-sync.js +3 -2
  122. package/dist/core/permission-rules.d.ts +7 -1
  123. package/dist/core/permission-rules.js +37 -8
  124. package/dist/core/read-only-shell.d.ts +1 -1
  125. package/dist/core/read-only-shell.js +30 -9
  126. package/dist/core/remote-env.d.ts +41 -1
  127. package/dist/core/remote-env.js +18 -0
  128. package/dist/core/resume-startup-cause.d.ts +18 -0
  129. package/dist/core/resume-startup-cause.js +12 -0
  130. package/dist/core/retention.js +7 -2
  131. package/dist/core/retired-keys.d.ts +8 -2
  132. package/dist/core/retired-keys.js +12 -1
  133. package/dist/core/roles.js +60 -10
  134. package/dist/core/rule-lane-reads.js +1 -1
  135. package/dist/core/runner/approval-feedback.d.ts +46 -0
  136. package/dist/core/runner/approval-feedback.js +41 -0
  137. package/dist/core/runner/compaction-call-options.d.ts +3 -3
  138. package/dist/core/runner/compaction-call-options.js +2 -2
  139. package/dist/core/runner/contracts.d.ts +34 -41
  140. package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
  141. package/dist/core/runner/cross-boundary-lane.js +190 -0
  142. package/dist/core/runner/decide-continuation.d.ts +4 -4
  143. package/dist/core/runner/decide-continuation.js +3 -1
  144. package/dist/core/runner/gate-exit.d.ts +32 -12
  145. package/dist/core/runner/gate-exit.js +77 -34
  146. package/dist/core/runner/inherited-ask-grants.js +2 -2
  147. package/dist/core/runner/mcp-redial.d.ts +52 -10
  148. package/dist/core/runner/mcp-redial.js +38 -9
  149. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  150. package/dist/core/runner/permission-rule-lanes.js +22 -10
  151. package/dist/core/runner/person-path-rows.d.ts +5 -3
  152. package/dist/core/runner/person-path-rows.js +2 -2
  153. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
  154. package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
  155. package/dist/core/runner/prepare-ask-lane.js +3 -3
  156. package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
  157. package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
  158. package/dist/core/runner/prepare-config-doors.d.ts +58 -15
  159. package/dist/core/runner/prepare-config-doors.js +167 -146
  160. package/dist/core/runner/prepare-context-lane.js +6 -3
  161. package/dist/core/runner/prepare-defer-classify.js +4 -7
  162. package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
  163. package/dist/core/runner/prepare-delegation-surface.js +8 -7
  164. package/dist/core/runner/prepare-execution-env.d.ts +1 -2
  165. package/dist/core/runner/prepare-execution-env.js +2 -1
  166. package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
  167. package/dist/core/runner/prepare-gate-stations.js +4 -3
  168. package/dist/core/runner/prepare-hands-readface.d.ts +3 -3
  169. package/dist/core/runner/prepare-hands-readface.js +3 -2
  170. package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
  171. package/dist/core/runner/prepare-inherited-gate.js +3 -2
  172. package/dist/core/runner/prepare-listings.d.ts +1 -1
  173. package/dist/core/runner/prepare-listings.js +4 -2
  174. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  175. package/dist/core/runner/prepare-memory-engine-session.js +19 -6
  176. package/dist/core/runner/prepare-memory.d.ts +3 -2
  177. package/dist/core/runner/prepare-memory.js +6 -2
  178. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  179. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  180. package/dist/core/runner/prepare-park-ask.d.ts +1 -1
  181. package/dist/core/runner/prepare-park-ask.js +9 -3
  182. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  183. package/dist/core/runner/prepare-policy-chain.js +14 -19
  184. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  185. package/dist/core/runner/prepare-project-context.js +6 -4
  186. package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
  187. package/dist/core/runner/prepare-prompt-assembly.js +20 -16
  188. package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
  189. package/dist/core/runner/prepare-prompt-inputs.js +6 -3
  190. package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
  191. package/dist/core/runner/prepare-protocol-tools.js +19 -12
  192. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  193. package/dist/core/runner/prepare-question-face.js +4 -3
  194. package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
  195. package/dist/core/runner/prepare-safety-scan.js +34 -27
  196. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
  197. package/dist/core/runner/prepare-suspend-saga.js +6 -2
  198. package/dist/core/runner/prepare-task.js +22 -19
  199. package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
  200. package/dist/core/runner/prepare-turn-wiring.js +14 -49
  201. package/dist/core/runner/prepare-wiring-manifest.d.ts +10 -5
  202. package/dist/core/runner/prepare-wiring-manifest.js +9 -6
  203. package/dist/core/runner/prepare-workspace-restore.js +2 -2
  204. package/dist/core/runner/resume-admission.d.ts +4 -1
  205. package/dist/core/runner/resume-admission.js +16 -14
  206. package/dist/core/runner/resume-apply.js +4 -4
  207. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  208. package/dist/core/runner/resume-internals-and-config.js +3 -8
  209. package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
  210. package/dist/core/runner/resume-policy-outcome.js +18 -15
  211. package/dist/core/runner/resume-preflight.js +2 -2
  212. package/dist/core/runner/resume-review-outcome.js +3 -3
  213. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  214. package/dist/core/runner/retired-runner-deps.js +1 -4
  215. package/dist/core/runner/run-leg.js +97 -43
  216. package/dist/core/runner/run-recovery-lanes.js +5 -3
  217. package/dist/core/runner/run-settle-and-teardown.js +2 -0
  218. package/dist/core/runner/run-terminal-adoption.js +21 -9
  219. package/dist/core/runner/run-turn-boundary.js +9 -3
  220. package/dist/core/runner/runtask.js +1 -1
  221. package/dist/core/runner/session-file-state-replay.d.ts +5 -2
  222. package/dist/core/runner/session-file-state-replay.js +3 -2
  223. package/dist/core/runner/skills-seat.d.ts +15 -0
  224. package/dist/core/runner/skills-seat.js +57 -0
  225. package/dist/core/runner/stream-steer-verb.js +2 -2
  226. package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
  227. package/dist/core/runner/sub-agent-deny-lists.js +7 -5
  228. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  229. package/dist/core/runner/synthetic-tools.js +2 -12
  230. package/dist/core/runner/tool-face-overlay.d.ts +24 -6
  231. package/dist/core/runner/tool-face-overlay.js +24 -15
  232. package/dist/core/runner-deps.d.ts +37 -22
  233. package/dist/core/session-policy-store.d.ts +19 -0
  234. package/dist/core/session-policy-store.js +22 -2
  235. package/dist/core/session-store.d.ts +35 -16
  236. package/dist/core/session-store.js +20 -12
  237. package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
  238. package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
  239. package/dist/core/shell-wrapper-table.d.ts +5 -3
  240. package/dist/core/shell-wrapper-table.js +1 -1
  241. package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
  242. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  243. package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
  244. package/dist/core/store-contracts/session-store-contract.js +639 -0
  245. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
  246. package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
  247. package/dist/core/task-event.d.ts +44 -6
  248. package/dist/core/task-notification.js +2 -2
  249. package/dist/core/task-registry-agent.js +1 -0
  250. package/dist/core/task-registry-shared.d.ts +5 -0
  251. package/dist/core/task-registry.d.ts +7 -0
  252. package/dist/core/task-registry.js +17 -0
  253. package/dist/core/task-result.d.ts +1 -1
  254. package/dist/core/task-spec.d.ts +7 -7
  255. package/dist/core/tighten-task-spec.d.ts +6 -4
  256. package/dist/core/tighten-task-spec.js +2 -2
  257. package/dist/core/tool-catalog-entries.d.ts +1 -1
  258. package/dist/core/tool-catalog-entries.js +52 -52
  259. package/dist/core/tool-face-reader.d.ts +49 -0
  260. package/dist/core/tool-face-reader.js +94 -0
  261. package/dist/core/tool-face.d.ts +17 -8
  262. package/dist/core/tool-face.js +1 -0
  263. package/dist/core/tool-policy.d.ts +67 -23
  264. package/dist/core/tool-policy.js +72 -60
  265. package/dist/core/tool-roster.d.ts +46 -28
  266. package/dist/core/tool-roster.js +91 -14
  267. package/dist/core/tool-spec-members.js +2 -2
  268. package/dist/core/tool-spec.d.ts +20 -4
  269. package/dist/core/tools.js +2 -0
  270. package/dist/core/trace.d.ts +24 -2
  271. package/dist/core/types.d.ts +3 -3
  272. package/dist/core/types.js +1 -1
  273. package/dist/core/untrusted-text.d.ts +23 -0
  274. package/dist/core/untrusted-text.js +10 -10
  275. package/dist/core/user-attachment.d.ts +56 -2
  276. package/dist/core/user-attachment.js +139 -56
  277. package/dist/core/wiring-manifest.d.ts +4 -2
  278. package/dist/engine/compaction/compaction.d.ts +2 -2
  279. package/dist/engine/compaction/utils.d.ts +2 -2
  280. package/dist/engine/harness/agent-harness.js +2 -1
  281. package/dist/engine/harness/types.d.ts +10 -4
  282. package/dist/engine/llm/types.d.ts +7 -2
  283. package/dist/engine/llm/types.js +2 -1
  284. package/dist/engine/loop/agent-loop.d.ts +12 -1
  285. package/dist/engine/loop/agent-loop.js +17 -5
  286. package/dist/engine/loop/types.d.ts +7 -1
  287. package/dist/engine/session/repo-utils.d.ts +5 -0
  288. package/dist/engine/session/repo-utils.js +9 -0
  289. package/dist/engine/session/storage-base.js +2 -2
  290. package/dist/index.d.ts +37 -17
  291. package/dist/index.js +31 -14
  292. package/dist/internal/harness.d.ts +1 -0
  293. package/dist/internal/harness.js +1 -0
  294. package/dist/internal/llm.d.ts +1 -1
  295. package/dist/internal/llm.js +1 -1
  296. package/dist/orchestration/goal.d.ts +24 -1
  297. package/dist/orchestration/goal.js +3 -2
  298. package/dist/orchestration/run-workflow-tool.d.ts +3 -0
  299. package/dist/orchestration/run-workflow-tool.js +1 -0
  300. package/dist/orchestration/workflow-governance.d.ts +1 -1
  301. package/dist/orchestration/workflow.d.ts +3 -0
  302. package/dist/orchestration/workflow.js +2 -1
  303. package/dist/prompt-assembly/artifact-store.d.ts +44 -9
  304. package/dist/prompt-assembly/artifact-store.js +38 -12
  305. package/dist/prompt-assembly/artifact.d.ts +12 -11
  306. package/dist/prompt-assembly/artifact.js +52 -21
  307. package/dist/prompt-assembly/assemble.d.ts +2 -0
  308. package/dist/prompt-assembly/assemble.js +2 -1
  309. package/dist/prompt-assembly/catalog/index.js +2 -1
  310. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  311. package/dist/prompt-assembly/catalog/memory.js +6 -0
  312. package/dist/prompt-assembly/catalog/schema.d.ts +19 -2
  313. package/dist/prompt-assembly/catalog/schema.js +3 -0
  314. package/dist/prompt-assembly/composer.d.ts +2 -0
  315. package/dist/prompt-assembly/composer.js +1 -1
  316. package/dist/prompt-assembly/overlay.d.ts +21 -11
  317. package/dist/prompt-assembly/overlay.js +57 -19
  318. package/dist/prompt-assembly/select.d.ts +21 -6
  319. package/dist/prompt-assembly/select.js +41 -4
  320. package/dist/prompts/default.d.ts +1 -12
  321. package/dist/prompts/default.js +0 -3
  322. package/dist/shell/lex.d.ts +87 -8
  323. package/dist/shell/lex.js +283 -49
  324. package/dist/stores/file/index.d.ts +8 -6
  325. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  326. package/dist/stores/file/permission-rule-store.js +2 -1
  327. package/dist/tools/artifact/artifact-tool.js +14 -3
  328. package/dist/tools/fs/bash-program-position.d.ts +3 -15
  329. package/dist/tools/fs/bash-program-position.js +3 -10
  330. package/dist/tools/fs/bash-readonly-classifier.js +2 -0
  331. package/dist/tools/fs/fs-bash.d.ts +3 -3
  332. package/dist/tools/fs/fs-bash.js +72 -101
  333. package/dist/tools/fs/fs-read.d.ts +12 -0
  334. package/dist/tools/fs/fs-read.js +10 -9
  335. package/dist/tools/fs/fs-shared.d.ts +27 -31
  336. package/dist/tools/fs/fs-shared.js +12 -15
  337. package/dist/tools/fs/fs-write.js +1 -1
  338. package/dist/tools/fs/index.js +2 -2
  339. package/dist/tools/fs/read-deny-home.d.ts +1 -1
  340. package/dist/tools/fs/read-deny-home.js +5 -4
  341. package/dist/tools/fs/read-deny.d.ts +16 -3
  342. package/dist/tools/fs/read-deny.js +12 -9
  343. package/dist/tools/fs/safety.d.ts +7 -6
  344. package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
  345. package/dist/tools/fs/shell-read-bindings.js +15 -16
  346. package/dist/tools/fs/shell-read-device.js +1 -1
  347. package/dist/tools/fs/shell-read-plan.js +36 -47
  348. package/dist/tools/fs/shell-read-word.d.ts +1 -6
  349. package/dist/tools/fs/shell-read-word.js +2 -20
  350. package/dist/tools/fs/shell-reentry-text.js +1 -1
  351. package/dist/tools/web.d.ts +2 -2
  352. package/package.json +4 -1
  353. package/test/export-surface.snapshot.json +5651 -5457
  354. package/wire-changes/core@7.53.0.json +1968 -0
  355. package/wire-changes/core@7.54.0.json +2870 -0
  356. package/dist/core/shell-scan.d.ts +0 -60
  357. package/dist/core/shell-scan.js +0 -183
@@ -1,4 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { types } from "node:util";
3
+ import { describeFault, receive } from "./mods/kernel/receive.js";
2
4
  export function canonicalize(value) {
3
5
  try {
4
6
  return encode(value);
@@ -11,7 +13,115 @@ export const UNCANONICALIZABLE = "<uncanonicalizable>";
11
13
  export function boundInputHashOf(value) {
12
14
  return createHash("sha256").update(canonicalize(value), "utf8").digest("hex");
13
15
  }
14
- const MAX_DEPTH = 256;
16
+ export function exactBoundInputHashOf(value) {
17
+ const bound = bindableValueOf(value);
18
+ if (!bound.ok)
19
+ return undefined;
20
+ const form = canonicalize(bound.value);
21
+ return form === UNCANONICALIZABLE ? undefined : createHash("sha256").update(form, "utf8").digest("hex");
22
+ }
23
+ export function bindableValueOf(value, top = "record") {
24
+ const received = receive(value, BINDING_RECEIPT);
25
+ if (!received.ok)
26
+ return received;
27
+ const copy = received.value;
28
+ const topOk = top === "list" ? Array.isArray(copy) : typeof copy === "object" && copy !== null && !Array.isArray(copy);
29
+ if (!topOk)
30
+ return { ok: false, fault: { kind: "not-container", path: [] } };
31
+ const fault = jsonFaultIn(copy, [], new Set());
32
+ return fault === undefined ? { ok: true, value: received.value } : { ok: false, fault };
33
+ }
34
+ export function capturedJsonOf(value, top = "record") {
35
+ const bound = bindableValueOf(value, top);
36
+ return bound.ok ? { ok: true, value: jsonFormOf(bound.value) } : bound;
37
+ }
38
+ function jsonFormOf(value) {
39
+ if (Object.is(value, -0))
40
+ return 0;
41
+ if (typeof value !== "object" || value === null)
42
+ return value;
43
+ if (Array.isArray(value))
44
+ return value.map(jsonFormOf);
45
+ const out = {};
46
+ for (const [key, member] of Object.entries(value))
47
+ if (member !== undefined)
48
+ Object.defineProperty(out, key, { value: jsonFormOf(member), enumerable: true, writable: true, configurable: true });
49
+ return out;
50
+ }
51
+ function jsonFaultIn(v, path, met) {
52
+ if (typeof v === "number")
53
+ return Number.isFinite(v) ? undefined : { kind: "not-finite", path: [...path] };
54
+ if (typeof v !== "object" || v === null)
55
+ return undefined;
56
+ if (met.has(v))
57
+ return { kind: "shared", path: [...path] };
58
+ met.add(v);
59
+ const members = [];
60
+ if (Array.isArray(v)) {
61
+ for (let i = 0; i < v.length; i++) {
62
+ if (!Object.hasOwn(v, i))
63
+ return { kind: "hole", path: [...path, String(i)] };
64
+ if (v[i] === undefined)
65
+ return { kind: "undefined-element", path: [...path, String(i)] };
66
+ members.push([String(i), v[i]]);
67
+ }
68
+ const named = Object.keys(v).find((k) => !isIndexBelow(k, v.length));
69
+ if (named !== undefined)
70
+ return { kind: "list-member", path: [...path, named] };
71
+ }
72
+ else
73
+ for (const entry of Object.entries(v))
74
+ members.push(entry);
75
+ for (const [key, member] of members) {
76
+ path.push(key);
77
+ const fault = jsonFaultIn(member, path, met);
78
+ path.pop();
79
+ if (fault !== undefined)
80
+ return fault;
81
+ }
82
+ return undefined;
83
+ }
84
+ export function describeBindingFault(value, fault) {
85
+ const path = ["args", ...fault.path];
86
+ const at = ` at ${path.join(".")}`;
87
+ switch (fault.kind) {
88
+ case "not-container":
89
+ return `a value that is not a record${at}`;
90
+ case "not-finite":
91
+ return `a number that is not finite${at}`;
92
+ case "hole":
93
+ return `a hole in a list${at}`;
94
+ case "list-member":
95
+ return `a named member on a list${at}`;
96
+ case "undefined-element":
97
+ return `an undefined list element${at}`;
98
+ case "shared":
99
+ return `one object met twice${at} (a shared reference)`;
100
+ case "too-deep":
101
+ return `containers nested deeper than ${MAX_DEPTH} levels`;
102
+ case "not-data":
103
+ return `${kindOfValueAt(value, fault.path)}${at}`;
104
+ default:
105
+ return describeFault({ ...fault, path });
106
+ }
107
+ }
108
+ function kindOfValueAt(value, path) {
109
+ let at = value;
110
+ for (const key of path)
111
+ at = typeof at === "object" && at !== null ? at[key] : undefined;
112
+ if (typeof at === "function" || typeof at === "symbol" || typeof at === "bigint")
113
+ return `a ${typeof at}`;
114
+ return typeof at === "object" && at !== null ? "an object that is not a plain record or list" : "a value that is not data";
115
+ }
116
+ export const MAX_DEPTH = 256;
117
+ const BINDING_RECEIPT = Object.freeze({ accessors: "refuse", depth: MAX_DEPTH, past: "refuse", others: "refuse", freeze: true, isProxy: (v) => types.isProxy(v) });
118
+ const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
119
+ function segment(text) {
120
+ if (!LONE_SURROGATE.test(text))
121
+ return `${Buffer.byteLength(text, "utf8")}:${text}`;
122
+ const spelled = JSON.stringify(text);
123
+ return `S${Buffer.byteLength(spelled, "utf8")}:${spelled}`;
124
+ }
15
125
  function encode(value, depth = 0) {
16
126
  if (value === null)
17
127
  return "N";
@@ -25,7 +135,7 @@ function encode(value, depth = 0) {
25
135
  case "bigint":
26
136
  return `i:${value.toString()}`;
27
137
  case "string":
28
- return `s${Buffer.byteLength(value, "utf8")}:${value}`;
138
+ return `s${segment(value)}`;
29
139
  case "function":
30
140
  return "fn";
31
141
  case "symbol":
@@ -66,7 +176,7 @@ function encodeOwnKeys(source, depth, skipIndicesBelow = 0) {
66
176
  catch {
67
177
  encoded = "<unreadable-property>";
68
178
  }
69
- out += `${Buffer.byteLength(k, "utf8")}:${k}=${encoded}`;
179
+ out += `${segment(k)}=${encoded}`;
70
180
  }
71
181
  return `${out}}`;
72
182
  }
@@ -91,7 +201,7 @@ function encodeBranded(value, depth) {
91
201
  try {
92
202
  const { buffer, byteOffset, byteLength, elements, family } = viewRange(value);
93
203
  const bytesToken = digestBytes(new Uint8Array(buffer, byteOffset, byteLength));
94
- return `V:${family}:${brand}:${byteLength}:${bytesToken}${encodeOwnKeys(value, depth, elements)}`;
204
+ return `V:${family}:${segment(brand)}:${byteLength}:${bytesToken}${encodeOwnKeys(value, depth, elements)}`;
95
205
  }
96
206
  catch {
97
207
  }
@@ -128,16 +238,16 @@ function encodeBranded(value, depth) {
128
238
  case "RegExp": {
129
239
  const source = String(regexpSourceGetter.call(value));
130
240
  const flags = String(regexpFlagsGetter.call(value));
131
- return `r${Buffer.byteLength(source, "utf8")}:${source}/${flags}${own}`;
241
+ return `r${segment(source)}/${flags}${own}`;
132
242
  }
133
243
  case "Error": {
134
244
  const name = String(value.name);
135
245
  const message = String(value.message);
136
- return `E${Buffer.byteLength(name, "utf8")}:${name}:${Buffer.byteLength(message, "utf8")}:${message}${own}`;
246
+ return `E${segment(name)}:${segment(message)}${own}`;
137
247
  }
138
248
  case "URL": {
139
249
  const href = String(urlHrefGetter.call(value));
140
- return `L${Buffer.byteLength(href, "utf8")}:${href}${own}`;
250
+ return `L${segment(href)}${own}`;
141
251
  }
142
252
  case "Boolean":
143
253
  case "Number":
@@ -158,7 +268,7 @@ function encodeBranded(value, depth) {
158
268
  }
159
269
  catch {
160
270
  }
161
- return `x${Buffer.byteLength(brand, "utf8")}:${brand}${own}`;
271
+ return `x${segment(brand)}${own}`;
162
272
  }
163
273
  function primordialGetter(proto, key) {
164
274
  const get = Object.getOwnPropertyDescriptor(proto, key)?.get;
@@ -236,3 +346,15 @@ function encodeNumber(n) {
236
346
  return "0";
237
347
  return String(n);
238
348
  }
349
+ export function canonicalJsonStringify(value) {
350
+ if (Array.isArray(value))
351
+ return `[${value.map((v) => (v === undefined || typeof v === "function" || typeof v === "symbol" ? "null" : canonicalJsonStringify(v))).join(",")}]`;
352
+ if (value !== null && typeof value === "object") {
353
+ const rec = value;
354
+ const keys = Object.keys(rec)
355
+ .filter((k) => rec[k] !== undefined)
356
+ .sort();
357
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJsonStringify(rec[k])}`).join(",")}}`;
358
+ }
359
+ return JSON.stringify(value);
360
+ }
@@ -6,7 +6,7 @@ import { type StoreFidelity, type Checkpoint, type CheckpointFeature, type Check
6
6
  * had carried beside the one its word now names, and the members added after the table, each a capability a reader
7
7
  * must have. Downstream reads them for display only (`CheckpointError.detail.requires`).
8
8
  */
9
- export declare const REQUIREMENT_WORDS: readonly ["resource", "binding", "token", "orgAdmission", "f012", "realApproval", "face", "requirements_digest", "org_admission_inherited", "org_write_grant", "org_governed", "delegation_provenance", "skill_grants", "skill_card_binding", "hands_coordinates", "hands_home", "path_rule_anchors", "path_rule_installations", "permission_mode", "plan_mode_restore", "persisted_rule_mandate", "deployment_authored", "call_names", "write_face", "denial_limit_fallback", "leg_scope", "tool_ceiling", "tool_lists_judged", "own_tool_lists"];
9
+ export declare const REQUIREMENT_WORDS: readonly ["resource", "binding", "token", "orgAdmission", "f012", "realApproval", "face", "requirements_digest", "org_admission_inherited", "org_write_grant", "org_governed", "delegation_provenance", "skill_grants", "skill_card_binding", "hands_coordinates", "hands_home", "path_rule_anchors", "path_rule_installations", "permission_mode", "plan_mode_restore", "persisted_rule_mandate", "deployment_authored", "call_names", "write_face", "denial_limit_fallback", "leg_scope", "tool_ceiling", "tool_lists_judged", "own_tool_lists", "approval_targets", "cross_boundary"];
10
10
  export type RequirementWord = (typeof REQUIREMENT_WORDS)[number];
11
11
  /** Runtime twin of {@link RequirementWord}. */
12
12
  export declare function isRequirementWord(word: unknown): word is RequirementWord;
@@ -227,6 +227,9 @@ export declare const CHECKPOINT_STATE_REQUIREMENTS: {
227
227
  readonly ownToolLists: {
228
228
  readonly word: "own_tool_lists";
229
229
  };
230
+ readonly crossBoundaryRecorded: {
231
+ readonly word: "cross_boundary";
232
+ };
230
233
  };
231
234
  export declare const PENDING_ACTION_REQUIREMENTS: {
232
235
  readonly tool_approval: {
@@ -308,9 +311,6 @@ export declare const PENDING_ACTION_REQUIREMENTS: {
308
311
  readonly implementationRevision: {
309
312
  readonly digest: "decision-read";
310
313
  };
311
- readonly rosterDigest: {
312
- readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
313
- };
314
314
  readonly family: {
315
315
  readonly digest: "decision-read";
316
316
  };
@@ -320,6 +320,9 @@ export declare const PENDING_ACTION_REQUIREMENTS: {
320
320
  readonly names: {
321
321
  readonly word: "call_names";
322
322
  };
323
+ readonly targets: {
324
+ readonly word: "approval_targets";
325
+ };
323
326
  readonly hasBidiControls: {
324
327
  readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
325
328
  };
@@ -582,6 +585,9 @@ export declare const CHECKPOINT_REQUIREMENTS: {
582
585
  readonly ownToolLists: {
583
586
  readonly word: "own_tool_lists";
584
587
  };
588
+ readonly crossBoundaryRecorded: {
589
+ readonly word: "cross_boundary";
590
+ };
585
591
  };
586
592
  };
587
593
  readonly resourceLedger: {
@@ -808,9 +814,6 @@ export declare const CHECKPOINT_REQUIREMENTS: {
808
814
  readonly implementationRevision: {
809
815
  readonly digest: "decision-read";
810
816
  };
811
- readonly rosterDigest: {
812
- readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
813
- };
814
817
  readonly family: {
815
818
  readonly digest: "decision-read";
816
819
  };
@@ -820,6 +823,9 @@ export declare const CHECKPOINT_REQUIREMENTS: {
820
823
  readonly names: {
821
824
  readonly word: "call_names";
822
825
  };
826
+ readonly targets: {
827
+ readonly word: "approval_targets";
828
+ };
823
829
  readonly hasBidiControls: {
824
830
  readonly ignorable: "shown, never decided (card, listing, transcript or reported count): every read of the name renders, carries transcript or counts";
825
831
  };
@@ -31,6 +31,8 @@ export const REQUIREMENT_WORDS = Object.freeze([
31
31
  "tool_ceiling",
32
32
  "tool_lists_judged",
33
33
  "own_tool_lists",
34
+ "approval_targets",
35
+ "cross_boundary",
34
36
  ]);
35
37
  export function isRequirementWord(word) {
36
38
  return typeof word === "string" && REQUIREMENT_WORDS.includes(word);
@@ -92,6 +94,7 @@ export const CHECKPOINT_STATE_REQUIREMENTS = {
92
94
  toolCeiling: { word: "tool_ceiling" },
93
95
  toolListsJudged: { word: "tool_lists_judged" },
94
96
  ownToolLists: { word: "own_tool_lists" },
97
+ crossBoundaryRecorded: { word: "cross_boundary" },
95
98
  };
96
99
  export const PENDING_ACTION_REQUIREMENTS = {
97
100
  tool_approval: {
@@ -121,10 +124,10 @@ export const PENDING_ACTION_REQUIREMENTS = {
121
124
  contractId: DECISION_READ,
122
125
  shapeDigest: DECISION_READ,
123
126
  implementationRevision: DECISION_READ,
124
- rosterDigest: SHOWN,
125
127
  family: DECISION_READ,
126
128
  pathTarget: DECISION_READ,
127
129
  names: { word: "call_names" },
130
+ targets: { word: "approval_targets" },
128
131
  hasBidiControls: SHOWN,
129
132
  batchToolCallIds: DECISION_READ,
130
133
  completedCallIds: SHOWN,
@@ -1,6 +1,6 @@
1
1
  import type { GateOutcome, HostDecisionFacts } from "./gate-outcome.js";
2
2
  import { type ExecutionOutcomeRecordWord } from "./checkpoint-execution-record.js";
3
- import type { CheckpointPause } from "./pause-registry.js";
3
+ import { type CheckpointPause } from "./pause-registry.js";
4
4
  import type { SystemInjectionPriority } from "./task-notification.js";
5
5
  import { type SteerReplayFacet } from "./steer-replay.js";
6
6
  import type { QuestionAnswer } from "./ask-question.js";
@@ -581,6 +581,16 @@ export type ResumeOutcome = {
581
581
  updatedInput?: unknown;
582
582
  /** Model-readable reason attached to a `deny` (else a default is used). */
583
583
  reason?: string;
584
+ /**
585
+ * What the approving PERSON wrote in the card's "and tell the agent what to do next" input — the `allow`
586
+ * arm's counterpart of a `deny`'s {@link reason}. The resumed run's continuation user message carries it to
587
+ * the model as the user's own words, after the batch's tool results, once, verbatim apart from the outer
588
+ * whitespace: no fence, no wrapper sentence, no length bound. PRESENT only when the person wrote something
589
+ * (blank — empty or whitespace-only — delivers nothing; a host whose card has no input omits the key).
590
+ * ARM- AND DECIDER-SCOPED like `answer`: a written value on a `deny` or on a decide whose `hostDecision.decidedBy`
591
+ * is not `"person"`, a non-string, or text carrying a `<system-reminder>` tag (opening or closing) is refused pre-CAS.
592
+ */
593
+ feedback?: string;
584
594
  /**
585
595
  * The ANSWER to a CONTENT-ASK (the reserved AskUserQuestion tool), carried by the decide itself
586
596
  * (ruled 2026-08-04). A content-ask is a question TO the user: `allow` alone says "let the tool
@@ -854,17 +864,15 @@ export type PendingAction = {
854
864
  * precedent: an optional group an older reader ignores): the IDENTITY of the row the park minted
855
865
  * this action against, read off the leg's tool roster at the suspend station — `capabilityId`
856
866
  * (engine-minted over {source, peer, name, contractId}), `contractId`, `shapeDigest`,
857
- * `implementationRevision` — plus the roster `digest` of the leg that parked. The resume finds the
858
- * same-name row on ITS leg and compares the FOUR identity members (`judgeParkedToolIdentity`): any
859
- * mismatch is a replacement wearing the name and the resume refuses it
860
- * (`resume.tool_contract_mismatch`, the `tool_unavailable` reopen family). All four ABSENT ⇒ a row
861
- * minted before the members existed ⇒ the name-only path, never widened by their absence.
867
+ * `implementationRevision`. With the face below they are the TOOL member of the row's approval object
868
+ * (`judgeApprovalObject`): an identity member that differs from the same-name row on the resuming leg, or is missing
869
+ * while another is present, is a replacement wearing the name (`resume.tool_contract_mismatch`, a reopen); a face
870
+ * that differs vetoes the call (`resume.target_moved`). All four ABSENT ⇒ a pre-identity row: the name alone is bound.
862
871
  */
863
872
  capabilityId?: string;
864
873
  contractId?: string;
865
874
  shapeDigest?: string;
866
875
  implementationRevision?: string;
867
- rosterDigest?: string;
868
876
  /**
869
877
  * design/388 B6 × B18 (additive; the identity group's precedent): the FACE the parked call was judged under —
870
878
  * display `family` + declared `pathTarget` — off the same roster row at the same mint. The pre-CAS resume-edit
@@ -880,6 +888,9 @@ export type PendingAction = {
880
888
  * them, as the live gate judged the original, and the resume re-mints its face under the spelling while it still
881
889
  * resolves to the row's tool. Absent on a row minted before it ⇒ the row's `toolName` alone. */
882
890
  names?: readonly string[];
891
+ /** The approval object's TARGETS (`approvalTargetsOf`): per reading of the path slot, where it resolved when the card
892
+ * was asked; absent ⇒ not judged. A role resolving elsewhere at the execution vetoes the call (`resume.target_moved`). */
893
+ targets?: import("./approval-object.js").ApprovalTargets;
883
894
  /**
884
895
  * #438 (additive; no checkpoint-version bump — the `reminderMark` precedent: an optional field an
885
896
  * older reader ignores. Unlike that precedent seat — which resume DOES read, through its
@@ -1003,8 +1014,7 @@ export interface CheckpointState {
1003
1014
  * The WRITE-face containment state at suspend: the RESOLVED write face, written ONLY when it is
1004
1015
  * non-default ("open"). An absent section IS "roots" for every reader — which is why it carries NO
1005
1016
  * version stamp: losing it can only make a resume STRICTER. Resume folds STRICTER-WINS, the read seat's
1006
- * law: roots unless the section says open AND the live resolution says open. No deny half and no
1007
- * governance marker.
1017
+ * law: roots unless the section says open AND the live resolution says open. No deny half and no governance marker.
1008
1018
  */
1009
1019
  writeFace?: {
1010
1020
  face: "open" | "roots";
@@ -1326,8 +1336,8 @@ export interface CheckpointState {
1326
1336
  * **persisted OR live declaration** (a monotonic join, never a downgrade): a run minted under a
1327
1337
  * declaring adapter keeps its memory fold and its prompt disclosure when resumed on an
1328
1338
  * undeclared/older adapter — the downgrade is closed in the derivation itself, deliberately
1329
- * WITHOUT a new refusal arm (one fewer failure path, same safety). Feeds the memory face and the
1330
- * prompt disclosure only — no gate/policy/roster behavior reads it (the design/378 red line).
1339
+ * WITHOUT a new refusal arm (one fewer failure path, same safety). ONE declaration, two readers: the content-class fold (the memory
1340
+ * face, the prompt disclosure — the design/378 red line binds it: no gate/policy/roster reads it) and the tree's cross-boundary taint bit.
1331
1341
  * Schema ADDITION (additive, Q5 posture; the version-gate residual is shared with
1332
1342
  * {@link placementRootSessionId} above and owned by the same version-lattice ticket).
1333
1343
  */
@@ -1362,6 +1372,9 @@ export interface CheckpointState {
1362
1372
  readonly definition?: string;
1363
1373
  readonly lists: string;
1364
1374
  };
1375
+ /** The row's session holds a cross-boundary record (`CROSS_BOUNDARY_RECORD_TYPE`, written before the row is put): a reader must read
1376
+ * that record to resume the leg under its tree's state. Presence-coded; a capability mark only — the bits live in the session. */
1377
+ crossBoundaryRecorded?: true;
1365
1378
  }
1366
1379
  /**
1367
1380
  * {@link CheckpointState} with **every** field made required-PRESENT, while each value keeps its original
@@ -1370,8 +1383,7 @@ export interface CheckpointState {
1370
1383
  * correctness field to {@link CheckpointState} is then a **compile error** at the serialization site until
1371
1384
  * it is explicitly handled — it can never be silently omitted and lost on resume. (Keying off
1372
1385
  * `keyof Required<…>` makes the mapped type non-homomorphic, so it forces presence of every key yet leaves
1373
- * each value's `| undefined` intact — `workspaceHandle: undefined` for a process-local suspend still
1374
- * type-checks.)
1386
+ * each value's `| undefined` intact — `workspaceHandle: undefined` for a process-local suspend still type-checks.)
1375
1387
  */
1376
1388
  export type SerializedCheckpointState = {
1377
1389
  [K in keyof Required<CheckpointState>]: CheckpointState[K];
@@ -1603,6 +1615,10 @@ export interface ResolvedOutcome {
1603
1615
  * the same decision" for no delivery benefit, since a replay is produced by re-presenting the same
1604
1616
  * outcome, not by reconstructing an equivalent one. */
1605
1617
  reason?: string;
1618
+ /** The approving person's FEEDBACK, if the `allow` carried any — recorded exactly as supplied (a blank value included)
1619
+ * and bound by the replay equality on the same ADDITIVE rule as {@link reason}: absence means "never recorded". No
1620
+ * reader requirement word guards it: `resolvedOutcome` is a store-written state-machine member, never minted with the row. */
1621
+ feedback?: string;
1606
1622
  /** The settlement record core minted for this decide ({@link import("./gate-outcome.js").GateOutcome}):
1607
1623
  * the row's own copy of what the resolved call's `tool_end` frame carries, written with the winner so
1608
1624
  * an audit reading the row reads the same record the stream carried. NOT part of the replay equality
@@ -1930,8 +1946,7 @@ export interface CheckpointSummary {
1930
1946
  approvalCard?: import("./tool-face.js").ToolApprovalCard;
1931
1947
  /** design S1e: when the checkpoint was created ({@link Checkpoint.createdAt}, epoch ms) —
1932
1948
  * projected so a supervisor inbox can sort/age pending entries (oldest-first triage) in ONE `listByScope`
1933
- * call, no N+1 `getCheckpoint`. ECHO-ONLY display/triage; always present (a Checkpoint always has a
1934
- * `createdAt`). */
1949
+ * call, no N+1 `getCheckpoint`. ECHO-ONLY display/triage; always present (a Checkpoint always has a `createdAt`). */
1935
1950
  createdAt?: number;
1936
1951
  /**
1937
1952
  * design S1e: a **BOUNDED, UNREDACTED** raw preview of the pending tool call's input
@@ -2099,24 +2114,33 @@ export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "g
2099
2114
  | "installation_record_absent" | "installation_record_misaligned" | "installation_record_invalid"
2100
2115
  /** On `checkpoint.config_refused` with `detail.code` `config.tool_face_control` — the arm prepare's own refusal carries as its `detail.reason`:
2101
2116
  * a tool-name list the row recorded is not a list / has a member that is not a string / has a spelling no tool name can have / is not in
2102
- * the one spelling a row records (`"not_a_list"`, `"not_a_string"`, `"unknown_name"`, `"unsupported_pattern"`); the record of the delegation tool that
2117
+ * the one spelling a row records (`"not_a_list"`, `"not_a_string"`, `"unknown_name"`, `"unsupported_pattern"`; the re-supplied config's own four lists —
2118
+ * `allowTools`, `excludeTools`, `deferTools`, `alwaysLoadTools` — are refused as `"not_a_list"` / `"not_a_string"`); the record of the delegation tool that
2103
2119
  * wrote the leg's lists is not one (`"invalid_record"`); the roster the resume hands mounts a delegation tool under another name than it declares
2104
2120
  * (`"renamed_mount"`); the process-wide table of declared names is occupied by a value that is not the engine's (`"registry_occupied"`). */
2105
- | "not_a_list" | "not_a_string" | "unknown_name" | "unsupported_pattern" | "invalid_record" | "renamed_mount" | "registry_occupied";
2121
+ | "not_a_list" | "not_a_string" | "unknown_name" | "unsupported_pattern" | "invalid_record" | "renamed_mount" | "registry_occupied"
2122
+ /** On `checkpoint.config_refused` with `detail.code` `config.unknown_role` — a role seat or a tier binding the deployment wrote that the engine cannot read:
2123
+ * a word the model catalog does not hold (`"unknown_model_ref"`), or a value that is no model reference at all — a number, a boolean, a list
2124
+ * (`"not_a_model_ref"`). The sentence names the seat (`roles.consolidate`, `tiers.pro`). */
2125
+ | "unknown_model_ref" | "not_a_model_ref";
2106
2126
  /**
2107
- * The codes a RESUME's pre-claim configuration screen carries as `detail.code` of a `checkpoint.config_refused` — the nine
2108
- * words prepare's mode, output-style, approval-reach, invoked-skill, attachment, recorded-mode and tool-face doors throw, held unchanged so one refusal
2109
- * reads the same on a fresh run (`TaskResult.errorCode`) and on a resume. `config.spec_retired_key`: a retired spec key;
2110
- * `config.output_style_invalid`: a malformed output-style seat; `config.permission_mode_invalid`: a mode word outside the closed
2111
- * set (the config's `permissionMode`, or one the row recorded); `config.shell_gate_value_retired`: a retired shell-floor word;
2112
- * `config.approval_reach_invalid`: an `approvalReach` outside its set; `config.user_invoked_skill_unknown` / `skill_deny_unreadable`:
2113
- * `userInvokedSkills` names a skill the config does not carry / one whose `disallowed-tools` entry the grammar reads as nothing;
2114
- * `config.user_attachment_invalid`: the config declares `userAttachments` (a resume sends no new human message) or a malformed
2115
- * value there; `config.tool_face_control`: the tool names the row recorded (its ceiling, its frozen policy chain, the record of who wrote
2116
- * its lists) are not readable as written, or the roster the resume hands mounts a delegation tool under another name than it declares
2117
- * (`detail.reason` names which: {@link CheckpointErrorReason}).
2127
+ * The codes a RESUME's pre-claim configuration screen carries as `detail.code` of a `checkpoint.config_refused` — the words prepare's
2128
+ * doors throw, held unchanged so one refusal reads the same on a fresh run (`TaskResult.errorCode`) and on a resume: the mode, output-style,
2129
+ * approval-reach, invoked-skill, attachment, recorded-mode and tool-face doors (`config.spec_retired_key` … `config.tool_face_control`, the first
2130
+ * nine — `detail.reason` names the tool-face arm: {@link CheckpointErrorReason}), and every value door of the config-door phase over the
2131
+ * re-supplied config and the deployment's deps (`configValueDoors`, the rest): the retired deps seats and caller-policy members
2132
+ * (`config.deps_retired_key`), the peer presence, the restore selector, the microCompact knob, the prompt selectors, `resumeAt` on a resume
2133
+ * (`resume_at.conflicts_resume`, `resume_at.mode_without_target` — a resume carrying `resumeAt` is refused as a conflict before its mode is
2134
+ * read, so `resume_at.invalid_mode` is a fresh run's word only), the containment faces, the add-only seats and the MCP / A2A `toolAxes` (`config.invalid_argument`), an MCP server's `toolFaces` (`config.tool_face_invalid`), the three memory seats,
2135
+ * the auto-consolidation arming (its role key too, and the role seats and tier bindings it reads: `config.unknown_role`, `detail.reason` naming the arm), the materialize strategy and persistence flag, the lock layer (`config.locked_registry`,
2136
+ * `config.locked_key`), an MCP server's content class, the skills-listing seats (`config.skill_listing_budget_invalid`), the limits and the
2137
+ * resource-suspend knobs, the attachment modes, the governance windows, the brain-call guardrail and the retention declaration over the stores the leg
2138
+ * would run on (`config.retention_policy`, `config.retention_capability`), and the checkpoint store seat itself (`config.invalid_checkpoint_store`: the
2139
+ * retired `null` spelling, a store that declares no execution outcome), and the skills seat and the hands band (`config.invalid_argument`;
2140
+ * a skill's `baseDir` by its own reader, `config.skill_base_dir_invalid`). A door not entered here (the leg's model, its rebuilt
2141
+ * roster, its answer face, the approval seat's value) still refuses after the claim, each for a stated reason (INTEGRATION-CORE, "A resume's two doors").
2118
2142
  */
2119
- export declare const CHECKPOINT_CONFIG_REFUSAL_CODES: readonly ["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control"];
2143
+ export declare const CHECKPOINT_CONFIG_REFUSAL_CODES: readonly ["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid"];
2120
2144
  export type CheckpointConfigRefusalCode = (typeof CHECKPOINT_CONFIG_REFUSAL_CODES)[number];
2121
2145
  export declare const isCheckpointConfigRefusalCode: (word: unknown) => word is CheckpointConfigRefusalCode;
2122
2146
  /** A typed checkpoint-store error so callers branch on `code` (mirrors `SessionError`). */
@@ -2295,13 +2319,13 @@ export declare class CheckpointError extends Error {
2295
2319
  * resolve, or try to supply the minted record), or — design/252 G-7 — `"approver"` (the attribution is not a
2296
2320
  * well-formed identifier: re-decide with a plain, bounded, control-character-free string, or omit
2297
2321
  * it). On a `checkpoint.config_refused` `field` names which INPUT carries the refusal — `"taskConfig"`
2298
- * (the re-supplied config: correct it and resume the same token) or `"inheritedGate"` (the mode the row
2299
- * recorded: no config reaches it; expire the row). The throw
2322
+ * (the re-supplied config: correct it and resume the same token), `"deps"` (the deployment's own seat — and the policies the
2323
+ * caller re-supplies as inherited constraints: correct them and resume the same token) or `"inheritedGate"` (the row's record: no config reaches it; expire the row). The throw
2300
2324
  * sites always knew which arm fired; this carries that fact instead of dropping it (ruled
2301
2325
  * 2026-08-03, cross-repo HITL discussion). Additive and optional — `code` remains the only REQUIRED
2302
2326
  * discriminant. */
2303
2327
  readonly detail?: {
2304
- field?: "boundCallId" | "boundInputHash" | "boundGrantDigest" | "answer" | "hostDecision" | "approver" | "taskConfig" | "inheritedGate";
2328
+ field?: "boundCallId" | "boundInputHash" | "boundGrantDigest" | "answer" | "hostDecision" | "approver" | "taskConfig" | "deps" | "inheritedGate";
2305
2329
  /** On `checkpoint.config_refused` — prepare's own code for the refusal ({@link CheckpointConfigRefusalCode}), the
2306
2330
  * word a fresh run of the same bad config reports as its `errorCode`. Absent on every other code. */
2307
2331
  code?: CheckpointConfigRefusalCode;
@@ -2498,13 +2522,13 @@ export declare class CheckpointError extends Error {
2498
2522
  * resolve, or try to supply the minted record), or — design/252 G-7 — `"approver"` (the attribution is not a
2499
2523
  * well-formed identifier: re-decide with a plain, bounded, control-character-free string, or omit
2500
2524
  * it). On a `checkpoint.config_refused` `field` names which INPUT carries the refusal — `"taskConfig"`
2501
- * (the re-supplied config: correct it and resume the same token) or `"inheritedGate"` (the mode the row
2502
- * recorded: no config reaches it; expire the row). The throw
2525
+ * (the re-supplied config: correct it and resume the same token), `"deps"` (the deployment's own seat — and the policies the
2526
+ * caller re-supplies as inherited constraints: correct them and resume the same token) or `"inheritedGate"` (the row's record: no config reaches it; expire the row). The throw
2503
2527
  * sites always knew which arm fired; this carries that fact instead of dropping it (ruled
2504
2528
  * 2026-08-03, cross-repo HITL discussion). Additive and optional — `code` remains the only REQUIRED
2505
2529
  * discriminant. */
2506
2530
  detail?: {
2507
- field?: "boundCallId" | "boundInputHash" | "boundGrantDigest" | "answer" | "hostDecision" | "approver" | "taskConfig" | "inheritedGate";
2531
+ field?: "boundCallId" | "boundInputHash" | "boundGrantDigest" | "answer" | "hostDecision" | "approver" | "taskConfig" | "deps" | "inheritedGate";
2508
2532
  /** On `checkpoint.config_refused` — prepare's own code for the refusal ({@link CheckpointConfigRefusalCode}), the
2509
2533
  * word a fresh run of the same bad config reports as its `errorCode`. Absent on every other code. */
2510
2534
  code?: CheckpointConfigRefusalCode;
@@ -2937,7 +2961,7 @@ export interface CheckpointStore {
2937
2961
  * status === 'pending'`), so the list reflects exactly the rows that are still resumable. Order is unspecified
2938
2962
  * (the inbox sorts by `severity`/`deadline` itself). An empty scope returns `[]`.
2939
2963
  *
2940
- * **OPTIONAL** for backward-compat with external {@link CheckpointStore} impls (a caller probes
2964
+ * **OPTIONAL** for backward-compat (RL-1336-checkpoint-listbyscope) with external {@link CheckpointStore} impls (a caller probes
2941
2965
  * `store.listByScope?.(scope) ?? []`); ALL THREE first-party impls (in-memory, file, Pg) provide it.
2942
2966
  */
2943
2967
  listByScope?(scope: string): Promise<CheckpointSummary[]>;
@@ -6,10 +6,10 @@ import { isAutoModeFallbackCause, readDenialLimitFallback } from "./auto-mode.js
6
6
  import { isAskOrigin, isPersistedRuleMandate } from "./ask-origin.js";
7
7
  import { readBoundBinding } from "./skill-grant-binding.js";
8
8
  import { checkpointExecutionRecorded, executionRecordDisposition, ExecutionOutcomeConflictError, } from "./checkpoint-execution-record.js";
9
+ import { parkedApprovalCardOf } from "./pause-registry.js";
9
10
  import { renderUntrustedCommandText, stripFormatCharacters } from "./permission-rule-model.js";
10
11
  import { egressText } from "./untrusted-egress.js";
11
12
  import { steerReplayRefusal } from "./steer-replay.js";
12
- import { isToolApprovalCard } from "./tool-face.js";
13
13
  import { isPermissionMode } from "./ask-origin.js";
14
14
  export function mintCheckpointToken() {
15
15
  return randomBytes(16).toString("hex");
@@ -251,7 +251,7 @@ export { REOPEN_REASONS } from "./resume-startup-cause.js";
251
251
  export function summarizeCheckpoint(cp) {
252
252
  const riskDescriptor = cp.gate.kind === "human" || cp.gate.kind === "irreversible_ask" ? cp.gate.riskDescriptor : undefined;
253
253
  const severity = riskDescriptor !== undefined ? riskSeverity(riskDescriptor.axes) : undefined;
254
- const gateCard = cp.gate.kind === "human" || cp.gate.kind === "irreversible_ask" ? cp.gate.approvalCard : undefined;
254
+ const cardReading = parkedApprovalCardOf(cp.gate);
255
255
  const tool = cp.pendingAction.kind === "tool_approval" ? cp.pendingAction : undefined;
256
256
  let toolInput;
257
257
  if (tool !== undefined) {
@@ -281,7 +281,7 @@ export function summarizeCheckpoint(cp) {
281
281
  ...(cp.sourceTaskId !== undefined ? { sourceTaskId: cp.sourceTaskId } : {}),
282
282
  ...(cp.principal !== undefined ? { principal: cp.principal } : {}),
283
283
  ...(tool !== undefined ? { toolCallId: tool.toolCallId, toolName: tool.toolName } : {}),
284
- ...(isToolApprovalCard(gateCard) ? { approvalCard: gateCard } : {}),
284
+ ...(cardReading.kind === "card" ? { approvalCard: cardReading.card } : {}),
285
285
  ...(toolInput !== undefined ? { toolInput } : {}),
286
286
  ...(cp.state.workspaceHandle !== undefined
287
287
  ? { restoreMode: cp.state.workspaceHandle.restoreMode === "park_only" ? "park_only" : "snapshot" }
@@ -305,7 +305,7 @@ export function summarizeCheckpoint(cp) {
305
305
  ...(hasBidi ? { hasBidiControls: true } : {}),
306
306
  };
307
307
  }
308
- export const CHECKPOINT_CONFIG_REFUSAL_CODES = Object.freeze(["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control"]);
308
+ export const CHECKPOINT_CONFIG_REFUSAL_CODES = Object.freeze(["config.spec_retired_key", "config.output_style_invalid", "config.permission_mode_invalid", "config.shell_gate_value_retired", "config.approval_reach_invalid", "config.user_invoked_skill_unknown", "config.skill_deny_unreadable", "config.user_attachment_invalid", "config.tool_face_control", "config.deps_retired_key", "config.peer_presence_invalid", "config.tool_model_gate_invalid", "config.microcompact_invalid", "config.prompt_selector_invalid", "resume_at.conflicts_resume", "resume_at.mode_without_target", "config.read_face_invalid", "config.write_face_invalid", "config.invalid_argument", "config.tool_face_invalid", "config.memory_delegation_evidence", "config.memory_provenance", "config.memory_capture_policy", "config.cross_boundary_posture", "config.auto_consolidation", "config.unknown_role", "config.tool_materialize_invalid", "config.memory_persistence_invalid", "config.tool_materialize_unreachable", "config.locked_registry", "config.locked_key", "config.mcp_content_class", "config.skill_listing_budget_invalid", "config.limit_unknown_key", "config.limit_invalid", "config.attachment_invalid", "config.usage_window_invalid", "config.brain_call_guardrail_invalid", "config.retention_policy", "config.retention_capability", "config.invalid_checkpoint_store", "config.skill_base_dir_invalid"]);
309
309
  export const isCheckpointConfigRefusalCode = (word) => CHECKPOINT_CONFIG_REFUSAL_CODES.some((w) => w === word);
310
310
  export class CheckpointError extends Error {
311
311
  code;
@@ -399,13 +399,13 @@ export function resolveCheckpointStore(spec, deps) {
399
399
  throw checkpointStoreExecutionUndeclared("TaskSpec.checkpointStore", spec.checkpointStore);
400
400
  return spec.checkpointStore;
401
401
  }
402
- if (deps.checkpointStore !== undefined && deps.checkpointStore.execution?.outcome !== true) {
402
+ if (deps.checkpointStore !== undefined && deps.checkpointStore?.execution?.outcome !== true) {
403
403
  throw checkpointStoreExecutionUndeclared("RunnerDeps.checkpointStore", deps.checkpointStore);
404
404
  }
405
405
  return deps.checkpointStore;
406
406
  }
407
407
  export function checkpointStoreExecutionUndeclared(seat, store) {
408
- const ctor = store.constructor?.name;
408
+ const ctor = store?.constructor?.name;
409
409
  const name = typeof ctor === "string" && ctor.length > 0 && ctor !== "Object" ? ` (${ctor})` : "";
410
410
  const e = new Error(`${seat}: the wired CheckpointStore${name} does not declare \`execution = { outcome: true }\` — the execution-outcome ` +
411
411
  "record (recordExecutionOutcome, and reopen refusing a recorded row) is a required member of the store contract; " +
@@ -441,6 +441,7 @@ export function winnerFromOutcome(outcome) {
441
441
  ...(outcome.answer === undefined ? {} : { answer: outcome.answer }),
442
442
  ...(outcome.gateOutcome === undefined ? {} : { gateOutcome: outcome.gateOutcome }),
443
443
  ...(outcome.reason === undefined ? {} : { reason: outcome.reason }),
444
+ ...(outcome.feedback === undefined ? {} : { feedback: outcome.feedback }),
444
445
  };
445
446
  }
446
447
  const CHECKPOINT_CONTROL_CHARS_RE = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;