@sema-agent/core 7.52.0 → 7.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/LICENSE +3 -1
  3. package/README.md +3 -1
  4. package/dist/agents/cross-session-envelope.d.ts +8 -0
  5. package/dist/agents/cross-session-envelope.js +6 -0
  6. package/dist/agents/cross-session-judge.d.ts +21 -1
  7. package/dist/agents/cross-session-judge.js +8 -0
  8. package/dist/agents/cross-session-ref.d.ts +5 -0
  9. package/dist/agents/cross-session-ref.js +1 -0
  10. package/dist/agents/org-delivery-gate.d.ts +122 -0
  11. package/dist/agents/org-delivery-gate.js +69 -0
  12. package/dist/agents/peer-held-queue.d.ts +9 -4
  13. package/dist/agents/peer-held-queue.js +6 -5
  14. package/dist/agents/peer-session-drain.d.ts +35 -6
  15. package/dist/agents/peer-session-drain.js +271 -182
  16. package/dist/agents/read-inbox-tool.d.ts +7 -0
  17. package/dist/agents/read-inbox-tool.js +5 -1
  18. package/dist/agents/send-message-tool.js +3 -4
  19. package/dist/agents/subagent.d.ts +6 -5
  20. package/dist/agents/subagent.js +117 -83
  21. package/dist/agents/tool-filter.d.ts +25 -4
  22. package/dist/agents/tool-filter.js +13 -3
  23. package/dist/brain/anthropic.d.ts +6 -1
  24. package/dist/brain/anthropic.js +4 -4
  25. package/dist/brain/model-presets.js +2 -1
  26. package/dist/brain/route-adjudicator.d.ts +6 -0
  27. package/dist/brain/routing.d.ts +24 -1
  28. package/dist/brain/routing.js +54 -19
  29. package/dist/brain/timeout.js +5 -4
  30. package/dist/core/a2a.d.ts +5 -2
  31. package/dist/core/a2a.js +33 -14
  32. package/dist/core/allow-entry.d.ts +3 -1
  33. package/dist/core/allow-entry.js +3 -2
  34. package/dist/core/approval-object.d.ts +87 -0
  35. package/dist/core/approval-object.js +85 -0
  36. package/dist/core/arg-summary.d.ts +3 -2
  37. package/dist/core/arg-summary.js +17 -11
  38. package/dist/core/ask-origin.d.ts +43 -27
  39. package/dist/core/ask-origin.js +20 -11
  40. package/dist/core/ask-question.d.ts +0 -1
  41. package/dist/core/ask-question.js +4 -67
  42. package/dist/core/ask-unresolvable-notice.d.ts +3 -2
  43. package/dist/core/auto-compaction.d.ts +106 -50
  44. package/dist/core/auto-compaction.js +69 -53
  45. package/dist/core/auto-mode-prompt.d.ts +4 -2
  46. package/dist/core/auto-mode-prompt.js +4 -3
  47. package/dist/core/canonical-json.d.ts +69 -0
  48. package/dist/core/canonical-json.js +130 -8
  49. package/dist/core/checkpoint-requirements.d.ts +13 -7
  50. package/dist/core/checkpoint-requirements.js +4 -1
  51. package/dist/core/checkpoint-store.d.ts +60 -36
  52. package/dist/core/checkpoint-store.js +7 -6
  53. package/dist/core/child-clamp-seats.d.ts +45 -6
  54. package/dist/core/child-clamp-seats.js +56 -4
  55. package/dist/core/compliance.js +3 -1
  56. package/dist/core/consolidate-scope.d.ts +1 -1
  57. package/dist/core/cross-boundary-taint.d.ts +213 -0
  58. package/dist/core/cross-boundary-taint.js +196 -0
  59. package/dist/core/decision-receipt.d.ts +44 -1
  60. package/dist/core/decision-receipt.js +16 -0
  61. package/dist/core/effective-path-target.d.ts +28 -6
  62. package/dist/core/effective-path-target.js +28 -2
  63. package/dist/core/engine-notice.d.ts +47 -4
  64. package/dist/core/engine-notice.js +17 -1
  65. package/dist/core/engine-storage-backend.d.ts +73 -0
  66. package/dist/core/engine-storage-backend.js +1 -0
  67. package/dist/core/file-history-store.d.ts +6 -2
  68. package/dist/core/file-history-store.js +1 -0
  69. package/dist/core/gate-fold.js +13 -4
  70. package/dist/core/gate-lanes.js +41 -34
  71. package/dist/core/gate-outcome.d.ts +18 -9
  72. package/dist/core/governance-codes.d.ts +9 -2
  73. package/dist/core/governance-codes.js +9 -0
  74. package/dist/core/hands-band-screen.d.ts +7 -0
  75. package/dist/core/hands-band-screen.js +32 -0
  76. package/dist/core/hooks.d.ts +21 -19
  77. package/dist/core/hooks.js +6 -5
  78. package/dist/core/locked-config.d.ts +110 -31
  79. package/dist/core/locked-config.js +155 -42
  80. package/dist/core/lsp.d.ts +1 -1
  81. package/dist/core/mcp-probe.js +1 -1
  82. package/dist/core/mcp-server-spec.d.ts +152 -17
  83. package/dist/core/mcp-server-spec.js +223 -40
  84. package/dist/core/mcp.d.ts +21 -14
  85. package/dist/core/mcp.js +59 -54
  86. package/dist/core/memory-engine/engine.d.ts +14 -19
  87. package/dist/core/memory-engine/engine.js +9 -6
  88. package/dist/core/memory-engine/export-bundle.d.ts +1 -1
  89. package/dist/core/memory-engine/export-bundle.js +1 -1
  90. package/dist/core/memory-engine/file-backend.d.ts +2 -6
  91. package/dist/core/memory-engine/file-backend.js +1 -12
  92. package/dist/core/memory.d.ts +3 -3
  93. package/dist/core/mode-policy.d.ts +16 -26
  94. package/dist/core/mode-policy.js +5 -18
  95. package/dist/core/mods/kernel/dispatch.js +13 -15
  96. package/dist/core/mods/kernel/events.d.ts +9 -6
  97. package/dist/core/mods/kernel/events.js +2 -2
  98. package/dist/core/mods/kernel/receive.d.ts +41 -11
  99. package/dist/core/mods/kernel/receive.js +124 -54
  100. package/dist/core/mods/kernel/site-rules.d.ts +80 -15
  101. package/dist/core/mods/kernel/site-rules.js +232 -40
  102. package/dist/core/mods/stations.d.ts +0 -6
  103. package/dist/core/mods/stations.js +0 -7
  104. package/dist/core/mounted-mcp.d.ts +57 -0
  105. package/dist/core/mounted-mcp.js +71 -2
  106. package/dist/core/own-property-receipt.d.ts +13 -0
  107. package/dist/core/own-property-receipt.js +3 -1
  108. package/dist/core/parent-spec-seat.d.ts +12 -15
  109. package/dist/core/parent-spec-seat.js +14 -6
  110. package/dist/core/pause-registry.d.ts +35 -1
  111. package/dist/core/pause-registry.js +10 -0
  112. package/dist/core/permission-rule-consent.d.ts +18 -5
  113. package/dist/core/permission-rule-consent.js +13 -8
  114. package/dist/core/permission-rule-model.d.ts +87 -15
  115. package/dist/core/permission-rule-model.js +87 -8
  116. package/dist/core/permission-rule-org.d.ts +200 -33
  117. package/dist/core/permission-rule-org.js +217 -91
  118. package/dist/core/permission-rule-session.js +2 -2
  119. package/dist/core/permission-rule-store.d.ts +8 -0
  120. package/dist/core/permission-rule-store.js +1 -0
  121. package/dist/core/permission-rule-sync.js +3 -2
  122. package/dist/core/permission-rules.d.ts +7 -1
  123. package/dist/core/permission-rules.js +37 -8
  124. package/dist/core/read-only-shell.d.ts +1 -1
  125. package/dist/core/read-only-shell.js +30 -9
  126. package/dist/core/remote-env.d.ts +41 -1
  127. package/dist/core/remote-env.js +18 -0
  128. package/dist/core/resume-startup-cause.d.ts +18 -0
  129. package/dist/core/resume-startup-cause.js +12 -0
  130. package/dist/core/retention.js +7 -2
  131. package/dist/core/retired-keys.d.ts +8 -2
  132. package/dist/core/retired-keys.js +12 -1
  133. package/dist/core/roles.js +60 -10
  134. package/dist/core/rule-lane-reads.js +1 -1
  135. package/dist/core/runner/approval-feedback.d.ts +46 -0
  136. package/dist/core/runner/approval-feedback.js +41 -0
  137. package/dist/core/runner/compaction-call-options.d.ts +3 -3
  138. package/dist/core/runner/compaction-call-options.js +2 -2
  139. package/dist/core/runner/contracts.d.ts +34 -41
  140. package/dist/core/runner/cross-boundary-lane.d.ts +87 -0
  141. package/dist/core/runner/cross-boundary-lane.js +190 -0
  142. package/dist/core/runner/decide-continuation.d.ts +4 -4
  143. package/dist/core/runner/decide-continuation.js +3 -1
  144. package/dist/core/runner/gate-exit.d.ts +32 -12
  145. package/dist/core/runner/gate-exit.js +77 -34
  146. package/dist/core/runner/inherited-ask-grants.js +2 -2
  147. package/dist/core/runner/mcp-redial.d.ts +52 -10
  148. package/dist/core/runner/mcp-redial.js +38 -9
  149. package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
  150. package/dist/core/runner/permission-rule-lanes.js +22 -10
  151. package/dist/core/runner/person-path-rows.d.ts +5 -3
  152. package/dist/core/runner/person-path-rows.js +2 -2
  153. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -4
  154. package/dist/core/runner/prepare-acquire-reconcile.js +3 -3
  155. package/dist/core/runner/prepare-ask-lane.js +3 -3
  156. package/dist/core/runner/prepare-caps-and-workflow.d.ts +6 -5
  157. package/dist/core/runner/prepare-caps-and-workflow.js +3 -3
  158. package/dist/core/runner/prepare-config-doors.d.ts +58 -15
  159. package/dist/core/runner/prepare-config-doors.js +167 -146
  160. package/dist/core/runner/prepare-context-lane.js +6 -3
  161. package/dist/core/runner/prepare-defer-classify.js +4 -7
  162. package/dist/core/runner/prepare-delegation-surface.d.ts +5 -4
  163. package/dist/core/runner/prepare-delegation-surface.js +8 -7
  164. package/dist/core/runner/prepare-execution-env.d.ts +1 -2
  165. package/dist/core/runner/prepare-execution-env.js +2 -1
  166. package/dist/core/runner/prepare-gate-stations.d.ts +2 -0
  167. package/dist/core/runner/prepare-gate-stations.js +4 -3
  168. package/dist/core/runner/prepare-hands-readface.d.ts +3 -3
  169. package/dist/core/runner/prepare-hands-readface.js +3 -2
  170. package/dist/core/runner/prepare-inherited-gate.d.ts +2 -0
  171. package/dist/core/runner/prepare-inherited-gate.js +3 -2
  172. package/dist/core/runner/prepare-listings.d.ts +1 -1
  173. package/dist/core/runner/prepare-listings.js +4 -2
  174. package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
  175. package/dist/core/runner/prepare-memory-engine-session.js +19 -6
  176. package/dist/core/runner/prepare-memory.d.ts +3 -2
  177. package/dist/core/runner/prepare-memory.js +6 -2
  178. package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
  179. package/dist/core/runner/prepare-offload-wrappers.js +2 -1
  180. package/dist/core/runner/prepare-park-ask.d.ts +1 -1
  181. package/dist/core/runner/prepare-park-ask.js +9 -3
  182. package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
  183. package/dist/core/runner/prepare-policy-chain.js +14 -19
  184. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  185. package/dist/core/runner/prepare-project-context.js +6 -4
  186. package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
  187. package/dist/core/runner/prepare-prompt-assembly.js +20 -16
  188. package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
  189. package/dist/core/runner/prepare-prompt-inputs.js +6 -3
  190. package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
  191. package/dist/core/runner/prepare-protocol-tools.js +19 -12
  192. package/dist/core/runner/prepare-question-face.d.ts +4 -2
  193. package/dist/core/runner/prepare-question-face.js +4 -3
  194. package/dist/core/runner/prepare-safety-scan.d.ts +7 -2
  195. package/dist/core/runner/prepare-safety-scan.js +34 -27
  196. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -2
  197. package/dist/core/runner/prepare-suspend-saga.js +6 -2
  198. package/dist/core/runner/prepare-task.js +22 -19
  199. package/dist/core/runner/prepare-turn-wiring.d.ts +10 -5
  200. package/dist/core/runner/prepare-turn-wiring.js +14 -49
  201. package/dist/core/runner/prepare-wiring-manifest.d.ts +10 -5
  202. package/dist/core/runner/prepare-wiring-manifest.js +9 -6
  203. package/dist/core/runner/prepare-workspace-restore.js +2 -2
  204. package/dist/core/runner/resume-admission.d.ts +4 -1
  205. package/dist/core/runner/resume-admission.js +16 -14
  206. package/dist/core/runner/resume-apply.js +4 -4
  207. package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
  208. package/dist/core/runner/resume-internals-and-config.js +3 -8
  209. package/dist/core/runner/resume-policy-outcome.d.ts +2 -2
  210. package/dist/core/runner/resume-policy-outcome.js +18 -15
  211. package/dist/core/runner/resume-preflight.js +2 -2
  212. package/dist/core/runner/resume-review-outcome.js +3 -3
  213. package/dist/core/runner/retired-runner-deps.d.ts +5 -6
  214. package/dist/core/runner/retired-runner-deps.js +1 -4
  215. package/dist/core/runner/run-leg.js +97 -43
  216. package/dist/core/runner/run-recovery-lanes.js +5 -3
  217. package/dist/core/runner/run-settle-and-teardown.js +2 -0
  218. package/dist/core/runner/run-terminal-adoption.js +21 -9
  219. package/dist/core/runner/run-turn-boundary.js +9 -3
  220. package/dist/core/runner/runtask.js +1 -1
  221. package/dist/core/runner/session-file-state-replay.d.ts +5 -2
  222. package/dist/core/runner/session-file-state-replay.js +3 -2
  223. package/dist/core/runner/skills-seat.d.ts +15 -0
  224. package/dist/core/runner/skills-seat.js +57 -0
  225. package/dist/core/runner/stream-steer-verb.js +2 -2
  226. package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
  227. package/dist/core/runner/sub-agent-deny-lists.js +7 -5
  228. package/dist/core/runner/synthetic-tools.d.ts +5 -2
  229. package/dist/core/runner/synthetic-tools.js +2 -12
  230. package/dist/core/runner/tool-face-overlay.d.ts +24 -6
  231. package/dist/core/runner/tool-face-overlay.js +24 -15
  232. package/dist/core/runner-deps.d.ts +37 -22
  233. package/dist/core/session-policy-store.d.ts +19 -0
  234. package/dist/core/session-policy-store.js +22 -2
  235. package/dist/core/session-store.d.ts +35 -16
  236. package/dist/core/session-store.js +20 -12
  237. package/dist/core/{shell-lexer.d.ts → shell-run-candidates.d.ts} +36 -12
  238. package/dist/core/{shell-lexer.js → shell-run-candidates.js} +145 -225
  239. package/dist/core/shell-wrapper-table.d.ts +5 -3
  240. package/dist/core/shell-wrapper-table.js +1 -1
  241. package/dist/core/store-contracts/checkpoint-store-contract.js +2 -2
  242. package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
  243. package/dist/core/store-contracts/session-store-contract.d.ts +49 -0
  244. package/dist/core/store-contracts/session-store-contract.js +639 -0
  245. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +12 -0
  246. package/dist/core/store-contracts/session-store-incarnation-contract.js +5 -2
  247. package/dist/core/task-event.d.ts +44 -6
  248. package/dist/core/task-notification.js +2 -2
  249. package/dist/core/task-registry-agent.js +1 -0
  250. package/dist/core/task-registry-shared.d.ts +5 -0
  251. package/dist/core/task-registry.d.ts +7 -0
  252. package/dist/core/task-registry.js +17 -0
  253. package/dist/core/task-result.d.ts +1 -1
  254. package/dist/core/task-spec.d.ts +7 -7
  255. package/dist/core/tighten-task-spec.d.ts +6 -4
  256. package/dist/core/tighten-task-spec.js +2 -2
  257. package/dist/core/tool-catalog-entries.d.ts +1 -1
  258. package/dist/core/tool-catalog-entries.js +52 -52
  259. package/dist/core/tool-face-reader.d.ts +49 -0
  260. package/dist/core/tool-face-reader.js +94 -0
  261. package/dist/core/tool-face.d.ts +17 -8
  262. package/dist/core/tool-face.js +1 -0
  263. package/dist/core/tool-policy.d.ts +67 -23
  264. package/dist/core/tool-policy.js +72 -60
  265. package/dist/core/tool-roster.d.ts +46 -28
  266. package/dist/core/tool-roster.js +91 -14
  267. package/dist/core/tool-spec-members.js +2 -2
  268. package/dist/core/tool-spec.d.ts +20 -4
  269. package/dist/core/tools.js +2 -0
  270. package/dist/core/trace.d.ts +24 -2
  271. package/dist/core/types.d.ts +3 -3
  272. package/dist/core/types.js +1 -1
  273. package/dist/core/untrusted-text.d.ts +23 -0
  274. package/dist/core/untrusted-text.js +10 -10
  275. package/dist/core/user-attachment.d.ts +56 -2
  276. package/dist/core/user-attachment.js +139 -56
  277. package/dist/core/wiring-manifest.d.ts +4 -2
  278. package/dist/engine/compaction/compaction.d.ts +2 -2
  279. package/dist/engine/compaction/utils.d.ts +2 -2
  280. package/dist/engine/harness/agent-harness.js +2 -1
  281. package/dist/engine/harness/types.d.ts +10 -4
  282. package/dist/engine/llm/types.d.ts +7 -2
  283. package/dist/engine/llm/types.js +2 -1
  284. package/dist/engine/loop/agent-loop.d.ts +12 -1
  285. package/dist/engine/loop/agent-loop.js +17 -5
  286. package/dist/engine/loop/types.d.ts +7 -1
  287. package/dist/engine/session/repo-utils.d.ts +5 -0
  288. package/dist/engine/session/repo-utils.js +9 -0
  289. package/dist/engine/session/storage-base.js +2 -2
  290. package/dist/index.d.ts +37 -17
  291. package/dist/index.js +31 -14
  292. package/dist/internal/harness.d.ts +1 -0
  293. package/dist/internal/harness.js +1 -0
  294. package/dist/internal/llm.d.ts +1 -1
  295. package/dist/internal/llm.js +1 -1
  296. package/dist/orchestration/goal.d.ts +24 -1
  297. package/dist/orchestration/goal.js +3 -2
  298. package/dist/orchestration/run-workflow-tool.d.ts +3 -0
  299. package/dist/orchestration/run-workflow-tool.js +1 -0
  300. package/dist/orchestration/workflow-governance.d.ts +1 -1
  301. package/dist/orchestration/workflow.d.ts +3 -0
  302. package/dist/orchestration/workflow.js +2 -1
  303. package/dist/prompt-assembly/artifact-store.d.ts +44 -9
  304. package/dist/prompt-assembly/artifact-store.js +38 -12
  305. package/dist/prompt-assembly/artifact.d.ts +12 -11
  306. package/dist/prompt-assembly/artifact.js +52 -21
  307. package/dist/prompt-assembly/assemble.d.ts +2 -0
  308. package/dist/prompt-assembly/assemble.js +2 -1
  309. package/dist/prompt-assembly/catalog/index.js +2 -1
  310. package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
  311. package/dist/prompt-assembly/catalog/memory.js +6 -0
  312. package/dist/prompt-assembly/catalog/schema.d.ts +19 -2
  313. package/dist/prompt-assembly/catalog/schema.js +3 -0
  314. package/dist/prompt-assembly/composer.d.ts +2 -0
  315. package/dist/prompt-assembly/composer.js +1 -1
  316. package/dist/prompt-assembly/overlay.d.ts +21 -11
  317. package/dist/prompt-assembly/overlay.js +57 -19
  318. package/dist/prompt-assembly/select.d.ts +21 -6
  319. package/dist/prompt-assembly/select.js +41 -4
  320. package/dist/prompts/default.d.ts +1 -12
  321. package/dist/prompts/default.js +0 -3
  322. package/dist/shell/lex.d.ts +87 -8
  323. package/dist/shell/lex.js +283 -49
  324. package/dist/stores/file/index.d.ts +8 -6
  325. package/dist/stores/file/permission-rule-store.d.ts +1 -1
  326. package/dist/stores/file/permission-rule-store.js +2 -1
  327. package/dist/tools/artifact/artifact-tool.js +14 -3
  328. package/dist/tools/fs/bash-program-position.d.ts +3 -15
  329. package/dist/tools/fs/bash-program-position.js +3 -10
  330. package/dist/tools/fs/bash-readonly-classifier.js +2 -0
  331. package/dist/tools/fs/fs-bash.d.ts +3 -3
  332. package/dist/tools/fs/fs-bash.js +72 -101
  333. package/dist/tools/fs/fs-read.d.ts +12 -0
  334. package/dist/tools/fs/fs-read.js +10 -9
  335. package/dist/tools/fs/fs-shared.d.ts +27 -31
  336. package/dist/tools/fs/fs-shared.js +12 -15
  337. package/dist/tools/fs/fs-write.js +1 -1
  338. package/dist/tools/fs/index.js +2 -2
  339. package/dist/tools/fs/read-deny-home.d.ts +1 -1
  340. package/dist/tools/fs/read-deny-home.js +5 -4
  341. package/dist/tools/fs/read-deny.d.ts +16 -3
  342. package/dist/tools/fs/read-deny.js +12 -9
  343. package/dist/tools/fs/safety.d.ts +7 -6
  344. package/dist/tools/fs/shell-read-bindings.d.ts +5 -3
  345. package/dist/tools/fs/shell-read-bindings.js +15 -16
  346. package/dist/tools/fs/shell-read-device.js +1 -1
  347. package/dist/tools/fs/shell-read-plan.js +36 -47
  348. package/dist/tools/fs/shell-read-word.d.ts +1 -6
  349. package/dist/tools/fs/shell-read-word.js +2 -20
  350. package/dist/tools/fs/shell-reentry-text.js +1 -1
  351. package/dist/tools/web.d.ts +2 -2
  352. package/package.json +4 -1
  353. package/test/export-surface.snapshot.json +5651 -5457
  354. package/wire-changes/core@7.53.0.json +1968 -0
  355. package/wire-changes/core@7.54.0.json +2870 -0
  356. package/dist/core/shell-scan.d.ts +0 -60
  357. package/dist/core/shell-scan.js +0 -183
@@ -2,10 +2,10 @@ import { Type } from "typebox";
2
2
  import { isAbsolute } from "node:path";
3
3
  import { backgroundChildTerminal } from "../core/delegation-frames.js";
4
4
  import { bindDelegationName } from "../core/delegation-name.js";
5
- import { resumeStartupCauseOf } from "../core/resume-startup-cause.js";
6
- import { errorCodeOf } from "../core/runner/terminal-account.js";
7
- import { applyParentSpecSeat, memoryTurnedOff, parentSpecSeatOfCtx } from "../core/parent-spec-seat.js";
8
- import { assertClampRecord, childClampSeats, clampSeatsOf, clampSourceOf, engineHeadlessLegSeats, foldClampSources, postureUnderClamps } from "../core/child-clamp-seats.js";
5
+ import { resumeRefusalDetailOf, resumeStartupCauseOf } from "../core/resume-startup-cause.js";
6
+ import { errorCodeOf, thrownFailureOf } from "../core/runner/terminal-account.js";
7
+ import { applyParentSpecSeat, parentSpecSeatOfCtx } from "../core/parent-spec-seat.js";
8
+ import { applyClampSeats, assertClampRecord, childClampSeats, clampSeatsOf, clampSourceOf, engineHeadlessLegSeats, foldClampSources, postureUnderClamps } from "../core/child-clamp-seats.js";
9
9
  import { assertNoRetiredKeys } from "../core/retired-keys.js";
10
10
  import { stripSpawnTurnQuestionFace } from "../core/ask-question.js";
11
11
  import { withDelegationProvenance } from "../core/tool-policy.js";
@@ -265,6 +265,11 @@ export function forkGovernanceDenial(enableFork, allowFork) {
265
265
  return "principal";
266
266
  return undefined;
267
267
  }
268
+ const UNDECLARED_EXTRA_TOOL_REFUSAL = {
269
+ undeclared_name: "the extraTools factory of this delegation tool injected a tool its declared extra tools do not name — the declaration is the upper bound of what the factory may inject.",
270
+ undeclared_origin: "the extraTools factory of this delegation tool injected a tool of a content class beyond the one its declared extra tools state — the declaration is the upper bound of what the factory may inject.",
271
+ };
272
+ const WORKTREE_NOT_A_REPOSITORY = "isolation.not_a_repository";
268
273
  const worktreeUnavailableSentence = (reason) => `Sub-agent not started: isolation "worktree" is unavailable on this run (${reason}). Retry without the isolation parameter.`;
269
274
  const WORKTREE_UNAVAILABLE = {
270
275
  readOnly: worktreeUnavailableSentence("no worktree capability — a read-only run mints no worktree"),
@@ -273,7 +278,20 @@ const WORKTREE_UNAVAILABLE = {
273
278
  seatSilent: worktreeUnavailableSentence("the runner this tool runs children on does not declare whether it can place a child in a tree other than the caller's (its seat has no canRerootChild), and an undeclared answer is read as no; use a Runner, or add that method to the seat"),
274
279
  };
275
280
  const placementRefused = (terminal) => terminal?.kind === "failed" && terminal.code === "isolation.unavailable";
276
- const isolationUnavailable = (content) => ({
281
+ const NOT_STARTED_RESULTS = new WeakSet();
282
+ function notStartedResult(result) {
283
+ const details = result.details;
284
+ if (typeof details === "object" && details !== null)
285
+ NOT_STARTED_RESULTS.add(details);
286
+ return result;
287
+ }
288
+ export function isNotStartedDelegationResult(result) {
289
+ if (typeof result !== "object" || result === null)
290
+ return false;
291
+ const details = result.details;
292
+ return typeof details === "object" && details !== null && NOT_STARTED_RESULTS.has(details);
293
+ }
294
+ const isolationUnavailable = (content) => notStartedResult({
277
295
  isError: true,
278
296
  content,
279
297
  details: { error: "isolation.unavailable" },
@@ -285,7 +303,7 @@ export function createSubagentWorktreeHelper(baseEnv, repoRoot) {
285
303
  const probe = await baseEnv.exec("git rev-parse --is-inside-work-tree", { cwd: repoRoot });
286
304
  if (!probe.ok || probe.value.exitCode !== 0) {
287
305
  const detail = probe.ok ? (probe.value.stderr || probe.value.stdout).trim().split("\n")[0] : thrownText(probe.error);
288
- throw new Error(`the working directory ${repoRoot} is not a git repository${detail ? ` (${detail})` : ""}`);
306
+ throw Object.assign(new Error(`the working directory ${repoRoot} is not a git repository${detail ? ` (${detail})` : ""}`), { code: WORKTREE_NOT_A_REPOSITORY });
289
307
  }
290
308
  const { env, worktreeDir } = await addWorktree(baseEnv, {
291
309
  repoRoot,
@@ -492,10 +510,11 @@ function createSteerHandle(stream, parentToolCallId, agentName, settled, retain)
492
510
  const RETIRED_RESUME_CLAMP_KEYS = Object.freeze({
493
511
  "currentClamps.readFaceRoots": 'the waker\'s read-face clamp is `currentClamps.readFace: "roots"` (the clamp table\'s own seat name)',
494
512
  "currentClamps.writeFaceRoots": 'the waker\'s write-face clamp is `currentClamps.writeFace: "roots"` (the clamp table\'s own seat name)',
513
+ "currentClamps.memoryOff": "the waker's memory-off floor is `currentClamps.memory: { enabled: false }` (the clamp table's own seat, with the one member it clamps)",
495
514
  });
496
515
  export function createSubagentResume(deps) {
497
516
  assertNoRetiredKeys(deps, RETIRED_RESUME_CLAMP_KEYS, "createSubagentResume");
498
- assertClampRecord(deps.currentClamps, "createSubagentResume currentClamps", undefined, ["memoryOff"]);
517
+ assertClampRecord(deps.currentClamps, "createSubagentResume currentClamps");
499
518
  const notifier = createSafeNotifier(deps.onNotifyError !== undefined ? { onError: deps.onNotifyError } : undefined);
500
519
  const resume = async (content) => {
501
520
  const ledger = deps.ledger;
@@ -555,17 +574,15 @@ export function createSubagentResume(deps) {
555
574
  entry.resumeCount += 1;
556
575
  entry.cycleSeq += 1;
557
576
  const wakeClamps = foldClampSources(entry.specSnapshot, deps.currentClamps);
558
- const resumeSpec = {
577
+ const resumeSpec = applyClampSeats({
559
578
  ...entry.specSnapshot,
560
579
  objective: createResumePrompt(marker, content, deps.peerOrigin !== undefined ? "peer" : "operator"),
561
580
  sessionId: entry.childSessionId,
562
581
  requireExistingSession: true,
563
582
  ...(deps.currentOnQuestion !== undefined ? { onQuestion: deps.currentOnQuestion } : {}),
564
583
  ...childClampSeats(wakeClamps),
565
- ...clampSeatsOf(wakeClamps, "specSeat"),
566
- ...(deps.currentClamps?.memoryOff === true ? { memory: memoryTurnedOff(entry.specSnapshot.memory) } : {}),
567
584
  signal: abort.signal,
568
- };
585
+ }, clampSeatsOf(wakeClamps, "specSeat"));
569
586
  if (deps.registry !== undefined && deps.taskId !== undefined && deps.taskAccess !== undefined) {
570
587
  const revived = await deps.registry.reviveBackgroundAgent(deps.taskId, deps.taskAccess, abort);
571
588
  if (!revived.ok) {
@@ -1063,10 +1080,10 @@ function chargeLocalDelegationInFlight(anchor, key) {
1063
1080
  live.delete(key);
1064
1081
  };
1065
1082
  }
1066
- const spawnAbortedResult = (wt) => ({
1083
+ const spawnAbortedResult = (wt, fault) => notStartedResult({
1067
1084
  isError: true,
1068
1085
  content: `Sub-agent not started: the delegating call was aborted.${wt ? `\n${wt}` : ""}`,
1069
- details: { error: "aborted" },
1086
+ details: { error: "aborted", ...fault },
1070
1087
  });
1071
1088
  const noopRelease = () => undefined;
1072
1089
  const DELEGATION_POOL_DEFAULT_SCOPE = "default";
@@ -1460,22 +1477,22 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1460
1477
  const parentSpecSeat = parentSpecSeatOfCtx(ctx);
1461
1478
  const reviveClaim = ctx.reviveClaim;
1462
1479
  if (reviveClaim !== undefined && opts.background === undefined) {
1463
- return {
1480
+ return notStartedResult({
1464
1481
  isError: true,
1465
1482
  content: "Sub-agent not revived: this delegation tool has no background surface (run_in_background is not available here), and a revival is a background run by definition.",
1466
1483
  details: { error: "revive.no_background" },
1467
- };
1484
+ });
1468
1485
  }
1469
1486
  const prompt = String(a.prompt ?? "").trim();
1470
1487
  if (!prompt) {
1471
- return { isError: true, content: "Sub-agent not started: 'prompt' was empty.", details: { error: "empty prompt" } };
1488
+ return notStartedResult({ isError: true, content: "Sub-agent not started: 'prompt' was empty.", details: { error: "empty prompt" } });
1472
1489
  }
1473
1490
  if (a.subagent_type !== undefined && typeof a.subagent_type !== "string") {
1474
- return {
1491
+ return notStartedResult({
1475
1492
  isError: true,
1476
1493
  content: `Sub-agent not started: subagent_type must be a string. Available subagent_type values: ${acceptedSubagentTypes().join(", ")}.`,
1477
1494
  details: { error: "unknown subagent_type" },
1478
- };
1495
+ });
1479
1496
  }
1480
1497
  const requestedType = a.subagent_type ?? "";
1481
1498
  let rawType = requestedType;
@@ -1485,11 +1502,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1485
1502
  const wanted = normalizeSubagentType(requestedType);
1486
1503
  const hits = wanted === "" ? [] : accepted.filter((n) => normalizeSubagentType(n) === wanted);
1487
1504
  if (hits.length > 1) {
1488
- return {
1505
+ return notStartedResult({
1489
1506
  isError: true,
1490
1507
  content: `Sub-agent not started: subagent_type "${requestedType}" is ambiguous — it matches ${hits.join(", ")}. Use the exact name.`,
1491
1508
  details: { error: "ambiguous subagent_type" },
1492
- };
1509
+ });
1493
1510
  }
1494
1511
  if (hits.length === 1)
1495
1512
  rawType = hits[0];
@@ -1497,62 +1514,62 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1497
1514
  }
1498
1515
  const wantsFork = forkOffered && rawType === FORK_SUBAGENT_TYPE;
1499
1516
  if (reviveClaim !== undefined && wantsFork) {
1500
- return { isError: true, content: `Sub-agent not revived: a "${FORK_SUBAGENT_TYPE}" agent cannot be revived — launch a new agent with the needed context instead.`, details: { error: "revive.fork_unsupported" } };
1517
+ return notStartedResult({ isError: true, content: `Sub-agent not revived: a "${FORK_SUBAGENT_TYPE}" agent cannot be revived — launch a new agent with the needed context instead.`, details: { error: "revive.fork_unsupported" } });
1501
1518
  }
1502
1519
  const omitted = rawType === "" || (!generalPurposeShadowed && rawType === GENERAL_PURPOSE_SUBAGENT_TYPE);
1503
1520
  const def = hasAgents && !wantsFork && !omitted ? agentMap.get(rawType) : undefined;
1504
1521
  const wantsBackground = opts.background !== undefined && (a.run_in_background !== false || def?.background === true);
1505
1522
  const spawnAgentType = wantsFork ? FORK_SUBAGENT_TYPE : omitted ? GENERAL_PURPOSE_SUBAGENT_TYPE : rawType;
1506
1523
  if (!def && !wantsFork && !omitted) {
1507
- return {
1524
+ return notStartedResult({
1508
1525
  isError: true,
1509
1526
  content: `Sub-agent not started: unknown subagent_type "${rawType}". Available subagent_type values: ${acceptedSubagentTypes().join(", ")}.`,
1510
1527
  details: { error: "unknown subagent_type" },
1511
- };
1528
+ });
1512
1529
  }
1513
1530
  const allowFlaw = toolNameListFlaw(delegationListWhere(toolName, def?.name), "allowed", def !== undefined ? def.allowTools : opts.allowTools);
1514
1531
  if (allowFlaw !== undefined)
1515
- return { isError: true, content: `Sub-agent not started: ${inlineUntrusted(allowFlaw, 480)}`, details: { error: "config.agent.unknown_tool" } };
1532
+ return notStartedResult({ isError: true, content: `Sub-agent not started: ${inlineUntrusted(allowFlaw, 480)}`, details: { error: "config.agent.unknown_tool" } });
1516
1533
  const denyFlaw = toolNameListFlaw(delegationListWhere(toolName, def?.name), "denied", def !== undefined ? def.denyTools : opts.denyTools);
1517
1534
  if (denyFlaw !== undefined)
1518
- return { isError: true, content: `Sub-agent not started: ${inlineUntrusted(denyFlaw, 480)}`, details: { error: "config.agent.unknown_tool" } };
1535
+ return notStartedResult({ isError: true, content: `Sub-agent not started: ${inlineUntrusted(denyFlaw, 480)}`, details: { error: "config.agent.unknown_tool" } });
1519
1536
  if (a.name !== undefined && typeof a.name !== "string") {
1520
- return { isError: true, content: "Sub-agent not started: name must be a string.", details: { error: "name.invalid" } };
1537
+ return notStartedResult({ isError: true, content: "Sub-agent not started: name must be a string.", details: { error: "name.invalid" } });
1521
1538
  }
1522
1539
  const agentName = a.name;
1523
1540
  if (agentName !== undefined) {
1524
1541
  if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(agentName)) {
1525
- return {
1542
+ return notStartedResult({
1526
1543
  isError: true,
1527
1544
  content: "Sub-agent not started: name must start with a letter or digit and contain only letters, digits, underscores, or hyphens (max 64 chars).",
1528
1545
  details: { error: "name.invalid" },
1529
- };
1546
+ });
1530
1547
  }
1531
1548
  if (reservedPeerNameReason(agentName) !== undefined) {
1532
- return { isError: true, content: normalizePeerName(agentName) === "main" ? 'Sub-agent not started: "main" is reserved — SendMessage routes it to the main conversation.' : 'Sub-agent not started: name must not be a reserved name ("main", "team-lead", "user" or "system", in any spelling) or have the shape of an agent id — those already address an agent directly.', details: { error: "name.reserved" } };
1549
+ return notStartedResult({ isError: true, content: normalizePeerName(agentName) === "main" ? 'Sub-agent not started: "main" is reserved — SendMessage routes it to the main conversation.' : 'Sub-agent not started: name must not be a reserved name ("main", "team-lead", "user" or "system", in any spelling) or have the shape of an agent id — those already address an agent directly.', details: { error: "name.reserved" } });
1533
1550
  }
1534
1551
  if (ctx.spawnedAgentName !== undefined && reviveClaim === undefined) {
1535
- return {
1552
+ return notStartedResult({
1536
1553
  isError: true,
1537
1554
  content: "Sub-agent not started: teammates cannot spawn other teammates — the team roster is flat. To spawn a subagent instead, omit the `name` parameter.",
1538
1555
  details: { error: "name.nested_teammate" },
1539
- };
1556
+ });
1540
1557
  }
1541
1558
  }
1542
1559
  if (a.cwd !== undefined && typeof a.cwd !== "string") {
1543
- return { isError: true, content: "Sub-agent not started: cwd must be an absolute path string.", details: { error: "cwd.relative" } };
1560
+ return notStartedResult({ isError: true, content: "Sub-agent not started: cwd must be an absolute path string.", details: { error: "cwd.relative" } });
1544
1561
  }
1545
1562
  const childCwd = a.cwd;
1546
1563
  if (childCwd !== undefined) {
1547
1564
  if (!isAbsolute(childCwd)) {
1548
- return { isError: true, content: "Sub-agent not started: cwd must be an absolute path.", details: { error: "cwd.relative" } };
1565
+ return notStartedResult({ isError: true, content: "Sub-agent not started: cwd must be an absolute path.", details: { error: "cwd.relative" } });
1549
1566
  }
1550
1567
  if ((a.isolation ?? def?.isolation) === "worktree") {
1551
- return {
1568
+ return notStartedResult({
1552
1569
  isError: true,
1553
1570
  content: 'Sub-agent not started: cwd and isolation "worktree" are mutually exclusive — the worktree defines its own working directory.',
1554
1571
  details: { error: "cwd.isolation_conflict" },
1555
- };
1572
+ });
1556
1573
  }
1557
1574
  }
1558
1575
  if (wantsFork) {
@@ -1560,21 +1577,21 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1560
1577
  const who = ctx.forkAccess.denied === "task"
1561
1578
  ? "this task (enableFork: false)"
1562
1579
  : `this principal (runtimeCaps.allowFork: false)`;
1563
- return {
1580
+ return notStartedResult({
1564
1581
  isError: true,
1565
1582
  content: `Sub-agent not started: subagent_type "${FORK_SUBAGENT_TYPE}" is disabled for ${who}. Delegate without subagent_type instead.`,
1566
1583
  details: { error: "fork.disabled" },
1567
- };
1584
+ });
1568
1585
  }
1569
1586
  if (ctx.insideFork === true) {
1570
- return { isError: true, content: `Sub-agent not started: subagent_type "${FORK_SUBAGENT_TYPE}" is not available inside a forked agent.`, details: { error: "fork.nested" } };
1587
+ return notStartedResult({ isError: true, content: `Sub-agent not started: subagent_type "${FORK_SUBAGENT_TYPE}" is not available inside a forked agent.`, details: { error: "fork.nested" } });
1571
1588
  }
1572
1589
  if (ctx.sessionId === undefined || (ctx.hostSessionFork === undefined && !hasSessionFork(opts.runner.sessions))) {
1573
- return {
1590
+ return notStartedResult({
1574
1591
  isError: true,
1575
1592
  content: `Sub-agent not started: subagent_type "${FORK_SUBAGENT_TYPE}" is unavailable here (this run has no fork-capable durable session). Delegate without subagent_type instead.`,
1576
1593
  details: { error: "fork.unavailable" },
1577
- };
1594
+ });
1578
1595
  }
1579
1596
  }
1580
1597
  const modelObjectForm = typeof a.model === "object" &&
@@ -1584,18 +1601,18 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1584
1601
  typeof a.model.api === "string";
1585
1602
  if (a.model !== undefined && typeof a.model !== "string" && !modelObjectForm) {
1586
1603
  const typeDesc = Array.isArray(a.model) ? "an array" : a.model === null ? "null" : typeof a.model === "object" ? "an object" : `a ${typeof a.model}`;
1587
- return {
1604
+ return notStartedResult({
1588
1605
  isError: true,
1589
1606
  content: `Sub-agent not started: \`model\` must be a model name (string) from this deployment's catalog — got ${typeDesc}. Omit the parameter to run the agent type's own model.`,
1590
1607
  details: { error: "model.invalid" },
1591
- };
1608
+ });
1592
1609
  }
1593
1610
  if (typeof a.model === "string" && a.model.trim() === "" && !wantsFork && reviveClaim === undefined) {
1594
- return {
1611
+ return notStartedResult({
1595
1612
  isError: true,
1596
1613
  content: "Sub-agent not started: `model` was empty. Name a model from this deployment's catalog, or omit the parameter to run the agent type's own model.",
1597
1614
  details: { error: "model.empty" },
1598
- };
1615
+ });
1599
1616
  }
1600
1617
  const requestedModel = typeof a.model === "string" && a.model.trim() !== "" ? a.model.trim() : undefined;
1601
1618
  let perCallModel;
@@ -1640,11 +1657,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1640
1657
  budget -= k.length + 2;
1641
1658
  }
1642
1659
  const rosterEcho = shown.length === rosterKeys.length ? shown.join(", ") : `${shown.join(", ")}, … (${rosterKeys.length - shown.length} more)`;
1643
- return {
1660
+ return notStartedResult({
1644
1661
  isError: true,
1645
1662
  content: `Sub-agent not started: unknown model "${inlineUntrusted(requestedModel, 80)}". Available model values: ${inlineUntrusted(rosterEcho, ROSTER_ECHO_MAX + 32)}. Omit \`model\` to run the agent type's own model, or inherit the caller's.`,
1646
1663
  details: { error: "model.unknown" },
1647
- };
1664
+ });
1648
1665
  }
1649
1666
  }
1650
1667
  }
@@ -1693,11 +1710,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1693
1710
  const inheritedSkillGrants = readSkillGrantCapture(ctx.activeSkillGrants?.());
1694
1711
  const inheritedAllowedTools = ctx.activeRequestAllowedTools?.();
1695
1712
  if (inheritedSkillGrants === undefined) {
1696
- return {
1713
+ return notStartedResult({
1697
1714
  isError: true,
1698
1715
  content: "Sub-agent not started: the parent's skill grants could not be read for the child (an unrecognizable capture); a child started without them would lose the parent's disallowed-tools refusals.",
1699
1716
  details: { error: "skill_grants.unreadable" },
1700
- };
1717
+ });
1701
1718
  }
1702
1719
  let worktreeDir;
1703
1720
  if (reviveClaim === undefined && (a.isolation ?? def?.isolation) === "worktree") {
@@ -1711,15 +1728,18 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1711
1728
  worktreeDir = (await iso.mint(ctx.toolCallId)).worktreeDir;
1712
1729
  }
1713
1730
  catch (e) {
1714
- return {
1731
+ return notStartedResult({
1715
1732
  isError: true,
1716
- content: `Sub-agent not started: worktree isolation failed — ${thrownText(e)}. Retry without the isolation parameter, or fix the repository state.`,
1717
- details: { error: "isolation.failed" },
1718
- };
1733
+ content: errorCodeOf(e) === WORKTREE_NOT_A_REPOSITORY
1734
+ ? "Sub-agent not started: worktree isolation failed — the working directory is not a git repository. Retry without the isolation parameter."
1735
+ : "Sub-agent not started: worktree isolation failed. Retry without the isolation parameter, or fix the repository state.",
1736
+ details: { error: "isolation.failed", cause: thrownText(e) },
1737
+ });
1719
1738
  }
1720
1739
  }
1721
1740
  let worktreeKeptPath;
1722
1741
  let childPlacement;
1742
+ let worktreeFault;
1723
1743
  const finishWorktree = async (terminal) => {
1724
1744
  if (worktreeDir === undefined)
1725
1745
  return undefined;
@@ -1737,9 +1757,15 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1737
1757
  }
1738
1758
  catch (e) {
1739
1759
  worktreeKeptPath = worktreeDir;
1740
- return `worktree: ${worktreeDir} (cleanup check failed: ${thrownText(e)})`;
1760
+ worktreeFault = thrownText(e);
1761
+ return `worktree: ${worktreeDir} (cleanup check failed — the directory is kept on disk)`;
1741
1762
  }
1742
1763
  };
1764
+ const reportedWorktreeLine = (line) => (line !== undefined && worktreeFault !== undefined ? `${line}: ${worktreeFault}` : line);
1765
+ const faultDetails = (cause) => ({
1766
+ ...(cause !== undefined ? { cause: thrownText(cause) } : {}),
1767
+ ...(worktreeFault !== undefined ? { worktreeCause: worktreeFault } : {}),
1768
+ });
1743
1769
  let injectedTools = [];
1744
1770
  let extraToolsNote;
1745
1771
  const treeBudget = extraToolsBudget ?? { used: 0 };
@@ -1779,13 +1805,13 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
1779
1805
  }
1780
1806
  const notStarted = async (why, details) => {
1781
1807
  const wt = await finishWorktree();
1782
- return { isError: true, content: `Sub-agent not started: ${why.slice(0, 1600)}${wt ? `\n${wt}` : ""}`, details };
1808
+ return notStartedResult({ isError: true, content: `Sub-agent not started: ${why.slice(0, 1600)}${wt ? `\n${wt}` : ""}`, details: { ...details, ...faultDetails() } });
1783
1809
  };
1784
1810
  if (ctx.signal?.aborted)
1785
1811
  return notStarted("the parent task was aborted while extraTools was being evaluated.", { error: "aborted" });
1786
1812
  const undeclared = opts.extraToolNames !== undefined ? firstUndeclaredExtraTool(opts.extraToolNames, injectedTools, toolName) : undefined;
1787
1813
  if (undeclared !== undefined)
1788
- return (reportExtraToolsError(extraToolNamesError(undeclared.sentence, undeclared.reason)), notStarted(undeclared.sentence, { error: EXTRA_TOOL_NAMES_CODE, reason: undeclared.reason }));
1814
+ return (reportExtraToolsError(extraToolNamesError(undeclared.sentence, undeclared.reason)), notStarted(UNDECLARED_EXTRA_TOOL_REFUSAL[undeclared.reason], { error: EXTRA_TOOL_NAMES_CODE, reason: undeclared.reason, cause: undeclared.sentence }));
1789
1815
  }
1790
1816
  const inherited = opts.tools === undefined && extraToolsNote === undefined ? inheritedChildPool(opts.inheritedTools ?? [], ctx.mountsCallerTool, wantsBackground && agentName === undefined && !wantsFork) : [];
1791
1817
  if (extraToolsNote !== undefined && opts.tools === undefined && (opts.inheritedTools?.length ?? 0) > 0)
@@ -2087,6 +2113,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2087
2113
  ...(inheritedSkillGrants.length > 0 ? { inheritedSkillGrants } : {}),
2088
2114
  ...(inheritedAllowedTools !== undefined && inheritedAllowedTools.length > 0 ? { inheritedAllowedTools: [...inheritedAllowedTools] } : {}),
2089
2115
  ...(childProvenanceRef !== undefined && provenanceRequest !== undefined ? { delegationProvenance: { ref: childProvenanceRef, contentSafety: provenanceRequest } } : {}),
2116
+ ...(reviveClaim === undefined && ctx.crossBoundaryTreeForChildren !== undefined ? { crossBoundaryTree: ctx.crossBoundaryTreeForChildren } : {}),
2090
2117
  ...(treeScope !== undefined ? { registryScope: treeScope } : {}),
2091
2118
  ...(ctx.checkpointScopeForChildren !== undefined ? { checkpointScope: ctx.checkpointScopeForChildren } : {}),
2092
2119
  ...(ctx.inheritedGateForChildren ? { inheritedGate: ctx.inheritedGateForChildren() } : {}),
@@ -2360,16 +2387,16 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2360
2387
  if (ctx.signal?.aborted) {
2361
2388
  await cancelObserver();
2362
2389
  const wt = await finishWorktree();
2363
- return spawnAbortedResult(wt);
2390
+ return spawnAbortedResult(wt, faultDetails());
2364
2391
  }
2365
2392
  if (spawnVerdict.kind === "block") {
2366
2393
  await cancelObserver();
2367
2394
  const wt = await finishWorktree();
2368
- return {
2395
+ return notStartedResult({
2369
2396
  isError: true,
2370
2397
  content: `Sub-agent not started: blocked by the auto-mode classifier${spawnVerdict.reason ? `: ${inlineUntrusted(spawnVerdict.reason)}` : ""}.${wt ? `\n${wt}` : ""}`,
2371
- details: { error: "autoMode.spawn_blocked" },
2372
- };
2398
+ details: { error: "autoMode.spawn_blocked", ...faultDetails() },
2399
+ });
2373
2400
  }
2374
2401
  }
2375
2402
  if (wantsFork) {
@@ -2387,11 +2414,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2387
2414
  }
2388
2415
  catch (e) {
2389
2416
  const wt = await finishWorktree();
2390
- return { isError: true, content: `Sub-agent not started: session fork failed (${thrownText(e)}).${wt ? `\n${wt}` : ""}`, details: { error: "fork failed" } };
2417
+ return notStartedResult({ isError: true, content: `Sub-agent not started: session fork failed.${wt ? `\n${wt}` : ""}`, details: { error: "fork failed", ...faultDetails(e) } });
2391
2418
  }
2392
2419
  if (!forkedId) {
2393
2420
  const wt = await finishWorktree();
2394
- return { isError: true, content: `Sub-agent not started: source session not found or fork unavailable.${wt ? `\n${wt}` : ""}`, details: { error: "source not found", forkLane: ctx.hostSessionFork ? "host" : "child-runner", ...(ctx.sessionId !== undefined ? { sourceSessionId: ctx.sessionId } : {}) } };
2421
+ return notStartedResult({ isError: true, content: `Sub-agent not started: source session not found or fork unavailable.${wt ? `\n${wt}` : ""}`, details: { error: "source not found", forkLane: ctx.hostSessionFork ? "host" : "child-runner", ...(ctx.sessionId !== undefined ? { sourceSessionId: ctx.sessionId } : {}), ...faultDetails() } });
2395
2422
  }
2396
2423
  const forkInternals = { ...childInternals, insideFork: true, ...(ctx.reminderMark !== undefined ? { reminderMark: ctx.reminderMark } : {}) };
2397
2424
  stepRecorder.lockTo(forkedId);
@@ -2425,7 +2452,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2425
2452
  }
2426
2453
  await cancelObserver();
2427
2454
  const wt = await finishWorktree();
2428
- return errorResult(`Sub-agent not started in background: ${admission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: admission.refusal.code, code: admission.refusal.code });
2455
+ return notStartedResult(errorResult(`Sub-agent not started in background: ${admission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: admission.refusal.code, code: admission.refusal.code, ...faultDetails() }));
2429
2456
  }
2430
2457
  }
2431
2458
  const forkSettlementSeat = ctx.delegationSettlement?.();
@@ -2437,11 +2464,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2437
2464
  catch (e) {
2438
2465
  dropHostAbortListener();
2439
2466
  const wt = await finishWorktree();
2440
- return {
2467
+ return notStartedResult({
2441
2468
  isError: true,
2442
- content: `Sub-agent not started in background: the delegation settlement account could not record the launch (${(thrownText(e)).slice(0, 300)}) — fail-closed; repair the memory control plane or retry.${wt ? `\n${wt}` : ""}`,
2443
- details: { error: "settlement_write_ahead_failed" },
2444
- };
2469
+ content: `Sub-agent not started in background: the delegation settlement account could not record the launch — fail-closed; repair the memory control plane or retry.${wt ? `\n${wt}` : ""}`,
2470
+ details: { error: "settlement_write_ahead_failed", ...faultDetails(e) },
2471
+ });
2445
2472
  }
2446
2473
  }
2447
2474
  const settleForkRow = (terminal) => {
@@ -2496,6 +2523,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2496
2523
  ...(rowModelKey !== undefined ? { model: rowModelKey } : {}),
2497
2524
  deliveryChannel: "attaching",
2498
2525
  toolUseId: ctx.toolCallId,
2526
+ ...(ctx.crossBoundaryTreeForChildren !== undefined ? { crossBoundaryTree: ctx.crossBoundaryTreeForChildren } : {}),
2499
2527
  ...(bg.agentStore !== undefined ? { store: bg.agentStore } : {}),
2500
2528
  abort,
2501
2529
  });
@@ -2515,7 +2543,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2515
2543
  catch {
2516
2544
  }
2517
2545
  }
2518
- return { isError: true, content: `Sub-agent not started in background: ${thrownText(e)}${wt ? `\n${wt}` : ""}`, details: { error: "register_failed" } };
2546
+ return notStartedResult({ isError: true, content: `Sub-agent not started in background: the background task could not be registered.${wt ? `\n${wt}` : ""}`, details: { error: "register_failed", ...faultDetails(e) } });
2519
2547
  }
2520
2548
  if (forkEntryGate.key !== undefined)
2521
2549
  chargeDelegationEntryHandle(bg.registry, forkEntryGate.key, bg.agentStore, taskId);
@@ -2809,7 +2837,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2809
2837
  }
2810
2838
  await cancelObserver();
2811
2839
  const wt = await finishWorktree();
2812
- return spawnAbortedResult(wt);
2840
+ return spawnAbortedResult(wt, faultDetails());
2813
2841
  }
2814
2842
  const syncForkAdmission = syncForkEntryGate.admit("local");
2815
2843
  if (!syncForkAdmission.admitted) {
@@ -2820,7 +2848,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2820
2848
  }
2821
2849
  await cancelObserver();
2822
2850
  const wt = await finishWorktree();
2823
- return errorResult(`Sub-agent not started: ${syncForkAdmission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: syncForkAdmission.refusal.code, code: syncForkAdmission.refusal.code });
2851
+ return notStartedResult(errorResult(`Sub-agent not started: ${syncForkAdmission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: syncForkAdmission.refusal.code, code: syncForkAdmission.refusal.code, ...faultDetails() }));
2824
2852
  }
2825
2853
  let forkChild;
2826
2854
  try {
@@ -2862,7 +2890,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2862
2890
  if (isDurablePause(forkChild.terminal)) {
2863
2891
  return durablePauseDelegationReport(` · ${FORK_SUBAGENT_TYPE}`, forkChild.terminal);
2864
2892
  }
2865
- const wtLine = await finishWorktree();
2893
+ const wtLine = reportedWorktreeLine(await finishWorktree());
2866
2894
  const forkFace = childTerminalFace(forkChild.terminal);
2867
2895
  const forkErr = classifySubagentError(forkChild.terminal);
2868
2896
  const forkLines = [
@@ -2931,7 +2959,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2931
2959
  dropHostAbortListener();
2932
2960
  await cancelObserver();
2933
2961
  const wt = await finishWorktree();
2934
- return errorResult(`Sub-agent not started in background: ${admission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: admission.refusal.code, code: admission.refusal.code });
2962
+ return notStartedResult(errorResult(`Sub-agent not started in background: ${admission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: admission.refusal.code, code: admission.refusal.code, ...faultDetails() }));
2935
2963
  }
2936
2964
  }
2937
2965
  const settlementSeat = ctx.delegationSettlement?.();
@@ -2944,11 +2972,11 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
2944
2972
  dropHostAbortListener();
2945
2973
  await cancelObserver();
2946
2974
  const wt = await finishWorktree();
2947
- return {
2975
+ return notStartedResult({
2948
2976
  isError: true,
2949
- content: `Sub-agent not started in background: the delegation settlement account could not record the launch (${(thrownText(e)).slice(0, 300)}) — fail-closed; repair the memory control plane or retry.${wt ? `\n${wt}` : ""}`,
2950
- details: { error: "settlement_write_ahead_failed" },
2951
- };
2977
+ content: `Sub-agent not started in background: the delegation settlement account could not record the launch — fail-closed; repair the memory control plane or retry.${wt ? `\n${wt}` : ""}`,
2978
+ details: { error: "settlement_write_ahead_failed", ...faultDetails(e) },
2979
+ });
2952
2980
  }
2953
2981
  }
2954
2982
  const settleDelegationRow = (terminal) => {
@@ -3038,6 +3066,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3038
3066
  ...(rowModelKey !== undefined ? { model: rowModelKey } : {}),
3039
3067
  deliveryChannel: "attaching",
3040
3068
  toolUseId: ctx.toolCallId,
3069
+ ...(ctx.crossBoundaryTreeForChildren !== undefined ? { crossBoundaryTree: ctx.crossBoundaryTreeForChildren } : {}),
3041
3070
  ...(bg.agentStore !== undefined ? { store: bg.agentStore } : {}),
3042
3071
  abort,
3043
3072
  });
@@ -3053,7 +3082,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3053
3082
  catch {
3054
3083
  }
3055
3084
  }
3056
- return { isError: true, content: `Sub-agent not started in background: ${thrownText(e)}${wt ? `\n${wt}` : ""}`, details: { error: "register_failed" } };
3085
+ return notStartedResult({ isError: true, content: `Sub-agent not started in background: the background task could not be registered.${wt ? `\n${wt}` : ""}`, details: { error: "register_failed", ...faultDetails(e) } });
3057
3086
  }
3058
3087
  if (capLedgerKey !== undefined)
3059
3088
  chargeDelegationEntryHandle(bg.registry, capLedgerKey, bg.agentStore, reviveRow === undefined ? taskId : undefined);
@@ -3640,18 +3669,23 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3640
3669
  ]);
3641
3670
  if (startup === "settled") {
3642
3671
  if (parkedResume !== undefined) {
3643
- const failure = await bgChildPromise.then((r) => ({ err: undefined, cause: resumeStartupCauseOf(r.terminal.kind === "failed" ? r.terminal.code : undefined) }), (e) => ({ err: childThrownText(e), cause: resumeStartupCauseOf(errorCodeOf(e)) }));
3672
+ const failure = await bgChildPromise.then((r) => ({ err: undefined, cause: resumeStartupCauseOf(r.terminal.kind === "failed" ? r.terminal.code : undefined), refusal: undefined }), (e) => ({ err: childThrownText(e), cause: resumeStartupCauseOf(errorCodeOf(e)), refusal: resumeRefusalDetailOf(thrownFailureOf(e, "").detail) }));
3644
3673
  return {
3645
3674
  isError: true,
3646
3675
  content: `Parked resume did not complete: ${(failure.err ?? "the resumed run settled before its delivery lane bound").slice(0, 600)}`,
3647
- details: { error: "parked_resume.startup_failed", task_id: taskId, ...(failure.cause !== undefined ? { cause: failure.cause } : {}) },
3676
+ details: {
3677
+ error: "parked_resume.startup_failed",
3678
+ task_id: taskId,
3679
+ ...(failure.cause !== undefined ? { cause: failure.cause } : {}),
3680
+ ...(failure.refusal !== undefined ? { detail: failure.refusal } : {}),
3681
+ },
3648
3682
  };
3649
3683
  }
3650
- return {
3684
+ return notStartedResult({
3651
3685
  isError: true,
3652
3686
  content: `Sub-agent not revived: the revival failed during startup (its transcript session may be gone or the run could not prepare). This cycle settled failed; the message was NOT delivered — it remains queued and will be delivered if a later revival succeeds, so do not blindly resend the same content.`,
3653
3687
  details: { error: "revive.startup_failed", task_id: taskId },
3654
- };
3688
+ });
3655
3689
  }
3656
3690
  }
3657
3691
  return {
@@ -3679,13 +3713,13 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3679
3713
  if (ctx.signal?.aborted) {
3680
3714
  await cancelObserver();
3681
3715
  const wt = await finishWorktree();
3682
- return spawnAbortedResult(wt);
3716
+ return spawnAbortedResult(wt, faultDetails());
3683
3717
  }
3684
3718
  const syncAdmission = syncEntryGate.admit("local");
3685
3719
  if (!syncAdmission.admitted) {
3686
3720
  await cancelObserver();
3687
3721
  const wt = await finishWorktree();
3688
- return errorResult(`Sub-agent not started: ${syncAdmission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: syncAdmission.refusal.code, code: syncAdmission.refusal.code });
3722
+ return notStartedResult(errorResult(`Sub-agent not started: ${syncAdmission.refusal.text}${wt ? `\n${wt}` : ""}`, { error: syncAdmission.refusal.code, code: syncAdmission.refusal.code, ...faultDetails() }));
3689
3723
  }
3690
3724
  const syncStartedAt = Date.now();
3691
3725
  let retainEntry;
@@ -3780,7 +3814,7 @@ function createSubagentToolNode(opts, depth, excluded, extraToolsBudget) {
3780
3814
  }
3781
3815
  }
3782
3816
  }
3783
- const worktreeLine = await finishWorktree(child.terminal);
3817
+ const worktreeLine = reportedWorktreeLine(await finishWorktree(child.terminal));
3784
3818
  if (worktreeDir !== undefined && placementRefused(child.terminal))
3785
3819
  return isolationUnavailable(WORKTREE_UNAVAILABLE.notHonored);
3786
3820
  const errClass = classifySubagentError(child.terminal);
@@ -1,5 +1,5 @@
1
1
  import type { AgentDefinition, ToolSpec } from "../core/types.js";
2
- import type { ToolLegKind, ToolSelector, ToolSelectorLayer } from "../core/tool-face.js";
2
+ import { type ToolLegKind, type ToolSelector, type ToolSelectorLayer } from "../core/tool-face.js";
3
3
  import { type ProtocolId } from "../core/protocol-table.js";
4
4
  import { type ToolNameListReading } from "../core/tool-name-list.js";
5
5
  /**
@@ -121,6 +121,9 @@ type UniverseTool = {
121
121
  readonly name: string;
122
122
  readonly aliases?: readonly string[];
123
123
  };
124
+ /** Do the layers ABOVE a leg decide a protocol row of these kinds? Yes when some kind of the row shares its spawner's tool surface
125
+ * ({@link SPAWNER_SURFACE_LEG_KINDS}): the leg holds it exactly when its spawner may. Any other row is the leg's own channel. */
126
+ export declare function protocolRowUnderCeiling(rowLegs: readonly ToolLegKind[]): boolean;
124
127
  /** The wire names a leg of these kinds relies on (the catalog's protocol column). */
125
128
  export declare function protocolToolNames(legs: readonly ToolLegKind[]): string[];
126
129
  /** Is this value a layer — an object (not a list) with the two lists `allow` / `deny`? One that is not admits NOTHING here;
@@ -130,11 +133,29 @@ export declare function isToolSelectorLayer(layer: unknown): layer is ToolSelect
130
133
  * Compile ONE run's tool selector from its layers (the ceiling it was spawned under, then its own lists — the LAST layer is its own)
131
134
  * and the kinds of leg it is. Each list is read by the one reading ({@link readAllowedToolList} / {@link readDeniedToolList}) and
132
135
  * matched by the one matcher ({@link listReaches}); a protocol tool of one of `legs` is admitted whatever the leg's own lists say —
133
- * and whatever the ceiling says too, unless its row is one the leg shares with its spawner (`protocolUnderCeiling`: the ceiling
134
- * layers decide it). Whether a list may reach a protocol tool at all is judged at prepare. The layers are kept as handed — the
135
- * producer passes frozen copies of the lists it read.
136
+ * and whatever the ceiling says too, unless a kind of its row shares its spawner's tool surface ({@link protocolRowUnderCeiling}):
137
+ * the ceiling layers decide it. Whether a list may reach a protocol tool at all is judged at prepare. The layers are kept as handed —
138
+ * the producer passes frozen copies of the lists it read.
136
139
  */
137
140
  export declare function compileToolSelector(layers: readonly ToolSelectorLayer[], legs?: readonly ToolLegKind[]): ToolSelector;
141
+ /**
142
+ * What a leg's tool valve leaves mounted — its one reading: nothing under the run's whole-face switch (`excludeAllTools`: every
143
+ * tool unmounts, protocol tools included), else what the compiled selector admits. The valve unmounts by it, and every question
144
+ * prepare asks about the post-valve roster before the valve runs (the full shell's reachability, the memory write channel, the
145
+ * persistence verdict, the two memory pairs' planning) asks it too.
146
+ */
147
+ export declare function valveLeaves(spec: {
148
+ readonly excludeAllTools?: true;
149
+ }, selector: Pick<ToolSelector, "admits">): (tool: UniverseTool) => boolean;
150
+ /**
151
+ * The valve's reading at the SERVER level — {@link valveLeaves} asked of a whole peer before any of its tools is known: can the valve
152
+ * leave a tool of the peer `prefix` (`mcp__srv__`) at all? Nothing under the run's whole-face switch; else what the compiled selector's
153
+ * lists can reach of the peer ({@link ToolSelector.admitsPeer} — read off the lists, never off what the server lists). A peer this
154
+ * answers `false` for leaves no tool on the roster whatever it lists, so a run has no reason to dial it or to teach its instructions.
155
+ */
156
+ export declare function valveLeavesPeer(spec: {
157
+ readonly excludeAllTools?: true;
158
+ }, selector: Pick<ToolSelector, "admitsPeer">): (prefix: string) => boolean;
138
159
  /** One protocol tool a denylist reaches, and whose list it is: the leg's own (the last layer) or one it inherits (a ceiling layer). */
139
160
  export interface DeniedProtocolTool {
140
161
  readonly name: string;