@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
@@ -0,0 +1,155 @@
1
+ import { createHash } from "node:crypto";
2
+ import { AppError } from "../shared/errors.js";
3
+ import { hybridDigest } from "./hybrid-contracts.js";
4
+ import { readFlowRunExecutionBundle, assertPreparedRunBundleSqlAuthority } from "./runs.js";
5
+ import { readRegisteredInteractiveWork } from "./interactive-work-registration.js";
6
+ import { PreparedInteractiveWorkspaceChanges } from "./interactive-mutation-scope.js";
7
+ import { PreparedInteractiveGitBaseline } from "./interactive-git-baseline.js";
8
+ import { readDescriptorStageInput } from "./descriptor-stage-coordinator.js";
9
+ import { stageGraphScope } from "./stage-work-graph.js";
10
+ import { assertRunMutationAllowed } from "./run-recovery-guard.js";
11
+ import { readBoundedReleaseFile } from "./release-source.js";
12
+ const event = "interactive.work_start";
13
+ const hash = (bytes) => createHash("sha256").update(bytes).digest("hex");
14
+ function refuse(reason) {
15
+ throw new AppError("interactive_work_start_invalid", "Interactive Work requires its issued input and actual physical start", 2, { reason, effect: "no_effect" });
16
+ }
17
+ export function readInteractiveWorkGit(bundle) {
18
+ const git = JSON.parse(bundle.blob("runtime/git-policy.json").toString("utf8"));
19
+ if (!git || typeof git.git_executable !== "string" || !/^[a-f0-9]{64}$/.test(git.git_sha256)
20
+ || hash(readBoundedReleaseFile(git.git_executable, 64 * 1024 * 1024)) !== git.git_sha256)
21
+ refuse("selected_git_changed");
22
+ return { git_executable: git.git_executable, git_sha256: git.git_sha256 };
23
+ }
24
+ /** Historical SQL-only start custody. Never recapture already edited sources. */
25
+ export function readInteractiveWorkStart(context, scope, bundle, workSessionId) {
26
+ const assignment = readRegisteredInteractiveWork(context, scope, bundle, scope.workId);
27
+ const rows = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.work_session_id')=? LIMIT 2", [scope.projectId, event, workSessionId]);
28
+ if (rows.length !== 1 || Buffer.byteLength(rows[0].payload_json) > 33 * 1024 * 1024)
29
+ refuse("start_custody_missing");
30
+ const receipt = JSON.parse(rows[0].payload_json);
31
+ if (!receipt || Object.keys(receipt).sort().join() !== "actor,attempt,bundle_sha256,hook_event_id,hook_event_key,packet_sha256,run_id,schema_id,snapshot,snapshot_sha256,stage,work_id,work_session_id"
32
+ || receipt.schema_id !== "dd-flow/interactive-work-start@1" || receipt.run_id !== scope.runId || receipt.work_id !== scope.workId
33
+ || receipt.work_session_id !== workSessionId || receipt.stage !== assignment.packet.stage || receipt.attempt !== assignment.receipt.attempt
34
+ || receipt.packet_sha256 !== assignment.packet.packet_sha256 || receipt.bundle_sha256 !== bundle.sha256
35
+ || !receipt.actor || Object.keys(receipt.actor).sort().join() !== "harness,provider_session_id,session_id")
36
+ refuse("start_binding_changed");
37
+ const actor = receipt.actor;
38
+ if (!context.db.get("SELECT 1 FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id JOIN hook_events h ON h.project_id=w.project_id AND h.event_key=ws.hook_event_id WHERE w.project_id=? AND w.run_id=? AND w.work_id=? AND ws.id=? AND ws.session_id=? AND ws.hook_event_id=? AND h.id=? AND h.status='claimed' AND h.session_id=ws.session_id AND h.harness=? AND h.provider_session_id=?", [scope.projectId, scope.runId, scope.workId, workSessionId, actor.session_id, receipt.hook_event_key, receipt.hook_event_id, actor.harness, actor.provider_session_id]))
39
+ refuse("physical_start_custody_changed");
40
+ const baseline = PreparedInteractiveGitBaseline.restore(Buffer.from(JSON.stringify(receipt.snapshot)), receipt.snapshot_sha256);
41
+ const start = context.db.get("SELECT start_receipt_json FROM work_sessions WHERE id=? AND work_id=?", [workSessionId, scope.workId]);
42
+ if (!start?.start_receipt_json || Buffer.byteLength(start.start_receipt_json) > 33 * 1024 * 1024)
43
+ refuse("start_packet_custody_missing");
44
+ const packetReceipt = JSON.parse(start.start_receipt_json);
45
+ if (typeof packetReceipt.context !== "string" || hash(Buffer.from(packetReceipt.context)) !== packetReceipt.context_sha256)
46
+ refuse("start_packet_changed");
47
+ const startContext = JSON.parse(packetReceipt.context);
48
+ if (startContext.run_id !== scope.runId || startContext.work_id !== scope.workId
49
+ || hybridDigest(startContext.interactive_start) !== hybridDigest({ schema_id: "dd-flow/interactive-work-start-binding@1",
50
+ packet_sha256: assignment.packet.packet_sha256, snapshot_sha256: baseline.sha256 }))
51
+ refuse("start_snapshot_binding_changed");
52
+ const frozen = bundle.execution.snapshot().scope;
53
+ if (baseline.snapshot().project_root !== frozen.projectRoot || baseline.snapshot().workspace !== frozen.workspace)
54
+ refuse("physical_start_scope_changed");
55
+ return { receipt, baseline, assignment };
56
+ }
57
+ /** Physical preparation precedes the ordinary hook/Session claim writer.
58
+ * The original Work snapshot is retained with that claim, never after edits. */
59
+ export class PreparedInteractiveWorkStart {
60
+ #scope;
61
+ #bundle;
62
+ #assignment;
63
+ #changes;
64
+ #baseline;
65
+ #git;
66
+ constructor(scope, bundle, assignment, changes, git) {
67
+ this.#scope = { ...scope };
68
+ this.#bundle = bundle;
69
+ this.#assignment = assignment;
70
+ this.#changes = changes;
71
+ const bytes = Buffer.from(JSON.stringify(changes.currentSnapshot()));
72
+ this.#baseline = PreparedInteractiveGitBaseline.restore(bytes, hash(bytes));
73
+ this.#git = { ...git };
74
+ Object.freeze(this);
75
+ }
76
+ static prepare(context, input) {
77
+ if (context.db.isOwnedWriteTransaction?.())
78
+ refuse("preparation_outside_writer_required");
79
+ const bundle = readFlowRunExecutionBundle(context, input);
80
+ if (!bundle)
81
+ refuse("bundle_required");
82
+ const assignment = readRegisteredInteractiveWork(context, input, bundle, input.workId), frozen = bundle.execution.snapshot().scope;
83
+ const git = readInteractiveWorkGit(bundle);
84
+ const changes = PreparedInteractiveWorkspaceChanges.prepare(context, input, bundle, { projectRoot: frozen.projectRoot,
85
+ workspace: frozen.workspace, gitExecutable: git.git_executable, env: context.env });
86
+ const prepared = new PreparedInteractiveWorkStart(input, bundle, assignment, changes, git);
87
+ const patch = changes.snapshot(), packet = assignment.packet;
88
+ if (hybridDigest(patch.delta.changes) !== packet.file_changes_sha256 || patch.scope_revision !== packet.scope_revision
89
+ || patch.user_inputs_sha256 !== packet.user_inputs_sha256)
90
+ refuse("issued_context_changed_before_start");
91
+ // Unchanged files are also selected reviewer/writer inputs, not just patch paths.
92
+ const files = new Map(changes.currentSnapshot().entries.filter(item => item.kind === "file").map(item => [item.path, item.sha256]));
93
+ if (packet.read_inputs.some(ref => ref.root === "workspace" && files.get(ref.path) !== ref.sha256))
94
+ refuse("issued_source_changed_before_start");
95
+ context.db.readSnapshot(() => prepared.assertSelection(context));
96
+ prepared.revalidate();
97
+ return prepared;
98
+ }
99
+ revalidate() {
100
+ if (hash(readBoundedReleaseFile(this.#git.git_executable, 64 * 1024 * 1024)) !== this.#git.git_sha256)
101
+ refuse("selected_git_changed");
102
+ this.#changes.revalidate();
103
+ }
104
+ binding() {
105
+ return { schema_id: "dd-flow/interactive-work-start-binding@1", packet_sha256: this.#assignment.packet.packet_sha256, snapshot_sha256: this.#baseline.sha256 };
106
+ }
107
+ assertSelection(context) {
108
+ const { projectId, runId, workId } = this.#scope, packet = this.#assignment.packet;
109
+ const current = readRegisteredInteractiveWork(context, this.#scope, this.#bundle, workId);
110
+ if (hybridDigest(current.receipt) !== hybridDigest(this.#assignment.receipt)
111
+ || hybridDigest(current.custody) !== hybridDigest(this.#assignment.custody)
112
+ || current.packet.packet_sha256 !== this.#assignment.packet.packet_sha256)
113
+ refuse("assignment_changed_before_start");
114
+ const run = assertPreparedRunBundleSqlAuthority(context, this.#scope, this.#bundle), index = JSON.parse(run.index_json);
115
+ const graph = stageGraphScope(context, projectId, runId, packet.owner_stage), stage = readDescriptorStageInput(context, { ...this.#scope, stage: packet.owner_stage }, this.#bundle);
116
+ if (run.status !== "running" || index.current_stage !== packet.owner_stage
117
+ || !index.stage_runs?.some((item) => item.stage === packet.owner_stage && item.status === "running" && item.attempt === graph.attempt)
118
+ || graph.attempt !== current.custody.scope.attempt || graph.cycle !== current.custody.scope.cycle
119
+ || stage.attempt !== graph.attempt || stage.inputSha256 !== packet.input_sha256)
120
+ refuse("active_assignment_required");
121
+ assertRunMutationAllowed(context, projectId, runId);
122
+ }
123
+ assertCustody(context) {
124
+ if (!context.db.isOwnedWriteTransaction?.())
125
+ refuse("owned_writer_required");
126
+ this.assertSelection(context);
127
+ this.#changes.assertCustody(context);
128
+ }
129
+ recordStart(context, workSessionId, hookEventKey, identity) {
130
+ this.assertCustody(context);
131
+ const { projectId, runId, workId } = this.#scope;
132
+ const link = context.db.get("SELECT 1 FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id JOIN sessions s ON s.project_id=w.project_id AND s.session_id=ws.session_id JOIN hook_events h ON h.project_id=w.project_id AND h.event_key=ws.hook_event_id WHERE w.project_id=? AND w.run_id=? AND w.work_id=? AND w.status='running' AND ws.id=? AND ws.status='running' AND ws.session_id=? AND ws.hook_event_id=? AND h.status='claimed' AND h.id=? AND h.session_id=ws.session_id AND s.harness=? AND s.provider_session_id=? AND h.harness=s.harness AND h.provider_session_id=s.provider_session_id", [projectId, runId, workId, workSessionId, identity.sessionId, hookEventKey, identity.hookEventId, identity.harness, identity.providerSessionId]);
133
+ if (!link)
134
+ refuse("claimed_work_session_required");
135
+ if (this.#assignment.retained.body.work_history.works.some(prior => prior.actor?.harness === identity.harness
136
+ && prior.actor.provider_session_id === identity.providerSessionId))
137
+ refuse("independent_physical_session_required");
138
+ if (context.db.get("SELECT 1 FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id JOIN sessions s ON s.project_id=w.project_id AND s.session_id=ws.session_id WHERE w.project_id=? AND w.run_id=? AND ws.id<>? AND s.harness=? AND s.provider_session_id=? LIMIT 1", [projectId, runId, workSessionId, identity.harness, identity.providerSessionId]))
139
+ refuse("independent_physical_session_required");
140
+ if (context.db.get("SELECT 1 FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.work_session_id')=?", [projectId, event, workSessionId]))
141
+ refuse("start_already_retained");
142
+ const packet = this.#assignment.packet;
143
+ const receipt = { schema_id: "dd-flow/interactive-work-start@1", run_id: runId, work_id: workId, work_session_id: workSessionId,
144
+ hook_event_key: hookEventKey, hook_event_id: identity.hookEventId, stage: packet.stage, attempt: this.#assignment.receipt.attempt,
145
+ packet_sha256: packet.packet_sha256, bundle_sha256: this.#bundle.sha256,
146
+ actor: { session_id: identity.sessionId, harness: identity.harness, provider_session_id: identity.providerSessionId },
147
+ snapshot_sha256: this.#baseline.sha256, snapshot: this.#baseline.snapshot() };
148
+ // Same bounded snapshot as the RUN baseline; SQL custody is not worker transport.
149
+ const json = JSON.stringify(receipt);
150
+ if (Buffer.byteLength(json) > 33 * 1024 * 1024)
151
+ refuse("unbounded_start_receipt");
152
+ context.db.run("INSERT INTO audit_events(project_id,event_type,payload_json,created_at) VALUES(?,?,?,?)", [projectId, event, json, context.now()]);
153
+ readInteractiveWorkStart(context, this.#scope, this.#bundle, workSessionId);
154
+ }
155
+ }
@@ -1,6 +1,4 @@
1
1
  import crypto from "node:crypto";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
2
  import { spawnSync } from "node:child_process";
5
3
  import { AppError } from "../shared/errors.js";
6
4
  import { appendAudit } from "./audit.js";
@@ -8,6 +6,31 @@ import { requireProjectByRoot } from "./projects.js";
8
6
  import { resolveProjectRoot } from "../storage/paths.js";
9
7
  const defaultTtlSeconds = 300;
10
8
  const defaultPollIntervalSeconds = 10;
9
+ export function prepareLaneWaitTiming(input) {
10
+ return {
11
+ timeoutSeconds: normalizeNonNegativeNumber(input.timeoutSeconds, 0, "timeout"),
12
+ pollIntervalSeconds: normalizePositiveNumber(input.pollIntervalSeconds, defaultPollIntervalSeconds, "poll-interval")
13
+ };
14
+ }
15
+ export function prepareLaneLock(context, input, action) {
16
+ if (typeof input.workerId !== "string" || !input.workerId.trim())
17
+ throw new AppError("validation", "Lane lock requires a nonempty worker ID", 2);
18
+ if (["acquire", "release", "wait-acquire"].includes(action) && (typeof input.reason !== "string" || !input.reason.trim()))
19
+ throw new AppError("validation", "Lane lock requires a nonempty reason", 2);
20
+ if (input.leaseToken !== undefined && (typeof input.leaseToken !== "string" || !input.leaseToken.trim()))
21
+ throw new AppError("validation", "Lease token must be nonempty text", 2);
22
+ const ttlSeconds = normalizePositiveNumber(input.ttlSeconds, defaultTtlSeconds, "ttl");
23
+ const { timeoutSeconds, pollIntervalSeconds } = prepareLaneWaitTiming(input);
24
+ const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
25
+ const lane = normalizeLane(input.lane);
26
+ const workspace = input.workspacePath !== undefined ? requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath) : undefined;
27
+ if (input.workspacePath === undefined && ["acquire", "wait", "wait-acquire"].includes(action))
28
+ throw new AppError("validation", "Lane lock requires a workspace path", 2);
29
+ if (action === "acquire" || action === "wait-acquire")
30
+ assertWorkerMayAcquireLaneLock(context, project.id, lane, input.workerId);
31
+ const lock = action === "heartbeat" || action === "release" ? requireOwnedActiveLock(context, project.id, lane, input.workerId, input.leaseToken) : undefined;
32
+ return { project, lane, ttlSeconds, timeoutSeconds, pollIntervalSeconds, lock, workspace };
33
+ }
11
34
  export function getLaneStatus(context, input) {
12
35
  const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
13
36
  return {
@@ -23,10 +46,16 @@ export function expireProjectLaneLocks(context, projectId) {
23
46
  export function expireProjectLaneWaiters(context, projectId) {
24
47
  expireStaleWaiters(context, projectId);
25
48
  }
26
- export function setLaneWorkspace(context, input) {
49
+ export function prepareLaneWorkspace(context, input) {
50
+ if (input.branch !== undefined && (typeof input.branch !== "string" || !input.branch.trim()))
51
+ throw new AppError("validation", "Expected branch must be nonempty text", 2);
27
52
  const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
28
53
  const lane = normalizeLane(input.lane);
29
54
  const workspacePath = resolveExistingPath(input.workspacePath);
55
+ return { project, lane, workspacePath };
56
+ }
57
+ export function setLaneWorkspace(context, input) {
58
+ const { project, lane, workspacePath } = prepareLaneWorkspace(context, input);
30
59
  const now = context.now();
31
60
  const existing = laneRecord(context, project.id, lane);
32
61
  context.db.run(`INSERT INTO lanes
@@ -69,11 +98,12 @@ export function checkLaneWorkspace(context, input) {
69
98
  };
70
99
  }
71
100
  export function acquireLaneLock(context, input) {
72
- const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
73
- const lane = normalizeLane(input.lane);
74
- requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath);
75
- assertWorkerMayAcquireLaneLock(context, project.id, lane, input.workerId);
76
- const ttlSeconds = normalizePositiveNumber(input.ttlSeconds, defaultTtlSeconds, "ttl");
101
+ const prepared = prepareLaneLock(context, input, "acquire");
102
+ return context.db.writeTransaction(() => acquirePreparedLaneLock(context, input, prepared));
103
+ }
104
+ function acquirePreparedLaneLock(context, input, prepared) {
105
+ const { project, lane, ttlSeconds } = prepared;
106
+ assertPreparedLaneLock(context, prepared, input.workerId);
77
107
  expireStaleLocks(context, project.id);
78
108
  const active = activeLaneLock(context, project.id, lane);
79
109
  if (active) {
@@ -115,14 +145,15 @@ export function acquireLaneLock(context, input) {
115
145
  ...(expired ? { expired_lock_id: expired.id } : {})
116
146
  };
117
147
  }
148
+ function assertPreparedLaneLock(context, prepared, workerId) {
149
+ if (JSON.stringify(laneRecord(context, prepared.project.id, prepared.lane)) !== JSON.stringify(prepared.workspace)
150
+ || context.db.get("SELECT root FROM projects WHERE id = ?", [prepared.project.id])?.root !== prepared.project.root)
151
+ throw new AppError("lane_workspace_changed", "Lane registration changed after workspace preparation", 1);
152
+ assertWorkerMayAcquireLaneLock(context, prepared.project.id, prepared.lane, workerId);
153
+ }
118
154
  export function heartbeatLaneLock(context, input) {
119
- const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
120
- const lane = normalizeLane(input.lane);
121
- if (input.workspacePath) {
122
- requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath);
123
- }
124
- const lock = requireOwnedActiveLock(context, project.id, lane, input.workerId, input.leaseToken);
125
- const ttlSeconds = normalizePositiveNumber(input.ttlSeconds, defaultTtlSeconds, "ttl");
155
+ const { project, lock: preparedLock, ttlSeconds } = prepareLaneLock(context, input, "heartbeat");
156
+ const lock = preparedLock;
126
157
  const now = context.now();
127
158
  context.db.run(`UPDATE lane_locks SET heartbeat_at = ?, expires_at = ?, updated_at = ? WHERE id = ?`, [now, expiresAt(now, ttlSeconds), now, lock.id]);
128
159
  appendAudit(context, {
@@ -133,12 +164,8 @@ export function heartbeatLaneLock(context, input) {
133
164
  return { ok: true, lock: activeLaneLock(context, project.id, lock.lane) };
134
165
  }
135
166
  export function releaseLaneLock(context, input) {
136
- const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
137
- const lane = normalizeLane(input.lane);
138
- if (input.workspacePath) {
139
- requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath);
140
- }
141
- const lock = requireOwnedActiveLock(context, project.id, lane, input.workerId, input.leaseToken);
167
+ const { project, lock: preparedLock } = prepareLaneLock(context, input, "release");
168
+ const lock = preparedLock;
142
169
  const now = context.now();
143
170
  context.db.run(`UPDATE lane_locks
144
171
  SET status = 'released', released_at = ?, reason = ?, updated_at = ?
@@ -152,11 +179,7 @@ export function releaseLaneLock(context, input) {
152
179
  return { ok: true, lock: laneLockById(context, lock.id) };
153
180
  }
154
181
  export async function waitForLaneLock(context, input) {
155
- const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
156
- const lane = normalizeLane(input.lane);
157
- requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath);
158
- const timeoutSeconds = normalizeNonNegativeNumber(input.timeoutSeconds, 0, "timeout");
159
- const pollIntervalSeconds = normalizePositiveNumber(input.pollIntervalSeconds, defaultPollIntervalSeconds, "poll-interval");
182
+ const { project, lane, timeoutSeconds, pollIntervalSeconds } = prepareLaneLock(context, input, "wait");
160
183
  const start = Date.now();
161
184
  while (true) {
162
185
  expireStaleLocks(context, project.id);
@@ -186,13 +209,18 @@ export function getLaneWaiters(context, input) {
186
209
  }))
187
210
  };
188
211
  }
189
- export function cancelLaneWaiter(context, input) {
212
+ export function prepareLaneWaiterCancellation(context, input) {
213
+ if (typeof input.workerId !== "string" || !input.workerId.trim())
214
+ throw new AppError("validation", "Lane waiter requires a nonempty worker ID", 2);
215
+ if (typeof input.reason !== "string" || !input.reason.trim())
216
+ throw new AppError("validation", "lane waiter cancel requires --reason", 2);
190
217
  const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
191
218
  const lane = normalizeLane(input.lane);
192
219
  const reason = input.reason.trim();
193
- if (!reason) {
194
- throw new AppError("validation", "lane waiter cancel requires --reason", 2);
195
- }
220
+ return { project, lane, reason };
221
+ }
222
+ export function cancelLaneWaiter(context, input) {
223
+ const { project, lane, reason } = prepareLaneWaiterCancellation(context, input);
196
224
  expireStaleWaiters(context, project.id);
197
225
  const now = context.now();
198
226
  const waiter = activeLaneWaiterForWorker(context, project.id, lane, input.workerId);
@@ -245,13 +273,7 @@ export function expireLaneWaiterById(context, input) {
245
273
  return { ok: true, expired: result.changes === 1, waiter_id: input.waiterId };
246
274
  }
247
275
  export async function waitAcquireLaneLock(context, input) {
248
- const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
249
- const lane = normalizeLane(input.lane);
250
- requireMatchingLaneWorkspace(context, project.id, lane, input.workspacePath);
251
- assertWorkerMayAcquireLaneLock(context, project.id, lane, input.workerId);
252
- const timeoutSeconds = normalizeNonNegativeNumber(input.timeoutSeconds, 0, "timeout");
253
- const pollIntervalSeconds = normalizePositiveNumber(input.pollIntervalSeconds, defaultPollIntervalSeconds, "poll-interval");
254
- const ttlSeconds = normalizePositiveNumber(input.ttlSeconds, defaultTtlSeconds, "ttl");
276
+ const { project, lane, timeoutSeconds, pollIntervalSeconds, ttlSeconds } = prepareLaneLock(context, input, "wait-acquire");
255
277
  const startedAt = Date.now();
256
278
  const waiterDeadline = timeoutSeconds > 0 ? new Date(startedAt + timeoutSeconds * 1000).toISOString() : null;
257
279
  while (true) {
@@ -375,10 +397,9 @@ function laneWaitersForProject(context, projectId, lane) {
375
397
  LIMIT 100`, [projectId]);
376
398
  }
377
399
  function activeLaneLock(context, projectId, lane) {
378
- expireStaleLocks(context, projectId);
379
400
  return context.db.get(`SELECT * FROM lane_locks
380
- WHERE project_id = ? AND lane = ? AND status = 'active'
381
- ORDER BY updated_at DESC, id DESC LIMIT 1`, [projectId, lane]);
401
+ WHERE project_id = ? AND lane = ? AND status = 'active' AND expires_at > ?
402
+ ORDER BY updated_at DESC, id DESC LIMIT 1`, [projectId, lane, context.now()]);
382
403
  }
383
404
  function activeLaneWaiterForWorker(context, projectId, lane, workerId) {
384
405
  return context.db.get(`SELECT * FROM lane_waiters
@@ -513,13 +534,15 @@ function ensureQueuedLaneWaiter(context, input) {
513
534
  return waiter;
514
535
  }
515
536
  function tryAcquireQueuedLaneLock(context, input) {
516
- expireStaleLocks(context, input.projectId);
517
- expireStaleWaiters(context, input.projectId);
518
- context.db.exec("BEGIN IMMEDIATE");
519
- try {
537
+ const prepared = prepareLaneLock(context, input, "wait-acquire");
538
+ if (prepared.project.id !== input.projectId || prepared.lane !== input.lane)
539
+ throw new AppError("lane_workspace_changed", "Lane identity changed while waiting", 1);
540
+ return context.db.writeTransaction(() => {
541
+ assertPreparedLaneLock(context, prepared, input.workerId);
542
+ expireStaleLocks(context, input.projectId);
543
+ expireStaleWaiters(context, input.projectId);
520
544
  const existingLock = activeLaneLock(context, input.projectId, input.lane);
521
545
  if (existingLock?.worker_id === input.workerId) {
522
- context.db.exec("COMMIT");
523
546
  return {
524
547
  acquired: true,
525
548
  payload: {
@@ -537,7 +560,6 @@ function tryAcquireQueuedLaneLock(context, input) {
537
560
  }
538
561
  const latest = latestLaneWaiterForWorker(context, input.projectId, input.lane, input.workerId);
539
562
  if (latest && ["cancelled", "expired"].includes(latest.status) && latest.updated_at >= input.invocationStartedAt) {
540
- context.db.exec("COMMIT");
541
563
  return {
542
564
  acquired: false,
543
565
  payload: {
@@ -561,14 +583,14 @@ function tryAcquireQueuedLaneLock(context, input) {
561
583
  });
562
584
  const head = firstQueuedLaneWaiter(context, input.projectId, input.lane);
563
585
  if (!existingLock && head?.id === waiter.id) {
564
- const lockResult = acquireLaneLock(context, {
586
+ const lockResult = acquirePreparedLaneLock(context, {
565
587
  projectRoot: input.projectRoot,
566
588
  lane: input.lane,
567
589
  workerId: input.workerId,
568
590
  workspacePath: input.workspacePath,
569
591
  ttlSeconds: input.ttlSeconds,
570
592
  reason: input.reason
571
- });
593
+ }, prepared);
572
594
  const now = context.now();
573
595
  context.db.run(`UPDATE lane_waiters
574
596
  SET status = 'acquired', acquired_at = ?, updated_at = ?
@@ -580,7 +602,6 @@ function tryAcquireQueuedLaneLock(context, input) {
580
602
  reason: input.reason,
581
603
  payload: { project_id: input.projectId, lane: input.lane, worker_id: input.workerId, waiter_id: waiter.id }
582
604
  });
583
- context.db.exec("COMMIT");
584
605
  return {
585
606
  acquired: true,
586
607
  payload: {
@@ -597,7 +618,6 @@ function tryAcquireQueuedLaneLock(context, input) {
597
618
  };
598
619
  }
599
620
  const position = queuedWaiterPosition(context, input.projectId, input.lane, waiter.id);
600
- context.db.exec("COMMIT");
601
621
  return {
602
622
  acquired: false,
603
623
  payload: {
@@ -611,18 +631,10 @@ function tryAcquireQueuedLaneLock(context, input) {
611
631
  position
612
632
  }
613
633
  };
614
- }
615
- catch (error) {
616
- context.db.exec("ROLLBACK");
617
- throw error;
618
- }
634
+ });
619
635
  }
620
636
  function resolveExistingPath(value) {
621
- const absolute = path.resolve(value);
622
- if (!fs.existsSync(absolute)) {
623
- throw new AppError("not_found", `Workspace path does not exist: ${absolute}`, 1);
624
- }
625
- return fs.realpathSync(absolute);
637
+ return resolveProjectRoot(value);
626
638
  }
627
639
  function detectBranch(workspacePath) {
628
640
  const result = spawnSync("git", ["-C", workspacePath, "rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf8" });
@@ -635,7 +647,7 @@ function expiresAt(now, ttlSeconds) {
635
647
  return new Date(new Date(now).getTime() + ttlSeconds * 1000).toISOString();
636
648
  }
637
649
  function normalizeLane(value) {
638
- const normalized = value.trim().toLowerCase();
650
+ const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
639
651
  if (!normalized || !/^[a-z0-9._-]+$/.test(normalized)) {
640
652
  throw new AppError("validation", "Lane name must contain only lowercase letters, numbers, dot, underscore, or hyphen", 2);
641
653
  }
@@ -643,15 +655,16 @@ function normalizeLane(value) {
643
655
  }
644
656
  function normalizePositiveNumber(value, fallback, label) {
645
657
  const normalized = value ?? fallback;
646
- if (!Number.isFinite(normalized) || normalized <= 0) {
647
- throw new AppError("validation", `--${label} must be a positive number`, 2);
658
+ if (!Number.isFinite(normalized) || normalized <= 0 ||
659
+ (label === "poll-interval" ? normalized * 1000 > 2 ** 31 - 1 : !Number.isFinite(new Date(Date.now() + normalized * 1000).getTime()))) {
660
+ throw new AppError("validation", `--${label} must be a positive number within the supported timer/date range`, 2);
648
661
  }
649
662
  return normalized;
650
663
  }
651
664
  function normalizeNonNegativeNumber(value, fallback, label) {
652
665
  const normalized = value ?? fallback;
653
- if (!Number.isFinite(normalized) || normalized < 0) {
654
- throw new AppError("validation", `--${label} must be zero or a positive number`, 2);
666
+ if (!Number.isFinite(normalized) || normalized < 0 || !Number.isFinite(new Date(Date.now() + normalized * 1000).getTime())) {
667
+ throw new AppError("validation", `--${label} must be zero or a positive number within the supported date range`, 2);
655
668
  }
656
669
  return normalized;
657
670
  }