@zhushanwen/subagent-core 0.5.1 → 0.7.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 (318) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-KXVBIVOU.js +16 -0
  3. package/dist/chunk-T2SYBW3I.js +24 -0
  4. package/dist/chunk-VURUAGMM.js +2305 -0
  5. package/dist/{types-Dv4QhSJ_.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +835 -668
  6. package/dist/{types-Dv4QhSJ_.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +835 -668
  7. package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
  8. package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
  9. package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
  10. package/dist/execution/engine/engine-discovery-scan.js +20 -0
  11. package/dist/execution/engine/paths.cjs +6 -23
  12. package/dist/execution/engine/paths.d.cts +1 -8
  13. package/dist/execution/engine/paths.d.ts +1 -8
  14. package/dist/execution/engine/paths.js +1 -1
  15. package/dist/execution/relay-env.cjs +12 -28
  16. package/dist/execution/relay-env.d.cts +1 -33
  17. package/dist/execution/relay-env.d.ts +1 -33
  18. package/dist/execution/relay-env.js +5 -3
  19. package/dist/index.cjs +14123 -15467
  20. package/dist/index.d.cts +1179 -1540
  21. package/dist/index.d.ts +1179 -1540
  22. package/dist/index.js +7694 -10986
  23. package/dist.bundle/index.cjs +33485 -0
  24. package/package.json +20 -26
  25. package/src/__tests__/record-store-last-line.test.ts +16 -7
  26. package/src/core/error-message.ts +7 -6
  27. package/src/core/host-services.ts +8 -2
  28. package/src/core/notify-ports.ts +17 -2
  29. package/src/execution/__tests__/agent-registry.test.ts +1 -1
  30. package/src/execution/__tests__/alive-store.test.ts +1 -1
  31. package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
  32. package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
  33. package/src/execution/__tests__/collect-budget.test.ts +291 -0
  34. package/src/execution/__tests__/collect-coordinator-service.test.ts +316 -0
  35. package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
  36. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +229 -0
  37. package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
  38. package/src/execution/__tests__/config.test.ts +1 -1
  39. package/src/execution/__tests__/delivery-methods.test.ts +179 -237
  40. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
  41. package/src/execution/__tests__/execute-nesting.test.ts +20 -13
  42. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +21 -34
  43. package/src/execution/__tests__/finalized-marker.test.ts +1 -1
  44. package/src/execution/__tests__/gc-timer.test.ts +8 -23
  45. package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
  46. package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
  47. package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
  48. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
  49. package/src/execution/__tests__/idle-gc.test.ts +200 -0
  50. package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
  51. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +1 -1
  52. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
  53. package/src/execution/__tests__/notify-batch.test.ts +500 -0
  54. package/src/execution/__tests__/notify-ledger.test.ts +27 -0
  55. package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
  56. package/src/execution/__tests__/record-entry-collect.test.ts +102 -0
  57. package/src/execution/__tests__/record-store.test.ts +60 -6
  58. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
  59. package/src/execution/__tests__/relay-env.test.ts +12 -1
  60. package/src/execution/__tests__/round-supervisor.test.ts +293 -0
  61. package/src/execution/__tests__/session-file-gc.test.ts +1 -1
  62. package/src/execution/__tests__/session-pending.test.ts +119 -17
  63. package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
  64. package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
  65. package/src/execution/__tests__/subagent-actions-core.test.ts +6 -0
  66. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +14 -11
  67. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
  68. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
  69. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
  70. package/src/execution/__tests__/subagent-service.test.ts +2 -2
  71. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
  72. package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
  73. package/src/execution/__tests__/sync-collect-recovery.test.ts +1102 -0
  74. package/src/execution/__tests__/tombstone-store.test.ts +1 -1
  75. package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
  76. package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
  77. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
  78. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
  79. package/src/execution/__tests__/worktree-registry.test.ts +1 -1
  80. package/src/execution/agent-registry.ts +6 -2
  81. package/src/execution/collect-coordinator.ts +200 -0
  82. package/src/execution/config.ts +77 -5
  83. package/src/execution/dialog-queue.ts +6 -73
  84. package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
  85. package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
  86. package/src/execution/engine/__tests__/common/event-journal.test.ts +1 -1
  87. package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
  88. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
  89. package/src/execution/engine/__tests__/common/pool-manager.test.ts +2 -2
  90. package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
  91. package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
  92. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
  93. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
  94. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
  95. package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
  96. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
  97. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
  98. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
  99. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +82 -55
  100. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
  101. package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
  102. package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
  103. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +8 -3
  104. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
  105. package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
  106. package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
  107. package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
  108. package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
  109. package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
  110. package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
  111. package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
  112. package/src/execution/engine/__tests__/registry.test.ts +206 -1
  113. package/src/execution/engine/__tests__/routing.test.ts +97 -0
  114. package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
  115. package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
  116. package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
  117. package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
  118. package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
  119. package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
  120. package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
  121. package/src/execution/engine/client/client-options.ts +103 -0
  122. package/src/execution/engine/client/engine-client.ts +687 -0
  123. package/src/execution/engine/client/mirror.ts +167 -0
  124. package/src/execution/engine/client/pid-file.ts +392 -0
  125. package/src/execution/engine/client/reaper.ts +95 -0
  126. package/src/execution/engine/client/remote-engine.ts +441 -0
  127. package/src/execution/engine/client/reverse-router.ts +255 -0
  128. package/src/execution/engine/common/capability-gate.ts +109 -22
  129. package/src/execution/engine/common/errors.ts +9 -25
  130. package/src/execution/engine/common/event-journal.ts +4 -50
  131. package/src/execution/engine/common/journal-replay.ts +3 -1
  132. package/src/execution/engine/common/kill-chain.ts +18 -251
  133. package/src/execution/engine/common/nesting-guard.ts +18 -114
  134. package/src/execution/engine/common/pool-manager.ts +4 -0
  135. package/src/execution/engine/common/session-view-service.ts +56 -84
  136. package/src/execution/engine/config.ts +151 -0
  137. package/src/execution/engine/d8-compat.ts +346 -0
  138. package/src/execution/engine/engine-discovery-roots.ts +107 -0
  139. package/src/execution/engine/engine-discovery-scan.ts +269 -0
  140. package/src/execution/engine/engine-discovery.ts +30 -7
  141. package/src/execution/engine/engine-inspect-package.ts +282 -0
  142. package/src/execution/engine/engine-manifest.ts +244 -0
  143. package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
  144. package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
  145. package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
  146. package/src/execution/engine/host/host-bridge.ts +150 -0
  147. package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
  148. package/src/execution/engine/host/pi-host-binding.ts +91 -0
  149. package/src/execution/engine/host/spawned-children.ts +139 -0
  150. package/src/execution/engine/host-task-spec.ts +29 -2
  151. package/src/execution/engine/model-validation.ts +55 -2
  152. package/src/execution/engine/paths.ts +16 -41
  153. package/src/execution/engine/port.ts +48 -2
  154. package/src/execution/engine/registry.ts +153 -34
  155. package/src/execution/engine/routing.ts +225 -52
  156. package/src/execution/engine/types.ts +25 -200
  157. package/src/execution/execution-record.ts +7 -0
  158. package/src/execution/finalize-record.ts +40 -11
  159. package/src/execution/idle-gc.ts +89 -14
  160. package/src/execution/lifecycle-manager.ts +10 -7
  161. package/src/execution/lifecycle-predicates.ts +10 -8
  162. package/src/execution/notifier.ts +234 -25
  163. package/src/execution/notify-host.ts +21 -1
  164. package/src/execution/record-entry.ts +16 -0
  165. package/src/execution/record-store.ts +189 -31
  166. package/src/execution/relay-env.ts +19 -36
  167. package/src/execution/round-supervisor/domain.ts +89 -0
  168. package/src/execution/round-supervisor/index.ts +33 -0
  169. package/src/execution/round-supervisor/notify-accounting.ts +87 -0
  170. package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
  171. package/src/execution/round-supervisor/service-binding.test.ts +661 -0
  172. package/src/execution/round-supervisor/service-binding.ts +273 -0
  173. package/src/execution/round-supervisor/supervisor.ts +426 -0
  174. package/src/execution/session-pending.ts +68 -74
  175. package/src/execution/settled-watchdog.ts +39 -0
  176. package/src/execution/subagent-actions-core.ts +62 -6
  177. package/src/execution/subagent-service.ts +1161 -406
  178. package/src/execution/subprocess-agent-runner.ts +16 -8
  179. package/src/execution/sync-rebuild.ts +87 -0
  180. package/src/execution/types.ts +104 -117
  181. package/src/execution/ui-channels.ts +13 -214
  182. package/src/execution/ui-request-handler-factory.ts +7 -4
  183. package/src/execution/ui-request-observability.ts +2 -2
  184. package/src/execution/workflow-state-root.ts +67 -0
  185. package/src/execution/worktree-git-ops.ts +5 -0
  186. package/src/execution/worktree-manager.ts +11 -1
  187. package/src/index.ts +55 -26
  188. package/src/orchestration/__tests__/config-loader.test.ts +1 -1
  189. package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
  190. package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
  191. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
  192. package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
  193. package/src/orchestration/__tests__/script-generate.test.ts +5 -5
  194. package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
  195. package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
  196. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +1 -1
  197. package/src/orchestration/execute-agent-call.ts +1 -1
  198. package/src/orchestration/file-run-store.ts +144 -59
  199. package/src/orchestration/models/types.ts +43 -42
  200. package/src/shared/__tests__/atomic-write.test.ts +1 -1
  201. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
  202. package/src/shared/zcode-model-ref.ts +31 -0
  203. package/dist/chunk-43ONBFZX.js +0 -240
  204. package/dist/chunk-A4IVZWVX.js +0 -31
  205. package/dist/chunk-APZY4IME.js +0 -27
  206. package/dist/chunk-V3VHZ2VX.js +0 -59
  207. package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
  208. package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
  209. package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
  210. package/dist/execution/engine/engines/zcode/constants.js +0 -54
  211. package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
  212. package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
  213. package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
  214. package/dist/execution/engine/engines/zcode/reader.js +0 -9
  215. package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
  216. package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
  217. package/src/__tests__/session-runner.test.ts +0 -69
  218. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  219. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
  220. package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
  221. package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
  222. package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
  223. package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
  224. package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
  225. package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
  226. package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
  227. package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
  228. package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
  229. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
  230. package/src/execution/__tests__/output-collector.test.ts +0 -469
  231. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  232. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
  233. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  234. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
  235. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
  236. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
  237. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
  238. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  239. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  240. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  241. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
  242. package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
  243. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
  244. package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
  245. package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
  246. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
  247. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
  248. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
  249. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
  250. package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
  251. package/src/execution/__tests__/spawn-args.test.ts +0 -446
  252. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
  253. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  254. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
  255. package/src/execution/__tests__/spawned-children.test.ts +0 -236
  256. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  257. package/src/execution/__tests__/stdin-writer.test.ts +0 -464
  258. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
  259. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  260. package/src/execution/__tests__/timeout-integration.test.ts +0 -616
  261. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  262. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  263. package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
  264. package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
  265. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
  266. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  267. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
  268. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  269. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
  270. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  271. package/src/execution/engine/common/schema-emulation.ts +0 -189
  272. package/src/execution/engine/common/session-view-projection.ts +0 -51
  273. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
  274. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  275. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
  276. package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
  277. package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
  278. package/src/execution/engine/engines/pi/output-collector.ts +0 -317
  279. package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
  280. package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
  281. package/src/execution/engine/engines/pi/reader.ts +0 -59
  282. package/src/execution/engine/engines/pi/registration.ts +0 -37
  283. package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
  284. package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
  285. package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
  286. package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
  287. package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
  288. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
  289. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
  290. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
  291. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
  292. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
  293. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
  294. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  295. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
  296. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
  297. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
  298. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
  299. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
  300. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
  301. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
  302. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
  303. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
  304. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
  305. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
  306. package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
  307. package/src/execution/engine/engines/zcode/connection.ts +0 -598
  308. package/src/execution/engine/engines/zcode/constants.ts +0 -176
  309. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
  310. package/src/execution/engine/engines/zcode/parser.ts +0 -102
  311. package/src/execution/engine/engines/zcode/preparer.ts +0 -235
  312. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  313. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  314. package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
  315. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
  316. package/src/execution/round-settlement.ts +0 -93
  317. package/src/execution/ui-request-queue.ts +0 -215
  318. package/src/shared/schema-env.ts +0 -44
@@ -84,79 +84,12 @@ function dialogTimeoutLogMessage(req: UiRequest, waitedMs: number): string {
84
84
  );
85
85
  }
86
86
 
87
- // ── 类型定义(本模块是 UiRequest/UiResponse/UiRequestHandler 的规范来源) ──
88
- // session-runner.ts 和 ui-channels.ts 复用这些类型(session-runner 再导出供测试 import)。
89
-
90
- /** Pi extension_ui_request 的方法枚举(dialog + fire-and-forget 两类)。
91
- * dialog 类:select/confirm/input/editor(占输入焦点,等响应)。
92
- * fire-and-forget 类:notify/setStatus/setWidget/setTitle/set_editor_text(纯展示/写入)。
93
- * (string & {}) 兜底:Pi 未来新增 method 或未知 method 走字符串字面量类型。 */
94
- export type UiMethod =
95
- | "select"
96
- | "confirm"
97
- | "input"
98
- | "editor"
99
- | "notify"
100
- | "setStatus"
101
- | "setWidget"
102
- | "setTitle"
103
- | "set_editor_text"
104
- | (string & {});
105
-
106
- /** UI 请求(session-runner 构造后传给 handler)。
107
- *
108
- * method 是判别字段,决定排队策略(dialog 排队)和业务路由(channel 分发)。
109
- * method 特定字段按 method 可选出现(与 ExtensionUiRequest 1:1,由 session-runner 从
110
- * ExtensionUiRequest 平铺构造)。channel/channelPayload 由 parseChannel 填充。
111
- *
112
- * 契约来源:.fix-plans/00-master-summary.md §二 2.2。 */
113
- export interface UiRequest {
114
- /** Pi rpc-types.ts 的 method(select/confirm/input/editor 为 dialog 类)。 */
115
- method: UiMethod;
116
- /** 请求 id(从 extension_ui_request envelope 顶层提取,用于 response 关联)。 */
117
- id: string;
118
- // method 特定字段(按 method 可选,与 ExtensionUiRequest 1:1)
119
- title?: string;
120
- options?: string[];
121
- message?: string;
122
- placeholder?: string;
123
- prefill?: string;
124
- notifyType?: string;
125
- statusKey?: string;
126
- statusText?: string | undefined;
127
- widgetKey?: string;
128
- widgetLines?: string[] | undefined;
129
- widgetPlacement?: "aboveEditor" | "belowEditor";
130
- text?: string;
131
- timeout?: number;
132
- /** channel 名(从 method 对应字段的 NUL 前缀解析)。
133
- * select → 从 title 解析;setWidget → 从 widgetLines[0] 解析;其他 → undefined。
134
- * 已知值:"ask_user"(select)、"gui_widget"(setWidget)。handler 按 channel 分发。 */
135
- channel?: string;
136
- /** channel 解析后的结构化 payload(已 JSON.parse)。
137
- * ask_user: {questions, allowCancel};gui_widget: {component};无 channel: undefined。 */
138
- channelPayload?: unknown;
139
- /** 内部元数据字段:发起该 UI 请求的子进程 pid(由 session-runner.handleUiRequest 从
140
- * child.pid 填入)。L2 队列据此关联 rejectChildDialogs(child close 时批量 reject)。
141
- * 下划线前缀表示内部字段,非 Pi 协议字段,不参与 stdin 回写。 */
142
- _childPid?: number;
143
- }
144
-
145
- /** UI 响应(handler 返回,session-runner 按 shape 回写 stdin)。
146
- * - {value}: select/input/editor 的答案
147
- * - {confirmed}: confirm 的答案
148
- * - {cancelled}: 取消(child close / handler 抛错 / 用户取消)
149
- * - {ack}: fire-and-forget(当前不透传到 TUI,留作协议完整) */
150
- export type UiResponse =
151
- | { value: string }
152
- | { confirmed: boolean }
153
- | { cancelled: true }
154
- | { ack: true };
155
-
156
- /** UI 请求 handler 签名(单函数,按 req.method 内部路由)。
157
- * 实现方负责:channel 业务路由(ask_user → AskUserComponent)+ 默认转发(ctx.ui.*)。
158
- * 抛错由调用方(DialogGlobalQueue / session-runner)兜底为 {cancelled:true}。 */
159
- export type UiRequestHandler = (req: UiRequest) => Promise<UiResponse>;
87
+ // ── 类型再导出(W7 / R3 S-A + R4-S③:SSOT 迁 @zhushanwen/subagent-engine-sdk
88
+ // src/ui-types.ts,结构等价;队列实现本体留 core——壳侧 host/askUser 消费端与
89
+ // inproc 过渡链路同样消费该类型面。双向可赋值断言挂本包 typecheck 断言族
90
+ // (contract-closure),漂移编译期可抓。 ──
91
+ export type { UiMethod, UiRequest, UiRequestHandler, UiResponse } from "@zhushanwen/subagent-engine-sdk";
92
+ import type { UiRequest, UiRequestHandler, UiResponse } from "@zhushanwen/subagent-engine-sdk";
160
93
 
161
94
  // ── DialogGlobalQueue 实现 ──
162
95
 
@@ -1,5 +1,6 @@
1
1
  // capability-gate.test.ts —— [D3-④ 预检 capabilities 化] 拦截矩阵单测。
2
- // 设计权威源:docs/design/subagent-dual-track-convergence.md §3.3 D3-④(r3 裁定:
2
+ // 设计权威源:docs/design/subagent-engine-protocolization.md §3.3「能力位」段(manifest
3
+ // 权威双向处置)+ 历史源 subagent-dual-track-convergence.md §3.3 D3-④(r3 裁定:
3
4
  // EngineCapabilities +maxTurns 位 pi=true/zcode=false,不保留硬编码 shape 检查)+
4
5
  // §3.4 错误规格第 1 行 + §4 V4④⑤(正反向验收)。
5
6
  //
@@ -7,21 +8,41 @@
7
8
  // 1. per-engine 拦截矩阵:pi 全放行(含 maxTurns/fork/conversation/worktree——V4⑤
8
9
  // 反向守护,pi 既有合法能力零拦截);zcode 四参数全拦(fork/conversation/
9
10
  // maxTurns/worktree)
10
- // 2. 错误族:engine_capability_unsupported + recovery 含可操作指引(换参数/换引擎)
11
- // 3. fork 判据(借位裁定):session 分叉通道族任一可用即放行——pi conversation=
12
- // native 放行(steer unsupported 不参与否决);通道族全缺才拦
11
+ // 2. 错误族:engine_capability_unsupported + recovery 含可操作指引(调参数 / 修
12
+ // manifest / 升级引擎包——W3 协议化口径,不再指向「engine: pi」内置兜底)
13
+ // 3. fork 判据(借位裁定):session 分叉通道族任一可用即放行(OR 语义,A6⑦)——
14
+ // pi conversation=native 放行(steer 虽 unsupported 不参与否决);通道族全缺才拦
15
+ // 4. [W3] 方向判定②:manifest 多声明 → assertGateCapabilitiesMatched 抛
16
+ // engine_capability_mismatch(gate 位逐位正反例 + 非 gate 位不判定)
13
17
 
14
18
  import { describe, expect, it } from "vitest";
15
19
 
16
- import { assertTaskShapeSupported, type TaskShapeForGate } from "../../common/capability-gate.ts";
20
+ import {
21
+ assertGateCapabilitiesMatched,
22
+ assertTaskShapeSupported,
23
+ type TaskShapeForGate,
24
+ } from "../../common/capability-gate.ts";
17
25
  import { EngineError } from "../../common/errors.ts";
26
+ import { readFileSync } from "node:fs";
27
+ import { dirname, join } from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+
18
30
  import type { EngineCapabilities } from "../../types.ts";
19
- import { PiEngine } from "../../engines/pi/pi-engine.ts";
20
- import { ZcodeEngine } from "../../engines/zcode/zcode-engine.ts";
21
31
 
22
- /** 真实引擎的 capabilities 面单测直取(D3 声明是判据本体——pi=true/zcode=false 扩位)。 */
23
- const PI_CAPS = new PiEngine({ getService: () => null }).capabilities();
24
- const ZCODE_CAPS = new ZcodeEngine({ engineDataDir: () => "/tmp/zcode-gate" }).capabilities();
32
+ // W10(§2.10 ②):gate 判据源改读引擎包 manifest(package.json xyz-agent.capabilities
33
+ // ——协议化后同步成员唯一源),不再深路径构造内建引擎实例(W11 删除)。
34
+ function manifestCaps(relPkg: string): EngineCapabilities {
35
+ const pkg = JSON.parse(
36
+ readFileSync(
37
+ join(dirname(fileURLToPath(import.meta.url)), "../../../../../../", relPkg, "package.json"),
38
+ "utf8",
39
+ ),
40
+ ) as { "xyz-agent": { subagentEngine: { capabilities: EngineCapabilities } } };
41
+ return pkg["xyz-agent"].subagentEngine.capabilities;
42
+ }
43
+
44
+ const PI_CAPS = manifestCaps("pi-subagent-cli");
45
+ const ZCODE_CAPS = manifestCaps("zcode-subagent-cli");
25
46
 
26
47
  /** 会话分叉通道族可用的 zcode 形态变体(fork 判据用)。 */
27
48
  const ZCODE_CAPS_WITH_CONVERSATION: EngineCapabilities = { ...ZCODE_CAPS, conversation: "native" };
@@ -34,12 +55,24 @@ function gate(
34
55
  assertTaskShapeSupported(engineId, caps, task);
35
56
  }
36
57
 
37
- function gateError(caps: EngineCapabilities, task: TaskShapeForGate, engineId = "zcode"): EngineError {
58
+ /** 断言载体(结构化面):EngineError(core)与 EngineSdkError(SDK 构造器)共用
59
+ * code/message/recovery 契约,测试按结构断言不绑类。 */
60
+ interface GateErrorShape {
61
+ code: string;
62
+ message: string;
63
+ recovery: string;
64
+ }
65
+
66
+ function gateError(caps: EngineCapabilities, task: TaskShapeForGate, engineId = "zcode"): GateErrorShape {
38
67
  try {
39
68
  gate(caps, task, engineId);
40
69
  } catch (err) {
41
- expect(err).toBeInstanceOf(EngineError);
42
- return err as EngineError;
70
+ // [W1 交接防漂移项落地] conversation 分支抛 SDK EngineSdkError
71
+ //(engineConversationUnsupportedError——core 与引擎侧判据单源,W3 接线);其余
72
+ // 分支仍为 core EngineError。code/recovery/message 前缀契约两侧一致。
73
+ expect(err).toHaveProperty("code");
74
+ expect(err).toHaveProperty("recovery");
75
+ return err as unknown as GateErrorShape;
43
76
  }
44
77
  throw new Error("expected assertTaskShapeSupported to throw");
45
78
  }
@@ -71,8 +104,10 @@ describe("capability-gate(D3-④ 拦截矩阵)", () => {
71
104
  expect(err.code).toBe("engine_capability_unsupported");
72
105
  expect(err.message).toMatch(pattern);
73
106
  expect(err.message).toContain("capabilities");
74
- // 错误信息可操作(§3.4):恢复指引指向换参数/换引擎
75
- expect(err.recovery).toMatch(/engine: pi|不传|去掉/);
107
+ // 错误信息可操作(§3.4 + W3 协议化口径):恢复指引 = 调整参数 / 修 manifest /
108
+ // 升级引擎包(能力声明的载体),不再指向「engine: pi」内置兜底
109
+ expect(err.recovery).toMatch(/去掉|不传/);
110
+ expect(err.recovery).toMatch(/修 manifest|升级引擎包/);
76
111
  }
77
112
  });
78
113
 
@@ -89,3 +124,68 @@ describe("capability-gate(D3-④ 拦截矩阵)", () => {
89
124
  expect(() => gate({ ...ZCODE_CAPS, steer: "native" }, { fork: true })).not.toThrow();
90
125
  });
91
126
  });
127
+
128
+ // ============================================================
129
+ // [W3] 方向判定②:manifest 多声明 → engine_capability_mismatch(impl-plan §2.3)
130
+ // ============================================================
131
+
132
+ describe("assertGateCapabilitiesMatched(manifest vs initialize 应答,gate 位方向判定)", () => {
133
+ function mismatchError(
134
+ manifestCaps: EngineCapabilities,
135
+ answeredCaps: EngineCapabilities,
136
+ ): EngineError {
137
+ try {
138
+ assertGateCapabilitiesMatched("fake", manifestCaps, answeredCaps);
139
+ } catch (err) {
140
+ expect(err).toBeInstanceOf(EngineError);
141
+ return err as EngineError;
142
+ }
143
+ throw new Error("expected assertGateCapabilitiesMatched to throw");
144
+ }
145
+
146
+ it("conversation:manifest 非 unsupported、应答 unsupported → engine_capability_mismatch", () => {
147
+ const err = mismatchError(
148
+ { ...ZCODE_CAPS, conversation: "native" },
149
+ { ...ZCODE_CAPS, conversation: "unsupported" },
150
+ );
151
+ expect(err.code).toBe("engine_capability_mismatch");
152
+ expect(err.message).toContain("conversation");
153
+ expect(err.recovery).toMatch(/manifest|升级引擎包/);
154
+ });
155
+
156
+ it("fork 通道族(OR 对偶):manifest 任一可用、应答双 unsupported → mismatch", () => {
157
+ const err = mismatchError(
158
+ { ...ZCODE_CAPS, steer: "native" },
159
+ { ...ZCODE_CAPS, steer: "unsupported", conversation: "unsupported" },
160
+ );
161
+ expect(err.code).toBe("engine_capability_mismatch");
162
+ expect(err.message).toContain("fork");
163
+ });
164
+
165
+ it("maxTurns:manifest true、应答 false → mismatch", () => {
166
+ const err = mismatchError({ ...ZCODE_CAPS, maxTurns: true }, { ...ZCODE_CAPS, maxTurns: false });
167
+ expect(err.code).toBe("engine_capability_mismatch");
168
+ expect(err.message).toContain("maxTurns");
169
+ });
170
+
171
+ it("sandbox:manifest 非 none、应答 none → mismatch", () => {
172
+ const err = mismatchError({ ...ZCODE_CAPS, sandbox: "emulated" }, { ...ZCODE_CAPS, sandbox: "none" });
173
+ expect(err.code).toBe("engine_capability_mismatch");
174
+ expect(err.message).toContain("sandbox");
175
+ });
176
+
177
+ it("应答强于 manifest(引擎兑现更多)→ 不抛;同值对齐 → 不抛(无多声明)", () => {
178
+ const weak = { ...ZCODE_CAPS, conversation: "unsupported" as const, maxTurns: false, sandbox: "none" as const };
179
+ const strong = { ...ZCODE_CAPS, conversation: "native" as const, maxTurns: true, sandbox: "emulated" as const };
180
+ // 应答强于 manifest:引擎兑现 manifest 全部声明,无多声明
181
+ expect(() => assertGateCapabilitiesMatched("fake", weak, strong)).not.toThrow();
182
+ // 同值对齐:无差异
183
+ expect(() => assertGateCapabilitiesMatched("fake", strong, strong)).not.toThrow();
184
+ });
185
+
186
+ it("非 gate 位不一致 → 不判定不抛(无论强弱一律 warn 留痕,归 EngineClient 诊断面)", () => {
187
+ const manifest = { ...ZCODE_CAPS, personaInjection: "file" as const, eventGranularity: "stream" as const, sessionRead: "full" as const, resume: "native" as const, interrupt: "native" as const, permissionMode: "native" as const, schemaEnforcement: "native" as const };
188
+ const weaker = { ...ZCODE_CAPS, personaInjection: "prompt" as const, eventGranularity: "coarse" as const, sessionRead: "outcome-only" as const, resume: "unsupported" as const, interrupt: "kill-only" as const, permissionMode: "fixed" as const, schemaEnforcement: "emulated" as const };
189
+ expect(() => assertGateCapabilitiesMatched("fake", manifest, weaker)).not.toThrow();
190
+ });
191
+ });
@@ -1,7 +1,9 @@
1
1
  // errors.test.ts —— 引擎层错误 SSOT 的结构锁定。
2
2
  //
3
- // 三视角:①构建者——11 条 code 与设计 §3.3.3 全表一致;②使用者——错误消息
4
- // code 前缀格式可被字符串匹配分流;③观察者——每条错误必有非空恢复指引(可操作)。
3
+ // 三视角:①构建者——12 条 code 与设计错误规格全表一致([W3] 协议化增
4
+ // engine_capability_mismatch——manifest 多声明的 run 期握手阻断面,与 SDK 协议错误码
5
+ // 词表同源);②使用者——错误消息 code 前缀格式可被字符串匹配分流;③观察者——每条
6
+ // 错误必有非空恢复指引(可操作)。
5
7
 
6
8
  import { describe, expect, it } from "vitest";
7
9
 
@@ -12,14 +14,12 @@ import {
12
14
  engineRunFailedDetail,
13
15
  engineTimeoutDetail,
14
16
  isEngineErrorCode,
15
- nestedSpawnRejectedError,
16
17
  promptTooLargeError,
17
- schemaEmulationFailedDetail,
18
18
  STDOUT_TAIL_ECHO_CHARS,
19
19
  } from "../../common/errors.ts";
20
20
 
21
21
  describe("ENGINE_ERROR_CODES(§3.3.3 全表)", () => {
22
- it("11 条错误码与设计文档错误规格表逐条一致", () => {
22
+ it("12 条错误码与设计文档错误规格表逐条一致([W3] 协议化增 engine_capability_mismatch)", () => {
23
23
  expect([...ENGINE_ERROR_CODES]).toEqual([
24
24
  "engine_not_found",
25
25
  "engine_probe_failed",
@@ -28,6 +28,7 @@ describe("ENGINE_ERROR_CODES(§3.3.3 全表)", () => {
28
28
  "schema_emulation_failed",
29
29
  "engine_timeout",
30
30
  "engine_capability_unsupported",
31
+ "engine_capability_mismatch",
31
32
  "engine_session_not_resumable",
32
33
  "model_not_available",
33
34
  "prompt_too_large",
@@ -90,13 +91,6 @@ describe("具名构造器", () => {
90
91
  expect(err.recovery).toMatch(/stdin/);
91
92
  });
92
93
 
93
- it("nestedSpawnRejectedError:说明防护规则 + 指向 task 内自行完成", () => {
94
- const err = nestedSpawnRejectedError();
95
- expect(err.code).toBe("nested_spawn_rejected");
96
- expect(err.message).toContain("XYZ_AGENT_SUBAGENT");
97
- expect(err.recovery).toMatch(/inside the current task/);
98
- });
99
-
100
94
  it("engineTimeoutDetail:含 stdout 尾部 + engine: pi 重跑建议", () => {
101
95
  const detail = engineTimeoutDetail("partial stdout output");
102
96
  expect(detail).toContain("partial stdout output");
@@ -123,10 +117,9 @@ describe("具名构造器", () => {
123
117
  expect(engineRunFailedDetail("crash", null, "t")).toContain("killed by signal");
124
118
  });
125
119
 
126
- it("schemaEmulationFailedDetail:含错误明细 + 原始输出尾部 + 重试一次语义", () => {
127
- const detail = schemaEmulationFailedDetail("Schema validation failed: /a must be number", '{"a":"x"}');
128
- expect(detail).toContain("Schema validation failed");
129
- expect(detail).toContain('{"a":"x"}');
130
- expect(detail).toMatch(/retry once/i);
131
- });
120
+ // nestedSpawnRejectedError 用例已随构造器删除(nesting-guard 收编 SDK 后死导出,
121
+ // 活体单源 SDK nesting-guard.ts NestedSpawnRejectedError,其行为由 SDK
122
+ // __tests__/primitives.test.ts + 本目录 nesting-guard.test.ts 覆盖)。
123
+ // schemaEmulationFailedDetail 用例已随函数删除(test-only 死镜像收口,活体单源
124
+ // SDK error-codes.ts,其行为由 SDK __tests__/primitives.test.ts 覆盖)。
132
125
  });
@@ -25,7 +25,7 @@ function tmpPath(name: string): string {
25
25
 
26
26
  afterEach(() => {
27
27
  if (tmpRoot !== undefined) {
28
- rmSync(tmpRoot, { recursive: true, force: true });
28
+ rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
29
29
  tmpRoot = undefined;
30
30
  }
31
31
  });
@@ -1,5 +1,11 @@
1
1
  // kill-chain.test.ts —— 杀链两分支 + 超时终态合成 + abort 两级编排(fake timers)。
2
2
  //
3
+ // 实现体已收编 @zhushanwen/subagent-engine-sdk(common/kill-chain.ts 为 re-export
4
+ // shim,s4-reuse 簇 1):SDK 侧 __tests__/kill-chain.test.ts 是超集演进版(+
5
+ // LoggerSink 捕获 + kill 抛错幂等用例),本文件保留 core 侧独有断言——engine: pi
6
+ // 重跑建议文案、stdout 尾部 2000 字截断、signalCode 形态退出、grace 贴边不升级。
7
+ // SDK 版 synthesizeTimeoutOutcome 的 engineId 必填(core 原缺省 "pi" 已删),用例显式传。
8
+ //
3
9
  // 三视角:①构建者——SIGTERM 优雅 / 超时 SIGKILL 两分支的信号序列正确;②使用者——
4
10
  // abortWithFallback 对 CLI-only 与 native-interrupt 引擎都收敛不悬挂;③观察者——
5
11
  // 合成终态的 error 含 stdout 尾部与 exitCode=null(被信号杀死判据)。
@@ -120,6 +126,7 @@ describe("synthesizeTimeoutOutcome", () => {
120
126
  const outcome = synthesizeTimeoutOutcome(
121
127
  { prompt: "review files", description: "review-files" },
122
128
  "last stdout lines...",
129
+ "pi",
123
130
  );
124
131
  expect(outcome.error!).toContain("engine_timeout");
125
132
  expect(outcome.error).toContain("review-files");
@@ -1,5 +1,11 @@
1
1
  // nesting-guard.test.ts —— 嵌套标记注入与原生标记剥离(D8 双层防护)。
2
2
  //
3
+ // 实现体已收编 @zhushanwen/subagent-engine-sdk(common/nesting-guard.ts 为
4
+ // re-export shim,s4-reuse 簇 2):SDK 侧 __tests__/primitives.test.ts 已有同语义
5
+ // 断言,本文件保留 core 侧独有细粒度断言——精确名 vs 前缀剥离边界(CLAUDE_UNRELATED)、
6
+ // 非 '1' 值不抛、空白 env 最小产出。错误形态随收编改 NestedSpawnRejectedError
7
+ //(code/recovery 文案与 core 词表逐字一致)。
8
+ //
3
9
  // 三视角:①构建者——三引擎原生标记(PI_SUBAGENT_* / CLAUDECODE / ZSW_NESTED)全部
4
10
  // 剥离且其余 env 保留;②使用者——子代理进程内 assertNotNestedSpawn 同步拒绝且文案
5
11
  // 可操作;③观察者——产出的 env 是新对象(不污染入参)。
@@ -9,9 +15,9 @@ import { describe, expect, it } from "vitest";
9
15
  import {
10
16
  assertNotNestedSpawn,
11
17
  buildNestedSpawnEnv,
18
+ NestedSpawnRejectedError,
12
19
  NESTED_SPAWN_ENV,
13
20
  } from "../../common/nesting-guard.ts";
14
- import { EngineError } from "../../common/errors.ts";
15
21
 
16
22
  describe("buildNestedSpawnEnv", () => {
17
23
  it("注入统一标记 XYZ_AGENT_SUBAGENT=1", () => {
@@ -60,12 +66,12 @@ describe("buildNestedSpawnEnv", () => {
60
66
 
61
67
  describe("assertNotNestedSpawn", () => {
62
68
  it("检测到统一标记(本进程已是 subagent)→ 抛 nested_spawn_rejected", () => {
63
- expect(() => assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" })).toThrowError(EngineError);
69
+ expect(() => assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" })).toThrowError(NestedSpawnRejectedError);
64
70
  try {
65
71
  assertNotNestedSpawn({ [NESTED_SPAWN_ENV]: "1" });
66
72
  expect.unreachable("should throw");
67
73
  } catch (err) {
68
- const e = err as EngineError;
74
+ const e = err as NestedSpawnRejectedError;
69
75
  expect(e.code).toBe("nested_spawn_rejected");
70
76
  // 文案说明防护规则(标记名)+ 指向 task 内自行完成
71
77
  expect(e.message).toContain("XYZ_AGENT_SUBAGENT");
@@ -29,7 +29,7 @@ beforeEach(() => {
29
29
  });
30
30
 
31
31
  afterEach(() => {
32
- rmSync(tmpRoot, { recursive: true, force: true });
32
+ rmSync(tmpRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
33
33
  });
34
34
 
35
35
  /** 读池 refs.json 的解析形态。 */
@@ -142,7 +142,7 @@ describe("releasePoolRef 引用计数与整池删除", () => {
142
142
  it("池目录不存在时 release → 无原生状态可清,视为成功不抛", () => {
143
143
  acquirePool(tmpRoot, "zcode", "ghost", "bg-1");
144
144
  // 归零但目录已被外部删除
145
- rmSync(resolvePoolDir(tmpRoot, "zcode", "ghost"), { recursive: true, force: true });
145
+ rmSync(resolvePoolDir(tmpRoot, "zcode", "ghost"), { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
146
146
  expect(() => releasePoolRef(tmpRoot, "zcode", "ghost", "bg-1")).not.toThrow();
147
147
  });
148
148
 
@@ -34,7 +34,7 @@ beforeEach(() => {
34
34
  });
35
35
 
36
36
  afterEach(() => {
37
- rmSync(dataDir, { recursive: true, force: true });
37
+ rmSync(dataDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
38
38
  // reader registry 是进程级状态——重置回内置集,防 fake 注入跨用例泄漏
39
39
  resetNativeSessionReaders();
40
40
  });
@@ -163,7 +163,13 @@ describe("降级链编排", () => {
163
163
  });
164
164
  });
165
165
 
166
- it("①级 db 不存在(真 zcode reader throw)→ ②级 journal 命中", async () => {
166
+ it("[W11/H1] ①级 reader 不可达(协议 read 失败降级形态)→ ②级 journal 命中", async () => {
167
+ // W11 后①级 reader 全经注入(生产 = runtime 协议 read,失败在其内部 catch 后
168
+ // 返回 undefined):注入一个恒 undefined 的 reader 复现「协议失败降②级」语义
169
+ // (原「真 zcode reader 对不存在 db 内部 catch 降级」分支随 H1 内建 reader
170
+ // 删除,sqlite 侧行为由 zcode 包 e2e 接替;NativeSessionReader 契约 = 不抛,
171
+ // 失败以 undefined 表达)。
172
+ registerNativeSessionReader("zcode", async () => undefined);
167
173
  const journalPath = join(dataDir, "engines", "zcode", "shared", "journal-sub-1.jsonl");
168
174
  await writeJournal(journalPath, [
169
175
  { type: "text_delta", delta: "part one. " },
@@ -190,7 +196,7 @@ describe("降级链编排", () => {
190
196
  });
191
197
 
192
198
  it("②级也不可达(无 journalPath)→ ③级 outcome-only,永不返回空数组", async () => {
193
- // zcode reader:dbPath 指向不存在文件 → ①级 throw 降级;handle 无 journalPath → ③级
199
+ // ①级无注册 reader(W11 后注册表初始为空)→ 直落②级;handle 无 journalPath → ③级
194
200
  const messages = await readSubagentHistoryMessages(
195
201
  makeRecord({ result: "final answer", endedAt: 2_000 }),
196
202
  dataDir,
@@ -228,6 +234,87 @@ describe("降级链编排", () => {
228
234
  expect(messages).toHaveLength(2);
229
235
  expect(messages[1]).toMatchObject({ content: "r" });
230
236
  });
237
+
238
+ // ============================================================
239
+ // ①级判空降级矩阵(设计 D3:turns 无实质内容 = 本级不可用,与②级同语义)
240
+ // ============================================================
241
+
242
+ it("①级 defined 空 turns({turns:[], source:'native'})→ 降②级,journal 内容命中(不返回 [task] 空壳)", async () => {
243
+ const journalPath = join(dataDir, "engines", "zcode", "shared", "journal-sub-1.jsonl");
244
+ await writeJournal(journalPath, [
245
+ { type: "text_delta", delta: "journal answer" },
246
+ { type: "turn_end" },
247
+ ]);
248
+ registerNativeSessionReader("zcode", async () => ({
249
+ engineId: "zcode",
250
+ sessionId: "sess-1",
251
+ turns: [],
252
+ source: "native",
253
+ }));
254
+ const record = makeRecord({
255
+ engineHandle: {
256
+ sessionRef: { sessionId: "sess-1", dbPath: ".zcode/cli/db/db.sqlite" },
257
+ poolKey: "shared",
258
+ journalPath,
259
+ },
260
+ });
261
+ const messages = await readSubagentHistoryMessages(record, dataDir);
262
+ expect(messages).toHaveLength(2);
263
+ expect(messages[0]).toMatchObject({ role: "user", content: "do the thing" });
264
+ expect(messages[1]).toMatchObject({ role: "assistant", content: "journal answer" });
265
+ });
266
+
267
+ it("①级非空数组但全空 turn(截断/被杀残留形态)→ 同样降级:无 journalPath 落③级 outcome-only", async () => {
268
+ registerNativeSessionReader("zcode", async () => ({
269
+ engineId: "zcode",
270
+ sessionId: "sess-1",
271
+ // closeTurn 对 step-finish 无条件 push + applyPartToTurn 空 acc 创建——形态代码级可达
272
+ turns: [{ text: "", thinking: "", toolCalls: [], closed: true }],
273
+ source: "native",
274
+ }));
275
+ const messages = await readSubagentHistoryMessages(
276
+ makeRecord({ result: "outcome text" }),
277
+ dataDir,
278
+ );
279
+ // 不是「仅 task」空壳:①级空 turn 被判不可用 → ③级占位投影
280
+ expect(messages).toHaveLength(2);
281
+ expect(messages[1]).toMatchObject({ role: "assistant", content: "outcome text" });
282
+ });
283
+
284
+ it("①级混合 turn(含空 turn 但任一有实质内容)→ 不降级,真实内容原样投影", async () => {
285
+ registerNativeSessionReader("zcode", async () => ({
286
+ engineId: "zcode",
287
+ sessionId: "sess-1",
288
+ turns: [
289
+ { text: "", thinking: "", toolCalls: [], closed: true },
290
+ { text: "real answer", thinking: "", toolCalls: [], closed: true },
291
+ ],
292
+ source: "native",
293
+ }));
294
+ const messages = await readSubagentHistoryMessages(makeRecord(), dataDir);
295
+ // task + 两个 turn(空 turn 也随①级放行原样投影)
296
+ expect(messages).toHaveLength(3);
297
+ expect(messages[2]).toMatchObject({ role: "assistant", content: "real answer" });
298
+ });
299
+
300
+ it("①空(defined 空 turns)②亦不可达(无 journalPath)→ 落③级 outcome-only 占位", async () => {
301
+ registerNativeSessionReader("zcode", async () => ({
302
+ engineId: "zcode",
303
+ sessionId: "sess-1",
304
+ turns: [],
305
+ source: "native",
306
+ }));
307
+ const messages = await readSubagentHistoryMessages(
308
+ makeRecord({ result: undefined, error: undefined }),
309
+ dataDir,
310
+ );
311
+ expect(messages).toHaveLength(2);
312
+ expect(messages[1]).toMatchObject({
313
+ role: "assistant",
314
+ content: "(no outcome recorded)",
315
+ status: "complete",
316
+ });
317
+ });
231
318
  });
232
319
 
233
320
  // ============================================================