@deksden-com/dd-flow-cli 0.9.0-beta.16 → 0.9.0-beta.160

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 (670) hide show
  1. package/CHANGELOG.md +959 -0
  2. package/README.md +139 -10
  3. package/dist/build-info.json +8 -8
  4. package/dist/cli/argument-values.js +38 -0
  5. package/dist/cli/command-inputs.js +417 -0
  6. package/dist/cli/command-metadata.js +303 -0
  7. package/dist/cli/command-option-descriptions.js +192 -0
  8. package/dist/cli/completion-cli.js +70 -0
  9. package/dist/cli/completion.js +57 -0
  10. package/dist/cli/delivery.js +108 -0
  11. package/dist/cli/diagnostic-invocation.js +62 -0
  12. package/dist/cli/diagnostic.js +131 -0
  13. package/dist/cli/error-output.js +62 -0
  14. package/dist/cli/executor-onboarding.js +76 -0
  15. package/dist/cli/flows.js +29 -0
  16. package/dist/cli/harnesses.js +84 -0
  17. package/dist/cli/help.js +521 -19
  18. package/dist/cli/hook-ingress.js +89 -0
  19. package/dist/cli/input-preparation.js +193 -0
  20. package/dist/cli/interactive-invocation.js +33 -0
  21. package/dist/cli/interactive.js +114 -0
  22. package/dist/cli/memory-fix-invocation.js +52 -0
  23. package/dist/cli/memory-fix.js +100 -0
  24. package/dist/cli/memory-flow-admission.js +54 -0
  25. package/dist/cli/memory-init-invocation.js +85 -0
  26. package/dist/cli/memory-init.js +250 -0
  27. package/dist/cli/memory-storage-admission.js +54 -0
  28. package/dist/cli/memory-storage-qualification.js +105 -0
  29. package/dist/cli/memory-storage-transition.js +123 -0
  30. package/dist/cli/memory-upgrade.js +189 -0
  31. package/dist/cli/models.js +39 -0
  32. package/dist/cli/native-hook-ingress.js +94 -0
  33. package/dist/cli/native-hook-preparation.js +82 -0
  34. package/dist/cli/operator-profiles.js +61 -0
  35. package/dist/cli/output-options.js +35 -0
  36. package/dist/cli/response-file.js +72 -0
  37. package/dist/cli/run-cli.js +2020 -555
  38. package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
  39. package/dist/cli/runtime-maintenance-ingress.js +52 -0
  40. package/dist/cli/runtime-process.js +153 -0
  41. package/dist/cli/setup.js +150 -0
  42. package/dist/cli.js +103 -2
  43. package/dist/domain/delivery-flows.js +8 -0
  44. package/dist/domain/diagnostic-aspects.js +103 -0
  45. package/dist/domain/diagnostic-flows.js +8 -0
  46. package/dist/domain/distill-flow.js +20 -0
  47. package/dist/domain/interactive-flow.js +1 -0
  48. package/dist/domain/memory-fix-flow.js +2 -0
  49. package/dist/domain/review-fix-flow.js +2 -0
  50. package/dist/domain/source-snapshot-flows.js +4 -0
  51. package/dist/domain/stage-catalog.js +1 -1
  52. package/dist/domain/stage-handler-identities.js +28 -0
  53. package/dist/harness-runtime/DD-ZCODE.md +112 -0
  54. package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
  55. package/dist/harness-runtime/bin/dd-agy.mjs +71 -0
  56. package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
  57. package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
  58. package/dist/harness-runtime/bin/dd-grok.mjs +50 -0
  59. package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
  60. package/dist/harness-runtime/bin/dd-zcode.mjs +95 -0
  61. package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
  62. package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
  63. package/dist/harness-runtime/lib/agy-error-boundary.mjs +87 -0
  64. package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
  65. package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
  66. package/dist/harness-runtime/lib/agy-native-inspection.mjs +225 -0
  67. package/dist/harness-runtime/lib/agy-native-inventory.mjs +19 -0
  68. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  69. package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +74 -0
  70. package/dist/harness-runtime/lib/agy-transcript-stream.mjs +54 -0
  71. package/dist/harness-runtime/lib/daemon-observation.d.mts +3 -0
  72. package/dist/harness-runtime/lib/daemon-observation.mjs +171 -0
  73. package/dist/harness-runtime/lib/daemon-operations.d.mts +2 -0
  74. package/dist/harness-runtime/lib/daemon-operations.mjs +512 -0
  75. package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +7 -0
  76. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1362 -0
  77. package/dist/harness-runtime/lib/dd-agy.mjs +105 -0
  78. package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
  79. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +271 -0
  80. package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
  81. package/dist/harness-runtime/lib/dd-codex.mjs +986 -0
  82. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +155 -0
  83. package/dist/harness-runtime/lib/dd-droid.mjs +739 -0
  84. package/dist/harness-runtime/lib/dd-grok-daemon.d.mts +1 -0
  85. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +667 -0
  86. package/dist/harness-runtime/lib/dd-grok.mjs +182 -0
  87. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +772 -0
  88. package/dist/harness-runtime/lib/dd-opencode.mjs +411 -0
  89. package/dist/harness-runtime/lib/dd-zcode-daemon.d.mts +1 -0
  90. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +845 -0
  91. package/dist/harness-runtime/lib/dd-zcode.mjs +1239 -0
  92. package/dist/harness-runtime/lib/delegation-instructions.d.mts +16 -0
  93. package/dist/harness-runtime/lib/delegation-instructions.mjs +179 -0
  94. package/dist/harness-runtime/lib/delivery-command.mjs +84 -0
  95. package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
  96. package/dist/harness-runtime/lib/driver-recovery.mjs +121 -0
  97. package/dist/harness-runtime/lib/droid-observation.mjs +70 -0
  98. package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
  99. package/dist/harness-runtime/lib/entity-references.mjs +9 -0
  100. package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
  101. package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
  102. package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
  103. package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
  104. package/dist/harness-runtime/lib/lifecycle-contract.d.mts +11 -0
  105. package/dist/harness-runtime/lib/lifecycle-contract.mjs +20 -0
  106. package/dist/harness-runtime/lib/managed-daemon.d.mts +16 -0
  107. package/dist/harness-runtime/lib/managed-daemon.mjs +698 -0
  108. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  109. package/dist/harness-runtime/lib/model-observations.mjs +113 -0
  110. package/dist/harness-runtime/lib/native-children.d.mts +34 -0
  111. package/dist/harness-runtime/lib/native-children.mjs +265 -0
  112. package/dist/harness-runtime/lib/native-hook-command.d.mts +8 -0
  113. package/dist/harness-runtime/lib/native-hook-command.mjs +306 -0
  114. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  115. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  116. package/dist/harness-runtime/lib/native-streams.mjs +38 -0
  117. package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
  118. package/dist/harness-runtime/lib/observation-clock.mjs +95 -0
  119. package/dist/harness-runtime/lib/opencode-plugin.mjs +112 -0
  120. package/dist/harness-runtime/lib/operation-context.mjs +5 -0
  121. package/dist/harness-runtime/lib/operation-errors.d.mts +16 -0
  122. package/dist/harness-runtime/lib/operation-errors.mjs +140 -0
  123. package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
  124. package/dist/harness-runtime/lib/operation-progress.mjs +118 -0
  125. package/dist/harness-runtime/lib/process-json.d.mts +5 -0
  126. package/dist/harness-runtime/lib/process-json.mjs +200 -0
  127. package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
  128. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +23 -0
  129. package/dist/harness-runtime/lib/provider-overload-policy.mjs +242 -0
  130. package/dist/harness-runtime/lib/runner-events.mjs +202 -0
  131. package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
  132. package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
  133. package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
  134. package/dist/harness-runtime/lib/setup-progress.mjs +53 -0
  135. package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
  136. package/dist/harness-runtime/lib/tool-observations.mjs +238 -0
  137. package/dist/harness-runtime/lib/zcode-native-hook-ownership.mjs +109 -0
  138. package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
  139. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
  140. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
  141. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
  142. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
  143. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
  144. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
  145. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
  146. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
  147. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
  148. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
  149. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
  150. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
  151. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
  152. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
  153. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
  154. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
  155. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
  156. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
  157. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
  158. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
  159. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
  160. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
  161. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
  162. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
  163. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
  164. package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
  165. package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
  166. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
  167. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
  168. package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
  169. package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
  170. package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
  171. package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
  172. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
  173. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
  174. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
  175. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
  176. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
  177. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
  178. package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
  179. package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
  180. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
  181. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
  182. package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
  183. package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
  184. package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
  185. package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
  186. package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
  187. package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
  188. package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
  189. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
  190. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
  191. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
  192. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
  193. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
  194. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
  195. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
  196. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
  197. package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
  198. package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
  199. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
  200. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
  201. package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
  202. package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
  203. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
  204. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
  205. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
  206. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
  207. package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
  208. package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
  209. package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
  210. package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
  211. package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
  212. package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
  213. package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
  214. package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
  215. package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
  216. package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
  217. package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
  218. package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
  219. package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
  220. package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
  221. package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
  222. package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
  223. package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
  224. package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
  225. package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
  226. package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
  227. package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
  228. package/dist/protocol/local-files.js +18 -9
  229. package/dist/runtime/context.js +8 -4
  230. package/dist/schemas/agent-profile.schema.json +1 -1
  231. package/dist/schemas/code-review-decision.schema.json +9 -0
  232. package/dist/schemas/code-review-result.schema.json +1 -1
  233. package/dist/schemas/code-verification.schema.json +7 -5
  234. package/dist/schemas/code-work-batch.schema.json +2 -2
  235. package/dist/schemas/code-work-result.schema.json +2 -1
  236. package/dist/schemas/delivery-stage-result.schema.json +286 -0
  237. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  238. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  239. package/dist/schemas/discovery-result.schema.json +184 -0
  240. package/dist/schemas/distill-stage-result.schema.json +667 -0
  241. package/dist/schemas/distill-work-result.schema.json +428 -0
  242. package/dist/schemas/execution-bundle.schema.json +215 -0
  243. package/dist/schemas/execution-settings.schema.json +162 -0
  244. package/dist/schemas/flow-descriptor.schema.json +54 -0
  245. package/dist/schemas/flow-run.schema.json +29 -0
  246. package/dist/schemas/harness-catalog.schema.json +80 -0
  247. package/dist/schemas/interactive-stage-result.schema.json +47 -0
  248. package/dist/schemas/interactive-work-result.schema.json +63 -0
  249. package/dist/schemas/mb-fix-stage-result.schema.json +93 -0
  250. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  251. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  252. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  253. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  254. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  255. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  256. package/dist/schemas/mb-upgrade-stage-result.schema.json +863 -0
  257. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  258. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  259. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  260. package/dist/schemas/memory-repair-work-result.schema.json +56 -0
  261. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  262. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  263. package/dist/schemas/model-catalog.schema.json +153 -0
  264. package/dist/schemas/plan-review-decision.schema.json +12 -3
  265. package/dist/schemas/plan-review-result.schema.json +2 -2
  266. package/dist/schemas/profile-settings.schema.json +122 -0
  267. package/dist/schemas/project-flow-pack-manifest.schema.json +2 -2
  268. package/dist/schemas/release-impact.schema.json +3 -3
  269. package/dist/schemas/release-manifest.schema.json +291 -0
  270. package/dist/schemas/review-fix-stage-result.schema.json +210 -0
  271. package/dist/schemas/run-control-receipt.schema.json +119 -0
  272. package/dist/schemas/run-control-request.schema.json +36 -0
  273. package/dist/schemas/run-engine-binding.schema.json +1 -1
  274. package/dist/schemas/stage-start-response.schema.json +4 -0
  275. package/dist/schemas/vnext-protocol-plan.schema.json +3 -3
  276. package/dist/services/accepted-intent.js +139 -0
  277. package/dist/services/assigned-lifecycle.js +382 -0
  278. package/dist/services/branch-context.js +3 -3
  279. package/dist/services/canon.js +54 -15
  280. package/dist/services/check-environment.js +21 -0
  281. package/dist/services/check-runner-evidence.js +344 -0
  282. package/dist/services/check-runner-proof.js +373 -0
  283. package/dist/services/cleanup.js +133 -40
  284. package/dist/services/cli-operation-classifier.js +32 -64
  285. package/dist/services/cli-upgrade-allowlist.js +27 -0
  286. package/dist/services/code-checks.js +1426 -121
  287. package/dist/services/codex-capacity.js +367 -0
  288. package/dist/services/codex-hook-delivery.js +41 -0
  289. package/dist/services/command-context.js +80 -0
  290. package/dist/services/compatibility-preflight.js +16 -3
  291. package/dist/services/config.js +11 -8
  292. package/dist/services/continuation-outcome.js +25 -0
  293. package/dist/services/controller-child-capacity.js +71 -0
  294. package/dist/services/controller-child-observer.js +121 -0
  295. package/dist/services/controller-child-repair.js +117 -0
  296. package/dist/services/controller-execution.js +97 -0
  297. package/dist/services/controller-fanout.js +277 -0
  298. package/dist/services/controller-memory-task.js +45 -0
  299. package/dist/services/controller-memory-worker.js +51 -0
  300. package/dist/services/controller-result-authority.js +127 -0
  301. package/dist/services/controller-work-failure.js +198 -0
  302. package/dist/services/dashboard.js +145 -58
  303. package/dist/services/delivery-access.js +123 -0
  304. package/dist/services/delivery-approval.js +68 -0
  305. package/dist/services/delivery-artifact.js +86 -0
  306. package/dist/services/delivery-checks.js +178 -0
  307. package/dist/services/delivery-execution.js +181 -0
  308. package/dist/services/delivery-intents.js +212 -0
  309. package/dist/services/delivery-operation.js +81 -0
  310. package/dist/services/delivery-policy.js +91 -0
  311. package/dist/services/delivery-procedures.js +43 -0
  312. package/dist/services/delivery-request.js +99 -0
  313. package/dist/services/delivery-result.js +144 -0
  314. package/dist/services/delivery-stage-commands.js +26 -0
  315. package/dist/services/delivery-stage-entry.js +56 -0
  316. package/dist/services/delivery-stage-handlers.js +135 -0
  317. package/dist/services/delivery-stage-results.js +94 -0
  318. package/dist/services/descriptor-coordinator-session.js +37 -0
  319. package/dist/services/descriptor-root-work.js +53 -0
  320. package/dist/services/descriptor-run-settlement.js +107 -0
  321. package/dist/services/descriptor-run-start.js +495 -0
  322. package/dist/services/descriptor-stage-coordinator.js +318 -0
  323. package/dist/services/descriptor-stage-settlement.js +268 -0
  324. package/dist/services/descriptor-stage-start.js +175 -0
  325. package/dist/services/diagnostic-evidence.js +73 -0
  326. package/dist/services/diagnostic-repair-intake.js +123 -0
  327. package/dist/services/diagnostic-repair-source-intake.js +102 -0
  328. package/dist/services/diagnostic-report-publication.js +72 -0
  329. package/dist/services/diagnostic-report.js +97 -0
  330. package/dist/services/diagnostic-run-bundle.js +113 -0
  331. package/dist/services/diagnostic-snapshot.js +159 -0
  332. package/dist/services/diagnostic-stage-handlers.js +109 -0
  333. package/dist/services/diagnostic-stage-results.js +158 -0
  334. package/dist/services/diagnostic-start.js +134 -0
  335. package/dist/services/diagnostic-work-batch.js +34 -0
  336. package/dist/services/diagnostic-work-collection.js +97 -0
  337. package/dist/services/diagnostic-work-registration.js +101 -0
  338. package/dist/services/diagnostic-work-results.js +93 -0
  339. package/dist/services/discovery/agy-discovery.js +2 -0
  340. package/dist/services/discovery/codex-discovery.js +2 -0
  341. package/dist/services/discovery/droid-discovery.js +2 -0
  342. package/dist/services/discovery/grok-discovery.js +2 -0
  343. package/dist/services/discovery/opencode-discovery.js +2 -0
  344. package/dist/services/discovery/static.js +31 -0
  345. package/dist/services/discovery/zcode-discovery.js +2 -0
  346. package/dist/services/distill-document-publication.js +280 -0
  347. package/dist/services/distill-promotion.js +197 -0
  348. package/dist/services/distill-publication-custody.js +162 -0
  349. package/dist/services/distill-stage-handlers.js +249 -0
  350. package/dist/services/distill-stage-results.js +105 -0
  351. package/dist/services/distill-user-inputs.js +4 -0
  352. package/dist/services/distill-work-batch.js +42 -0
  353. package/dist/services/distill-work-collection.js +74 -0
  354. package/dist/services/distill-work-registration.js +93 -0
  355. package/dist/services/distill-work-results.js +98 -0
  356. package/dist/services/engines.js +354 -163
  357. package/dist/services/eval-snapshots.js +1326 -150
  358. package/dist/services/execution-bundles.js +275 -0
  359. package/dist/services/execution-policy.js +185 -0
  360. package/dist/services/executor-onboarding.js +56 -0
  361. package/dist/services/external-work-launch.js +316 -0
  362. package/dist/services/flow-catalog.js +54 -0
  363. package/dist/services/flow-descriptors.js +82 -0
  364. package/dist/services/frozen-engine.js +404 -0
  365. package/dist/services/generic-execution.js +165 -0
  366. package/dist/services/harness-adapter.js +342 -35
  367. package/dist/services/harness-config.js +2 -0
  368. package/dist/services/harness-discovery.js +29 -0
  369. package/dist/services/harness-doctor.js +75 -0
  370. package/dist/services/harness-probe-effects.js +51 -0
  371. package/dist/services/harness-version-probe.js +100 -0
  372. package/dist/services/hook-memory-routing.js +188 -0
  373. package/dist/services/hook-recovery-guard.js +14 -0
  374. package/dist/services/hook-session-observation.js +24 -0
  375. package/dist/services/hooks.js +813 -327
  376. package/dist/services/hybrid-contracts.js +479 -0
  377. package/dist/services/hybrid-digest.js +14 -0
  378. package/dist/services/ids.js +29 -1
  379. package/dist/services/installation-lock.js +95 -0
  380. package/dist/services/installed-flow-source.js +261 -0
  381. package/dist/services/interactive-attached-session.js +215 -0
  382. package/dist/services/interactive-baseline-custody.js +54 -0
  383. package/dist/services/interactive-before-versions.js +148 -0
  384. package/dist/services/interactive-bundle-data.js +85 -0
  385. package/dist/services/interactive-checks.js +179 -0
  386. package/dist/services/interactive-execution.js +33 -0
  387. package/dist/services/interactive-finish-integration.js +236 -0
  388. package/dist/services/interactive-git-baseline.js +230 -0
  389. package/dist/services/interactive-git-dispatch.js +278 -0
  390. package/dist/services/interactive-input-delivery.js +82 -0
  391. package/dist/services/interactive-mutation-scope.js +231 -0
  392. package/dist/services/interactive-request.js +287 -0
  393. package/dist/services/interactive-run-bundle.js +109 -0
  394. package/dist/services/interactive-stage-entry.js +41 -0
  395. package/dist/services/interactive-stage-handlers.js +289 -0
  396. package/dist/services/interactive-stage-observation.js +136 -0
  397. package/dist/services/interactive-stage-results.js +111 -0
  398. package/dist/services/interactive-user-inputs.js +142 -0
  399. package/dist/services/interactive-work-batch.js +43 -0
  400. package/dist/services/interactive-work-collection.js +119 -0
  401. package/dist/services/interactive-work-completion.js +180 -0
  402. package/dist/services/interactive-work-context.js +249 -0
  403. package/dist/services/interactive-work-history.js +112 -0
  404. package/dist/services/interactive-work-registration.js +124 -0
  405. package/dist/services/interactive-work-results.js +115 -0
  406. package/dist/services/interactive-work-start.js +155 -0
  407. package/dist/services/lanes.js +78 -65
  408. package/dist/services/lifecycle-command.js +1 -288
  409. package/dist/services/lifecycle-contract.js +1 -0
  410. package/dist/services/lifecycle-invocations.js +2549 -0
  411. package/dist/services/managed-daemon-binding.js +129 -0
  412. package/dist/services/managed-lease-monitor.js +133 -0
  413. package/dist/services/managed-processes.js +449 -69
  414. package/dist/services/memory-accepted-composition.js +78 -0
  415. package/dist/services/memory-baseline-preservation.js +65 -0
  416. package/dist/services/memory-completed-correction-wave.js +328 -0
  417. package/dist/services/memory-compose-handler.js +380 -0
  418. package/dist/services/memory-composition-acceptance.js +375 -0
  419. package/dist/services/memory-composition-graph.js +165 -0
  420. package/dist/services/memory-composition-registration.js +161 -0
  421. package/dist/services/memory-composition-work-custody.js +156 -0
  422. package/dist/services/memory-composition-work-results.js +108 -0
  423. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  424. package/dist/services/memory-corrected-review-batch.js +37 -0
  425. package/dist/services/memory-corrected-review-findings.js +108 -0
  426. package/dist/services/memory-corrected-review-inputs.js +215 -0
  427. package/dist/services/memory-corrected-review-projection.js +78 -0
  428. package/dist/services/memory-corrected-review-receipt.js +178 -0
  429. package/dist/services/memory-corrected-review-registration.js +192 -0
  430. package/dist/services/memory-correction-check-receipt.js +235 -0
  431. package/dist/services/memory-correction-input-owner.js +6 -0
  432. package/dist/services/memory-custody-snapshot.js +36 -0
  433. package/dist/services/memory-discover-handler.js +104 -0
  434. package/dist/services/memory-finish-evidence.js +457 -0
  435. package/dist/services/memory-finish-handler.js +229 -0
  436. package/dist/services/memory-finish-integration.js +491 -0
  437. package/dist/services/memory-finish-readiness.js +169 -0
  438. package/dist/services/memory-fix-finish-integration.js +129 -0
  439. package/dist/services/memory-fix-git-dispatch.js +139 -0
  440. package/dist/services/memory-fix-intake-custody.js +11 -0
  441. package/dist/services/memory-fix-intake-settlement.js +127 -0
  442. package/dist/services/memory-fix-publication.js +196 -0
  443. package/dist/services/memory-fix-repair-admission.js +116 -0
  444. package/dist/services/memory-fix-request.js +141 -0
  445. package/dist/services/memory-fix-run-bundle.js +83 -0
  446. package/dist/services/memory-fix-scope.js +78 -0
  447. package/dist/services/memory-fix-sources.js +85 -0
  448. package/dist/services/memory-fix-stage-entry.js +24 -0
  449. package/dist/services/memory-fix-stage-handlers.js +282 -0
  450. package/dist/services/memory-fix-stage-results.js +106 -0
  451. package/dist/services/memory-fix-workspace.js +127 -0
  452. package/dist/services/memory-flow-user-inputs.js +88 -0
  453. package/dist/services/memory-git-integration.js +220 -0
  454. package/dist/services/memory-historical-corrected-review.js +212 -0
  455. package/dist/services/memory-historical-original-review.js +143 -0
  456. package/dist/services/memory-historical-repair-registration.js +105 -0
  457. package/dist/services/memory-historical-second-review.js +147 -0
  458. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  459. package/dist/services/memory-init-contexts.js +181 -0
  460. package/dist/services/memory-init-controller-start.js +119 -0
  461. package/dist/services/memory-init-engine-release.js +223 -0
  462. package/dist/services/memory-init-git-policy.js +165 -0
  463. package/dist/services/memory-init-lint-capability.js +203 -0
  464. package/dist/services/memory-init-native-capacity.js +309 -0
  465. package/dist/services/memory-init-preflight.js +334 -0
  466. package/dist/services/memory-init-project-bootstrap.js +599 -0
  467. package/dist/services/memory-init-request-candidate.js +213 -0
  468. package/dist/services/memory-init-request-input.js +82 -0
  469. package/dist/services/memory-init-resource-storage.js +125 -0
  470. package/dist/services/memory-init-run-allocation.js +81 -0
  471. package/dist/services/memory-init-run-bundle.js +135 -0
  472. package/dist/services/memory-init-start.js +181 -0
  473. package/dist/services/memory-init-startup-custody.js +80 -0
  474. package/dist/services/memory-init-startup-input.js +240 -0
  475. package/dist/services/memory-init-storage.js +91 -0
  476. package/dist/services/memory-init-stores.js +359 -0
  477. package/dist/services/memory-init-worktrunk-capability.js +174 -0
  478. package/dist/services/memory-layer-publication.js +611 -0
  479. package/dist/services/memory-layer.js +225 -0
  480. package/dist/services/memory-lint-config.js +194 -0
  481. package/dist/services/memory-native-review-copy.js +127 -0
  482. package/dist/services/memory-normal-flow-entry.js +87 -0
  483. package/dist/services/memory-ordinary-defaults.js +129 -0
  484. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  485. package/dist/services/memory-preflight-handler.js +274 -0
  486. package/dist/services/memory-repair-current-view.js +299 -0
  487. package/dist/services/memory-repair-document-delta.js +489 -0
  488. package/dist/services/memory-repair-history.js +496 -0
  489. package/dist/services/memory-repair-physical-binding.js +194 -0
  490. package/dist/services/memory-repair-publication-files.js +152 -0
  491. package/dist/services/memory-repair-publication-intent.js +27 -0
  492. package/dist/services/memory-repair-publication-plan.js +162 -0
  493. package/dist/services/memory-repair-publication-source.js +225 -0
  494. package/dist/services/memory-repair-publication.js +795 -0
  495. package/dist/services/memory-repair-registration.js +240 -0
  496. package/dist/services/memory-repair-work-baseline.js +415 -0
  497. package/dist/services/memory-repair-work-completion.js +117 -0
  498. package/dist/services/memory-repair-work-custody.js +73 -0
  499. package/dist/services/memory-repair-work-results.js +108 -0
  500. package/dist/services/memory-repair-workspace.js +261 -0
  501. package/dist/services/memory-repair-writer-copy.js +736 -0
  502. package/dist/services/memory-result-binding.js +239 -0
  503. package/dist/services/memory-retained-review-authority.js +138 -0
  504. package/dist/services/memory-retained-review-results.js +70 -0
  505. package/dist/services/memory-retained-second-baseline.js +102 -0
  506. package/dist/services/memory-retained-second-repairs.js +162 -0
  507. package/dist/services/memory-review-acceptance.js +214 -0
  508. package/dist/services/memory-review-correction-plan.js +206 -0
  509. package/dist/services/memory-review-handler.js +585 -0
  510. package/dist/services/memory-review-inputs.js +246 -0
  511. package/dist/services/memory-review-limits.js +10 -0
  512. package/dist/services/memory-review-receipt.js +180 -0
  513. package/dist/services/memory-review-registration.js +117 -0
  514. package/dist/services/memory-review-work-custody.js +126 -0
  515. package/dist/services/memory-review-work-input.js +91 -0
  516. package/dist/services/memory-review-work-results.js +95 -0
  517. package/dist/services/memory-second-corrected-review-inputs.js +167 -0
  518. package/dist/services/memory-second-correction-plan.js +77 -0
  519. package/dist/services/memory-second-repair-baseline.js +91 -0
  520. package/dist/services/memory-second-repair-launch.js +614 -0
  521. package/dist/services/memory-second-repair-registration.js +88 -0
  522. package/dist/services/memory-second-repair-source.js +187 -0
  523. package/dist/services/memory-second-review-acceptance.js +115 -0
  524. package/dist/services/memory-source-observations.js +117 -0
  525. package/dist/services/memory-stage-dispatch.js +65 -0
  526. package/dist/services/memory-stage-results.js +290 -0
  527. package/dist/services/memory-tool-probe.js +25 -0
  528. package/dist/services/memory-upgrade-analysis-handler.js +243 -0
  529. package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
  530. package/dist/services/memory-upgrade-evidence.js +100 -0
  531. package/dist/services/memory-upgrade-inventory.js +442 -0
  532. package/dist/services/memory-upgrade-publication-custody.js +73 -0
  533. package/dist/services/memory-upgrade-publication.js +413 -0
  534. package/dist/services/memory-upgrade-selection.js +430 -0
  535. package/dist/services/memory-upgrade-start.js +60 -0
  536. package/dist/services/memory-upgrade-storage-readiness.js +340 -0
  537. package/dist/services/memory-verification-acceptance.js +156 -0
  538. package/dist/services/memory-verification-checks.js +317 -0
  539. package/dist/services/memory-verification-receipt.js +160 -0
  540. package/dist/services/memory-verify-handler.js +137 -0
  541. package/dist/services/memory-work-result-json.js +12 -0
  542. package/dist/services/memory-work-result-preparation.js +64 -0
  543. package/dist/services/merge-queue.js +228 -149
  544. package/dist/services/merge-server.js +163 -35
  545. package/dist/services/migrations.js +164 -114
  546. package/dist/services/model-catalog.js +109 -0
  547. package/dist/services/model-discovery.js +46 -0
  548. package/dist/services/native-daemon-history.js +50 -0
  549. package/dist/services/native-session-control.js +39 -0
  550. package/dist/services/operator-profiles.js +236 -0
  551. package/dist/services/physical-startup.js +45 -0
  552. package/dist/services/plan-runtime.js +26 -11
  553. package/dist/services/plans.js +28 -25
  554. package/dist/services/project-flow-source.js +195 -0
  555. package/dist/services/project-git-integration.js +92 -0
  556. package/dist/services/project-registry.js +97 -0
  557. package/dist/services/project-summary.js +1 -1
  558. package/dist/services/projects.js +17 -87
  559. package/dist/services/prompt-delivery.js +71 -0
  560. package/dist/services/prompts.js +28 -17
  561. package/dist/services/protocols.js +163 -87
  562. package/dist/services/provider-capacity.js +463 -0
  563. package/dist/services/recovery-observation-budget.js +121 -0
  564. package/dist/services/recovery-snapshot-database.js +588 -0
  565. package/dist/services/release-archive-producer.js +52 -0
  566. package/dist/services/release-archive.js +143 -0
  567. package/dist/services/release-cache.js +150 -0
  568. package/dist/services/release-compatibility.js +18 -0
  569. package/dist/services/release-download.js +67 -0
  570. package/dist/services/release-envelope.js +104 -0
  571. package/dist/services/release-manifest.js +45 -0
  572. package/dist/services/release-payload.js +114 -0
  573. package/dist/services/release-producer.js +63 -0
  574. package/dist/services/release-provenance.js +160 -0
  575. package/dist/services/release-registry.js +66 -0
  576. package/dist/services/release-source.js +194 -0
  577. package/dist/services/repair-intents.js +29 -0
  578. package/dist/services/repair-receipt.js +13 -0
  579. package/dist/services/retained-native-hook.js +274 -0
  580. package/dist/services/review-copy.js +165 -0
  581. package/dist/services/review-deferral.js +23 -0
  582. package/dist/services/review-fix-handoff.js +82 -0
  583. package/dist/services/review-fix-intake-custody.js +17 -0
  584. package/dist/services/review-fix-stage-entry.js +43 -0
  585. package/dist/services/review-fix-stage-handlers.js +176 -0
  586. package/dist/services/review-fix-stage-results.js +86 -0
  587. package/dist/services/run-control-receipt.js +56 -0
  588. package/dist/services/run-control-worker.js +469 -0
  589. package/dist/services/run-control.js +1109 -0
  590. package/dist/services/run-controller-adapter.js +434 -0
  591. package/dist/services/run-controller-capture.js +186 -0
  592. package/dist/services/run-controller-process.js +226 -0
  593. package/dist/services/run-controller-recovery.js +335 -0
  594. package/dist/services/run-controller-state.js +106 -0
  595. package/dist/services/run-controller.js +1717 -0
  596. package/dist/services/run-engine-bindings.js +1 -1
  597. package/dist/services/run-fork.js +147 -0
  598. package/dist/services/run-health.js +149 -0
  599. package/dist/services/run-observations.js +152 -0
  600. package/dist/services/run-projection.js +22 -64
  601. package/dist/services/run-recovery-guard.js +107 -0
  602. package/dist/services/run-recovery-runtime.js +112 -0
  603. package/dist/services/run-recovery.js +485 -0
  604. package/dist/services/run-start-custody.js +189 -0
  605. package/dist/services/run-timeline.js +59 -0
  606. package/dist/services/runs.js +996 -271
  607. package/dist/services/runtime-budget.js +446 -0
  608. package/dist/services/runtime-command.js +43 -0
  609. package/dist/services/runtime-scope-capture.js +52 -0
  610. package/dist/services/runtime-scope-control.js +468 -0
  611. package/dist/services/runtime-scope-resume.js +605 -0
  612. package/dist/services/runtime-scope-stop.js +211 -0
  613. package/dist/services/runtime-scope-worker.js +314 -0
  614. package/dist/services/runtime-service.js +19 -14
  615. package/dist/services/schema-validation.js +10 -8
  616. package/dist/services/scope-writer-cleanup.js +27 -0
  617. package/dist/services/sessions.js +37 -91
  618. package/dist/services/setup.js +427 -0
  619. package/dist/services/stage-blocker.js +17 -7
  620. package/dist/services/stage-context.js +240 -18
  621. package/dist/services/stage-handlers.js +141 -0
  622. package/dist/services/stage-lifecycle.js +156 -119
  623. package/dist/services/stage-pause.js +222 -94
  624. package/dist/services/stage-report-renderer.js +230 -6
  625. package/dist/services/stage-work-graph.js +52 -0
  626. package/dist/services/technical-notes.js +31 -0
  627. package/dist/services/tooling.js +111 -44
  628. package/dist/services/usage.js +49 -101
  629. package/dist/services/verification-matrix.js +393 -0
  630. package/dist/services/version-status.js +1 -1
  631. package/dist/services/vnext-code-review.js +302 -91
  632. package/dist/services/vnext-code.js +325 -251
  633. package/dist/services/vnext-contracts.js +10 -1
  634. package/dist/services/vnext-execution-profile.js +80 -5
  635. package/dist/services/vnext-fanout.js +399 -20
  636. package/dist/services/vnext-merge.js +336 -114
  637. package/dist/services/vnext-plan-review.js +288 -133
  638. package/dist/services/vnext-plan.js +230 -106
  639. package/dist/services/vnext-protocolize.js +534 -96
  640. package/dist/services/vnext-specify.js +131 -84
  641. package/dist/services/vnext-workspace-policy.js +7 -2
  642. package/dist/services/work-registry.js +1950 -215
  643. package/dist/services/work-retry-context.js +55 -0
  644. package/dist/services/workspace-bootstrap.js +53 -15
  645. package/dist/services/workspace-files.js +85 -0
  646. package/dist/services/worktrees.js +108 -48
  647. package/dist/shared/entity-references.js +1 -0
  648. package/dist/shared/errors.js +27 -0
  649. package/dist/storage/agent-output.js +26 -0
  650. package/dist/storage/data-preservation.js +65 -0
  651. package/dist/storage/database.js +931 -40
  652. package/dist/storage/foreign-key-transaction.js +39 -0
  653. package/dist/storage/immutable-input.js +45 -0
  654. package/dist/storage/import-guard.js +159 -0
  655. package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
  656. package/dist/storage/native-cleanup.js +52 -0
  657. package/dist/storage/paired-writer-migration.js +424 -0
  658. package/dist/storage/paths.js +17 -4
  659. package/dist/storage/projection-lock.js +73 -0
  660. package/dist/storage/work-references.js +23 -0
  661. package/dist/storage/writer-contract.js +96 -0
  662. package/dist/storage/writer-migration.js +346 -0
  663. package/dist/storage/writer-restore.js +217 -0
  664. package/dist/verification-components.json +384 -0
  665. package/package.json +52 -13
  666. package/tools/create-canon-release.mjs +33 -0
  667. package/tools/probe-codex-history.mjs +37 -0
  668. package/tools/produce-hybrid-release.mjs +41 -0
  669. package/tools/repair-paused-run-status.mjs +84 -0
  670. package/tools/verification-jobs.mjs +342 -0
@@ -2,22 +2,27 @@ import crypto from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { spawnSync } from "node:child_process";
5
+ import { commandResult } from '../harness-runtime/lib/process-json.mjs';
6
+ import { SETUP_STARTUP_MS } from '../harness-runtime/lib/setup-progress.mjs';
5
7
  import { requireProjectByRoot } from "./projects.js";
6
8
  import { appendAudit } from "./audit.js";
7
9
  import { persistProtocolState, requireProtocol, readProtocolRuntimeState } from "./protocols.js";
8
- import { attachFlowRunStage, completeFlowRunStage, getFlowRunStatus, startFlowRun } from "./runs.js";
10
+ import { attachFlowRunStage, prepareFlowRunStart, prepareFlowRunStageAttachment, prepareStageDirectory, completeFlowRunStage, getFlowRunStatus, startFlowRun } from "./runs.js";
9
11
  import { validateSchema } from "./schema-validation.js";
10
12
  import { reconcileSessionCoverage, registerFlowSession } from "./sessions.js";
11
13
  import { usageForRun } from "./usage.js";
12
- import { boundCanonicalPlan } from "./plan-runtime.js";
13
- import { AppError } from "../shared/errors.js";
14
- import { planJsonPath, resolveProjectRoot } from "../storage/paths.js";
14
+ import { boundCanonicalPlan, prepareCanonicalPlan } from "./plan-runtime.js";
15
+ import { prepareJsonFile, prepareJsonSchema, prepareOutputDirectory, prepareOutputFile, prepareTextFile } from "../cli/input-preparation.js";
16
+ import { AppError, errorRecord, processEvidence, diagnosticJson } from "../shared/errors.js";
17
+ import { planJsonPath, projectHome, resolveProjectRoot } from "../storage/paths.js";
15
18
  import { resolveCanonRoot } from "./canon.js";
16
19
  import { preflightMemoryPermissions } from "./memory-permissions.js";
17
20
  import { registerProject } from "./projects.js";
18
21
  import { registerProtocol } from "./protocols.js";
19
22
  import { previewNextEntityId } from "./ids.js";
20
23
  import { hookSessionIdentity, sessionIdForHookEvent } from "./hooks.js";
24
+ import { assignedSessionIdentity, lifecycleSessionIdentity } from "./assigned-lifecycle.js";
25
+ import { assertRunMutationAllowed } from "./run-recovery.js";
21
26
  const stagePromptSections = [
22
27
  "stage_identity",
23
28
  "authoritative_runtime_facts",
@@ -28,63 +33,30 @@ const stagePromptSections = [
28
33
  "work_contract",
29
34
  "completion_contract"
30
35
  ];
31
- function bootstrapStageRun(context, projectRoot, input) {
32
- if (input.stage !== "specify") {
33
- throw new AppError("validation", "--bootstrap currently starts the initial specify stage only", 2, { stage: input.stage });
34
- }
35
- const subject = input.bootstrap?.subject.trim();
36
- if (!subject)
37
- throw new AppError("usage", "--bootstrap requires --subject", 2);
36
+ function bootstrapStageRun(context, projectRoot, bootstrap, intakeMarkdown) {
38
37
  registerProject(context, { root: projectRoot });
39
- const preview = previewNextEntityId(context, { projectRoot, type: "protocol", slug: subject });
40
- const protocolId = preview.entity.id;
41
- registerProtocol(context, { handshakeId: protocolId, projectRoot });
42
- const started = startFlowRun(context, {
43
- projectRoot,
44
- flowKind: "mb_sdlc",
45
- subjectType: "protocol",
46
- subjectId: protocolId,
47
- slug: subject,
48
- nextAction: "run_specify"
49
- });
50
- const intakeFile = input.bootstrap?.intakeFile;
51
- if (intakeFile) {
52
- const source = path.resolve(intakeFile);
53
- if (!fs.existsSync(source) || !fs.statSync(source).isFile()) {
54
- throw new AppError("not_found", "--intake-file must point to an existing file", 1, { intake_file: intakeFile });
55
- }
38
+ registerProtocol(context, { handshakeId: bootstrap.protocolId, projectRoot });
39
+ const started = startFlowRun(context, bootstrap.startInput, bootstrap.start);
40
+ if (intakeMarkdown !== undefined) {
56
41
  if (!started.run.run_root)
57
42
  throw new AppError("runtime_missing", "New RUN has no artifact root", 1, { run_id: started.run.id });
58
43
  const intakeDir = path.join(started.run.run_root, "intake");
59
44
  fs.mkdirSync(intakeDir, { recursive: true });
60
- fs.copyFileSync(source, path.join(intakeDir, "user-request.md"));
45
+ fs.writeFileSync(path.join(intakeDir, "user-request.md"), intakeMarkdown);
61
46
  }
62
47
  return started.run.id;
63
48
  }
64
- function stagePreflight(projectRoot, stageRoot) {
49
+ function stagePreflight(projectRoot) {
65
50
  const memoryBank = preflightMemoryPermissions({
66
51
  root: projectRoot,
67
52
  memoryBank: ".memory-bank",
68
53
  flow: "custom",
69
- mode: "write",
54
+ mode: "read",
70
55
  targets: [{ path: ".memory-bank", mode: "read" }]
71
56
  });
72
- const probe = path.join(stageRoot, `.dd-flow-permission-${crypto.randomUUID()}`);
73
- try {
74
- fs.writeFileSync(probe, "");
75
- fs.renameSync(probe, `${probe}.renamed`);
76
- fs.rmSync(`${probe}.renamed`);
77
- return { ...memoryBank, ok: memoryBank.ok === true, stage_workspace: { path: stageRoot, status: "passed" } };
78
- }
79
- catch (error) {
80
- for (const candidate of [probe, `${probe}.renamed`]) {
81
- try {
82
- fs.rmSync(candidate, { force: true });
83
- }
84
- catch { /* best effort */ }
85
- }
86
- return { ...memoryBank, ok: false, stage_workspace: { path: stageRoot, status: "failed", message: String(error) } };
87
- }
57
+ if (memoryBank.ok !== true)
58
+ throw new AppError("permission_preflight_failed", "Stage project context is not readable", 1, { preflight: memoryBank });
59
+ return memoryBank;
88
60
  }
89
61
  function flowKindForStage(stage) {
90
62
  return ["code", "implementation", "readiness", "merge"].includes(stage) ? "implementation" : "planning";
@@ -103,23 +75,57 @@ function runtimeFacts(view, projectRoot) {
103
75
  git: view.index.execution?.git ?? { branch: null, head: null, status: "unavailable" }
104
76
  };
105
77
  }
106
- export function startStage(context, input) {
107
- if (input.requireSessionBinding && !input.hookEventId) {
78
+ export function prepareLegacyStageStart(context, input, intakeMarkdown) {
79
+ if (input.bootstrap && input.stage !== "specify")
80
+ throw new AppError("validation", "--bootstrap currently starts the initial specify stage only", 2);
81
+ if (input.bootstrap && !input.bootstrap.subject?.trim())
82
+ throw new AppError("usage", "--bootstrap requires --subject", 2);
83
+ if (!input.bootstrap && !input.runId)
84
+ throw new AppError("usage", "stage start requires a RUN id or --bootstrap", 2);
85
+ if (input.dir !== undefined)
86
+ prepareStageDirectory(input.dir);
87
+ const intake = intakeMarkdown ?? (input.bootstrap?.intakeFile ? prepareTextFile(input.bootstrap.intakeFile, "SPECIFY intake").text : undefined);
88
+ const projectRoot = resolveProjectRoot(input.projectRoot);
89
+ const retained = !input.bootstrap && input.runId ? runView(getFlowRunStatus(context, { projectRoot, runId: input.runId })) : null;
90
+ const dir = input.dir ?? defaultStageDir(input.stage, retained?.run.flow_kind ?? "mb_sdlc");
91
+ if (retained) {
92
+ prepareFlowRunStageAttachment(context, { projectRoot, runId: retained.run.id, stage: input.stage, dir, status: "running", dataSchemaId: dataSchemaForStage(input.stage) });
93
+ const root = path.join(runHomePath(retained.run), dir);
94
+ for (const name of ["stage-prompt.md", "stage-prompt.json", "stage-start.json", "stage-input.json"])
95
+ prepareOutputFile(path.join(root, name));
96
+ if (retained.run.subject.type === "protocol")
97
+ readProtocolRuntimeState(context, requireProtocol(context, retained.run.subject.id, retained.run.project_id));
98
+ }
99
+ const preflight = stagePreflight(projectRoot);
100
+ const sources = stageInstructionSources(context, projectRoot, retained?.run.flow_kind ?? "mb_sdlc", input.stage).map(source => ({ ...source, text: fs.existsSync(source.absolute) ? fs.readFileSync(source.absolute, "utf8").trim() : "(unavailable)" }));
101
+ let bootstrap;
102
+ if (input.bootstrap) {
103
+ const project = context.db.get("SELECT id FROM projects WHERE root = ?", [projectRoot]);
104
+ prepareOutputDirectory(project ? projectHome(context.ddFlowHome, project.id) : path.join(context.ddFlowHome, "projects"));
105
+ const preview = previewNextEntityId(context, { projectRoot, type: "protocol", slug: input.bootstrap.subject });
106
+ const startInput = { projectRoot, flowKind: "mb_sdlc", subjectType: "protocol", subjectId: preview.entity.id, slug: input.bootstrap.subject, nextAction: "run_specify" };
107
+ bootstrap = { protocolId: preview.entity.id, startInput, start: prepareFlowRunStart(context, startInput) };
108
+ }
109
+ return { intakeMarkdown: intake, projectRoot, retained, dir, preflight, sources, bootstrap };
110
+ }
111
+ export function startStage(context, input, prepared = prepareLegacyStageStart(context, input)) {
112
+ if (input.requireSessionBinding && !input.hookEventId && !assignedSessionIdentity(context)) {
108
113
  throw new AppError("trusted_session_binding_required", "This stage requires a trusted harness lifecycle binding; run it from a controlled Session with the dd-flow adapter enabled", 1);
109
114
  }
110
- const projectRoot = resolveProjectRoot(input.projectRoot);
115
+ const { projectRoot, retained, dir, preflight, sources } = prepared;
116
+ if (retained)
117
+ prepareFlowRunStageAttachment(context, { projectRoot, runId: retained.run.id, stage: input.stage, dir: input.dir ?? defaultStageDir(input.stage, retained.run.flow_kind), status: "running", dataSchemaId: dataSchemaForStage(input.stage) });
111
118
  let requiredSessionId = null;
112
119
  let requiredIdentity = null;
113
120
  if (input.requireSessionBinding) {
114
- registerProject(context, { root: projectRoot });
115
- requiredIdentity = hookSessionIdentity(context, requireProjectByRoot(context, projectRoot).id, input.hookEventId);
121
+ requiredIdentity = lifecycleSessionIdentity(context, requireProjectByRoot(context, projectRoot).id, input.hookEventId);
116
122
  requiredSessionId = requiredIdentity.sessionId;
117
123
  }
118
- const runId = input.bootstrap ? bootstrapStageRun(context, projectRoot, input) : input.runId;
124
+ const runId = prepared.bootstrap ? bootstrapStageRun(context, projectRoot, prepared.bootstrap, prepared.intakeMarkdown) : input.runId;
119
125
  if (!runId)
120
126
  throw new AppError("usage", "stage start requires a RUN id or --bootstrap", 2);
121
- const before = runView(getFlowRunStatus(context, { projectRoot, runId }));
122
- const dir = input.dir ?? defaultStageDir(input.stage, before.run.flow_kind);
127
+ const before = retained ?? runView(getFlowRunStatus(context, { projectRoot, runId }));
128
+ assertRunMutationAllowed(context, before.run.project_id, before.run.id);
123
129
  const attached = runView(attachFlowRunStage(context, {
124
130
  projectRoot,
125
131
  runId,
@@ -132,17 +138,14 @@ export function startStage(context, input) {
132
138
  const stageRoot = path.join(runHome, dir);
133
139
  ensureWithin(runHome, stageRoot, "stage root");
134
140
  fs.mkdirSync(stageRoot, { recursive: true });
135
- const preflight = stagePreflight(projectRoot, stageRoot);
136
- if (preflight.ok !== true)
137
- throw new AppError("permission_preflight_failed", "Stage workspace is not writable", 1, { preflight });
138
141
  if (attached.run.subject.type === "protocol") {
139
142
  syncProtocolLifecycle(context, attached.run.project_id, attached.run.subject.id, input.stage, "running");
140
143
  }
141
- const sessionId = requiredSessionId ?? (input.hookEventId ? sessionIdForHookEvent(context, attached.run.project_id, input.hookEventId) : null);
144
+ const sessionId = requiredSessionId ?? assignedSessionIdentity(context)?.sessionId ?? (input.hookEventId ? sessionIdForHookEvent(context, attached.run.project_id, input.hookEventId) : null);
142
145
  if (sessionId) {
143
146
  const identity = requiredIdentity ?? (input.hookEventId ? hookSessionIdentity(context, attached.run.project_id, input.hookEventId) : null);
144
147
  registerFlowSession(context, {
145
- sessionId,
148
+ hookEventId: input.hookEventId,
146
149
  payloadJson: JSON.stringify({
147
150
  project_root: projectRoot,
148
151
  harness: identity?.harness ?? "codex-desktop",
@@ -162,12 +165,12 @@ export function startStage(context, input) {
162
165
  continuation_policy: "go_router",
163
166
  session_kind: "orchestrator",
164
167
  current_stage: input.stage,
165
- cwd: attached.run.workspace_root
168
+ cwd: identity?.cwd ?? null
166
169
  })
167
170
  });
168
171
  }
169
172
  const promptPath = path.join(stageRoot, "stage-prompt.md");
170
- const prompt = composeStagePrompt(context, projectRoot, before, attached, input.stage, dir, preflight);
173
+ const prompt = composeStagePrompt(context, projectRoot, before, attached, input.stage, dir, preflight, sources);
171
174
  atomicWrite(promptPath, prompt);
172
175
  const semanticInputPath = path.join(stageRoot, "stage-input.json");
173
176
  if (!fs.existsSync(semanticInputPath)) {
@@ -178,7 +181,6 @@ export function startStage(context, input) {
178
181
  const aspectMapPath = path.join(stageRoot, "aspect-map.json");
179
182
  const attempt = attached.index.stage_runs?.find((stage) => stage.stage === input.stage)?.attempt ?? "try-001";
180
183
  const attemptNumber = Number(attempt.replace("try-", "")) || 1;
181
- const sources = stageInstructionSources(context, projectRoot, attached.run.flow_kind, input.stage);
182
184
  atomicWrite(promptDataPath, {
183
185
  schema_id: "dd-flow/stage-prompt@2",
184
186
  run_id: attached.run.id,
@@ -257,12 +259,13 @@ export function startStage(context, input) {
257
259
  lifecycle: "stage start -> semantic work -> stage finish"
258
260
  };
259
261
  }
260
- export function finishStage(context, input) {
262
+ export function prepareStageFinish(context, input) {
261
263
  const projectRoot = resolveProjectRoot(input.projectRoot);
262
264
  if (!input.runId)
263
265
  throw new AppError("usage", "stage finish requires a RUN id", 2);
264
266
  const runId = input.runId;
265
267
  const view = runView(getFlowRunStatus(context, { projectRoot, runId }));
268
+ assertRunMutationAllowed(context, view.run.project_id, view.run.id);
266
269
  const existing = view.index.stage_runs?.find((stage) => stage.stage === input.stage);
267
270
  if (!existing) {
268
271
  throw new AppError("not_found", `Run stage is not attached: ${input.stage}`, 1, { run_id: view.run.id, stage: input.stage });
@@ -271,31 +274,37 @@ export function finishStage(context, input) {
271
274
  const runHome = runHomePath(view.run);
272
275
  const stageRoot = path.join(runHome, dir);
273
276
  ensureWithin(runHome, stageRoot, "stage root");
274
- fs.mkdirSync(stageRoot, { recursive: true });
275
277
  const semanticFile = resolveStageFile(input.semanticFile ?? "@stage/stage-input.json", stageRoot, runHome);
276
- const receipt = beginFinishReceipt(context, stageRoot, semanticFile, view.run.id, input.stage);
278
+ ensureWithin(runHome, semanticFile, "semantic file");
279
+ const source = prepareJsonSchema(semanticFile, "Stage finish input", { schemaName: "stage-finish-input", projectRoot, runId, runRoot: runHome, ddFlowHome: context.ddFlowHome });
280
+ const semantic = source.value;
281
+ const status = stringValue(semantic.status) ?? "done";
282
+ if (!["done", "waiting_for_user", "blocked", "failed"].includes(status)) {
283
+ throw new AppError("validation", "Stage finish status must be done, waiting_for_user, blocked, or failed", 2, { status });
284
+ }
285
+ validateStageOutcome(input.stage, status, semantic);
286
+ const planFinish = input.stage === "plan" ? preparePlanFinish(context, projectRoot, view, stageRoot) : undefined;
287
+ return { projectRoot, runId, view, existing, runHome, stageRoot, semanticFile, semantic, status, source, planFinish };
288
+ }
289
+ export async function finishStage(context, input, prepared = prepareStageFinish(context, input)) {
290
+ const { projectRoot, runId, view, runHome, stageRoot, semanticFile, semantic, status, source, planFinish } = prepared;
291
+ assertRunMutationAllowed(context, view.run.project_id, view.run.id);
292
+ fs.mkdirSync(stageRoot, { recursive: true });
293
+ const receipt = beginFinishReceipt(context, stageRoot, semanticFile, view.run.id, input.stage, source.text);
277
294
  try {
278
- validateSchema({ schemaName: "stage-finish-input", file: semanticFile, projectRoot, runId, runRoot: runHome, ddFlowHome: context.ddFlowHome });
279
- const semantic = readSemanticFile(semanticFile, runHome);
280
- const status = stringValue(semantic.status) ?? "done";
281
- if (!["done", "waiting_for_user", "blocked", "failed"].includes(status)) {
282
- throw new AppError("validation", "Stage finish status must be done, waiting_for_user, blocked, or failed", 2, { status });
283
- }
284
- validateStageOutcome(input.stage, status, semantic);
285
295
  const coverage = workerCoverage(context, view.run.project_id, view.run.id);
286
296
  if (coverage.jobs.missing?.length) {
287
297
  throw new AppError("worker_jobs_incomplete", "Stage finish requires all declared worker jobs", 1, { coverage });
288
298
  }
289
- const lint = runTargetedMemoryBankLint(projectRoot);
290
- const planFinish = input.stage === "plan"
291
- ? preparePlanFinish(context, projectRoot, view, stageRoot)
292
- : undefined;
299
+ const lint = await runTargetedMemoryBankLint(projectRoot, undefined, path.join(stageRoot, "diagnostics"));
300
+ if (planFinish)
301
+ boundCanonicalPlan(context, { projectId: view.run.project_id, protocolId: view.run.subject.id, planPath: planFinish.plan_path }, planFinish.canonical);
293
302
  const report = buildStageReport(context, view, input.stage, status, semantic, stageRoot, lint, planFinish);
294
303
  const dataPath = path.join(stageRoot, "stage-report.json");
295
304
  const reportPath = path.join(stageRoot, "stage-report.md");
296
305
  const htmlPath = path.join(stageRoot, "stage-report.html");
306
+ validateSchema({ schemaName: stageReportSchemaName(input.stage, planFinish), file: dataPath, data: report, projectRoot, runId, runRoot: runHome, ddFlowHome: context.ddFlowHome });
297
307
  atomicWrite(dataPath, report);
298
- validateSchema({ schemaName: stageReportSchemaName(input.stage, planFinish), file: dataPath, projectRoot, runId, runRoot: runHome, ddFlowHome: context.ddFlowHome });
299
308
  atomicWrite(reportPath, renderMarkdown(report));
300
309
  atomicWrite(htmlPath, renderHtml(projectRoot, report));
301
310
  if (view.run.subject.type === "protocol") {
@@ -480,12 +489,10 @@ function semanticInputTemplate(stage) {
480
489
  next_action: waiting ? "waiting_for_user: obtain the clarification packet" : "Continue to the next approved stage."
481
490
  };
482
491
  }
483
- function composeStagePrompt(context, projectRoot, before, current, stage, dir, preflight) {
492
+ function composeStagePrompt(context, projectRoot, before, current, stage, dir, preflight, sources) {
484
493
  const project = requireProjectByRoot(context, projectRoot);
485
494
  const runHome = runHomePath(current.run);
486
- const instructions = stageInstructionSources(context, projectRoot, current.run.flow_kind, stage).map(({ label, absolute }) => {
487
- return fs.existsSync(absolute) ? `### ${label}\n\n${fs.readFileSync(absolute, "utf8").trim()}` : `### ${label}\n\n(unavailable)`;
488
- }).join("\n\n");
495
+ const instructions = sources.map(({ label, text }) => `### ${label}\n\n${text}`).join("\n\n");
489
496
  const protocol = safeProtocolState(context, current.run.project_id, current.run.subject.id);
490
497
  return [
491
498
  "<stage_identity>",
@@ -508,7 +515,7 @@ function composeStagePrompt(context, projectRoot, before, current, stage, dir, p
508
515
  "</authoritative_runtime_facts>",
509
516
  "",
510
517
  "<preflight>",
511
- `- Permission probe: ${String(preflight.ok === true ? "passed" : "failed")}.`,
518
+ `- Read-only permission check: ${String(preflight.ok === true ? "passed" : "failed")}.`,
512
519
  "- CLI compatibility was checked before this state-changing command.",
513
520
  "</preflight>",
514
521
  "",
@@ -581,16 +588,6 @@ function safeProtocolState(context, projectId, protocolId) {
581
588
  return undefined;
582
589
  }
583
590
  }
584
- function readSemanticFile(file, runHome) {
585
- const resolved = path.resolve(file);
586
- ensureWithin(runHome, resolved, "semantic file");
587
- if (!fs.existsSync(resolved))
588
- throw new AppError("not_found", "Semantic input file is missing", 1, { path: file });
589
- const value = JSON.parse(fs.readFileSync(resolved, "utf8"));
590
- if (!value || typeof value !== "object" || Array.isArray(value))
591
- throw new AppError("validation", "Semantic input must be a JSON object", 2);
592
- return value;
593
- }
594
591
  function validateStageOutcome(stage, status, semantic) {
595
592
  if (stage !== "specify")
596
593
  return;
@@ -602,17 +599,12 @@ function validateStageOutcome(stage, status, semantic) {
602
599
  throw new AppError("semantic_status_inconsistent", "SPECIFY done cannot contain unresolved structured questions", 2);
603
600
  }
604
601
  }
605
- function beginFinishReceipt(context, stageRoot, semanticFile, runId, stage) {
602
+ function beginFinishReceipt(context, stageRoot, semanticFile, runId, stage, raw) {
606
603
  const receiptDir = path.join(stageRoot, "finish-receipts");
607
604
  fs.mkdirSync(receiptDir, { recursive: true });
608
605
  const number = fs.readdirSync(receiptDir).filter((file) => /^\d{3}\.json$/u.test(file)).length + 1;
609
606
  const receiptPath = path.join(receiptDir, `${String(number).padStart(3, "0")}.json`);
610
- let raw = null;
611
- try {
612
- raw = fs.readFileSync(semanticFile, "utf8");
613
- }
614
- catch { /* receipt records the missing input below */ }
615
- const semanticSha = raw === null ? null : crypto.createHash("sha256").update(raw).digest("hex");
607
+ const semanticSha = crypto.createHash("sha256").update(raw).digest("hex");
616
608
  atomicWrite(receiptPath, {
617
609
  schema_id: "dd-flow/stage-finish-receipt@1",
618
610
  run_id: runId,
@@ -750,7 +742,8 @@ function buildStageReport(context, view, stage, status, semantic, stageRoot, lin
750
742
  next_action: stringValue(semantic.next_action) ?? "Resolve the stage result before continuing.",
751
743
  ...(Array.isArray(semantic.questions) ? { questions: semantic.questions } : {}),
752
744
  ...(Array.isArray(semantic.reviewer_findings) ? { reviewer_findings: semantic.reviewer_findings } : {}),
753
- ...(Array.isArray(semantic.def_outcomes) ? { def_outcomes: semantic.def_outcomes } : {})
745
+ ...(Array.isArray(semantic.def_outcomes) ? { def_outcomes: semantic.def_outcomes } : {}),
746
+ ...(semantic.materialization !== undefined ? { materialization: semantic.materialization } : {})
754
747
  },
755
748
  mechanical: {
756
749
  started_at: startedAt,
@@ -775,17 +768,13 @@ function buildStageReport(context, view, stage, status, semantic, stageRoot, lin
775
768
  }
776
769
  function preparePlanFinish(context, projectRoot, view, stageRoot) {
777
770
  const planPath = planJsonPath(projectRoot, view.run.subject.id);
778
- const canonical = boundCanonicalPlan(context, {
771
+ const canonical = prepareCanonicalPlan(context, {
779
772
  projectId: view.run.project_id,
780
773
  protocolId: view.run.subject.id,
781
774
  planPath
782
775
  });
783
776
  const aspectMapPath = path.join(stageRoot, "aspect-map.json");
784
- if (!fs.existsSync(aspectMapPath)) {
785
- throw new AppError("not_found", "PLAN aspect-map.json is missing", 1, { path: aspectMapPath });
786
- }
787
- const raw = fs.readFileSync(aspectMapPath, "utf8");
788
- const value = JSON.parse(raw);
777
+ const { text: raw, value } = prepareJsonFile(aspectMapPath, "PLAN aspect map");
789
778
  if (!value || typeof value !== "object" || Array.isArray(value)) {
790
779
  throw new AppError("validation", "PLAN aspect-map.json must be a JSON object", 2, { path: aspectMapPath });
791
780
  }
@@ -848,7 +837,7 @@ function workerCoverage(context, projectId, runId) {
848
837
  jobs: { expected: jobs.map((job) => job.job_id), missing: missingJobs }
849
838
  };
850
839
  }
851
- export function runTargetedMemoryBankLint(projectRoot, selectedFiles) {
840
+ export async function runTargetedMemoryBankLint(projectRoot, selectedFiles, diagnosticRoot) {
852
841
  const files = [...new Set((selectedFiles ?? gitChangedFiles(projectRoot)).filter((file) => file.startsWith(".memory-bank/") && file.toLowerCase().endsWith(".md") && !file.split(/[\\/]/u).some((part) => part === ".." || part.startsWith(".env"))))];
853
842
  for (const file of files)
854
843
  ensureWithin(projectRoot, path.resolve(projectRoot, file), "lint target");
@@ -856,23 +845,71 @@ export function runTargetedMemoryBankLint(projectRoot, selectedFiles) {
856
845
  return { ok: true, status: "not_applicable_no_changed_docs", files, finding_count: 0 };
857
846
  }
858
847
  const binary = process.env.MB_LINT_BIN ?? "mb-lint";
859
- const result = spawnSync(binary, ["--root", projectRoot, "--files", ...files, "--format", "json"], { cwd: projectRoot, encoding: "utf8" });
860
- if (result.error || result.status === null) {
861
- throw new AppError("lint_gate_unavailable", "Selected-file mb-lint is unavailable", 1, { binary, files, cause: String(result.error ?? "process did not start") });
848
+ const fail = (code, message, details) => {
849
+ const error = new AppError(code, message, 1, { binary, files, ...details });
850
+ if (diagnosticRoot) {
851
+ try {
852
+ fs.mkdirSync(diagnosticRoot, { recursive: true });
853
+ const file = path.join(diagnosticRoot, `lint-${crypto.randomUUID()}.json`);
854
+ if (details.report) {
855
+ const reportFile = file.replace(/\.json$/, ".report.json"), report = diagnosticJson(details.report);
856
+ const reportBytes = Buffer.from(report);
857
+ fs.writeFileSync(reportFile, reportBytes.length <= 1024 * 1024 ? report : JSON.stringify({ truncated: true, bytes: reportBytes.length, excerpt: reportBytes.subarray(0, 128 * 1024).toString("utf8") }), { flag: "wx", mode: 0o600 });
858
+ error.details.report_path = reportFile;
859
+ }
860
+ delete error.details.report;
861
+ fs.writeFileSync(file, diagnosticJson(errorRecord(error)), { flag: "wx", mode: 0o600 });
862
+ error.details.diagnostic_path = file;
863
+ }
864
+ catch (capture) {
865
+ delete error.details.report;
866
+ error.details.capture_error = errorRecord(capture);
867
+ }
868
+ }
869
+ delete error.details.report;
870
+ throw error;
871
+ };
872
+ let result;
873
+ try {
874
+ result = await commandResult(binary, ["--root", projectRoot, "--files", ...files, "--format", "json"], { cwd: projectRoot, startupMs: SETUP_STARTUP_MS });
862
875
  }
863
- let parsed = {};
876
+ catch (cause) {
877
+ const recorded = errorRecord(cause), unavailable = ["ENOENT", "EACCES", "ENOEXEC"].includes(recorded.code);
878
+ fail(unavailable ? "lint_gate_unavailable" : "lint_gate_tool_failed", "Selected-file mb-lint could not execute", { cause: recorded });
879
+ }
880
+ const evidence = processEvidence(result);
881
+ if (result.signal || result.exit_code !== 0 && result.exit_code !== 1)
882
+ fail("lint_gate_tool_failed", "Selected-file mb-lint did not complete normally", { process: evidence });
883
+ let parsed;
864
884
  try {
865
- parsed = result.stdout ? JSON.parse(result.stdout) : {};
885
+ parsed = JSON.parse(result.stdout);
866
886
  }
867
887
  catch {
868
- throw new AppError("lint_gate_invalid_output", "Selected-file mb-lint did not return JSON", 1, { binary, files });
888
+ fail(result.exit_code === 0 ? "lint_gate_invalid_output" : "lint_gate_tool_failed", "Selected-file mb-lint did not return a report", { process: evidence });
869
889
  }
870
- if (result.status !== 0) {
871
- throw new AppError("lint_gate_failed", "Selected-file mb-lint reported blocking findings", 1, { binary, files, result: parsed });
890
+ const report = parsed;
891
+ const severities = { error: "errors", warning: "warnings", info: "info", suggestion: "suggestions" };
892
+ const matchingRoot = () => { try {
893
+ return typeof report?.root === "string" && fs.realpathSync(path.resolve(projectRoot, report.root)) === fs.realpathSync(projectRoot);
872
894
  }
873
- const findingCount = parsed && typeof parsed === "object" && Array.isArray(parsed.findings)
874
- ? parsed.findings.length
875
- : 0;
895
+ catch {
896
+ return false;
897
+ } };
898
+ const valid = report && report.tool === "mb-lint" && typeof report.version === "string" && report.version.trim()
899
+ && matchingRoot()
900
+ && report.memoryBank === ".memory-bank" && report.summary && Array.isArray(report.findings)
901
+ && report.findings.every(finding => finding && typeof finding === "object" && typeof finding.severity === "string" && Object.hasOwn(severities, finding.severity)
902
+ && [finding.ruleId, finding.file, finding.message].every(value => typeof value === "string" && value.trim()))
903
+ && Object.entries(severities).every(([severity, key]) => Number.isSafeInteger(report.summary[key]) && Number(report.summary[key]) >= 0
904
+ && report.summary[key] === report.findings.filter(finding => finding.severity === severity).length);
905
+ if (!valid)
906
+ fail(result.exit_code === 0 ? "lint_gate_invalid_output" : "lint_gate_tool_failed", "Selected-file mb-lint returned an invalid report", { process: evidence });
907
+ const errors = Number(report.summary.errors);
908
+ if ((errors > 0 ? 1 : 0) !== result.exit_code)
909
+ fail("lint_gate_invalid_output", "Selected-file mb-lint report contradicts its exit status", { process: evidence });
910
+ if (errors > 0)
911
+ fail("lint_gate_failed", "Selected-file mb-lint reported blocking findings", { process: evidence, report: parsed, summary: report.summary, finding_count: report.findings.length });
912
+ const findingCount = report.findings.length;
876
913
  return { ok: true, status: "passed", binary, files, finding_count: findingCount, result: parsed };
877
914
  }
878
915
  function renderMarkdown(report) {