@deksden-com/dd-flow-cli 0.9.0-beta.144 → 0.9.0-beta.149

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 (254) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +13 -8
  3. package/dist/build-info.json +7 -7
  4. package/dist/cli/command-inputs.js +13 -3
  5. package/dist/cli/command-metadata.js +51 -16
  6. package/dist/cli/diagnostic-invocation.js +46 -0
  7. package/dist/cli/diagnostic.js +120 -0
  8. package/dist/cli/help.js +67 -1
  9. package/dist/cli/hook-ingress.js +27 -3
  10. package/dist/cli/memory-flow-admission.js +9 -3
  11. package/dist/cli/memory-init-invocation.js +10 -3
  12. package/dist/cli/memory-init.js +77 -68
  13. package/dist/cli/memory-storage-admission.js +3 -2
  14. package/dist/cli/memory-storage-qualification.js +105 -0
  15. package/dist/cli/memory-storage-transition.js +123 -0
  16. package/dist/cli/memory-upgrade.js +189 -0
  17. package/dist/cli/native-hook-ingress.js +14 -4
  18. package/dist/cli/native-hook-preparation.js +55 -0
  19. package/dist/cli/response-file.js +2 -1
  20. package/dist/cli/run-cli.js +79 -40
  21. package/dist/cli/setup.js +2 -1
  22. package/dist/cli.js +18 -0
  23. package/dist/domain/diagnostic-aspects.js +103 -0
  24. package/dist/domain/diagnostic-flows.js +8 -0
  25. package/dist/domain/stage-handler-identities.js +8 -0
  26. package/dist/harness-runtime/bin/dd-agy.mjs +3 -3
  27. package/dist/harness-runtime/bin/dd-grok.mjs +3 -3
  28. package/dist/harness-runtime/bin/dd-zcode.mjs +5 -5
  29. package/dist/harness-runtime/lib/agy-error-boundary.mjs +58 -0
  30. package/dist/harness-runtime/lib/agy-native-inspection.mjs +216 -0
  31. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  32. package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
  33. package/dist/harness-runtime/lib/daemon-operations.mjs +84 -10
  34. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +366 -52
  35. package/dist/harness-runtime/lib/dd-agy.mjs +17 -3
  36. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +27 -13
  37. package/dist/harness-runtime/lib/dd-codex.mjs +4 -0
  38. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +4 -3
  39. package/dist/harness-runtime/lib/dd-droid.mjs +71 -29
  40. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +73 -16
  41. package/dist/harness-runtime/lib/dd-grok.mjs +6 -3
  42. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +66 -20
  43. package/dist/harness-runtime/lib/dd-opencode.mjs +30 -3
  44. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +7 -6
  45. package/dist/harness-runtime/lib/dd-zcode.mjs +44 -14
  46. package/dist/harness-runtime/lib/delegation-instructions.mjs +1 -1
  47. package/dist/harness-runtime/lib/driver-recovery.mjs +9 -8
  48. package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
  49. package/dist/harness-runtime/lib/entity-references.mjs +9 -0
  50. package/dist/harness-runtime/lib/managed-daemon.d.mts +1 -1
  51. package/dist/harness-runtime/lib/managed-daemon.mjs +24 -9
  52. package/dist/harness-runtime/lib/native-children.d.mts +8 -1
  53. package/dist/harness-runtime/lib/native-children.mjs +114 -8
  54. package/dist/harness-runtime/lib/native-hook-command.mjs +4 -4
  55. package/dist/harness-runtime/lib/native-request-proof.mjs +1 -1
  56. package/dist/harness-runtime/lib/observation-clock.d.mts +2 -2
  57. package/dist/harness-runtime/lib/observation-clock.mjs +7 -4
  58. package/dist/harness-runtime/lib/opencode-plugin.mjs +3 -3
  59. package/dist/harness-runtime/lib/operation-errors.mjs +1 -1
  60. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +5 -3
  61. package/dist/harness-runtime/lib/provider-overload-policy.mjs +20 -7
  62. package/dist/harness-runtime/lib/runner-events.mjs +3 -1
  63. package/dist/harness-runtime/lib/setup-progress.mjs +8 -6
  64. package/dist/harness-runtime/lib/tool-observations.mjs +1 -1
  65. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  66. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  67. package/dist/schemas/execution-bundle.schema.json +7 -1
  68. package/dist/schemas/mb-upgrade-stage-result.schema.json +863 -0
  69. package/dist/schemas/memory-repair-work-result.schema.json +9 -2
  70. package/dist/schemas/project-flow-pack-manifest.schema.json +1 -1
  71. package/dist/schemas/release-impact.schema.json +3 -3
  72. package/dist/schemas/stage-start-response.schema.json +4 -0
  73. package/dist/services/accepted-intent.js +13 -1
  74. package/dist/services/canon.js +43 -7
  75. package/dist/services/check-environment.js +21 -0
  76. package/dist/services/check-runner-evidence.js +267 -15
  77. package/dist/services/cli-operation-classifier.js +1 -1
  78. package/dist/services/cli-upgrade-allowlist.js +1 -1
  79. package/dist/services/code-checks.js +34 -19
  80. package/dist/services/compatibility-preflight.js +5 -2
  81. package/dist/services/controller-execution.js +10 -4
  82. package/dist/services/controller-fanout.js +34 -10
  83. package/dist/services/controller-memory-task.js +45 -0
  84. package/dist/services/controller-memory-worker.js +49 -0
  85. package/dist/services/dashboard.js +2 -2
  86. package/dist/services/descriptor-run-settlement.js +5 -3
  87. package/dist/services/descriptor-run-start.js +46 -20
  88. package/dist/services/descriptor-stage-coordinator.js +66 -13
  89. package/dist/services/descriptor-stage-settlement.js +2 -1
  90. package/dist/services/descriptor-stage-start.js +40 -4
  91. package/dist/services/diagnostic-evidence.js +73 -0
  92. package/dist/services/diagnostic-report-publication.js +72 -0
  93. package/dist/services/diagnostic-report.js +67 -0
  94. package/dist/services/diagnostic-run-bundle.js +74 -0
  95. package/dist/services/diagnostic-snapshot.js +159 -0
  96. package/dist/services/diagnostic-stage-handlers.js +108 -0
  97. package/dist/services/diagnostic-stage-results.js +132 -0
  98. package/dist/services/diagnostic-start.js +84 -0
  99. package/dist/services/diagnostic-work-batch.js +34 -0
  100. package/dist/services/diagnostic-work-collection.js +97 -0
  101. package/dist/services/diagnostic-work-registration.js +101 -0
  102. package/dist/services/diagnostic-work-results.js +93 -0
  103. package/dist/services/engines.js +64 -14
  104. package/dist/services/eval-snapshots.js +186 -119
  105. package/dist/services/execution-bundles.js +19 -7
  106. package/dist/services/external-work-launch.js +5 -3
  107. package/dist/services/flow-catalog.js +13 -4
  108. package/dist/services/frozen-engine.js +148 -11
  109. package/dist/services/hook-memory-routing.js +188 -0
  110. package/dist/services/hook-recovery-guard.js +14 -0
  111. package/dist/services/hook-session-observation.js +24 -0
  112. package/dist/services/hooks.js +27 -8
  113. package/dist/services/hybrid-contracts.js +4 -13
  114. package/dist/services/hybrid-digest.js +14 -0
  115. package/dist/services/installed-flow-source.js +47 -4
  116. package/dist/services/lifecycle-invocations.js +179 -38
  117. package/dist/services/memory-accepted-composition.js +5 -4
  118. package/dist/services/memory-completed-correction-wave.js +23 -15
  119. package/dist/services/memory-compose-handler.js +163 -21
  120. package/dist/services/memory-composition-acceptance.js +186 -10
  121. package/dist/services/memory-composition-graph.js +42 -11
  122. package/dist/services/memory-composition-registration.js +23 -8
  123. package/dist/services/memory-composition-work-custody.js +14 -9
  124. package/dist/services/memory-composition-work-results.js +15 -3
  125. package/dist/services/memory-corrected-review-batch.js +10 -3
  126. package/dist/services/memory-corrected-review-findings.js +4 -2
  127. package/dist/services/memory-corrected-review-inputs.js +10 -5
  128. package/dist/services/memory-corrected-review-receipt.js +17 -9
  129. package/dist/services/memory-corrected-review-registration.js +3 -2
  130. package/dist/services/memory-correction-check-receipt.js +20 -4
  131. package/dist/services/memory-custody-snapshot.js +36 -0
  132. package/dist/services/memory-finish-evidence.js +44 -22
  133. package/dist/services/memory-finish-handler.js +37 -23
  134. package/dist/services/memory-finish-integration.js +218 -48
  135. package/dist/services/memory-finish-readiness.js +66 -19
  136. package/dist/services/memory-git-integration.js +87 -18
  137. package/dist/services/memory-historical-corrected-review.js +21 -15
  138. package/dist/services/memory-historical-original-review.js +22 -9
  139. package/dist/services/memory-historical-repair-registration.js +14 -8
  140. package/dist/services/memory-historical-second-review.js +30 -11
  141. package/dist/services/memory-init-contexts.js +44 -2
  142. package/dist/services/memory-init-controller-start.js +27 -8
  143. package/dist/services/memory-init-git-policy.js +50 -21
  144. package/dist/services/memory-init-lint-capability.js +24 -6
  145. package/dist/services/memory-init-native-capacity.js +17 -4
  146. package/dist/services/memory-init-preflight.js +21 -17
  147. package/dist/services/memory-init-request-candidate.js +73 -17
  148. package/dist/services/memory-init-request-input.js +23 -7
  149. package/dist/services/memory-init-run-bundle.js +49 -12
  150. package/dist/services/memory-init-storage.js +17 -7
  151. package/dist/services/memory-init-worktrunk-capability.js +3 -7
  152. package/dist/services/memory-layer.js +71 -6
  153. package/dist/services/memory-lint-config.js +111 -2
  154. package/dist/services/memory-native-review-copy.js +5 -67
  155. package/dist/services/memory-normal-flow-entry.js +12 -0
  156. package/dist/services/memory-ordinary-defaults.js +22 -5
  157. package/dist/services/memory-preflight-handler.js +15 -0
  158. package/dist/services/memory-repair-current-view.js +1 -1
  159. package/dist/services/memory-repair-document-delta.js +70 -33
  160. package/dist/services/memory-repair-history.js +12 -7
  161. package/dist/services/memory-repair-physical-binding.js +1 -119
  162. package/dist/services/memory-repair-publication-plan.js +5 -3
  163. package/dist/services/memory-repair-publication-source.js +1 -1
  164. package/dist/services/memory-repair-publication.js +3 -2
  165. package/dist/services/memory-repair-registration.js +2 -1
  166. package/dist/services/memory-repair-work-baseline.js +4 -2
  167. package/dist/services/memory-repair-work-completion.js +32 -12
  168. package/dist/services/memory-repair-work-results.js +21 -2
  169. package/dist/services/memory-repair-workspace.js +11 -2
  170. package/dist/services/memory-repair-writer-copy.js +2 -1
  171. package/dist/services/memory-result-binding.js +78 -12
  172. package/dist/services/memory-retained-review-authority.js +17 -8
  173. package/dist/services/memory-retained-second-baseline.js +1 -1
  174. package/dist/services/memory-retained-second-repairs.js +12 -6
  175. package/dist/services/memory-review-correction-plan.js +47 -12
  176. package/dist/services/memory-review-handler.js +17 -17
  177. package/dist/services/memory-review-inputs.js +55 -9
  178. package/dist/services/memory-review-limits.js +10 -0
  179. package/dist/services/memory-review-receipt.js +2 -2
  180. package/dist/services/memory-review-registration.js +13 -4
  181. package/dist/services/memory-review-work-custody.js +3 -1
  182. package/dist/services/memory-review-work-input.js +26 -7
  183. package/dist/services/memory-review-work-results.js +26 -4
  184. package/dist/services/memory-second-corrected-review-inputs.js +5 -3
  185. package/dist/services/memory-second-correction-plan.js +2 -1
  186. package/dist/services/memory-second-repair-launch.js +4 -4
  187. package/dist/services/memory-second-repair-source.js +1 -1
  188. package/dist/services/memory-stage-dispatch.js +38 -1
  189. package/dist/services/memory-stage-results.js +113 -22
  190. package/dist/services/memory-tool-probe.js +25 -0
  191. package/dist/services/memory-upgrade-analysis-handler.js +243 -0
  192. package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
  193. package/dist/services/memory-upgrade-evidence.js +100 -0
  194. package/dist/services/memory-upgrade-inventory.js +442 -0
  195. package/dist/services/memory-upgrade-publication-custody.js +73 -0
  196. package/dist/services/memory-upgrade-publication.js +413 -0
  197. package/dist/services/memory-upgrade-selection.js +430 -0
  198. package/dist/services/memory-upgrade-start.js +60 -0
  199. package/dist/services/memory-upgrade-storage-readiness.js +340 -0
  200. package/dist/services/memory-verification-acceptance.js +38 -17
  201. package/dist/services/memory-verification-checks.js +92 -27
  202. package/dist/services/memory-verification-receipt.js +6 -5
  203. package/dist/services/memory-verify-handler.js +15 -13
  204. package/dist/services/memory-work-result-json.js +12 -0
  205. package/dist/services/memory-work-result-preparation.js +5 -4
  206. package/dist/services/merge-server.js +4 -2
  207. package/dist/services/migrations.js +127 -98
  208. package/dist/services/native-daemon-history.js +2 -1
  209. package/dist/services/physical-startup.js +45 -0
  210. package/dist/services/project-registry.js +97 -0
  211. package/dist/services/project-summary.js +1 -1
  212. package/dist/services/projects.js +3 -93
  213. package/dist/services/prompt-delivery.js +71 -0
  214. package/dist/services/provider-capacity.js +112 -46
  215. package/dist/services/recovery-snapshot-database.js +32 -4
  216. package/dist/services/release-cache.js +8 -0
  217. package/dist/services/repair-intents.js +1 -12
  218. package/dist/services/repair-receipt.js +13 -0
  219. package/dist/services/run-control-worker.js +35 -18
  220. package/dist/services/run-control.js +2 -1
  221. package/dist/services/run-controller-adapter.js +2 -1
  222. package/dist/services/run-controller-process.js +4 -7
  223. package/dist/services/run-controller-recovery.js +8 -2
  224. package/dist/services/run-controller.js +215 -94
  225. package/dist/services/run-fork.js +1 -1
  226. package/dist/services/run-recovery-guard.js +30 -0
  227. package/dist/services/run-recovery.js +11 -44
  228. package/dist/services/run-start-custody.js +17 -5
  229. package/dist/services/runs.js +6 -1
  230. package/dist/services/runtime-scope-resume.js +12 -6
  231. package/dist/services/runtime-scope-stop.js +3 -2
  232. package/dist/services/runtime-scope-worker.js +46 -19
  233. package/dist/services/runtime-service.js +2 -1
  234. package/dist/services/sessions.js +3 -24
  235. package/dist/services/setup.js +63 -13
  236. package/dist/services/stage-handlers.js +22 -7
  237. package/dist/services/stage-pause.js +111 -44
  238. package/dist/services/version-status.js +1 -1
  239. package/dist/services/vnext-code.js +2 -2
  240. package/dist/services/vnext-fanout.js +51 -9
  241. package/dist/services/vnext-plan-review.js +3 -5
  242. package/dist/services/work-registry.js +117 -39
  243. package/dist/services/workspace-bootstrap.js +2 -1
  244. package/dist/services/workspace-files.js +1 -1
  245. package/dist/shared/entity-references.js +1 -8
  246. package/dist/storage/data-preservation.js +65 -0
  247. package/dist/storage/database.js +53 -19
  248. package/dist/storage/import-guard.js +84 -27
  249. package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
  250. package/dist/storage/paired-writer-migration.js +424 -0
  251. package/dist/storage/writer-contract.js +11 -4
  252. package/dist/storage/writer-migration.js +313 -52
  253. package/dist/storage/writer-restore.js +217 -0
  254. package/package.json +13 -6
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import { prepareResponseDestination, writeResponseFile } from "./response-file.js";
3
+ import { preparePromptDelivery, publishPromptDelivery } from "../services/prompt-delivery.js";
3
4
  import { requiredOption, optionalOption, optionalNumber, optionalPositiveNumber } from "./argument-values.js";
4
5
  import { resolveCommandPaths, resolveCommandProjectRoot } from "../services/command-context.js";
5
6
  import { assertAuxiliaryCommandScope, cliManagedInvocationScope, manualRecoveryInvocationScope, assertManualRecoveryInvocationTarget } from "../services/lifecycle-invocations.js";
@@ -49,6 +50,7 @@ import { validateSchema } from "../services/schema-validation.js";
49
50
  import { preflightMemoryPermissions } from "../services/memory-permissions.js";
50
51
  import { ingestDroidUsage, ingestAgyUsage, ingestGrokUsage, ingestOpenCodeUsage, ingestZcodeUsage } from "../services/usage.js";
51
52
  import { applyMigration, assessMigrationImpact, assertUpgradeRunStorageReady, planMigration, prepareMigrationApply, verifyMigrationReport } from "../services/migrations.js";
53
+ import { PreparedUpgradeStorageReadiness } from "../services/memory-upgrade-storage-readiness.js";
52
54
  import { publishProjectSummary } from "../services/project-summary.js";
53
55
  import { requireProjectByRoot } from "../services/projects.js";
54
56
  import { resolveProjectRoot, resolveDdFlowHome } from "../storage/paths.js";
@@ -62,9 +64,11 @@ import { addVnextCodeRepair, prepareVnextCodeRepair, prepareVnextCodeStart } fro
62
64
  import { isVnextCodeReviewRun, prepareCodeReviewDecision, prepareVnextCodeReviewRepair, prepareVnextCodeReviewStart } from "../services/vnext-code-review.js";
63
65
  import { applyVnextMerge, getVnextMergeRequest, isVnextMergeRun, prepareVnextMergeFinish, prepareVnextMergeStart, repairVnextMerge, routeVnextMergeRequest } from "../services/vnext-merge.js";
64
66
  import { sdlcStageHandlers } from "../services/stage-handlers.js";
65
- import { startMemoryStage, finishMemoryStage } from "../services/memory-stage-dispatch.js";
67
+ import { startMemoryStage, finishMemoryStage, startMemoryUpgradeStage, finishMemoryUpgradeStage } from "../services/memory-stage-dispatch.js";
68
+ import { startDiagnosticStage, finishDiagnosticStage } from "../services/diagnostic-stage-handlers.js";
69
+ import { isDiagnosticFlow } from "../domain/diagnostic-flows.js";
66
70
  import { bindStageCoordinatorWork } from "../services/work-registry.js";
67
- import { registerMemoryCompositionFromStage } from "../services/memory-compose-handler.js";
71
+ import { registerMemoryCompositionFromStage, publishMemoryUpgradeFromStage } from "../services/memory-compose-handler.js";
68
72
  import { runMemoryVerificationChecks } from "../services/memory-verify-handler.js";
69
73
  import { registerMemoryReviewFromStage, collectMemoryInitialReviewFromStage } from "../services/memory-review-handler.js";
70
74
  import { PreparedRetainedMemoryReviewAuthority } from "../services/memory-retained-review-authority.js";
@@ -73,7 +77,7 @@ import { registerMemoryCorrectionsFromStage, registerMemorySecondCorrectionsFrom
73
77
  import { integrateMemoryFinishFromStage, registerMemoryFinishEvidenceFromStage } from "../services/memory-finish-handler.js";
74
78
  import { registerMemoryRepairBaselineFromStage, registerMemorySecondRepairBaselineFromStage, reserveMemoryRepairWriterCopyFromStage, reserveMemorySecondRepairCopyFromStage, materializeMemoryRepairWriterCopyFromStage, materializeMemorySecondRepairCopyFromStage, prepareMemoryRepairDispatchFromStage, prepareMemorySecondRepairDispatchFromStage, registerMemoryRepairCurrentViewFromStage, registerMemorySecondRepairCurrentViewFromStage, registerMemoryRepairPublicationSourceFromStage, reserveMemoryRepairPublicationAgainstSourceFromStage, reserveMemorySecondRepairPublicationFromStage, applyMemoryRepairPublicationFromStage, applyMemorySecondRepairPublicationFromStage, finishMemoryRepairPublicationFromStage, finishMemorySecondRepairPublicationFromStage } from "../services/memory-review-handler.js";
75
79
  import { mergeServerStatus, serveMergeRequests, stopMergeServer } from "../services/merge-server.js";
76
- import { getVnextFanoutStatus, memoryStageFanoutDescriptor, observeVnextNativeChildren, prepareNativeObservations, reconcileVnextFanout } from "../services/vnext-fanout.js";
80
+ import { getVnextFanoutStatus, memoryStageFanoutDescriptor, diagnosticStageFanoutDescriptor, observeVnextNativeChildren, prepareNativeObservations, reconcileVnextFanout } from "../services/vnext-fanout.js";
77
81
  import { pauseStageForUser, resumeStageAfterUser, prepareStagePause, prepareStageResume, stagePauseCommand } from "../services/stage-pause.js";
78
82
  import { runtimeCommand } from "../services/runtime-command.js";
79
83
  import { managedLifecycleCommand } from "../services/lifecycle-invocations.js";
@@ -81,7 +85,7 @@ import { blockStageForRuntime, unblockStageAfterRuntimeRepair, prepareStageRunti
81
85
  import { classifyCliOperation, requiresExplicitUpgradeAuthorization } from "../services/cli-operation-classifier.js";
82
86
  import { prepareWorkerPrompt, renderWorkerPrompt } from "../services/prompts.js";
83
87
  import { finishStage, prepareStageFinish, startStage, prepareLegacyStageStart } from "../services/stage-lifecycle.js";
84
- import { addWorkBatch, prepareWorkBatch, prepareWorkDeps, prepareWorkDelete, prepareWorkSettlement, prepareWorkRetry, assertStageLifecycleOwner, assertWorkLifecycleOwner, cancelWork, deleteWork, failWork, finishWork, listWorks, mutateWorkDeps, prepareWorkResult, workResultByteLimit, retryWork, showWork, startWork } from "../services/work-registry.js";
88
+ import { addWorkBatch, assertGenericWorkBatchAllowed, prepareWorkBatch, prepareWorkDeps, prepareWorkDelete, prepareWorkSettlement, prepareWorkRetry, assertStageLifecycleOwner, assertWorkLifecycleOwner, cancelWork, deleteWork, failWork, finishWork, listWorks, mutateWorkDeps, prepareWorkResult, workResultByteLimit, retryWork, showWork, startWork } from "../services/work-registry.js";
85
89
  import { launchExternalWork } from "../services/external-work-launch.js";
86
90
  import { createEvalBootstrapSnapshot, prepareEvalBootstrapSnapshot, createEvalRunSnapshot, prepareEvalRunSnapshotCreation, prepareVnextSpecifyRun, prepareEvalRunRestore, prepareEvalBootstrapRestore, restoreEvalBootstrapSnapshot, restoreEvalRunSnapshot } from "../services/eval-snapshots.js";
87
91
  import { forkRunFromSnapshot, prepareRunFork } from "../services/run-fork.js";
@@ -328,7 +332,7 @@ async function runCliRequest(args, io, env) {
328
332
  if (!invocationId) {
329
333
  const preparationContext = createContext({ ...env }, "read_existing", undefined, maintenanceOptions);
330
334
  try {
331
- preparedInput = await prepareCliInput(invocationArgs, preparationContext, io, scopeProjectRoot, output.responseFile);
335
+ preparedInput = await prepareCliInput(invocationArgs, preparationContext, io, scopeProjectRoot, output.responseFile, undefined, commandProgress(io, output));
332
336
  }
333
337
  finally {
334
338
  preparationContext.db.close?.();
@@ -357,8 +361,8 @@ async function runCliRequest(args, io, env) {
357
361
  throw error;
358
362
  }
359
363
  },
360
- prepare: async () => { preparedInput = await prepareCliInput(invocationArgs, dispatchContext, io, scopeProjectRoot, output.responseFile, preparedRoute); },
361
- assertCurrent: scope => assertLifecycleInvocationCurrent(dispatchContext, scope, command) });
364
+ prepare: async () => { preparedInput = await prepareCliInput(invocationArgs, dispatchContext, io, scopeProjectRoot, output.responseFile, preparedRoute, commandProgress(io, output)); },
365
+ assertCurrent: scope => assertLifecycleInvocationCurrent(dispatchContext, scope, command), progress: commandProgress(io, output) });
362
366
  if (admission.replay) {
363
367
  retainedOutcome = admission.outcome;
364
368
  settleHook = undefined;
@@ -386,7 +390,7 @@ async function runCliRequest(args, io, env) {
386
390
  throw new AppError(error.code, error.message, error.exitCode, error.details);
387
391
  }
388
392
  if (!retainedOutcome && !preparedInput)
389
- preparedInput = await prepareCliInput(invocationArgs, dispatchContext, io, scopeProjectRoot, output.responseFile);
393
+ preparedInput = await prepareCliInput(invocationArgs, dispatchContext, io, scopeProjectRoot, output.responseFile, undefined, commandProgress(io, output));
390
394
  if (!retainedOutcome)
391
395
  await preflightCliCompatibility(dispatchContext, invocationArgs, env, scopeProjectRoot);
392
396
  if (!retainedOutcome) {
@@ -394,11 +398,10 @@ async function runCliRequest(args, io, env) {
394
398
  const event = !invocationId ? nativeEvent : null;
395
399
  settleHook = observeLifecycleCommand(dispatchContext, command, event ?? undefined);
396
400
  }
397
- const result = retainedOutcome ? retainedOutcome.result : await dispatch(dispatchArgs, dispatchContext, io, scopeProjectRoot, classification, output, preparedInput);
398
- if (!retainedOutcome && invocationArgs[0] === "stage" && invocationArgs[1] === "start"
399
- && result && typeof result === "object" && "prompt_path" in result && typeof result.prompt_path === "string") {
401
+ const result = preparePromptDelivery(retainedOutcome ? retainedOutcome.result : await dispatch(dispatchArgs, dispatchContext, io, scopeProjectRoot, classification, output, preparedInput));
402
+ if (!retainedOutcome && result && typeof result === "object" && "worker_prompt_markdown" in result && typeof result.worker_prompt_markdown === "string") {
400
403
  try {
401
- bindLifecyclePublishedPacket(dispatchContext, fs.readFileSync(result.prompt_path, "utf8"));
404
+ bindLifecyclePublishedPacket(dispatchContext, result.worker_prompt_markdown);
402
405
  }
403
406
  catch (cause) {
404
407
  throw new AppError("invocation_packet_binding_failed", "Stage started but its published lifecycle assignments could not be retained", 1, { effect: "committed", cause: String(cause) });
@@ -422,6 +425,7 @@ async function runCliRequest(args, io, env) {
422
425
  writeProgressJsonl(io, "done", "Command finished");
423
426
  emitHumanProgress(io, output, progress, "done");
424
427
  const payload = attachProgress(resultWithWarnings, progress, output);
428
+ publishPromptDelivery(payload);
425
429
  const visible = writeResponseFile(payload, output);
426
430
  const maintenanceReceipt = payload;
427
431
  const maintenanceExpiry = maintenanceReceipt?.lease_expires_at ?? maintenanceReceipt?.process?.lease_expires_at;
@@ -436,7 +440,7 @@ async function runCliRequest(args, io, env) {
436
440
  const record = errorRecord(caught);
437
441
  maintenanceDiagnostics?.failure(caught);
438
442
  const error = isAppError(caught) ? caught : Object.assign(new AppError(record.code, record.message, record.exitCode, { effect: "unknown", ...record.details, ...(caught?.errcode !== undefined ? { sqlite_extended_code: caught.errcode } : {}) }), { ...(record.cause ? { cause: record.cause } : {}), ...(record.cleanup_error ? { cleanup_error: record.cleanup_error } : {}), ...(record.retryable !== undefined ? { retryable: record.retryable } : {}) });
439
- if (!settleHook && !invocationSettlement) {
443
+ if (!settleHook && !invocationSettlement && error.code !== "prompt_delivery_pending") {
440
444
  let earlyContext;
441
445
  try {
442
446
  const command = quote(["dd-flow", ...args]);
@@ -481,11 +485,9 @@ async function runCliRequest(args, io, env) {
481
485
  if (isAppError(error)) {
482
486
  delete error.details.retry_command;
483
487
  delete error.details.retry_instruction;
484
- const settled = errorRecord(error);
485
- settleLifecycleRejection(invocationSettlement.context, invocationSettlement.id, settled);
486
- // Serialization owns a copy. Publish the committed settlement, not
487
- // the original rejection which has no successor authority.
488
- Object.assign(error.details, settled.details);
488
+ // The common settlement classifies original validated proof before
489
+ // errorRecord clones diagnostic objects and loses capability identity.
490
+ settleLifecycleRejection(invocationSettlement.context, invocationSettlement.id, error);
489
491
  }
490
492
  else
491
493
  settleLifecycleInvocation(invocationSettlement.context, invocationSettlement.id, { error: { code: "unexpected", message: String(error), exitCode: 1, details: {} } });
@@ -558,6 +560,8 @@ function databaseModeForCommand(args, classification) {
558
560
  if (isRuntimeMaintenance(args))
559
561
  return "read_existing";
560
562
  const [family, command] = args;
563
+ if (family === "migration" && command === "readiness")
564
+ return "prepared_existing";
561
565
  // Managed attempts are issued only from a prepared store. Opening that
562
566
  // existing writer must not run migrations before their input is admitted.
563
567
  if (parseArgs(args.slice(2)).options.has("invocation-id"))
@@ -635,7 +639,12 @@ function writeProgressJsonl(io, phase, message, detail) {
635
639
  io.stderr.write(`${JSON.stringify({ schema_id: "dd-flow/progress@1", phase, message, at: new Date().toISOString(), ...(detail ? { detail } : {}) })}\n`);
636
640
  }
637
641
  function commandProgress(io, output) {
638
- return (message) => output.progressJsonl ? writeProgressJsonl(io, "running", message) : io.stderr.write(`[running] ${message}\n`);
642
+ return (message) => {
643
+ if (output.progressJsonl)
644
+ writeProgressJsonl(io, "running", message);
645
+ else if (!output.json && !output.hookJsonOnly)
646
+ io.stderr.write(`[running] ${message}\n`);
647
+ };
639
648
  }
640
649
  function attachProgress(result, progress, output) {
641
650
  if (progress.length === 0 || output.hookJsonOnly)
@@ -842,6 +851,14 @@ function stringValue(value) {
842
851
  function shortSha(value) {
843
852
  return value ? value.slice(0, 12) : "unknown";
844
853
  }
854
+ function compositionProposalRetry(context, parsed) {
855
+ return {
856
+ retry_command: runtimeCommand(context, ["memory", "compose", "register", "--run", requiredOption(parsed, "run"),
857
+ "--project-root", requiredOption(parsed, "project-root"), "--request-key", requiredOption(parsed, "request-key"),
858
+ "--result-file", requiredOption(parsed, "result-file"), "--json", "--progress-jsonl"]),
859
+ retry_instruction: "Correct only the rejected composition proposal, then execute retry_command in this same Session. No Work graph was registered by this rejected call; do not dispatch children or finish the Stage until registration succeeds."
860
+ };
861
+ }
845
862
  /** All caller supplied file/stdin data is consumed here, before a managed
846
863
  * invocation is allowed to claim execution or a stage claims its hook event. */
847
864
  async function prepareCliInput(...args) {
@@ -852,7 +869,7 @@ async function prepareCliInput(...args) {
852
869
  return prepareError(error);
853
870
  }
854
871
  }
855
- async function prepareCliInputValue(args, context, io, scopeProjectRoot, responseFile = null, route = prepareCommandRoute(args)) {
872
+ async function prepareCliInputValue(args, context, io, scopeProjectRoot, responseFile = null, route = prepareCommandRoute(args), progress) {
856
873
  const { family, command, parsed } = route;
857
874
  const prepared = { route };
858
875
  if (optionalOption(parsed, "reason-file")) {
@@ -941,6 +958,10 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
941
958
  prepared.codexHooks = prepareCodexHooks(context, { projectRoot: requiredOption(parsed, "project-root"), target: optionalOption(parsed, "target"), profile: optionalOption(parsed, "profile"), yes: hasOption(parsed, "yes") });
942
959
  if (route.key === "migration apply")
943
960
  prepared.migrationApply = prepareMigrationApply(context, migrationApplyInput(parsed, classifyCliOperation(args, context.env)));
961
+ if (route.key === "migration readiness")
962
+ prepared.upgradeStorageScope = {
963
+ projectRoot: requiredOption(parsed, "project-root"), workspaceRoot: requiredOption(parsed, "workspace-root"), requestId: requiredOption(parsed, "request-id")
964
+ };
944
965
  if (route.key === "migration verify")
945
966
  prepared.migrationVerification = verifyMigrationReport(context, { file: requiredOption(parsed, "file") });
946
967
  if (responseFile)
@@ -1115,6 +1136,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1115
1136
  if (route.key === "work add-batch") {
1116
1137
  const file = requiredOption(parsed, "file");
1117
1138
  try {
1139
+ assertGenericWorkBatchAllowed(context, requiredOption(parsed, "parent"));
1118
1140
  prepared.workBatch = prepareWorkBatch(context, { parentWorkId: requiredOption(parsed, "parent"), file,
1119
1141
  ...(optionalOption(parsed, "stage") ? { stage: optionalOption(parsed, "stage") } : {}),
1120
1142
  ...(optionalOption(parsed, "request-key") ? { requestKey: optionalOption(parsed, "request-key") } : {}) });
@@ -1210,14 +1232,15 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1210
1232
  const bundle = readFlowRunExecutionBundle(context, { projectRoot: requiredOption(parsed, "project-root"), runId: requiredPosition(parsed, 0, "run-id") });
1211
1233
  if (bundle)
1212
1234
  prepared.stageBindingBundle = { stage, bundle, ...(contextSha256 ? { contextSha256 } : {}) };
1213
- if (bundle?.descriptor.descriptor.id === "mb-init") {
1235
+ if (bundle && (["mb-init", "mb-upgrade"].includes(bundle.descriptor.descriptor.id) || isDiagnosticFlow(bundle.descriptor.descriptor.id))) {
1214
1236
  bundle.descriptor.stage(stage);
1215
1237
  if (hasOption(parsed, "dir"))
1216
1238
  throw new AppError("usage", "Memory stage layout belongs to its frozen descriptor", 2);
1217
1239
  const loaded = contextFile && contextSha256 ? loadExternalStageContext({ file: contextFile, expectedSha256: contextSha256, stage }) : undefined;
1218
1240
  if (loaded)
1219
1241
  prepared.stageStart = { externalContext: loaded };
1220
- prepared.memoryStage = { operation: "start", bytes: loaded ? Buffer.from(loaded.bytes) : Buffer.alloc(0) };
1242
+ prepared.memoryStage = { operation: "start", bytes: loaded ? Buffer.from(loaded.bytes) : Buffer.alloc(0),
1243
+ flowId: isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
1221
1244
  return prepared;
1222
1245
  }
1223
1246
  }
@@ -1313,7 +1336,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1313
1336
  throw new AppError("usage", "work finish requires exactly one of --result-file or --result-stdin", 2);
1314
1337
  const maxBytes = workResultByteLimit(context, requiredPosition(parsed, 0, "work-id"));
1315
1338
  prepared.workFinish = { result: resultFile ? prepareTextFile(resultFile, "Work result", maxBytes).text : await readStdin(io.stdin, maxBytes) };
1316
- prepareWorkResult(context, requiredPosition(parsed, 0, "work-id"), prepared.workFinish.result);
1339
+ prepareWorkResult(context, requiredPosition(parsed, 0, "work-id"), prepared.workFinish.result, progress);
1317
1340
  }
1318
1341
  if (family === "stage" && command === "fanout" && requiredPosition(parsed, 0, "fanout action") === "reconcile") {
1319
1342
  prepared.observations = prepareNativeObservations(prepareJsonFile(requiredOption(parsed, "observations-file"), "native observations").value);
@@ -1323,10 +1346,18 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1323
1346
  }
1324
1347
  if (family === "memory" && (["compose", "corrections"].includes(command ?? "") && parsed.positional[0] === "register"
1325
1348
  || command === "repair" && parsed.positional[0] === "publication-reserve")) {
1326
- const bytes = prepareFileBytes(requiredOption(parsed, "result-file"), `Memory ${command} result`, 1024 * 1024).bytes;
1327
- if (!bytes.length || bytes.length > 1024 * 1024)
1328
- throw new AppError("usage", "Memory operation result exceeds its byte bound", 2);
1329
- prepared.memoryOperationBytes = bytes;
1349
+ try {
1350
+ const bytes = prepareFileBytes(requiredOption(parsed, "result-file"), `Memory ${command} result`, 1024 * 1024).bytes;
1351
+ if (!bytes.length || bytes.length > 1024 * 1024)
1352
+ throw new AppError("usage", "Memory operation result exceeds its byte bound", 2, { phase: "prepare", effect: "no_effect", recoverable: true });
1353
+ prepared.memoryOperationBytes = bytes;
1354
+ }
1355
+ catch (error) {
1356
+ if (command === "compose" && isAppError(error) && error.details.phase === "prepare"
1357
+ && error.details.effect === "no_effect" && error.details.recoverable === true)
1358
+ Object.assign(error.details, compositionProposalRetry(context, parsed));
1359
+ throw error;
1360
+ }
1330
1361
  }
1331
1362
  if (family !== "stage" || command !== "finish")
1332
1363
  return prepared;
@@ -1343,10 +1374,11 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1343
1374
  const semanticFile = optionalOption(parsed, "semantic-file") ?? optionalOption(parsed, "data");
1344
1375
  const resultFile = optionalOption(parsed, "result-file") ?? semanticFile;
1345
1376
  const runtime = run(projectRoot, runId);
1346
- if (JSON.parse(runtime.indexJson).execution_bundle?.flow_id === "mb-init") {
1377
+ const retainedFlowId = JSON.parse(runtime.indexJson).execution_bundle?.flow_id;
1378
+ if (["mb-init", "mb-upgrade"].includes(retainedFlowId) || isDiagnosticFlow(retainedFlowId)) {
1347
1379
  const bundle = readFlowRunExecutionBundle(context, { projectRoot, runId });
1348
- if (!bundle || bundle.descriptor.descriptor.id !== "mb-init")
1349
- throw new AppError("cli_input_unprepared", "Memory RUN bundle is unavailable", 1);
1380
+ if (!bundle || !["mb-init", "mb-upgrade"].includes(bundle.descriptor.descriptor.id) && !isDiagnosticFlow(bundle.descriptor.descriptor.id))
1381
+ throw new AppError("cli_input_unprepared", "Registered RUN bundle is unavailable", 1);
1350
1382
  bundle.descriptor.stage(stage);
1351
1383
  if (["dir", "outcome", "decision-file", "verification-file", "retry-check", "reason", "reason-file", "request", "work"].some(option => hasOption(parsed, option)))
1352
1384
  throw new AppError("usage", "Memory stage finish requires its registered JSON result, not legacy result options", 2);
@@ -1355,7 +1387,7 @@ async function prepareCliInputValue(args, context, io, scopeProjectRoot, respons
1355
1387
  const bytes = resultStdin ? Buffer.from(await readStdin(io.stdin, 1024 * 1024)) : prepareFileBytes(resultFile, "Memory stage result", 1024 * 1024).bytes;
1356
1388
  if (!bytes.length || bytes.length > 1024 * 1024)
1357
1389
  throw new AppError("usage", "Memory stage result exceeds its byte bound", 2);
1358
- prepared.memoryStage = { operation: "finish", bytes };
1390
+ prepared.memoryStage = { operation: "finish", bytes, flowId: isDiagnosticFlow(bundle.descriptor.descriptor.id) ? bundle.descriptor.descriptor.id : bundle.descriptor.descriptor.id === "mb-upgrade" ? "mb-upgrade" : "mb-init" };
1359
1391
  return prepared;
1360
1392
  }
1361
1393
  const terminalReplay = (name) => {
@@ -1668,6 +1700,7 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
1668
1700
  });
1669
1701
  }
1670
1702
  if (family === "work" && command === "add-batch") {
1703
+ assertGenericWorkBatchAllowed(context, requiredOption(parsed, "parent"));
1671
1704
  return addWorkBatch(context, { parentWorkId: requiredOption(parsed, "parent"), file: requiredOption(parsed, "file"), prepared: prepared.workBatch,
1672
1705
  ...(optionalOption(parsed, "stage") ? { stage: optionalOption(parsed, "stage") } : {}),
1673
1706
  ...(optionalOption(parsed, "request-key") ? { requestKey: optionalOption(parsed, "request-key") } : {}) });
@@ -1694,7 +1727,7 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
1694
1727
  const hookEventId = optionalOption(parsed, "hook-event-id");
1695
1728
  const recoveryId = optionalOption(parsed, "recovery-id");
1696
1729
  const projectRoot = requiredScopeProjectRoot(scopeProjectRoot, "work start");
1697
- return startWork(context, requiredPosition(parsed, 0, "work-id"), { ...(hookEventId ? { hookEventId } : {}), ...(recoveryId ? { recoveryId } : {}), projectRoot });
1730
+ return startWork(context, requiredPosition(parsed, 0, "work-id"), { ...(hookEventId ? { hookEventId } : {}), ...(recoveryId ? { recoveryId } : {}), projectRoot, progress: commandProgress(io, output) });
1698
1731
  }
1699
1732
  if (family === "work" && command === "finish") {
1700
1733
  const resultFile = optionalOption(parsed, "result-file");
@@ -1748,7 +1781,7 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
1748
1781
  matchKey: entityReferenceVariants(runId).map(reference => stageStartMatchKey(reference, stage, projectRoot, contextSha256)),
1749
1782
  errorCode: "trusted_session_binding_required", operation: "Memory stage start"
1750
1783
  }).eventKey;
1751
- const work = startMemoryStage(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes });
1784
+ const work = (isDiagnosticFlow(prepared.memoryStage.flowId) ? startDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? startMemoryUpgradeStage : startMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes });
1752
1785
  try {
1753
1786
  const binding = bindStageCoordinatorWork(context, { workId: work.work_id, hookEventId: event, stage,
1754
1787
  promptPath: work.prompt_path, resultPath: work.result_path, ...(contextSha256 ? { contextSha256 } : {}) });
@@ -1758,7 +1791,7 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
1758
1791
  const finish = managedLifecycleCommand(context, runtimeCommand(context, ["stage", "finish", runId,
1759
1792
  "--stage", stage, "--project-root", projectRoot, "--result-file", work.result_path, "--json"]));
1760
1793
  const pause = stagePauseCommand(context, { projectRoot, runId, stage, workId: work.work_id });
1761
- const orchestration = memoryStageFanoutDescriptor(context, { projectRoot, runId, stage });
1794
+ const orchestration = memoryStageFanoutDescriptor(context, { projectRoot, runId, stage }) ?? diagnosticStageFanoutDescriptor(context, { projectRoot, runId, stage });
1762
1795
  const delivery = { ...work, binding, ...(orchestration ? { orchestration } : {}), next: { finish_command: finish, pause_command: pause },
1763
1796
  worker_prompt_markdown: `${work.worker_prompt_markdown}\n## Current lifecycle commands\n\nWrite the semantic result to the assigned result path, then execute exactly:\n${finish}\n\nFor a required user choice, write the question file named by this command, then execute exactly:\n${pause}\n` };
1764
1797
  bindLifecyclePublishedPacket(context, delivery.worker_prompt_markdown);
@@ -1867,7 +1900,7 @@ async function dispatch(args, context, io, scopeProjectRoot = null, classificati
1867
1900
  // Descriptor settlement validates exact coordinator custody and claims
1868
1901
  // the fresh hook atomically with result acceptance. Do not consume it
1869
1902
  // through the SDLC lifecycle owner before that settlement.
1870
- return controlledReply(finishMemoryStage(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes,
1903
+ return controlledReply((isDiagnosticFlow(prepared.memoryStage.flowId) ? finishDiagnosticStage : prepared.memoryStage.flowId === "mb-upgrade" ? finishMemoryUpgradeStage : finishMemoryStage)(context, { projectRoot, runId, stage, bytes: prepared.memoryStage.bytes,
1871
1904
  hookEventId: hookEventId ?? findRecentMatchingHookEvent(context, {
1872
1905
  projectId: requireProjectByRoot(context, resolveProjectRoot(projectRoot)).id,
1873
1906
  matchKey: entityReferenceVariants(runId).map(reference => stageLifecycleMatchKey("stage_finish", reference, stage, projectRoot)),
@@ -2179,6 +2212,13 @@ function dispatchEngine(context, command, parsed, classification, prepared) {
2179
2212
  function dispatchMigration(context, command, parsed, classification, prepared) {
2180
2213
  if (command === "impact")
2181
2214
  return assessMigrationImpact(context, { projectRoot: requiredOption(parsed, "project-root"), ...(optionalOption(parsed, "target-version") ? { targetVersion: optionalOption(parsed, "target-version") } : {}), ...(optionalOption(parsed, "mode") ? { mode: optionalOption(parsed, "mode") } : {}) });
2215
+ if (command === "readiness") {
2216
+ if (!prepared.upgradeStorageScope)
2217
+ throw new AppError("validation", "Upgrade storage scope must be prepared before publication", 2);
2218
+ // Unlike the initial readonly syntax pass, this connection is admitted
2219
+ // prepared-existing. Physical writer checks still precede receipt writes.
2220
+ return { ok: true, ...PreparedUpgradeStorageReadiness.prepare(context, prepared.upgradeStorageScope).apply(context) };
2221
+ }
2182
2222
  if (command === "plan" || command === "report") {
2183
2223
  return planMigration(context, {
2184
2224
  projectRoot: requiredOption(parsed, "project-root"),
@@ -2425,7 +2465,7 @@ function dispatchMemory(context, command, parsed, prepared) {
2425
2465
  const workspaceRoot = requiredOption(parsed, "workspace-root");
2426
2466
  if (wave === "2") {
2427
2467
  const bundle = readFlowRunExecutionBundle(context, work);
2428
- if (!bundle || bundle.descriptor.descriptor.id !== "mb-init" || bundle.execution.snapshot().scope.workspace !== workspaceRoot)
2468
+ if (!bundle || !["mb-init", "mb-upgrade"].includes(bundle.descriptor.descriptor.id) || bundle.execution.snapshot().scope.workspace !== workspaceRoot)
2429
2469
  throw new AppError("memory_repair_scope_invalid", "Repair workspace does not match its frozen memory RUN", 2, { phase: "prepare", effect: "no_effect" });
2430
2470
  }
2431
2471
  if (subcommand === "current-view")
@@ -2455,14 +2495,13 @@ function dispatchMemory(context, command, parsed, prepared) {
2455
2495
  if (error instanceof AppError && (error.code === "memory_stage_result_invalid"
2456
2496
  || error.code === "memory_preflight_handler_invalid" && ["unselected_preflight_source", "proposed_source_sha256_mismatch"].includes(String(error.details.reason))) && error.details.phase === "prepare"
2457
2497
  && error.details.effect === "no_effect" && error.details.recoverable === true) {
2458
- error.details.retry_command = runtimeCommand(context, ["memory", "compose", "register", "--run", requiredOption(parsed, "run"),
2459
- "--project-root", requiredOption(parsed, "project-root"), "--request-key", requiredOption(parsed, "request-key"),
2460
- "--result-file", requiredOption(parsed, "result-file"), "--json", "--progress-jsonl"]);
2461
- error.details.retry_instruction = "Correct only the rejected composition proposal, then execute retry_command in this same Session. No Work graph was registered by this rejected call; do not dispatch children or finish the Stage until registration succeeds.";
2498
+ Object.assign(error.details, compositionProposalRetry(context, parsed));
2462
2499
  }
2463
2500
  throw error;
2464
2501
  }
2465
2502
  }
2503
+ if (command === "upgrade" && subcommand === "publish")
2504
+ return publishMemoryUpgradeFromStage(context, scope());
2466
2505
  if (command === "verify" && subcommand === "checks")
2467
2506
  return runMemoryVerificationChecks(context, scope());
2468
2507
  if (command === "review" && subcommand === "register")
package/dist/cli/setup.js CHANGED
@@ -129,7 +129,8 @@ export async function runSetupCli(args, env, io = { stdout: process.stdout, stde
129
129
  throw error;
130
130
  }
131
131
  }
132
- result = { ...installed, action: route.key === "setup update" ? "setup_update" : "setup_install", observed_cli: observedCli,
132
+ result = { ...installed, request_installation: installed.installation,
133
+ action: route.key === "setup update" ? "setup_update" : "setup_install", observed_cli: observedCli,
133
134
  executor: installed.executor ? { profile_id: installed.executor.id, revision: hybridDigest(installed.executor), readiness: "unknown_requires_qualification" } : { profile_id: null, readiness: "not_configured" },
134
135
  ...readSetupStatus(home) };
135
136
  }
package/dist/cli.js CHANGED
@@ -49,10 +49,28 @@ if (args[0] === "init" || args[0] === "flow" && args[1] === "mb-init") {
49
49
  publishSetup('imports_ready');
50
50
  process.exit(await runMemoryInitCli(args, process.env));
51
51
  }
52
+ if (args[0] === "upgrade" || args[0] === "flow" && args[1] === "mb-upgrade") {
53
+ const { runMemoryUpgradeCli } = await import("./cli/memory-upgrade.js");
54
+ process.exit(await runMemoryUpgradeCli(args, process.env));
55
+ }
56
+ if (args[0] === "review" || args[0] === "flow" && ["mb-audit", "project-review"].includes(args[1] ?? "")) {
57
+ publishSetup('ingress_entered');
58
+ const { runDiagnosticCli } = await import("./cli/diagnostic.js");
59
+ publishSetup('imports_ready');
60
+ process.exit(await runDiagnosticCli(args, process.env));
61
+ }
52
62
  if (args.slice(0, 3).join(" ") === "runtime storage admit") {
53
63
  const { runMemoryStorageAdmissionCli } = await import("./cli/memory-storage-admission.js");
54
64
  process.exit(runMemoryStorageAdmissionCli(args));
55
65
  }
66
+ if (args.slice(0, 3).join(" ") === "runtime storage qualify") {
67
+ const { runMemoryStorageQualificationCli } = await import("./cli/memory-storage-qualification.js");
68
+ process.exit(runMemoryStorageQualificationCli(args));
69
+ }
70
+ if (args.slice(0, 3).join(" ") === "runtime storage transition") {
71
+ const { runMemoryStorageTransitionCli } = await import("./cli/memory-storage-transition.js");
72
+ process.exit(runMemoryStorageTransitionCli(args));
73
+ }
56
74
  if (args.slice(0, 3).join(" ") === "runtime flow admit") {
57
75
  const { runMemoryFlowAdmissionCli } = await import("./cli/memory-flow-admission.js");
58
76
  process.exit(await runMemoryFlowAdmissionCli(args));
@@ -0,0 +1,103 @@
1
+ /** Registered baseline coverage; applicability remains agent-owned. */
2
+ export const diagnosticAspects = {
3
+ "mb-audit": [
4
+ {
5
+ "id": "01",
6
+ "question": "Structure, indexes and reachability of active memory"
7
+ },
8
+ {
9
+ "id": "02",
10
+ "question": "Links, frontmatter and durable traceability"
11
+ },
12
+ {
13
+ "id": "03",
14
+ "question": "Source of truth, duplicates, freshness and factual contradictions"
15
+ },
16
+ {
17
+ "id": "04",
18
+ "question": "Delivery docs, epics/features, protocols and verification matrices"
19
+ },
20
+ {
21
+ "id": "05",
22
+ "question": "System boundaries, C4, ADRs and contracts"
23
+ },
24
+ {
25
+ "id": "06",
26
+ "question": "Scenarios, fixtures, evidence and runners"
27
+ },
28
+ {
29
+ "id": "07",
30
+ "question": "UI contracts and user guides"
31
+ },
32
+ {
33
+ "id": "08",
34
+ "question": "Engineering standards and code contracts"
35
+ },
36
+ {
37
+ "id": "09",
38
+ "question": "Operations, release policy and active named deferrals"
39
+ },
40
+ {
41
+ "id": "10",
42
+ "question": "Memory lifecycle, archives and durable promotion"
43
+ },
44
+ {
45
+ "id": "11",
46
+ "question": "Code-to-memory traceability"
47
+ },
48
+ {
49
+ "id": "12",
50
+ "question": "Project agent skills, prompts and execution guidance"
51
+ }
52
+ ],
53
+ "project-review": [
54
+ {
55
+ "id": "structure_navigation_review",
56
+ "question": "Can readers locate system truth and delivery evidence?"
57
+ },
58
+ {
59
+ "id": "feature_epic_layer_review",
60
+ "question": "Are durable capabilities and delivery layers coherent?"
61
+ },
62
+ {
63
+ "id": "spec_conformance_review",
64
+ "question": "Does actual project behavior conform to its normative specs?"
65
+ },
66
+ {
67
+ "id": "architecture_harmonization_review",
68
+ "question": "Are architecture and boundaries coherent top-down?"
69
+ },
70
+ {
71
+ "id": "adr_decision_review",
72
+ "question": "Are significant decisions, alternatives and consequences recorded?"
73
+ },
74
+ {
75
+ "id": "scenario_evidence_review",
76
+ "question": "Do actual scenarios, fixtures, checks and evidence cover capabilities?"
77
+ },
78
+ {
79
+ "id": "contract_traceability_review",
80
+ "question": "Are public contracts traced through implementation and tests?"
81
+ },
82
+ {
83
+ "id": "frontmatter_crosslink_review",
84
+ "question": "Are metadata and cross-links factual and current?"
85
+ },
86
+ {
87
+ "id": "engineering_standards_review",
88
+ "question": "Does actual code follow applicable engineering standards?"
89
+ },
90
+ {
91
+ "id": "operations_policy_review",
92
+ "question": "Are applicable Git, environment and delivery policies followed?"
93
+ },
94
+ {
95
+ "id": "protocol_delivery_trace_review",
96
+ "question": "Do protocols and RUNs factually establish delivery and closure?"
97
+ },
98
+ {
99
+ "id": "def_followup_review",
100
+ "question": "Are active DEFs visible, deduplicated and bound to future gates?"
101
+ }
102
+ ]
103
+ };
@@ -0,0 +1,8 @@
1
+ /** Only the accepted E5 read-only slice, not a registry of future workflows. */
2
+ export const diagnosticFlowStages = Object.freeze({
3
+ "mb-audit": ["preflight", "audit", "review", "report"],
4
+ "project-review": ["preflight", "analyze", "review", "report"]
5
+ });
6
+ export function isDiagnosticFlow(id) {
7
+ return typeof id === "string" && Object.hasOwn(diagnosticFlowStages, id);
8
+ }
@@ -18,3 +18,11 @@ export const memoryInitHandlerIdentities = Object.freeze({
18
18
  review: Object.freeze({ stage: "review", entryId: "memory-stage-entry", finishId: "memory-stage-finish" }),
19
19
  finish: Object.freeze({ stage: "finish", entryId: "memory-stage-entry", finishId: "memory-stage-finish" })
20
20
  });
21
+ export const memoryUpgradeHandlerIdentities = Object.freeze({
22
+ preflight: Object.freeze({ stage: "preflight", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" }),
23
+ "diff-analysis": Object.freeze({ stage: "diff-analysis", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" }),
24
+ upgrade: Object.freeze({ stage: "upgrade", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" }),
25
+ verify: Object.freeze({ stage: "verify", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" }),
26
+ review: Object.freeze({ stage: "review", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" }),
27
+ finish: Object.freeze({ stage: "finish", entryId: "memory-upgrade-stage-entry", finishId: "memory-upgrade-stage-finish" })
28
+ });
@@ -23,7 +23,7 @@ async function hook(options) {
23
23
  const normalized = { schema_id: "dd-flow/agy-tool-event@1", event_id: identity.event_id, phase, daemon_id: identity.daemon_id, launch_cwd: identity.launch_cwd, conversation_id: payload.conversationId, parent_conversation_id: identity.parent_conversation_id, execution_num: payload.executionNum, step_index: payload.stepIdx, tool: payload.toolCall?.name, input: args, workspace_paths: payload.workspacePaths, transcript_path: payload.transcriptPath, model: payload.modelName, profile: identity.profile, ...(phase === "after" ? { error: payload.error ?? "" } : {}) };
24
24
  await invokeNativeHook({ bin: options["dd-flow-bin"] ?? identity.dd_flow_bin,
25
25
  args: ["agy", "event", "handle", "--project-root", options["project-root"] ?? identity.project_root, "--json"],
26
- payload: normalized, home: options["dd-flow-home"] ?? identity.dd_flow_home, timeoutMs: budget.remaining("admission", 15_000) });
26
+ payload: normalized, home: options["dd-flow-home"] ?? identity.dd_flow_home, timeoutMs: budget.remaining("admission") });
27
27
  }
28
28
  return event === "PreToolUse" ? { decision: "allow" } : {};
29
29
  } catch (error) {
@@ -31,8 +31,8 @@ async function hook(options) {
31
31
  // reads only receipts matching request IDs it actually accepted this turn.
32
32
  const correctable = event === "PreToolUse" && error.code === "lifecycle_shell_syntax_invalid" && error.details?.effect === "no_effect"
33
33
  && error.details?.recoverable === true && error.details?.disposition === "pre_cli_shell_refusal";
34
- try { await writeJsonAtomic(path.join(options["state-dir"], "hook-failures", `${requestId}.json`), { request_id: requestId, observed_at: new Date().toISOString(), code: error.code ?? "agy_hook_rejected", message: error.message,
35
- details: { ...error.details, effect: correctable ? "no_effect" : "unknown", ...(correctable ? { native_pre_cli_refusal: true } : {}) } }); }
34
+ try { await budget.run(() => writeJsonAtomic(path.join(options["state-dir"], "hook-failures", `${requestId}.json`), { request_id: requestId, observed_at: new Date().toISOString(), code: error.code ?? "agy_hook_rejected", message: error.message,
35
+ details: { ...error.details, effect: correctable ? "no_effect" : "unknown", ...(correctable ? { native_pre_cli_refusal: true } : {}) } }, () => budget.remaining("failure_receipt_commit")), "failure_receipt"); }
36
36
  catch (storage) { process.stderr.write(`${JSON.stringify({ code: error.code, receipt_error: storage.message })}\n`); }
37
37
  throw error;
38
38
  }
@@ -12,12 +12,12 @@ async function hook(options) {
12
12
  const budget = hookBudget();
13
13
  const stdin = await readNativeHookInput(process.stdin, budget); const payload = JSON.parse(stdin || "{}"); const identity = await callDaemon(options["state-dir"], "hook.resolve", { sessionId: payload.sessionId ?? payload.session_id, payload }, budget.remaining("identity"));
14
14
  const enriched = { ...payload, _meta: { ...(payload._meta ?? {}), ddGrok: identity } }; const args = ["grok", "event", "handle", "--project-root", options["project-root"], "--json"]; const command = options["dd-flow-bin"];
15
- try { return await invokeNativeHook({ bin: command, args, home: options["dd-flow-home"], payload: enriched, timeoutMs: budget.remaining("admission", 15_000) }); }
15
+ try { return await invokeNativeHook({ bin: command, args, home: options["dd-flow-home"], payload: enriched, timeoutMs: budget.remaining("admission") }); }
16
16
  catch (error) {
17
17
  if (identity.nativeHookBinding) error.details = { ...error.details, native_hook_binding: identity.nativeHookBinding };
18
18
  try {
19
- await writeNativeHookFailure(options["state-dir"], identity.nativeHookBinding, error, hookBudget(1_000, null));
20
- if (identity.nativeHookBinding) await callDaemon(options["state-dir"], "hook.failed", { requestId: identity.nativeHookBinding.request_id }, 1_000);
19
+ await writeNativeHookFailure(options["state-dir"], identity.nativeHookBinding, error, budget);
20
+ if (identity.nativeHookBinding) await callDaemon(options["state-dir"], "hook.failed", { requestId: identity.nativeHookBinding.request_id }, budget.remaining("failure_notification"));
21
21
  } catch (storage) { process.stderr.write(`${JSON.stringify({ code: error.code, receipt_error: storage.message })}\n`); }
22
22
  throw error;
23
23
  }
@@ -37,14 +37,14 @@ async function hook(options) {
37
37
  const identity = await callDaemon(options["state-dir"], "hook.resolve", { sessionId: payload.session_id ?? payload.sessionId, payload }, budget.remaining("identity"));
38
38
  const command = options["dd-flow-bin"]; const args = ["zcode", "hook", "handle", "--project-root", options["project-root"], "--json"];
39
39
 
40
- try { return await invokeNativeHook({ bin: command, args, home: options["dd-flow-home"], timeoutMs: budget.remaining("admission", 15_000), payload: { ...payload, _meta: { ...(payload._meta ?? {}), ddZcode: identity } } }); }
40
+ try { return await invokeNativeHook({ bin: command, args, home: options["dd-flow-home"], timeoutMs: budget.remaining("admission"), payload: { ...payload, _meta: { ...(payload._meta ?? {}), ddZcode: identity } } }); }
41
41
  catch (error) {
42
42
  if (identity.nativeHookBinding) error.details = { ...error.details, native_hook_binding: identity.nativeHookBinding };
43
43
  try {
44
- // The 25s work budget leaves this bounded 2s evidence tail inside the
45
- // qualified 30s native hook limit, even after the work deadline expired.
46
- await writeNativeHookFailure(options["state-dir"], identity.nativeHookBinding, error, hookBudget(1_000, null));
47
- if (identity.nativeHookBinding) await callDaemon(options["state-dir"], "hook.failed", { requestId: identity.nativeHookBinding.request_id }, 1_000);
44
+ // Evidence shares the original deadline; an expired admission cannot
45
+ // start a new independent failure-report window.
46
+ await writeNativeHookFailure(options["state-dir"], identity.nativeHookBinding, error, budget);
47
+ if (identity.nativeHookBinding) await callDaemon(options["state-dir"], "hook.failed", { requestId: identity.nativeHookBinding.request_id }, budget.remaining("failure_notification"));
48
48
  } catch (storage) { process.stderr.write(`${JSON.stringify({ code: error.code, receipt_error: storage.message })}\n`); }
49
49
  throw error;
50
50
  }