@deksden-com/dd-flow-cli 0.9.0-beta.14 → 0.9.0-beta.140

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 (493) hide show
  1. package/CHANGELOG.md +733 -0
  2. package/README.md +143 -1
  3. package/dist/build-info.json +8 -8
  4. package/dist/cli/argument-values.js +38 -0
  5. package/dist/cli/command-inputs.js +376 -0
  6. package/dist/cli/command-metadata.js +197 -0
  7. package/dist/cli/command-option-descriptions.js +191 -0
  8. package/dist/cli/completion-cli.js +70 -0
  9. package/dist/cli/completion.js +57 -0
  10. package/dist/cli/error-output.js +52 -0
  11. package/dist/cli/executor-onboarding.js +76 -0
  12. package/dist/cli/flows.js +29 -0
  13. package/dist/cli/harnesses.js +84 -0
  14. package/dist/cli/help.js +328 -18
  15. package/dist/cli/hook-ingress.js +78 -0
  16. package/dist/cli/input-preparation.js +165 -0
  17. package/dist/cli/memory-flow-admission.js +44 -0
  18. package/dist/cli/memory-init-invocation.js +78 -0
  19. package/dist/cli/memory-init.js +240 -0
  20. package/dist/cli/memory-storage-admission.js +53 -0
  21. package/dist/cli/models.js +39 -0
  22. package/dist/cli/native-hook-ingress.js +80 -0
  23. package/dist/cli/operator-profiles.js +61 -0
  24. package/dist/cli/output-options.js +35 -0
  25. package/dist/cli/response-file.js +71 -0
  26. package/dist/cli/run-cli.js +1689 -545
  27. package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
  28. package/dist/cli/runtime-maintenance-ingress.js +52 -0
  29. package/dist/cli/runtime-process.js +153 -0
  30. package/dist/cli/setup.js +149 -0
  31. package/dist/cli.js +71 -2
  32. package/dist/domain/stage-catalog.js +1 -1
  33. package/dist/domain/stage-handler-identities.js +20 -0
  34. package/dist/harness-runtime/DD-ZCODE.md +112 -0
  35. package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
  36. package/dist/harness-runtime/bin/dd-agy.mjs +56 -0
  37. package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
  38. package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
  39. package/dist/harness-runtime/bin/dd-grok.mjs +40 -0
  40. package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
  41. package/dist/harness-runtime/bin/dd-zcode.mjs +87 -0
  42. package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
  43. package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
  44. package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
  45. package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
  46. package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
  47. package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
  48. package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
  49. package/dist/harness-runtime/lib/daemon-operations.mjs +371 -0
  50. package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
  51. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +724 -0
  52. package/dist/harness-runtime/lib/dd-agy.mjs +70 -0
  53. package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
  54. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +196 -0
  55. package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
  56. package/dist/harness-runtime/lib/dd-codex.mjs +817 -0
  57. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +129 -0
  58. package/dist/harness-runtime/lib/dd-droid.mjs +584 -0
  59. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +498 -0
  60. package/dist/harness-runtime/lib/dd-grok.mjs +177 -0
  61. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +507 -0
  62. package/dist/harness-runtime/lib/dd-opencode.mjs +354 -0
  63. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +750 -0
  64. package/dist/harness-runtime/lib/dd-zcode.mjs +1145 -0
  65. package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
  66. package/dist/harness-runtime/lib/delegation-instructions.mjs +157 -0
  67. package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
  68. package/dist/harness-runtime/lib/driver-recovery.mjs +139 -0
  69. package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
  70. package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
  71. package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
  72. package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
  73. package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
  74. package/dist/harness-runtime/lib/lifecycle-contract.d.mts +10 -0
  75. package/dist/harness-runtime/lib/lifecycle-contract.mjs +19 -0
  76. package/dist/harness-runtime/lib/managed-daemon.d.mts +13 -0
  77. package/dist/harness-runtime/lib/managed-daemon.mjs +654 -0
  78. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  79. package/dist/harness-runtime/lib/model-observations.mjs +101 -0
  80. package/dist/harness-runtime/lib/native-children.d.mts +16 -0
  81. package/dist/harness-runtime/lib/native-children.mjs +113 -0
  82. package/dist/harness-runtime/lib/native-hook-command.d.mts +7 -0
  83. package/dist/harness-runtime/lib/native-hook-command.mjs +251 -0
  84. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  85. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  86. package/dist/harness-runtime/lib/native-streams.mjs +45 -0
  87. package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
  88. package/dist/harness-runtime/lib/observation-clock.mjs +92 -0
  89. package/dist/harness-runtime/lib/opencode-plugin.mjs +85 -0
  90. package/dist/harness-runtime/lib/operation-context.mjs +5 -0
  91. package/dist/harness-runtime/lib/operation-errors.d.mts +14 -0
  92. package/dist/harness-runtime/lib/operation-errors.mjs +116 -0
  93. package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
  94. package/dist/harness-runtime/lib/operation-progress.mjs +114 -0
  95. package/dist/harness-runtime/lib/process-json.d.mts +5 -0
  96. package/dist/harness-runtime/lib/process-json.mjs +201 -0
  97. package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
  98. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +13 -0
  99. package/dist/harness-runtime/lib/provider-overload-policy.mjs +138 -0
  100. package/dist/harness-runtime/lib/runner-events.mjs +200 -0
  101. package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
  102. package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
  103. package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
  104. package/dist/harness-runtime/lib/setup-progress.mjs +51 -0
  105. package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
  106. package/dist/harness-runtime/lib/tool-observations.mjs +228 -0
  107. package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
  108. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
  109. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
  110. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
  111. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
  112. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
  113. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
  114. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
  115. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
  116. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
  117. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
  118. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
  119. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
  120. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
  121. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
  122. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
  123. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
  124. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
  125. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
  126. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
  127. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
  128. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
  129. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
  130. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
  131. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
  132. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
  133. package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
  134. package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
  135. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
  136. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
  137. package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
  138. package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
  139. package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
  140. package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
  141. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
  142. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
  143. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
  144. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
  145. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
  146. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
  147. package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
  148. package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
  149. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
  150. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
  151. package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
  152. package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
  153. package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
  154. package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
  155. package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
  156. package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
  157. package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
  158. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
  159. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
  160. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
  161. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
  162. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
  163. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
  164. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
  165. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
  166. package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
  167. package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
  168. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
  169. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
  170. package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
  171. package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
  172. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
  173. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
  174. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
  175. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
  176. package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
  177. package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
  178. package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
  179. package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
  180. package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
  181. package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
  182. package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
  183. package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
  184. package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
  185. package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
  186. package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
  187. package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
  188. package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
  189. package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
  190. package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
  191. package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
  192. package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
  193. package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
  194. package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
  195. package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
  196. package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
  197. package/dist/protocol/local-files.js +18 -9
  198. package/dist/runtime/context.js +8 -4
  199. package/dist/schemas/agent-profile.schema.json +1 -1
  200. package/dist/schemas/code-review-result.schema.json +1 -1
  201. package/dist/schemas/code-verification.schema.json +7 -5
  202. package/dist/schemas/code-work-batch.schema.json +2 -2
  203. package/dist/schemas/discovery-result.schema.json +184 -0
  204. package/dist/schemas/execution-bundle.schema.json +205 -0
  205. package/dist/schemas/execution-settings.schema.json +162 -0
  206. package/dist/schemas/flow-descriptor.schema.json +54 -0
  207. package/dist/schemas/flow-run.schema.json +28 -0
  208. package/dist/schemas/harness-catalog.schema.json +80 -0
  209. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  210. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  211. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  212. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  213. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  214. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  215. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  216. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  217. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  218. package/dist/schemas/memory-repair-work-result.schema.json +49 -0
  219. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  220. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  221. package/dist/schemas/model-catalog.schema.json +153 -0
  222. package/dist/schemas/plan-review-decision.schema.json +3 -3
  223. package/dist/schemas/plan-review-result.schema.json +2 -2
  224. package/dist/schemas/profile-settings.schema.json +122 -0
  225. package/dist/schemas/release-manifest.schema.json +291 -0
  226. package/dist/schemas/run-control-receipt.schema.json +118 -0
  227. package/dist/schemas/run-control-request.schema.json +36 -0
  228. package/dist/schemas/run-engine-binding.schema.json +1 -1
  229. package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
  230. package/dist/services/branch-context.js +3 -3
  231. package/dist/services/canon.js +11 -8
  232. package/dist/services/check-runner-evidence.js +168 -0
  233. package/dist/services/cleanup.js +133 -40
  234. package/dist/services/cli-operation-classifier.js +25 -62
  235. package/dist/services/cli-upgrade-allowlist.js +27 -0
  236. package/dist/services/code-checks.js +1156 -107
  237. package/dist/services/codex-hook-delivery.js +32 -0
  238. package/dist/services/command-context.js +80 -0
  239. package/dist/services/compatibility-preflight.js +13 -3
  240. package/dist/services/config.js +11 -8
  241. package/dist/services/continuation-outcome.js +20 -0
  242. package/dist/services/controller-child-capacity.js +13 -0
  243. package/dist/services/controller-child-observer.js +115 -0
  244. package/dist/services/controller-execution.js +88 -0
  245. package/dist/services/controller-fanout.js +202 -0
  246. package/dist/services/dashboard.js +143 -58
  247. package/dist/services/descriptor-coordinator-session.js +35 -0
  248. package/dist/services/descriptor-root-work.js +53 -0
  249. package/dist/services/descriptor-run-settlement.js +105 -0
  250. package/dist/services/descriptor-run-start.js +449 -0
  251. package/dist/services/descriptor-stage-coordinator.js +197 -0
  252. package/dist/services/descriptor-stage-settlement.js +222 -0
  253. package/dist/services/descriptor-stage-start.js +139 -0
  254. package/dist/services/discovery/agy-discovery.js +2 -0
  255. package/dist/services/discovery/codex-discovery.js +2 -0
  256. package/dist/services/discovery/droid-discovery.js +2 -0
  257. package/dist/services/discovery/grok-discovery.js +2 -0
  258. package/dist/services/discovery/opencode-discovery.js +2 -0
  259. package/dist/services/discovery/static.js +31 -0
  260. package/dist/services/discovery/zcode-discovery.js +2 -0
  261. package/dist/services/engines.js +294 -153
  262. package/dist/services/eval-snapshots.js +1215 -116
  263. package/dist/services/execution-bundles.js +263 -0
  264. package/dist/services/execution-policy.js +185 -0
  265. package/dist/services/executor-onboarding.js +56 -0
  266. package/dist/services/external-work-launch.js +308 -0
  267. package/dist/services/flow-catalog.js +21 -0
  268. package/dist/services/flow-descriptors.js +82 -0
  269. package/dist/services/frozen-engine.js +250 -0
  270. package/dist/services/generic-execution.js +164 -0
  271. package/dist/services/harness-adapter.js +355 -36
  272. package/dist/services/harness-config.js +2 -0
  273. package/dist/services/harness-discovery.js +29 -0
  274. package/dist/services/harness-doctor.js +75 -0
  275. package/dist/services/harness-probe-effects.js +51 -0
  276. package/dist/services/harness-version-probe.js +100 -0
  277. package/dist/services/hooks.js +771 -325
  278. package/dist/services/hybrid-contracts.js +483 -0
  279. package/dist/services/ids.js +29 -1
  280. package/dist/services/installation-lock.js +95 -0
  281. package/dist/services/installed-flow-source.js +183 -0
  282. package/dist/services/lanes.js +78 -65
  283. package/dist/services/lifecycle-command.js +1 -288
  284. package/dist/services/lifecycle-contract.js +1 -0
  285. package/dist/services/lifecycle-invocations.js +2007 -0
  286. package/dist/services/managed-daemon-binding.js +38 -0
  287. package/dist/services/managed-lease-monitor.js +133 -0
  288. package/dist/services/managed-processes.js +475 -55
  289. package/dist/services/memory-accepted-composition.js +77 -0
  290. package/dist/services/memory-baseline-preservation.js +65 -0
  291. package/dist/services/memory-completed-correction-wave.js +320 -0
  292. package/dist/services/memory-compose-handler.js +258 -0
  293. package/dist/services/memory-composition-acceptance.js +199 -0
  294. package/dist/services/memory-composition-graph.js +134 -0
  295. package/dist/services/memory-composition-registration.js +146 -0
  296. package/dist/services/memory-composition-work-custody.js +151 -0
  297. package/dist/services/memory-composition-work-results.js +96 -0
  298. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  299. package/dist/services/memory-corrected-review-batch.js +30 -0
  300. package/dist/services/memory-corrected-review-findings.js +106 -0
  301. package/dist/services/memory-corrected-review-inputs.js +210 -0
  302. package/dist/services/memory-corrected-review-projection.js +78 -0
  303. package/dist/services/memory-corrected-review-receipt.js +170 -0
  304. package/dist/services/memory-corrected-review-registration.js +191 -0
  305. package/dist/services/memory-correction-check-receipt.js +219 -0
  306. package/dist/services/memory-correction-input-owner.js +6 -0
  307. package/dist/services/memory-discover-handler.js +104 -0
  308. package/dist/services/memory-finish-evidence.js +435 -0
  309. package/dist/services/memory-finish-handler.js +215 -0
  310. package/dist/services/memory-finish-integration.js +280 -0
  311. package/dist/services/memory-finish-readiness.js +122 -0
  312. package/dist/services/memory-git-integration.js +151 -0
  313. package/dist/services/memory-historical-corrected-review.js +206 -0
  314. package/dist/services/memory-historical-original-review.js +130 -0
  315. package/dist/services/memory-historical-repair-registration.js +99 -0
  316. package/dist/services/memory-historical-second-review.js +128 -0
  317. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  318. package/dist/services/memory-init-contexts.js +89 -0
  319. package/dist/services/memory-init-controller-start.js +84 -0
  320. package/dist/services/memory-init-engine-release.js +223 -0
  321. package/dist/services/memory-init-git-policy.js +136 -0
  322. package/dist/services/memory-init-lint-capability.js +185 -0
  323. package/dist/services/memory-init-native-capacity.js +296 -0
  324. package/dist/services/memory-init-preflight.js +330 -0
  325. package/dist/services/memory-init-project-bootstrap.js +599 -0
  326. package/dist/services/memory-init-request-candidate.js +157 -0
  327. package/dist/services/memory-init-request-input.js +66 -0
  328. package/dist/services/memory-init-resource-storage.js +125 -0
  329. package/dist/services/memory-init-run-allocation.js +81 -0
  330. package/dist/services/memory-init-run-bundle.js +98 -0
  331. package/dist/services/memory-init-start.js +181 -0
  332. package/dist/services/memory-init-startup-custody.js +80 -0
  333. package/dist/services/memory-init-startup-input.js +240 -0
  334. package/dist/services/memory-init-storage.js +81 -0
  335. package/dist/services/memory-init-stores.js +359 -0
  336. package/dist/services/memory-init-worktrunk-capability.js +178 -0
  337. package/dist/services/memory-layer-publication.js +611 -0
  338. package/dist/services/memory-layer.js +156 -0
  339. package/dist/services/memory-lint-config.js +85 -0
  340. package/dist/services/memory-native-review-copy.js +165 -0
  341. package/dist/services/memory-normal-flow-entry.js +75 -0
  342. package/dist/services/memory-ordinary-defaults.js +112 -0
  343. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  344. package/dist/services/memory-preflight-handler.js +259 -0
  345. package/dist/services/memory-repair-current-view.js +299 -0
  346. package/dist/services/memory-repair-document-delta.js +451 -0
  347. package/dist/services/memory-repair-history.js +491 -0
  348. package/dist/services/memory-repair-physical-binding.js +312 -0
  349. package/dist/services/memory-repair-publication-files.js +152 -0
  350. package/dist/services/memory-repair-publication-intent.js +27 -0
  351. package/dist/services/memory-repair-publication-plan.js +160 -0
  352. package/dist/services/memory-repair-publication-source.js +225 -0
  353. package/dist/services/memory-repair-publication.js +794 -0
  354. package/dist/services/memory-repair-registration.js +239 -0
  355. package/dist/services/memory-repair-work-baseline.js +413 -0
  356. package/dist/services/memory-repair-work-completion.js +97 -0
  357. package/dist/services/memory-repair-work-custody.js +73 -0
  358. package/dist/services/memory-repair-work-results.js +89 -0
  359. package/dist/services/memory-repair-workspace.js +252 -0
  360. package/dist/services/memory-repair-writer-copy.js +735 -0
  361. package/dist/services/memory-result-binding.js +173 -0
  362. package/dist/services/memory-retained-review-authority.js +129 -0
  363. package/dist/services/memory-retained-review-results.js +70 -0
  364. package/dist/services/memory-retained-second-baseline.js +102 -0
  365. package/dist/services/memory-retained-second-repairs.js +156 -0
  366. package/dist/services/memory-review-acceptance.js +214 -0
  367. package/dist/services/memory-review-correction-plan.js +171 -0
  368. package/dist/services/memory-review-handler.js +585 -0
  369. package/dist/services/memory-review-inputs.js +200 -0
  370. package/dist/services/memory-review-receipt.js +180 -0
  371. package/dist/services/memory-review-registration.js +108 -0
  372. package/dist/services/memory-review-work-custody.js +124 -0
  373. package/dist/services/memory-review-work-input.js +72 -0
  374. package/dist/services/memory-review-work-results.js +73 -0
  375. package/dist/services/memory-second-corrected-review-inputs.js +165 -0
  376. package/dist/services/memory-second-correction-plan.js +76 -0
  377. package/dist/services/memory-second-repair-baseline.js +91 -0
  378. package/dist/services/memory-second-repair-launch.js +614 -0
  379. package/dist/services/memory-second-repair-registration.js +88 -0
  380. package/dist/services/memory-second-repair-source.js +187 -0
  381. package/dist/services/memory-second-review-acceptance.js +115 -0
  382. package/dist/services/memory-source-observations.js +117 -0
  383. package/dist/services/memory-stage-dispatch.js +28 -0
  384. package/dist/services/memory-stage-results.js +199 -0
  385. package/dist/services/memory-verification-acceptance.js +135 -0
  386. package/dist/services/memory-verification-checks.js +252 -0
  387. package/dist/services/memory-verification-receipt.js +159 -0
  388. package/dist/services/memory-verify-handler.js +135 -0
  389. package/dist/services/memory-work-result-preparation.js +63 -0
  390. package/dist/services/merge-queue.js +228 -149
  391. package/dist/services/merge-server.js +161 -35
  392. package/dist/services/migrations.js +37 -16
  393. package/dist/services/model-catalog.js +109 -0
  394. package/dist/services/model-discovery.js +46 -0
  395. package/dist/services/native-daemon-history.js +49 -0
  396. package/dist/services/native-session-control.js +39 -0
  397. package/dist/services/operator-profiles.js +236 -0
  398. package/dist/services/plan-runtime.js +26 -11
  399. package/dist/services/plans.js +28 -25
  400. package/dist/services/projects.js +37 -17
  401. package/dist/services/prompts.js +28 -17
  402. package/dist/services/protocols.js +163 -87
  403. package/dist/services/provider-capacity.js +385 -0
  404. package/dist/services/recovery-observation-budget.js +121 -0
  405. package/dist/services/recovery-snapshot-database.js +560 -0
  406. package/dist/services/release-archive-producer.js +52 -0
  407. package/dist/services/release-archive.js +143 -0
  408. package/dist/services/release-cache.js +142 -0
  409. package/dist/services/release-compatibility.js +18 -0
  410. package/dist/services/release-download.js +67 -0
  411. package/dist/services/release-envelope.js +104 -0
  412. package/dist/services/release-manifest.js +45 -0
  413. package/dist/services/release-payload.js +114 -0
  414. package/dist/services/release-producer.js +63 -0
  415. package/dist/services/release-provenance.js +160 -0
  416. package/dist/services/release-registry.js +66 -0
  417. package/dist/services/release-source.js +194 -0
  418. package/dist/services/repair-intents.js +42 -0
  419. package/dist/services/review-copy.js +165 -0
  420. package/dist/services/review-deferral.js +23 -0
  421. package/dist/services/run-control-receipt.js +56 -0
  422. package/dist/services/run-control-worker.js +411 -0
  423. package/dist/services/run-control.js +1056 -0
  424. package/dist/services/run-controller-adapter.js +399 -0
  425. package/dist/services/run-controller-capture.js +186 -0
  426. package/dist/services/run-controller-process.js +208 -0
  427. package/dist/services/run-controller-recovery.js +289 -0
  428. package/dist/services/run-controller-state.js +97 -0
  429. package/dist/services/run-controller.js +1205 -0
  430. package/dist/services/run-engine-bindings.js +1 -1
  431. package/dist/services/run-fork.js +147 -0
  432. package/dist/services/run-health.js +149 -0
  433. package/dist/services/run-observations.js +152 -0
  434. package/dist/services/run-projection.js +22 -64
  435. package/dist/services/run-recovery-guard.js +77 -0
  436. package/dist/services/run-recovery-runtime.js +112 -0
  437. package/dist/services/run-recovery.js +489 -0
  438. package/dist/services/run-start-custody.js +177 -0
  439. package/dist/services/runs.js +1019 -247
  440. package/dist/services/runtime-budget.js +430 -0
  441. package/dist/services/runtime-command.js +43 -0
  442. package/dist/services/runtime-scope-capture.js +52 -0
  443. package/dist/services/runtime-scope-control.js +468 -0
  444. package/dist/services/runtime-scope-resume.js +599 -0
  445. package/dist/services/runtime-scope-stop.js +210 -0
  446. package/dist/services/runtime-scope-worker.js +287 -0
  447. package/dist/services/runtime-service.js +96 -0
  448. package/dist/services/schema-validation.js +10 -8
  449. package/dist/services/scope-writer-cleanup.js +27 -0
  450. package/dist/services/sessions.js +35 -69
  451. package/dist/services/setup.js +377 -0
  452. package/dist/services/stage-blocker.js +17 -7
  453. package/dist/services/stage-context.js +193 -19
  454. package/dist/services/stage-handlers.js +74 -0
  455. package/dist/services/stage-lifecycle.js +100 -108
  456. package/dist/services/stage-pause.js +89 -75
  457. package/dist/services/stage-report-renderer.js +234 -6
  458. package/dist/services/stage-work-graph.js +52 -0
  459. package/dist/services/tooling.js +32 -23
  460. package/dist/services/usage.js +49 -101
  461. package/dist/services/verification-matrix.js +374 -0
  462. package/dist/services/vnext-code-review.js +223 -88
  463. package/dist/services/vnext-code.js +327 -226
  464. package/dist/services/vnext-contracts.js +10 -1
  465. package/dist/services/vnext-execution-profile.js +80 -5
  466. package/dist/services/vnext-fanout.js +311 -19
  467. package/dist/services/vnext-merge.js +332 -111
  468. package/dist/services/vnext-plan-review.js +279 -127
  469. package/dist/services/vnext-plan.js +229 -104
  470. package/dist/services/vnext-protocolize.js +411 -86
  471. package/dist/services/vnext-specify.js +119 -81
  472. package/dist/services/vnext-workspace-policy.js +7 -2
  473. package/dist/services/work-registry.js +1627 -199
  474. package/dist/services/workspace-bootstrap.js +52 -15
  475. package/dist/services/workspace-files.js +85 -0
  476. package/dist/services/worktrees.js +98 -44
  477. package/dist/shared/entity-references.js +8 -0
  478. package/dist/shared/errors.js +17 -0
  479. package/dist/storage/agent-output.js +26 -0
  480. package/dist/storage/database.js +891 -39
  481. package/dist/storage/foreign-key-transaction.js +39 -0
  482. package/dist/storage/immutable-input.js +45 -0
  483. package/dist/storage/import-guard.js +102 -0
  484. package/dist/storage/native-cleanup.js +52 -0
  485. package/dist/storage/paths.js +17 -4
  486. package/dist/storage/projection-lock.js +73 -0
  487. package/dist/storage/work-references.js +23 -0
  488. package/dist/storage/writer-contract.js +89 -0
  489. package/dist/storage/writer-migration.js +85 -0
  490. package/package.json +43 -13
  491. package/tools/create-canon-release.mjs +33 -0
  492. package/tools/produce-hybrid-release.mjs +41 -0
  493. package/tools/repair-paused-run-status.mjs +84 -0
@@ -0,0 +1,312 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import { createHash } from "node:crypto";
4
+ import { AppError } from "../shared/errors.js";
5
+ import { appendAudit } from "./audit.js";
6
+ import { hookSessionIdentity } from "./hooks.js";
7
+ import { hybridDigest } from "./hybrid-contracts.js";
8
+ import { runtimeHarness } from "./execution-policy.js";
9
+ import { parseLifecycleCommand, commandPosition } from "./lifecycle-command.js";
10
+ import { resolveWorkReference } from "../storage/work-references.js";
11
+ import { assertRunMutationAllowed } from "./run-recovery-guard.js";
12
+ import { currentLifecycleAdmission } from "./lifecycle-invocations.js";
13
+ import { recoveryGuard } from "./run-recovery-guard.js";
14
+ const event = "memory.repair_native_binding";
15
+ function refuse(reason) {
16
+ throw new AppError("memory_repair_native_binding_invalid", "Native repair requires its actual direct-child Hook and independently owned copy", 1, { reason, effect: "no_effect" });
17
+ }
18
+ /** Preserve raw Hook CWD. A scoped literal shell route becomes physical
19
+ * execution proof only after the CLI independently admitted process.cwd. */
20
+ export function memoryRepairExecutionIdentity(context, input) {
21
+ const reader = { ...context };
22
+ delete reader.observeLifecycleHook;
23
+ const identity = hookSessionIdentity(reader, input.projectId, input.eventKey);
24
+ if (identity.cwd === input.root)
25
+ return { identity, invocationId: null };
26
+ const rows = context.db.all("SELECT id,status,command,scope_json,identity_json FROM lifecycle_invocations WHERE event_key=? AND status IN ('executing','settled') LIMIT 2", [input.eventKey]);
27
+ if (rows.length !== 1)
28
+ refuse("repair_execution_cwd_unproven");
29
+ const row = rows[0];
30
+ try {
31
+ if ([row.command, row.scope_json, row.identity_json].some(value => typeof value !== "string" || Buffer.byteLength(value) > 1024 * 1024))
32
+ refuse("repair_execution_cwd_unproven");
33
+ const scope = JSON.parse(row.scope_json), native = JSON.parse(row.identity_json), parsed = parseLifecycleCommand(row.command);
34
+ const project = context.db.get("SELECT root FROM projects WHERE id=?", [input.projectId]);
35
+ const parent = context.db.get("SELECT provider_session_id FROM sessions WHERE project_id=? AND session_id=? AND run_id=?", [input.projectId, identity.parentSessionId, input.runId]);
36
+ if (parsed.kind === "none" || parsed.supported === false || parsed.invocation.operation !== "work_start"
37
+ || scope.runId !== input.runId || scope.projectRoot !== project?.root || !Array.isArray(native) || native.length !== 6
38
+ || native[0] !== identity.daemonId || scope.daemonId !== identity.daemonId || native[1] !== scope.rootSessionId
39
+ || !parent || native[3] !== parent.provider_session_id || typeof native[4] !== "string" || !native[4]
40
+ || native[2] !== identity.providerSessionId || native[5]?.executionCwd !== input.root)
41
+ refuse("repair_execution_cwd_unproven");
42
+ const target = resolveWorkReference(context, commandPosition(parsed.invocation, 0), { projectId: input.projectId });
43
+ if (target.work_id !== input.workId)
44
+ refuse("repair_execution_cwd_unproven");
45
+ const retained = context.db.get("SELECT 1 FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id JOIN hook_events he ON he.project_id=w.project_id AND he.event_key=ws.hook_event_id WHERE w.project_id=? AND w.run_id=? AND w.work_id=? AND ws.hook_event_id=? AND ws.session_id=? AND he.status='claimed' AND EXISTS (SELECT 1 FROM audit_events a WHERE a.project_id=w.project_id AND a.event_type IN ('memory.repair_work_start','memory.native_review_binding') AND json_extract(a.payload_json,'$.run_id')=w.run_id AND json_extract(a.payload_json,'$.work_id')=w.work_id AND json_extract(a.payload_json,'$.work_session_id')=ws.id AND (a.event_type='memory.repair_work_start' OR json_extract(a.payload_json,'$.invocation_id')=?))", [input.projectId, input.runId, input.workId, input.eventKey, identity.sessionId, row.id]);
46
+ if (!currentLifecycleAdmission(context, row.id) && !retained)
47
+ refuse("repair_execution_cwd_not_admitted");
48
+ return { identity: { ...identity, cwd: input.root }, invocationId: row.id };
49
+ }
50
+ catch (error) {
51
+ if (error instanceof AppError && error.code === "memory_repair_native_binding_invalid")
52
+ throw error;
53
+ return refuse("repair_execution_cwd_unproven");
54
+ }
55
+ }
56
+ /** Hook ingress selects only an independently prepared repair copy. This
57
+ * establishes a command's assigned directory, not claim/repair authority. */
58
+ export function memoryRepairAssignedHookCwd(context, input) {
59
+ const work = context.db.get("SELECT payload_json,result_schema,status FROM works WHERE project_id=? AND run_id=? AND work_id=?", [input.projectId, input.runId, input.workId]);
60
+ let payload;
61
+ try {
62
+ payload = JSON.parse(work?.payload_json ?? "null");
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ if (payload?.kind !== "memory-repair" && work?.result_schema !== "dd-flow/memory-repair-work-result@1")
68
+ return null;
69
+ const run = context.db.get("SELECT r.run_root,r.run_dir,r.flow_kind,p.root AS project_root FROM runs r JOIN projects p ON p.id=r.project_id WHERE r.project_id=? AND r.id=?", [input.projectId, input.runId]);
70
+ if (!run || run.flow_kind !== "mb-init" || run.project_root !== input.projectRoot || payload.read_only !== false
71
+ || ![1, 2].includes(payload.memory_repair?.wave ?? 0) || work?.result_schema !== "dd-flow/memory-repair-work-result@1")
72
+ refuse("registered_memory_repair_required");
73
+ const generation = assertRunMutationAllowed(context, input.projectId, input.runId), runRoot = run.run_root ?? run.run_dir;
74
+ const external = context.db.get("SELECT 1 FROM sqlite_schema WHERE type='table' AND name='work_launches'")
75
+ ? context.db.get("SELECT operation_id,status,profile_json,profile_hash,provider_session_id FROM work_launches WHERE work_id=?", [input.workId]) : undefined;
76
+ const native = !external;
77
+ const admitted = (root) => {
78
+ if (native && input.observedCwd !== root && input.literalExecutionCwd !== root)
79
+ throw new AppError("memory_repair_native_copy_route_unavailable", "Native repair requires a genuinely observed child execution directory inside its owned writer copy", 1, { phase: "prepare", effect: "no_effect", recoverable: false, expected: root, actual: input.observedCwd ?? null,
80
+ next_action: "Use only a documented native child/tool capability that establishes this exact directory; otherwise stop and select external delegation in a new RUN." });
81
+ return { root, native };
82
+ };
83
+ if (work.status === "created") {
84
+ // Routing consumes registered copy custody only. Actual Work start owns
85
+ // physical source/copy/profile admission after the durable native Hook.
86
+ const rows = (eventType) => context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.work_id')=? AND json_extract(payload_json,'$.generation')=? LIMIT 2", [input.projectId, eventType, input.runId, input.workId, generation]);
87
+ const intents = rows("memory.repair_writer_copy_intent"), copies = rows("memory.repair_writer_copy_ready");
88
+ if (intents.length !== 1 || copies.length !== 1 || Buffer.byteLength(intents[0].payload_json) > 1024 * 1024
89
+ || Buffer.byteLength(copies[0].payload_json) > 12 * 1024 * 1024)
90
+ refuse("owned_ready_copy_required");
91
+ try {
92
+ const intent = JSON.parse(intents[0].payload_json), ready = JSON.parse(copies[0].payload_json);
93
+ const workspace_manifest_sha256 = ready.workspace_manifest_sha256, readyIntent = { ...ready };
94
+ delete readyIntent.workspace_manifest_sha256;
95
+ delete readyIntent.workspace_manifest_base64;
96
+ const relative = `works/${input.workId}/writer-workspaces/generation-${generation}`;
97
+ if (intent.schema_id !== "dd-flow/memory-repair-writer-copy-intent@1" || intent.project_id !== input.projectId || intent.run_id !== input.runId
98
+ || intent.work_id !== input.workId || intent.generation !== generation || intent.run_root !== runRoot || !path.isAbsolute(runRoot)
99
+ || intent.copy_relative !== relative || !/^[a-f0-9]{64}$/.test(intent.baseline_registration_sha256)
100
+ || !/^[a-f0-9]{64}$/.test(workspace_manifest_sha256) || hybridDigest(readyIntent) !== hybridDigest(intent))
101
+ refuse("owned_ready_copy_required");
102
+ if (external) {
103
+ if (external.provider_session_id !== input.providerSessionId)
104
+ refuse("foreign_physical_session");
105
+ const profile = JSON.parse(external.profile_json), metadata = profile.memory_repair_copy;
106
+ if (profile.delegation?.mode !== "external" || hybridDigest(metadata) !== hybridDigest({ root: relative, copy_intent_sha256: hybridDigest(intent),
107
+ workspace_manifest_sha256, baseline_registration_sha256: intent.baseline_registration_sha256 }))
108
+ refuse("native_copy_cwd_mismatch");
109
+ }
110
+ if (fs.realpathSync(runRoot) !== path.resolve(runRoot))
111
+ refuse("owned_ready_copy_required");
112
+ let destination = runRoot;
113
+ for (const part of relative.split('/')) {
114
+ destination = path.join(destination, part);
115
+ if (!fs.lstatSync(destination).isDirectory())
116
+ refuse("owned_ready_copy_required");
117
+ }
118
+ return admitted(destination);
119
+ }
120
+ catch (error) {
121
+ if (error instanceof AppError)
122
+ throw error;
123
+ return refuse("owned_ready_copy_required");
124
+ }
125
+ }
126
+ // Running writers retain their committed directory, not today's source bytes.
127
+ let binding = external;
128
+ let nativeStart;
129
+ if (!binding) {
130
+ const rows = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type='memory.repair_native_binding' AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.work_id')=? LIMIT 2", [input.projectId, input.runId, input.workId]);
131
+ if (rows.length !== 1 || Buffer.byteLength(rows[0].payload_json) > 1024 * 1024)
132
+ refuse("native_registered_start_changed");
133
+ try {
134
+ const retained = JSON.parse(rows[0].payload_json);
135
+ if (retained.schema_id !== "dd-flow/memory-repair-native-binding@1" || retained.project_id !== input.projectId || retained.run_id !== input.runId || retained.work_id !== input.workId
136
+ || typeof retained.work_session_id !== "string" || typeof retained.hook_event_key !== "string")
137
+ refuse("native_registered_start_changed");
138
+ binding = retained.binding;
139
+ nativeStart = retained;
140
+ }
141
+ catch (error) {
142
+ if (error instanceof AppError)
143
+ throw error;
144
+ return refuse("native_registered_start_changed");
145
+ }
146
+ }
147
+ const starts = context.db.all("SELECT ws.id,ws.hook_event_id,ws.start_receipt_json FROM work_sessions ws JOIN sessions s ON s.project_id=? AND s.session_id=ws.session_id WHERE ws.work_id=? AND ws.status='running' AND s.run_id=? AND s.worker_id=? AND s.provider_session_id=? LIMIT 2", [input.projectId, input.workId, input.runId, input.workId, input.providerSessionId]);
148
+ if (work.status !== "running" || !binding || binding.provider_session_id !== input.providerSessionId || starts.length !== 1)
149
+ refuse("native_registered_start_changed");
150
+ if (nativeStart && (nativeStart.work_session_id !== starts[0].id || nativeStart.hook_event_key !== starts[0].hook_event_id
151
+ || binding.operation_id !== `native-hook:${nativeStart.hook_event_key}`
152
+ || !context.db.get("SELECT 1 FROM hook_events WHERE project_id=? AND event_key=? AND status='claimed' AND provider_session_id=?", [input.projectId, nativeStart.hook_event_key, input.providerSessionId])))
153
+ refuse("native_registered_start_changed");
154
+ try {
155
+ const text = starts[0].start_receipt_json;
156
+ if (typeof text !== "string" || Buffer.byteLength(text) > 16 * 1024 * 1024)
157
+ refuse("native_registered_start_changed");
158
+ const start = JSON.parse(text), packet = JSON.parse(start.context), profile = JSON.parse(binding.profile_json), metadata = profile.memory_repair_copy;
159
+ if (profile.delegation?.mode !== (native ? "native" : "external") || start.version !== 2 || createHash("sha256").update(start.context).digest("hex") !== start.context_sha256
160
+ || typeof metadata?.root !== "string" || metadata.root !== `works/${input.workId}/writer-workspaces/generation-${start.generation}`
161
+ || packet.work_id !== input.workId || packet.run_id !== input.runId || packet.workspace_root !== path.join(runRoot, metadata.root)
162
+ || packet.memory_repair_input?.provider_session_id !== input.providerSessionId
163
+ || packet.memory_repair_input?.launch_operation_id !== binding.operation_id)
164
+ refuse("native_registered_start_changed");
165
+ return admitted(packet.workspace_root);
166
+ }
167
+ catch (error) {
168
+ if (error instanceof AppError)
169
+ throw error;
170
+ return refuse("native_registered_start_changed");
171
+ }
172
+ }
173
+ /** Native children have no external launch row. Read the immutable physical
174
+ * Hook and copy journal instead; preparation cannot manufacture a Session. */
175
+ export function readMemoryRepairPhysicalBinding(context, workId, route, operationId) {
176
+ const external = context.db.get("SELECT 1 FROM sqlite_schema WHERE type='table' AND name='work_launches'")
177
+ ? context.db.get("SELECT operation_id,status,profile_json,profile_hash,provider_session_id FROM work_launches WHERE work_id=?", [workId]) : undefined;
178
+ if (route.delegation.mode === "external")
179
+ return external;
180
+ if (external)
181
+ refuse("native_work_has_external_launch");
182
+ const work = context.db.get("SELECT project_id,run_id,parent_work_id FROM works WHERE work_id=?", [workId]);
183
+ if (!work?.parent_work_id)
184
+ refuse("owned_native_work_required");
185
+ const run = context.db.get("SELECT run_root,run_dir FROM runs WHERE project_id=? AND id=?", [work.project_id, work.run_id]);
186
+ if (!run)
187
+ refuse("owned_native_run_required");
188
+ const retained = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.work_id')=? LIMIT 2", [work.project_id, event, work.run_id, workId]);
189
+ let prior;
190
+ if (retained.length) {
191
+ try {
192
+ if (retained.length !== 1 || Buffer.byteLength(retained[0].payload_json) > 1024 * 1024)
193
+ refuse("ambiguous_native_binding");
194
+ prior = JSON.parse(retained[0].payload_json);
195
+ if (!prior || prior.schema_id !== "dd-flow/memory-repair-native-binding@1" || prior.project_id !== work.project_id
196
+ || prior.run_id !== work.run_id || prior.work_id !== workId || typeof prior.work_session_id !== "string"
197
+ || !prior.work_session_id || Object.keys(prior).sort().join(",") !== "binding,hook_event_key,parent_provider_session_id,parent_session_id,project_id,run_id,schema_id,work_id,work_session_id")
198
+ refuse("foreign_native_binding");
199
+ }
200
+ catch (error) {
201
+ if (error instanceof AppError)
202
+ throw error;
203
+ refuse("invalid_native_binding");
204
+ }
205
+ }
206
+ const key = prior?.hook_event_key ?? (operationId?.startsWith("native-hook:") ? operationId.slice(12) : context.env.DD_FLOW_MEMORY_REPAIR_HOOK_EVENT);
207
+ if (!key || key.length > 1024)
208
+ refuse("native_start_hook_required");
209
+ const reader = { ...context };
210
+ delete reader.observeLifecycleHook;
211
+ let identity;
212
+ try {
213
+ identity = hookSessionIdentity(reader, work.project_id, key);
214
+ }
215
+ catch (error) {
216
+ if (error instanceof AppError && error.code === "hook_event_not_found")
217
+ refuse("native_start_hook_required");
218
+ throw error;
219
+ }
220
+ const hook = context.db.get("SELECT status,created_at FROM hook_events WHERE project_id=? AND event_key=? AND id=? AND event_name='PreToolUse'", [work.project_id, key, identity.hookEventId]);
221
+ const parents = context.db.all("SELECT DISTINCT s.session_id,s.harness,s.status,s.current_stage,s.run_id,s.worker_id,s.provider_session_id FROM work_sessions ws JOIN sessions s ON s.project_id=? AND s.session_id=ws.session_id WHERE ws.work_id=? AND s.session_id=? LIMIT 2", [work.project_id, work.parent_work_id, identity.parentSessionId]);
222
+ if (!hook || !["observed", "claimed"].includes(hook.status) || parents.length !== 1)
223
+ refuse("native_parent_or_hook_required");
224
+ const parent = parents[0];
225
+ if (parent.run_id !== work.run_id || !prior && parent.worker_id !== work.parent_work_id || parent.harness !== runtimeHarness(route.coordinator)
226
+ || identity.parentSessionId !== parent.session_id || identity.sessionId === parent.session_id
227
+ || identity.harness !== runtimeHarness(route.worker) || identity.model !== route.worker.model
228
+ || identity.provider && identity.provider !== route.worker.provider)
229
+ refuse("native_route_or_parent_mismatch");
230
+ 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 w.work_id<>? AND s.harness=? AND s.provider_session_id=? LIMIT 1", [work.project_id, work.run_id, workId, identity.harness, identity.providerSessionId]))
231
+ refuse("native_repair_session_not_fresh");
232
+ let freshnessAt = context.now();
233
+ const currentId = context.env.DD_FLOW_CURRENT_INVOCATION;
234
+ const admission = currentId ? currentLifecycleAdmission(context, currentId) : null;
235
+ if (admission) {
236
+ const project = context.db.get("SELECT root FROM projects WHERE id=?", [work.project_id]);
237
+ const attempt = context.db.get("SELECT event_key,scope_json,command FROM lifecycle_invocations WHERE id=?", [currentId]);
238
+ if (attempt?.event_key === key) {
239
+ const scope = JSON.parse(attempt.scope_json), parsed = parseLifecycleCommand(attempt.command);
240
+ if (scope.runId !== work.run_id || scope.projectRoot !== project?.root
241
+ || scope.generation !== (recoveryGuard(context, work.project_id, work.run_id)?.generation ?? 0))
242
+ refuse("native_invocation_scope_changed");
243
+ if (parsed.kind !== "none" && parsed.supported !== false
244
+ && parsed.invocation.operation === "work_start"
245
+ && resolveWorkReference(context, commandPosition(parsed.invocation, 0), { projectId: work.project_id }).work_id === workId)
246
+ freshnessAt = admission.admittedAt;
247
+ }
248
+ }
249
+ if (!prior && (parent.status !== "active" || parent.current_stage !== "review" || Date.parse(hook.created_at) < Date.parse(freshnessAt) - 60_000
250
+ || Date.parse(hook.created_at) > Date.parse(freshnessAt) || Date.parse(freshnessAt) > Date.parse(context.now())
251
+ || !Number.isFinite(Date.parse(hook.created_at))))
252
+ refuse("native_hook_or_parent_not_current");
253
+ if (prior && (hook.status !== "claimed" || !context.db.get("SELECT 1 FROM work_sessions ws JOIN sessions s ON s.project_id=? AND s.session_id=ws.session_id WHERE ws.id=? AND ws.work_id=? AND ws.hook_event_id=? AND ws.session_id=? AND s.run_id=? AND s.worker_id=? AND s.provider_session_id=? AND s.provider_parent_session_id=?", [work.project_id, prior.work_session_id, workId, key, identity.sessionId, work.run_id, workId, identity.providerSessionId, parent.session_id])))
254
+ refuse("native_registered_start_changed");
255
+ const copies = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type='memory.repair_writer_copy_ready' AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.work_id')=? LIMIT 2", [work.project_id, work.run_id, workId]);
256
+ if (copies.length !== 1 || Buffer.byteLength(copies[0].payload_json) > 12 * 1024 * 1024)
257
+ refuse("owned_ready_copy_required");
258
+ let copy;
259
+ let intent;
260
+ try {
261
+ const value = JSON.parse(copies[0].payload_json), workspace_manifest_sha256 = value.workspace_manifest_sha256;
262
+ delete value.workspace_manifest_sha256;
263
+ delete value.workspace_manifest_base64;
264
+ copy = { ...value, workspace_manifest_sha256 };
265
+ intent = value;
266
+ if (value.schema_id !== "dd-flow/memory-repair-writer-copy-intent@1" || value.project_id !== work.project_id
267
+ || value.run_id !== work.run_id || value.work_id !== workId || !Number.isSafeInteger(value.generation) || value.generation < 0
268
+ || !path.isAbsolute(value.run_root) || value.run_root !== (run.run_root ?? run.run_dir)
269
+ || value.copy_relative !== `works/${workId}/writer-workspaces/generation-${value.generation}`
270
+ || !/^[a-f0-9]{64}$/.test(workspace_manifest_sha256) || !/^[a-f0-9]{64}$/.test(value.baseline_registration_sha256))
271
+ refuse("foreign_ready_copy");
272
+ }
273
+ catch (error) {
274
+ if (error instanceof AppError)
275
+ throw error;
276
+ return refuse("invalid_ready_copy");
277
+ }
278
+ const physical = memoryRepairExecutionIdentity(context, { projectId: work.project_id, runId: work.run_id,
279
+ workId, eventKey: key, root: path.join(copy.run_root, copy.copy_relative) });
280
+ const frozen = { coordinator: route.coordinator, worker: route.worker, delegation: { mode: "native", max_parallel: null } };
281
+ const binding = { operation_id: `native-hook:${key}`, status: "start_requested",
282
+ profile_json: JSON.stringify({ ...frozen, memory_repair_copy: { root: copy.copy_relative,
283
+ copy_intent_sha256: hybridDigest(intent), workspace_manifest_sha256: copy.workspace_manifest_sha256,
284
+ baseline_registration_sha256: copy.baseline_registration_sha256 },
285
+ ...(physical.invocationId ? { native_execution_cwd: { invocation_id: physical.invocationId, root: physical.identity.cwd } } : {}) }),
286
+ profile_hash: createHash("sha256").update(JSON.stringify(frozen)).digest("hex"), provider_session_id: identity.providerSessionId };
287
+ if (prior && (prior.parent_session_id !== parent.session_id || prior.parent_provider_session_id !== parent.provider_session_id
288
+ || hybridDigest(prior.binding) !== hybridDigest(binding)))
289
+ refuse("native_binding_changed");
290
+ return binding;
291
+ }
292
+ /** Commit only inside the same writer that claimed the Hook and inserted
293
+ * the physical WorkSession; rollback removes both authorities together. */
294
+ export function recordMemoryRepairNativeBinding(context, workId, route, binding, workSessionId) {
295
+ if (route.delegation.mode !== "native")
296
+ return;
297
+ if (context.db.isOwnedWriteTransaction?.() !== true)
298
+ refuse("owned_claim_writer_required");
299
+ const actual = readMemoryRepairPhysicalBinding(context, workId, route, binding.operation_id);
300
+ const key = binding.operation_id.slice(12);
301
+ const row = context.db.get("SELECT w.project_id,w.run_id,he.parent_session_id,p.provider_session_id AS parent_provider_session_id FROM works w JOIN work_sessions ws ON ws.work_id=w.work_id JOIN hook_events he ON he.project_id=w.project_id AND he.event_key=ws.hook_event_id AND he.session_id=ws.session_id JOIN sessions p ON p.project_id=w.project_id AND p.session_id=he.parent_session_id WHERE w.work_id=? AND ws.id=? AND ws.status='running' AND he.status='claimed' AND he.event_key=? AND he.provider_session_id=?", [workId, workSessionId, key, binding.provider_session_id]);
302
+ if (!row || hybridDigest(actual) !== hybridDigest(binding))
303
+ refuse("native_claim_identity_changed");
304
+ const payload = { schema_id: "dd-flow/memory-repair-native-binding@1", project_id: row.project_id, run_id: row.run_id,
305
+ work_id: workId, work_session_id: workSessionId, parent_session_id: row.parent_session_id,
306
+ parent_provider_session_id: row.parent_provider_session_id, hook_event_key: key, binding };
307
+ const prior = context.db.get("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.work_id')=?", [row.project_id, event, row.run_id, workId]);
308
+ if (prior && hybridDigest(JSON.parse(prior.payload_json)) !== hybridDigest(payload))
309
+ refuse("native_binding_changed");
310
+ if (!prior)
311
+ appendAudit(context, { projectId: row.project_id, eventType: event, payload });
312
+ }
@@ -0,0 +1,152 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { AppError } from "../shared/errors.js";
5
+ function refuse(reason) {
6
+ throw new AppError("memory_repair_staging_invalid", "Publication staging file is not the owned exact output prefix", 1, { reason, effect: "no_effect" });
7
+ }
8
+ const noFollow = (fs.constants.O_NOFOLLOW ?? 0) | (fs.constants.O_NONBLOCK ?? 0);
9
+ function regular(stat, limit) {
10
+ if (!stat.isFile() || stat.nlink !== 1 || stat.size > limit)
11
+ refuse("linked_special_or_oversized_staging_file");
12
+ }
13
+ function same(left, right) {
14
+ return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mode === right.mode
15
+ && left.nlink === right.nlink && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
16
+ }
17
+ /** Read-only verification after independently retained readiness. Unlike staging
18
+ * recovery, a ready file is never repaired if it becomes missing or partial.
19
+ */
20
+ export function verifyRetainedMemoryRepairFile(file, value, mode) {
21
+ if (!(value instanceof Uint8Array) || value.byteLength > 16 * 1024 * 1024)
22
+ refuse("invalid_ready_bytes");
23
+ const before = fs.lstatSync(file);
24
+ regular(before, value.byteLength);
25
+ if (before.size !== value.byteLength || (before.mode & 0o7777) !== mode)
26
+ refuse("ready_staging_file_changed");
27
+ const fd = fs.openSync(file, fs.constants.O_RDONLY | noFollow);
28
+ try {
29
+ if (!same(before, fs.fstatSync(fd)))
30
+ refuse("staging_identity_changed");
31
+ const bytes = Buffer.alloc(value.byteLength);
32
+ let offset = 0;
33
+ while (offset < bytes.length) {
34
+ const count = fs.readSync(fd, bytes, offset, bytes.length - offset, offset);
35
+ if (!count)
36
+ refuse("ready_staging_file_changed");
37
+ offset += count;
38
+ }
39
+ if (!bytes.equals(Buffer.from(value)) || !same(before, fs.fstatSync(fd)) || !same(before, fs.lstatSync(file)))
40
+ refuse("ready_staging_file_changed");
41
+ }
42
+ finally {
43
+ fs.closeSync(fd);
44
+ }
45
+ }
46
+ /** Low-level staging effects only. The publication owner must independently
47
+ * journal this exact directory/slot before calling. This function grants no
48
+ * SQL/Session authority and never changes an MB destination. Unknown existing
49
+ * bytes are preserved; an owned exact partial file is completed by append.
50
+ */
51
+ export function stageRetainedMemoryRepairFile(directory, slot, value, mode) {
52
+ if (!path.isAbsolute(directory) || fs.realpathSync(directory) !== path.resolve(directory)
53
+ || !fs.lstatSync(directory).isDirectory() || (fs.lstatSync(directory).mode & 0o7777) !== 0o700
54
+ || !/^action-[0-9]{1,6}\.tmp$/.test(slot) || !(value instanceof Uint8Array) || value.byteLength > 16 * 1024 * 1024
55
+ || !Number.isInteger(mode) || mode < 0 || mode > 0o7777)
56
+ refuse("invalid_staging_binding");
57
+ const directoryIdentity = fs.lstatSync(directory);
58
+ const bytes = Buffer.from(value), file = path.join(directory, slot);
59
+ let fd, changed = false, initialSize = 0, replayed = false;
60
+ try {
61
+ const prior = fs.lstatSync(file, { throwIfNoEntry: false });
62
+ if (prior) {
63
+ replayed = true;
64
+ regular(prior, bytes.length);
65
+ if ((prior.mode & 0o7777) !== 0o600 && (prior.size !== bytes.length || (prior.mode & 0o7777) !== mode))
66
+ refuse("staging_mode_changed");
67
+ fd = fs.openSync(file, fs.constants.O_RDONLY | noFollow);
68
+ if (!same(prior, fs.fstatSync(fd)))
69
+ refuse("staging_identity_changed");
70
+ }
71
+ else {
72
+ fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_CREAT | fs.constants.O_EXCL | noFollow, 0o600);
73
+ changed = true;
74
+ }
75
+ const before = fs.fstatSync(fd);
76
+ regular(before, bytes.length);
77
+ initialSize = before.size;
78
+ const retained = Buffer.alloc(initialSize);
79
+ let read = 0;
80
+ while (read < retained.length) {
81
+ const count = fs.readSync(fd, retained, read, retained.length - read, read);
82
+ if (!count)
83
+ refuse("staging_changed_during_read");
84
+ read += count;
85
+ }
86
+ if (!same(before, fs.fstatSync(fd)) || !retained.equals(bytes.subarray(0, initialSize)))
87
+ refuse("unknown_staging_bytes");
88
+ if (initialSize < bytes.length && replayed) {
89
+ fs.closeSync(fd);
90
+ fd = undefined;
91
+ fd = fs.openSync(file, fs.constants.O_RDWR | noFollow);
92
+ if (!same(before, fs.fstatSync(fd)))
93
+ refuse("staging_identity_changed");
94
+ }
95
+ let written = initialSize;
96
+ while (written < bytes.length) {
97
+ changed = true;
98
+ const count = fs.writeSync(fd, bytes, written, bytes.length - written, written);
99
+ if (!count)
100
+ throw new Error("No progress writing retained staging bytes");
101
+ written += count;
102
+ }
103
+ if ((fs.fstatSync(fd).mode & 0o7777) !== mode) {
104
+ changed = true;
105
+ fs.fchmodSync(fd, mode);
106
+ }
107
+ fs.fsyncSync(fd);
108
+ const after = fs.fstatSync(fd);
109
+ regular(after, bytes.length);
110
+ if ((after.mode & 0o7777) !== mode)
111
+ refuse("staging_final_mode_changed");
112
+ if (after.size !== bytes.length)
113
+ refuse("staging_identity_changed");
114
+ const verified = Buffer.alloc(bytes.length);
115
+ let checked = 0;
116
+ while (checked < verified.length) {
117
+ const count = fs.readSync(fd, verified, checked, verified.length - checked, checked);
118
+ if (!count)
119
+ refuse("staging_changed_during_read");
120
+ checked += count;
121
+ }
122
+ if (!verified.equals(bytes) || !same(after, fs.fstatSync(fd)))
123
+ refuse("staging_output_changed");
124
+ const named = fs.lstatSync(file);
125
+ if (after.size !== bytes.length || !same(after, named))
126
+ refuse("staging_identity_changed");
127
+ fs.closeSync(fd);
128
+ fd = undefined;
129
+ const parent = fs.openSync(directory, fs.constants.O_RDONLY | noFollow);
130
+ try {
131
+ const current = fs.fstatSync(parent), namedDirectory = fs.lstatSync(directory);
132
+ if (!current.isDirectory() || current.dev !== directoryIdentity.dev || current.ino !== directoryIdentity.ino
133
+ || current.dev !== namedDirectory.dev || current.ino !== namedDirectory.ino || (current.mode & 0o7777) !== 0o700)
134
+ refuse("staging_directory_changed");
135
+ fs.fsyncSync(parent);
136
+ }
137
+ finally {
138
+ fs.closeSync(parent);
139
+ }
140
+ return { path: file, sha256: createHash("sha256").update(bytes).digest("hex"), status: "ready", replayed,
141
+ bytes_appended: bytes.length - initialSize };
142
+ }
143
+ catch (error) {
144
+ if (!changed && error instanceof AppError)
145
+ throw error;
146
+ throw new AppError("memory_repair_staging_pending", "Owned staging output remains pending; preserve it for exact-prefix reconciliation", 1, { effect: "publication_pending", path: file, cause: error instanceof Error ? error.message : String(error) });
147
+ }
148
+ finally {
149
+ if (fd !== undefined)
150
+ fs.closeSync(fd);
151
+ }
152
+ }
@@ -0,0 +1,27 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { hybridDigest } from "./hybrid-contracts.js";
3
+ import { RetainedMemoryRepairPublicationPlan } from "./memory-repair-publication-plan.js";
4
+ /** Metadata decoding only: no start, source, Session or publication authority.
5
+ * v1 is never promoted to v2 by optional caller fields. */
6
+ export function retainedMemoryRepairPublicationPlans(receipt) {
7
+ if (!receipt || typeof receipt !== "object" || Array.isArray(receipt)) {
8
+ throw new AppError("memory_repair_publication_invalid", "Retained publication intent must be an object", 1, { reason: "invalid_retained_intent_shape", effect: "no_effect" });
9
+ }
10
+ const fields = ["schema_id", "project_id", "run_id", "work_id", "generation", "work_session_id", "source_root", "private_root", "output_sha256",
11
+ "start_receipt_sha256", "result_sha256", "result_base64", "delta_sha256", "transition_sha256", "before_sha256", "before_base64", "after_sha256", "after_base64", "actions"];
12
+ const current = receipt.schema_id === "dd-flow/memory-repair-publication-intent@2";
13
+ if (current)
14
+ fields.push("source_view_sha256", "source_receipt_sha256", "private_plan_sha256", "private_plan");
15
+ if ((!current && receipt.schema_id !== "dd-flow/memory-repair-publication-intent@1")
16
+ || Object.keys(receipt).sort().join(",") !== fields.sort().join(",")
17
+ || current && (!receipt.private_plan || typeof receipt.private_plan !== "object" || Array.isArray(receipt.private_plan)
18
+ || [receipt.source_view_sha256, receipt.source_receipt_sha256, receipt.private_plan_sha256].some(value => typeof value !== "string" || !/^[a-f0-9]{64}$/.test(value)))
19
+ || Buffer.byteLength(JSON.stringify(receipt)) > 160 * 1024 * 1024) {
20
+ throw new AppError("memory_repair_publication_invalid", "Retained publication intent has a foreign version or shape", 1, { reason: "invalid_retained_intent_shape", effect: "no_effect" });
21
+ }
22
+ const retained = { before_sha256: receipt.before_sha256, before_base64: receipt.before_base64,
23
+ after_sha256: receipt.after_sha256, after_base64: receipt.after_base64, actions: receipt.actions };
24
+ const plan = RetainedMemoryRepairPublicationPlan.restore(Buffer.from(JSON.stringify(retained)), hybridDigest(retained));
25
+ const privatePlan = current ? RetainedMemoryRepairPublicationPlan.restore(Buffer.from(JSON.stringify(receipt.private_plan)), receipt.private_plan_sha256) : plan;
26
+ return { current, plan, privatePlan };
27
+ }