@deksden-com/dd-flow-cli 0.9.0-beta.15 → 0.9.0-beta.151

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 (560) hide show
  1. package/CHANGELOG.md +907 -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 +386 -0
  6. package/dist/cli/command-metadata.js +232 -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/diagnostic-invocation.js +46 -0
  11. package/dist/cli/diagnostic.js +120 -0
  12. package/dist/cli/error-output.js +52 -0
  13. package/dist/cli/executor-onboarding.js +76 -0
  14. package/dist/cli/flows.js +29 -0
  15. package/dist/cli/harnesses.js +84 -0
  16. package/dist/cli/help.js +396 -19
  17. package/dist/cli/hook-ingress.js +102 -0
  18. package/dist/cli/input-preparation.js +165 -0
  19. package/dist/cli/memory-flow-admission.js +50 -0
  20. package/dist/cli/memory-init-invocation.js +85 -0
  21. package/dist/cli/memory-init.js +249 -0
  22. package/dist/cli/memory-storage-admission.js +54 -0
  23. package/dist/cli/memory-storage-qualification.js +105 -0
  24. package/dist/cli/memory-storage-transition.js +123 -0
  25. package/dist/cli/memory-upgrade.js +189 -0
  26. package/dist/cli/models.js +39 -0
  27. package/dist/cli/native-hook-ingress.js +90 -0
  28. package/dist/cli/native-hook-preparation.js +55 -0
  29. package/dist/cli/operator-profiles.js +61 -0
  30. package/dist/cli/output-options.js +35 -0
  31. package/dist/cli/response-file.js +72 -0
  32. package/dist/cli/run-cli.js +1734 -550
  33. package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
  34. package/dist/cli/runtime-maintenance-ingress.js +52 -0
  35. package/dist/cli/runtime-process.js +153 -0
  36. package/dist/cli/setup.js +150 -0
  37. package/dist/cli.js +89 -2
  38. package/dist/domain/diagnostic-aspects.js +103 -0
  39. package/dist/domain/diagnostic-flows.js +8 -0
  40. package/dist/domain/stage-catalog.js +1 -1
  41. package/dist/domain/stage-handler-identities.js +28 -0
  42. package/dist/harness-runtime/DD-ZCODE.md +112 -0
  43. package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
  44. package/dist/harness-runtime/bin/dd-agy.mjs +56 -0
  45. package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
  46. package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
  47. package/dist/harness-runtime/bin/dd-grok.mjs +40 -0
  48. package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
  49. package/dist/harness-runtime/bin/dd-zcode.mjs +87 -0
  50. package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
  51. package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
  52. package/dist/harness-runtime/lib/agy-error-boundary.mjs +79 -0
  53. package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
  54. package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
  55. package/dist/harness-runtime/lib/agy-native-inspection.mjs +216 -0
  56. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  57. package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +67 -0
  58. package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
  59. package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
  60. package/dist/harness-runtime/lib/daemon-operations.d.mts +2 -0
  61. package/dist/harness-runtime/lib/daemon-operations.mjs +462 -0
  62. package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
  63. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1092 -0
  64. package/dist/harness-runtime/lib/dd-agy.mjs +86 -0
  65. package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
  66. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +231 -0
  67. package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
  68. package/dist/harness-runtime/lib/dd-codex.mjs +954 -0
  69. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +141 -0
  70. package/dist/harness-runtime/lib/dd-droid.mjs +626 -0
  71. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +555 -0
  72. package/dist/harness-runtime/lib/dd-grok.mjs +180 -0
  73. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +627 -0
  74. package/dist/harness-runtime/lib/dd-opencode.mjs +390 -0
  75. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +752 -0
  76. package/dist/harness-runtime/lib/dd-zcode.mjs +1200 -0
  77. package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
  78. package/dist/harness-runtime/lib/delegation-instructions.mjs +166 -0
  79. package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
  80. package/dist/harness-runtime/lib/driver-recovery.mjs +140 -0
  81. package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
  82. package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
  83. package/dist/harness-runtime/lib/entity-references.mjs +9 -0
  84. package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
  85. package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
  86. package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
  87. package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
  88. package/dist/harness-runtime/lib/lifecycle-contract.d.mts +10 -0
  89. package/dist/harness-runtime/lib/lifecycle-contract.mjs +19 -0
  90. package/dist/harness-runtime/lib/managed-daemon.d.mts +16 -0
  91. package/dist/harness-runtime/lib/managed-daemon.mjs +698 -0
  92. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  93. package/dist/harness-runtime/lib/model-observations.mjs +113 -0
  94. package/dist/harness-runtime/lib/native-children.d.mts +34 -0
  95. package/dist/harness-runtime/lib/native-children.mjs +265 -0
  96. package/dist/harness-runtime/lib/native-hook-command.d.mts +7 -0
  97. package/dist/harness-runtime/lib/native-hook-command.mjs +251 -0
  98. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  99. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  100. package/dist/harness-runtime/lib/native-streams.mjs +45 -0
  101. package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
  102. package/dist/harness-runtime/lib/observation-clock.mjs +95 -0
  103. package/dist/harness-runtime/lib/opencode-plugin.mjs +85 -0
  104. package/dist/harness-runtime/lib/operation-context.mjs +5 -0
  105. package/dist/harness-runtime/lib/operation-errors.d.mts +16 -0
  106. package/dist/harness-runtime/lib/operation-errors.mjs +127 -0
  107. package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
  108. package/dist/harness-runtime/lib/operation-progress.mjs +114 -0
  109. package/dist/harness-runtime/lib/process-json.d.mts +5 -0
  110. package/dist/harness-runtime/lib/process-json.mjs +201 -0
  111. package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
  112. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +23 -0
  113. package/dist/harness-runtime/lib/provider-overload-policy.mjs +242 -0
  114. package/dist/harness-runtime/lib/runner-events.mjs +202 -0
  115. package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
  116. package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
  117. package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
  118. package/dist/harness-runtime/lib/setup-progress.mjs +53 -0
  119. package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
  120. package/dist/harness-runtime/lib/tool-observations.mjs +228 -0
  121. package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
  122. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
  123. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
  124. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
  125. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
  126. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
  127. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
  128. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
  129. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
  130. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
  131. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
  132. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
  133. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
  134. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
  135. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
  136. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
  137. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
  138. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
  139. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
  140. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
  141. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
  142. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
  143. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
  144. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
  145. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
  146. package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
  147. package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
  148. package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
  149. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
  150. package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
  151. package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
  152. package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
  153. package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
  154. package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
  155. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
  156. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
  157. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
  158. package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
  159. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
  160. package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
  161. package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
  162. package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
  163. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
  164. package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
  165. package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
  166. package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
  167. package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
  168. package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
  169. package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
  170. package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
  171. package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
  172. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
  173. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
  174. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
  175. package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
  176. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
  177. package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
  178. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
  179. package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
  180. package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
  181. package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
  182. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
  183. package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
  184. package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
  185. package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
  186. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
  187. package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
  188. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
  189. package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
  190. package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
  191. package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
  192. package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
  193. package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
  194. package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
  195. package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
  196. package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
  197. package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
  198. package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
  199. package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
  200. package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
  201. package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
  202. package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
  203. package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
  204. package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
  205. package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
  206. package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
  207. package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
  208. package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
  209. package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
  210. package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
  211. package/dist/protocol/local-files.js +18 -9
  212. package/dist/runtime/context.js +8 -4
  213. package/dist/schemas/agent-profile.schema.json +1 -1
  214. package/dist/schemas/code-review-decision.schema.json +9 -0
  215. package/dist/schemas/code-review-result.schema.json +1 -1
  216. package/dist/schemas/code-verification.schema.json +7 -5
  217. package/dist/schemas/code-work-batch.schema.json +2 -2
  218. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  219. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  220. package/dist/schemas/discovery-result.schema.json +184 -0
  221. package/dist/schemas/execution-bundle.schema.json +211 -0
  222. package/dist/schemas/execution-settings.schema.json +162 -0
  223. package/dist/schemas/flow-descriptor.schema.json +54 -0
  224. package/dist/schemas/flow-run.schema.json +29 -0
  225. package/dist/schemas/harness-catalog.schema.json +80 -0
  226. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  227. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  228. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  229. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  230. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  231. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  232. package/dist/schemas/mb-upgrade-stage-result.schema.json +863 -0
  233. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  234. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  235. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  236. package/dist/schemas/memory-repair-work-result.schema.json +56 -0
  237. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  238. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  239. package/dist/schemas/model-catalog.schema.json +153 -0
  240. package/dist/schemas/plan-review-decision.schema.json +12 -3
  241. package/dist/schemas/plan-review-result.schema.json +2 -2
  242. package/dist/schemas/profile-settings.schema.json +122 -0
  243. package/dist/schemas/project-flow-pack-manifest.schema.json +1 -1
  244. package/dist/schemas/release-impact.schema.json +3 -3
  245. package/dist/schemas/release-manifest.schema.json +291 -0
  246. package/dist/schemas/run-control-receipt.schema.json +118 -0
  247. package/dist/schemas/run-control-request.schema.json +36 -0
  248. package/dist/schemas/run-engine-binding.schema.json +1 -1
  249. package/dist/schemas/stage-start-response.schema.json +4 -0
  250. package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
  251. package/dist/services/accepted-intent.js +139 -0
  252. package/dist/services/branch-context.js +3 -3
  253. package/dist/services/canon.js +54 -15
  254. package/dist/services/check-environment.js +21 -0
  255. package/dist/services/check-runner-evidence.js +277 -0
  256. package/dist/services/check-runner-proof.js +305 -0
  257. package/dist/services/cleanup.js +133 -40
  258. package/dist/services/cli-operation-classifier.js +26 -63
  259. package/dist/services/cli-upgrade-allowlist.js +27 -0
  260. package/dist/services/code-checks.js +1401 -119
  261. package/dist/services/codex-hook-delivery.js +32 -0
  262. package/dist/services/command-context.js +80 -0
  263. package/dist/services/compatibility-preflight.js +16 -3
  264. package/dist/services/config.js +11 -8
  265. package/dist/services/continuation-outcome.js +20 -0
  266. package/dist/services/controller-child-capacity.js +71 -0
  267. package/dist/services/controller-child-observer.js +121 -0
  268. package/dist/services/controller-execution.js +94 -0
  269. package/dist/services/controller-fanout.js +226 -0
  270. package/dist/services/controller-memory-task.js +45 -0
  271. package/dist/services/controller-memory-worker.js +49 -0
  272. package/dist/services/dashboard.js +143 -58
  273. package/dist/services/descriptor-coordinator-session.js +35 -0
  274. package/dist/services/descriptor-root-work.js +53 -0
  275. package/dist/services/descriptor-run-settlement.js +107 -0
  276. package/dist/services/descriptor-run-start.js +475 -0
  277. package/dist/services/descriptor-stage-coordinator.js +250 -0
  278. package/dist/services/descriptor-stage-settlement.js +223 -0
  279. package/dist/services/descriptor-stage-start.js +175 -0
  280. package/dist/services/diagnostic-evidence.js +73 -0
  281. package/dist/services/diagnostic-report-publication.js +72 -0
  282. package/dist/services/diagnostic-report.js +67 -0
  283. package/dist/services/diagnostic-run-bundle.js +74 -0
  284. package/dist/services/diagnostic-snapshot.js +159 -0
  285. package/dist/services/diagnostic-stage-handlers.js +108 -0
  286. package/dist/services/diagnostic-stage-results.js +132 -0
  287. package/dist/services/diagnostic-start.js +84 -0
  288. package/dist/services/diagnostic-work-batch.js +34 -0
  289. package/dist/services/diagnostic-work-collection.js +97 -0
  290. package/dist/services/diagnostic-work-registration.js +101 -0
  291. package/dist/services/diagnostic-work-results.js +93 -0
  292. package/dist/services/discovery/agy-discovery.js +2 -0
  293. package/dist/services/discovery/codex-discovery.js +2 -0
  294. package/dist/services/discovery/droid-discovery.js +2 -0
  295. package/dist/services/discovery/grok-discovery.js +2 -0
  296. package/dist/services/discovery/opencode-discovery.js +2 -0
  297. package/dist/services/discovery/static.js +31 -0
  298. package/dist/services/discovery/zcode-discovery.js +2 -0
  299. package/dist/services/engines.js +354 -163
  300. package/dist/services/eval-snapshots.js +1316 -150
  301. package/dist/services/execution-bundles.js +275 -0
  302. package/dist/services/execution-policy.js +185 -0
  303. package/dist/services/executor-onboarding.js +56 -0
  304. package/dist/services/external-work-launch.js +310 -0
  305. package/dist/services/flow-catalog.js +30 -0
  306. package/dist/services/flow-descriptors.js +82 -0
  307. package/dist/services/frozen-engine.js +387 -0
  308. package/dist/services/generic-execution.js +164 -0
  309. package/dist/services/harness-adapter.js +355 -36
  310. package/dist/services/harness-config.js +2 -0
  311. package/dist/services/harness-discovery.js +29 -0
  312. package/dist/services/harness-doctor.js +75 -0
  313. package/dist/services/harness-probe-effects.js +51 -0
  314. package/dist/services/harness-version-probe.js +100 -0
  315. package/dist/services/hook-memory-routing.js +188 -0
  316. package/dist/services/hook-recovery-guard.js +14 -0
  317. package/dist/services/hook-session-observation.js +24 -0
  318. package/dist/services/hooks.js +791 -326
  319. package/dist/services/hybrid-contracts.js +474 -0
  320. package/dist/services/hybrid-digest.js +14 -0
  321. package/dist/services/ids.js +29 -1
  322. package/dist/services/installation-lock.js +95 -0
  323. package/dist/services/installed-flow-source.js +226 -0
  324. package/dist/services/lanes.js +78 -65
  325. package/dist/services/lifecycle-command.js +1 -288
  326. package/dist/services/lifecycle-contract.js +1 -0
  327. package/dist/services/lifecycle-invocations.js +2148 -0
  328. package/dist/services/managed-daemon-binding.js +38 -0
  329. package/dist/services/managed-lease-monitor.js +133 -0
  330. package/dist/services/managed-processes.js +449 -69
  331. package/dist/services/memory-accepted-composition.js +78 -0
  332. package/dist/services/memory-baseline-preservation.js +65 -0
  333. package/dist/services/memory-completed-correction-wave.js +328 -0
  334. package/dist/services/memory-compose-handler.js +400 -0
  335. package/dist/services/memory-composition-acceptance.js +375 -0
  336. package/dist/services/memory-composition-graph.js +165 -0
  337. package/dist/services/memory-composition-registration.js +161 -0
  338. package/dist/services/memory-composition-work-custody.js +156 -0
  339. package/dist/services/memory-composition-work-results.js +108 -0
  340. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  341. package/dist/services/memory-corrected-review-batch.js +37 -0
  342. package/dist/services/memory-corrected-review-findings.js +108 -0
  343. package/dist/services/memory-corrected-review-inputs.js +215 -0
  344. package/dist/services/memory-corrected-review-projection.js +78 -0
  345. package/dist/services/memory-corrected-review-receipt.js +178 -0
  346. package/dist/services/memory-corrected-review-registration.js +192 -0
  347. package/dist/services/memory-correction-check-receipt.js +235 -0
  348. package/dist/services/memory-correction-input-owner.js +6 -0
  349. package/dist/services/memory-custody-snapshot.js +36 -0
  350. package/dist/services/memory-discover-handler.js +104 -0
  351. package/dist/services/memory-finish-evidence.js +457 -0
  352. package/dist/services/memory-finish-handler.js +229 -0
  353. package/dist/services/memory-finish-integration.js +450 -0
  354. package/dist/services/memory-finish-readiness.js +169 -0
  355. package/dist/services/memory-git-integration.js +220 -0
  356. package/dist/services/memory-historical-corrected-review.js +212 -0
  357. package/dist/services/memory-historical-original-review.js +143 -0
  358. package/dist/services/memory-historical-repair-registration.js +105 -0
  359. package/dist/services/memory-historical-second-review.js +147 -0
  360. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  361. package/dist/services/memory-init-contexts.js +131 -0
  362. package/dist/services/memory-init-controller-start.js +103 -0
  363. package/dist/services/memory-init-engine-release.js +223 -0
  364. package/dist/services/memory-init-git-policy.js +165 -0
  365. package/dist/services/memory-init-lint-capability.js +203 -0
  366. package/dist/services/memory-init-native-capacity.js +309 -0
  367. package/dist/services/memory-init-preflight.js +334 -0
  368. package/dist/services/memory-init-project-bootstrap.js +599 -0
  369. package/dist/services/memory-init-request-candidate.js +213 -0
  370. package/dist/services/memory-init-request-input.js +82 -0
  371. package/dist/services/memory-init-resource-storage.js +125 -0
  372. package/dist/services/memory-init-run-allocation.js +81 -0
  373. package/dist/services/memory-init-run-bundle.js +135 -0
  374. package/dist/services/memory-init-start.js +181 -0
  375. package/dist/services/memory-init-startup-custody.js +80 -0
  376. package/dist/services/memory-init-startup-input.js +240 -0
  377. package/dist/services/memory-init-storage.js +91 -0
  378. package/dist/services/memory-init-stores.js +359 -0
  379. package/dist/services/memory-init-worktrunk-capability.js +174 -0
  380. package/dist/services/memory-layer-publication.js +611 -0
  381. package/dist/services/memory-layer.js +221 -0
  382. package/dist/services/memory-lint-config.js +194 -0
  383. package/dist/services/memory-native-review-copy.js +103 -0
  384. package/dist/services/memory-normal-flow-entry.js +87 -0
  385. package/dist/services/memory-ordinary-defaults.js +129 -0
  386. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  387. package/dist/services/memory-preflight-handler.js +274 -0
  388. package/dist/services/memory-repair-current-view.js +299 -0
  389. package/dist/services/memory-repair-document-delta.js +488 -0
  390. package/dist/services/memory-repair-history.js +496 -0
  391. package/dist/services/memory-repair-physical-binding.js +194 -0
  392. package/dist/services/memory-repair-publication-files.js +152 -0
  393. package/dist/services/memory-repair-publication-intent.js +27 -0
  394. package/dist/services/memory-repair-publication-plan.js +162 -0
  395. package/dist/services/memory-repair-publication-source.js +225 -0
  396. package/dist/services/memory-repair-publication.js +795 -0
  397. package/dist/services/memory-repair-registration.js +240 -0
  398. package/dist/services/memory-repair-work-baseline.js +415 -0
  399. package/dist/services/memory-repair-work-completion.js +117 -0
  400. package/dist/services/memory-repair-work-custody.js +73 -0
  401. package/dist/services/memory-repair-work-results.js +108 -0
  402. package/dist/services/memory-repair-workspace.js +261 -0
  403. package/dist/services/memory-repair-writer-copy.js +736 -0
  404. package/dist/services/memory-result-binding.js +239 -0
  405. package/dist/services/memory-retained-review-authority.js +138 -0
  406. package/dist/services/memory-retained-review-results.js +70 -0
  407. package/dist/services/memory-retained-second-baseline.js +102 -0
  408. package/dist/services/memory-retained-second-repairs.js +162 -0
  409. package/dist/services/memory-review-acceptance.js +214 -0
  410. package/dist/services/memory-review-correction-plan.js +206 -0
  411. package/dist/services/memory-review-handler.js +585 -0
  412. package/dist/services/memory-review-inputs.js +246 -0
  413. package/dist/services/memory-review-limits.js +10 -0
  414. package/dist/services/memory-review-receipt.js +180 -0
  415. package/dist/services/memory-review-registration.js +117 -0
  416. package/dist/services/memory-review-work-custody.js +126 -0
  417. package/dist/services/memory-review-work-input.js +91 -0
  418. package/dist/services/memory-review-work-results.js +95 -0
  419. package/dist/services/memory-second-corrected-review-inputs.js +167 -0
  420. package/dist/services/memory-second-correction-plan.js +77 -0
  421. package/dist/services/memory-second-repair-baseline.js +91 -0
  422. package/dist/services/memory-second-repair-launch.js +614 -0
  423. package/dist/services/memory-second-repair-registration.js +88 -0
  424. package/dist/services/memory-second-repair-source.js +187 -0
  425. package/dist/services/memory-second-review-acceptance.js +115 -0
  426. package/dist/services/memory-source-observations.js +117 -0
  427. package/dist/services/memory-stage-dispatch.js +65 -0
  428. package/dist/services/memory-stage-results.js +290 -0
  429. package/dist/services/memory-tool-probe.js +25 -0
  430. package/dist/services/memory-upgrade-analysis-handler.js +243 -0
  431. package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
  432. package/dist/services/memory-upgrade-evidence.js +100 -0
  433. package/dist/services/memory-upgrade-inventory.js +442 -0
  434. package/dist/services/memory-upgrade-publication-custody.js +73 -0
  435. package/dist/services/memory-upgrade-publication.js +413 -0
  436. package/dist/services/memory-upgrade-selection.js +430 -0
  437. package/dist/services/memory-upgrade-start.js +60 -0
  438. package/dist/services/memory-upgrade-storage-readiness.js +340 -0
  439. package/dist/services/memory-verification-acceptance.js +156 -0
  440. package/dist/services/memory-verification-checks.js +317 -0
  441. package/dist/services/memory-verification-receipt.js +160 -0
  442. package/dist/services/memory-verify-handler.js +137 -0
  443. package/dist/services/memory-work-result-json.js +12 -0
  444. package/dist/services/memory-work-result-preparation.js +64 -0
  445. package/dist/services/merge-queue.js +228 -149
  446. package/dist/services/merge-server.js +163 -35
  447. package/dist/services/migrations.js +164 -114
  448. package/dist/services/model-catalog.js +109 -0
  449. package/dist/services/model-discovery.js +46 -0
  450. package/dist/services/native-daemon-history.js +50 -0
  451. package/dist/services/native-session-control.js +39 -0
  452. package/dist/services/operator-profiles.js +236 -0
  453. package/dist/services/physical-startup.js +45 -0
  454. package/dist/services/plan-runtime.js +26 -11
  455. package/dist/services/plans.js +28 -25
  456. package/dist/services/project-registry.js +97 -0
  457. package/dist/services/project-summary.js +1 -1
  458. package/dist/services/projects.js +17 -87
  459. package/dist/services/prompt-delivery.js +71 -0
  460. package/dist/services/prompts.js +28 -17
  461. package/dist/services/protocols.js +163 -87
  462. package/dist/services/provider-capacity.js +463 -0
  463. package/dist/services/recovery-observation-budget.js +121 -0
  464. package/dist/services/recovery-snapshot-database.js +588 -0
  465. package/dist/services/release-archive-producer.js +52 -0
  466. package/dist/services/release-archive.js +143 -0
  467. package/dist/services/release-cache.js +150 -0
  468. package/dist/services/release-compatibility.js +18 -0
  469. package/dist/services/release-download.js +67 -0
  470. package/dist/services/release-envelope.js +104 -0
  471. package/dist/services/release-manifest.js +45 -0
  472. package/dist/services/release-payload.js +114 -0
  473. package/dist/services/release-producer.js +63 -0
  474. package/dist/services/release-provenance.js +160 -0
  475. package/dist/services/release-registry.js +66 -0
  476. package/dist/services/release-source.js +194 -0
  477. package/dist/services/repair-intents.js +31 -0
  478. package/dist/services/repair-receipt.js +13 -0
  479. package/dist/services/review-copy.js +165 -0
  480. package/dist/services/review-deferral.js +23 -0
  481. package/dist/services/run-control-receipt.js +56 -0
  482. package/dist/services/run-control-worker.js +428 -0
  483. package/dist/services/run-control.js +1092 -0
  484. package/dist/services/run-controller-adapter.js +400 -0
  485. package/dist/services/run-controller-capture.js +186 -0
  486. package/dist/services/run-controller-process.js +205 -0
  487. package/dist/services/run-controller-recovery.js +295 -0
  488. package/dist/services/run-controller-state.js +97 -0
  489. package/dist/services/run-controller.js +1395 -0
  490. package/dist/services/run-engine-bindings.js +1 -1
  491. package/dist/services/run-fork.js +147 -0
  492. package/dist/services/run-health.js +149 -0
  493. package/dist/services/run-observations.js +152 -0
  494. package/dist/services/run-projection.js +22 -64
  495. package/dist/services/run-recovery-guard.js +107 -0
  496. package/dist/services/run-recovery-runtime.js +112 -0
  497. package/dist/services/run-recovery.js +456 -0
  498. package/dist/services/run-start-custody.js +189 -0
  499. package/dist/services/runs.js +1023 -246
  500. package/dist/services/runtime-budget.js +446 -0
  501. package/dist/services/runtime-command.js +43 -0
  502. package/dist/services/runtime-scope-capture.js +52 -0
  503. package/dist/services/runtime-scope-control.js +468 -0
  504. package/dist/services/runtime-scope-resume.js +605 -0
  505. package/dist/services/runtime-scope-stop.js +211 -0
  506. package/dist/services/runtime-scope-worker.js +314 -0
  507. package/dist/services/runtime-service.js +19 -14
  508. package/dist/services/schema-validation.js +10 -8
  509. package/dist/services/scope-writer-cleanup.js +27 -0
  510. package/dist/services/sessions.js +36 -91
  511. package/dist/services/setup.js +427 -0
  512. package/dist/services/stage-blocker.js +17 -7
  513. package/dist/services/stage-context.js +240 -18
  514. package/dist/services/stage-handlers.js +89 -0
  515. package/dist/services/stage-lifecycle.js +152 -116
  516. package/dist/services/stage-pause.js +202 -91
  517. package/dist/services/stage-report-renderer.js +234 -6
  518. package/dist/services/stage-work-graph.js +52 -0
  519. package/dist/services/tooling.js +41 -30
  520. package/dist/services/usage.js +49 -101
  521. package/dist/services/verification-matrix.js +393 -0
  522. package/dist/services/version-status.js +1 -1
  523. package/dist/services/vnext-code-review.js +235 -88
  524. package/dist/services/vnext-code.js +327 -226
  525. package/dist/services/vnext-contracts.js +10 -1
  526. package/dist/services/vnext-execution-profile.js +80 -5
  527. package/dist/services/vnext-fanout.js +355 -21
  528. package/dist/services/vnext-merge.js +332 -111
  529. package/dist/services/vnext-plan-review.js +287 -132
  530. package/dist/services/vnext-plan.js +228 -104
  531. package/dist/services/vnext-protocolize.js +533 -95
  532. package/dist/services/vnext-specify.js +123 -81
  533. package/dist/services/vnext-workspace-policy.js +7 -2
  534. package/dist/services/work-registry.js +1706 -200
  535. package/dist/services/workspace-bootstrap.js +53 -15
  536. package/dist/services/workspace-files.js +85 -0
  537. package/dist/services/worktrees.js +105 -48
  538. package/dist/shared/entity-references.js +1 -0
  539. package/dist/shared/errors.js +27 -0
  540. package/dist/storage/agent-output.js +26 -0
  541. package/dist/storage/data-preservation.js +65 -0
  542. package/dist/storage/database.js +930 -40
  543. package/dist/storage/foreign-key-transaction.js +39 -0
  544. package/dist/storage/immutable-input.js +45 -0
  545. package/dist/storage/import-guard.js +159 -0
  546. package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
  547. package/dist/storage/native-cleanup.js +52 -0
  548. package/dist/storage/paired-writer-migration.js +424 -0
  549. package/dist/storage/paths.js +17 -4
  550. package/dist/storage/projection-lock.js +73 -0
  551. package/dist/storage/work-references.js +23 -0
  552. package/dist/storage/writer-contract.js +96 -0
  553. package/dist/storage/writer-migration.js +346 -0
  554. package/dist/storage/writer-restore.js +217 -0
  555. package/dist/verification-components.json +299 -0
  556. package/package.json +51 -13
  557. package/tools/create-canon-release.mjs +33 -0
  558. package/tools/probe-codex-history.mjs +37 -0
  559. package/tools/produce-hybrid-release.mjs +41 -0
  560. package/tools/repair-paused-run-status.mjs +84 -0
@@ -0,0 +1,14 @@
1
+ export type DelegationWork = { work_id: string; start_command: string; launch_policy?: string };
2
+ export type DelegationInput = { harness: string; stage: string; capacity: number; works?: DelegationWork[]; totalWorks?: number; remainingWorks?: number };
3
+ export function delegationAdapter(harness: string): string | null;
4
+ export function renderNativeChildFollowupInstruction(harness: string, childId: string | { session_id?: unknown; parent_session_id?: unknown; terminal_turn_id?: unknown; continuation_ref?: unknown }): string | null;
5
+ export function delegationContract(harness: string): string;
6
+ export const lifecycleRetryInstruction: string;
7
+ export const lifecycleCommandCompletionInstruction: string;
8
+ export const stageLifecycleInstruction: string;
9
+ export function workerDelegationTask(input: { workId: string; startCommand: string; launchPolicy?: string }): string;
10
+ export function renderDelegationInstructions(input: DelegationInput): string;
11
+ export function renderCapacityInstructions(input: { harness: string; maximum: number }): string;
12
+ export function renderWaitInstructions(input: { harness: string; stage: string }): string;
13
+ export function renderAdapterPolicy(input: { harness: string }): string;
14
+ export function renderRecoveryProbeInstructions(input: { harness: string; command: string }): string;
@@ -0,0 +1,166 @@
1
+ const ADAPTERS = {
2
+ codex: {
3
+ name: "Codex",
4
+ launch: "This Session uses the Codex multi-agent v2 API in the `collaboration` namespace. In code mode call `tools.collaboration__spawn_agent` once per assignment with exactly `task_name`, `message`, and `fork_turns: \"none\"` for fresh context. Keep the current model and reasoning by omitting overrides. Do not create a root Session or run the child's command yourself.",
5
+ wait: "The spawn result is a handle, not completion. In code mode use `tools.collaboration__wait_agent` and native completion messages until every launched child is terminal. A mailbox update is not necessarily final. A wait timeout leaves the same child running: continue waiting without relaunch or interruption. Retain terminal results and product Work receipts. Codex v2 owns idle-agent residency; do not interrupt a completed child as cleanup.",
6
+ partial: "If a spawn is refused, stop issuing new spawns and retain every successful child handle. Wait for every already-launched child to become terminal; silence is not completion. Do not interrupt a running child to free capacity, and do not interrupt completed children as cleanup. Report completed/launched assignments, assignments not launched and the exact refusal. Return after this partial wave; the controller will issue remaining Work when capacity is available. Do not replay an ambiguous spawn."
7
+ },
8
+ zcode: {
9
+ name: "ZCode",
10
+ launch: "Use the native `Agent` tool for every assignment in this current session. Use `TaskOutput` (or the tool's native wait operation) to await the returned child; never call a shell, create a new root session, or ask a child to create descendants.",
11
+ wait: "Wait on the returned native Agent task handles with `TaskOutput` (or the native wait operation) until all direct children settle. A missing or quiet result is not permission to launch a replacement.",
12
+ },
13
+ droid: {
14
+ name: "Droid",
15
+ launch: "Use the native `Task` tool for every assignment with `subagent_type: \"dd-flow-worker\"` and no complexity override. Do not use Missions, a root Session, or a shell command as a delegation substitute.",
16
+ wait: "Wait for each native Task result. Do not interrupt or replace a quiet Task; the coordinator remains responsible for the Stage.",
17
+ },
18
+ grok: {
19
+ name: "Grok",
20
+ launch: "Use the native `spawn_subagent` tool for each assignment in this current session. Keep the returned child handles and wait with `get_command_or_subagent_output`; do not invoke external roots or shell-based substitutes.",
21
+ wait: "Use `get_command_or_subagent_output` for every returned child handle before continuing. Never infer completion from silence or replace an unavailable child.",
22
+ },
23
+ opencode: {
24
+ name: "OpenCode",
25
+ launch: "Use OpenCode v2's native `subagent` tool with agent: \"dd-flow-worker\", description, and prompt containing the assignment. Omit sessionID for a fresh child and omit model overrides. For independent fanout assignments use background: true. Do not create a new root Session or use an external runner. Use `shell` with explicit workdir and timeout: 0 for issued lifecycle calls, never background those CLI calls.",
26
+ wait: "Await each native subagent result or its automatic background completion notification. Retain the real returned sessionID. Do not invent a wait tool or poll by sending child prompts. Native notifications can continue the parent automatically; a running tool handle is not completion. Never synthesize a Session ID or relaunch a quiet child."
27
+ },
28
+ antigravity: {
29
+ name: "Antigravity",
30
+ launch: "Use the harness's native subagent action in this current conversation for each assignment. Do not create a root Session, use an external runner, or ask a child to create descendants; the adapter will observe the native `subagent_info.subagents` records.",
31
+ wait: "Wait for the native child result and let the adapter observe its conversation ID and terminal status. Never invent or synthesize IDs, infer completion from text, or replace a quiet child.",
32
+ }
33
+ };
34
+
35
+ export function delegationAdapter(harness) {
36
+ const aliases = { codex: "codex", "codex-desktop": "codex", zcode: "zcode", "zcode-acp": "zcode", droid: "droid", "droid-cli": "droid", grok: "grok", "grok-acp": "grok", opencode: "opencode", "opencode-server": "opencode", agy: "antigravity", antigravity: "antigravity", "antigravity-cli": "antigravity" };
37
+ return Object.hasOwn(aliases, harness) ? aliases[harness] : null;
38
+ }
39
+
40
+ /** Only documented same-child APIs may continue an existing native worker. */
41
+ export function renderNativeChildFollowupInstruction(harness, childId) {
42
+ const child = childId && typeof childId === "object" ? childId : null;
43
+ childId = child?.session_id ?? childId;
44
+ if (typeof childId !== "string" || !childId) return null;
45
+ const adapter = delegationAdapter(harness), target = JSON.stringify(childId);
46
+ const message = JSON.stringify("Continue the same assigned Work after the transient provider failure; do not restart it or repeat committed lifecycle commands.");
47
+ if (adapter === "zcode") {
48
+ const ref = child?.continuation_ref;
49
+ if (ref?.schema_id !== "zcode/child-continuation@1" || ref.capability !== "dd-flow/managed-provider-recovery@1" || ref.child_session_id !== childId
50
+ || ref.parent_session_id !== child.parent_session_id || ref.terminal_turn_id !== child.terminal_turn_id || !/^agent_[\w-]{1,200}$/.test(ref.agent_id ?? "")) return null;
51
+ return `Use the native SendMessage tool exactly once with to: ${JSON.stringify(ref.agent_id)}, summary: "Continue existing Work", and message: ${message}. Retain messageId and delivery only when the native result supplies them; never invent missing IDs. The adapter verifies typed native completion and successor evidence. Wait for this same agent with TaskOutput. If admission is uncertain, do not resend. Do not spawn a replacement or override model/reasoning.`;
52
+ }
53
+ if (adapter === "codex") return `Use collaboration.followup_task with target: ${target} and message: ${message}. Do not spawn a replacement.`;
54
+ if (adapter === "opencode") return `Use the native subagent tool with sessionID: ${target} and prompt: ${message}. Keep the same model and reasoning. Do not spawn a replacement.`;
55
+ if (adapter === "droid") return `Use the native Task tool with resume: ${target}, subagent_type: "dd-flow-worker", and prompt: ${message}. Omit model and complexity overrides. Do not spawn a replacement.`;
56
+ if (adapter === "grok") return `Use the native send_subagent_message tool with subagent_id: ${target}, delivery: "queue", and text: ${message}. Retain its accepted message_id and wait on the same subagent. If admission is uncertain, do not resend. Do not spawn a replacement.`;
57
+ return null;
58
+ }
59
+
60
+ function requireAdapter(harness) {
61
+ const key = delegationAdapter(harness);
62
+ if (!key) throw Object.assign(new Error(`Unsupported delegation adapter: ${harness}`), { code: "delegation_contract_unsupported" });
63
+ return ADAPTERS[key];
64
+ }
65
+
66
+ export function delegationContract(harness) {
67
+ const key = delegationAdapter(harness);
68
+ requireAdapter(harness);
69
+ return `dd-flow/delegation/${key}@${["codex", "opencode"].includes(key) ? 2 : 1}`;
70
+ }
71
+
72
+ export const lifecycleCommandCompletionInstruction = "Run runtime-issued lifecycle CLI calls in the foreground, never with a native background or detached-shell option. A shell tool may yield before the lifecycle process exits. Retain and poll its exact process/session handle to completion, including inside a tool wrapper; empty interim output is not a CLI result. If a wrapper returns 'Script running with cell ID …', use that wrapper's wait tool to finish the same cell before expecting an inner shell session handle; do not execute the command again. Read final stdout or response_file before deciding continuation, and never reissue the command while it is pending. When the result provides prompt_delivery, read its complete plain Markdown file at prompt_delivery.path before working; it contains the current instructions, unlike the historical prompt_path. If delivery publication is pending, stop for reconciliation without repeating the accepted command.";
73
+
74
+ export const lifecycleRetryInstruction = `${lifecycleCommandCompletionInstruction} A failure is not permission to replay a lifecycle command. For proven effect=no_effect with recoverable=true and retry_command, correct the input and execute that exact issued successor. A check failure can retain receipts while leaving Work running: correct the evidenced cause first, then use the CLI's exact retry_command for an intentional fresh check attempt; never replay a check merely because Work is unsettled. If a successful CODE finish returns outcome=verification_required, inspect the retained receipts, update its verification file, and use only next.finish_command: the Stage is still running and the previous invocation ID is consumed. If continuation.kind=repair_required, or a successful result has outcome=repair_required and a repair Work ID, end this Turn for the registered repair child; use any retry_command only after that repair settles and verification is refreshed. Unknown effects require reconciliation, never replay. A committed effect without an explicit continuation is not retryable. A native shell launch refusal before the CLI starts permits correcting only that shell-form error and retrying the same exact command. Otherwise report the primary error and stop; never invent IDs, call hooks directly, or run status as a substitute.`;
75
+
76
+ export const stageLifecycleInstruction = [
77
+ "The project root identifies this RUN; use the Stage packet's declared execution workspace and absolute artifact paths. Do not change a native Session's working directory to a workspace provisioned for a later Stage.",
78
+ "In a controller-managed fanout, the coordinator ends the entry Turn after the Work graph is returned; the controller dispatches children. A completed child or Work is not Stage success: settle the declared graph and Stage gate before finishing.",
79
+ "Execute each runtime-issued lifecycle operation and its arguments exactly. One literal lifecycle call may be composed with ordinary shell commands; preserve conditions, stdin and redirects, and never replay the surrounding shell chain after failure. Invocation IDs are internal authority; never add, copy or invent one.",
80
+ lifecycleRetryInstruction
81
+ ].join(" ");
82
+
83
+ export function workerDelegationTask({ workId, startCommand, launchPolicy }) {
84
+ if (!workId || !startCommand) throw new Error("ready fan-out Work lacks its exact start command");
85
+ const context = launchPolicy === "fresh_agent_required"
86
+ ? "You are the already-selected fresh leaf worker for this Work. Execute its lifecycle start yourself; do not delegate it to another child."
87
+ : "You are the already-selected worker. Execute this Work yourself; do not delegate it to another child.";
88
+ return [
89
+ `Complete one already-declared Work: ${workId}.`,
90
+ context,
91
+ "Your first technical action must be this exact lifecycle command:",
92
+ startCommand,
93
+ "Execute the issued operation and target exactly. Lifecycle invocation IDs are internal runtime authority and are intentionally omitted; never add or invent them. Preserve any explicit native receipt handle that the command does contain.",
94
+ startCommand.startsWith("cd '")
95
+ ? "Execute the literal cd shell prefix exactly; it routes this command into its runtime-owned private execution copy. Do not invent native spawn fields. After start, obey the packet's read_only/write scopes and prefix subsequent issued lifecycle commands with the same literal cd route. A review copy never grants permission to write reviewed inputs. The runtime independently checks the CLI process directory."
96
+ : "Use the native shell's inherited working directory. Do not set or override a workdir/cwd field for this lifecycle command.",
97
+ "Continue only if it succeeds and returns the authoritative Work packet.",
98
+ lifecycleRetryInstruction,
99
+ "After a successful start, complete the assigned Work, write its required result, invoke its exact work finish command, then stop.",
100
+ "Do not start another Work, create a child, change dependencies, ask the user, or treat a quiet sibling as failed. You cannot ask the user or pause the parent Stage. Missing facts go through this Work's declared result/failure contract; only the coordinator handles Stage HITL."
101
+ ].join("\n");
102
+ }
103
+
104
+ export function renderDelegationInstructions({ harness, stage, capacity, works = [], totalWorks = works.length, remainingWorks = 0 }) {
105
+ const adapter = requireAdapter(harness);
106
+ const count = works.length;
107
+ if (!Number.isInteger(capacity) || capacity < 1 || count < 1 || count > capacity) throw new Error("Invalid native delegation wave size");
108
+ const assignments = works.map((work, index) => {
109
+ const task = workerDelegationTask({ workId: work.work_id, startCommand: work.start_command, launchPolicy: work.launch_policy });
110
+ return { task_name: `dd_flow_${index}_${work.work_id.toLowerCase().replace(/[^a-z0-9_]/g, "_")}`, context: work.launch_policy === "fresh_agent_required" ? "fresh" : "provider_default", message: task };
111
+ });
112
+ return [
113
+ `Adapter delegation contract: ${delegationContract(harness)}.`,
114
+ `Launch exactly ${count} direct native children for the current ${stage} Stage; the qualified capacity is ${capacity}.`,
115
+ ...(["plan-review", "code-review"].includes(stage) ? [
116
+ `Review dispatch phase: the whole group contains ${totalWorks} Work; this wave contains ${count}; ${remainingWorks} remain after this wave.`,
117
+ "Keep the accepted PLAN/CODE review inputs and aspect maps unchanged across every wave. Do not apply findings or edit reviewed files while any reviewer remains unstarted or running.",
118
+ "After this wave's children settle, return immediately. The controller will dispatch remaining reviewers or issue semantic completion after the full group has settled."
119
+ ] : []),
120
+ adapter.launch,
121
+ "Retain the frozen coordinator model and reasoning for native children; do not choose a different model, reasoning level or permission mode.",
122
+ "You are the coordinator. The JSON assignments below contain child-only messages, not instructions for you to execute. Pass each message verbatim as the native tool's task/message/prompt argument. For context=fresh, select empty conversation context before launch; if unavailable, report the limitation and stop. Use only fields exposed by your actual native tool schema; if the native tool is absent, report that error without substituting a shell command.",
123
+ "Every child must be a direct child of this current Session. Wait for all launched children to settle before returning. One failed child is evidence for the coordinator, not a reason to cancel its siblings.",
124
+ adapter.partial ?? "If a spawn is refused, stop issuing new spawns and retain every successful child handle. Wait for all already-launched children, then release completed children using the adapter's exposed native close/release mechanism when supported. A failed batch does not undo successful spawns. Report completed/launched assignments, assignments not launched and the exact refusal; never claim no children launched when any spawn succeeded. Return after this partial wave; the controller will issue remaining Work when capacity is available. Do not replay an ambiguous spawn.",
125
+ "Do not finish this Stage, repair it, or start a successor in this Turn. Do not invent provider or internal session IDs; lifecycle evidence comes from the adapter.",
126
+ adapter.wait,
127
+ "Child assignments (JSON data):",
128
+ JSON.stringify(assignments, null, 2)
129
+ ].join("\n\n");
130
+ }
131
+
132
+ export function renderCapacityInstructions({ harness, maximum }) {
133
+ const adapter = requireAdapter(harness);
134
+ if (!Number.isInteger(maximum) || maximum < 1 || maximum > 15) throw new Error("Native capacity limit must be an integer from 1 through 15");
135
+ return [
136
+ `Adapter delegation contract: ${delegationContract(harness)}.`,
137
+ "This is a technical native-subagent capacity qualification, not product work.",
138
+ `Using the current Session's native ${adapter.name} mechanism, concurrently launch at most ${maximum} direct leaf children.`,
139
+ adapter.launch,
140
+ "Give each child a distinct number and a task_name such as capacity_1 if required by the tool. Its entire task is: return that number, without tools, files, dd-flow commands, or descendants. Use empty conversation context. Do not retry, replace, or add children after a launch refusal.",
141
+ adapter.wait,
142
+ "Wait for every child actually launched to settle, then return a compact summary."
143
+ ].join("\n");
144
+ }
145
+
146
+ export function renderWaitInstructions({ harness, stage }) {
147
+ const adapter = requireAdapter(harness);
148
+ return [
149
+ `Native child Work for ${stage} is still running.`,
150
+ adapter.wait,
151
+ "Do not create a Session, Work, or additional child agent. Do not cancel siblings merely because one child failed, and do not finish this Stage."
152
+ ].join("\n");
153
+ }
154
+
155
+ export function renderAdapterPolicy({ harness }) {
156
+ const adapter = requireAdapter(harness);
157
+ return [adapter.launch, adapter.wait, "Lifecycle identity and completion must come from adapter observations; never synthesize provider or internal Session IDs."].join(" ");
158
+ }
159
+
160
+ export function renderRecoveryProbeInstructions({ harness, command }) {
161
+ const adapter = requireAdapter(harness);
162
+ return ["Technical native child cancellation qualification, not product work.", adapter.launch,
163
+ "Launch exactly one fresh direct child, task_name recovery_probe if required. Pass this JSON string as its message/prompt:",
164
+ JSON.stringify(`Run exactly this read-only command: ${command}\nDo not access files, use the network, modify anything, or create children.`),
165
+ adapter.wait, "External operator control will interrupt this tree. Do not close it early or launch replacements."].join("\n");
166
+ }
@@ -0,0 +1,14 @@
1
+ const generations = new WeakMap();
2
+
3
+ // A cancellation invalidates preparation already in flight, while a later
4
+ // explicit prompt captures a fresh generation and can resume normally.
5
+ export function captureDispatchGuard(owner) {
6
+ const generation = generations.get(owner) ?? 0;
7
+ return () => {
8
+ if (generation !== (generations.get(owner) ?? 0)) throw Object.assign(new Error("Prompt cancelled before native dispatch"), { code: "operation_cancelled" });
9
+ };
10
+ }
11
+
12
+ export function cancelPendingDispatch(owner) {
13
+ generations.set(owner, (generations.get(owner) ?? 0) + 1);
14
+ }
@@ -0,0 +1,140 @@
1
+ import { processSnapshot } from "./process-snapshot.mjs";
2
+ import { readdir, readFile, mkdir, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { inspectDaemonOperation } from "./daemon-operations.mjs";
5
+ import { writeJsonAtomic } from "./runner-events.mjs";
6
+ import { reportedError } from "./operation-errors.mjs";
7
+ import { ObservationClock } from "./observation-clock.mjs";
8
+ import { runtimeProcess } from "./managed-daemon.mjs";
9
+ import { nativeShutdownConfirmed } from "./native-children.mjs";
10
+
11
+ async function cleanShutdownConfirmed(root, state) {
12
+ const proof = state.shutdown;
13
+ let fence;
14
+ try { fence = JSON.parse(await readFile(path.join(root, 'operation-fence.json'), 'utf8')); }
15
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
16
+ return state.shutdown_state === "clean" && state.active_tree === false
17
+ && typeof state.daemon_id === 'string' && fence?.daemon_id === state.daemon_id && Number.isSafeInteger(fence.generation) && fence.generation >= 0
18
+ && nativeShutdownConfirmed(proof, { daemonId: state.daemon_id, generation: fence.generation });
19
+ }
20
+
21
+ /** Explicit same-Session restart retains native stores and the old daemon
22
+ * receipt; it does not turn a terminal directory into a new execution. */
23
+ export async function authorizeRetainedDaemonResume(root, previous, sessionId, config) {
24
+ const sessions = [...(previous.sessions ?? []), ...(previous.root_session_id ? [previous.root_session_id] : [])];
25
+ if (!await cleanShutdownConfirmed(root, previous) || typeof sessionId !== "string" || !sessions.some(session => (typeof session === "string" ? session : session.provider_session_id) === sessionId)) throw Object.assign(new Error("terminal daemon restart requires a retained, settled Session identity and complete shutdown proof"), { code: "daemon_state_terminal" });
26
+ for (const key of ["cwd", "projectRoot", "ddFlowHome", "ddFlowBin", "provider", "model", "reasoning", "mode", "variant", "agent", "bin", "noFlow"]) {
27
+ if ((previous.config?.[key] ?? null) !== (config[key] ?? null)) throw Object.assign(new Error(`retained daemon configuration changed: ${key}`), { code: "daemon_config_mismatch" });
28
+ }
29
+ await assertDaemonReplaceable(root);
30
+ await reconcileDriverReplies(root);
31
+ if (!/^[a-zA-Z0-9-]+$/.test(previous.daemon_id ?? "")) throw Object.assign(new Error("original daemon identity is invalid"), { code: "daemon_state_terminal" });
32
+ const directory = path.join(root, "daemon-history"); await mkdir(directory, { recursive: true, mode: 0o700 });
33
+ const file = path.join(directory, `${previous.daemon_id}.json`), bytes = `${JSON.stringify(previous, null, 2)}\n`;
34
+ try { await writeFile(file, bytes, { flag: "wx", mode: 0o600 }); }
35
+ catch (error) { if (error.code !== "EEXIST" || await readFile(file, "utf8") !== bytes) throw error; }
36
+ }
37
+
38
+ /** A dead bridge alone does not prove its provider tree was stopped. Require
39
+ * the adapter's durable clean-shutdown receipt as well, for every bridge. */
40
+ export async function recoverySettlement(driversRoot) {
41
+ const daemons = [];
42
+ const registries = new Map();
43
+ async function visit(directory) {
44
+ const entries = await readdir(directory, { withFileTypes: true });
45
+ const daemonRoot = entries.some(entry => entry.name === "daemon.json" && entry.isFile());
46
+ for (const entry of entries) {
47
+ const file = path.join(directory, entry.name);
48
+ if (entry.isSymbolicLink()) throw Object.assign(new Error("driver evidence contains a symbolic link"), { code: "recovery_settlement_unconfirmed" });
49
+ // Native stores contain package/auth symlinks, not adapter daemon
50
+ // receipts. Do not traverse their contents as a daemon inventory.
51
+ if (entry.isDirectory()) {
52
+ if (daemonRoot && ["gemini", "grok-home", "home", "xdg-data", "xdg-cache", "xdg-config"].includes(entry.name)) continue;
53
+ await visit(file);
54
+ }
55
+ else if (entry.name === "daemon.json") {
56
+ const state = JSON.parse(await readFile(file, "utf8"));
57
+ if (!await cleanShutdownConfirmed(directory, state)) throw Object.assign(new Error("provider tree has no complete clean shutdown receipt"), { code: "recovery_settlement_unconfirmed" });
58
+ await assertDaemonReplaceable(directory);
59
+ await reconcileDriverReplies(directory);
60
+ if (state.config?.resourceHome && state.resource_process?.id) {
61
+ const key = state.config.resourceHome;
62
+ if (!registries.has(key)) registries.set(key, await runtimeProcess(state.config, "status"));
63
+ const processes = registries.get(key)?.processes;
64
+ if (!Array.isArray(processes) || !processes.some(record => record.id === state.resource_process.id)) throw Object.assign(new Error("managed daemon registration is missing"), { code: "recovery_settlement_unconfirmed" });
65
+ const attemptRoot = path.dirname(path.resolve(driversRoot));
66
+ for (const record of processes.filter(record => record.id === state.resource_process.id || [record.stdout_path, record.stderr_path].some(file => typeof file === "string" && path.resolve(file).startsWith(`${attemptRoot}${path.sep}`)))) {
67
+ if (!["stopped", "failed"].includes(record.state)) throw Object.assign(new Error("a retained managed process has not settled"), { code: "recovery_settlement_unconfirmed", details: { process_id: record.id, state: record.state } });
68
+ if (Number.isInteger(record.pid) && record.pid > 0) {
69
+ try { process.kill(record.pid, 0); }
70
+ catch (error) { if (error.code === "ESRCH") continue; }
71
+ if (typeof record.pid_started_at === "string" && record.pid_started_at.trim()) {
72
+ const observed = (await processSnapshot()).find(item => item.pid === record.pid);
73
+ if (!observed || record.pid_started_at.trim().replace(/\s+/g, " ") !== observed.started) continue;
74
+ }
75
+ throw Object.assign(new Error("a retained managed process is still live or unconfirmed"), { code: "recovery_settlement_unconfirmed", details: { process_id: record.id } });
76
+ }
77
+ }
78
+ }
79
+ daemons.push({ state_file: file, daemon_id: state.daemon_id, shutdown_state: state.shutdown_state, pid: state.pid });
80
+ }
81
+ }
82
+ }
83
+ await visit(driversRoot);
84
+ if (!daemons.length) throw Object.assign(new Error("no provider shutdown evidence found"), { code: "recovery_settlement_unconfirmed" });
85
+ return { settled: true, reason: "observed_clean_adapter_shutdown", observed_at: new Date().toISOString(), daemons };
86
+ }
87
+
88
+ export async function assertDaemonReplaceable(root) {
89
+ let state;
90
+ try { state = JSON.parse(await readFile(path.join(root, "daemon.json"), "utf8")); }
91
+ catch (error) { if (error.code === "ENOENT") return; throw error; }
92
+ if (!Number.isInteger(state.pid) || state.pid <= 0) throw Object.assign(new Error("original daemon ownership is unknown"), { code: "operation_observation_lost", details: { state_dir: root } });
93
+ const pids = new Set([state.pid, state.provider_pid, ...(state.owned_processes ?? []).map(process => process.pid)].filter(pid => Number.isInteger(pid) && pid > 0));
94
+ for (const pid of pids) {
95
+ try { process.kill(pid, 0); }
96
+ catch (error) { if (error.code === "ESRCH") continue; }
97
+ const retained = state.owned_processes?.filter(record => record.pid === pid && typeof record.started === "string" && record.started.trim());
98
+ if (retained?.length) {
99
+ const observed = (await processSnapshot()).find(record => record.pid === pid);
100
+ if (!observed || retained.every(record => record.started !== observed.started)) continue;
101
+ }
102
+ throw Object.assign(new Error("original daemon/provider is live or its ownership is unconfirmed; do not create a competing bridge"), { code: "operation_observation_lost", details: { state_dir: root, pid } });
103
+ }
104
+ }
105
+
106
+ /** Observe the original operation; never re-send its parameters. */
107
+ export async function recoverDriverReply(root, id, { timeoutMs = 30_000, pollMs = 250 } = {}) {
108
+ const clock = new ObservationClock({ timeoutMs });
109
+ do {
110
+ let receipt;
111
+ try { receipt = await inspectDaemonOperation(root, id); }
112
+ catch (error) { if (error.code !== "operation_not_found") throw error; }
113
+ if (receipt?.state === "completed") return receipt.result;
114
+ if (receipt?.state === "failed") throw reportedError(receipt.error, "provider operation failed");
115
+ if (clock.sample()) break;
116
+ await new Promise(resolve => setTimeout(resolve, pollMs));
117
+ } while (true);
118
+ throw Object.assign(new Error("original provider operation has no confirmed reply; reconcile it before starting another Turn"), {
119
+ code: "operation_observation_lost", details: { operation_id: id, state_dir: root }
120
+ });
121
+ }
122
+
123
+ /** Crash recovery barrier. Import late replies into the client ledger before
124
+ * any subsequent productive call, even when a new runner process is used. */
125
+ export async function reconcileDriverReplies(root) {
126
+ const directory = path.join(root, "client-operations");
127
+ let entries;
128
+ try { entries = await readdir(directory); } catch (error) { if (error.code === "ENOENT") return; throw error; }
129
+ for (const entry of entries.filter(name => name.endsWith(".json"))) {
130
+ const file = path.join(directory, entry), record = JSON.parse(await readFile(file, "utf8"));
131
+ if (["completed", "failed", "interrupted"].includes(record.state)) continue;
132
+ let receipt;
133
+ try { receipt = await inspectDaemonOperation(root, record.operation_id); }
134
+ catch (error) { if (error.code !== "operation_not_found") throw error; }
135
+ if (!["completed", "failed", "interrupted"].includes(receipt?.state)) throw Object.assign(new Error("a previous driver request has an unknown outcome; no new productive request was sent"), {
136
+ code: "operation_observation_lost", details: { operation_id: record.operation_id, state_dir: root }
137
+ });
138
+ await writeJsonAtomic(file, { ...record, state: receipt.state, result: receipt.result, error: receipt.error, reconciled_at: new Date().toISOString() });
139
+ }
140
+ }
@@ -0,0 +1,66 @@
1
+ import { createHash } from "node:crypto";
2
+ import { open, readFile, readdir, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+
5
+ /** Cache native filenames, then read only a bounded header and small settings.
6
+ * New child discovery may walk the directory once; heartbeats never replay it. */
7
+ export class DroidMetadataReader {
8
+ constructor(factory) { this.factory = factory; this.files = new Map(); this.cache = new Map(); }
9
+ async locate(id) {
10
+ if (this.files.has(id)) return this.files.get(id);
11
+ const visit = async directory => {
12
+ for (const entry of await readdir(directory, { withFileTypes: true }).catch(error => { if (error.code === "ENOENT") return []; throw error; })) {
13
+ const file = path.join(directory, entry.name);
14
+ if (entry.isDirectory()) await visit(file);
15
+ else if (entry.isFile() && entry.name.endsWith(".jsonl")) this.files.set(entry.name.slice(0, -6), file);
16
+ }
17
+ };
18
+ await visit(path.join(this.factory, "sessions"));
19
+ return this.files.get(id) ?? null;
20
+ }
21
+ async read(id) {
22
+ const file = await this.locate(id); if (!file) return null;
23
+ const settingsFile = file.replace(/\.jsonl$/, ".settings.json");
24
+ const info = await stat(settingsFile).catch(error => { if (error.code === "ENOENT") return null; throw error; });
25
+ if (!info || info.size > 1_048_576) return null;
26
+ const identity = `${info.ino}:${info.mtimeMs}:${info.size}`;
27
+ if (this.cache.get(id)?.identity === identity) return this.cache.get(id).value;
28
+ const handle = await open(file, "r"); const buffer = Buffer.alloc(65_536);
29
+ let header;
30
+ try { const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0); header = JSON.parse(buffer.subarray(0, bytesRead).toString("utf8").split("\n")[0]); }
31
+ finally { await handle.close(); }
32
+ if (header.type !== "session_start" || header.id !== id) throw Object.assign(new Error("native metadata Session identity differs"), { code: "session_identity_mismatch" });
33
+ let bytes, settings;
34
+ try { bytes = await readFile(settingsFile, "utf8"); settings = JSON.parse(bytes); }
35
+ catch (error) { if (error instanceof SyntaxError || error.code === "ENOENT") return null; throw error; }
36
+ const value = { header, settings, transcript_path: file, source: { path: settingsFile, sha256: createHash("sha256").update(bytes).digest("hex") } };
37
+ this.cache.set(id, { identity, value }); return value;
38
+ }
39
+ }
40
+
41
+ export function parseDroidRoutingLine(line) {
42
+ if (!line.includes("[Model-Router] Model transition | Context: ")) return null;
43
+ let context; try { context = JSON.parse(line.split(" | Context: ").slice(1).join(" | Context: ")); } catch { return null; }
44
+ if (context.slot !== "main" || typeof context.sessionId !== "string" || typeof context.modelId !== "string") return null;
45
+ return { session_id: context.sessionId, model: context.modelId, previous_model: context.previousModelId ?? null,
46
+ reason: typeof context.reason === "string" ? context.reason : null, native_timestamp: /^\[([^\]]+)\]/.exec(line)?.[1] ?? null,
47
+ event_sha256: createHash("sha256").update(line).digest("hex") };
48
+ }
49
+
50
+ /** Keep the cursor in daemon state. Bound every read, tolerate incomplete lines
51
+ * and restart from zero after truncation/rotation of this execution's own log. */
52
+ export async function readDroidRoutingLog(file, cursor = {}) {
53
+ let handle;
54
+ try { handle = await open(file, "r"); } catch (error) { if (error.code === "ENOENT") return { cursor, events: [] }; throw error; }
55
+ try {
56
+ const info = await handle.stat();
57
+ const offset = info.ino === cursor.ino && info.size >= (cursor.offset ?? 0) ? cursor.offset ?? 0 : 0;
58
+ const buffer = Buffer.alloc(Math.min(1_048_576, Math.max(0, info.size - offset)));
59
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, offset);
60
+ const end = buffer.subarray(0, bytesRead).lastIndexOf(10) + 1;
61
+ const lines = buffer.subarray(0, end).toString("utf8").split("\n");
62
+ // Persist offsets only, never a partial native line that may contain secrets.
63
+ return { cursor: { ino: info.ino, offset: offset + (end || (bytesRead === buffer.length && bytesRead === 1_048_576 ? bytesRead : 0)) }, events: lines.map(parseDroidRoutingLine).filter(Boolean) };
64
+
65
+ } finally { await handle.close(); }
66
+ }
@@ -0,0 +1,2 @@
1
+ export function shortEntityReference(id: string): string;
2
+ export function entityReferenceVariants(id: string): string[];
@@ -0,0 +1,9 @@
1
+ /** Stable model-facing reference for persisted project, RUN and Work IDs. */
2
+ export function shortEntityReference(id) {
3
+ return /^(?:PRJ|RUN|WRK)-\d{3,}(?:-|$)/.exec(id)?.[0]?.replace(/-$/, "") ?? id;
4
+ }
5
+
6
+ /** Accepted spellings of one already-resolved entity. Wrong full slugs stay distinct. */
7
+ export function entityReferenceVariants(id) {
8
+ return [...new Set([id, shortEntityReference(id)])];
9
+ }
@@ -0,0 +1,8 @@
1
+ export const RENEWAL_POLICY: Readonly<{ startupMs: number; budgetMs: number; attemptMs: number; safetyMs: number }>;
2
+ export type RenewalState = { uncertainSince: number | null; attempt: number; exhausted: boolean; leaseExpiresAt: string | null };
3
+ export function createRenewalState(options?: { leaseExpiresAt?: string | null }): RenewalState;
4
+ export function renewalRemaining(state: RenewalState, now?: number, wallNow?: number): number;
5
+ export function renewalFailure(state: RenewalState, now?: number): number;
6
+ export function renewalDelay(state: RenewalState): number;
7
+ export function renewalConfirmed(state: RenewalState, now?: number, leaseExpiresAt?: string | null): boolean;
8
+ export function maintenanceRetryable(error: unknown): boolean;
@@ -0,0 +1,37 @@
1
+ /** Shared policy only; transports and owner-specific fences stay at callsites. */
2
+ export const RENEWAL_POLICY = Object.freeze({ startupMs: 120_000, budgetMs: 126_000, attemptMs: 5_000, safetyMs: 1_000 });
3
+ export function createRenewalState({ leaseExpiresAt = null } = {}) { return { uncertainSince: null, attempt: 0, exhausted: false, leaseExpiresAt }; }
4
+ export function renewalRemaining(state, now = performance.now(), wallNow = Date.now()) {
5
+ const expiry = Date.parse(state.leaseExpiresAt ?? "");
6
+ const budget = Number.isFinite(expiry) ? Math.max(0, expiry - wallNow - RENEWAL_POLICY.safetyMs) : state.leaseExpiresAt != null ? 0 : RENEWAL_POLICY.budgetMs;
7
+ const remaining = state.exhausted ? 0 : Number.isFinite(expiry) || state.uncertainSince === null ? budget : Math.max(0, budget - (now - state.uncertainSince));
8
+ if (remaining === 0) state.exhausted = true;
9
+ return remaining;
10
+ }
11
+ export function renewalFailure(state, now = performance.now()) { state.uncertainSince ??= now; state.attempt++; return renewalRemaining(state, now); }
12
+ export function renewalDelay(state) { return Math.min(2_000, 250 * 2 ** Math.min(3, Math.max(0, state.attempt - 1))); }
13
+ export function renewalConfirmed(state, now = performance.now(), leaseExpiresAt = null) {
14
+ // Caller verifies exact owner/fence. A committed receipt, not elapsed time,
15
+ // establishes the new authority horizon.
16
+ if (leaseExpiresAt !== null) {
17
+ const expiry = Date.parse(leaseExpiresAt);
18
+ if (!Number.isFinite(expiry) || expiry <= Date.now() + RENEWAL_POLICY.safetyMs) return false;
19
+ state.leaseExpiresAt = leaseExpiresAt; state.exhausted = false;
20
+ }
21
+ if (!renewalRemaining(state, now)) return false;
22
+ state.uncertainSince = null; state.attempt = 0; return true;
23
+ }
24
+ export function maintenanceRetryable(error) {
25
+ let retryable = false;
26
+ // Inspect only bounded typed causes from our maintenance transport, never text.
27
+ for (let depth = 0; error && depth < 8; depth++, error = error.cause ?? error.details?.cause) {
28
+ if (error.details?.cleanup_unconfirmed === true || error.cleanup_error || error.details?.cleanup_error
29
+ || error.details?.store_cleanup_errors?.length || error.details?.transaction_cleanup_error || error.details?.transaction_close_error) return false;
30
+ if (error.details?.effect === "unknown") return false;
31
+ if (["process_lease_lost", "controller_lease_lost", "process_maintenance_receipt_invalid", "runtime_owner_mismatch"].includes(error.code)) return false;
32
+ if (error.code === "process_ownership_unknown" && error.details?.reason === "physical_identity_unavailable" && ["process_confirmation", "observer_registration"].includes(error.details.phase) && error.details.effect === "no_effect" && error.details.native_dispatch_started === false) retryable = true;
33
+ if (["process_heartbeat_timeout", "process_maintenance_timeout", "hook_deadline_exceeded", "native_hook_timeout", "SQLITE_BUSY", "SQLITE_LOCKED"].includes(error.code)) retryable = true;
34
+ if (error.code === "ERR_SQLITE_ERROR" && [5, 6].includes((error.details?.sqlite_extended_code ?? error.sqlite_extended_code ?? error.errcode) & 255)) retryable = true;
35
+ }
36
+ return retryable;
37
+ }
@@ -0,0 +1,20 @@
1
+ import type { LifecycleOperation } from "./lifecycle-contract.mjs";
2
+ export type { LifecycleOperation } from "./lifecycle-contract.mjs";
3
+ export interface ParsedCommandArgs { positional: string[]; options: Map<string, string[]> }
4
+ export interface LifecycleInvocation {
5
+ operation: LifecycleOperation; executable: string; launcher?: string; argv: string[]; env: Record<string, string>; args: ParsedCommandArgs; command: string;
6
+ rewriteSafe: boolean; wrapped: boolean; heredoc: boolean; sourceRange?: { start: number; end: number }; contexts?: string[]; expectedCwd?: string;
7
+ }
8
+ export type LifecycleAnalysis = ({ participation: "none" | "lifecycle" | "auxiliary" | "unproven"; auxiliary?: { operation: string; args: ParsedCommandArgs; expectedCwd?: string } } & (
9
+ | { kind: "none"; unresolved?: true; reason?: string }
10
+ | { kind: "standalone"; invocation: LifecycleInvocation; supported?: boolean; invocations?: LifecycleInvocation[] }
11
+ | { kind: "compound"; invocation: LifecycleInvocation; reason: string; supported?: boolean; invocations?: LifecycleInvocation[] }));
12
+ export function lifecycleCommandFromPayload(payload: { command?: unknown; tool_input?: unknown }): string | undefined;
13
+ export function parseLifecycleCommand(command: string): LifecycleAnalysis;
14
+ export function continuationCommand(command: string): { operation: string; args: ParsedCommandArgs; expectedCwd?: string } | null;
15
+ export function unwrapShellCommand(command: string): string;
16
+ export function parseCommandArgs(argv: string[]): ParsedCommandArgs;
17
+ export function commandOption(invocation: LifecycleInvocation, name: string): string | undefined;
18
+ export function commandHasOption(invocation: LifecycleInvocation, name: string): boolean;
19
+ export function commandPosition(invocation: LifecycleInvocation, index: number): string | undefined;
20
+ export function shellSuffixOffset(command: string): number;