@sema-agent/core 7.55.0 → 7.57.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 (502) hide show
  1. package/CHANGELOG.md +1054 -0
  2. package/LICENSE +1 -1
  3. package/dist/agents/cascade.js +1 -1
  4. package/dist/agents/cc-peer-directory.js +1 -0
  5. package/dist/agents/child-model-seat.d.ts +0 -11
  6. package/dist/agents/child-model-seat.js +0 -3
  7. package/dist/agents/list-agents-tool.d.ts +3 -1
  8. package/dist/agents/list-agents-tool.js +7 -7
  9. package/dist/agents/org-delivery-gate.js +3 -4
  10. package/dist/agents/peer-directory.d.ts +22 -4
  11. package/dist/agents/peer-directory.js +24 -2
  12. package/dist/agents/peer-held-queue.d.ts +69 -49
  13. package/dist/agents/peer-held-queue.js +255 -106
  14. package/dist/agents/peer-session-drain.js +65 -45
  15. package/dist/agents/repair-loop.js +2 -2
  16. package/dist/agents/send-message-tool.js +7 -6
  17. package/dist/agents/subagent.d.ts +6 -4
  18. package/dist/agents/subagent.js +72 -68
  19. package/dist/agents/tool-filter.d.ts +7 -5
  20. package/dist/agents/tool-filter.js +12 -9
  21. package/dist/agents/verify.d.ts +3 -2
  22. package/dist/agents/verify.js +3 -3
  23. package/dist/brain/anthropic.js +45 -80
  24. package/dist/brain/media-degrade.d.ts +18 -7
  25. package/dist/brain/media-degrade.js +13 -2
  26. package/dist/brain/model-capability.d.ts +37 -0
  27. package/dist/brain/model-capability.js +34 -0
  28. package/dist/brain/model-presets.d.ts +2 -8
  29. package/dist/brain/model-presets.js +1 -6
  30. package/dist/brain/open-responses.js +23 -34
  31. package/dist/brain/openai.js +25 -96
  32. package/dist/brain/provider-dialect.d.ts +3 -2
  33. package/dist/brain/provider-dialect.js +2 -2
  34. package/dist/brain/reasoning-request.d.ts +96 -0
  35. package/dist/brain/reasoning-request.js +174 -0
  36. package/dist/brain/reasoning.d.ts +11 -11
  37. package/dist/brain/reasoning.js +4 -3
  38. package/dist/brain/request-params.d.ts +13 -4
  39. package/dist/brain/request-params.js +21 -5
  40. package/dist/brain/status-sink.d.ts +20 -0
  41. package/dist/brain/status-sink.js +7 -0
  42. package/dist/brain/stream-engine.d.ts +9 -0
  43. package/dist/brain/stream-engine.js +24 -10
  44. package/dist/brain/stream-shared.d.ts +5 -4
  45. package/dist/brain/stream-shared.js +4 -4
  46. package/dist/core/a2a.d.ts +2 -1
  47. package/dist/core/a2a.js +19 -13
  48. package/dist/core/agent-definition.d.ts +10 -0
  49. package/dist/core/allow-entry.d.ts +23 -23
  50. package/dist/core/allow-entry.js +42 -46
  51. package/dist/core/allow-rule-shadow.d.ts +3 -3
  52. package/dist/core/approval-object.d.ts +21 -5
  53. package/dist/core/approval-object.js +44 -17
  54. package/dist/core/ask-origin.d.ts +66 -20
  55. package/dist/core/ask-origin.js +63 -23
  56. package/dist/core/ask-question.d.ts +51 -8
  57. package/dist/core/ask-question.js +3 -4
  58. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  59. package/dist/core/ask-unresolvable-notice.js +16 -2
  60. package/dist/core/auto-compaction.d.ts +71 -6
  61. package/dist/core/auto-compaction.js +42 -26
  62. package/dist/core/background-agent-store.d.ts +6 -2
  63. package/dist/core/background-agent-store.js +1 -1
  64. package/dist/core/checkpoint-generation.d.ts +53 -0
  65. package/dist/core/checkpoint-generation.js +35 -0
  66. package/dist/core/checkpoint-queries.d.ts +180 -0
  67. package/dist/core/checkpoint-queries.js +272 -0
  68. package/dist/core/checkpoint-requirements.d.ts +19 -1
  69. package/dist/core/checkpoint-requirements.js +6 -0
  70. package/dist/core/checkpoint-store.d.ts +105 -53
  71. package/dist/core/checkpoint-store.js +43 -20
  72. package/dist/core/cross-boundary-taint.d.ts +6 -5
  73. package/dist/core/cross-boundary-taint.js +5 -5
  74. package/dist/core/decision-receipt.d.ts +37 -3
  75. package/dist/core/decision-receipt.js +17 -17
  76. package/dist/core/delegation-not-started.d.ts +6 -0
  77. package/dist/core/delegation-not-started.js +17 -0
  78. package/dist/core/engine-attestation.d.ts +93 -0
  79. package/dist/core/engine-attestation.js +70 -0
  80. package/dist/core/engine-capabilities.d.ts +4 -1
  81. package/dist/core/engine-capabilities.js +1 -1
  82. package/dist/core/engine-notice.d.ts +32 -12
  83. package/dist/core/engine-notice.js +6 -0
  84. package/dist/core/file-history-store.d.ts +104 -22
  85. package/dist/core/file-history-store.js +37 -19
  86. package/dist/core/gate-fold.d.ts +1 -1
  87. package/dist/core/gate-fold.js +22 -10
  88. package/dist/core/gate-lanes.js +73 -65
  89. package/dist/core/gate-outcome.d.ts +26 -5
  90. package/dist/core/gate-outcome.js +26 -0
  91. package/dist/core/governance-codes.d.ts +5 -1
  92. package/dist/core/governance-codes.js +6 -0
  93. package/dist/core/hooks.d.ts +19 -18
  94. package/dist/core/hooks.js +3 -1
  95. package/dist/core/host-floor.d.ts +128 -0
  96. package/dist/core/host-floor.js +206 -0
  97. package/dist/core/host-target.d.ts +38 -3
  98. package/dist/core/host-target.js +38 -5
  99. package/dist/core/mailbox-store.d.ts +62 -1
  100. package/dist/core/mailbox-store.js +59 -0
  101. package/dist/core/mcp-name-judge.d.ts +46 -0
  102. package/dist/core/mcp-name-judge.js +61 -0
  103. package/dist/core/mcp-probe.d.ts +1 -1
  104. package/dist/core/mcp-probe.js +2 -5
  105. package/dist/core/mcp.d.ts +5 -1
  106. package/dist/core/mcp.js +70 -64
  107. package/dist/core/memory-engine/consolidation-driver.js +4 -3
  108. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  109. package/dist/core/memory-engine/distiller.js +26 -17
  110. package/dist/core/memory-engine/engine.js +4 -4
  111. package/dist/core/memory-engine/layout.d.ts +60 -8
  112. package/dist/core/memory-engine/layout.js +70 -8
  113. package/dist/core/model-seat.d.ts +10 -3
  114. package/dist/core/mods/classic-events.d.ts +67 -0
  115. package/dist/core/mods/classic-events.js +1 -0
  116. package/dist/core/mods/dollar.d.ts +13 -0
  117. package/dist/core/mods/extension-call.d.ts +31 -0
  118. package/dist/core/mods/extension-call.js +43 -0
  119. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  120. package/dist/core/mods/kernel/dispatch.js +140 -69
  121. package/dist/core/mods/kernel/events.d.ts +47 -11
  122. package/dist/core/mods/kernel/events.js +66 -42
  123. package/dist/core/mods/kernel/index.d.ts +4 -4
  124. package/dist/core/mods/kernel/index.js +2 -2
  125. package/dist/core/mods/kernel/receive.d.ts +39 -5
  126. package/dist/core/mods/kernel/receive.js +290 -17
  127. package/dist/core/mods/kernel/registration.d.ts +33 -2
  128. package/dist/core/mods/kernel/registration.js +6 -7
  129. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  130. package/dist/core/mods/kernel/site-rules.js +24 -42
  131. package/dist/core/mods/spec-seats.d.ts +69 -0
  132. package/dist/core/mods/spec-seats.js +114 -0
  133. package/dist/core/mods/stations.d.ts +28 -8
  134. package/dist/core/mods/stations.js +29 -13
  135. package/dist/core/mods/tool-call.d.ts +79 -0
  136. package/dist/core/mods/tool-call.js +152 -0
  137. package/dist/core/namespaced-rule-name.d.ts +32 -38
  138. package/dist/core/namespaced-rule-name.js +29 -36
  139. package/dist/core/parent-spec-seat.d.ts +6 -1
  140. package/dist/core/parent-spec-seat.js +2 -0
  141. package/dist/core/park-selfcheck.js +3 -0
  142. package/dist/core/permission-rule-consent.d.ts +24 -3
  143. package/dist/core/permission-rule-consent.js +136 -41
  144. package/dist/core/permission-rule-model.d.ts +57 -5
  145. package/dist/core/permission-rule-model.js +90 -31
  146. package/dist/core/permission-rule-org.d.ts +6 -2
  147. package/dist/core/permission-rule-org.js +8 -4
  148. package/dist/core/permission-rule-provider.d.ts +5 -2
  149. package/dist/core/permission-rule-provider.js +41 -11
  150. package/dist/core/permission-rule-store.d.ts +3 -2
  151. package/dist/core/permission-rule-store.js +11 -2
  152. package/dist/core/permission-rule-sync.js +3 -2
  153. package/dist/core/permission-rule-syntax.d.ts +5 -4
  154. package/dist/core/permission-rule-syntax.js +2 -2
  155. package/dist/core/permission-rules.d.ts +4 -4
  156. package/dist/core/permission-rules.js +11 -20
  157. package/dist/core/persisted-rule-arms.d.ts +2 -2
  158. package/dist/core/persisted-rule-arms.js +10 -12
  159. package/dist/core/principal-name.d.ts +20 -0
  160. package/dist/core/principal-name.js +22 -0
  161. package/dist/core/prompt-section-seat.js +4 -6
  162. package/dist/core/protocol-http-auth.d.ts +40 -5
  163. package/dist/core/protocol-http-auth.js +168 -4
  164. package/dist/core/protocol-naming.d.ts +20 -0
  165. package/dist/core/protocol-naming.js +20 -3
  166. package/dist/core/read-only-shell.d.ts +20 -5
  167. package/dist/core/read-only-shell.js +29 -14
  168. package/dist/core/remote-env.d.ts +37 -1
  169. package/dist/core/remote-env.js +11 -0
  170. package/dist/core/resume-startup-cause.d.ts +24 -2
  171. package/dist/core/resume-startup-cause.js +20 -1
  172. package/dist/core/retired-keys.d.ts +16 -0
  173. package/dist/core/retired-keys.js +16 -4
  174. package/dist/core/rewrite-rejudge.d.ts +60 -0
  175. package/dist/core/rewrite-rejudge.js +36 -0
  176. package/dist/core/roles.d.ts +28 -1
  177. package/dist/core/roles.js +81 -26
  178. package/dist/core/rule-lane-reads.d.ts +20 -15
  179. package/dist/core/rule-lane-reads.js +45 -17
  180. package/dist/core/rule-owner.d.ts +3 -3
  181. package/dist/core/rule-owner.js +3 -2
  182. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  183. package/dist/core/runner/announce-once-ledger.js +5 -0
  184. package/dist/core/runner/assemble-result.d.ts +1 -0
  185. package/dist/core/runner/assemble-result.js +1 -1
  186. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  187. package/dist/core/runner/caller-roster.d.ts +16 -4
  188. package/dist/core/runner/caller-roster.js +33 -6
  189. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  190. package/dist/core/runner/capability-withheld-seat.js +24 -0
  191. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  192. package/dist/core/runner/classifier-ladder.js +3 -3
  193. package/dist/core/runner/compact-session.d.ts +10 -0
  194. package/dist/core/runner/compact-session.js +202 -0
  195. package/dist/core/runner/compaction-call-options.d.ts +2 -2
  196. package/dist/core/runner/compaction-seams.d.ts +21 -1
  197. package/dist/core/runner/compaction-seams.js +11 -8
  198. package/dist/core/runner/construction-doors.js +3 -0
  199. package/dist/core/runner/contracts.d.ts +50 -40
  200. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  201. package/dist/core/runner/cross-boundary-lane.js +40 -27
  202. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  203. package/dist/core/runner/denial-limit-arms.js +1 -1
  204. package/dist/core/runner/derived-route-fallback.d.ts +13 -0
  205. package/dist/core/runner/derived-route-fallback.js +6 -0
  206. package/dist/core/runner/env-capability-census.d.ts +3 -2
  207. package/dist/core/runner/env-capability-census.js +9 -3
  208. package/dist/core/runner/file-history-request.d.ts +18 -0
  209. package/dist/core/runner/file-history-request.js +21 -13
  210. package/dist/core/runner/file-history-restore.d.ts +45 -0
  211. package/dist/core/runner/file-history-restore.js +46 -0
  212. package/dist/core/runner/gate-exit.d.ts +3 -3
  213. package/dist/core/runner/gate-exit.js +4 -3
  214. package/dist/core/runner/image.d.ts +7 -17
  215. package/dist/core/runner/image.js +9 -60
  216. package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
  217. package/dist/core/runner/permission-rule-lanes.js +39 -17
  218. package/dist/core/runner/person-path-rows.d.ts +12 -9
  219. package/dist/core/runner/person-path-rows.js +18 -7
  220. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
  221. package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
  222. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  223. package/dist/core/runner/prepare-ask-lane.js +5 -2
  224. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  225. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  226. package/dist/core/runner/prepare-config-doors.d.ts +35 -38
  227. package/dist/core/runner/prepare-config-doors.js +46 -28
  228. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  229. package/dist/core/runner/prepare-defer-classify.js +7 -8
  230. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  231. package/dist/core/runner/prepare-file-history.js +7 -39
  232. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  233. package/dist/core/runner/prepare-gate-stations.js +10 -1
  234. package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
  235. package/dist/core/runner/prepare-hands-readface.js +17 -14
  236. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  237. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  238. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  239. package/dist/core/runner/prepare-park-ask.d.ts +2 -0
  240. package/dist/core/runner/prepare-park-ask.js +7 -7
  241. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  242. package/dist/core/runner/prepare-policy-chain.js +67 -76
  243. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  244. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  245. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  246. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  247. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  248. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  249. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  250. package/dist/core/runner/prepare-safety-scan.js +0 -17
  251. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  252. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  253. package/dist/core/runner/prepare-task.d.ts +5 -2
  254. package/dist/core/runner/prepare-task.js +48 -43
  255. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
  256. package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
  257. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  258. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  259. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  260. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  261. package/dist/core/runner/resume-admission.js +1 -1
  262. package/dist/core/runner/resume-apply.js +11 -12
  263. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  264. package/dist/core/runner/resume-claim.d.ts +4 -2
  265. package/dist/core/runner/resume-claim.js +15 -8
  266. package/dist/core/runner/retired-runner-deps.js +1 -0
  267. package/dist/core/runner/rewind-files.d.ts +12 -0
  268. package/dist/core/runner/rewind-files.js +90 -0
  269. package/dist/core/runner/run-attachment-seats.js +2 -1
  270. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  271. package/dist/core/runner/run-brain-sinks.js +4 -2
  272. package/dist/core/runner/run-harness-handlers.js +12 -4
  273. package/dist/core/runner/run-leg.d.ts +1 -1
  274. package/dist/core/runner/run-leg.js +40 -39
  275. package/dist/core/runner/run-notification-lane.d.ts +2 -0
  276. package/dist/core/runner/run-notification-lane.js +2 -2
  277. package/dist/core/runner/run-recovery-lanes.js +3 -4
  278. package/dist/core/runner/run-settle-and-teardown.js +7 -12
  279. package/dist/core/runner/run-terminal-adoption.js +3 -4
  280. package/dist/core/runner/run-turn-boundary.js +4 -15
  281. package/dist/core/runner/runtask.d.ts +10 -0
  282. package/dist/core/runner/runtask.js +35 -42
  283. package/dist/core/runner/send-message-continuation.js +1 -1
  284. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  285. package/dist/core/runner/session-read-file-states.js +28 -0
  286. package/dist/core/runner/session-rule-policy.js +4 -3
  287. package/dist/core/runner/session-verb-doors.d.ts +28 -0
  288. package/dist/core/runner/session-verb-doors.js +48 -0
  289. package/dist/core/runner/session-write-ledger.d.ts +30 -0
  290. package/dist/core/runner/session-write-ledger.js +101 -0
  291. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  292. package/dist/core/runner/shell-env-withheld.js +51 -0
  293. package/dist/core/runner/skills-seat.js +6 -2
  294. package/dist/core/runner/stream-settle-backstop.js +12 -15
  295. package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
  296. package/dist/core/runner/sub-agent-deny-lists.js +25 -17
  297. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  298. package/dist/core/runner/synthetic-tools.js +4 -1
  299. package/dist/core/runner/teardown-bounded.d.ts +1 -0
  300. package/dist/core/runner/teardown-bounded.js +1 -0
  301. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  302. package/dist/core/runner/tool-disclosure.js +1 -3
  303. package/dist/core/runner/tool-end-body.d.ts +1 -1
  304. package/dist/core/runner/tool-end-body.js +10 -9
  305. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  306. package/dist/core/runner/tool-not-executed.js +11 -0
  307. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  308. package/dist/core/runner/tool-occurrence.js +7 -0
  309. package/dist/core/runner/turn-attachments.d.ts +33 -15
  310. package/dist/core/runner/turn-attachments.js +62 -37
  311. package/dist/core/runner-deps.d.ts +7 -7
  312. package/dist/core/safety-axis-vocab.d.ts +6 -4
  313. package/dist/core/safety-axis-vocab.js +6 -5
  314. package/dist/core/safety-merge-corpus.js +11 -3
  315. package/dist/core/secret-env.d.ts +30 -3
  316. package/dist/core/secret-env.js +47 -8
  317. package/dist/core/select-model.js +3 -3
  318. package/dist/core/session-policy-store.d.ts +32 -15
  319. package/dist/core/session-policy-store.js +156 -36
  320. package/dist/core/session-store.d.ts +29 -10
  321. package/dist/core/session-store.js +51 -19
  322. package/dist/core/session.d.ts +82 -16
  323. package/dist/core/session.js +53 -0
  324. package/dist/core/shell-read-silence.d.ts +11 -12
  325. package/dist/core/shell-read-silence.js +9 -5
  326. package/dist/core/shell-run-candidates.js +3 -1
  327. package/dist/core/shell-wrapper-projection.d.ts +1 -1
  328. package/dist/core/shell-wrapper-projection.js +1 -1
  329. package/dist/core/shell-wrapper-table.d.ts +14 -7
  330. package/dist/core/shell-wrapper-table.js +5 -4
  331. package/dist/core/side-query.js +10 -1
  332. package/dist/core/skill-grant.d.ts +7 -2
  333. package/dist/core/skill-grant.js +5 -0
  334. package/dist/core/skills-directory.js +6 -2
  335. package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
  336. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  337. package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
  338. package/dist/core/store-contracts/file-history-store-contract.js +40 -1
  339. package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
  340. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  341. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  342. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  343. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  344. package/dist/core/store-contracts/session-store-contract.js +150 -14
  345. package/dist/core/stub-env.d.ts +2 -0
  346. package/dist/core/stub-env.js +1 -0
  347. package/dist/core/synthetic-read-verdict.js +3 -3
  348. package/dist/core/task-event.d.ts +32 -4
  349. package/dist/core/task-notification.d.ts +16 -12
  350. package/dist/core/task-registry-agent.d.ts +8 -4
  351. package/dist/core/task-registry-agent.js +14 -8
  352. package/dist/core/task-registry-shared.d.ts +35 -6
  353. package/dist/core/task-registry-shared.js +11 -0
  354. package/dist/core/task-registry.d.ts +10 -1
  355. package/dist/core/task-registry.js +12 -2
  356. package/dist/core/task-result.d.ts +18 -0
  357. package/dist/core/task-spec.d.ts +18 -13
  358. package/dist/core/tighten-task-spec.js +2 -1
  359. package/dist/core/tool-catalog-entries.d.ts +23 -0
  360. package/dist/core/tool-catalog-entries.js +14 -2
  361. package/dist/core/tool-check-reading.d.ts +11 -0
  362. package/dist/core/tool-check-reading.js +11 -6
  363. package/dist/core/tool-model-gate.d.ts +2 -2
  364. package/dist/core/tool-name-aliases.d.ts +48 -18
  365. package/dist/core/tool-name-aliases.js +36 -19
  366. package/dist/core/tool-name-readings.d.ts +6 -32
  367. package/dist/core/tool-name-readings.js +2 -9
  368. package/dist/core/tool-policy.d.ts +78 -204
  369. package/dist/core/tool-policy.js +152 -204
  370. package/dist/core/tool-result-store.js +3 -0
  371. package/dist/core/tool-roster.d.ts +14 -19
  372. package/dist/core/tool-roster.js +11 -44
  373. package/dist/core/tool-spec-members.js +7 -2
  374. package/dist/core/tool-spec.d.ts +19 -11
  375. package/dist/core/tools.js +49 -9
  376. package/dist/core/trace.d.ts +6 -3
  377. package/dist/core/trace.js +2 -1
  378. package/dist/core/types.d.ts +1 -1
  379. package/dist/core/untrusted-egress.d.ts +20 -0
  380. package/dist/core/untrusted-egress.js +77 -3
  381. package/dist/core/user-attachment.d.ts +8 -1
  382. package/dist/core/user-attachment.js +64 -4
  383. package/dist/core/wiring-manifest.d.ts +9 -0
  384. package/dist/core/wiring-manifest.js +1 -0
  385. package/dist/core/workflow-journal-store.js +1 -1
  386. package/dist/engine/compaction/compaction.js +3 -2
  387. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  388. package/dist/engine/execution-env/node-execution-env.js +11 -2
  389. package/dist/engine/harness/agent-harness.d.ts +32 -6
  390. package/dist/engine/harness/agent-harness.js +65 -9
  391. package/dist/engine/harness/types.d.ts +29 -2
  392. package/dist/engine/llm/types.d.ts +28 -11
  393. package/dist/engine/loop/agent-loop.d.ts +23 -4
  394. package/dist/engine/loop/agent-loop.js +42 -30
  395. package/dist/engine/loop/types.d.ts +16 -6
  396. package/dist/engine/session/memory-repo.d.ts +9 -2
  397. package/dist/engine/session/memory-repo.js +11 -1
  398. package/dist/engine/session/repo-utils.d.ts +6 -5
  399. package/dist/engine/session/repo-utils.js +14 -6
  400. package/dist/index.d.ts +34 -17
  401. package/dist/index.js +22 -11
  402. package/dist/internal/harness-types.d.ts +1 -1
  403. package/dist/internal/harness.d.ts +2 -1
  404. package/dist/internal/harness.js +1 -0
  405. package/dist/internal/llm.d.ts +1 -1
  406. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  407. package/dist/orchestration/run-workflow-tool.js +5 -3
  408. package/dist/orchestration/workflow.d.ts +3 -0
  409. package/dist/orchestration/workflow.js +36 -18
  410. package/dist/primitives/credential-ref.d.ts +89 -0
  411. package/dist/primitives/credential-ref.js +125 -0
  412. package/dist/primitives/index.d.ts +2 -0
  413. package/dist/primitives/index.js +1 -0
  414. package/dist/prompt-assembly/artifact.d.ts +2 -2
  415. package/dist/prompt-assembly/artifact.js +5 -3
  416. package/dist/prompt-assembly/assemble.d.ts +3 -2
  417. package/dist/prompt-assembly/assemble.js +1 -1
  418. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  419. package/dist/prompt-assembly/catalog/schema.js +34 -2
  420. package/dist/prompt-assembly/catalog/sections.js +0 -1
  421. package/dist/prompt-assembly/composer.d.ts +3 -1
  422. package/dist/prompt-assembly/composer.js +1 -1
  423. package/dist/prompt-assembly/event-registry.js +1 -0
  424. package/dist/prompt-assembly/overlay.js +3 -3
  425. package/dist/prompt-assembly/renderers.d.ts +1 -1
  426. package/dist/prompt-assembly/renderers.js +0 -3
  427. package/dist/prompt-assembly/role-base.d.ts +15 -0
  428. package/dist/prompt-assembly/role-base.js +9 -0
  429. package/dist/prompt-assembly/select.d.ts +39 -14
  430. package/dist/prompt-assembly/select.js +47 -16
  431. package/dist/prompt-assembly/sugar.d.ts +17 -11
  432. package/dist/prompt-assembly/sugar.js +8 -3
  433. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  434. package/dist/prompt-assembly/tool-catalog.js +114 -4
  435. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  436. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  437. package/dist/prompt-assembly/types.d.ts +0 -7
  438. package/dist/scenarios/full-body.d.ts +11 -11
  439. package/dist/scenarios/full-body.js +4 -3
  440. package/dist/shell/lex.js +10 -1
  441. package/dist/stores/file/adoption/adopt.js +4 -3
  442. package/dist/stores/file/adoption/marker.js +3 -2
  443. package/dist/stores/file/checkpoint-store.d.ts +21 -4
  444. package/dist/stores/file/checkpoint-store.js +38 -7
  445. package/dist/stores/file/file-history-store.js +18 -11
  446. package/dist/stores/file/index.js +2 -1
  447. package/dist/stores/file/mailbox-store.d.ts +2 -1
  448. package/dist/stores/file/mailbox-store.js +26 -1
  449. package/dist/stores/file/permission-rule-adopt.js +4 -3
  450. package/dist/stores/file/permission-rule-store.js +11 -5
  451. package/dist/stores/file/session-store.d.ts +29 -6
  452. package/dist/stores/file/session-store.js +42 -50
  453. package/dist/tools/artifact/artifact-tool.js +3 -2
  454. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  455. package/dist/tools/fs/bash-program-position.js +56 -9
  456. package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
  457. package/dist/tools/fs/bash-readonly-classifier.js +5 -10
  458. package/dist/tools/fs/fs-bash.js +15 -8
  459. package/dist/tools/fs/fs-glob.d.ts +86 -0
  460. package/dist/tools/fs/fs-glob.js +226 -0
  461. package/dist/tools/fs/fs-read.js +14 -14
  462. package/dist/tools/fs/fs-search-tools.js +7 -7
  463. package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
  464. package/dist/tools/fs/pattern-kill-guard.js +429 -0
  465. package/dist/tools/fs/pdf.d.ts +9 -6
  466. package/dist/tools/fs/pdf.js +3 -3
  467. package/dist/tools/fs/program-read-model.d.ts +57 -7
  468. package/dist/tools/fs/program-read-model.js +11 -1
  469. package/dist/tools/fs/program-read-model.rows.js +78 -21
  470. package/dist/tools/fs/read-deny-home.js +3 -2
  471. package/dist/tools/fs/removal-targets.d.ts +17 -7
  472. package/dist/tools/fs/removal-targets.js +47 -20
  473. package/dist/tools/fs/search.d.ts +10 -0
  474. package/dist/tools/fs/search.js +20 -26
  475. package/dist/tools/fs/shell-read-argv.js +89 -12
  476. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  477. package/dist/tools/fs/shell-read-bindings.js +41 -0
  478. package/dist/tools/fs/shell-read-check.d.ts +10 -0
  479. package/dist/tools/fs/shell-read-check.js +13 -20
  480. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  481. package/dist/tools/fs/shell-read-environment.js +3 -2
  482. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  483. package/dist/tools/fs/shell-read-establish.js +19 -20
  484. package/dist/tools/fs/shell-read-identity.d.ts +12 -9
  485. package/dist/tools/fs/shell-read-identity.js +9 -4
  486. package/dist/tools/fs/shell-read-plan.js +24 -16
  487. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  488. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  489. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  490. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  491. package/dist/tools/fs/shell-reentry-text.js +40 -2
  492. package/dist/tools/todo.js +63 -63
  493. package/dist/tools/web.d.ts +19 -14
  494. package/dist/tools/web.js +46 -61
  495. package/package.json +1 -1
  496. package/test/export-surface.snapshot.json +221 -7
  497. package/wire-changes/core-stores-sql@7.57.0.json +29 -0
  498. package/wire-changes/core@7.56.0.json +3891 -0
  499. package/wire-changes/core@7.57.0.json +1487 -0
  500. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  501. package/wire-changes/mods-kernel@7.57.0.json +29 -0
  502. package/wire-changes/primitives@7.57.0.json +245 -0
@@ -1,8 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { homedir } from "node:os";
3
3
  import { argsReadFrom, carryArgsReadFrom, withArgsReading } from "./effective-path-target.js";
4
+ import { editRewrittenSentence, readRejudge, rewriteChasedSentence } from "./rewrite-rejudge.js";
4
5
  import { brandPolicyAskClass } from "./ask-class.js";
5
6
  import { decisionAskClassesOf, headlessDenialMessage } from "./ask-origin.js";
7
+ import { attest, attestationOf, isEngineAttestation, mergeAttestation, mintAttestation, withAttestation } from "./engine-attestation.js";
6
8
  import { ownReadRootCandidate, readRootGrantSeat } from "./read-root-grant-screen.js";
7
9
  import { decidersNote, settledByDecider } from "./gate-outcome.js";
8
10
  import { unjudgedAllowRefused } from "./real-approval.js";
@@ -10,6 +12,7 @@ export { policyCannotAnswer, rowDemandsAPerson } from "./real-approval.js";
10
12
  import { sanitizeAutoModeArmingRecipe } from "./auto-mode-arming.js";
11
13
  import { join, normalize as normalizePath, sep } from "node:path";
12
14
  import { BASH_READONLY_DEFAULT_ALLOW, parseLeadingCommandName } from "../tools/fs/index.js";
15
+ import { readOnlyShellVerdict } from "./read-only-shell.js";
13
16
  import { protectivePathTargetOf, shellFaceToolNames } from "./tool-registry.js";
14
17
  import { heldBy } from "./tool-name-readings.js";
15
18
  import { bindableValueOf, boundInputHashOf, describeBindingFault, exactBoundInputHashOf } from "./canonical-json.js";
@@ -19,9 +22,9 @@ import { egressText, egressThrownText } from "./untrusted-egress.js";
19
22
  import { assertNoRetiredKeys, assertNoRetiredToolPolicyKeys, RETIRED_DECISION_MEMBERS, RETIRED_TOOL_POLICY_KEYS } from "./retired-keys.js";
20
23
  import { DECISION_MEMBER_ARMS, isEngineRefusal, nestedRecordsOf, receiveContract, receiveNestedRecords, refusedOutOfContract, screenContractValues } from "./decision-receipt.js";
21
24
  export { isEngineRefusal } from "./decision-receipt.js";
22
- import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "./permission-rules.js";
25
+ import { isCoveringRuleName, ruleNameCovers } from "./namespaced-rule-name.js";
23
26
  import { ruleContentOf } from "./permission-rule-model.js";
24
- import { wildcardPeerRefusalOf } from "./tool-name-aliases.js";
27
+ import { grantWildcardRefusalOf } from "./tool-name-aliases.js";
25
28
  import { ruleSpellingOf } from "./permission-rule-syntax.js";
26
29
  import { protocolOf } from "./protocol-table.js";
27
30
  import { anchorSpelling, isAbsoluteForFamily, normalizeAbsPathLexically, pathFamilyOf, writeTargetPath } from "../tools/fs/safety.js";
@@ -37,75 +40,7 @@ export function exemptRootsSeat(exemptRoots) {
37
40
  function settledByNobody(kind) {
38
41
  return { kind, who: { party: "none" }, when: Date.now() };
39
42
  }
40
- const ATTESTATION_GROUP_OF = {
41
- settlement: "answer",
42
- origin: "answer",
43
- classes: "answer",
44
- inputDigest: "answer",
45
- classifierCause: "classifierCause",
46
- classifierRound: "classifierRound",
47
- unresolvableCause: "unresolvableCause",
48
- foldedClasses: "foldedClasses",
49
- pathDenial: "pathDenial",
50
- bindingRefusal: "bindingRefusal",
51
- };
52
- const ATTESTATION_MEMBERS = Object.keys(ATTESTATION_GROUP_OF);
53
- const groupLead = (g) => ATTESTATION_MEMBERS.find((k) => ATTESTATION_GROUP_OF[k] === g);
54
- const ENGINE_ATTESTATIONS = new WeakSet();
55
- function detachedMember(v) {
56
- if (Array.isArray(v))
57
- return Object.freeze([...v]);
58
- if (typeof v !== "object" || v === null)
59
- return v;
60
- return Object.freeze(Object.fromEntries(Object.entries(v).map(([k, x]) => [k, typeof x === "object" && x !== null ? Object.freeze(Array.isArray(x) ? [...x] : { ...x }) : x])));
61
- }
62
- export function mintAttestation(call, members) {
63
- const record = { toolCallId: call.toolCallId, toolName: call.toolName };
64
- for (const k of ATTESTATION_MEMBERS)
65
- if (members[k] !== undefined)
66
- record[k] = detachedMember(members[k]);
67
- const minted = Object.freeze(record);
68
- ENGINE_ATTESTATIONS.add(minted);
69
- return minted;
70
- }
71
- export function isEngineAttestation(v) {
72
- return typeof v === "object" && v !== null && ENGINE_ATTESTATIONS.has(v);
73
- }
74
- const boundTo = (r, call) => isEngineAttestation(r) && r.toolCallId === call.toolCallId && r.toolName === call.toolName ? r : undefined;
75
- export function attestationOf(d, call) {
76
- if (typeof d !== "object" || d === null)
77
- return undefined;
78
- return boundTo(Object.getOwnPropertyDescriptor(d, "attestation")?.value, call);
79
- }
80
- export function mergeAttestation(call, earlier, later, scope = "all") {
81
- const a = boundTo(earlier, call);
82
- const b = boundTo(later, call);
83
- if (a === undefined)
84
- return b;
85
- const members = {};
86
- if (b !== undefined)
87
- for (const k of ATTESTATION_MEMBERS)
88
- if (b[k] !== undefined)
89
- members[k] = b[k];
90
- let filled = false;
91
- for (const g of new Set(Object.values(ATTESTATION_GROUP_OF))) {
92
- if ((scope === "answer" && g !== "answer") || members[groupLead(g)] !== undefined || a[groupLead(g)] === undefined)
93
- continue;
94
- for (const k of ATTESTATION_MEMBERS)
95
- if (ATTESTATION_GROUP_OF[k] === g && a[k] !== undefined)
96
- members[k] = a[k];
97
- filled = true;
98
- }
99
- if (!filled)
100
- return b;
101
- return mintAttestation(call, members);
102
- }
103
- export function attest(d, call, members) {
104
- return withAttestation(d, mergeAttestation(call, attestationOf(d, call), mintAttestation(call, members)));
105
- }
106
- export function withAttestation(d, record) {
107
- return record === undefined ? d : { ...d, attestation: record };
108
- }
43
+ export { attest, attestationOf, isEngineAttestation, mergeAttestation, mintAttestation, withAttestation } from "./engine-attestation.js";
109
44
  const UNASKED_SEAT_SETTLEMENTS = new Set(["task_aborted", "no_approver"]);
110
45
  function seatNeverAsked(settlement) {
111
46
  return settlement !== undefined && UNASKED_SEAT_SETTLEMENTS.has(settlement.kind);
@@ -196,21 +131,11 @@ export function toolPolicyWriteGuardRows(policies) {
196
131
  return undefined;
197
132
  return async (at) => (await Promise.all(sources.map((rowsOf) => rowsOf(at)))).flat();
198
133
  }
199
- export function namespacedCoveringEntries(entries, behavior) {
200
- return (entries ?? []).filter((entry) => isNamespacedCoveringRuleName(entry, behavior));
134
+ export function coveringRuleEntries(entries, behavior) {
135
+ return (entries ?? []).filter((entry) => isCoveringRuleName(entry, behavior));
201
136
  }
202
- function allowlistNameRefusal(who, entry, list) {
203
- if (typeof entry !== "string")
204
- return undefined;
205
- const sentence = wildcardPeerRefusalOf(ruleSpellingOf(entry)?.toolName ?? entry, "allow");
206
- if (sentence === undefined)
207
- return undefined;
208
- const e = new Error(`${who}: ${list} entry "${entry}" — ${sentence}`);
209
- e.code = "config.invalid_tool_name_set";
210
- return e;
211
- }
212
- export function namespacedCoveringHit(covering, call) {
213
- return covering.length > 0 && nameListHolds({ has: (name) => covering.some((e) => namespacedRuleNameCovers(e, name)) }, call);
137
+ export function coveringRuleHit(covering, call) {
138
+ return covering.length > 0 && nameListHolds({ has: (name) => covering.some((e) => ruleNameCovers(e, name)) }, call);
214
139
  }
215
140
  export function projectionToolNames(c) {
216
141
  return c.kind === "shell_command" ? { member: "tools", list: c.tools } : { member: "names", list: c.names };
@@ -219,13 +144,13 @@ export function checkToolPolicyProjection(projection, req) {
219
144
  const listed = (list) => heldBy("policy.projectionReplay", { has: (n) => list.includes(n) }, req);
220
145
  for (const c of projection.components) {
221
146
  if (c.kind === "tool_deny") {
222
- if (listed(c.names) || namespacedCoveringHit(namespacedCoveringEntries(c.names, "deny"), req)) {
147
+ if (listed(c.names) || coveringRuleHit(coveringRuleEntries(c.names, "deny"), req)) {
223
148
  return { action: "deny", message: `tool "${req.toolName}" is denied by a frozen inherited policy projection` };
224
149
  }
225
150
  continue;
226
151
  }
227
152
  if (c.kind === "tool_allowlist") {
228
- if (!listed(c.names) && !namespacedCoveringHit(namespacedCoveringEntries(c.names, "allow"), req)) {
153
+ if (!listed(c.names) && !coveringRuleHit(coveringRuleEntries(c.names, "allow"), req)) {
229
154
  return { action: "deny", message: `tool "${req.toolName}" is not in a frozen inherited policy projection's allowlist` };
230
155
  }
231
156
  continue;
@@ -300,6 +225,12 @@ const HOOK_SEAM_UNREAD = new Set(["decisionReason"]);
300
225
  const HOOK_SEAM_OPTIONAL = new Set(["action"]);
301
226
  const HOOK_RECEIPTS = new WeakSet();
302
227
  const ENGINE_RECEIPTS = new WeakSet();
228
+ function askOfAnotherCall(d, call) {
229
+ if (call === undefined || d.action !== "ask" || d.attestation === undefined || attestationOf(d, call) !== undefined)
230
+ return undefined;
231
+ return refusedOutOfContract(`a permission decision asks with the engine's record of another call — what the engine found about that call's question is not this call's; ` +
232
+ `a policy answers the call it is asked about (a cached or relayed ask is asked again); denied fail-closed rather than reading the findings as absent`);
233
+ }
303
234
  export function refuseOutOfContractDecision(d, opts) {
304
235
  const hookSeam = opts?.reasonIsNonInput === true;
305
236
  if (hookSeam && (d === null || d === undefined || Object.is(d, false)))
@@ -308,7 +239,7 @@ export function refuseOutOfContractDecision(d, opts) {
308
239
  return refusedOutOfContract(`a permission decision's "action" is absent (the decision is ${d === null || d === undefined ? String(d) : `a ${typeof d}`}, not an object) — the closed set is allow/deny/ask; denied fail-closed rather than reading a word outside it as an allow`);
309
240
  }
310
241
  if ((hookSeam ? HOOK_RECEIPTS : ENGINE_RECEIPTS).has(d) || isEngineRefusal(d))
311
- return d;
242
+ return askOfAnotherCall(d, opts?.call) ?? d;
312
243
  const decision = receiveContract(d, hookSeam ? HOOK_RESULT_MEMBERS : DECISION_MEMBERS, "", RETIRED_DECISION_MEMBERS);
313
244
  if (decision.kind === "refused")
314
245
  return decision.refused;
@@ -323,13 +254,9 @@ export function refuseOutOfContractDecision(d, opts) {
323
254
  : `a permission decision carries an "attestation" the engine did not mint — the member is an engine record (who settled the call, ` +
324
255
  `which question it answered); denied fail-closed rather than reading a caller's value as a settlement`);
325
256
  }
326
- const folded = contract.foldedAskClasses;
327
- const signed = attestation?.foldedClasses;
328
- if (folded !== undefined && !(signed !== undefined && Array.isArray(folded) && signed.length === folded.length && signed.every((c, i) => c === folded[i]))) {
329
- return refusedOutOfContract(`a permission decision carries "foldedAskClasses" that no policy fold of the engine attested on it — the member is ` +
330
- `engine-written (combinePolicies records the classes of the asks it collapsed); denied fail-closed rather than letting a ` +
331
- `class no station judged reach the class derivation`);
332
- }
257
+ const foreign = askOfAnotherCall({ action: contract.action, attestation }, opts?.call);
258
+ if (foreign !== undefined)
259
+ return foreign;
333
260
  if (hookSeam && contract.additionalContext !== undefined && typeof contract.additionalContext !== "string") {
334
261
  return refusedOutOfContract(`a PreToolUse hook result's "additionalContext" is not a string — the member is the text appended for the model; denied fail-closed rather than rendering a value this layer cannot classify`);
335
262
  }
@@ -387,86 +314,75 @@ export function toolPolicyNameSets(p) {
387
314
  const sets = p?.nameSets;
388
315
  return Array.isArray(sets) ? sets : [];
389
316
  }
390
- export function createAllowDenyPolicy(opts) {
391
- assertNoRetiredKeys(opts, RETIRED_ALLOW_DENY_POLICY_OPTIONS, "createAllowDenyPolicy");
392
- const invalid = [];
393
- const screen = (entries, list) => {
394
- if (entries === undefined)
395
- return undefined;
396
- const kept = [];
397
- const seen = new Set();
398
- for (const entry of entries) {
399
- const ns = protocolOf(entry);
400
- if (ns !== undefined) {
401
- const suffix = entry.slice(ns.prefix.length);
402
- const sep = suffix.indexOf("__");
403
- const malformed = suffix.length === 0 || sep === 0 || (sep > 0 && suffix.length === sep + 2);
404
- if (malformed) {
405
- const family = ns.id.toUpperCase();
406
- const lesson = `a malformed ${family} tool name (empty peer or tool segment) — it can never match any mounted tool. ` +
407
- `Use \`${ns.prefix}<peer>\` for every tool of a peer, or \`${ns.prefix}<peer>__<tool>\` for one tool.`;
408
- invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
409
- continue;
410
- }
411
- }
412
- const spelled = ruleSpellingOf(entry);
413
- if (spelled === undefined) {
414
- const lesson = `a spelling no tool name can have — the rule syntax reads no tool name in it, so a name set never names a tool by it. Fix the entry.`;
317
+ function screenToolNameList(entries, list, behavior, invalid) {
318
+ if (entries === undefined)
319
+ return undefined;
320
+ const kept = [];
321
+ const seen = new Set();
322
+ for (const entry of entries) {
323
+ const ns = protocolOf(entry);
324
+ if (ns !== undefined) {
325
+ const suffix = entry.slice(ns.prefix.length);
326
+ const sep = suffix.indexOf("__");
327
+ if (suffix.length === 0 || sep === 0 || (sep > 0 && suffix.length === sep + 2)) {
328
+ const lesson = `a malformed ${ns.id.toUpperCase()} tool name (empty peer or tool segment) — it can never match any mounted tool. ` +
329
+ `Use \`${ns.prefix}<peer>\` for every tool of a peer, or \`${ns.prefix}<peer>__<tool>\` for one tool.`;
415
330
  invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
416
331
  continue;
417
332
  }
418
- if (ruleContentOf(spelled) === undefined) {
419
- if (spelled.toolName === "*" && list === "deny") {
420
- const lesson = `the wildcard — \`*\` names no tool, and a deny entry reaches the tool it names, so this one would be kept and never match ` +
421
- `(a deny that reads protective and denies nothing). Name the tools to deny; to leave a run no tools, write an empty allow list.`;
422
- invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
423
- continue;
424
- }
425
- const wild = list === "allow" ? wildcardPeerRefusalOf(spelled.toolName, "allow") : undefined;
426
- if (wild !== undefined) {
427
- invalid.push({ entry, list, message: `"${entry}": ${wild}`, lesson: wild });
428
- continue;
429
- }
430
- if (!seen.has(spelled.toolName)) {
431
- seen.add(spelled.toolName);
432
- kept.push(spelled.toolName);
433
- }
434
- continue;
435
- }
333
+ }
334
+ const spelled = ruleSpellingOf(entry);
335
+ if (spelled === undefined) {
336
+ const lesson = `a spelling no tool name can have — the rule syntax reads no tool name in it, so a name set never names a tool by it. Fix the entry.`;
337
+ invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
338
+ continue;
339
+ }
340
+ if (ruleContentOf(spelled) !== undefined) {
436
341
  const lesson = `a rule CONTENT form, not a tool name — a name set matches raw tool names, so this entry ` +
437
342
  `can never match any mounted tool (in an allow list it removes the tool entirely). Use the tool NAME here, ` +
438
343
  `and route the narrowing through the lane that speaks this grammar: parameter rules via ` +
439
344
  `createPermissionRulePolicy, Bash command prefixes via the persisted allow-rule lane.`;
440
345
  invalid.push({ entry, list, message: `"${entry}" is ${lesson}`, lesson });
346
+ continue;
441
347
  }
442
- return kept;
443
- };
444
- const screenedAllow = screen(opts.allow, "allow");
445
- const screenedDeny = screen(opts.deny, "deny");
446
- if (invalid.length > 0) {
447
- if ((opts.onInvalidName ?? "throw") === "throw") {
448
- const byLesson = new Map();
449
- for (const i of invalid) {
450
- const group = byLesson.get(i.lesson) ?? [];
451
- group.push({ entry: i.entry, list: i.list });
452
- byLesson.set(i.lesson, group);
453
- }
454
- const e = new Error(`createAllowDenyPolicy: ${invalid.length} entr${invalid.length === 1 ? "y is" : "ies are"} not tool name(s):\n` +
455
- [...byLesson.entries()]
456
- .map(([lesson, group]) => ` Each of the following is ${lesson}\n` + group.map((g) => ` [${g.list}] "${g.entry}"`).join("\n"))
457
- .join("\n"));
458
- e.code = "config.invalid_tool_name_set";
459
- e.issues = invalid;
460
- throw e;
348
+ const wild = behavior === "allow" ? grantWildcardRefusalOf(spelled.toolName) : undefined;
349
+ if (wild !== undefined) {
350
+ invalid.push({ entry, list, message: `"${entry}": ${wild}`, lesson: wild });
351
+ continue;
461
352
  }
353
+ if (!seen.has(spelled.toolName)) {
354
+ seen.add(spelled.toolName);
355
+ kept.push(spelled.toolName);
356
+ }
357
+ }
358
+ return kept;
359
+ }
360
+ function toolNameSetRefusal(who, invalid) {
361
+ const byLesson = new Map();
362
+ for (const i of invalid)
363
+ byLesson.set(i.lesson, [...(byLesson.get(i.lesson) ?? []), { entry: i.entry, list: i.list }]);
364
+ const e = new Error(`${who}: ${invalid.length} entr${invalid.length === 1 ? "y is" : "ies are"} not tool name(s):\n` +
365
+ [...byLesson.entries()].map(([lesson, group]) => ` Each of the following is ${lesson}\n` + group.map((g) => ` [${g.list}] "${g.entry}"`).join("\n")).join("\n"));
366
+ e.code = "config.invalid_tool_name_set";
367
+ e.issues = invalid;
368
+ return e;
369
+ }
370
+ export function createAllowDenyPolicy(opts) {
371
+ assertNoRetiredKeys(opts, RETIRED_ALLOW_DENY_POLICY_OPTIONS, "createAllowDenyPolicy");
372
+ const invalid = [];
373
+ const screenedAllow = screenToolNameList(opts.allow, "allow", "allow", invalid);
374
+ const screenedDeny = screenToolNameList(opts.deny, "deny", "deny", invalid);
375
+ if (invalid.length > 0) {
376
+ if ((opts.onInvalidName ?? "throw") === "throw")
377
+ throw toolNameSetRefusal("createAllowDenyPolicy", invalid);
462
378
  for (const issue of invalid)
463
379
  opts.onInvalidNameIssue?.(issue);
464
380
  }
465
381
  opts = { ...opts, ...(screenedAllow ? { allow: screenedAllow } : {}), ...(screenedDeny ? { deny: screenedDeny } : {}) };
466
382
  const allow = opts.allow ? new Set(opts.allow) : undefined;
467
383
  const deny = new Set(opts.deny ?? []);
468
- const denyCovering = namespacedCoveringEntries(opts.deny, "deny");
469
- const allowCovering = namespacedCoveringEntries(opts.allow, "allow");
384
+ const denyCovering = coveringRuleEntries(opts.deny, "deny");
385
+ const allowCovering = coveringRuleEntries(opts.allow, "allow");
470
386
  return {
471
387
  projection: {
472
388
  components: [
@@ -477,10 +393,10 @@ export function createAllowDenyPolicy(opts) {
477
393
  },
478
394
  nameSets: [{ ...(opts.allow ? { allow: [...opts.allow] } : {}), ...(opts.deny ? { deny: [...opts.deny] } : {}) }],
479
395
  check(req) {
480
- if (nameListHolds(deny, req) || namespacedCoveringHit(denyCovering, req)) {
396
+ if (nameListHolds(deny, req) || coveringRuleHit(denyCovering, req)) {
481
397
  return { action: "deny", message: `tool "${req.toolName}" is denied by policy` };
482
398
  }
483
- if (allow && !nameListHolds(allow, req) && !namespacedCoveringHit(allowCovering, req)) {
399
+ if (allow && !nameListHolds(allow, req) && !coveringRuleHit(allowCovering, req)) {
484
400
  return { action: "deny", message: `tool "${req.toolName}" is not in the allowlist` };
485
401
  }
486
402
  return ALLOW;
@@ -497,19 +413,21 @@ export function createApprovalPolicy(opts) {
497
413
  if (opts.approvalTimeoutMs !== undefined && opts.approvalTimeoutMs > 2_147_483_647) {
498
414
  throw new Error(`createApprovalPolicy: approvalTimeoutMs must not exceed 2147483647ms (~24.8 days) (got ${opts.approvalTimeoutMs}) — a host timer truncates a larger delay and fires immediately, denying every request at once; omit it to wait indefinitely`);
499
415
  }
500
- for (const [list, entries] of [["autoAllow", opts.autoAllow ?? []], ["requireApproval", opts.denyByDefault === true ? opts.requireApproval : []]]) {
501
- for (const entry of entries) {
502
- const refusal = allowlistNameRefusal("createApprovalPolicy", entry, list);
503
- if (refusal !== undefined)
504
- throw refusal;
505
- }
506
- }
416
+ const invalid = [];
417
+ const requireApproval = screenToolNameList(opts.requireApproval, "requireApproval", "ask", invalid) ?? [];
418
+ const denied = screenToolNameList(opts.deny, "deny", "deny", invalid);
419
+ const autoAllow = screenToolNameList(opts.autoAllow, "autoAllow", "allow", invalid);
420
+ if (opts.denyByDefault === true)
421
+ screenToolNameList(requireApproval, "requireApproval", "allow", invalid);
422
+ if (invalid.length > 0)
423
+ throw toolNameSetRefusal("createApprovalPolicy", invalid);
424
+ opts = { ...opts, requireApproval, ...(denied !== undefined ? { deny: denied } : {}), ...(autoAllow !== undefined ? { autoAllow } : {}) };
507
425
  const need = new Set(opts.requireApproval);
508
426
  const deny = new Set(opts.deny ?? []);
509
427
  const auto = new Set(opts.autoAllow ?? []);
510
- const needCovering = namespacedCoveringEntries(opts.requireApproval, "ask");
511
- const denyCovering = namespacedCoveringEntries(opts.deny, "deny");
512
- const autoCovering = namespacedCoveringEntries(opts.autoAllow, "allow");
428
+ const needCovering = coveringRuleEntries(opts.requireApproval, "ask");
429
+ const denyCovering = coveringRuleEntries(opts.deny, "deny");
430
+ const autoCovering = coveringRuleEntries(opts.autoAllow, "allow");
513
431
  return {
514
432
  projection: {
515
433
  components: [
@@ -526,10 +444,10 @@ export function createApprovalPolicy(opts) {
526
444
  },
527
445
  ],
528
446
  async check(req, signal) {
529
- if (nameListHolds(deny, req) || namespacedCoveringHit(denyCovering, req)) {
447
+ if (nameListHolds(deny, req) || coveringRuleHit(denyCovering, req)) {
530
448
  return { action: "deny", message: `tool "${req.toolName}" is denied by policy` };
531
449
  }
532
- if (nameListHolds(need, req) || namespacedCoveringHit(needCovering, req)) {
450
+ if (nameListHolds(need, req) || coveringRuleHit(needCovering, req)) {
533
451
  const attestOver = (inputDigest) => (d, settlement, bindingRefusal) => ({ ...d, attestation: mintAttestation(req, { settlement, origin: "policy", ...(inputDigest !== undefined ? { inputDigest } : {}), ...(bindingRefusal !== undefined ? { bindingRefusal } : {}) }) });
534
452
  const unasked = unaskedSeatAnswer(req, signal, { aborted: `approval aborted for "${req.toolName}" (run or turn interrupted)`, unreachable: `approval for "${req.toolName}" was not requested: nobody can be asked about this call` }, "policy");
535
453
  if (unasked !== undefined)
@@ -592,7 +510,7 @@ export function createApprovalPolicy(opts) {
592
510
  }
593
511
  return attest({ action: "deny", message: `approval denied for "${req.toolName}"` }, settledByDecider("person", "refused", undefined));
594
512
  }
595
- if (nameListHolds(auto, req) || namespacedCoveringHit(autoCovering, req))
513
+ if (nameListHolds(auto, req) || coveringRuleHit(autoCovering, req))
596
514
  return ALLOW;
597
515
  if (opts.denyByDefault) {
598
516
  return { action: "deny", message: `tool "${req.toolName}" requires explicit allow` };
@@ -636,7 +554,6 @@ export function combinePolicies(...policies) {
636
554
  let asked;
637
555
  let current = Object.freeze({ ...req });
638
556
  let rewrite;
639
- let records;
640
557
  let ruleAskText;
641
558
  let probeMandateSeen = false;
642
559
  let mandateSeen = false;
@@ -644,25 +561,64 @@ export function combinePolicies(...policies) {
644
561
  let noRulingSeen;
645
562
  let authoredBySeen = false;
646
563
  const contributors = [];
647
- const settleDeny = (d) => {
564
+ const decisions = [];
565
+ const recordsExcept = (at) => decisions.reduce((acc, d, j) => (j !== at && d?.action === "allow" && d.attestation !== undefined ? mergeAttestation(req, acc, d.attestation) : acc), undefined);
566
+ const settleDeny = (d, at) => {
648
567
  const out = rewrite !== undefined ? refusalOf(d, current.args) : d;
568
+ const records = recordsExcept(at);
649
569
  if (records === undefined)
650
570
  return out;
651
571
  return { ...out, attestation: mergeAttestation(req, records, d.attestation) };
652
572
  };
653
573
  let seatDeny;
654
- for (const p of policies) {
655
- const d = refuseOutOfContractDecision(await p.check(current, signal));
574
+ const denied = (d, at) => {
575
+ decisions[at] = undefined;
576
+ if (!seatNeverAsked(attestationOf(d, current)?.settlement))
577
+ return settleDeny(d, at);
578
+ seatDeny ??= settleDeny(d, at);
579
+ return undefined;
580
+ };
581
+ let emitter = -1;
582
+ let personWrote = false;
583
+ for (const [at, p] of policies.entries()) {
584
+ const d = refuseOutOfContractDecision(await p.check(current, signal), { call: req });
656
585
  if (d.action === "deny") {
657
- if (!seatNeverAsked(attestationOf(d, current)?.settlement))
658
- return settleDeny(d);
659
- seatDeny ??= settleDeny(d);
586
+ const ended = denied(d, at);
587
+ if (ended !== undefined)
588
+ return ended;
660
589
  continue;
661
590
  }
662
- if (d.updatedInput !== undefined) {
591
+ decisions[at] = d;
592
+ if (readRejudge(current, current.args, d).kind === "rewritten") {
593
+ if (personWrote)
594
+ return settleDeny({ action: "deny", message: `${editRewrittenSentence(req.toolName)}, which a later policy layer wrote over a person's edit — denied fail-closed` }, at);
663
595
  current = Object.freeze(await withArgsReading(current, d.updatedInput, signal));
664
596
  rewrite = d;
597
+ emitter = at;
598
+ personWrote = attestationOf(d, current)?.settlement?.who.party === "person" && answeredFor(d, req, current.args);
599
+ }
600
+ }
601
+ for (let at = 0; at < emitter; at++) {
602
+ const p = policies[at];
603
+ const d = refuseOutOfContractDecision(await p.check(current, signal), { call: req });
604
+ if (d.action === "deny") {
605
+ const ended = denied(d, at);
606
+ if (ended !== undefined)
607
+ return ended;
608
+ continue;
665
609
  }
610
+ if (readRejudge(current, current.args, d).kind === "rewritten")
611
+ return settleDeny({ action: "deny", message: rewriteChasedSentence(req.toolName) }, at);
612
+ const { updatedInput: _sameBytes, ...asIs } = d;
613
+ const first = decisions[at];
614
+ decisions[at] = asIs.action === "allow" && first?.action === "allow" && first.attestation !== undefined ? withAttestation(asIs, mergeAttestation(req, first.attestation, asIs.attestation)) : asIs;
615
+ }
616
+ if (seatDeny !== undefined)
617
+ return seatDeny;
618
+ let records;
619
+ for (const d of decisions) {
620
+ if (d === undefined)
621
+ continue;
666
622
  if (d.action === "allow" && d.attestation !== undefined)
667
623
  records = mergeAttestation(req, records, d.attestation);
668
624
  if (d.action === "ask" && (asked === undefined || (d.requiresRealApproval === true && asked.requiresRealApproval !== true))) {
@@ -684,8 +640,6 @@ export function combinePolicies(...policies) {
684
640
  if (d.action === "ask")
685
641
  contributors.push(d);
686
642
  }
687
- if (seatDeny !== undefined)
688
- return seatDeny;
689
643
  if (asked) {
690
644
  const merged = rewrite?.updatedInput;
691
645
  const withRuleAsk = ruleAskText !== undefined && asked.matchedAskRule === undefined ? { ...asked, matchedAskRule: ruleAskText } : asked;
@@ -694,16 +648,15 @@ export function combinePolicies(...policies) {
694
648
  const withFallback = fallbackSeen !== undefined && withMandate.denialLimitFallback === undefined ? { ...withMandate, denialLimitFallback: fallbackSeen, requiresRealApproval: true } : withMandate;
695
649
  const withNoRuling = noRulingSeen !== undefined && withFallback.classifierNoRuling === undefined ? { ...withFallback, classifierNoRuling: noRulingSeen, requiresRealApproval: true } : withFallback;
696
650
  const withAuthor = authoredBySeen && withNoRuling.authoredBy === undefined ? { ...withNoRuling, authoredBy: "deployment" } : withNoRuling;
697
- const folded = new Set(withAuthor.foldedAskClasses ?? []);
651
+ const folded = new Set(attestationOf(asked, req)?.foldedClasses ?? []);
698
652
  for (const c of contributors)
699
653
  if (c !== asked)
700
- for (const k of decisionAskClassesOf(c))
654
+ for (const k of decisionAskClassesOf(c, req))
701
655
  folded.add(k);
702
656
  if (withNoRuling !== withMandate)
703
- for (const k of decisionAskClassesOf(asked))
657
+ for (const k of decisionAskClassesOf(asked, req))
704
658
  folded.add(k);
705
- const withClasses = folded.size > 0 ? { ...withAuthor, foldedAskClasses: [...folded] } : withAuthor;
706
- const out = merged !== undefined ? { ...withClasses, updatedInput: merged } : withClasses;
659
+ const out = merged !== undefined ? { ...withAuthor, updatedInput: merged } : withAuthor;
707
660
  return folded.size > 0 ? attest(out, req, { foldedClasses: [...folded] }) : out;
708
661
  }
709
662
  const allowed = rewrite ?? ALLOW;
@@ -780,17 +733,17 @@ export function createUnverifiableDeletePolicy(opts) {
780
733
  if (typeof command !== "string")
781
734
  return ALLOW;
782
735
  const removal = removalReadingOf(command, req, opts?.removalSeat, safeRoots);
783
- return removal === undefined ? ALLOW : removal.judge(signal).then((found) => (found === undefined ? ALLOW : removalAsk(found.guard, found.text)));
736
+ return removal === undefined ? ALLOW : removal.judge(signal).then((found) => (found === undefined ? ALLOW : removalAsk(req, found.guard, found.text)));
784
737
  },
785
738
  }, "external_authority");
786
739
  }
787
- function removalAsk(guard, text) {
740
+ function removalAsk(req, guard, text) {
788
741
  const messages = {
789
742
  dangerous_delete: `Dangerous removal: ${text}. No permission mode, allow rule or classifier clears this — only a person confirming this call does.`,
790
743
  unverifiable_delete: `Unverifiable recursive delete (fail-closed unless cleared): ${text}. Re-run the delete with the resolved literal path written into the command itself (or assign the variable a literal path in the same command, e.g. \`DIR=/exact/path; rm -rf "$DIR"\`) so the target can be verified.`,
791
- unverifiable_shell_text: `Unverifiable shell text (fail-closed unless cleared): ${text}. Write the text into the command itself (a \`-c\` string, a here-document or a here-string) and the engine reads it as it reads any command.`,
744
+ unverifiable_shell_text: `Unverifiable shell text (fail-closed unless cleared): ${text}.`,
792
745
  };
793
- return { action: "ask", decisionReason: "safety", requiresRealApproval: true, guards: [guard], message: messages[guard] };
746
+ return attest({ action: "ask", decisionReason: "safety", requiresRealApproval: true, message: messages[guard] }, req, { guards: [guard] });
794
747
  }
795
748
  function pathSegments(p) {
796
749
  return p.split(/[\\/]/).filter(Boolean);
@@ -859,16 +812,15 @@ export function createTranscriptIntegrityPolicy(opts) {
859
812
  }
860
813
  return false;
861
814
  };
862
- const askReason = (what) => ({
815
+ const askReason = (req, what) => attest({
863
816
  action: "ask",
864
817
  decisionReason: "safety",
865
818
  requiresRealApproval: true,
866
- guards: ["transcript_write"],
867
819
  message: `Session-transcript write (fail-closed unless cleared): ${what}. Session transcripts (the .jsonl files ` +
868
820
  `under the agent data dir's sessions/ directory) are harness-written session state, not agent working ` +
869
821
  `files — modifying or deleting them tampers with the run's own audit trail. Reading them (ls/cat/grep ` +
870
822
  `as a single simple command) is fine.`,
871
- });
823
+ }, req, { guards: ["transcript_write"] });
872
824
  return brandPolicyAskClass({
873
825
  check(req) {
874
826
  if (shellToolsListHolds(shellTools, req)) {
@@ -879,20 +831,16 @@ export function createTranscriptIntegrityPolicy(opts) {
879
831
  const cwdInsideProtected = req.cwd !== undefined && inProtectedDir(req.cwd);
880
832
  if (!referencesProtectedDir(cmd) && !cwdInsideProtected)
881
833
  return ALLOW;
882
- const parsed = parseLeadingCommandName(command);
883
- if ("name" in parsed && readAllow.has(parsed.name))
834
+ const verdict = readOnlyShellVerdict(command, { cwd: req.cwd, readers: readAllow });
835
+ if (verdict.readOnly)
884
836
  return ALLOW;
885
- return askReason("name" in parsed
886
- ? `\`${parsed.name}\` is not a read-only command${cwdInsideProtected ? " and the shell's working directory is inside the transcript directory" : ""}`
887
- : cwdInsideProtected
888
- ? "the shell's working directory is inside the transcript directory and this is not a single read-only command (fail-closed)"
889
- : "the command references the transcript directory and is not a single read-only command (fail-closed)");
837
+ return askReason(req, `${cwdInsideProtected ? "the shell's working directory is inside the transcript directory" : "the command references the transcript directory"} and is not read-only: ${verdict.reason}`);
890
838
  }
891
839
  const writeTarget = protectivePathTargetOf(req);
892
840
  if (writeTarget !== undefined && writeTarget.access !== "read") {
893
841
  const p = writeTargetPath(req);
894
842
  if (typeof p === "string" && inProtectedDir(p, req.cwd)) {
895
- return askReason(`"${p}" is inside the session-transcript directory`);
843
+ return askReason(req, `"${p}" is inside the session-transcript directory`);
896
844
  }
897
845
  }
898
846
  return ALLOW;
@@ -6,6 +6,7 @@ import { deliverEngineNotice } from "./types.js";
6
6
  import { TOOL_SEARCH_NAME } from "./runner/tool-disclosure.js";
7
7
  import { mountRuleFace, toolFace } from "./tool-catalog-entries.js";
8
8
  import { thrownText } from "./thrown-value.js";
9
+ import { carryNotStartedReceipt } from "./delegation-not-started.js";
9
10
  export const TOOL_RESULT_REF_CONFLICT_CODE = "tool_result.ref_conflict";
10
11
  export class ToolResultRefConflictError extends Error {
11
12
  ref;
@@ -239,6 +240,8 @@ export function withToolResultOffload(tool, store, thresholdChars, sessionId, re
239
240
  const wrappedExecute = async (toolCallId, params, signal, onUpdate) => {
240
241
  const res = await tool.execute(toolCallId, params, signal, onUpdate);
241
242
  const offloadedDetails = res.details === undefined ? undefined : await offloadOversizedDetailStrings(res.details, store, thresholdChars, sessionId, toolCallId, provenance);
243
+ if (offloadedDetails !== undefined)
244
+ carryNotStartedReceipt(res.details, offloadedDetails.value);
242
245
  const withDetails = (r) => offloadedDetails === undefined || offloadedDetails.value === res.details ? r : { ...r, details: offloadedDetails.value };
243
246
  if (totalTextChars(res.content) <= thresholdChars)
244
247
  return withDetails(res);