@zhushanwen/subagent-core 0.4.0 → 0.6.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 (309) hide show
  1. package/dist/{chunk-4KN4TTG7.js → chunk-43ONBFZX.js} +1 -1
  2. package/dist/{chunk-X7SZ5HLQ.js → chunk-V3VHZ2VX.js} +20 -27
  3. package/dist/execution/engine/engines/zcode/constants.cjs +29 -41
  4. package/dist/execution/engine/engines/zcode/constants.d.cts +65 -53
  5. package/dist/execution/engine/engines/zcode/constants.d.ts +65 -53
  6. package/dist/execution/engine/engines/zcode/constants.js +17 -27
  7. package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
  8. package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
  9. package/dist/execution/engine/engines/zcode/reader.js +2 -2
  10. package/dist/index.cjs +17100 -14082
  11. package/dist/index.d.cts +5336 -4033
  12. package/dist/index.d.ts +5336 -4033
  13. package/dist/index.js +17020 -14055
  14. package/dist/{types-DpUO16pj.d.cts → types-C3fE3R9x.d.cts} +280 -112
  15. package/dist/{types-DpUO16pj.d.ts → types-C3fE3R9x.d.ts} +280 -112
  16. package/dist.bundle/index.cjs +34933 -0
  17. package/package.json +3 -3
  18. package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
  19. package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
  20. package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
  21. package/src/__tests__/m2-append-content-probe.test.ts +0 -1
  22. package/src/__tests__/manifest-store.test.ts +10 -9
  23. package/src/__tests__/record-store-cache.test.ts +0 -2
  24. package/src/__tests__/record-store-index.test.ts +1 -2
  25. package/src/__tests__/review-fix-loop-script.test.ts +4 -2
  26. package/src/__tests__/review-fix-loop-utils.test.ts +10 -10
  27. package/src/__tests__/robustness-low-batch1.test.ts +6 -5
  28. package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
  29. package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
  30. package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
  31. package/src/__tests__/session-runner.test.ts +1 -1
  32. package/src/core/__tests__/host-services.test.ts +2 -2
  33. package/src/core/__tests__/logger.test.ts +1 -1
  34. package/src/core/error-message.ts +9 -0
  35. package/src/core/host-services.ts +21 -5
  36. package/src/core/notify-ports.ts +18 -5
  37. package/src/execution/__tests__/agent-profile.test.ts +4 -4
  38. package/src/execution/__tests__/agent-registry.test.ts +370 -0
  39. package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
  40. package/src/execution/__tests__/agents-assembly.test.ts +2 -2
  41. package/src/execution/__tests__/alive-store.test.ts +1 -1
  42. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
  43. package/src/execution/__tests__/chat-engine-routing.test.ts +68 -33
  44. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +4 -4
  45. package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
  46. package/src/execution/__tests__/collect-budget.test.ts +291 -0
  47. package/src/execution/__tests__/collect-coordinator-service.test.ts +327 -0
  48. package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
  49. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +262 -0
  50. package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
  51. package/src/execution/__tests__/config.test.ts +1 -1
  52. package/src/execution/__tests__/delivery-methods.test.ts +75 -62
  53. package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
  54. package/src/execution/__tests__/descendant-sweep.test.ts +6 -6
  55. package/src/execution/__tests__/dialog-queue.test.ts +2 -2
  56. package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
  57. package/src/execution/__tests__/epipe-fallback.test.ts +29 -24
  58. package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
  59. package/src/execution/__tests__/execute-nesting.test.ts +34 -188
  60. package/src/execution/__tests__/execution-record.test.ts +217 -60
  61. package/src/execution/__tests__/execution-runtime-face.test.ts +5 -5
  62. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +4 -4
  63. package/src/execution/__tests__/finalize-record.test.ts +173 -17
  64. package/src/execution/__tests__/finalized-marker.test.ts +1 -1
  65. package/src/execution/__tests__/gc-timer.test.ts +56 -3
  66. package/src/execution/__tests__/get-record-for-action-restart.test.ts +12 -12
  67. package/src/execution/__tests__/get-state-handshake.test.ts +1 -1
  68. package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
  69. package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
  70. package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
  71. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
  72. package/src/execution/__tests__/keep-alive-no-progress.test.ts +50 -148
  73. package/src/execution/__tests__/kill-all-escalation.test.ts +2 -2
  74. package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
  75. package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
  76. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +1 -1
  77. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +1 -1
  78. package/src/execution/__tests__/model-resolver.test.ts +2 -2
  79. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
  80. package/src/execution/__tests__/nested-visibility.test.ts +2 -0
  81. package/src/execution/__tests__/notify-batch.test.ts +500 -0
  82. package/src/execution/__tests__/notify-ledger.test.ts +1000 -18
  83. package/src/execution/__tests__/output-collector.test.ts +117 -6
  84. package/src/execution/__tests__/pi-invocation.test.ts +36 -4
  85. package/src/execution/__tests__/record-entry-collect.test.ts +102 -0
  86. package/src/execution/__tests__/record-store.test.ts +10 -9
  87. package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
  88. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
  89. package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
  90. package/src/execution/__tests__/relay-env.test.ts +12 -1
  91. package/src/execution/__tests__/rpc-mode.test.ts +2 -2
  92. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
  93. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +15 -9
  94. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +4 -4
  95. package/src/execution/__tests__/run-spawn-edges.test.ts +17 -15
  96. package/src/execution/__tests__/run-spawn-integration.test.ts +2 -2
  97. package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
  98. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
  99. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +4 -4
  100. package/src/execution/__tests__/service-kill-escalation.test.ts +7 -5
  101. package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
  102. package/src/execution/__tests__/session-file-gc.test.ts +36 -1
  103. package/src/execution/__tests__/session-pending.test.ts +257 -14
  104. package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
  105. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +1 -1
  106. package/src/execution/__tests__/session-runner-close-prune.test.ts +2 -2
  107. package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
  108. package/src/execution/__tests__/session-runner-epipe.test.ts +3 -3
  109. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +5 -4
  110. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
  112. package/src/execution/__tests__/settled-watchdog.test.ts +282 -47
  113. package/src/execution/__tests__/spawn-args.test.ts +11 -10
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +3 -3
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
  117. package/src/execution/__tests__/spawned-children.test.ts +2 -1
  118. package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
  119. package/src/execution/__tests__/start-sync-model-guard.test.ts +5 -5
  120. package/src/execution/__tests__/stdin-writer.test.ts +6 -4
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
  122. package/src/execution/__tests__/subagent-actions-core.test.ts +48 -22
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +29 -26
  124. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +21 -8
  125. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -22
  126. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +30 -29
  127. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +45 -20
  128. package/src/execution/__tests__/subagent-service.test.ts +37 -30
  129. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
  130. package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
  131. package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
  132. package/src/execution/__tests__/sync-collect-recovery.test.ts +1117 -0
  133. package/src/execution/__tests__/temp-prompt.test.ts +1 -1
  134. package/src/execution/__tests__/timeout-integration.test.ts +6 -5
  135. package/src/execution/__tests__/tombstone-store.test.ts +1 -1
  136. package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
  137. package/src/execution/__tests__/turn-limiter.test.ts +1 -1
  138. package/src/execution/__tests__/ui-request-handler-factory.test.ts +12 -6
  139. package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
  140. package/src/execution/__tests__/ui-request-queue.test.ts +142 -2
  141. package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
  142. package/src/execution/__tests__/worktree-manager.test.ts +14 -5
  143. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
  144. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
  145. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
  146. package/src/execution/__tests__/worktree-registry.test.ts +1 -1
  147. package/src/execution/agent-registry.ts +74 -30
  148. package/src/execution/agent-result-mapper.ts +3 -0
  149. package/src/execution/cold-resurrect.ts +199 -0
  150. package/src/execution/collect-coordinator.ts +200 -0
  151. package/src/execution/config.ts +77 -5
  152. package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
  153. package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
  154. package/src/execution/engine/__tests__/common/event-journal.test.ts +1 -1
  155. package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
  156. package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
  157. package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
  158. package/src/execution/engine/__tests__/common/pool-manager.test.ts +213 -53
  159. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
  160. package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
  161. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +22 -112
  162. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +15 -28
  163. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +1 -1
  164. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +12 -12
  165. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +2 -2
  166. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +21 -82
  167. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +4 -7
  168. package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
  169. package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
  170. package/src/execution/engine/__tests__/registry.test.ts +4 -2
  171. package/src/execution/engine/__tests__/routing.test.ts +115 -6
  172. package/src/execution/engine/common/capability-gate.ts +92 -0
  173. package/src/execution/engine/common/journal-wiring.ts +97 -0
  174. package/src/execution/engine/common/kill-chain.ts +42 -10
  175. package/src/execution/engine/common/nesting-guard.ts +66 -0
  176. package/src/execution/engine/common/persona-router.ts +18 -8
  177. package/src/execution/engine/common/pool-manager.ts +332 -78
  178. package/src/execution/engine/common/session-view-service.ts +506 -0
  179. package/src/execution/engine/common/session-view-types.ts +125 -0
  180. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
  181. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
  182. package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
  183. package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +1 -1
  184. package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
  185. package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
  186. package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
  187. package/src/execution/engine/engines/pi/reader.ts +11 -0
  188. package/src/execution/engine/engines/pi/registration.ts +4 -2
  189. package/src/execution/{session-runner.ts → engine/engines/pi/session-runner.ts} +617 -412
  190. package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
  191. package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
  192. package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
  193. package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
  194. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +54 -27
  195. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
  196. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +13 -12
  197. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
  198. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
  199. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
  200. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
  201. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +20 -8
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +77 -110
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +26 -320
  204. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
  205. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
  206. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
  207. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
  208. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +48 -148
  209. package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
  210. package/src/execution/engine/engines/zcode/connection.ts +24 -11
  211. package/src/execution/engine/engines/zcode/constants.ts +75 -71
  212. package/src/execution/engine/engines/zcode/golden-sample.ts +8 -46
  213. package/src/execution/engine/engines/zcode/parser.ts +12 -346
  214. package/src/execution/engine/engines/zcode/preparer.ts +12 -143
  215. package/src/execution/engine/engines/zcode/session-channel.ts +351 -39
  216. package/src/execution/engine/engines/zcode/zcode-engine.ts +665 -760
  217. package/src/execution/engine/host-task-spec.ts +32 -36
  218. package/src/execution/engine/model-validation.ts +177 -0
  219. package/src/execution/engine/port.ts +24 -6
  220. package/src/execution/engine/routing.ts +75 -1
  221. package/src/execution/engine/types.ts +30 -103
  222. package/src/execution/execution-record.ts +229 -144
  223. package/src/execution/finalize-record.ts +141 -99
  224. package/src/execution/idle-gc.ts +28 -0
  225. package/src/execution/lifecycle-predicates.ts +1 -1
  226. package/src/execution/notifier.ts +234 -25
  227. package/src/execution/notify-host.ts +232 -0
  228. package/src/execution/record-entry.ts +16 -0
  229. package/src/execution/record-store.ts +280 -103
  230. package/src/execution/round-settlement.ts +93 -0
  231. package/src/execution/session-file-gc.ts +96 -62
  232. package/src/execution/session-reconstructor.ts +256 -143
  233. package/src/execution/sessions-index.ts +117 -47
  234. package/src/execution/settled-watchdog.ts +264 -52
  235. package/src/execution/subagent-actions-core.ts +84 -28
  236. package/src/execution/subagent-service.ts +1225 -964
  237. package/src/execution/subprocess-agent-runner.ts +144 -97
  238. package/src/execution/sync-rebuild.ts +87 -0
  239. package/src/execution/types.ts +72 -0
  240. package/src/execution/ui-request-handler-factory.ts +102 -74
  241. package/src/execution/ui-request-queue.ts +50 -19
  242. package/src/index.ts +442 -316
  243. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +1 -1
  244. package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
  245. package/src/orchestration/__tests__/args-validator.test.ts +14 -0
  246. package/src/orchestration/__tests__/config-loader.test.ts +1 -1
  247. package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +1 -1
  248. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +11 -9
  249. package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
  250. package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
  251. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
  252. package/src/orchestration/__tests__/file-run-store.test.ts +7 -6
  253. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +2 -2
  254. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +1 -1
  255. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
  256. package/src/orchestration/__tests__/lifecycle.test.ts +7 -5
  257. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
  258. package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
  259. package/src/orchestration/__tests__/run-snapshot.test.ts +8 -5
  260. package/src/orchestration/__tests__/script-generate.test.ts +5 -5
  261. package/src/orchestration/__tests__/script-lint.test.ts +17 -0
  262. package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
  263. package/src/orchestration/__tests__/test-mocks.ts +2 -0
  264. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
  265. package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
  266. package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +27 -19
  267. package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
  268. package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
  269. package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
  270. package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +1 -1
  271. package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
  272. package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
  273. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
  274. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +1 -1
  275. package/src/orchestration/agent-opts-resolver.ts +1 -1
  276. package/src/orchestration/args-validator.ts +53 -31
  277. package/src/orchestration/execute-agent-call.ts +19 -73
  278. package/src/orchestration/launcher.ts +128 -81
  279. package/src/orchestration/lifecycle.ts +43 -45
  280. package/src/orchestration/models/ports.ts +4 -4
  281. package/src/orchestration/models/run-runtime.ts +2 -2
  282. package/src/orchestration/models/trace.ts +1 -1
  283. package/src/orchestration/models/types.ts +111 -22
  284. package/src/orchestration/models/workflow-run.ts +1 -1
  285. package/src/orchestration/script-lint.ts +91 -58
  286. package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +157 -150
  287. package/src/shared/__tests__/atomic-write.test.ts +1 -1
  288. package/src/shared/__tests__/meta-parser.test.ts +151 -0
  289. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
  290. package/src/shared/__tests__/resource-discovery.test.ts +258 -215
  291. package/src/shared/atomic-write.ts +12 -9
  292. package/src/shared/meta-parser.ts +158 -84
  293. package/src/shared/model-ref.ts +15 -2
  294. package/src/shared/resource-discovery.ts +9 -183
  295. package/src/shared/schema-jsonify.ts +1 -1
  296. package/workflows/review-fix-loop-utils.cjs +151 -89
  297. package/workflows/review-fix-loop-utils.d.cts +287 -0
  298. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  299. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  300. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  301. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  302. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  303. package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +0 -387
  304. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -710
  305. package/src/execution/engine/engines/zcode/appserver-home.ts +0 -442
  306. package/src/execution/engine/engines/zcode/appserver-probe.ts +0 -141
  307. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  308. package/src/execution/execute-options-mapper.ts +0 -115
  309. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
@@ -5,37 +5,44 @@
5
5
  // 从"自己 spawn pi"改为"委托 SubagentService.executeAndAwait"。
6
6
  // MF-3: 从 orchestration/infra 迁入 execution,同层委托 SubagentService。
7
7
  //
8
+ // [D6 任务形状合流] AgentCallOpts 已是 EnginePort.run 的单一任务形状——本类直传 opts
9
+ // 给 engine.run(无 ExecuteOptions/AgentTaskSpec 中间态映射);pi 边界的一次直出在
10
+ // PiEngine.agentCallToExecuteOptions。mergeTimeoutSignal(原 execute-options-mapper
11
+ // 的运行期件,D-A9)随 mapper 删除迁入本文件(唯一消费点)。
12
+ //
8
13
  // 接线层级:
9
14
  // [跨模块 port] implements AgentRunner(orchestration/models/ports.ts)
10
- // [模块内直调] mapToExecuteOptions + mergeTimeoutSignal(execute-options-mapper
11
- // [P4 路由层] engine/routing.ts routeEngine(三层优先级 + probe + fallback 三守卫,D9)
15
+ // [模块内直调] mergeTimeoutSignal(本文件,D-A9
16
+ // [P4 路由层] engine/routing.ts routeEngineForHost(D3-② 路由单点:三层优先级 +
17
+ // pi 同步短路 + probe + fallback 三守卫,D9)
18
+ // [公共预检] engine/common/capability-gate(D3-④:capabilities 驱动的调用前拒绝)
12
19
  // [引擎层] EnginePort.run(pi = 本地 DI 绑定实例;非 pi = registry.getEngine 动态获取)
20
+ // [公共 journal] engine/common/journal-wiring(D3-③:writer + retarget + 回填单实现)
13
21
  // [模块内直调] this.subagentService.executeAndAwait(PiEngine 内部委托目标)
14
22
  //
15
23
  // 设计基线:
16
- // D-A2(映射归 adapter)/ D-A8(onEvent 桥接)/ D-A9(timeoutMs 合并 signal)/
24
+ // D-A8(onEvent 桥接)/ D-A9(timeoutMs 合并 signal)/
17
25
  // D-008(model 填底,不调 resolveModel)/ BC-9(timeoutMs 行为)/ BC-10(live-record 进度)
18
26
 
19
27
  import type { AgentRunner } from "../orchestration/models/ports.ts";
20
28
  import type { AgentCallOpts, AgentResult } from "../orchestration/models/types.ts";
21
29
  import type { AgentEvent } from "../shared/agent-event.ts";
22
- import { getEngineDataDir } from "./engine/common/data-dir.ts";
23
- import { JournalWriter } from "./engine/common/event-journal.ts";
24
- import { createPiEngine, PI_POOL_KEY } from "./engine/engines/pi/registration.ts";
25
- import { executeOptionsToTaskSpec } from "./engine/engines/pi/task-spec-mapper.ts";
26
- import { resolveJournalPath } from "./engine/paths.ts";
30
+ import { assertTaskShapeSupported } from "./engine/common/capability-gate.ts";
31
+ import { HOST_TIMEOUT_ABORT_REASON } from "./engine/common/kill-chain.ts";
32
+ import { JOURNAL_INITIAL_POOL_KEY, wireEventJournal } from "./engine/common/journal-wiring.ts";
33
+ import { createPiEngine } from "./engine/engines/pi/registration.ts";
27
34
  import type { EnginePort, RunContext } from "./engine/port.ts";
28
- import { routeEngine, resolveEngineRouting, type EngineRouteResult, type EngineRoutingInput } from "./engine/routing.ts";
29
- import { getEngine, hasEngine, listEngines } from "./engine/registry.ts";
30
- import type { AgentOutcome, EngineHandle } from "./engine/types.ts";
31
- import { mapToExecuteOptions, mergeTimeoutSignal } from "./execute-options-mapper.ts";
35
+ import { validateModelForEngine } from "./engine/model-validation.ts";
36
+ import { routeEngineForHost, type EngineRouteResult, type EngineRoutingInput } from "./engine/routing.ts";
37
+ import { getEngine } from "./engine/registry.ts";
38
+ import type { AgentOutcome } from "./engine/types.ts";
32
39
  import { getModelConfigService } from "./model-config-service.ts";
33
40
  import type { ModelInfo } from "./model-resolver.ts";
34
41
  import { modelRefFromVerified } from "../shared/model-ref";
35
- import { registerSpawnedChildForRecord } from "./session-runner.ts";
42
+ import { registerSpawnedChildForRecord } from "./engine/engines/pi/session-runner.ts";
36
43
  import type { SubagentStream } from "./stream-sink.ts";
37
44
  import type { SubagentService } from "./subagent-service.ts";
38
- import type { ExecuteOptions } from "./types.ts";
45
+ import { toErrorMessage } from "../core/error-message.ts";
39
46
 
40
47
  // ── 构造依赖(per-session 注入)──
41
48
 
@@ -71,10 +78,12 @@ export interface SubprocessAgentRunnerDeps {
71
78
  * 非 pi 引擎(P4 路由可达:frontmatter/调用参数/全局默认指定)经 registry.getEngine
72
79
  * 动态获取——「引擎身份」的归属边界在注册表,SAR 不感知具体引擎实现。
73
80
  *
74
- * [P4 配置路由] 每次运行经 engine/routing.ts 解析三层优先级(调用参数 opts.engine >
75
- * agent frontmatter engine > 全局默认 'pi')+ probe + fallback 三守卫(D9)。路由失败
76
- * (engine_not_found / engine_probe_failed / model_not_available)不 reject,入
77
- * result.error——与 executeAgentCall 契约一致。
81
+ * [P4 配置路由] 每次运行经 engine/routing.ts routeEngineForHost(D3-② 路由单点:
82
+ * 唯一实现承载三层优先级(调用参数 opts.engine > agent frontmatter engine > 全局默认
83
+ * 'pi')+ pi 同步短路 + registry 注入 + probe/fallback 三守卫,D9;本类与
84
+ * SubagentService.execute 是其仅有的两调用点)。路由失败(engine_not_found /
85
+ * engine_probe_failed / model_not_available)与预检命中(engine_capability_unsupported,
86
+ * D3-④)不 reject,入 result.error——与 executeAgentCall 契约一致。
78
87
  */
79
88
  export class SubprocessAgentRunner implements AgentRunner {
80
89
  private readonly subagentService: SubagentService;
@@ -85,7 +94,8 @@ export class SubprocessAgentRunner implements AgentRunner {
85
94
  constructor(deps: SubprocessAgentRunnerDeps) {
86
95
  this.subagentService = deps.subagentService;
87
96
  this.ctxModel = deps.ctxModel;
88
- this.piEngine = createPiEngine(() => this.subagentService);
97
+ // [D4 聚合连带] asEngineService 显式视图适配(原结构化直绑依赖查询面 public)。
98
+ this.piEngine = createPiEngine(() => this.subagentService.asEngineService);
89
99
  }
90
100
 
91
101
  /**
@@ -99,16 +109,21 @@ export class SubprocessAgentRunner implements AgentRunner {
99
109
  }
100
110
 
101
111
  /**
102
- * 执行单次 agent 调用:路由(P4)→ EnginePort.run → PiEngine 委托
112
+ * 执行单次 agent 调用:路由(P4)→ 预检(D3-④)→ EnginePort.run → PiEngine 委托
103
113
  * SubagentService.executeAndAwait。
104
114
  *
105
115
  * 接线链路:
106
- * routeEngine(三层 + probe + 守卫)→ mergeTimeoutSignal → mapToExecuteOptions →
107
- * AgentTaskSpec → engine.runPiEngine:spec ExecuteOptions 还原 + engine 留痕)→
108
- * executeAndAwait AgentOutcome AgentResult
116
+ * routeEngineForHost(D3-② 路由单点:三层 + pi 同步短路 + probe + 守卫)→
117
+ * assertTaskShapeSupportedD3-④ 预检 capabilities 化)→ mergeTimeoutSignal
118
+ * engine.run(opts 直传——D6 合流:AgentCallOpts EnginePort 任务形状,零映射;
119
+ * PiEngine 内一次直出 ExecuteOptions + engine 留痕) → executeAndAwait →
120
+ * AgentOutcome → AgentResult
109
121
  *
110
122
  * 错误处理:不 reject。
111
123
  * - 路由失败(未注册 id / probe 失败 + 守卫或 strict)→ AgentResult.error(错误码前缀)
124
+ * - 预检命中(capabilities 不支持的任务形状参数)→ AgentResult.error
125
+ * (engine_capability_unsupported——[D3-④] workflow 域 zcode+worktree 由漏拦变
126
+ * 拦截,本单元唯一有意行为变化;拒绝在 journal/run 之前,无进程无 journal 产物)
112
127
  * - executeAndAwait 内部失败 → 返回 AgentResult(success:false) → 已映射 error 字段
113
128
  * - executeAndAwait throw(嵌套超限 BC-12)→ catch → AgentResult.error
114
129
  * - spawn 级失败已由 runSpawn 内部收口为 failed AgentResult(不逃逸)
@@ -121,69 +136,57 @@ export class SubprocessAgentRunner implements AgentRunner {
121
136
  ): Promise<AgentResult> {
122
137
  const startedAt = Date.now();
123
138
 
124
- // ── P4 路由:三层优先级 + probe + fallback 三守卫(D9①/D7)──
125
- // 路由在最前——引擎身份决定 journal 路径与后续一切执行面;失败(未注册 id /
126
- // probe 失败 + strict/守卫)按「不 reject」契约转 result.error。
127
- // pi 快路径同步短路(不经 routeEngine 的 await):pi 恒免探、无 fallback 可言、
128
- // engineFor('pi') 本地 DI 绑定恒可用——不引入微任务边界,缺省路径时序与 P1 接线
129
- // 前完全一致(下游依赖「run 内首个 await 前已触达 executeAndAwait」的时序契约)。
130
- let routingInput: EngineRoutingInput;
139
+ // ── P4 路由(D3-② 单点:routeEngineForHost)+ D3-④ 预检 ──
140
+ // 路由在最前——引擎身份决定 journal 路径与后续一切执行面。pi 快路径同步短路
141
+ //(routed Promise,零微任务——缺省路径时序与 P1 接线前完全一致,下游依赖
142
+ // 「run 内首个 await 前已触达 executeAndAwait」的时序契约)。路由失败(未注册
143
+ // id / probe 失败 + strict/守卫)与预检命中(capabilities 驱动,含 worktree——
144
+ // workflow 域漏拦缺口修复)一并按「不 reject」契约转 result.error。
131
145
  let route: EngineRouteResult;
132
146
  try {
133
- routingInput = this.buildRoutingInput(opts);
134
- const routing = resolveEngineRouting(routingInput);
135
- if (routing.engineId === "pi") {
136
- route = {
137
- engine: this.piEngine,
138
- engineId: "pi",
139
- requestedEngineId: "pi",
140
- source: routing.source,
141
- };
142
- } else {
143
- route = await routeEngine({
144
- routing: routingInput,
145
- taskModel: opts.model,
146
- strict: getModelConfigService()?.getGlobalConfig().engineRouting?.strict === true,
147
- probe: (engineId) => this.engineFor(engineId).probe(),
148
- getEngineFn: (engineId) => this.engineFor(engineId),
149
- // pi 经本地 DI 绑定恒可用(不依赖 registry 全局注册态——SAR 持有服务引用),
150
- // has/list 注入同一口径,engine_not_found 文案不会把本地 pi 漏报成未注册
151
- hasEngineFn: (engineId) => engineId === "pi" || hasEngine(engineId),
152
- listEnginesFn: () => (hasEngine("pi") ? listEngines() : ["pi", ...listEngines()]),
153
- });
147
+ const routed = routeEngineForHost({
148
+ routing: this.buildRoutingInput(opts),
149
+ taskModel: opts.model,
150
+ strict: getModelConfigService()?.getGlobalConfig().engineRouting?.strict === true,
151
+ probe: (engineId) => this.engineFor(engineId).probe(),
152
+ piEngine: this.piEngine,
153
+ });
154
+ route = routed instanceof Promise ? await routed : routed;
155
+ // [D3-④] SAR 路径预检调用点(run 前同模块调用;唯一实现 = common/capability-gate)。
156
+ // pi 全参数放行(V4⑤ 反向守护);zcode 拦 fork/conversation/maxTurns/worktree。
157
+ // [D6 合流] opts(AgentCallOpts)直传预检——TaskShapeForGate 是结构子集,
158
+ // conversation/fork/worktree/maxTurns 均在合流形状字段表内。
159
+ assertTaskShapeSupported(route.engineId, route.engine.capabilities(), opts);
160
+ // [u-h2 D2-2 调用点②] workflow 域非 pi 引擎的派发同步期 model 校验——与 chat
161
+ // 路径(subagent-service.executeViaEngine)共享同一入口 validateModelForEngine
162
+ // 与同一错误文案(V2-4④:agent({engine:'zcode', model:<pi id>}) 同步期报
163
+ // 「引擎与模型不配套」,不再落 engine.run prepare 期晚炸)。校验对象是显式
164
+ // opts.model(frontmatter model 的解析归 pi 链,workflow 域非 pi 路径现状不消费
165
+ // ——维持现状语义不扩散)。「不 reject」契约:throw 由本 try catch 收口
166
+ // errorResult,不进入 journal 创建与 engine.run(零 record/spawn 副作用)。
167
+ if (route.engineId !== "pi") {
168
+ validateModelForEngine(route.engine, opts.model);
154
169
  }
155
170
  } catch (err) {
156
- // buildRoutingInput 的 agent 解析期校验(未注册 frontmatter engine)与路由失败
157
- // (probe + strict/守卫)一并在此收口——「不 reject」契约
171
+ // buildRoutingInput 的 agent 解析期校验(未注册 frontmatter engine)、路由失败
172
+ //(probe + strict/守卫)与预检拒绝(engine_capability_unsupported)一并在此
173
+ // 收口——「不 reject」契约
158
174
  return errorResult(err, startedAt);
159
175
  }
160
176
 
161
177
  // ── P2 event journal 接线(设计 D6 第②级;对齐点③:路径权威 = 引擎池 key)──
162
- // host onEvent 回调内统一落盘(全引擎免费获得②级数据源)。初始 poolKey pi
163
- // 缺省占位(pi 'shared');非池化稳定引擎(zcode)在 prepare 期经
164
- // RunContext.onPoolResolved 声明实际池 key → writer.retarget——保证 journal 落盘
165
- // 路径与 handle.poolKey 同源(handle.journalPath 由本方法 run 返回后回填)。
178
+ // [D3-③] writer + retarget + 回填收敛 common/journal-wiring(与 chat 域同一实现):
179
+ // 初始 poolKey 占位 'shared'(pi 恒终值);非池化稳定引擎(zcode)在 prepare 期经
180
+ // RunContext.onPoolResolved 声明实际池 key → retarget——保证 journal 落盘路径与
181
+ // handle.poolKey 同源(handle.journalPath 由本方法 run 返回后回填)。
166
182
  //
167
183
  // taskId 为宿主侧任务标识(journal 文件名与池引用计数 key)——executeAndAwait
168
184
  // 不外露内部 record id(取真实 id 需 hook record store 且改 createRecordForMode
169
185
  // 签名,影响面大;P4 决策:保留占位,`sa-` 前缀与 record id 同构。影响面:record
170
- // GC 时无法按 taskId 联动删 journal(journal 依赖 30 TTL 自然回收),read ②级
171
- // handle.journalPath 自描述定位不受影响)。
186
+ // GC 时无法按 taskId 联动删 journal(journal 依赖 TTL 兜底回收,见 D8 分域裁决),
187
+ // read ②级经 handle.journalPath 自描述定位不受影响)。
172
188
  const taskId = `sa-${crypto.randomUUID()}`;
173
- const journal = new JournalWriter({
174
- path: resolveJournalPath(getEngineDataDir(), route.engineId, PI_POOL_KEY, taskId),
175
- taskId,
176
- engineId: route.engineId,
177
- });
178
- const retargetJournal = (poolKey: string): void => {
179
- journal.retarget(resolveJournalPath(getEngineDataDir(), route.engineId, poolKey, taskId));
180
- };
181
- // 包装:先写 journal 再转发原 onEvent(原 onEvent 未传时也恒传包装版——
182
- // 下游 onEvent 通道是事件生成后的纯转发,无行为分支,仅多一次入队)
183
- const journalingOnEvent = (event: AgentEvent): void => {
184
- journal.append(event);
185
- onEvent?.(event);
186
- };
189
+ const journal = wireEventJournal({ engineId: route.engineId, taskId, forwardEvents: onEvent });
187
190
 
188
191
  try {
189
192
  // ── [U1 D2] RunContext.modelRef 接入:ctxModel 继承路径的孪生守卫 ──
@@ -202,40 +205,39 @@ export class SubprocessAgentRunner implements AgentRunner {
202
205
  // ── D-A9: timeoutMs 合并 signal(超时 abort 带 HOST_TIMEOUT_ABORT_REASON 标记)──
203
206
  const mergedSignal = mergeTimeoutSignal(signal, opts.timeoutMs);
204
207
 
205
- // ── D-A2 + D-008: AgentCallOpts → ExecuteOptions 映射 ──
206
- const mappedOpts: ExecuteOptions = mapToExecuteOptions(opts, this.ctxModel);
207
-
208
208
  // ── P1/P4 引擎接线:EnginePort.run ──
209
209
  const runCtx: RunContext = {
210
210
  taskId,
211
- poolKey: PI_POOL_KEY,
211
+ poolKey: JOURNAL_INITIAL_POOL_KEY,
212
212
  signal: mergedSignal,
213
- onEvent: journalingOnEvent,
213
+ onEvent: journal.onEvent,
214
214
  ctxModel: this.ctxModel,
215
215
  ...(route.engineFallback !== undefined ? { engineFallback: route.engineFallback } : {}),
216
- onPoolResolved: retargetJournal,
216
+ onPoolResolved: journal.onPoolResolved,
217
217
  // [U0 D10] 终止链路径①:引擎 spawn 的子进程注册进 session-runner 的
218
218
  // spawnedChildren 记账(dispose killAll 收割兜底对 workflow 域引擎任务生效);
219
219
  // taskId('sa-' 前缀)即记账 key,与 chat 域 kickOffEngineRun 的 record.id 同构
220
220
  onChildSpawned: (child) => registerSpawnedChildForRecord(taskId, child),
221
221
  ...(stream !== undefined ? { stream } : {}),
222
- // 解耦形态(有 schemaEnv 无 schema)的兜底通道——耦合形态下引擎从 task.schema
223
- // 派生等值,此值被忽略(见 RunContext.schemaEnv 注释)
224
- ...(mappedOpts.schemaEnv !== undefined ? { schemaEnv: mappedOpts.schemaEnv } : {}),
222
+ // [D6 合流] 解耦形态(有 schemaEnv 无 schema)不再经 RunContext.schemaEnv
223
+ // 兜底通道——schemaEnv 已在合流形状 AgentCallOpts.schemaEnv 内,pi 直出
224
+ // (agentCallToExecuteOptions)以「schema 派生优先、schemaEnv 兜底」取值,
225
+ // 与原 ctx 兜底链路逐字节等值。
225
226
  };
226
227
  const { handle, outcome } = await route.engine.run(
227
- // 泛化为中立声明(PiEngine 内部再还原回 ExecuteOptions——往返保真,
228
- // engines/pi/__tests__/task-spec-mapper.test.ts 逐字段锁定)
229
- executeOptionsToTaskSpec(mappedOpts),
228
+ // [D6 合流] opts 直传——AgentCallOpts 即 EnginePort 任务形状(缺省路径零映射;
229
+ // pi 边界一次直出由 PiEngine.agentCallToExecuteOptions 承担,逐字段等值由
230
+ // engines/pi/__tests__/spawn-opts-direct.test.ts 对照表锁定)
231
+ opts,
230
232
  runCtx,
231
233
  );
232
234
  // handle.journalPath 回填(§3.3.6:read ②级的自描述定位符——运行期落盘路径
233
235
  // 权威在 writer,handle 记录最终路径供跨重启 read 消费)
234
- backfillJournalPath(handle, journal.path);
236
+ journal.backfillHandle(handle);
235
237
  return outcomeToRunnerResult(outcome);
236
238
  } catch (err) {
237
239
  // executeAndAwait throw(嵌套超限 ForkDepthExceededError,BC-12)或未预期异常 → 不 reject,入 error。
238
- const message = err instanceof Error ? err.message : String(err);
240
+ const message = toErrorMessage(err);
239
241
  return {
240
242
  content: "",
241
243
  durationMs: Date.now() - startedAt,
@@ -252,9 +254,11 @@ export class SubprocessAgentRunner implements AgentRunner {
252
254
  // ── 内部 ──
253
255
 
254
256
  /**
255
- * 引擎获取:pi 走 per-session DI 绑定(mock 语义 + 生产同单例,P1 行为零变化);
256
- * pi 经 registry.getEngine 动态获取(P4:引擎身份归属注册表,未注册 id 抛
257
- * EngineNotFoundError——路由期已前置校验,这里是防御性兜底)。
257
+ * 引擎获取(routeEngineForHost 的 probe 注入体):pi 走 per-session DI 绑定(mock
258
+ * 语义 + 生产同单例,P1 行为零变化);非 pi 经 registry.getEngine 动态获取(P4
259
+ * 引擎身份归属注册表,未注册 id 抛 EngineNotFoundError——路由期已前置校验,这里
260
+ * 是防御性兜底)。[D3-②] get/has/list 的路由期注入已由 routeEngineForHost 内部
261
+ * 承载(本地 pi 恒可用口径),本方法只剩 probe 一个消费点(pi 请求同步短路恒免探)。
258
262
  */
259
263
  private engineFor(engineId: string): EnginePort {
260
264
  if (engineId === "pi") return this.piEngine;
@@ -280,21 +284,16 @@ export class SubprocessAgentRunner implements AgentRunner {
280
284
  }
281
285
  }
282
286
 
283
- /** 路由期错误 → AgentResult.error(错误码前缀格式保留——engine_not_found 等)。 */
287
+ /** 路由期/预检错误 → AgentResult.error(错误码前缀格式保留——engine_not_found 等)。 */
284
288
  function errorResult(err: unknown, startedAt: number): AgentResult {
285
289
  return {
286
290
  content: "",
287
291
  durationMs: Date.now() - startedAt,
288
- error: err instanceof Error ? err.message : String(err),
292
+ error: toErrorMessage(err),
289
293
  toolCalls: [],
290
294
  };
291
295
  }
292
296
 
293
- /** handle.journalPath 回填(一次写者:SAR 是 handle 的首个消费者)。 */
294
- function backfillJournalPath(handle: EngineHandle, journalPath: string): void {
295
- handle.data.journalPath = journalPath;
296
- }
297
-
298
297
  /**
299
298
  * AgentOutcome → workflow AgentResult:剥离引擎层新增字段(engineId/engineFallback/
300
299
  * exitCode——engineFallback 经 record(pi 路径)/outcome(zcode 路径)留痕,GUI 投影
@@ -305,6 +304,9 @@ function backfillJournalPath(handle: EngineHandle, journalPath: string): void {
305
304
  function outcomeToRunnerResult(outcome: AgentOutcome): AgentResult {
306
305
  return {
307
306
  content: outcome.content,
307
+ // [D5-③] 失败分诊标签透传(pi 引擎产出;zcode 不产 failureKind,缺省 =
308
+ // unknown = 可重试)。成功路径 undefined 不落键。
309
+ ...(outcome.failureKind !== undefined ? { failureKind: outcome.failureKind } : {}),
308
310
  parsedOutput: outcome.parsedOutput,
309
311
  usage: outcome.usage,
310
312
  durationMs: outcome.durationMs,
@@ -315,3 +317,48 @@ function outcomeToRunnerResult(outcome: AgentOutcome): AgentResult {
315
317
  toolCalls: outcome.toolCalls,
316
318
  };
317
319
  }
320
+
321
+ /**
322
+ * D-A9: per-call timeoutMs 合并进 AbortSignal([D6 合流迁入]——原定义在已删除的
323
+ * execution/execute-options-mapper.ts,本类是唯一消费点,运行期件随消费方落位)。
324
+ *
325
+ * 墙钟 timeoutMs(per-call)+ 外部 signal(run 级 abort)都生效。
326
+ * 缺此合并则 agent({timeoutMs:5000}) 静默无效(BC-9)。
327
+ *
328
+ * @param signal 外部 signal(workflow run 级 controller.signal)
329
+ * @param timeoutMs per-call 墙钟超时;undefined/<=0 → 不设超时,原样返回 signal
330
+ * @returns 合并后的 signal(timeoutMs 或外部 signal 任一 abort 都触发)
331
+ */
332
+ export function mergeTimeoutSignal(
333
+ signal: AbortSignal,
334
+ timeoutMs?: number,
335
+ ): AbortSignal {
336
+ if (!timeoutMs || timeoutMs <= 0) {
337
+ return signal;
338
+ }
339
+
340
+ const controller = new AbortController();
341
+ // 超时 abort 带 reason 标记(对齐点④):引擎合成终态时判别「宿主超时」
342
+ // (engine_timeout 公共合成)vs「外部 cancel」(中止标记)——pi 链路不读 reason,
343
+ // 行为不变。外部 signal abort 不带标记(用户/编排层 cancel 语义)。
344
+ const timer = setTimeout(() => controller.abort(HOST_TIMEOUT_ABORT_REASON), timeoutMs);
345
+ timer.unref();
346
+
347
+ const onExternalAbort = (): void => controller.abort();
348
+ if (signal.aborted) {
349
+ controller.abort();
350
+ } else {
351
+ signal.addEventListener("abort", onExternalAbort, { once: true });
352
+ }
353
+
354
+ controller.signal.addEventListener(
355
+ "abort",
356
+ () => {
357
+ clearTimeout(timer);
358
+ if (!signal.aborted) signal.removeEventListener("abort", onExternalAbort);
359
+ },
360
+ { once: true },
361
+ );
362
+
363
+ return controller.signal;
364
+ }
@@ -0,0 +1,87 @@
1
+ // src/execution/sync-rebuild.ts
2
+ //
3
+ // [E1 恢复批语义修复] sync 批崩溃恢复(E1)与批闭合 flush(S11 兜底)的两条
4
+ // BgNotifyRecord/SubagentRecord 映射,从 subagent-service 拆出(D4 按变化轴拆分:
5
+ // 改恢复批的通知语义 / 落标数据源形态,只改本文件)。两函数均纯映射——零 service/
6
+ // store 依赖,rootSessionId 由调用方注入。
7
+
8
+ import { deriveOutcome } from "./execution-record.ts";
9
+ import type { BgNotifyRecord } from "./notifier.ts";
10
+ import type { SubagentRecord } from "./types.ts";
11
+
12
+ /**
13
+ * E1 末条 entry 终态快照 → BgNotifyRecord(补发成员;sync 仅 one-shot,round/
14
+ * sessionFile 不透传——与 route() 缓冲快照的 one-shot 形态对齐)。
15
+ *
16
+ * [E1 恢复批语义修复] status/outcome/patchFile 三点对齐 notify-host toNotifyRecord
17
+ * 的映射(正常 flush 路径对同一成员的补发形态),不再直通 rec.status:
18
+ * - status:one-shot 成功成员崩溃时末条 entry 恒为 running+resumable(SP-5 轮终
19
+ * 形态,resumable 豁免正据此放行其入批)——直通会让补发记录仍是 running 形态:
20
+ * buildBatchLlmContent 批头只统计 closed 成员(全员成功的恢复批显示
21
+ * 「0 finished, 0 failed, 0 cancelled」),条目文案落「finished a round」
22
+ * (对话轮次语义)。同 toNotifyRecord:closed 或非 chatMode → "closed"(仅
23
+ * chatMode 轮次形态保持 running——sync 成员恒 one-shot,此分支为防御完整性)。
24
+ * - outcome:closed 状态物化(单一权威 deriveOutcome)——resumable 成员末条未
25
+ * 终态化,closedReason 缺省与正常 flush 路径同形,无 error 即 completed、有
26
+ * error 即 failed;notifier.notifyBatch 投影边界的 `??` 兜底对此幂等。
27
+ * - patchFile:透传(依赖 rebuildEntryRecord 的同名投影)——worktree one-shot
28
+ * 成员的 git-apply 回收指针只在 closed+completed 分支文案携带(running 分支
29
+ * 不含),正常 flush 路径经 toNotifyRecord 特意携带,恢复批不得缺失。
30
+ */
31
+ export function syncRebuildToNotifyMember(rec: SubagentRecord): BgNotifyRecord {
32
+ const status: BgNotifyRecord["status"] =
33
+ rec.status === "closed" || !rec.chatMode ? "closed" : "running";
34
+ return {
35
+ id: rec.id,
36
+ status,
37
+ closedReason: rec.closedReason,
38
+ outcome: status === "closed" ? deriveOutcome(rec.closedReason, rec.error) : undefined,
39
+ agent: rec.agent,
40
+ model: rec.model,
41
+ result: rec.result,
42
+ error: rec.error,
43
+ startedAt: rec.startedAt,
44
+ endedAt: rec.endedAt,
45
+ patchFile: rec.patchFile,
46
+ };
47
+ }
48
+
49
+ /**
50
+ * [S11] getFullRecord miss 成员的缓冲快照兜底 → 最小 SubagentRecord(batchFinalized
51
+ * 落标数据源)。getFullRecord 不可达(子 session 文件缺失/已 GC)时,缓冲的
52
+ * BgNotifyRecord 是该成员唯一残存数据。最小形态只保标记链路必需字段:
53
+ * id/agent/task/startedAt 是 rebuildEntryRecord 的解析门槛(缺 task 的 entry 会被
54
+ * E1 扫描判损坏跳过——标记失效方向,task 占位空串保 entry 可解析);终态字段
55
+ * (closedReason/result/error/endedAt/model/patchFile)自缓冲快照如实投影;
56
+ * rootSessionId 取当前 session 根(E1 候选过滤的归属口径)。
57
+ */
58
+ export function bufferedMemberFallbackRecord(
59
+ m: BgNotifyRecord,
60
+ rootSessionId: string | undefined,
61
+ ): SubagentRecord {
62
+ return {
63
+ id: m.id,
64
+ agent: m.agent,
65
+ task: "",
66
+ slug: "",
67
+ status: "closed",
68
+ closedReason: m.closedReason,
69
+ mode: "background",
70
+ startedAt: m.startedAt,
71
+ rootSessionId,
72
+ parentRecordId: undefined,
73
+ depth: 0,
74
+ endedAt: m.endedAt,
75
+ turns: 0,
76
+ totalTokens: 0,
77
+ model: m.model ?? "",
78
+ thinkingLevel: undefined,
79
+ eventLog: [],
80
+ displayItems: [],
81
+ result: m.result,
82
+ error: m.error,
83
+ sessionFile: undefined,
84
+ chatMode: false,
85
+ patchFile: m.patchFile,
86
+ };
87
+ }
@@ -9,6 +9,7 @@
9
9
 
10
10
  import type { GuiRenderResult } from "@xyz-agent/extension-protocol";
11
11
 
12
+ import type { AgentFailureKind } from "../orchestration/models/types.ts";
12
13
  import type { ModelInfo, ModelRegistryLike } from "./model-resolver.ts";
13
14
 
14
15
  // ============================================================
@@ -318,6 +319,12 @@ export interface AgentResult {
318
319
  durationMs: number;
319
320
  success: boolean;
320
321
  error?: string;
322
+ /**
323
+ * [D5-③] 失败分诊结构化标签(类型 SSOT 在 orchestration/models/types.ts 的
324
+ * AgentFailureKind——消费语义「unknown=可重试」与其文档同源)。collectResult 对
325
+ * 最终 error 分类后写入;缺省 = unknown(可重试)。type-only 引用零运行时依赖。
326
+ */
327
+ failureKind?: AgentFailureKind;
321
328
  sessionId: string;
322
329
  toolCalls: ToolCall[];
323
330
  usage?: AgentUsageTotal;
@@ -472,6 +479,14 @@ export interface ExecutionRecord {
472
479
  * 回填(sessionFile 即定位符)。持久化经 subagent-record entry。
473
480
  */
474
481
  engineHandle?: { sessionRef: Record<string, string>; journalPath?: string; poolKey: string };
482
+ /**
483
+ * 同步收集模式标记(subagent-sync-collect 设计 §3.1.3,U1 foundation 契约)。
484
+ * 创建时确定不可变;undefined = async(缺省语义,旧记录零迁移)。持久化经
485
+ * subagent-record entry(record-entry.ts 序列化白名单,entry 唯一写点)。
486
+ * 消费方:U2 collectCoordinator 路由(sync→批缓冲)、U5 E1 重建投影。
487
+ * U2 接线点:service.createRecordForMode 从 ExecuteOptions.collect 读入 identity。
488
+ */
489
+ readonly collectMode?: "sync";
475
490
 
476
491
  // ── 状态(实时更新)──
477
492
  status: ExecutionStatus;
@@ -485,6 +500,13 @@ export interface ExecutionRecord {
485
500
  * record 无此字段,投影层按 projectOutcome 兜底(closed-legacy 语义)。
486
501
  */
487
502
  outcome?: ExecutionOutcome;
503
+ /**
504
+ * 离开批的终局标记(subagent-sync-collect 设计 §3.1.3,U1 foundation 契约)。
505
+ * 两出口统一落标:① 批闭合 flush 写账成功后;② E9 dispose 逐条转 async 写账后
506
+ * (均 appendEntry 持久化,U3/U5 写点)。undefined = 未离开批 / 旧记录零迁移。
507
+ * 消费方:U5 E1 重建扫描只收「collectMode=sync 且无本标记」的成员(防双重通知)。
508
+ */
509
+ batchFinalized?: boolean;
488
510
  /** 完整执行内容,按 turn 组织。createRecord 初始化为 [空 turn]。 */
489
511
  turns: Turn[];
490
512
  /** turn 计数(= turns.filter(closed).length,冗余存储供投影直接读)。 */
@@ -669,6 +691,17 @@ export interface ExecuteOptions {
669
691
  * undefined/false = 一次性模式(默认,行为完全不变)。service.execute 透传到 createRecordForMode。
670
692
  */
671
693
  conversation?: boolean;
694
+ /**
695
+ * 同步收集模式(subagent-sync-collect 设计 §3.1.3,U1 foundation 契约)。
696
+ * undefined = config collectSync.default(缺省 "async",新 session 生效)。
697
+ * schema 层枚举限 "async"|"sync";运行时宽收 string 与 engine 字段同风格
698
+ * (非法值 ≠ "sync" 按 async 处理)。
699
+ * "sync" + conversation:true 组合在 startHandler E4 校验即拒
700
+ * (immediate throw,不产生半启动 record)。
701
+ * U2 接线点:service.createRecordForMode 读入 createRecord identity.collectMode
702
+ * (U1 打通类型与 startHandler 透传,record 落点归 U2)。
703
+ */
704
+ collect?: string;
672
705
  /**
673
706
  * 空闲超时毫秒数(仅 conversation 模式有意义)。覆盖默认 5min idle timeout。
674
707
  * 优先级:参数 > env XYZ_SUBAGENT_IDLE_TIMEOUT_MS > 默认 300000ms。
@@ -757,6 +790,13 @@ export interface BgResponse {
757
790
  * 值语义由 U2(execution/notify-ledger.ts)兑现。
758
791
  */
759
792
  notifyContract: "ledger+at-least-once";
793
+ /**
794
+ * 同步收集登记回显段(subagent-sync-collect 设计 §3.1.1 交互样例,U1 foundation)。
795
+ * 仅 resolved 模式为 sync 时附带(async 响应字节零变化,G3):mode = 生效模式;
796
+ * pendingSyncCount = 当前未闭合批的 sync 成员总数(含本条;跨轮派发续累不重置,
797
+ * 与 D2 隐式批一致)。
798
+ */
799
+ collect?: { mode: "sync"; pendingSyncCount: number };
760
800
  }
761
801
 
762
802
  /** list 的内层响应(挂在 SubagentToolResult.listResponse)。 */
@@ -831,6 +871,8 @@ export interface SubagentRecord {
831
871
  status: ExecutionStatus;
832
872
  /** L2 关闭原因子枚举(仅 status="closed" 时有意义)。SP-1 新增。 */
833
873
  closedReason?: ClosedReason;
874
+ /** 终态三态对外语义(U3 C-outcome)。磁盘重建源一等直读;无字段的存量兜底走 projectOutcome。 */
875
+ outcome?: ExecutionOutcome;
834
876
  mode: ExecutionMode;
835
877
  startedAt: number;
836
878
  /** 根 Pi session ID(session 隔离过滤用)。递归链上所有层 record 同值。 */
@@ -893,12 +935,37 @@ export interface SubagentRecord {
893
935
  * subagent-engine-history);缺省 = pi(走 JSONL 直读链)。
894
936
  */
895
937
  engineHandle?: { sessionRef: Record<string, string>; journalPath?: string; poolKey: string };
938
+ /**
939
+ * 同步收集模式标记(与 ExecutionRecord.collectMode 同源投影/重建,U1 foundation)。
940
+ * 缺省(存量 record)= async 投影,消费方零迁移。
941
+ */
942
+ collectMode?: "sync";
943
+ /**
944
+ * 离开批终局标记(与 ExecutionRecord.batchFinalized 同源投影/重建,U1 foundation)。
945
+ * 缺省 = 未离开批;U5 E1 重建扫描据此排除已离场成员。
946
+ */
947
+ batchFinalized?: boolean;
896
948
  }
897
949
 
898
950
  // ============================================================
899
951
  // 配置(global + session)
900
952
  // ============================================================
901
953
 
954
+ /**
955
+ * 同步收集(sync collect)配置节类型(subagent-sync-collect 设计 §3.1.3,U1 foundation)。
956
+ * 权威默认值在 config.ts DEFAULT_COLLECT_SYNC;坏值 sanitize 回默认不炸启动(E5,
957
+ * 与 maxConcurrent 同判)。类型定义于 types.ts(避免 config → types 反向依赖成环),
958
+ * config.ts re-export。
959
+ */
960
+ export interface CollectSyncConfig {
961
+ /** start 未显式传 collect 时的缺省模式。新 session 生效(与 engine 配置时机一致)。 */
962
+ default: "async" | "sync";
963
+ /** 批通知单条目结果正文预算(字符):超出截断并接 session_read 指针行。flush 时热读。 */
964
+ perItemChars: number;
965
+ /** 批通知结果正文总量预算(字符):Σ 超限时统一收紧 effectivePerItem(U4 算法)。flush 时热读。 */
966
+ totalChars: number;
967
+ }
968
+
902
969
  /**
903
970
  * 全局配置(~/.pi/agent/subagents/config.json)。
904
971
  *
@@ -916,6 +983,11 @@ export interface SubagentsGlobalConfig {
916
983
  defaultEngine?: string;
917
984
  /** 引擎路由策略(D9①):strict=true 时一切 probe 失败直接报错(不 fallback)。 */
918
985
  engineRouting?: { strict: boolean };
986
+ /**
987
+ * 同步收集配置节(subagent-sync-collect 设计 §3.1.3,U1 foundation)。
988
+ * 整节缺省 = DEFAULT_COLLECT_SYNC(config.ts);逐字段 sanitize 回默认(E5)。
989
+ */
990
+ collectSync?: CollectSyncConfig;
919
991
  }
920
992
 
921
993
  // ============================================================