@sema-agent/core 7.47.0 → 7.49.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 (431) hide show
  1. package/CHANGELOG.md +472 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +39 -32
  51. package/dist/core/arg-summary.d.ts +17 -24
  52. package/dist/core/arg-summary.js +169 -68
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +95 -66
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +32 -7
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +4 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp-server-spec.d.ts +1 -1
  101. package/dist/core/mcp.d.ts +4 -0
  102. package/dist/core/mcp.js +70 -43
  103. package/dist/core/memory-engine/content-origin.js +2 -14
  104. package/dist/core/memory-engine/engine.d.ts +32 -22
  105. package/dist/core/memory-engine/engine.js +103 -55
  106. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  107. package/dist/core/memory-engine/file-backend.js +37 -252
  108. package/dist/core/memory-engine/index.d.ts +1 -1
  109. package/dist/core/memory-engine/index.js +1 -1
  110. package/dist/core/memory-engine/layout.d.ts +139 -9
  111. package/dist/core/memory-engine/layout.js +350 -7
  112. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  113. package/dist/core/memory-engine/scope-contract.js +8 -0
  114. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  115. package/dist/core/memory-engine/session-incarnation.js +5 -2
  116. package/dist/core/memory-engine/types.d.ts +10 -1
  117. package/dist/core/memory.js +5 -17
  118. package/dist/core/model-seat.d.ts +4 -4
  119. package/dist/core/model-seat.js +1 -1
  120. package/dist/core/mounted-mcp.d.ts +57 -0
  121. package/dist/core/mounted-mcp.js +19 -0
  122. package/dist/core/namespaced-rule-name.d.ts +29 -0
  123. package/dist/core/namespaced-rule-name.js +52 -0
  124. package/dist/core/park-selfcheck.d.ts +1 -1
  125. package/dist/core/park-selfcheck.js +16 -6
  126. package/dist/core/path-guard-rows.d.ts +99 -0
  127. package/dist/core/path-guard-rows.js +45 -0
  128. package/dist/core/path-identity.d.ts +22 -16
  129. package/dist/core/path-identity.js +10 -10
  130. package/dist/core/path-rule-binding.d.ts +2 -1
  131. package/dist/core/path-rule-binding.js +3 -1
  132. package/dist/core/pause-registry.d.ts +16 -2
  133. package/dist/core/pause-registry.js +6 -0
  134. package/dist/core/permission-rule-consent.js +0 -7
  135. package/dist/core/permission-rule-model.d.ts +68 -24
  136. package/dist/core/permission-rule-model.js +105 -24
  137. package/dist/core/permission-rule-store.js +2 -2
  138. package/dist/core/permission-rules.d.ts +3 -30
  139. package/dist/core/permission-rules.js +4 -54
  140. package/dist/core/read-root-candidate.d.ts +1 -3
  141. package/dist/core/read-root-candidate.js +4 -15
  142. package/dist/core/real-approval.d.ts +4 -3
  143. package/dist/core/retired-keys.d.ts +13 -0
  144. package/dist/core/retired-keys.js +14 -0
  145. package/dist/core/roles.d.ts +2 -3
  146. package/dist/core/roles.js +15 -6
  147. package/dist/core/runner/assemble-result.d.ts +0 -7
  148. package/dist/core/runner/assemble-result.js +19 -31
  149. package/dist/core/runner/caller-roster.d.ts +78 -0
  150. package/dist/core/runner/caller-roster.js +219 -0
  151. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  152. package/dist/core/runner/checkpoint-scope.js +2 -2
  153. package/dist/core/runner/child-tree.js +2 -2
  154. package/dist/core/runner/contracts.d.ts +68 -35
  155. package/dist/core/runner/decide-continuation.d.ts +51 -3
  156. package/dist/core/runner/decide-continuation.js +76 -21
  157. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  158. package/dist/core/runner/denial-limit-arms.js +11 -9
  159. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  160. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  161. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  162. package/dist/core/runner/finish-reason-seat.js +40 -0
  163. package/dist/core/runner/gate-exit.d.ts +44 -32
  164. package/dist/core/runner/gate-exit.js +112 -25
  165. package/dist/core/runner/inherited-ask-grants.js +6 -4
  166. package/dist/core/runner/mcp-redial.d.ts +3 -3
  167. package/dist/core/runner/mcp-redial.js +3 -4
  168. package/dist/core/runner/park-commit.d.ts +1 -1
  169. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  170. package/dist/core/runner/permission-rule-lanes.js +5 -4
  171. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  172. package/dist/core/runner/prepare-artifact.js +2 -1
  173. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  174. package/dist/core/runner/prepare-ask-lane.js +12 -6
  175. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  176. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  177. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  178. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  179. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  180. package/dist/core/runner/prepare-config-doors.js +10 -5
  181. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  182. package/dist/core/runner/prepare-defer-classify.js +5 -3
  183. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  184. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  185. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  186. package/dist/core/runner/prepare-gate-stations.js +9 -7
  187. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  188. package/dist/core/runner/prepare-hands-readface.js +7 -7
  189. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  190. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  191. package/dist/core/runner/prepare-listings.d.ts +7 -24
  192. package/dist/core/runner/prepare-listings.js +4 -5
  193. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  194. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  195. package/dist/core/runner/prepare-memory.d.ts +6 -0
  196. package/dist/core/runner/prepare-memory.js +13 -13
  197. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  198. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  199. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  200. package/dist/core/runner/prepare-park-ask.js +17 -10
  201. package/dist/core/runner/prepare-policy-chain.js +24 -44
  202. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  203. package/dist/core/runner/prepare-project-context.js +3 -4
  204. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  205. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  206. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  207. package/dist/core/runner/prepare-run-refs.js +2 -1
  208. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  209. package/dist/core/runner/prepare-safety-scan.js +1 -2
  210. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  211. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  212. package/dist/core/runner/prepare-task.d.ts +1 -1
  213. package/dist/core/runner/prepare-task.js +67 -56
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  215. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  216. package/dist/core/runner/resume-apply.js +7 -14
  217. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  218. package/dist/core/runner/resume-internals-and-config.js +2 -2
  219. package/dist/core/runner/resume-policy-outcome.js +5 -32
  220. package/dist/core/runner/resume-review-outcome.js +4 -1
  221. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  222. package/dist/core/runner/retired-runner-deps.js +10 -1
  223. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  224. package/dist/core/runner/run-brain-sinks.js +5 -2
  225. package/dist/core/runner/run-harness-handlers.js +27 -34
  226. package/dist/core/runner/run-leg.d.ts +0 -2
  227. package/dist/core/runner/run-leg.js +32 -33
  228. package/dist/core/runner/run-terminal-adoption.js +4 -3
  229. package/dist/core/runner/runtask.js +8 -8
  230. package/dist/core/runner/session-rule-policy.js +5 -5
  231. package/dist/core/runner/stream-settle-backstop.js +7 -4
  232. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  233. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  234. package/dist/core/runner/terminal-account.d.ts +48 -0
  235. package/dist/core/runner/terminal-account.js +186 -0
  236. package/dist/core/runner/tool-end-body.d.ts +54 -17
  237. package/dist/core/runner/tool-end-body.js +27 -2
  238. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  239. package/dist/core/runner/tool-face-overlay.js +6 -4
  240. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  241. package/dist/core/runner/tool-occurrence.js +123 -0
  242. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  243. package/dist/core/runner/tool-progress-lane.js +25 -34
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/safety-axis-vocab.d.ts +1 -1
  249. package/dist/core/safety-merge-corpus.d.ts +1 -1
  250. package/dist/core/secret-env.d.ts +16 -5
  251. package/dist/core/secret-env.js +23 -63
  252. package/dist/core/sensitive-path-policy.d.ts +19 -18
  253. package/dist/core/sensitive-path-policy.js +73 -49
  254. package/dist/core/session-policy-store.d.ts +6 -3
  255. package/dist/core/session-policy-store.js +28 -10
  256. package/dist/core/session-reconcile.d.ts +3 -0
  257. package/dist/core/session-reconcile.js +5 -4
  258. package/dist/core/session-store.d.ts +5 -0
  259. package/dist/core/session-store.js +12 -0
  260. package/dist/core/session.d.ts +13 -0
  261. package/dist/core/shared-memory/normalize.d.ts +17 -4
  262. package/dist/core/shared-memory/normalize.js +7 -7
  263. package/dist/core/shell-lexer.js +5 -4
  264. package/dist/core/shell-wrapper-table.d.ts +2 -2
  265. package/dist/core/shell-wrapper-table.js +1 -1
  266. package/dist/core/skill-grant.js +1 -1
  267. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  268. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  269. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  270. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  271. package/dist/core/stub-env.d.ts +2 -0
  272. package/dist/core/stub-env.js +1 -0
  273. package/dist/core/synthetic-read-verdict.js +2 -2
  274. package/dist/core/task-event.d.ts +59 -5
  275. package/dist/core/task-result.d.ts +1 -1
  276. package/dist/core/task-spec.d.ts +42 -9
  277. package/dist/core/terminal-cause.d.ts +94 -11
  278. package/dist/core/tighten-task-spec.d.ts +5 -4
  279. package/dist/core/tighten-task-spec.js +20 -25
  280. package/dist/core/tool-catalog-entries.d.ts +5 -7
  281. package/dist/core/tool-catalog-entries.js +14 -15
  282. package/dist/core/tool-face.d.ts +47 -0
  283. package/dist/core/tool-face.js +5 -0
  284. package/dist/core/tool-model-gate.d.ts +5 -5
  285. package/dist/core/tool-name-aliases.d.ts +35 -10
  286. package/dist/core/tool-name-aliases.js +15 -0
  287. package/dist/core/tool-name-list.d.ts +30 -0
  288. package/dist/core/tool-name-list.js +55 -0
  289. package/dist/core/tool-name-readings.d.ts +1 -9
  290. package/dist/core/tool-name-readings.js +1 -3
  291. package/dist/core/tool-policy.d.ts +195 -85
  292. package/dist/core/tool-policy.js +165 -381
  293. package/dist/core/tool-registry.d.ts +44 -1
  294. package/dist/core/tool-registry.js +26 -0
  295. package/dist/core/tool-roster.d.ts +19 -1
  296. package/dist/core/tool-roster.js +21 -2
  297. package/dist/core/tool-spec-members.d.ts +45 -0
  298. package/dist/core/tool-spec-members.js +169 -0
  299. package/dist/core/tool-spec.d.ts +46 -8
  300. package/dist/core/tools.d.ts +6 -2
  301. package/dist/core/tools.js +8 -4
  302. package/dist/core/untrusted-egress.js +29 -26
  303. package/dist/core/untrusted-text.d.ts +13 -10
  304. package/dist/core/untrusted-text.js +6 -44
  305. package/dist/core/workflow-journal-store.d.ts +4 -1
  306. package/dist/core/write-protect.d.ts +65 -29
  307. package/dist/core/write-protect.js +235 -177
  308. package/dist/engine/compaction/compaction.d.ts +2 -2
  309. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  310. package/dist/engine/execution-env/node-execution-env.js +16 -38
  311. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  312. package/dist/engine/execution-env/symlink-chain.js +32 -0
  313. package/dist/engine/harness/types.d.ts +7 -0
  314. package/dist/engine/llm/tool-turns.d.ts +3 -0
  315. package/dist/engine/llm/tool-turns.js +1 -0
  316. package/dist/engine/llm/types.d.ts +59 -23
  317. package/dist/engine/loop/agent-loop.js +16 -2
  318. package/dist/engine/session/memory-repo.js +11 -3
  319. package/dist/engine/session/repo-utils.d.ts +8 -0
  320. package/dist/engine/session/repo-utils.js +13 -0
  321. package/dist/index.d.ts +20 -23
  322. package/dist/index.js +17 -20
  323. package/dist/internal/harness.d.ts +1 -1
  324. package/dist/internal/harness.js +1 -1
  325. package/dist/internal/llm.d.ts +2 -2
  326. package/dist/internal/llm.js +1 -1
  327. package/dist/orchestration/governance-baseline-validity.js +1 -1
  328. package/dist/orchestration/run-spec.js +3 -3
  329. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  330. package/dist/orchestration/run-workflow-tool.js +38 -78
  331. package/dist/orchestration/workflow-governance.d.ts +21 -25
  332. package/dist/orchestration/workflow-governance.js +38 -78
  333. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  334. package/dist/orchestration/workflow-primitives.js +5 -12
  335. package/dist/orchestration/workflow-types.d.ts +1 -1
  336. package/dist/orchestration/workflow.d.ts +61 -11
  337. package/dist/orchestration/workflow.js +191 -119
  338. package/dist/prompt-assembly/types.d.ts +1 -1
  339. package/dist/scenarios/full-body.d.ts +1 -1
  340. package/dist/shell/lex.d.ts +0 -21
  341. package/dist/shell/lex.js +278 -70
  342. package/dist/shell/shell-words.d.ts +35 -0
  343. package/dist/shell/shell-words.js +65 -0
  344. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  345. package/dist/stores/file/checkpoint-store.js +5 -2
  346. package/dist/stores/file/index.d.ts +0 -8
  347. package/dist/stores/file/index.js +0 -12
  348. package/dist/stores/file/session-store.d.ts +3 -0
  349. package/dist/stores/file/session-store.js +44 -19
  350. package/dist/tools/artifact/artifact-tool.js +2 -0
  351. package/dist/tools/fs/bash-program-position.d.ts +17 -3
  352. package/dist/tools/fs/bash-program-position.js +25 -10
  353. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  354. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  355. package/dist/tools/fs/containment-face.d.ts +4 -0
  356. package/dist/tools/fs/containment-face.js +3 -0
  357. package/dist/tools/fs/fs-shared.d.ts +10 -0
  358. package/dist/tools/fs/fs-shared.js +18 -0
  359. package/dist/tools/fs/fs-write.js +4 -2
  360. package/dist/tools/fs/index.d.ts +3 -2
  361. package/dist/tools/fs/index.js +2 -2
  362. package/dist/tools/fs/program-read-model.d.ts +99 -23
  363. package/dist/tools/fs/program-read-model.js +129 -55
  364. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  365. package/dist/tools/fs/program-read-model.rows.js +18 -10
  366. package/dist/tools/fs/read-deny-home.d.ts +35 -30
  367. package/dist/tools/fs/read-deny-home.js +45 -38
  368. package/dist/tools/fs/read-deny.d.ts +35 -27
  369. package/dist/tools/fs/read-deny.js +126 -92
  370. package/dist/tools/fs/removal-targets.d.ts +56 -23
  371. package/dist/tools/fs/removal-targets.js +74 -87
  372. package/dist/tools/fs/safety.d.ts +29 -22
  373. package/dist/tools/fs/safety.js +17 -11
  374. package/dist/tools/fs/search.js +10 -8
  375. package/dist/tools/fs/shell-read-argv.d.ts +4 -7
  376. package/dist/tools/fs/shell-read-argv.js +6 -8
  377. package/dist/tools/fs/shell-read-bindings.d.ts +203 -46
  378. package/dist/tools/fs/shell-read-bindings.js +488 -144
  379. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  380. package/dist/tools/fs/shell-read-builtins.js +43 -0
  381. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  382. package/dist/tools/fs/shell-read-check.js +51 -42
  383. package/dist/tools/fs/shell-read-establish.js +9 -10
  384. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  385. package/dist/tools/fs/shell-read-functions.js +29 -0
  386. package/dist/tools/fs/shell-read-judge.d.ts +48 -18
  387. package/dist/tools/fs/shell-read-judge.js +33 -4
  388. package/dist/tools/fs/shell-read-plan.d.ts +13 -20
  389. package/dist/tools/fs/shell-read-plan.js +200 -194
  390. package/dist/tools/fs/shell-read-start.d.ts +80 -0
  391. package/dist/tools/fs/shell-read-start.js +99 -0
  392. package/dist/tools/fs/shell-read-word.d.ts +35 -6
  393. package/dist/tools/fs/shell-read-word.js +89 -9
  394. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  395. package/dist/tools/fs/shell-read-workdir.js +281 -0
  396. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  397. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  398. package/dist/tools/fs/shell-reentry-text.d.ts +26 -26
  399. package/dist/tools/fs/shell-reentry-text.js +31 -34
  400. package/dist/tools/task-list.d.ts +1 -2
  401. package/dist/tools/web.js +1 -1
  402. package/package.json +4 -1
  403. package/test/export-surface.snapshot.json +107 -143
  404. package/wire-changes/core@7.48.0.json +252 -0
  405. package/wire-changes/core@7.49.0.json +4765 -0
  406. package/dist/agents/teacher.d.ts +0 -159
  407. package/dist/agents/teacher.js +0 -577
  408. package/dist/agents/team.d.ts +0 -226
  409. package/dist/agents/team.js +0 -257
  410. package/dist/core/strategy-store.d.ts +0 -238
  411. package/dist/core/strategy-store.js +0 -253
  412. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  413. package/dist/orchestration/builtin-workflows.js +0 -159
  414. package/dist/scenarios/env.d.ts +0 -40
  415. package/dist/scenarios/env.js +0 -39
  416. package/dist/scenarios/scenario-registry.d.ts +0 -110
  417. package/dist/scenarios/scenario-registry.js +0 -140
  418. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  419. package/dist/scenarios/teacher-quickstart.js +0 -12
  420. package/dist/stores/cc/lockfile.d.ts +0 -10
  421. package/dist/stores/cc/lockfile.js +0 -98
  422. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  423. package/dist/stores/cc/mailbox-store.js +0 -255
  424. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  425. package/dist/stores/cc/roster-adapter.js +0 -117
  426. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  427. package/dist/stores/cc/sidecar-transcript.js +0 -264
  428. package/dist/stores/cc/task-list-store.d.ts +0 -2
  429. package/dist/stores/cc/task-list-store.js +0 -125
  430. package/dist/stores/file/strategy-store.d.ts +0 -97
  431. package/dist/stores/file/strategy-store.js +0 -341
@@ -1,9 +1,14 @@
1
- import { ASK_USER_QUESTION_TOOL_NAME, isLiveQuestionFace, markBoundOnlyQuestionFace } from "../ask-question.js";
1
+ import { isAskOrigin } from "../ask-origin.js";
2
+ import { isLiveQuestionFace, markBoundOnlyQuestionFace } from "../ask-question.js";
2
3
  import { boundInputHashOf } from "../canonical-json.js";
3
4
  import { CheckpointError } from "../checkpoint-store.js";
5
+ import { decidersNote, isHostDecider, settlementOfHostDecision } from "../gate-outcome.js";
4
6
  import { formatHookFeedback } from "../hooks.js";
7
+ import { facetOf, isGateKind, isQuestionGate } from "../pause-registry.js";
8
+ import { humanRefusalSentence, policyCannotAnswer, screenApproverAttribution } from "../tool-policy.js";
9
+ import { mintGateOutcome } from "./gate-exit.js";
5
10
  import { delimitUntrusted, REVIEWER_NOTE_MAX_BODY } from "../untrusted-text.js";
6
- import { wireOf } from "../tool-name-readings.js";
11
+ import { engineCardOf } from "../tool-roster.js";
7
12
  export function resumeDecisionWasNegative(resume) {
8
13
  const o = resume.outcome;
9
14
  return o.decision === "reject" || o.decision === "deny";
@@ -50,9 +55,7 @@ export function sameWinner(incoming, persisted) {
50
55
  (persisted.reason === undefined || incoming.reason === persisted.reason));
51
56
  }
52
57
  export function pendingContentAskCallId(cp) {
53
- return cp.pendingAction.kind === "tool_approval" && wireOf("resume.contentAskRow", cp.pendingAction) === ASK_USER_QUESTION_TOOL_NAME
54
- ? cp.pendingAction.toolCallId
55
- : undefined;
58
+ return cp.pendingAction.kind === "tool_approval" && engineCardOf(cp.pendingAction) === "question" ? cp.pendingAction.toolCallId : undefined;
56
59
  }
57
60
  export function answerFaceForRedeemedCall(answer, redeemedCallId, base, redeemedQuestionsHash) {
58
61
  let consumed = false;
@@ -70,6 +73,54 @@ export function answerFaceForRedeemedCall(answer, redeemedCallId, base, redeemed
70
73
  export function describeSuppliedValue(value) {
71
74
  return typeof value === "string" ? value : value === null ? "null" : typeof value;
72
75
  }
76
+ export const SUPPLIED_RECORD_KEY = ["gateOutcome", "the settlement record is minted by core from the host's decision facts and the row's origin, never supplied"];
77
+ export function refuseSuppliedKeys(decide, keys) {
78
+ for (const [key, why] of keys) {
79
+ if (Reflect.get(decide, key) !== undefined) {
80
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume carries \`${key}\` — ${why}; refusing pre-CAS, the checkpoint stays pending`, { field: "hostDecision" });
81
+ }
82
+ }
83
+ }
84
+ export function captureHostDecision(cp, raw, lane, verdict) {
85
+ if (typeof raw !== "object" || raw === null) {
86
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume carries no hostDecision — a ${lane} decide names who decided it ({ decidedBy: "person" | "sla_timeout" | "policy", approver? }); refusing pre-CAS, the checkpoint stays pending`, { field: "hostDecision" });
87
+ }
88
+ const decidedBy = raw.decidedBy;
89
+ if (!isHostDecider(decidedBy)) {
90
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume hostDecision.decidedBy "${describeSuppliedValue(decidedBy)}" is outside the closed set — it is exactly "person", "sla_timeout" or "policy"; refusing pre-CAS, the checkpoint stays pending`, { field: "hostDecision" });
91
+ }
92
+ const gateIsQuestion = isGateKind(cp.gate.kind) && isQuestionGate(cp.gate);
93
+ if (decidedBy === "sla_timeout" && !(isGateKind(cp.gate.kind) && facetOf(cp.gate) === "A")) {
94
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume hostDecision.decidedBy "sla_timeout" names the host's SLA sweep, which resolves approval rows only — this ${gateIsQuestion ? "question" : `"${String(cp.gate.kind)}"`} row's deadline is an abandonment TTL (expired, never resolved); refusing pre-CAS, the checkpoint stays pending`, { field: "hostDecision" });
95
+ }
96
+ const cannotAllow = !verdict.allows
97
+ ? undefined
98
+ : decidedBy === "sla_timeout"
99
+ ? ` — that word names a wait that ended with nobody answering, and it cannot approve an action that EXECUTES (an allow is decided by "person" or "policy")`
100
+ : policyCannotAnswer(cp, decidedBy)
101
+ ? ` on a row that requires real approval — a policy's answer is not a person's, and this row demands a person (decide it as "person", or refuse it as "policy")`
102
+ : undefined;
103
+ if (cannotAllow !== undefined)
104
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume carries decision "${verdict.word}" decided by "${decidedBy}"${cannotAllow}; refusing pre-CAS, the checkpoint stays pending`, { field: "hostDecision" });
105
+ const attribution = screenApproverAttribution(raw.approver);
106
+ if (attribution.defect !== undefined) {
107
+ throw new CheckpointError("checkpoint.invalid_outcome", `resume carries an approver attribution this engine refuses: ${attribution.defect}; refusing pre-CAS, the checkpoint stays pending`, { field: "approver" });
108
+ }
109
+ return { decidedBy, ...(attribution.approver !== undefined ? { approver: attribution.approver } : {}) };
110
+ }
111
+ export function parkedOriginOf(cp) {
112
+ if (cp.pendingAction.kind === "tool_approval")
113
+ return isAskOrigin(cp.pendingAction.origin) ? cp.pendingAction.origin : undefined;
114
+ return cp.pendingAction.kind === "plan_review" ? "plan_review" : undefined;
115
+ }
116
+ export function mintDecideRecord(cp, facts, verdict) {
117
+ const origin = parkedOriginOf(cp);
118
+ if (origin === undefined) {
119
+ throw new CheckpointError("checkpoint.unsupported_version", "this checkpoint's pending approval carries no origin word (a row minted before the ask's origin was persisted on the park) — its settlement cannot be recorded; the checkpoint stays pending", { reason: "origin_missing" });
120
+ }
121
+ const settlement = settlementOfHostDecision(facts, verdict.allowed ? "allowed" : "refused", verdict.note);
122
+ return mintGateOutcome({ ...(verdict.allowed ? {} : { deniedBy: "ask_resolution" }), settled: { settlement, origin } });
123
+ }
73
124
  export function assertOutcomeText(value, field) {
74
125
  if (value !== undefined && typeof value !== "string") {
75
126
  throw new CheckpointError("checkpoint.invalid_outcome", `resume \`${field}\` is not a plain string (got ${typeof value}) — a decide's text payload is an operator's plain data, not a live object; refusing pre-CAS, the checkpoint stays pending`);
@@ -82,7 +133,7 @@ function reorientClause(fullShellReachable) {
82
133
  return `Before continuing, ${source} to confirm what is already done, then continue the remaining work. ` +
83
134
  "Do NOT restart the task or re-run work that is already committed.";
84
135
  }
85
- export function resumeContinuation(resume, mark, fullShellReachable) {
136
+ export function resumeContinuation(resume, mark, fullShellReachable, delegatedChild) {
86
137
  if (resume.outcome.gate === "wake") {
87
138
  return formatHookFeedback(`You were WOKEN from a parked pause by an operator. ${reorientClause(fullShellReachable)}`, mark);
88
139
  }
@@ -96,36 +147,40 @@ export function resumeContinuation(resume, mark, fullShellReachable) {
96
147
  return formatHookFeedback(`You were resumed after a dry-run review. ${verdict}. ${reorientClause(fullShellReachable)}`, mark);
97
148
  }
98
149
  if (resume.outcome.gate === "plan_review") {
150
+ const byWhom = resume.outcome.hostDecision.decidedBy === "policy" ? " by this deployment's own policy, not by a person" : "";
99
151
  if (resume.outcome.decision === "approve") {
100
- return formatHookFeedback("Your proposed PLAN was REVIEWED and APPROVED. Proceed with that plan now — begin executing it. " +
152
+ return formatHookFeedback(`Your proposed PLAN was REVIEWED and APPROVED${byWhom}. Proceed with that plan now — begin executing it. ` +
101
153
  "This is a RESUMED task; do NOT re-plan or restart from scratch, just carry out the approved plan.", mark);
102
154
  }
103
155
  if (resume.outcome.decision === "edit") {
104
156
  if (!resume.outcome.editedPlan) {
105
- return formatHookFeedback("Your proposed PLAN was REVIEWED and EDITED, but no revised plan text was supplied — proceed with your " +
157
+ return formatHookFeedback(`Your proposed PLAN was REVIEWED and EDITED${byWhom}, but no revised plan text was supplied — proceed with your ` +
106
158
  "ORIGINAL plan as-is, begin executing it now. This is a RESUMED task; do NOT re-plan or restart from scratch.", mark);
107
159
  }
108
- return formatHookFeedback("Your proposed PLAN was REVIEWED and EDITED by a human reviewer. Proceed with the REVISED plan below " +
160
+ return formatHookFeedback(`Your proposed PLAN was REVIEWED and EDITED${byWhom || " by a human reviewer"}. Proceed with the REVISED plan below ` +
109
161
  "(it supersedes your earlier plan); begin executing it now. This is a RESUMED task; do NOT re-plan " +
110
162
  "or restart from scratch, just carry out the revised plan.\n\nThe REVISED plan to follow is:\n" +
111
163
  delimitUntrusted("revised plan", resume.outcome.editedPlan), mark);
112
164
  }
113
- const why = resume.outcome.reason ? ` Reviewer note: ${delimitUntrusted("reviewer note", resume.outcome.reason, REVIEWER_NOTE_MAX_BODY)}` : "";
114
- return formatHookFeedback(`Your proposed PLAN was REVIEWED and REJECTED; it was NOT executed.${why} Produce a NEW plan that ` +
115
- "addresses the concern, then continue. This is a RESUMED task — re-plan from the current state; do " +
116
- "NOT execute the rejected plan.", mark);
165
+ const { reason } = resume.outcome;
166
+ const policyNote = decidersNote(reason);
167
+ return formatHookFeedback(resume.outcome.hostDecision.decidedBy === "person"
168
+ ? `${humanRefusalSentence("plan", reason, delegatedChild)} This is a RESUMED task; do NOT execute the rejected plan.`
169
+ : `Your proposed PLAN was REVIEWED and REJECTED${byWhom}; it was NOT executed.${policyNote === undefined ? "" : ` Reviewer note: ${delimitUntrusted("reviewer note", policyNote, REVIEWER_NOTE_MAX_BODY)}`} ` +
170
+ "This is a RESUMED task — re-plan from the current state; do NOT execute the rejected plan.", mark);
117
171
  }
118
172
  const { pendingAction } = resume.cp;
119
173
  if (pendingAction.kind !== "tool_approval") {
120
174
  return formatHookFeedback("This is a RESUMED task — continue from where you left off without restarting or re-running prior work.", mark);
121
175
  }
122
- const decided = resume.outcome.decision === "allow"
176
+ const { decision, hostDecision } = resume.outcome;
177
+ const resumed = "This is a RESUMED task — every step before this point is already done and its results are in the conversation above. Do NOT restart the task or re-run any tool you already ran";
178
+ const carryOn = "; continue from this exact point, building on the existing results, and finish the remaining work.";
179
+ if (decision === "deny" && hostDecision.decidedBy === "person") {
180
+ return formatHookFeedback(`${humanRefusalSentence("tool use", resume.outcome.reason, delegatedChild)} ${resumed}${delegatedChild ? carryOn : "."}`, mark);
181
+ }
182
+ const decided = decision === "allow"
123
183
  ? "was APPROVED and has now been executed — its result is in the tool results above"
124
- : resume.outcome.hostDecision.decidedBy === "policy"
125
- ? "was DENIED by this deployment's own policy, not by a person — the refusal and its reason are in the tool results above"
126
- : `was DENIED${resume.outcome.reason ? `: ${delimitUntrusted("reviewer note", resume.outcome.reason, REVIEWER_NOTE_MAX_BODY)}` : ""}`;
127
- return formatHookFeedback(`The pending tool call "${pendingAction.toolName}" ${decided}. ` +
128
- `This is a RESUMED task — every step before this point is already done and its results are in the ` +
129
- `conversation above. Do NOT restart the task or re-run any tool you already ran; continue from this ` +
130
- `exact point, building on the existing results, and finish the remaining work.`, mark);
184
+ : `was DENIED ${hostDecision.decidedBy === "policy" ? "by this deployment's own policy" : "because its approval window elapsed with no answer"}, not by a person — the refusal and its reason are in the tool results above`;
185
+ return formatHookFeedback(`The pending tool call "${pendingAction.toolName}" ${decided}. ${resumed}${carryOn}`, mark);
131
186
  }
@@ -2,6 +2,7 @@ import { type AutoModeDecider, type AutoModeDenialLimitOptions, type AutoModeDen
2
2
  import { type AutoModeArmingRecipe } from "../auto-mode-arming.js";
3
3
  import { type ClassifierUnavailableSeat } from "../classifier-unavailable-arm.js";
4
4
  import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "../tool-policy.js";
5
+ import { type Settlement } from "../gate-outcome.js";
5
6
  import { type EngineNotice } from "../types.js";
6
7
  import { type AskClass, type AskClassFacts, type AskClassification, type AskOrigin, type AskOriginFacts } from "../ask-origin.js";
7
8
  import type { Prepared, StopForDenialLimit } from "./contracts.js";
@@ -220,12 +221,23 @@ type ResolveJudgment<A extends InheritedAsk> = Extract<InheritedClassifierJudgme
220
221
  export declare function inheritedFallbackJudgment<A extends InheritedAsk>(ask: A, fallback: UnarmedDenialLimitFallback, latestBlockedAction: string, facts: AskClassFacts): ResolveJudgment<A>;
221
222
  /** One resolution of an inherited ask at its frozen approver (the three arms): a no-ruling card its POLICY refused counts
222
223
  * ({@link settleNoRulingAsk}); at the bound the call is resolved again there as the fallback. Returns the judgment it answered. */
223
- export declare function resolveInheritedAsk<A extends InheritedAsk, R extends Pick<ResolvedAsk, "action" | "settlement">>(judged: ResolveJudgment<A>, resolveWith: (j: ResolveJudgment<A>) => Promise<R>, tracker: AutoModeDenialTracker | undefined, toolName: string, facts: AskClassFacts): Promise<{
224
- resolved: R;
224
+ export declare function resolveInheritedAsk<A extends InheritedAsk>(judged: ResolveJudgment<A>, resolveWith: (j: ResolveJudgment<A>) => Promise<ResolvedAsk>, tracker: AutoModeDenialTracker | undefined, call: {
225
+ toolCallId: string;
226
+ toolName: string;
227
+ }, facts: AskClassFacts): Promise<{
228
+ resolved: ResolvedAsk;
225
229
  judged: ResolveJudgment<A>;
226
230
  }>;
227
- /** The resolver's answer as the settlement reads it. */
228
- export type FallbackResolution = Pick<ResolvedAsk, "action" | "settlement" | "approverUnavailable">;
231
+ /** The resolver's answer as the settlement reads it: its action, the settlement its engine record names for the call, the routing marker. */
232
+ export type FallbackResolution = {
233
+ action: ResolvedAsk["action"];
234
+ settlement?: Settlement;
235
+ approverUnavailable?: true;
236
+ };
237
+ export declare const fallbackResolutionOf: (r: ResolvedAsk, call: {
238
+ toolCallId: string;
239
+ toolName: string;
240
+ }) => FallbackResolution;
229
241
  /** A deny nobody JUDGED, at a wrapper arm — read off the one table over the settlement words
230
242
  * ({@link SETTLEMENT_NOBODY_JUDGED}) rather than listed here, so a word added to the set answers this
231
243
  * question by getting a row and not by falling out of a disjunction. `approver_unavailable` is NOT
@@ -245,7 +257,7 @@ export declare function settleDenialLimitFallback(opts: {
245
257
  fallback: UnarmedDenialLimitFallback | undefined;
246
258
  mintedHere: boolean;
247
259
  tracker: AutoModeDenialTracker | undefined;
248
- resolved: FallbackResolution;
260
+ resolved: ResolvedAsk;
249
261
  headless: (r: FallbackResolution) => boolean;
250
262
  stop: StopForDenialLimit;
251
263
  toolName: string;
@@ -2,7 +2,7 @@ import { markTightenMessage } from "../safety-axis-vocab.js";
2
2
  import { classifierParseFailureDenyMessage, createAutoModeDenialTracker, denialLimitFallbackMessage, denialLimitSentence, isAutoModeFallbackCause, rungDidNotRule, unarmedWindow } from "../auto-mode.js";
3
3
  import { sanitizeAutoModeArmingRecipe, tightenDenialLimit } from "../auto-mode-arming.js";
4
4
  import { classifierNoRulingArm, settleNoRulingAsk } from "../classifier-unavailable-arm.js";
5
- import { attestClassifierDenyCause, attestClassifierRound, carryEngineAttestations } from "../tool-policy.js";
5
+ import { attest, attestationOf } from "../tool-policy.js";
6
6
  import { SETTLEMENT_NOBODY_JUDGED } from "../gate-outcome.js";
7
7
  import { deliverEngineNotice } from "../types.js";
8
8
  import { inlineUntrusted } from "../untrusted-text.js";
@@ -88,7 +88,7 @@ export async function judgeInheritedClassifier(opts) {
88
88
  const { autoMode, req } = opts;
89
89
  const facts = opts.facts ?? INHERITED_STATION_FACTS, m = facts.mandateMarks;
90
90
  const frames = [...(m.egress === true ? [markTightenMessage(req.toolName, "egress")] : []), ...(m.irreversibility === "always" ? [markTightenMessage(req.toolName, "irreversible")] : [])];
91
- const ask = (frames.length > 0 ? carryEngineAttestations(opts.ask, { ...opts.ask, message: [opts.ask.message ?? inheritedAskFallbackMessage(req.toolName), ...frames].join(" — ") }) : opts.ask);
91
+ const ask = (frames.length > 0 ? { ...opts.ask, message: [opts.ask.message ?? inheritedAskFallbackMessage(req.toolName), ...frames].join(" — ") } : opts.ask);
92
92
  const origin = askOriginOf(ask, facts);
93
93
  const classification = classifyAsk(ask, facts);
94
94
  const classifierStandsDown = () => {
@@ -103,7 +103,7 @@ export async function judgeInheritedClassifier(opts) {
103
103
  .catch(() => ({ kind: "unavailable", cause: "error" }));
104
104
  if (verdict.kind === "allow" && classifierStandsDown())
105
105
  return { kind: "resolve", ask, fallback: ask.denialLimitFallback, mintedHere: false, origin, classification };
106
- const attributed = (d) => (verdict.classifier !== undefined ? attestClassifierRound(d, verdict.classifier, req) : d);
106
+ const attributed = (d) => (verdict.classifier !== undefined ? attest(d, req, { classifierRound: verdict.classifier }) : d);
107
107
  if (verdict.kind === "allow") {
108
108
  autoMode.denialTracking?.recordAllow();
109
109
  return { kind: "allow", result: attributed({ action: "allow", decisionReason: "classifier", ...(opts.allowRewrite !== undefined ? { updatedInput: opts.allowRewrite } : {}) }) };
@@ -123,23 +123,24 @@ export async function judgeInheritedClassifier(opts) {
123
123
  message: verdict.kind === "block" ? `auto-mode classifier blocked ${opts.subject} at an inherited ancestor layer${reason ? `: ${reason}` : category ? `: [${category}]` : ""}` : `${reason} (${opts.subject}, at an inherited ancestor layer)`,
124
124
  decisionReason: "classifier",
125
125
  };
126
- return { kind: "deny", result: attributed(verdict.kind === "parse_error" ? attestClassifierDenyCause(denied, "parse_error", req) : denied) };
126
+ return { kind: "deny", result: attributed(verdict.kind === "parse_error" ? attest(denied, req, { classifierCause: "parse_error" }) : denied) };
127
127
  }
128
128
  return inheritedFallbackJudgment(ask, tracked.fallback, reason || category || req.toolName, facts);
129
129
  }
130
130
  export function inheritedFallbackJudgment(ask, fallback, latestBlockedAction, facts) {
131
131
  const { classifierNoRuling: _why, ...standing } = ask;
132
- const minted = carryEngineAttestations(ask, { ...standing, message: denialLimitFallbackMessage(fallback, latestBlockedAction), decisionReason: "classifier", requiresRealApproval: true, denialLimitFallback: fallback });
132
+ const minted = { ...standing, message: denialLimitFallbackMessage(fallback, latestBlockedAction), decisionReason: "classifier", requiresRealApproval: true, denialLimitFallback: fallback };
133
133
  return { kind: "resolve", ask: minted, fallback, mintedHere: true, origin: askOriginOf(minted, facts), classification: classifyAsk(minted, facts) };
134
134
  }
135
- export async function resolveInheritedAsk(judged, resolveWith, tracker, toolName, facts) {
135
+ export async function resolveInheritedAsk(judged, resolveWith, tracker, call, facts) {
136
136
  const resolved = await resolveWith(judged);
137
- const refallback = settleNoRulingAsk({ ask: judged.ask, mintedHere: judged.noRulingHere === true, resolved, tracker });
137
+ const refallback = settleNoRulingAsk({ ask: judged.ask, mintedHere: judged.noRulingHere === true, resolved: fallbackResolutionOf(resolved, call), tracker });
138
138
  if (refallback === undefined)
139
139
  return { resolved, judged };
140
- const again = inheritedFallbackJudgment(judged.ask, refallback, toolName, facts);
140
+ const again = inheritedFallbackJudgment(judged.ask, refallback, call.toolName, facts);
141
141
  return { resolved: await resolveWith(again), judged: again };
142
142
  }
143
+ export const fallbackResolutionOf = (r, call) => ({ action: r.action, settlement: attestationOf(r, call)?.settlement, ...(r.approverUnavailable === true ? { approverUnavailable: true } : {}) });
143
144
  export function headlessDenyAtFold(r) {
144
145
  return r.settlement !== undefined && SETTLEMENT_NOBODY_JUDGED[r.settlement.kind];
145
146
  }
@@ -147,9 +148,10 @@ export function headlessDenyAtRecheck(r) {
147
148
  return headlessDenyAtFold(r) || r.settlement?.kind === "approver_unavailable" || r.approverUnavailable === true;
148
149
  }
149
150
  export function settleDenialLimitFallback(opts) {
150
- const { fallback, resolved } = opts;
151
+ const { fallback } = opts;
151
152
  if (fallback === undefined)
152
153
  return;
154
+ const resolved = fallbackResolutionOf(opts.resolved, opts);
153
155
  if (resolved.action === "allow") {
154
156
  if (opts.mintedHere)
155
157
  opts.tracker?.recordAllow();
@@ -0,0 +1,8 @@
1
+ import type { EngineNotice } from "../engine-notice.js";
2
+ /** Where the announcement goes and whom it is attributed to — the same triple as the sibling `route.*` seats. */
3
+ export interface ExtraBodyDroppedSeatInput {
4
+ onNotice: ((notice: EngineNotice) => void) | undefined;
5
+ sessionId: string;
6
+ runId: string;
7
+ }
8
+ export declare function createExtraBodyDroppedScope({ onNotice, sessionId, runId }: ExtraBodyDroppedSeatInput): <T>(fn: () => Promise<T>) => Promise<T>;
@@ -0,0 +1,22 @@
1
+ import { runWithExtraBodyDropped } from "../../brain/status-sink.js";
2
+ import { deliverEngineNotice } from "../engine-notice.js";
3
+ export function createExtraBodyDroppedScope({ onNotice, sessionId, runId }) {
4
+ const announced = new Set();
5
+ return (fn) => runWithExtraBodyDropped(({ api, modelId, keys }) => {
6
+ if (keys.length === 0)
7
+ return;
8
+ const set = `${api}\u0000${[...keys].sort().join("\u0000")}`;
9
+ if (announced.has(set))
10
+ return;
11
+ announced.add(set);
12
+ const many = keys.length > 1;
13
+ deliverEngineNotice(onNotice, {
14
+ code: "route.extra_body_reserved_dropped",
15
+ message: `The extraBody of a ${api} request sent as "${modelId}" carried ${many ? "keys" : "a key"} the engine sets itself — ` +
16
+ `${keys.map((k) => `"${k}"`).join(", ")} — and ${many ? "they were" : "it was"} dropped: the request went out ` +
17
+ `with the engine's own value${many ? "s" : ""} (or without ${many ? "them" : "it"}, where the engine sends none). Remove ${many ? "them" : "it"} from extraBody; ` +
18
+ `the same drop applies to every request that model spec is used on, and this notice is said once per run for this set of keys.`,
19
+ detail: { keys: [...keys], api, modelId, sessionId, runId },
20
+ });
21
+ }, fn);
22
+ }
@@ -0,0 +1,9 @@
1
+ import type { EngineNotice } from "../engine-notice.js";
2
+ export interface FinishReasonSeat {
3
+ /** Observe one assistant message; announce each stream-end fact this leg has not announced yet. */
4
+ observe(message: unknown): void;
5
+ }
6
+ export declare function createFinishReasonSeat(onNotice: ((notice: EngineNotice) => void) | undefined, ids: {
7
+ sessionId: string;
8
+ runId: string;
9
+ }): FinishReasonSeat;
@@ -0,0 +1,40 @@
1
+ import { deliverEngineNotice } from "../engine-notice.js";
2
+ import { readMember } from "../thrown-value.js";
3
+ export function createFinishReasonSeat(onNotice, ids) {
4
+ const announced = new Set();
5
+ const once = (key) => {
6
+ if (announced.has(key))
7
+ return false;
8
+ announced.add(key);
9
+ return true;
10
+ };
11
+ return {
12
+ observe(message) {
13
+ const word = readMember(message, "finishReasonUnknown");
14
+ if (typeof word === "string" && once(`unknown\u0000${word}`)) {
15
+ deliverEngineNotice(onNotice, {
16
+ code: "route.finish_reason_unknown",
17
+ message: `The provider ended a response with "${word}", a finish reason this engine does not read. The turn was kept ` +
18
+ `as the model left it, but the provider may have cut it short — the text above may be incomplete.`,
19
+ detail: { finishReason: word, sessionId: ids.sessionId, runId: ids.runId },
20
+ });
21
+ }
22
+ const late = readMember(message, "streamEndIgnored");
23
+ const statement = readMember(late, "statement");
24
+ const lateWord = readMember(late, "word");
25
+ const frames = readMember(late, "frames");
26
+ if ((statement === "ending" || statement === "error" || statement === "content") &&
27
+ typeof lateWord === "string" &&
28
+ typeof frames === "number" &&
29
+ once(`late\u0000${statement}\u0000${lateWord}`)) {
30
+ const what = statement === "error" ? `an error "${lateWord}"` : statement === "ending" ? `the ending "${lateWord}"` : `${lateWord} content`;
31
+ deliverEngineNotice(onNotice, {
32
+ code: "route.stream_end_ignored",
33
+ message: `After the provider had already ended a response, its stream sent more (first: ${what}; ${frames} frame${frames === 1 ? "" : "s"} in all). ` +
34
+ `The first ending stands; nothing after it was added to the turn.`,
35
+ detail: { statement, word: lateWord, frames, sessionId: ids.sessionId, runId: ids.runId },
36
+ });
37
+ }
38
+ },
39
+ };
40
+ }
@@ -6,7 +6,7 @@
6
6
  * refused, written once at the refusing site; WHAT was settled, written at the resolution site) and hands
7
7
  * them here; the mint assembles the record, runs the invariant screen, and refuses a record the engine
8
8
  * composed wrong. Every projection of the outcome (the deny observer's payload, the call's `tool_end`
9
- * frame, the engine's per-call sideband) is the object minted here, never a re-derivation;
9
+ * frame, the call's occurrence record) is the object minted here, never a re-derivation;
10
10
  * - the settlement LEDGER of a pass ({@link createSettlementLedger}) — the one rule every attestation read
11
11
  * goes through;
12
12
  * - the PASS RECORD ({@link GatePass}) — the per-call cells the gate's station groups read and write, and
@@ -28,10 +28,12 @@ import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from ".
28
28
  import type { SafeNotifier } from "../safe-notify.js";
29
29
  import type { HookSeatOutcome, PermissionDeniedPayload, PreToolUseResult, ToolGateInput, ToolGateResult } from "../hooks.js";
30
30
  /** The ask a gate pass settled, as the gate captured it at its resolution site: the settlement the
31
- * resolver composed and the origin word the ask carried. Both or neither (invariant I1). */
31
+ * resolver composed and the origin word the ask carried. Both or neither (invariant I1). `licensed` is the engine record's
32
+ * digest of the bytes the settlement licensed: the allow exit keeps a settlement only for the bytes that run. */
32
33
  export interface SettledAsk {
33
34
  settlement: Settlement;
34
35
  origin: AskOrigin;
36
+ licensed?: string;
35
37
  }
36
38
  /** The facts a gate pass hands the mint. `deniedBy` is present exactly when the pass refused; `cause` only
37
39
  * beside it, when the refusing round was a classifier round that did not rule (the station's attestation,
@@ -62,43 +64,42 @@ export declare function mintGateOutcome(facts: GateExitFacts): GateOutcome;
62
64
  export declare function directDeny(deniedBy: Exclude<DeniedBy, "ask_resolution">): GateOutcome;
63
65
  /**
64
66
  * The gate's settlement LEDGER for one pass — the one place "which ask did this pass consume" is written,
65
- * with ONE rule for every attestation read (the main adjudication, the approval-edit re-check, the gate's
66
- * own ask resolutions), so the three sites cannot disagree about what an attested decision means:
67
- * - an engine attestation on a decision object (the approval factory's wait ended inside a policy
68
- * `check()`; an inherited lane resolved an ancestor's ask) is a settled ask of THIS call — read off the
69
- * identity-keyed seat, never off a caller-composable member;
70
- * - a deny carrying a REFUSAL attestation is the ask's own resolution (`ask_resolution`); a deny carrying a
71
- * person's YES is a later layer's VETO (the yes stays on the settlement, the layer is the disposition —
72
- * invariant I3);
67
+ * with ONE rule for every read, all through the decision's engine record ({@link attestationOf}):
68
+ * - a record on an adjudication (the approval factory's wait ended inside a policy `check()`; an inherited
69
+ * lane resolved an ancestor's ask) is a settled ask of THIS call — an approval only for the bytes it licensed (an
70
+ * allow that runs other bytes runs unattributed); a deny carrying a REFUSAL record is the
71
+ * ask's own resolution (`ask_resolution`), a deny carrying a person's YES is a later layer's VETO (the yes
72
+ * stays on the settlement, the layer is the disposition — invariant I3), and an allow carrying a refusal
73
+ * record is that refusal (invariant I4: the record says what ended the wait, whatever the decision claims);
74
+ * - a resolution's record counts only when it answers THE ask the gate put to the resolver — its origin word,
75
+ * its class set, the bytes the answer licenses (the record's `inputDigest`); a resolution
76
+ * without such a record settled nothing the engine can attribute: a deny is recorded as the resolver's
77
+ * out-of-contract refusal (`approver_contract`), an allow on a real-approval ask is refused, a plain allow
78
+ * is a posture allow; a resolution still carrying the retired `settlement` member is refused loudly;
73
79
  * - the LATEST resolution wins (a re-check refusal replaces the first approval; a re-approval renews it);
74
80
  * - a SURVIVING ask supersedes any settlement read off an earlier decision (a tighten minted a new
75
81
  * question; whoever resolves it settles it afresh).
76
- * For a resolver's object the attestation outranks the exposed member; the member is the fallback for a
77
- * resolver seat that composes without attesting (a hand-built resolver; the ask lane's own intercept
78
- * deny). TRUST BOUNDARY, stated: `ToolGateInput.resolveAsk` is wired by prepare from the engine's own
79
- * resolver — a wrapper that spreads a resolved object (dropping the identity-keyed attestation) and
80
- * REPLACES the member is inside the engine's trust line, not a deployment's; making the member
81
- * attestation-only is the follow-up that migrates the ask lane's composition and the test resolvers
82
- * onto an engine-owned mint.
83
82
  */
84
83
  export interface SettlementLedger {
85
84
  /** The ask this pass consumed, or undefined when no ask was settled (a direct deny, a plain allow). */
86
85
  readonly settled: SettledAsk | undefined;
87
86
  /** An engine-composed settlement the gate itself minted (the unshown content ask's refusal). */
88
87
  set(settled: SettledAsk): void;
89
- /** Record an ask's resolution: the resolver's settlement beside the ask's own origin word. */
90
- fromResolved(resolved: ResolvedAsk, asked: PermissionResult, toolName: string): void;
91
- /** Read an adjudication's attestation. For a deny, returns the refusing layer word (`ask_resolution`
92
- * for an attested refusal, `policy` otherwise — a veto when a yes rides the settlement); undefined
93
- * for an allow or an ask. */
94
- fromDecision(decision: PermissionResult): DeniedBy | undefined;
95
- /** Read a deny's attested classifier CAUSE for this call (an inherited station's `unavailable` /
96
- * `parse_error` round travelling through an ancestor wrapper into this fold); undefined for a ruling
97
- * block, a non-classifier deny, an allow or an ask. */
88
+ /** Record an ask's resolution; returns the resolution the gate goes on with (the resolver's, or the engine's refusal). */
89
+ fromResolved(resolved: ResolvedAsk, asked: PermissionResult, req: ToolCallRequest): ResolvedAsk;
90
+ /** Read an adjudication's record; returns the decision the gate goes on with and, for a deny, the refusing layer word
91
+ * (`ask_resolution` for a refusal record, `policy` otherwise — a veto when a yes rides the settlement). */
92
+ fromDecision(decision: PermissionResult): {
93
+ decision: PermissionResult;
94
+ deniedBy?: DeniedBy;
95
+ };
96
+ /** The allow exit: the bytes that RUN are decided — a settlement licensed for other bytes leaves the record (the call runs
97
+ * unattributed). */
98
+ keepForBytes(runs: unknown): void;
99
+ /** A deny's recorded classifier CAUSE for this call (an inherited station's `unavailable` / `parse_error` outcome). */
98
100
  causeOf(decision: PermissionResult): ClassifierDenyCause | undefined;
99
- /** Read a decision's attested CLASSIFICATION for this call — which model an ancestor's frozen classifier
100
- * asked and which answered, on the allow arm as much as the deny arm. Undefined when no inherited
101
- * classifier judged the call, or when the ancestor's decider could vouch for no name. */
101
+ /** A decision's recorded CLASSIFICATION for this call — which model an ancestor's frozen classifier asked and which
102
+ * answered, on either arm. */
102
103
  classifierRoundOf(decision: PermissionResult): AutoModeClassifierRound | undefined;
103
104
  /** A surviving ask supersedes whatever an earlier decision settled. */
104
105
  supersede(): void;
@@ -116,6 +117,15 @@ export declare function createSettlementLedger(call: {
116
117
  * a non-object primitive passes through as-is (immutable anyway).
117
118
  */
118
119
  export declare function cloneObserverInput(input: unknown): unknown;
120
+ /**
121
+ * The input a gate exit decided on, as the call's record keeps it ({@link ToolGateResult.finalInput}): a deep,
122
+ * FROZEN copy — never the live object the tool receives (a tool or a later layer writing into its own arguments
123
+ * must not rewrite what the gate decided), and never writable by a reader; the deny observer gets a writable
124
+ * {@link cloneObserverInput} of it. A graph `structuredClone` refuses (functions, handles) is kept as a shallow
125
+ * copy frozen at its own top level only — its members are the live arguments' own, and freezing those would
126
+ * freeze the call's input under the tool.
127
+ */
128
+ export declare function frozenInputSnapshot(input: unknown): unknown;
119
129
  /**
120
130
  * The PreToolUse screening face as the gate's stations see it — the hook machinery of `runToolGate` (the seat
121
131
  * runner, the per-call seat bound, the fresh per-screening context, the result screen, the two fail-closed
@@ -297,9 +307,11 @@ export interface GatePass {
297
307
  * on BOTH its arms (a write tool's target), and the fold's read station (a shell command's written targets,
298
308
  * `ShellReadVerdict.writeProtected`). Reader: the lanes' mandate. */
299
309
  writeProtected?: true;
300
- /** borrowed-mutable — the same judge could NOT RESOLVE the target: no automatic lane may answer the
301
- * ask. Writer and reader as above; the pair is mutually exclusive (one verdict per judgment). */
302
- writeProtectionUnresolved?: true;
310
+ /** borrowed-mutable — the READING of a written target could not say where it leads on disk (a target a shell command's
311
+ * program writes, placed, whose destination the read station could not resolve): no automatic lane may answer the ask.
312
+ * A fact of the reading, not of a judge. Writer: the fold's read station (`ShellReadVerdict.targetUnresolved`). Reader:
313
+ * the lanes' mandate. */
314
+ targetUnresolved?: true;
303
315
  /** borrowed-mutable — the rewrite remembered BEFORE a hook-ask promotion / tighten, re-applied on the
304
316
  * approved path (a redaction is not cancelled because a person confirmed). Writer: the fold. Readers: the
305
317
  * fold's probe and write-protection judges, the lanes, the allow exit. */