@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
@@ -265,8 +265,9 @@ export interface TaskNotificationPayload {
265
265
  * `[Cross-session idle notice] …` as a plain user-frame line) — never a `<task-notification>` shell,
266
266
  * never the peer-message envelope (a notice is engine speech about a peer, not a peer's words; the
267
267
  * envelope would put it past the parity judgment as a peer's request). `text` is rendered by the
268
- * drain from the record's TYPED `peerMeta.notice` (the authority); the record's own `content` mirror is
269
- * never what reaches the model. Minted ONLY by the engine's session-box drain.
268
+ * drain from the record's TYPED `peerMeta.notice` (the authority, which rides THIS frame once, at
269
+ * `_sema_provenance.peerMeta.notice` — a host renders a card from there, never by parsing `text`); the
270
+ * record's own `content` mirror is never what reaches the model. Minted ONLY by the engine's session-box drain.
270
271
  */
271
272
  crossSessionNotice?: {
272
273
  kind: "delivery_notice" | "idle_notice";
@@ -275,29 +276,32 @@ export interface TaskNotificationPayload {
275
276
  /**
276
277
  * design/385 §1.4 d1 / §4.1 — the engine-minted PROVENANCE side record of an engine-injected peer
277
278
  * frame, a typed key (never model text) so a host can attribute and correlate the injection on the
278
- * wire. Present exactly when {@link agentMessage} OR {@link crossSessionMessage} is — one record
279
- * per carrier (the notice carrier {@link crossSessionNotice} too), `kind` naming which. Its fields are read per `kind` (see {@link SemaProvenance}):
279
+ * wire. Present exactly when one of the four peer carriers is ({@link agentMessage}, {@link crossSessionMessage},
280
+ * {@link crossSessionNotice}, {@link inboxNotice}) — one record per frame, `kind` naming which. Its fields are read per `kind` (see {@link SemaProvenance}):
280
281
  * on the agent-message lane `from` is the sender label the frame's attribute spells, `taskId` the
281
282
  * sender's run/agent id, `seq` the producer's per-frame counter (= this payload's `seq`) and
282
- * `agentType` the sender's resolved agent type when the producer knows it; on the cross-session
283
- * lane `from` is the sender's ADDRESS, `taskId` the recipient's own box handle, `seq` the box seq,
284
- * and the typed peer record rides in `peerMeta`.
283
+ * `agentType` the sender's resolved agent type when the producer knows it; on the two box-record
284
+ * lanes `from` is the sender's ADDRESS, `taskId` the recipient's own box handle, `seq` the box seq,
285
+ * and the record's typed peer metadata rides in `peerMeta` (on a notice frame its `notice` is THE typed notice).
285
286
  */
286
287
  _sema_provenance?: SemaProvenance;
287
288
  }
288
289
  /** design/385 §1.4 d1 / §4.1 — see {@link TaskNotificationPayload._sema_provenance}. `kind` is a
289
- * closed set of the two engine lanes that mint the record; a future lane adds a member, never a
290
+ * closed set of the engine carriers that mint the record; a future carrier adds a member, never a
290
291
  * second key. */
291
292
  export interface SemaProvenance {
292
- /** `agent_message` = the same-process uplink (§1.4 d1); `cross_session_message` = the session-box
293
- * drain (§4.1) — `from` is then the sender's ADDRESS, `taskId` the recipient's own box handle,
294
- * `seq` the box seq, and the typed peer record rides in `peerMeta`. */
293
+ /** `agent_message` = the same-process uplink (§1.4 d1); `cross_session_message` / `cross_session_notice` =
294
+ * the session-box drain over a box record (§4.1 / §4.4) — `from` is then the sender's ADDRESS, `taskId` the
295
+ * recipient's own box handle, `seq` the box seq, and the record's typed meta rides in `peerMeta`;
296
+ * `inbox_notice` = the drain's own line about its box (no record behind it: its facts are the carrier's). */
295
297
  kind: "agent_message" | "cross_session_message" | "cross_session_notice" | "inbox_notice";
296
298
  from: string;
297
299
  taskId: string;
298
300
  seq: number;
299
301
  agentType?: string;
300
- /** cross_session_message only — the store record's typed peer metadata, verbatim (authority). */
302
+ /** The two box-record kinds (`cross_session_message`, `cross_session_notice`) — the store record's typed peer
303
+ * metadata, verbatim (authority; a notice frame's `peerMeta.notice` is the typed notice, its carrier holds only
304
+ * the rendered line). Absent on `agent_message` / `inbox_notice`, and on a record that carried no peerMeta. */
301
305
  peerMeta?: import("./mailbox-store.js").MailboxPeerMeta;
302
306
  }
303
307
  /**
@@ -443,19 +443,23 @@ export declare function deliverToRunningAgentLane(core: DurableAgentCore, id: st
443
443
  * counterpart rows here). This variant is the SENDMESSAGE footer's source and lists EVERY running
444
444
  * agent, named or not: SendMessage addresses by name AND by id, so dropping named rows here (the way
445
445
  * {@link runningAgentFooterLane} does for the task faces, per CC `rxo`'s `!n.has(i.id)`) would hide the
446
- * very rows a retry needs. The task faces' split lives in `runningAgentFooterLane` (RB-332). */
446
+ * very rows a retry needs. The label is the name someone chose, else the description: the name an agent
447
+ * carries only because it must carry one ({@link chosenAgentName}) says nothing about what it does.
448
+ * The task faces' split lives in `runningAgentFooterLane` (RB-332). */
447
449
  export declare function runningBackgroundAgentLabelsLane(core: DurableAgentCore, access: TaskAccess): string[];
448
450
  /**
449
451
  * The not-found FOOTER's two rows, split the way the reference assembles them:
450
452
  * - `named` = CC `uG_` (220:467941-467953): the agentNameRegistry's KEYS whose task is a running local
451
453
  * agent, listed as BARE NAMES — the string a retry should pass verbatim. sema's counterpart
452
- * of "has a registry entry" is the handle carrying an explicit `name` (spawn-time label),
453
- * the same field TaskStop's name leg and SendMessage address by.
454
+ * of "has a registry entry" is the handle carrying a CHOSEN name (the spawn-time label; the
455
+ * name an agent carries only because every agent has one is not a registry entry —
456
+ * {@link chosenAgentName}).
454
457
  * - `background` = CC `rxo` (220:467937-467951): the remaining running background agents as `id (label)`
455
458
  * rows. CC filters `!n.has(i.id)` — a NAMED agent is deliberately NOT repeated here, because
456
459
  * its addressable form is the name, not the id. The pre-RB-332 sema code merged both legs
457
460
  * into one list and justified it with "named has no counterpart", a claim [c209-D] retired
458
- * when the explicit `name` field landed.
461
+ * when the explicit `name` field landed. The id stays in these rows because TaskOutput
462
+ * resolves exact ids only: an agent nobody named is the one a retry can reach by its id alone.
459
463
  * CC's `YEd` "Running teammates:" leg has no sema counterpart (no teammate registry on this face) and is
460
464
  * honestly absent rather than faked.
461
465
  */
@@ -5,7 +5,7 @@ import { canAccessAgentRecord, BackgroundAgentStoreError, clearRevivedRowTermina
5
5
  import { shutdownDebug } from "./shutdown-debug.js";
6
6
  import { delimitUntrusted } from "./untrusted-text.js";
7
7
  import { boundedRedactedSummary } from "./untrusted-egress.js";
8
- import { mintCompletionId, commitCompletionIdIfEmpty, clipTaskOutput, assertOwnership, sleepPollStep, alreadyTerminalStopNote, canAccess, normalizeAgentName, closestName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR, } from "./task-registry-shared.js";
8
+ import { mintCompletionId, commitCompletionIdIfEmpty, clipTaskOutput, assertOwnership, sleepPollStep, alreadyTerminalStopNote, canAccess, normalizeAgentName, engineAgentName, chosenAgentName, closestName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR, } from "./task-registry-shared.js";
9
9
  import { buildToolResultRef, OFFLOAD_TOOL_NAME, toolResultProvenanceOf } from "./tool-result-store.js";
10
10
  import { thrownLabel } from "./thrown-value.js";
11
11
  import { agentStateSourceOfHandle, agentStateSummary, readAgentState } from "./agent-state.js";
@@ -367,6 +367,10 @@ export function registerBackgroundAgentLane(core, input) {
367
367
  if (core.handles.has(id))
368
368
  throw new Error(`TaskRegistry: task id already registered: ${id}`);
369
369
  const now = input.now ?? Date.now();
370
+ if (input.name !== undefined && (typeof input.name !== "string" || input.name === "")) {
371
+ throw new Error(`TaskRegistry: background-agent name must be a non-empty string (got ${JSON.stringify(input.name)}); omit it to take the derived one`);
372
+ }
373
+ const name = input.name ?? engineAgentName(id);
370
374
  core.handles.set(id, {
371
375
  id,
372
376
  type: "background_agent",
@@ -375,7 +379,7 @@ export function registerBackgroundAgentLane(core, input) {
375
379
  ...(input.resolveParkedStop !== undefined ? { resolveParkedStop: input.resolveParkedStop } : {}),
376
380
  ...(input.sessionScoped ? { sessionScoped: true } : {}),
377
381
  ...(input.description !== undefined ? { description: input.description } : {}),
378
- ...(input.name !== undefined ? { name: input.name } : {}),
382
+ name,
379
383
  ...(input.agentType !== undefined ? { agentType: input.agentType } : {}),
380
384
  ...(input.parentTaskId !== undefined ? { parentTaskId: input.parentTaskId } : {}),
381
385
  ...(input.parentSessionId !== undefined ? { parentSessionId: input.parentSessionId } : {}),
@@ -396,6 +400,7 @@ export function registerBackgroundAgentLane(core, input) {
396
400
  if (input.durableSeed !== undefined) {
397
401
  const seeded = structuredClone(input.durableSeed.record);
398
402
  seeded.rev = input.durableSeed.rev;
403
+ seeded.name = name;
399
404
  handle.durable = {
400
405
  store: input.store,
401
406
  record: seeded,
@@ -417,7 +422,7 @@ export function registerBackgroundAgentLane(core, input) {
417
422
  ...(input.parentSessionId !== undefined ? { parentSessionId: input.parentSessionId } : {}),
418
423
  ...(input.rootSessionId !== undefined ? { rootSessionId: input.rootSessionId } : {}),
419
424
  ...(input.parentTaskId !== undefined ? { parentTaskId: input.parentTaskId } : {}),
420
- ...(input.name !== undefined ? { name: input.name } : {}),
425
+ name,
421
426
  ...(input.agentType !== undefined ? { agentType: input.agentType } : {}),
422
427
  ...(input.description !== undefined ? { description: input.description } : {}),
423
428
  ...(input.model !== undefined ? { model: input.model } : {}),
@@ -892,7 +897,7 @@ export function resolveBackgroundAgentByNameLane(core, name, access, opts) {
892
897
  };
893
898
  const named = [];
894
899
  for (const h of core.handles.values()) {
895
- if (h.type !== "background_agent" || h.name === undefined || !canAccess(h, access))
900
+ if (h.type !== "background_agent" || !canAccess(h, access))
896
901
  continue;
897
902
  if (h.name === name || normalizeAgentName(h.name) === key)
898
903
  named.push(h);
@@ -902,7 +907,7 @@ export function resolveBackgroundAgentByNameLane(core, name, access, opts) {
902
907
  if (namedRunning.length > 1) {
903
908
  return {
904
909
  status: "ambiguous",
905
- message: `Multiple RUNNING background agents match "${name}": ${namedRunning.map((h) => `${h.id} (${h.name ?? h.description ?? "unnamed"})`).join(", ")}. Use the task ID.`,
910
+ message: `Multiple RUNNING background agents match "${name}": ${namedRunning.map((h) => `${h.id} (${h.name})`).join(", ")}. Use the task ID.`,
906
911
  };
907
912
  }
908
913
  if (namedRunning.length === 1)
@@ -1256,7 +1261,7 @@ export function runningBackgroundAgentLabelsLane(core, access) {
1256
1261
  for (const h of core.handles.values()) {
1257
1262
  if (h.type !== "background_agent" || h.status !== "running" || !canAccess(h, access))
1258
1263
  continue;
1259
- const label = h.name ?? h.description;
1264
+ const label = chosenAgentName(h.id, h.name) ?? h.description;
1260
1265
  out.push(label ? `${h.id} (${label})` : h.id);
1261
1266
  }
1262
1267
  return out;
@@ -1267,8 +1272,9 @@ export function runningAgentFooterLane(core, access) {
1267
1272
  for (const h of core.handles.values()) {
1268
1273
  if (h.type !== "background_agent" || h.status !== "running" || !canAccess(h, access))
1269
1274
  continue;
1270
- if (h.name !== undefined && h.name !== "") {
1271
- named.push(h.name);
1275
+ const chosen = chosenAgentName(h.id, h.name);
1276
+ if (chosen !== undefined) {
1277
+ named.push(chosen);
1272
1278
  continue;
1273
1279
  }
1274
1280
  background.push(h.description ? `${h.id} (${h.description})` : h.id);
@@ -321,11 +321,12 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
321
321
  reason: "not_found" | "not_running" | "no_channel";
322
322
  }) => void) | undefined)?
323
323
  ]>;
324
- /** [c209-D] the EXPLICIT addressing name (CC Agent.name parity, validated at spawn: charset regex +
325
- * "main" reserved). Distinct from `description` (the display/legacy-matching label): the name layer
326
- * resolves latest-wins ("a newer agent took the name"), the description layers keep their
327
- * running-preferred + ambiguous posture. Absent on pre-[c209] rows and unnamed spawns. */
328
- name?: string;
324
+ /** The addressing name: the spawner's explicit one (CC Agent.name parity, validated at spawn: charset
325
+ * regex + reserved set), or — when the spawn named none — the one {@link engineAgentName} derives from
326
+ * the handle, written by the registration itself, so every background agent has exactly one. Distinct
327
+ * from `description` (the display/legacy-matching label): the name layer resolves latest-wins ("a newer
328
+ * agent took the name"), the description layers keep their running-preferred + ambiguous posture. */
329
+ name: string;
329
330
  /** design/129: this child OUTLIVES its parent turn — owner is the SESSION id; the parent-teardown reap
330
331
  * skips it; `reapSessionBackground` is its terminal anchor. Explicit flag, never inferred from key values
331
332
  * (hostTaskId===sessionId deployments would otherwise be ambiguous). */
@@ -836,6 +837,32 @@ export declare const DURABLE_AGENT_HEARTBEAT_MS = 60000;
836
837
  * durable arm (a bare exact-key miss lets padded/legacy/name-shaped ids leak into live branches —
837
838
  * the server 1.250 HIGH) — one shared regex kills the drift, roster-normalize precedent. */
838
839
  export declare const DURABLE_AGENT_HANDLE_RE: RegExp;
840
+ /**
841
+ * The name a background agent carries when its spawner named none: `agent-` + the first twelve hex
842
+ * digits of its handle (`a3fa9c2d1b7e04a15` → `agent-3fa9c2d1b7e0`; a handle with fewer digits keeps
843
+ * them all). A pure function of the handle, so the same agent id reads the same name in every process
844
+ * and every store — a host that finds a row from an earlier version without a name derives it here, it
845
+ * does not invent one.
846
+ *
847
+ * Shorter than the id's sixteen digits on purpose: a name of the SHAPE of an agent id (`a`, an optional
848
+ * `<label>-`, sixteen hex) already addresses an agent directly and is refused as a name everywhere
849
+ * (`reservedPeerNameReason`), so a minted name is an ordinary admissible name — nothing in the name
850
+ * grammar singles it out. Twelve digits (48 bits) because the name layer resolves a name to the NEWEST
851
+ * agent that holds it: two agents of one caller would have to share twelve digits of their ids to collide.
852
+ *
853
+ * The registry's registration is the one place this is called (see `registerBackgroundAgentLane`); every
854
+ * reader that needs to know whether SOMEONE chose a name goes through {@link chosenAgentName}.
855
+ */
856
+ export declare function engineAgentName(handle: string): string;
857
+ /**
858
+ * The name SOMEONE chose for an agent — `undefined` when the agent's name is the one {@link engineAgentName}
859
+ * derives from its handle (or there is none). Every agent has a name to be addressed by; only a chosen one is
860
+ * also a spawn identity (the teammate key, `spawnName` on frames, a roster entry, the unnamed-child tool pool),
861
+ * and a reader that hands a row's name back into a place that reads it as an identity — a revival's `name`
862
+ * argument, a retained resume's row name — goes through here, so an agent nobody named stays unnamed in every
863
+ * later cycle. A reader that only needs to ADDRESS the agent reads `name` as it is.
864
+ */
865
+ export declare function chosenAgentName(handle: string, name: string | undefined): string | undefined;
839
866
  /** Synthetic settle error the subagent reap path passes after a stop/parent teardown. It is NOT a
840
867
  * real child error — settleBackgroundAgent never stores it (status "killed" + stoppedBy already say
841
868
  * it); exported so the subagent call sites and the registry agree on the exact sentinel. */
@@ -937,7 +964,9 @@ export interface RegisterBackgroundAgentInput extends TaskAccess {
937
964
  description?: string;
938
965
  /** [c209-D] explicit addressing name (CC Agent.name parity) — the CALLER validates it (charset +
939
966
  * reserved "main") before registration; the registry stores it verbatim. Duplicate names are legal
940
- * (latest-wins at resolution; older rows stay task_id-addressable). */
967
+ * (latest-wins at resolution; older rows stay task_id-addressable). ABSENT = the spawner named none:
968
+ * the registration gives the agent the name {@link engineAgentName} derives from its handle (this is
969
+ * the only place a name is minted), on the live handle and the durable row alike. */
941
970
  name?: string;
942
971
  /** the RESOLVED subagent type ("general-purpose"/"fork"/a roster name), persisted
943
972
  * so a REVIVE cycle's observer frames can reproduce the row's TYPE column (never the description). */
@@ -279,6 +279,17 @@ export function formatWorkflowRun(run) {
279
279
  }
280
280
  export const DURABLE_AGENT_HEARTBEAT_MS = 60_000;
281
281
  export const DURABLE_AGENT_HANDLE_RE = /^a[0-9a-f]{6,32}$/;
282
+ export function engineAgentName(handle) {
283
+ if (!DURABLE_AGENT_HANDLE_RE.test(handle)) {
284
+ throw new TypeError(`engineAgentName: ${JSON.stringify(handle)} is not an agent handle (expected "a" followed by 6-32 hex digits)`);
285
+ }
286
+ return `agent-${handle.slice(1, 13)}`;
287
+ }
288
+ export function chosenAgentName(handle, name) {
289
+ if (name === undefined)
290
+ return undefined;
291
+ return DURABLE_AGENT_HANDLE_RE.test(handle) && name === engineAgentName(handle) ? undefined : name;
292
+ }
282
293
  export const BG_AGENT_REAP_STOP_ERROR = "stopped (parent task ended or TaskStop)";
283
294
  export function normalizeAgentName(s) {
284
295
  return s
@@ -7,7 +7,7 @@ import { type BackgroundAgentStore } from "./background-agent-store.js";
7
7
  import type { TaskNotificationPayload } from "./task-notification.js";
8
8
  import type { ToolResultStore } from "./tool-result-store.js";
9
9
  import { type SemaTaskType, type StopSource, type SemaTaskStatus, type TaskRetrievalStatus, type UnifiedTaskOutput, type UnifiedTaskResult, type SemaTaskHandle, type TaskAccess, type BackgroundAgentTaskHandle, type MonitorTimers, type RegisterMonitorInput, type RegisterWorkflowInput, canAccessWorkflowRun, clipTaskOutput, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE } from "./task-registry-shared.js";
10
- export { normalizeAgentName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR } from "./task-registry-shared.js";
10
+ export { normalizeAgentName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR, engineAgentName, chosenAgentName } from "./task-registry-shared.js";
11
11
  export type { ParkedClaimTicket, RegisterBackgroundAgentInput } from "./task-registry-shared.js";
12
12
  import type { RegisterBackgroundAgentInput, ParkedClaimTicket } from "./task-registry-shared.js";
13
13
  import { type AgentStateSource } from "./agent-state.js";
@@ -645,6 +645,9 @@ export declare class TaskRegistry {
645
645
  * agent of another tree, a workflow run, an id no live handle answers (a durable row read back) — is content from beyond the
646
646
  * boundary on a poll and nothing on a stop. */
647
647
  boundaryLegsOf(id: string, access: TaskAccess, verb: "output" | "stop", tree: object): BoundaryLegsGiven;
648
+ /** What a session is still owed when one of its legs ends: each of its {@link liveTasks} delivers into a LATER leg of the session —
649
+ * another tree — so each is read as that leg's poll of it ({@link boundaryLegsOf}, `"output"`, under a tree no handle recorded). */
650
+ owedDeliveries(access: TaskAccess): BoundaryLegsGiven[];
648
651
  pollTask(id: string, access: TaskAccess, opts?: TaskPollOptions): Promise<UnifiedTaskResult>;
649
652
  stopTask(id: string, access: TaskAccess, opts?: TaskStopOptions): Promise<UnifiedTaskResult>;
650
653
  /** S2b — bounded delivery-confirmation wait (see deliverToRunningAgent). Test-tunable. */
@@ -677,6 +680,12 @@ export declare class TaskRegistry {
677
680
  createdAt: number;
678
681
  updatedAt: number;
679
682
  }>;
683
+ /** The tasks `access` reaches that have not finished (`pending`, `running` or `parked`), newest first — EVERY one, with no display
684
+ * cap ({@link list}'s): the one reading of a leg's live background tasks (its end's {@link owedDeliveries}, the post-compaction
685
+ * listing and the resume's orphan diff, the suspend's snapshot), each consumer projecting its own columns from it. */
686
+ liveTasks(access: TaskAccess): ReturnType<TaskRegistry["list"]>;
687
+ /** Every row `access` reaches, newest first, in {@link list}'s projection — the one walk both readings take. */
688
+ private rowsUnder;
680
689
  /** Throttled {@link gc} for hot-path callers (design/115 review B5): prepare-task runs once per task,
681
690
  * and a full-map sweep per prepare is pure overhead — sweep at most once per minute. */
682
691
  maybeGc(now?: number): number;
@@ -9,7 +9,7 @@ import { stripCwdSentinel } from "../tools/fs/fs-shared.js";
9
9
  import { registerMonitorLane, pollMonitorLane, stopMonitorLane } from "./task-registry-monitor.js";
10
10
  import { registerWorkflowLane, pollWorkflowLane, stopWorkflowLane } from "./task-registry-workflow.js";
11
11
  import { mintCompletionId, canAccessWorkflowRun, formatWorkflowRun, clipTaskOutput, assertOwnership, sleepPollStep, statusFromBackground, rollSpoolText, accountDroppedBytes, renderSpoolBody, stdoutHeadingOf, REPLAY_FACE, SPOOL_REPLAY, INCREMENT_REPLAY, spoolDropNote, droppedGapNote, alreadyTerminalStopNote, terminalTaskSummary, TASK_OUTPUT_MAX_CHARS, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccess, DURABLE_AGENT_HANDLE_RE, } from "./task-registry-shared.js";
12
- export { normalizeAgentName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR } from "./task-registry-shared.js";
12
+ export { normalizeAgentName, DURABLE_AGENT_HEARTBEAT_MS, DURABLE_AGENT_HANDLE_RE, BG_AGENT_REAP_STOP_ERROR, engineAgentName, chosenAgentName } from "./task-registry-shared.js";
13
13
  import { TASK_OUTPUT_TOOL_NAME, TASK_STOP_TOOL_NAME, TASK_OUTPUT_MISSING_ID_MESSAGE, TASK_STOP_MISSING_ID_MESSAGE, TASK_STOP_PARAMS, resolveTaskIdArg, REGISTRY_TASK_TOOL_CAPS, composeTaskOutputDescription, composeTaskOutputParams, composeTaskStopDescription, } from "./task-tool-shape.js";
14
14
  import { durableAgentArmedLane, durableAgentRowProbeLane, beginDurableClaimLane, endDurableClaimLane, reapDurableAgentsLane, noteBackgroundAgentActivityLane, reapStaleSessionBackgroundAgentsLane, releaseDurableTranscriptAnchorLane, bindBackgroundAgentSessionLane, registerBackgroundAgentLane, recordBackgroundAgentOrgAdmissionLane, parkBackgroundAgentLane, reconcileParkedAgentsLane, claimParkedAgentLane, rollbackParkedClaimLane, consumeParkedFlipLane, finalizeParkedResumeLane, settleBackgroundAgentLane, abortBackgroundAgentsForOwnerLane, serveDurableAgentRowLane, resolveBackgroundAgentByNameLane, backgroundAgentCycleSeqLane, activeDelegationHandlesLane, markRetainedContinuationLane, reviveBackgroundAgentLane, settleRevivedAgentLane, unmarkRetainedContinuationLane, attachAgentNotifyLane, deliverToRunningAgentLane, runningBackgroundAgentLabelsLane, runningAgentFooterLane, notFoundRunningAgentsTail, pollBackgroundAgentLane, stopBackgroundAgentLane, } from "./task-registry-agent.js";
15
15
  import { mountRuleFace, toolFace } from "./tool-catalog-entries.js";
@@ -32,6 +32,7 @@ const TASK_PREFIX = {
32
32
  background_agent: "a",
33
33
  monitor: "m",
34
34
  };
35
+ const A_LATER_LEG = Object.freeze({});
35
36
  function noTask(taskId, runningAgents) {
36
37
  return {
37
38
  content: `No task found with ID: ${taskId}${runningAgents ? notFoundRunningAgentsTail(runningAgents) : ""}`,
@@ -871,6 +872,9 @@ export class TaskRegistry {
871
872
  return { legs: [] };
872
873
  return { legs: verb === "output" ? ["outside_read"] : [] };
873
874
  }
875
+ owedDeliveries(access) {
876
+ return this.liveTasks(access).map((t) => this.boundaryLegsOf(t.task_id, access, "output", A_LATER_LEG));
877
+ }
874
878
  async pollTask(id, access, opts = {}) {
875
879
  const taskId = id.trim();
876
880
  const deadline = opts.block ? blockDeadline(opts.timeoutMs, Date.now()) : undefined;
@@ -1017,6 +1021,12 @@ The durable record is still marked running (last update ${new Date(row.updatedAt
1017
1021
  lastGcAt = 0;
1018
1022
  list(access, opts = {}) {
1019
1023
  const limit = Math.min(500, Math.max(1, Math.floor(opts.limit ?? 50)));
1024
+ return this.rowsUnder(access).slice(0, limit);
1025
+ }
1026
+ liveTasks(access) {
1027
+ return this.rowsUnder(access).filter((t) => t.status === "pending" || t.status === "running" || t.status === "parked");
1028
+ }
1029
+ rowsUnder(access) {
1020
1030
  const out = [];
1021
1031
  for (const h of this.handles.values()) {
1022
1032
  if (!canAccess(h, access))
@@ -1034,7 +1044,7 @@ The durable record is still marked running (last update ${new Date(row.updatedAt
1034
1044
  });
1035
1045
  }
1036
1046
  out.sort((a, b) => b.createdAt - a.createdAt);
1037
- return out.slice(0, limit);
1047
+ return out;
1038
1048
  }
1039
1049
  maybeGc(now = Date.now()) {
1040
1050
  if (now - this.lastGcAt < 60_000)
@@ -247,6 +247,24 @@ export interface TaskResult {
247
247
  effectiveReasoning?: import("../brain/reasoning.js").ResolvedReasoning;
248
248
  /** Final assistant text. */
249
249
  result: string;
250
+ /**
251
+ * Where {@link result} was read from: the session-tree entry ids of the committed assistant messages the engine selected
252
+ * as the answer's source, in conversation order — the ids `message_committed.entryId` carries on the stream. One id for
253
+ * an ordinary answer; every member of the continuation chain when a cut answer was continued (`result` is their texts,
254
+ * joined). `result` is the answer's one authority: a committed message can differ from what streamed (engine notes
255
+ * placed at finalize, a degenerate cut trimmed), so a consumer that rendered the stream replaces the named messages'
256
+ * text rows with `result` instead of comparing; one that cannot bind an id (it lost that `message_committed`) reads the
257
+ * named entries from the session rather than guessing which rows they were.
258
+ *
259
+ * EMPTY when `result` was read from no committed message (the run produced no assistant message, or only one that was
260
+ * never appended — an empty failure). A named message may contribute no text (a tool-calling message a park or a stop
261
+ * ended on; a thinking-only head of a continuation chain), so `result` may be empty beside a non-empty list. ABSENT when
262
+ * the provenance is unknown: a record an older engine wrote, a result rebuilt from a checkpoint row alone, or an answer
263
+ * a leg read from a message committed before it began (whose append that leg never saw).
264
+ *
265
+ * Not yet byte-equal: `result` alone drops inline `<think>…</think>` blocks and is trimmed; the named messages keep both.
266
+ */
267
+ resultEntryIds?: readonly string[];
250
268
  /**
251
269
  * Best-effort salvaged assistant text from a terminal FAILURE. Consumption recipe: on a non-`completed`
252
270
  * status read `result` FIRST — most failure terminals (max-turns, budget, tool errors, …) still carry
@@ -296,12 +296,12 @@ export interface TaskSpec {
296
296
  advisorModel?: ModelRef;
297
297
  /** Thinking level. If omitted, a default from the resolved role's `RoleSpec.thinking` applies. */
298
298
  thinking?: ThinkingLevel;
299
- /** This task's role text: it replaces the selected role base (`promptRole`). Text carrying a locked section verbatim
300
- * (an already-assembled prompt) is refused by name (`prompt.assembled_role_refused`). */
299
+ /** This task's role text: it replaces the role base `promptRole` selects; the task names its role base first, above its role's preset (`RoleSpec`).
300
+ * Text carrying a locked section verbatim (an already-assembled prompt) is refused by name (`prompt.assembled_role_refused`). */
301
301
  systemPrompt?: string;
302
- /** The role base `core/role.base` selects: `"general"` (absent), `"code"`, `"coordinator"`, `"cowork"` (rendered from the
303
- * mounted tools and the working directory); `systemPrompt` replaces whichever is selected. Not inherited (a child gets
304
- * the sub-agent persona). A value outside the closed set (`HOST_ROLES`, tested by `isHostRole`) is refused at prepare. */
302
+ /** The role base `core/role.base` selects — `"general"`, `"code"`, `"coordinator"`, `"cowork"` (rendered from the mounted tools and the
303
+ * working directory) — and the run's host role; `systemPrompt` replaces it. A task naming neither takes its role's preset (`RoleSpec.promptRole` /
304
+ * `systemPrompt`) whole; an explicit `"general"` names the general base and ends that chain, absent does not. Not inherited (a child gets the sub-agent persona). Outside the closed set (`HOST_ROLES`, `isHostRole`) ⇒ refused at prepare. */
305
305
  promptRole?: import("../prompt-assembly/catalog/schema.js").HostRole;
306
306
  /** `"minimal"` leaves the core-behavior band out; the locked sections (mode sections in play among them) and
307
307
  * `appendSystemPrompt` stay. Absent ⇒ standard. Rides the parent spec seat to every engine-built child (a clamp-table
@@ -600,14 +600,14 @@ export interface TaskSpec {
600
600
  */
601
601
  deferSelfResolve?: boolean;
602
602
  /**
603
- * R2 双形轴(2026-07-18 裁): which prompt-profile face this task speaks — "simple" (default;
604
- * the short-form tool descriptions + lean system sections, what CC serves every non-claude
605
- * model id) or "classic" (the long-form face, ≈ CC 4.x-era wording — switchable per task/model,
606
- * e.g. serving classic to a model that scores better on it; center distribution rides this field).
607
- * Affects PRESENTATION only (descriptions/section wording), never tool behavior or policy.
608
- * Inherited by delegated children unless their spec overrides.
603
+ * The task's one switch on the prompt's shape: `true` adds the `lean_prompt` trait to the model's declared traits
604
+ * (`Model.promptTraits`), `false` removes it (the long, classic shape of the system sections and tool descriptions),
605
+ * absent leaves the model's answer. It moves no other trait — a model-family trait stays the model's. PRESENTATION
606
+ * only (section wording, tool descriptions), never tool behavior or policy. Inherited by delegated children (and
607
+ * workflow agents) unless their spec writes it; a value that is not a boolean refuses the task
608
+ * (`config.prompt_selector_invalid`).
609
609
  */
610
- promptProfile?: "simple" | "classic";
610
+ promptLean?: boolean;
611
611
  /**
612
612
  * core half — PER-TASK custom sub-agents. Same shape as the boot injection point
613
613
  * ({@link RunnerDeps.agents} / `SubagentToolOptions.agents`): full {@link AgentDefinition} objects
@@ -665,7 +665,7 @@ export interface TaskSpec {
665
665
  * registrations hang handlers on the `classic.*` events the engine's stations raise (tool pre/post/failure/batch,
666
666
  * prompt submit, stop, compaction, permission denied). A delegated child dispatches its parent's task seat as its own
667
667
  * (the parent spec seat fills an unset one). */
668
- mods?: readonly import("./mods/kernel/index.js").ModRegistration<import("./mods/dollar.js").EngineDollar>[];
668
+ mods?: readonly import("./mods/classic-events.js").EngineModRegistration[];
669
669
  /**
670
670
  * The session's SELF-REPORTED presence for the peer directory (`agent` = what it is, `intent` = what
671
671
  * it is doing; each ≤ 120 chars). The engine never writes a directory row: the same object goes out
@@ -1538,6 +1538,11 @@ export interface TaskSpec {
1538
1538
  * the default was off — a probe pinning "no background_tasks frame without opt-in" reds. */
1539
1539
  backgroundTasks?: boolean;
1540
1540
  toolsDelta?: true;
1541
+ /** The notice that a declared MCP server did not connect for this message: its tools are unavailable for now, and it is
1542
+ * tried again when the next message arrives. Rides the leg's first request (a fresh leg's first user message, a resumed leg's continuation),
1543
+ * once per session per server and error. DEFAULT ON — boolean: `false` is the opt-out, a non-boolean is refused at the
1544
+ * task's door (`config.invalid_argument`). BREAKING: the notice used to ride {@link toolsDelta}, and only a turn boundary. */
1545
+ mcpUnavailable?: boolean;
1541
1546
  /** [c209-C] listing family — DEFAULT ON (boolean, not `true`: explicit `false` is the opt-out;
1542
1547
  * see the family carve-out note above). BREAKING (B-3): pre-[c209-C] the default was off. */
1543
1548
  agentListing?: boolean;
@@ -1,4 +1,5 @@
1
1
  import { combinePolicies } from "./tool-policy.js";
2
+ import { namesEveryTool } from "../agents/tool-filter.js";
2
3
  import { clampPermissionMode } from "./ask-origin.js";
3
4
  import { CLAMP_SEATS, clampCellOf, clampCellPath, composeClampSeat, loosensClampSeat } from "./child-clamp-seats.js";
4
5
  export class TaskSpecTightenError extends Error {
@@ -25,7 +26,7 @@ export function tightenTaskSpec(base, overrides) {
25
26
  {
26
27
  const b = base.allowTools;
27
28
  const o = overrides.allowTools;
28
- if (b !== undefined && o !== undefined && !b.includes("*")) {
29
+ if (b !== undefined && o !== undefined && !b.some(namesEveryTool)) {
29
30
  const wider = o.filter((entry) => !b.includes(entry));
30
31
  if (wider.length > 0)
31
32
  throw new TaskSpecTightenError(`tightenTaskSpec: cannot widen allowTools beyond the base list (override names ${JSON.stringify(wider)}; the override may only narrow)`);
@@ -54,6 +54,29 @@ export declare function toolFace(id: string): ToolFaceDeclaration;
54
54
  /** Is `contract` a contract object the catalog minted for an engine definition ({@link toolFace}) — the one record of "the engine
55
55
  * declared this", which a value written by hand (the same id spelled out) is not. */
56
56
  export declare function isCatalogContract(contract: unknown): boolean;
57
+ /**
58
+ * "Does this call dispatch to the ENGINE's own instance of one of these definitions?" — the one judge, read off the call's face:
59
+ * one of the engine's own mount sites mounted the tool (`engineMounted`, the one identity a caller cannot wear), and the
60
+ * contract it carries is the one the catalog gives one of `ids`. Never the name or the contract alone: a caller's tool can take
61
+ * an engine name, and a contract id can be written by hand. False for every other call — a caller's or a protocol peer's tool,
62
+ * a face rebuilt from a park row minted before the row recorded its mount site, a bare request (no face). A row minted since
63
+ * carries the mount site its roster entry had at the park, so the pre-claim recheck of its edit reads this judge's answer at park time.
64
+ */
65
+ export declare function engineMountedAs(ids: readonly string[]): (face: {
66
+ readonly engineMounted?: true;
67
+ readonly contractId: string;
68
+ } | undefined) => boolean;
69
+ /** Is this call's face the engine's own shell tool (either of its two mounts)? */
70
+ export declare const isEngineShellFace: (face: {
71
+ readonly engineMounted?: true;
72
+ readonly contractId: string;
73
+ } | undefined) => boolean;
74
+ /** Is this call's face one of the content-routing tools the engine mounts (question, answer, blocked report)? They route content,
75
+ * act on nothing, and no stored rule governs them: the persisted-rule lane does not judge them and their card offers no rule. */
76
+ export declare const routesContent: (face: {
77
+ readonly engineMounted?: true;
78
+ readonly contractId: string;
79
+ } | undefined) => boolean;
57
80
  /**
58
81
  * The rule face a definition whose schema is BUILT PER MOUNT puts on its instance: its row's primaries only (none ⇒ no rule
59
82
  * face). The row's `params` is the static view's vocabulary, the fullest mount's; a mount's own is read off the schema it
@@ -58,7 +58,7 @@ export const TOOL_CATALOG_ENTRIES = [
58
58
  },
59
59
  {
60
60
  id: "bash", name: "Bash", source: "builtin", definedIn: "src/tools/fs/fs-bash.ts", mountedBy: ["hands"],
61
- cards: ["bash", "readonly_out_of_root", "read_unestablished", "bash_invalid_timeout"],
61
+ cards: ["bash", "readonly_out_of_root", "read_unestablished", "bash_invalid_timeout", "bash_self_kill_refused"],
62
62
  face: {
63
63
  family: "shell", boundaryLegs: ["env"], effect: "write", contentOrigin: "execution", contract: c(FULL_SHELL_CONTRACT_ID),
64
64
  ruleFace: SHELL_RULE_FACE,
@@ -174,6 +174,7 @@ export const ENGINE_CARDS = Object.freeze({
174
174
  read_path_denied: "src/tools/fs/safety.ts",
175
175
  readonly_out_of_root: "src/tools/fs/shell-read-check.ts",
176
176
  read_unestablished: "src/tools/fs/shell-read-check.ts",
177
+ bash_self_kill_refused: "src/tools/fs/pattern-kill-guard.ts",
177
178
  });
178
179
  const byId = new Map();
179
180
  for (const e of TOOL_CATALOG_ENTRIES) {
@@ -190,12 +191,23 @@ export function toolFace(id) {
190
191
  throw new Error(`tool catalog: no definition ${JSON.stringify(id)}`);
191
192
  const face = { contentOrigin: "local", ...structuredClone(e.face) };
192
193
  if (face.contract !== undefined)
193
- CATALOG_CONTRACTS.add(face.contract);
194
+ CATALOG_CONTRACTS.add(Object.freeze(face.contract));
194
195
  return face;
195
196
  }
196
197
  export function isCatalogContract(contract) {
197
198
  return typeof contract === "object" && contract !== null && CATALOG_CONTRACTS.has(contract);
198
199
  }
200
+ export function engineMountedAs(ids) {
201
+ const contracts = new Set(ids.map((id) => {
202
+ const contractId = byId.get(id)?.face.contract?.contractId;
203
+ if (contractId === undefined)
204
+ throw new Error(`tool catalog: ${JSON.stringify(id)} declares no contract — an engine mount is judged by its definition's contract`);
205
+ return contractId;
206
+ }));
207
+ return (face) => face?.engineMounted === true && contracts.has(face.contractId);
208
+ }
209
+ export const isEngineShellFace = engineMountedAs(["bash", "bash-readonly"]);
210
+ export const routesContent = engineMountedAs(["ask-user-question", "structured-output", "report-blocked"]);
199
211
  export function mountRuleFace(id) {
200
212
  const primaryParams = toolFace(id).ruleFace?.primaryParams;
201
213
  return primaryParams === undefined ? undefined : { primaryParams: [...primaryParams] };
@@ -11,6 +11,8 @@ export type ToolCheckStanding = Exclude<PermissionResult, {
11
11
  action: "deny";
12
12
  }>;
13
13
  /** What a reading came to. `minted` on an ask: the reading minted it over an allow (the ask carries no stamp of the round yet).
14
+ * `cleared`: the allow layer's `hook` member cleared the ask, `entries` naming the registrations that spoke (the allow layer
15
+ * records the clearance as it records the member's clear on a `classic.PreToolUse` allow).
14
16
  * `approved`: a person an inherited installation's question went to approved an edit of the call — the gate's approved-edit
15
17
  * pass takes it, as it takes an edit approved at this leg's own question. */
16
18
  export type ToolCheckReading = {
@@ -30,6 +32,7 @@ export type ToolCheckReading = {
30
32
  readonly allow: Extract<PermissionResult, {
31
33
  action: "allow";
32
34
  }>;
35
+ readonly entries: readonly string[];
33
36
  } | {
34
37
  readonly kind: "shadowed";
35
38
  readonly shadows: readonly AllowRuleShadow[];
@@ -53,6 +56,14 @@ export interface ToolCheckCall {
53
56
  readonly request: ToolCallRequest;
54
57
  readonly signal: AbortSignal | undefined;
55
58
  }
59
+ /**
60
+ * The allow layer's `hook` member clearing an ask — an extension's word that the call needs no asking, whichever event spoke
61
+ * it (a `classic.PreToolUse` allow at the head of the layer, a `tool.check` allow behind the read-only arm): the allow over
62
+ * the args the gate judged (the policy's rewrite riding), named by the registrations that spoke.
63
+ */
64
+ export declare function extensionAllowOf(speakers: readonly string[], rewrite: unknown): Extract<PermissionResult, {
65
+ action: "allow";
66
+ }>;
56
67
  /** One chain a gate raises `tool.check` on: its raise over a projection; for the leg's own bus only, the allow layer's
57
68
  * predicate under which its `allow` may clear an ask; for an inherited installation only, the settlement its question takes. */
58
69
  export interface ToolCheckChain {
@@ -1,5 +1,5 @@
1
1
  import { refusalOf } from "./tool-policy.js";
2
- import { allowRuleShadowOf } from "./allow-entry.js";
2
+ import { allowRuleShadowOf, withAllowRuleShadow } from "./allow-entry.js";
3
3
  import { inlineUntrusted } from "./untrusted-text.js";
4
4
  import { failedHandlerClause } from "./mods/stations.js";
5
5
  const STANDS = Object.freeze({ kind: "stands" });
@@ -23,9 +23,14 @@ function readToolCheck(heard, standing, call, mayClear) {
23
23
  }
24
24
  if (standing.action === "allow")
25
25
  return STANDS;
26
+ const entries = heard.by !== undefined ? [heard.by] : [];
26
27
  if (mayClear?.() === true)
27
- return { kind: "cleared", allow: { action: "allow", message: `${who} allowed this call`, decisionReason: "hook", ...rewritten } };
28
- return { kind: "shadowed", shadows: [allowRuleShadowOf("hook", heard.by !== undefined ? [heard.by] : [])] };
28
+ return { kind: "cleared", allow: extensionAllowOf(entries, call.rewrite), entries };
29
+ return { kind: "shadowed", shadows: [allowRuleShadowOf("hook", entries)] };
30
+ }
31
+ export function extensionAllowOf(speakers, rewrite) {
32
+ const who = speakers.length > 0 ? speakers.map((s) => `extension "${inlineUntrusted(s, 80)}"`).join(", ") : "an extension";
33
+ return { action: "allow", message: `${who} allowed this call`, decisionReason: "hook", ...(rewrite !== undefined ? { updatedInput: rewrite } : {}) };
29
34
  }
30
35
  function speakerOf(heard) {
31
36
  return { who: heard.by !== undefined ? `extension "${inlineUntrusted(heard.by, 80)}"` : "an extension", why: heard.reason !== undefined ? `: ${inlineUntrusted(heard.reason, 500)}` : "" };
@@ -38,7 +43,7 @@ export async function readToolChecks(chains, standing, call, project) {
38
43
  let raised = false;
39
44
  let current = standing;
40
45
  let moved;
41
- const shadows = [];
46
+ let shadows = [];
42
47
  for (const chain of chains) {
43
48
  const heard = await chain.raise(project(current, chain.mayClear));
44
49
  if (heard === undefined)
@@ -62,7 +67,7 @@ export async function readToolChecks(chains, standing, call, project) {
62
67
  continue;
63
68
  }
64
69
  if (reading.kind === "shadowed")
65
- shadows.push(...reading.shadows);
70
+ shadows = reading.shadows.reduce(withAllowRuleShadow, shadows);
66
71
  if (reading.kind === "asked") {
67
72
  moved = { ...reading, minted: reading.minted || (moved?.kind === "asked" && moved.minted), ...(moved?.kind === "asked" && moved.marked === true ? { marked: true } : {}) };
68
73
  current = reading.ask;
@@ -75,6 +80,6 @@ export async function readToolChecks(chains, standing, call, project) {
75
80
  if (!raised)
76
81
  return undefined;
77
82
  if (moved?.kind === "asked" && shadows.length > 0)
78
- return { ...moved, ask: { ...moved.ask, allowRuleShadowed: [...(moved.ask.allowRuleShadowed ?? []), ...shadows] } };
83
+ return { ...moved, ask: { ...moved.ask, allowRuleShadowed: shadows.reduce(withAllowRuleShadow, [...(moved.ask.allowRuleShadowed ?? [])]) } };
79
84
  return moved ?? (shadows.length > 0 ? { kind: "shadowed", shadows } : STANDS);
80
85
  }
@@ -34,8 +34,8 @@
34
34
  import type { ToolSpec } from "./types.js";
35
35
  /** The shared tail extractor (BYOM ids may carry provider prefixes — "openrouter/anthropic/claude-fable-5"):
36
36
  * boundary-aware LAST path segment, case-folded. Single source for every model-family/model-id
37
- * comparison site (`isFableFamilyModelId` consumes it too — the prompt-shape axis, semantically
38
- * independent but sharing the one tail-extraction posture). */
37
+ * comparison site (the tool-registration gate's; prompt text never reads a model id — it selects on the model's
38
+ * declared traits). */
39
39
  export declare function modelIdTail(id: string): string;
40
40
  /** One gate class's matching rule (both axes optional; a rule with BOTH axes empty gates nothing —
41
41
  * the per-class OFF shape a deployment reaches by explicitly clearing the axes). */