@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
@@ -122,17 +122,26 @@ export declare function applyExtraBody(body: Record<string, unknown>, model: Pic
122
122
  export declare function lockHeader(headers: Record<string, string>, lowerName: string, value: string): void;
123
123
  /**
124
124
  * #343 (review r4) — case-fold READ-AND-CLAIM for an AUGMENTABLE structural header (`anthropic-beta`):
125
- * returns the current value under whatever spelling the user bag carried and deletes that spelling,
126
- * so the caller's canonical lowercase write REPLACES it instead of duplicating beside it (the
125
+ * returns the value under EVERY spelling the bag carried, in key order, and deletes them all, so the
126
+ * caller's canonical lowercase write REPLACES them instead of duplicating beside them (the
127
127
  * read-modify-write used to key the read by the exact lowercase name and miss `Anthropic-Beta`,
128
- * losing the user's betas from the merge AND double-sending the header).
128
+ * losing the user's betas from the merge AND double-sending the header). A spelling is claimed whatever
129
+ * it holds — its value is returned as it is, so a spelling holding `undefined` does not end the claim.
129
130
  */
130
- export declare function takeHeaderCasefold(headers: Record<string, string>, lowerName: string): string | undefined;
131
+ export declare function takeHeaderSpellings(headers: Record<string, string>, lowerName: string): unknown[];
132
+ /** The entries of a comma-list header value (`" a , b,,c"` → `a`, `b`, `c`); a value that is not a string carries none. */
133
+ export declare function headerListEntries(value: unknown): string[];
131
134
  /** A caller's header bag read ONCE, into a plain copy of its own enumerable entries — what a request build hands both
132
135
  * the route law (which credential rides, and its identity) and the merge (what goes on the wire), so a bag whose getters
133
136
  * or keys answer differently on a second read cannot be judged as one bag and sent as another. */
134
137
  export declare function headerBagOnce(bag: Readonly<Record<string, string>> | undefined): Record<string, string> | undefined;
135
138
  export declare function mergeHeaders(...bags: Array<Record<string, string> | undefined>): Record<string, string>;
139
+ /** The values a request is DECLARED with ({@link import("./stream-engine.js").SSERequest.declared}): every value of the header bags it was
140
+ * built from — the route's credential headers included, as the merge after `applyRouteCredentialHeaders` holds them — the values the
141
+ * deployment or the call stated outside a bag (a configured protocol version, each entry of a list header the brain re-folds), and the
142
+ * key when it names a secret ({@link namesASecret}: a placeholder key is left in the words as it is left to every child). The values the
143
+ * brain writes itself (a structural lock, the default version, the beta entries it chose) are not among them. */
144
+ export declare function declaredRequestValues(bags: ReadonlyArray<Readonly<Record<string, string>> | undefined>, stated: ReadonlyArray<string | undefined>, key: string | undefined): string[];
136
145
  /**
137
146
  * The output-cap key(s) each lane's wire form uses. A lane's set is exactly the keys THAT lane's
138
147
  * endpoint reads — a stray cap key belonging to another wire form is inert there and must not be
@@ -1,4 +1,4 @@
1
- import { isCredentialHeaderName } from "../core/secret-env.js";
1
+ import { isCredentialHeaderName, namesASecret } from "../core/secret-env.js";
2
2
  import { isPlainRecord } from "../core/mods/kernel/receive.js";
3
3
  import { BrainError } from "./errors.js";
4
4
  export const OPENAI_RESERVED = new Set([
@@ -92,15 +92,18 @@ export function lockHeader(headers, lowerName, value) {
92
92
  }
93
93
  headers[lowerName] = value;
94
94
  }
95
- export function takeHeaderCasefold(headers, lowerName) {
95
+ export function takeHeaderSpellings(headers, lowerName) {
96
+ const values = [];
96
97
  for (const k of Object.keys(headers)) {
97
98
  if (k.toLowerCase() === lowerName) {
98
- const v = headers[k];
99
+ values.push(headers[k]);
99
100
  delete headers[k];
100
- return v;
101
101
  }
102
102
  }
103
- return undefined;
103
+ return values;
104
+ }
105
+ export function headerListEntries(value) {
106
+ return typeof value === "string" ? value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "") : [];
104
107
  }
105
108
  export function headerBagOnce(bag) {
106
109
  return bag === undefined ? undefined : { ...bag };
@@ -126,6 +129,19 @@ export function mergeHeaders(...bags) {
126
129
  }
127
130
  return out;
128
131
  }
132
+ export function declaredRequestValues(bags, stated, key) {
133
+ const out = new Set();
134
+ for (const bag of bags)
135
+ for (const value of Object.values(bag ?? {}))
136
+ if (typeof value === "string" && value !== "")
137
+ out.add(value);
138
+ for (const value of stated)
139
+ if (value !== undefined && value !== "")
140
+ out.add(value);
141
+ if (key !== undefined && namesASecret(key))
142
+ out.add(key);
143
+ return [...out];
144
+ }
129
145
  export const OUTPUT_CAP_KEYS = {
130
146
  openai: ["max_tokens", "max_completion_tokens"],
131
147
  anthropic: ["max_tokens"],
@@ -1,5 +1,6 @@
1
1
  import type { BrainRetryErrClass, BrainStatus } from "../core/types.js";
2
2
  import type { ReasoningWireFacts } from "./reasoning.js";
3
+ import type { CapabilityDeclaration, ModelCapability } from "./model-capability.js";
3
4
  /** Run `fn` with a per-task brain-status sink in scope. ALS propagates it through the async brain calls
4
5
  * inside `fn` (the harness's prompt → brain.stream → connect/retry loop), so {@link emitBrainStatus}
5
6
  * reaches THIS task's sink and nothing else. */
@@ -168,3 +169,22 @@ export declare function runWithCredentialOriginRefusals<T>(observe: (r: Credenti
168
169
  * `routeRefusalError`; a judgment that only advises reports nothing). The
169
170
  * observer is the Runner's own seat, whose one delivery is the guarded `deliverEngineNotice` — nothing is swallowed here. */
170
171
  export declare function reportCredentialOriginRefusal(report: CredentialOriginRefusalReport): void;
172
+ /** A request that withheld a capability from the model it was sent to: the model, the capability, the model's declaration
173
+ * that withheld it (`capabilityOf`), and how many blocks it replaced. */
174
+ export interface CapabilityWithheldReport {
175
+ modelId: string;
176
+ capability: ModelCapability;
177
+ cause: Exclude<CapabilityDeclaration, "declared_on">;
178
+ count: number;
179
+ }
180
+ /**
181
+ * Run `fn` with a per-run withheld-capability sink in scope — the SIXTH brain→runner ALS channel, with the fourth's shape
182
+ * and for its reasons: the WHOLE leg (the end-of-task compaction runs after the leg's prompt, and a child leg running
183
+ * inside its parent's tool call must report to its own leg, not to the scope it inherited), not shielded around the leg's
184
+ * internal calls, not revoked on settlement, no-op outside the scope.
185
+ */
186
+ export declare function runWithCapabilityWithheld<T>(observe: (r: CapabilityWithheldReport) => void, fn: () => Promise<T>): Promise<T>;
187
+ /** Report a withheld capability to the active per-run sink, if any (called by the message assemblers' one emit,
188
+ * `reportImagesWithheld`). The observer is the Runner's own seat, whose one delivery is the guarded `deliverEngineNotice`
189
+ * — nothing is swallowed here: a seat that fails otherwise fails the request build, never the person's notice in silence. */
190
+ export declare function reportCapabilityWithheld(report: CapabilityWithheldReport): void;
@@ -75,3 +75,10 @@ export function runWithCredentialOriginRefusals(observe, fn) {
75
75
  export function reportCredentialOriginRefusal(report) {
76
76
  credentialOriginRefusalSinkStore.getStore()?.observe(report);
77
77
  }
78
+ const capabilityWithheldSinkStore = new AsyncLocalStorage();
79
+ export function runWithCapabilityWithheld(observe, fn) {
80
+ return capabilityWithheldSinkStore.run({ observe }, fn);
81
+ }
82
+ export function reportCapabilityWithheld(report) {
83
+ capabilityWithheldSinkStore.getStore()?.observe(report);
84
+ }
@@ -109,6 +109,12 @@ export declare const WAITING_FIRST_TOKEN_EVERY_MS = 30000;
109
109
  export interface SSERequest {
110
110
  url: string;
111
111
  headers: Record<string, string>;
112
+ /**
113
+ * Every header value this request was DECLARED with — the model entry's, the deployment's and the call's header bags as the
114
+ * route kept them, and the key — as the adapter built them. An endpoint's words lose these before the engine carries them
115
+ * ({@link remoteWords}); the engine's own protocol words (`content-type`, the version and the beta list it chose) are not declared.
116
+ */
117
+ declared: readonly string[];
112
118
  body: string;
113
119
  /**
114
120
  * The per-request output cap this request ACTUALLY carries on the wire, when the adapter sets one
@@ -194,6 +200,9 @@ export interface StreamControls {
194
200
  * raising the provider's own in-band failure from `finalize`: the terminal message the engine mints for that
195
201
  * failure keeps it (the text the provider streamed, the usage it reported), rather than an empty shell. */
196
202
  keepOutput(output: KeptOutput): void;
203
+ /** The provider's own words in an in-band failure, as the engine carries them: this attempt's request ({@link SSERequest.declared}) taken
204
+ * out, then the credential vocabulary. A judge that reads the frame (the condition, the input-too-long anchor) reads the raw words. */
205
+ providerWords(words: string): string;
197
206
  }
198
207
  /** The output a parser hands over with {@link StreamControls.keepOutput}. */
199
208
  export interface KeptOutput {
@@ -9,7 +9,7 @@ import { FAST_MAX_BACKOFF_MS, providerWaitHint, retryBackoffMs } from "./retry.j
9
9
  import { bindBrainStatusEmitter, emitBrainStatus, emitBrainTelemetry, reportExtraBodyDropped } from "./status-sink.js";
10
10
  import { createAttemptController, firstByteWindow, refuseRetiredTimeoutKnobs, resolveFirstByteRetries, resolveWatchdogMs, STALL_FIRST_BYTE_MS, STALL_FIRST_TOKEN_MS, STALL_IDLE_MS, } from "./timeout.js";
11
11
  import { readMember, thrownText } from "../core/thrown-value.js";
12
- import { egressText } from "../core/untrusted-egress.js";
12
+ import { remoteWords } from "../core/protocol-http-auth.js";
13
13
  const DEFAULT_MAX_RETRIES = 10;
14
14
  const MAX_RETRIES_ENV_CEILING = 15;
15
15
  const MAX_RETRIES_ENV = "SEMA_MAX_RETRIES";
@@ -294,6 +294,13 @@ export function runStreamingBrain(args) {
294
294
  let attemptPartial;
295
295
  let attemptOutput;
296
296
  let routeSeen;
297
+ let declaredSeen = [];
298
+ const echoCarried = (value, field) => {
299
+ if (remoteWords(value, declaredSeen) === value)
300
+ return value;
301
+ emitBrainTelemetry({ kind: "echo_dropped", field });
302
+ return undefined;
303
+ };
297
304
  void run()
298
305
  .catch((err) => {
299
306
  const aborted = signal?.aborted === true || isAbortError(err);
@@ -313,7 +320,8 @@ export function runStreamingBrain(args) {
313
320
  errorMsg.usage = kept.usage;
314
321
  }
315
322
  errorMsg.stopReason = aborted ? "aborted" : "error";
316
- errorMsg.errorMessage = thrownText(err);
323
+ const said = thrownText(err);
324
+ errorMsg.errorMessage = brainErrorCodeOf(err) !== undefined ? said : remoteWords(said, declaredSeen);
317
325
  const failure = aborted ? {} : thrownBrainFailure(err);
318
326
  if (failure.code !== undefined) {
319
327
  if (failure.errorKind !== undefined)
@@ -328,13 +336,17 @@ export function runStreamingBrain(args) {
328
336
  const statusNum = typeof status === "number" ? status : undefined;
329
337
  if (namesTheFailure(statusNum))
330
338
  errorMsg.apiErrorStatus = statusNum;
331
- if (requestIdSeen !== undefined)
332
- errorMsg.requestId = requestIdSeen;
339
+ const requestId = requestIdSeen === undefined ? undefined : echoCarried(requestIdSeen, "requestId");
340
+ if (requestId !== undefined)
341
+ errorMsg.requestId = requestId;
333
342
  if (routeSeen !== undefined)
334
343
  errorMsg.apiErrorRoute = routeSeen;
335
344
  const providerCode = readMember(err, "providerCode");
336
- if ((statusNum === undefined || refusedTheRequest(statusNum)) && typeof providerCode === "string" && isProviderEchoShape(providerCode))
337
- errorMsg.apiErrorCode = providerCode;
345
+ if ((statusNum === undefined || refusedTheRequest(statusNum)) && typeof providerCode === "string" && isProviderEchoShape(providerCode)) {
346
+ const apiErrorCode = echoCarried(providerCode, "apiErrorCode");
347
+ if (apiErrorCode !== undefined)
348
+ errorMsg.apiErrorCode = apiErrorCode;
349
+ }
338
350
  const condition = readMember(err, "providerCondition");
339
351
  const source = readMember(err, "providerConditionSource");
340
352
  if (isProviderCondition(condition) && isProviderConditionSource(source)) {
@@ -370,6 +382,7 @@ export function runStreamingBrain(args) {
370
382
  r.onCommitted?.();
371
383
  reportRequestStrip(model, r);
372
384
  routeSeen = admittedRequestRoute(r.route);
385
+ declaredSeen = r.declared;
373
386
  };
374
387
  commit(req);
375
388
  const dialect = resolveProviderDialect(req.url, model.api);
@@ -475,7 +488,7 @@ export function runStreamingBrain(args) {
475
488
  }
476
489
  else if (classifyFetchThrow(e) === "request_unbuildable") {
477
490
  cc.dispose();
478
- throw new BrainError("invalid_request", `${httpLabel} request could not be built: ${egressText("same-principal", stripUrlCredentials(thrownText(e)))}`);
491
+ throw new BrainError("invalid_request", `${httpLabel} request could not be built: ${remoteWords(stripUrlCredentials(thrownText(e)), req.declared)}`);
479
492
  }
480
493
  else {
481
494
  netErr = e;
@@ -634,14 +647,14 @@ export function runStreamingBrain(args) {
634
647
  continue;
635
648
  }
636
649
  if (netErr) {
637
- const chain = describeNetworkError(netErr);
650
+ const chain = remoteWords(describeNetworkError(netErr), req.declared);
638
651
  const proxyRefusal = connectReading?.proxyRefusal;
639
652
  throw new BrainError("network", proxyRefusal === undefined ? chain : `${proxyTunnelRefusedSentence(proxyRefusal.status)} — ${chain}`, undefined, { apiError: true });
640
653
  }
641
654
  if (r !== undefined && errorBody === undefined)
642
655
  errorBody = await readErrorBody(r, signal);
643
656
  const terminalVerdict = judge();
644
- const detail = errorBody?.text ?? "";
657
+ const detail = errorBody === undefined ? "" : remoteWords(errorBody.endedNormally ? errorBody.text : errorBody.text.replace(/\S+$/u, ""), req.declared);
645
658
  const status = r?.status ?? 0;
646
659
  const itl = terminalVerdict?.inputTooLong ?? "no";
647
660
  const providerCode = refusedTheRequest(status) ? readProviderErrorCode(errorBody) : undefined;
@@ -737,6 +750,7 @@ export function runStreamingBrain(args) {
737
750
  keepOutput: (output) => {
738
751
  attemptOutput = output;
739
752
  },
753
+ providerWords: (words) => remoteWords(words, req.declared),
740
754
  });
741
755
  const INBAND_OVERLOAD_WARNING = "API overloaded mid-response. The response above may be incomplete.";
742
756
  const onLineOverloadTierA = (line) => {
@@ -761,7 +775,7 @@ export function runStreamingBrain(args) {
761
775
  throw e;
762
776
  failure = {
763
777
  kind: "connection",
764
- err: new BrainError("network", `mid-stream read failed: ${describeNetworkError(e)}`, undefined, { apiError: true }),
778
+ err: new BrainError("network", `mid-stream read failed: ${remoteWords(describeNetworkError(e), req.declared)}`, undefined, { apiError: true }),
765
779
  };
766
780
  break readLoop;
767
781
  }
@@ -17,9 +17,10 @@ import { type AssistantMessage, type ModelOutputInvalid, type StreamDropCause }
17
17
  /** The warning (the reference's former words; later replaced by a resume request) stamped beside `partialFinalized` when a stream ended before its close — by the
18
18
  * mid-stream promotion (the body threw) and by the parsers' own finalize (content arrived, no finish frame). */
19
19
  export declare const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
20
- /** A provider word as a stream-end seat carries it: the word in the provider echo shape, else `?` — the fact that a
21
- * word arrived survives, bytes outside the shape do not (the echo discipline: dropped, never rewritten). */
22
- export declare function echoFoldedWord(raw: string): string;
20
+ /** A provider word as a stream-end seat carries it: the word in the provider echo shape that the stream's mint
21
+ * (`providerWords`) leaves as it is, else `?` — the fact that a word arrived survives, bytes outside the shape or holding
22
+ * what the request was declared with do not (the echo discipline: dropped, never rewritten). */
23
+ export declare function echoFoldedWord(raw: string, providerWords: (words: string) => string): string;
23
24
  /**
24
25
  * The record of what arrived after a stream's first terminal statement — the one ordering rule both wire parsers
25
26
  * apply: the first ending (a finish / stop reason, a message stop, an in-band error) decides the turn; after it the
@@ -27,7 +28,7 @@ export declare function echoFoldedWord(raw: string): string;
27
28
  * here. Rides `AssistantMessage.streamEndIgnored` (the first refused frame's kind and word, how many came); the
28
29
  * Runner announces it (`route.stream_end_ignored`).
29
30
  */
30
- export declare function createStreamEndLedger(): {
31
+ export declare function createStreamEndLedger(providerWords: (words: string) => string): {
31
32
  note(statement: StreamEndStatement, word: string): void;
32
33
  readonly ignored: AssistantMessage["streamEndIgnored"];
33
34
  };
@@ -3,14 +3,14 @@ import { inspectDegenerate } from "./repetition.js";
3
3
  import { emitBrainTelemetry } from "./status-sink.js";
4
4
  import { stampStreamDrops } from "../internal/llm.js";
5
5
  export const STREAM_TORN_WARNING = "Connection closed mid-response. The response above may be incomplete.";
6
- export function echoFoldedWord(raw) {
7
- return isProviderEchoShape(raw) ? raw : "?";
6
+ export function echoFoldedWord(raw, providerWords) {
7
+ return isProviderEchoShape(raw) && providerWords(raw) === raw ? raw : "?";
8
8
  }
9
- export function createStreamEndLedger() {
9
+ export function createStreamEndLedger(providerWords) {
10
10
  let ignored;
11
11
  return {
12
12
  note(statement, word) {
13
- ignored = ignored === undefined ? { statement, word: echoFoldedWord(word), frames: 1 } : { ...ignored, frames: ignored.frames + 1 };
13
+ ignored = ignored === undefined ? { statement, word: echoFoldedWord(word, providerWords), frames: 1 } : { ...ignored, frames: ignored.frames + 1 };
14
14
  },
15
15
  get ignored() {
16
16
  return ignored;
@@ -1,4 +1,5 @@
1
1
  import type { AgentTool } from "../internal/harness-types.js";
2
+ import { type HostFloor } from "./host-floor.js";
2
3
  import type { A2aServerSpec, ToolEffect } from "./types.js";
3
4
  /** The hard per-skill description bound (ruled 2026-08-03: ~2KiB). */
4
5
  export declare const A2A_SKILL_DESCRIPTION_MAX_CHARS = 2048;
@@ -96,4 +97,4 @@ export declare class A2aRpcError extends Error {
96
97
  * `allSettled` keeps it fail-open: one unreachable peer is a skipped peer with a warning, never a task
97
98
  * that cannot start.
98
99
  */
99
- export declare function materializeA2aTools(specs: readonly A2aServerSpec[], principal?: string, signal?: AbortSignal): Promise<MaterializedA2a>;
100
+ export declare function materializeA2aTools(specs: readonly A2aServerSpec[], principal?: string, signal?: AbortSignal, hostFloor?: HostFloor): Promise<MaterializedA2a>;
package/dist/core/a2a.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { Type } from "typebox";
3
3
  import { A2A_TASK_STATES } from "./a2a-task-state.js";
4
- import { assertEndpointBound, redirectPolicy, resolveProtocolHttpHeaders, underDeclaredHeaders } from "./protocol-http-auth.js";
4
+ import { assertEndpointBound, carriesDeclaredHeaders, resolveProtocolHttpHeaders, underDeclaredHeaders } from "./protocol-http-auth.js";
5
+ import { fetchFollowing, hopRefusal, HOST_FLOOR_REFUSED_CODE } from "./host-floor.js";
5
6
  import { describeHttpTransportFailure } from "./mcp-failure.js";
6
7
  import { findNamespacePrefixCollision, mintNamespacePrefix, mintNamespacedToolName } from "./protocol-naming.js";
7
8
  import { A2A_NAMESPACE } from "./protocol-table.js";
@@ -77,6 +78,7 @@ function safeId(v) {
77
78
  return undefined;
78
79
  return inlineUntrusted(s, A2A_ID_MAX_CHARS);
79
80
  }
81
+ const A2A_MAX_REDIRECTS = 20;
80
82
  function withRequestDeadline(outer, timeoutMs) {
81
83
  const controller = new AbortController();
82
84
  let timedOut = false;
@@ -144,21 +146,25 @@ async function readBoundedText(res, what) {
144
146
  async function requestJson(t, what, init) {
145
147
  const doFetch = resolveFetch();
146
148
  const deadline = withRequestDeadline(init.signal, init.timeoutMs);
149
+ const peerLabel = inlineUntrusted(t.peer, A2A_ID_MAX_CHARS);
147
150
  try {
148
- const res = await doFetch(init.url, {
151
+ const followed = await fetchFollowing(doFetch, new URL(init.url), {
149
152
  method: init.method,
150
- signal: deadline.signal,
151
- redirect: redirectPolicy(t.headers),
152
153
  headers: underDeclaredHeaders({ accept: "application/json", "a2a-version": A2A_PROTOCOL_VERSION, ...(init.body !== undefined ? { "content-type": "application/json" } : {}) }, t.headers),
153
154
  ...(init.body !== undefined ? { body: init.body } : {}),
154
- });
155
- const text = await readBoundedText(res, `${what} from A2A peer "${inlineUntrusted(t.peer, A2A_ID_MAX_CHARS)}"`);
155
+ signal: deadline.signal,
156
+ }, { refusal: (url) => hopRefusal(url, t.floor, false), follows: () => !carriesDeclaredHeaders(t.headers), maxRedirects: A2A_MAX_REDIRECTS });
157
+ if (followed.kind === "refused")
158
+ throw Object.assign(new Error(`a2a: ${what} on peer "${peerLabel}" is not sent — ${followed.reason}`), { code: HOST_FLOOR_REFUSED_CODE });
159
+ if (followed.kind === "too_many")
160
+ throw new Error(`a2a: ${what} on peer "${peerLabel}" was redirected more than ${A2A_MAX_REDIRECTS} times`);
161
+ const res = followed.res;
162
+ const text = await readBoundedText(res, `${what} from A2A peer "${peerLabel}"`);
156
163
  return { status: res.status, text };
157
164
  }
158
165
  catch (err) {
159
166
  if (init.signal?.aborted === true)
160
167
  throw err;
161
- const peerLabel = inlineUntrusted(t.peer, A2A_ID_MAX_CHARS);
162
168
  if (deadline.timedOut()) {
163
169
  throw new Error(`a2a: ${what} on peer "${peerLabel}" got no answer within ${init.timeoutMs}ms. The client stopped waiting — the peer may still be acting on the request, so treat the outcome as UNKNOWN and verify before retrying.`, { cause: err });
164
170
  }
@@ -553,16 +559,16 @@ function declaredPeerOf(declared, index) {
553
559
  const judged = judgeEntryToolAxes(snapshot, "a2a");
554
560
  return judged.ok ? { spec: judged.entry } : { spec: snapshot, refusal: judged.error };
555
561
  }
556
- async function materializePeer(peer, principal, lifecycle, signal) {
562
+ async function materializePeer(peer, principal, lifecycle, signal, floor) {
557
563
  if ("refusal" in peer)
558
564
  throw peer.refusal;
559
565
  const { spec } = peer;
560
566
  const declaredAxes = spec.toolAxes;
561
567
  const headers = resolveProtocolHttpHeaders(A2A_NAMESPACE.id, spec, principal);
562
- const discovery = { peer: spec.name, endpoint: spec.url, headers };
568
+ const discovery = { peer: spec.name, endpoint: spec.url, headers, floor };
563
569
  const card = readCard(spec.name, await discoverCardBody(spec, discovery, signal), spec.url);
564
570
  assertEndpointBound(A2A_NAMESPACE.id, spec.name, card.endpoint, spec.cardUrl === undefined ? [spec.url] : [spec.url, spec.cardUrl], headers);
565
- const transport = { peer: spec.name, endpoint: card.endpoint, headers };
571
+ const transport = { peer: spec.name, endpoint: card.endpoint, headers, floor };
566
572
  const tools = [];
567
573
  const skillAxes = [];
568
574
  for (const skill of card.skills) {
@@ -592,7 +598,7 @@ function asPeerWarning(spec, err) {
592
598
  warning.code = "a2a.peer_unavailable";
593
599
  return warning;
594
600
  }
595
- export async function materializeA2aTools(specs, principal, signal) {
601
+ export async function materializeA2aTools(specs, principal, signal, hostFloor) {
596
602
  const peers = specs.map((spec, index) => declaredPeerOf(spec, index));
597
603
  if (peers.length > 0) {
598
604
  const collision = findNamespacePrefixCollision(A2A_NAMESPACE, peers.map((p) => p.spec.name));
@@ -610,7 +616,7 @@ export async function materializeA2aTools(specs, principal, signal) {
610
616
  const toolAxes = [];
611
617
  const warnings = [];
612
618
  const statuses = [];
613
- const settled = await Promise.allSettled(peers.map((peer) => materializePeer(peer, principal, lifecycle, signal)));
619
+ const settled = await Promise.allSettled(peers.map((peer) => materializePeer(peer, principal, lifecycle, signal, hostFloor)));
614
620
  for (let i = 0; i < peers.length; i++) {
615
621
  const spec = peers[i].spec;
616
622
  const outcome = settled[i];
@@ -645,7 +651,7 @@ export async function materializeA2aTools(specs, principal, signal) {
645
651
  }
646
652
  const previous = statuses.find((s) => s.name === spec.name)?.toolNames ?? [];
647
653
  try {
648
- const fresh = await materializePeer(target, principal, lifecycle, signal);
654
+ const fresh = await materializePeer(target, principal, lifecycle, signal, hostFloor);
649
655
  const names = fresh.tools.map((t) => t.name);
650
656
  results.push({
651
657
  peer: spec.name,
@@ -157,4 +157,14 @@ export interface SkillSpec {
157
157
  * byte-identical result; a placeholder with no directory stays verbatim.
158
158
  */
159
159
  baseDir?: string;
160
+ /**
161
+ * The hooks this skill carries — registrations on the mods bus (the `TaskSpec.mods` form: user tier, a name unique in the
162
+ * run), whose handlers take part only while the skill is ACTIVE on the leg that loads it: from its activation (the `Skill`
163
+ * tool's success, or prepare for a skill the person invoked by name; a resumed run reopens the skills its park recorded
164
+ * active) to the end of that run. A host compiles a frontmatter `hooks:` table into one such registration; the engine
165
+ * reads no hook grammar. Each hangs `classic.*` events only (any other event refuses the prepare, `config.mods_invalid`).
166
+ * They are admitted with the leg's other registrations at its prepare (so a skill never activated still counts as a hook
167
+ * the leg may run) and stay the leg's own: a delegated child neither dispatches them nor is screened by them.
168
+ */
169
+ mods?: readonly import("./mods/classic-events.js").EngineModRegistration[];
160
170
  }
@@ -1,3 +1,4 @@
1
+ import type { EditRewritten } from "./rewrite-rejudge.js";
1
2
  import { type RuleToolNameVerdict } from "./tool-name-aliases.js";
2
3
  import type { ToolCallRequest } from "./tool-policy.js";
3
4
  import { type AllowRuleMember, type AllowRuleShadow } from "./allow-rule-shadow.js";
@@ -46,14 +47,15 @@ export type AllowEntryInert = {
46
47
  readonly entry: string;
47
48
  readonly reason: AllowEntryInertReason;
48
49
  } & AllowEntryInertDetail;
49
- /** One entry the grammar reads (kind closed): a whole non-shell tool; a protocol namespace; the whole shell tool; and one
50
- * kind per rule grammar (`ruleToolGrammarOf`) — a shell command rule, a path rule, a name rule, a host rule — each the row
51
- * the persisted grammar parses, its `behavior` the list's direction. */
50
+ /** One entry the grammar reads (kind closed): a whole non-shell tool; a covering spelling — a set of tool names
51
+ * ({@link isCoveringRuleName}: a protocol peer, a glob over a protocol name's tool segment, and on a deny list a `*` anywhere in
52
+ * the name, `*` alone every tool); the whole shell tool; and one kind per rule grammar (`ruleToolGrammarOf`) — a shell command
53
+ * rule, a path rule, a name rule, a host rule — each the row the persisted grammar parses, its `behavior` the list's direction. */
52
54
  export type CompiledAllowEntry = {
53
55
  readonly kind: "tool";
54
56
  readonly name: string;
55
57
  } | {
56
- readonly kind: "namespace";
58
+ readonly kind: "covering";
57
59
  readonly pattern: string;
58
60
  } | {
59
61
  readonly kind: "shell";
@@ -71,15 +73,6 @@ export type CompiledAllowEntry = {
71
73
  readonly kind: "domain";
72
74
  readonly rule: PersistedRule;
73
75
  };
74
- /**
75
- * THE near-miss reading of a tool name the judgment calls current: the spelling the run mounts when the run mounts no tool of this
76
- * exact name but one that differs from it only by case (`BASH` beside `Bash`), else `undefined`. Two kinds of name are never a near
77
- * miss, because the roster they would be read against is not the final one: an engine tool's (the engine mounts some of its tools
78
- * after a list is read) and a protocol tool's (a refresh mounts and unmounts them while the run goes on) — in both the exact
79
- * spelling can be the right one by the time it matters. Every station that asks "is this name a case twin of a mounted tool" reads
80
- * this answer: an entry list ({@link readRuleEntry}), a tool policy's name lists (the prepare-time policy-name audit).
81
- */
82
- export declare function nearMissSpellingOf(name: string, roster: ReadonlySet<string>): string | undefined;
83
76
  /**
84
77
  * THE universe a ROOT-facing tool-name list is read against: every name the engine's catalog carries, and the names the reader knows
85
78
  * are carried (`carried`). A list is root-facing when it bounds the tools of the run that holds it — the run's own `allowTools` /
@@ -108,15 +101,13 @@ export type RuleEntryReading = {
108
101
  * grammar alone is read — what a resume's pre-claim screen can read before the leg has a roster.
109
102
  */
110
103
  export declare function readRuleEntry(raw: unknown, behavior: "allow" | "deny", roster?: ReadonlySet<string>): RuleEntryReading;
111
- /** The tool name a compiled entry speaks for — its tool, its namespace spelling, or its rule's tool (what a name audit reads). */
104
+ /** The tool name a compiled entry speaks for — its tool, its covering spelling, or its rule's tool (what a name audit reads). */
112
105
  export declare function compiledEntryName(compiled: CompiledAllowEntry): string;
113
106
  /**
114
- * Compile one list WHOLE through {@link readRuleEntry}: the entries it reads and the ones it reads as nothing (each with its
115
- * reason and, for a name the roster refuses, the judgment's word and the spelling to write). An allow list holding `*` voids
116
- * the list (every other entry on it reads as nothing too: the list grants nothing — the safe direction) — `*` as the lenient
117
- * rule parser names it ({@link namesWholeRoster}), so an entry the stricter entry grammar refuses (`* (*)`) still voids. A
118
- * `*` on a deny list reads as nothing by itself and the rest of that list still refuses: a deny list never loses an entry to
119
- * a wildcard beside it. `roster` as in {@link readRuleEntry}.
107
+ * Compile one list through {@link readRuleEntry}, entry by entry: the entries it reads and the ones it reads as nothing (each
108
+ * with its reason and, for a name the roster refuses, the judgment's word and the spelling to write). No entry changes how
109
+ * another is read: a `*` on an allow list grants nothing by itself (`wildcard_all`) and the entries beside it keep their
110
+ * reading; on a deny list it refuses every tool. `roster` as in {@link readRuleEntry}.
120
111
  */
121
112
  export declare function compileAllowList(entries: readonly string[], behavior: "allow" | "deny", roster?: ReadonlySet<string>): {
122
113
  rows: Array<{
@@ -135,7 +126,9 @@ export declare const AUTO_STRIPPED_PROGRAMS: readonly ["python", "python3", "pyt
135
126
  * disclosed.
136
127
  */
137
128
  export declare function autoStripped(compiled: CompiledAllowEntry, call: ToolCallRequest | undefined): boolean;
138
- /** {@link autoStripped} over a person's stored ALLOW row (a deny / ask row is never stripped; a path row never is). */
129
+ /** {@link autoStripped} over a person's stored ALLOW row, read as its list twin ({@link entryOfRow}): a row is stripped exactly when
130
+ * the entry spelling the same rule is (a deny / ask row never is; a row no grammar reads has no twin and is not stripped here — the
131
+ * lane reads no allow it cannot parse). */
139
132
  export declare function autoStrippedRule(rule: PersistedRule, call: ToolCallRequest): boolean;
140
133
  /** One row a list matcher reads. */
141
134
  export interface AllowEntryRow {
@@ -275,6 +268,10 @@ export declare function screenAllowedToolsValue(value: unknown, seat: AllowedToo
275
268
  /** The disclosure record for one member, minted from the entries it matched: each sanitized (deployment or model-authored
276
269
  * text on a human trust boundary) and capped, the rest counted. */
277
270
  export declare function allowRuleShadowOf(member: AllowRuleMember, entries: readonly string[]): AllowRuleShadow;
271
+ /** A disclosure list with one more member's record folded in: ONE record per member — a member already disclosed gains the
272
+ * other record's entries after its own (every speaking, in reading order: two shown names that read alike are two speakers),
273
+ * the cap kept and the rest counted; any other member is appended. Records are minted values already ({@link allowRuleShadowOf}). */
274
+ export declare function withAllowRuleShadow(list: readonly AllowRuleShadow[], shadow: AllowRuleShadow): AllowRuleShadow[];
278
275
  /** Read a disclosure value off a decision WITHOUT trusting it (a policy's own value, an ancestor's): every record a known
279
276
  * member with a list of strings, or nothing — a display member must never throw where a card is minted. */
280
277
  export declare function readAllowRuleShadows(value: unknown): readonly AllowRuleShadow[] | undefined;
@@ -325,8 +322,9 @@ export declare function allowRuleShadowSentence(shadows: readonly AllowRuleShado
325
322
  authoredBy?: "deployment";
326
323
  probeReason?: string;
327
324
  }): string;
328
- /** The card's two disclosure members off a surviving ask, minted at every station that builds an approval request: the
329
- * sanitized records, and the message with the sentence rendered onto it. */
325
+ /** The card's disclosure members off a surviving ask, minted at every station that builds an approval request: the
326
+ * sanitized records, the message with the sentence rendered onto it, and the outlet of a person's rewritten edit (the
327
+ * approved-edit pass's own member, whose form is the bytes the card presents). */
330
328
  export declare function cardDisclosureOf(decision: {
331
329
  message?: string;
332
330
  allowRuleShadowed?: unknown;
@@ -334,9 +332,11 @@ export declare function cardDisclosureOf(decision: {
334
332
  mandate?: PersistedRuleMandate;
335
333
  authoredBy?: "deployment";
336
334
  probeReason?: string;
335
+ editRewritten?: EditRewritten;
337
336
  }, fallbackMessage: string): {
338
337
  message: string;
339
338
  allowRuleShadowed?: readonly AllowRuleShadow[];
339
+ editRewritten?: EditRewritten;
340
340
  };
341
341
  /** The notice for list entries that grant (or refuse) nothing — one code for every list. */
342
342
  export declare const ALLOWED_TOOL_NOT_GRANTED_CODE = "permission.allowed_tool_not_granted";