@deksden-com/dd-flow-cli 0.9.0-beta.136 → 0.9.0-beta.138

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 (230) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +9 -0
  3. package/dist/build-info.json +6 -6
  4. package/dist/cli/argument-values.js +5 -5
  5. package/dist/cli/command-inputs.js +89 -20
  6. package/dist/cli/command-metadata.js +56 -3
  7. package/dist/cli/command-option-descriptions.js +5 -0
  8. package/dist/cli/executor-onboarding.js +8 -3
  9. package/dist/cli/flows.js +29 -0
  10. package/dist/cli/help.js +240 -6
  11. package/dist/cli/input-preparation.js +54 -5
  12. package/dist/cli/memory-flow-admission.js +44 -0
  13. package/dist/cli/memory-init-invocation.js +78 -0
  14. package/dist/cli/memory-init.js +240 -0
  15. package/dist/cli/memory-storage-admission.js +53 -0
  16. package/dist/cli/native-hook-ingress.js +1 -1
  17. package/dist/cli/response-file.js +2 -0
  18. package/dist/cli/run-cli.js +283 -160
  19. package/dist/cli/setup.js +9 -7
  20. package/dist/cli.js +54 -2
  21. package/dist/domain/stage-handler-identities.js +20 -0
  22. package/dist/harness-runtime/DD-ZCODE.md +13 -0
  23. package/dist/harness-runtime/bin/dd-opencode.mjs +3 -3
  24. package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
  25. package/dist/harness-runtime/lib/daemon-operations.mjs +4 -3
  26. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +4 -2
  27. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +11 -5
  28. package/dist/harness-runtime/lib/dd-codex.mjs +22 -10
  29. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +2 -1
  30. package/dist/harness-runtime/lib/dd-droid.mjs +2 -1
  31. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +4 -2
  32. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +20 -5
  33. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +45 -10
  34. package/dist/harness-runtime/lib/dd-zcode.mjs +7 -3
  35. package/dist/harness-runtime/lib/delegation-instructions.mjs +5 -3
  36. package/dist/harness-runtime/lib/lifecycle-command.mjs +1 -0
  37. package/dist/harness-runtime/lib/managed-daemon.d.mts +1 -0
  38. package/dist/harness-runtime/lib/managed-daemon.mjs +50 -15
  39. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  40. package/dist/harness-runtime/lib/native-hook-command.mjs +1 -1
  41. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  42. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  43. package/dist/harness-runtime/lib/opencode-plugin.mjs +5 -1
  44. package/dist/harness-runtime/lib/operation-progress.mjs +3 -1
  45. package/dist/runtime/context.js +1 -1
  46. package/dist/schemas/discovery-result.schema.json +184 -0
  47. package/dist/schemas/execution-bundle.schema.json +205 -0
  48. package/dist/schemas/execution-settings.schema.json +162 -0
  49. package/dist/schemas/flow-descriptor.schema.json +54 -0
  50. package/dist/schemas/flow-run.schema.json +22 -0
  51. package/dist/schemas/harness-catalog.schema.json +80 -0
  52. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  53. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  54. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  55. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  56. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  57. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  58. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  59. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  60. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  61. package/dist/schemas/memory-repair-work-result.schema.json +49 -0
  62. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  63. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  64. package/dist/schemas/model-catalog.schema.json +153 -0
  65. package/dist/schemas/profile-settings.schema.json +122 -0
  66. package/dist/schemas/release-manifest.schema.json +291 -0
  67. package/dist/schemas/run-engine-binding.schema.json +1 -1
  68. package/dist/services/check-runner-evidence.js +51 -4
  69. package/dist/services/cli-operation-classifier.js +8 -47
  70. package/dist/services/code-checks.js +387 -34
  71. package/dist/services/controller-child-observer.js +99 -0
  72. package/dist/services/controller-execution.js +88 -0
  73. package/dist/services/controller-fanout.js +79 -13
  74. package/dist/services/dashboard.js +8 -2
  75. package/dist/services/descriptor-coordinator-session.js +35 -0
  76. package/dist/services/descriptor-root-work.js +53 -0
  77. package/dist/services/descriptor-run-settlement.js +105 -0
  78. package/dist/services/descriptor-run-start.js +449 -0
  79. package/dist/services/descriptor-stage-coordinator.js +197 -0
  80. package/dist/services/descriptor-stage-settlement.js +222 -0
  81. package/dist/services/descriptor-stage-start.js +139 -0
  82. package/dist/services/engines.js +39 -22
  83. package/dist/services/eval-snapshots.js +83 -25
  84. package/dist/services/execution-bundles.js +263 -0
  85. package/dist/services/execution-policy.js +20 -16
  86. package/dist/services/external-work-launch.js +91 -11
  87. package/dist/services/flow-catalog.js +21 -0
  88. package/dist/services/flow-descriptors.js +82 -0
  89. package/dist/services/frozen-engine.js +242 -0
  90. package/dist/services/generic-execution.js +164 -0
  91. package/dist/services/harness-adapter.js +28 -2
  92. package/dist/services/hooks.js +24 -6
  93. package/dist/services/hybrid-contracts.js +31 -3
  94. package/dist/services/ids.js +29 -1
  95. package/dist/services/installation-lock.js +7 -4
  96. package/dist/services/installed-flow-source.js +183 -0
  97. package/dist/services/lifecycle-invocations.js +257 -78
  98. package/dist/services/memory-accepted-composition.js +77 -0
  99. package/dist/services/memory-baseline-preservation.js +65 -0
  100. package/dist/services/memory-completed-correction-wave.js +320 -0
  101. package/dist/services/memory-compose-handler.js +258 -0
  102. package/dist/services/memory-composition-acceptance.js +199 -0
  103. package/dist/services/memory-composition-graph.js +134 -0
  104. package/dist/services/memory-composition-registration.js +146 -0
  105. package/dist/services/memory-composition-work-custody.js +151 -0
  106. package/dist/services/memory-composition-work-results.js +96 -0
  107. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  108. package/dist/services/memory-corrected-review-batch.js +30 -0
  109. package/dist/services/memory-corrected-review-findings.js +106 -0
  110. package/dist/services/memory-corrected-review-inputs.js +210 -0
  111. package/dist/services/memory-corrected-review-projection.js +78 -0
  112. package/dist/services/memory-corrected-review-receipt.js +170 -0
  113. package/dist/services/memory-corrected-review-registration.js +191 -0
  114. package/dist/services/memory-correction-check-receipt.js +219 -0
  115. package/dist/services/memory-correction-input-owner.js +6 -0
  116. package/dist/services/memory-discover-handler.js +104 -0
  117. package/dist/services/memory-finish-evidence.js +435 -0
  118. package/dist/services/memory-finish-handler.js +215 -0
  119. package/dist/services/memory-finish-integration.js +280 -0
  120. package/dist/services/memory-finish-readiness.js +122 -0
  121. package/dist/services/memory-git-integration.js +151 -0
  122. package/dist/services/memory-historical-corrected-review.js +206 -0
  123. package/dist/services/memory-historical-original-review.js +130 -0
  124. package/dist/services/memory-historical-repair-registration.js +99 -0
  125. package/dist/services/memory-historical-second-review.js +128 -0
  126. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  127. package/dist/services/memory-init-contexts.js +89 -0
  128. package/dist/services/memory-init-controller-start.js +84 -0
  129. package/dist/services/memory-init-engine-release.js +223 -0
  130. package/dist/services/memory-init-git-policy.js +136 -0
  131. package/dist/services/memory-init-lint-capability.js +185 -0
  132. package/dist/services/memory-init-native-capacity.js +241 -0
  133. package/dist/services/memory-init-preflight.js +312 -0
  134. package/dist/services/memory-init-project-bootstrap.js +599 -0
  135. package/dist/services/memory-init-request-candidate.js +157 -0
  136. package/dist/services/memory-init-request-input.js +66 -0
  137. package/dist/services/memory-init-resource-storage.js +125 -0
  138. package/dist/services/memory-init-run-allocation.js +81 -0
  139. package/dist/services/memory-init-run-bundle.js +98 -0
  140. package/dist/services/memory-init-start.js +175 -0
  141. package/dist/services/memory-init-startup-custody.js +80 -0
  142. package/dist/services/memory-init-startup-input.js +240 -0
  143. package/dist/services/memory-init-storage.js +81 -0
  144. package/dist/services/memory-init-stores.js +359 -0
  145. package/dist/services/memory-init-worktrunk-capability.js +172 -0
  146. package/dist/services/memory-layer-publication.js +611 -0
  147. package/dist/services/memory-layer.js +156 -0
  148. package/dist/services/memory-lint-config.js +85 -0
  149. package/dist/services/memory-native-review-copy.js +165 -0
  150. package/dist/services/memory-normal-flow-entry.js +75 -0
  151. package/dist/services/memory-ordinary-defaults.js +112 -0
  152. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  153. package/dist/services/memory-preflight-handler.js +259 -0
  154. package/dist/services/memory-repair-current-view.js +299 -0
  155. package/dist/services/memory-repair-document-delta.js +451 -0
  156. package/dist/services/memory-repair-history.js +491 -0
  157. package/dist/services/memory-repair-physical-binding.js +312 -0
  158. package/dist/services/memory-repair-publication-files.js +152 -0
  159. package/dist/services/memory-repair-publication-intent.js +27 -0
  160. package/dist/services/memory-repair-publication-plan.js +160 -0
  161. package/dist/services/memory-repair-publication-source.js +225 -0
  162. package/dist/services/memory-repair-publication.js +794 -0
  163. package/dist/services/memory-repair-registration.js +239 -0
  164. package/dist/services/memory-repair-work-baseline.js +413 -0
  165. package/dist/services/memory-repair-work-completion.js +97 -0
  166. package/dist/services/memory-repair-work-custody.js +73 -0
  167. package/dist/services/memory-repair-work-results.js +89 -0
  168. package/dist/services/memory-repair-workspace.js +252 -0
  169. package/dist/services/memory-repair-writer-copy.js +735 -0
  170. package/dist/services/memory-result-binding.js +173 -0
  171. package/dist/services/memory-retained-review-authority.js +129 -0
  172. package/dist/services/memory-retained-review-results.js +70 -0
  173. package/dist/services/memory-retained-second-baseline.js +102 -0
  174. package/dist/services/memory-retained-second-repairs.js +156 -0
  175. package/dist/services/memory-review-acceptance.js +214 -0
  176. package/dist/services/memory-review-correction-plan.js +171 -0
  177. package/dist/services/memory-review-handler.js +585 -0
  178. package/dist/services/memory-review-inputs.js +200 -0
  179. package/dist/services/memory-review-receipt.js +180 -0
  180. package/dist/services/memory-review-registration.js +108 -0
  181. package/dist/services/memory-review-work-custody.js +124 -0
  182. package/dist/services/memory-review-work-input.js +72 -0
  183. package/dist/services/memory-review-work-results.js +73 -0
  184. package/dist/services/memory-second-corrected-review-inputs.js +165 -0
  185. package/dist/services/memory-second-correction-plan.js +76 -0
  186. package/dist/services/memory-second-repair-baseline.js +91 -0
  187. package/dist/services/memory-second-repair-launch.js +614 -0
  188. package/dist/services/memory-second-repair-registration.js +88 -0
  189. package/dist/services/memory-second-repair-source.js +187 -0
  190. package/dist/services/memory-second-review-acceptance.js +115 -0
  191. package/dist/services/memory-source-observations.js +117 -0
  192. package/dist/services/memory-stage-dispatch.js +28 -0
  193. package/dist/services/memory-stage-results.js +199 -0
  194. package/dist/services/memory-verification-acceptance.js +135 -0
  195. package/dist/services/memory-verification-checks.js +252 -0
  196. package/dist/services/memory-verification-receipt.js +159 -0
  197. package/dist/services/memory-verify-handler.js +135 -0
  198. package/dist/services/memory-work-result-preparation.js +63 -0
  199. package/dist/services/projects.js +17 -2
  200. package/dist/services/recovery-snapshot-database.js +416 -1
  201. package/dist/services/repair-intents.js +1 -1
  202. package/dist/services/review-copy.js +10 -2
  203. package/dist/services/run-control.js +80 -9
  204. package/dist/services/run-controller-capture.js +10 -3
  205. package/dist/services/run-controller-process.js +21 -0
  206. package/dist/services/run-controller-recovery.js +3 -1
  207. package/dist/services/run-controller-state.js +1 -1
  208. package/dist/services/run-controller.js +184 -48
  209. package/dist/services/run-recovery-guard.js +2 -0
  210. package/dist/services/run-recovery.js +145 -5
  211. package/dist/services/run-start-custody.js +177 -0
  212. package/dist/services/runs.js +319 -25
  213. package/dist/services/stage-context.js +9 -1
  214. package/dist/services/stage-handlers.js +74 -0
  215. package/dist/services/stage-lifecycle.js +2 -1
  216. package/dist/services/stage-report-renderer.js +76 -0
  217. package/dist/services/stage-work-graph.js +17 -0
  218. package/dist/services/vnext-code.js +3 -3
  219. package/dist/services/vnext-execution-profile.js +2 -2
  220. package/dist/services/vnext-fanout.js +136 -10
  221. package/dist/services/vnext-merge.js +8 -3
  222. package/dist/services/vnext-plan-review.js +6 -4
  223. package/dist/services/vnext-protocolize.js +60 -2
  224. package/dist/services/work-registry.js +616 -71
  225. package/dist/services/workspace-files.js +1 -1
  226. package/dist/storage/database.js +84 -6
  227. package/dist/storage/writer-contract.js +11 -7
  228. package/package.json +13 -3
  229. package/tools/create-canon-release.mjs +33 -0
  230. package/tools/produce-hybrid-release.mjs +41 -0
@@ -0,0 +1,115 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { FrozenGenericExecution } from "./generic-execution.js";
3
+ import { hybridDigest } from "./hybrid-contracts.js";
4
+ import { readMemoryInitBootstrapReadiness } from "./memory-init-bootstrap-readiness.js";
5
+ import { PreparedMemoryStageResult } from "./memory-stage-results.js";
6
+ import { PreparedMemoryInitProjectBootstrap } from "./memory-init-project-bootstrap.js";
7
+ import { PreparedMemoryInitBootstrapReadiness } from "./memory-init-bootstrap-readiness.js";
8
+ import { AdmittedFrozenEngine } from "./frozen-engine.js";
9
+ import { observeMemoryInitSourceInventory } from "./memory-init-preflight.js";
10
+ import { RetainedExecutionBundle } from "./execution-bundles.js";
11
+ function refuse(reason) {
12
+ throw new AppError("memory_preflight_bootstrap_custody_invalid", "Preflight does not consume its independently accepted bootstrap", 2, { reason, effect: "no_effect" });
13
+ }
14
+ /** Bootstrap-specific admission for the productive preflight handler. Result
15
+ * schema, RUN/input identity, physical revalidation and coordinator settlement
16
+ * remain separate handler obligations; this is not stage completion authority.
17
+ */
18
+ export class PreparedMemoryPreflightBootstrapCustody {
19
+ #scope;
20
+ #authoritySha256;
21
+ #resultSha256;
22
+ #physical = null;
23
+ #semanticScope;
24
+ constructor(scope, authoritySha256, resultSha256, semanticScope) {
25
+ this.#scope = { ...scope };
26
+ this.#authoritySha256 = authoritySha256;
27
+ this.#resultSha256 = resultSha256;
28
+ this.#semanticScope = semanticScope;
29
+ Object.freeze(this);
30
+ }
31
+ static prepare(context, input) {
32
+ if (!(input.execution instanceof FrozenGenericExecution) || !(input.result instanceof PreparedMemoryStageResult)
33
+ || input.execution.settings.flow_id !== "mb-init")
34
+ refuse("unprepared_preflight");
35
+ const frozen = input.execution.snapshot();
36
+ const scope = { requestId: frozen.scope.requestId, projectRoot: frozen.scope.projectRoot, workspaceRoot: frozen.scope.workspace };
37
+ const accepted = readMemoryInitBootstrapReadiness(context, scope);
38
+ if (!accepted || accepted.authority.binding.execution_sha256 !== input.execution.sha256)
39
+ refuse("missing_or_foreign_bootstrap");
40
+ const result = input.result.value(), details = result.details;
41
+ if (result.stage !== "preflight" || result.schema_id !== "dd-flow/mb-init-preflight-result@1")
42
+ refuse("foreign_stage");
43
+ const semanticScope = details.semantic_scope;
44
+ if (typeof semanticScope !== "string" || !semanticScope.trim() || Buffer.byteLength(semanticScope) > 16384 || semanticScope.includes("\0"))
45
+ refuse("invalid_semantic_scope");
46
+ return new PreparedMemoryPreflightBootstrapCustody(scope, hybridDigest(accepted.authority), input.result.sha256, semanticScope);
47
+ }
48
+ /** Productive preparation additionally restores the request-owned bootstrap
49
+ * and rechecks its physical prerequisites. No publication or model probe is
50
+ * dispatched. Result/RUN input and invoking assertBundleReference remain
51
+ * obligations of the registered stage handler, not this bootstrap fence.
52
+ */
53
+ static preparePhysical(context, input) {
54
+ if (!(input.engine instanceof AdmittedFrozenEngine))
55
+ refuse("selected_engine_not_admitted");
56
+ const prepared = PreparedMemoryPreflightBootstrapCustody.prepare(context, input);
57
+ const bootstrap = PreparedMemoryInitProjectBootstrap.restore(context, input.execution);
58
+ PreparedMemoryInitBootstrapReadiness.prepare(context, { bootstrap, engine: input.engine });
59
+ const inventory = prepared.observeInventory(context);
60
+ prepared.assertCustody(context);
61
+ prepared.#physical = { bootstrap, engine: input.engine, inventorySha256: inventory.sha256 };
62
+ return prepared;
63
+ }
64
+ /** Outside writers: recheck current root/source/tools/pack/engine/storage.
65
+ * The acceptance writer uses assertCustody only, with no filesystem access.
66
+ */
67
+ revalidate(context) {
68
+ if (!this.#physical)
69
+ refuse("physical_preparation_required");
70
+ PreparedMemoryInitBootstrapReadiness.prepare(context, this.#physical);
71
+ if (this.observeInventory(context).sha256 !== this.#physical.inventorySha256)
72
+ refuse("preserved_inventory_changed");
73
+ this.assertCustody(context);
74
+ }
75
+ /** SQL-only fence for the handler's eventual atomic acceptance writer. */
76
+ assertCustody(context) {
77
+ const accepted = readMemoryInitBootstrapReadiness(context, this.#scope);
78
+ if (!accepted || hybridDigest(accepted.authority) !== this.#authoritySha256)
79
+ refuse("bootstrap_changed_after_preparation");
80
+ }
81
+ /** Exact manifest reference, not merely a same-hash path supplied by an agent.
82
+ * RUN/input identity is separately fenced by its prepared result binding and
83
+ * descriptor settlement; this method alone is not RUN execution authority.
84
+ */
85
+ assertBundleReference(context, bundle, result) {
86
+ if (!(bundle instanceof RetainedExecutionBundle) || !(result instanceof PreparedMemoryStageResult))
87
+ refuse("unprepared_bundle_reference");
88
+ context.db.readSnapshot(() => {
89
+ this.assertCustody(context);
90
+ const frozen = bundle.execution.snapshot(), accepted = readMemoryInitBootstrapReadiness(context, this.#scope);
91
+ if (!accepted)
92
+ refuse("missing_or_foreign_bootstrap");
93
+ const value = result.value(), details = value.details;
94
+ if (bundle.descriptor.descriptor.id !== "mb-init" || bundle.execution.sha256 !== accepted.authority.binding.execution_sha256
95
+ || frozen.scope.requestId !== this.#scope.requestId || frozen.scope.projectRoot !== this.#scope.projectRoot || frozen.scope.workspace !== this.#scope.workspaceRoot
96
+ || value.stage !== "preflight" || value.run_id !== bundle.manifest.run_id
97
+ || bundle.manifest.bootstrap_receipts.length !== 1
98
+ || bundle.manifest.bootstrap_receipts[0].sha256 !== accepted.authority.bootstrap_sha256
99
+ || !bundle.blob(bundle.manifest.bootstrap_receipts[0].path).equals(Buffer.from(JSON.stringify(accepted.authority.receipt))))
100
+ refuse("foreign_bundle_bootstrap_reference");
101
+ if (details.semantic_scope !== this.#semanticScope)
102
+ refuse("foreign_preflight_semantic_scope");
103
+ // Bootstrap/physical preparation belongs to the exact result that was
104
+ // checked, not another schema-valid result with the same selected fields.
105
+ if (result.sha256 !== this.#resultSha256)
106
+ refuse("preflight_result_changed_after_preparation");
107
+ });
108
+ }
109
+ observeInventory(context) {
110
+ const accepted = readMemoryInitBootstrapReadiness(context, this.#scope);
111
+ if (!accepted)
112
+ refuse("missing_or_foreign_bootstrap");
113
+ return observeMemoryInitSourceInventory(accepted.authority.binding.target, accepted.authority.receipt.baseline_sha256, context.env);
114
+ }
115
+ }
@@ -0,0 +1,259 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { RetainedExecutionBundle } from "./execution-bundles.js";
3
+ import { PreparedMemoryStageResult } from "./memory-stage-results.js";
4
+ import { PreparedMemoryPreflightBootstrapCustody } from "./memory-preflight-bootstrap-custody.js";
5
+ import { PreparedMemoryBaselinePreservation } from "./memory-baseline-preservation.js";
6
+ import { PreparedMemoryResultBinding } from "./memory-result-binding.js";
7
+ import { ObservedMemorySources } from "./memory-source-observations.js";
8
+ import { memorySourceKey } from "./memory-stage-results.js";
9
+ import { readMemoryInitBootstrapReadiness } from "./memory-init-bootstrap-readiness.js";
10
+ import { observeMemoryInitSourceInventory } from "./memory-init-preflight.js";
11
+ import { readMemoryInitProjectBootstrap } from "./memory-init-project-bootstrap.js";
12
+ import { readPublishedMemoryReferenceInventory } from "./memory-layer-publication.js";
13
+ import path from "node:path";
14
+ import { PreparedDescriptorStageStart } from "./descriptor-stage-start.js";
15
+ import { PreparedDescriptorStageCoordinator, readDescriptorStageInput } from "./descriptor-stage-coordinator.js";
16
+ import { PreparedDescriptorStageSettlement } from "./descriptor-stage-settlement.js";
17
+ import { assertPreparedRunBundleSqlAuthority, readFlowRunExecutionBundle } from "./runs.js";
18
+ import { requireProjectByRoot } from "./projects.js";
19
+ import { resolveProjectRoot } from "../storage/paths.js";
20
+ import { readAcceptedStageData } from "./stage-report-renderer.js";
21
+ import { readMemoryCompositionRegistration } from "./memory-composition-registration.js";
22
+ import { hybridDigest } from "./hybrid-contracts.js";
23
+ function refuse(reason) {
24
+ throw new AppError("memory_preflight_handler_invalid", "Memory preflight cannot accept this execution or result", 2, { reason, effect: "no_effect" });
25
+ }
26
+ function bounded(bytes, empty = false) {
27
+ if (!(bytes instanceof Uint8Array) || bytes.length > 1024 * 1024 || !empty && !bytes.length)
28
+ refuse("invalid_result_bytes");
29
+ }
30
+ function selected(context, input) {
31
+ const bundle = readFlowRunExecutionBundle(context, input);
32
+ if (!bundle || bundle.descriptor.descriptor.id !== "mb-init" || bundle.descriptor.descriptor.entry_stage !== "preflight")
33
+ refuse("registered_memory_bundle_required");
34
+ const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
35
+ const scope = { projectId: project.id, runId: input.runId, stage: "preflight" };
36
+ const run = assertPreparedRunBundleSqlAuthority(context, scope, bundle);
37
+ const stage = JSON.parse(run.index_json).stage_runs.find((entry) => entry.stage === "preflight");
38
+ return { bundle, scope, accepted: stage?.status === "done" };
39
+ }
40
+ /** Proposed references select a subset, never establish the source allowlist.
41
+ * Only regular files in the independently restored bootstrap baseline may be
42
+ * preflight project evidence. Ignored/private, linked, runtime and canon paths
43
+ * are not silently read as project truth. Their other proof roles are separate.
44
+ */
45
+ export function captureMemoryPreflightSources(context, bundle, bytes) {
46
+ return captureSources(context, bundle, bytes).sources;
47
+ }
48
+ /** Historical blueprint support comes only from the independently registered
49
+ * graph. It is not a current output observation or a caller-supplied allowlist. */
50
+ export function captureRegisteredMemoryCompositionSources(context, bundle, registrationScope) {
51
+ const registration = readMemoryCompositionRegistration(context, registrationScope);
52
+ if (registration.run_id !== bundle.manifest.run_id || registration.execution_sha256 !== bundle.execution.sha256)
53
+ refuse("foreign_composition_registration");
54
+ return { ...captureSources(context, bundle, Buffer.from(registration.result_base64, "base64"), true),
55
+ registrationSha256: hybridDigest(registration), inputSha256: registration.input_sha256 };
56
+ }
57
+ function captureSources(context, bundle, bytes, registeredBlueprint = false) {
58
+ bounded(bytes);
59
+ if (!(bundle instanceof RetainedExecutionBundle) || bundle.descriptor.descriptor.id !== "mb-init")
60
+ refuse("prepared_memory_bundle_required");
61
+ const preservation = PreparedMemoryBaselinePreservation.prepare(context, bundle.execution), scope = bundle.execution.snapshot().scope;
62
+ const ready = readMemoryInitBootstrapReadiness(context, { requestId: scope.requestId, projectRoot: scope.projectRoot, workspaceRoot: scope.workspace });
63
+ if (!ready || ready.authority.binding.execution_sha256 !== bundle.execution.sha256)
64
+ refuse("accepted_bootstrap_required");
65
+ const inventory = observeMemoryInitSourceInventory(ready.authority.binding.target, ready.authority.receipt.baseline_sha256, context.env);
66
+ const allowed = new Map(inventory.entries.filter(entry => entry.kind === "file").map(entry => [entry.path, entry.sha256]));
67
+ let value;
68
+ try {
69
+ value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
70
+ }
71
+ catch {
72
+ refuse("invalid_result_json");
73
+ }
74
+ const registered = readMemoryInitProjectBootstrap(context, ready.authority.binding.scope);
75
+ if (!registered)
76
+ refuse("accepted_bootstrap_required");
77
+ const owned = readPublishedMemoryReferenceInventory(context.ddFlowHome, { ...ready.authority.binding.scope,
78
+ targetSha256: registered.receipt.target_sha256, layerSha256: registered.receipt.layer_sha256,
79
+ packSha256: ready.authority.binding.pack_sha256, installationSha256: ready.authority.binding.installation_manifest_sha256 }, ready.authority.binding.target, registered.receipt.layer_publication_sha256, registered.receipt.draft_identity_sha256);
80
+ const receipts = new Map(bundle.manifest.bootstrap_receipts.map(ref => [`execution-bundle/${ref.path}`, ref.sha256]));
81
+ for (const ref of ready.authority.evidence) {
82
+ const selected = bundle.manifest.inventory.find(item => item.path === ref.path && item.sha256 === ref.sha256);
83
+ if (selected)
84
+ receipts.set(`execution-bundle/${ref.path}`, ref.sha256);
85
+ }
86
+ let run = null;
87
+ const acceptedReferences = new Map();
88
+ const selectRun = () => run ??= assertPreparedRunBundleSqlAuthority(context, { projectId: ready.projectId, runId: bundle.manifest.run_id }, bundle);
89
+ let selectedAccepted = false;
90
+ const rejectProposal = (reason, reference, message) => {
91
+ const proposal = value;
92
+ if (registeredBlueprint || proposal.run_id !== bundle.manifest.run_id || typeof proposal.stage !== "string" || typeof proposal.input_sha256 !== "string")
93
+ refuse("unselected_preflight_source");
94
+ const index = JSON.parse(selectRun().index_json), stage = index.stage_runs.find((stage) => stage.stage === proposal.stage);
95
+ if (index.current_stage !== proposal.stage || stage?.status !== "running" || stage.input_sha256 !== proposal.input_sha256)
96
+ refuse("unselected_preflight_source");
97
+ throw new AppError("memory_preflight_handler_invalid", message, 2, { reason, ...reference, phase: "prepare", effect: "no_effect", recoverable: true });
98
+ };
99
+ const proposedMismatches = [];
100
+ const pending = [{ value, role: "source", original: false }], locations = new Map(), expected = new Map(), historical = new Map();
101
+ let nodes = 0;
102
+ while (pending.length) {
103
+ if (++nodes > 100000)
104
+ refuse("result_tree_exceeds_bound");
105
+ const entry = pending.pop(), node = entry.value;
106
+ if (Array.isArray(node)) {
107
+ for (const child of node)
108
+ pending.push({ ...entry, value: child });
109
+ continue;
110
+ }
111
+ if (!node || typeof node !== "object")
112
+ continue;
113
+ const record = node;
114
+ if (typeof record.root === "string" && typeof record.path === "string" && typeof record.sha256 === "string") {
115
+ let selected;
116
+ if (["project", "workspace"].includes(record.root)) {
117
+ selected = allowed.get(record.path) ?? undefined;
118
+ if (!entry.original && ["evidence", "artifacts"].includes(entry.role))
119
+ selected ??= owned.artifacts.get(record.path);
120
+ }
121
+ else if (!entry.original && (entry.role === "evidence" || entry.role === "artifacts")) {
122
+ if (record.root === "run") {
123
+ selected = receipts.get(record.path);
124
+ if (selected === undefined) {
125
+ if (!selectedAccepted) {
126
+ let stage = value.stage;
127
+ const declared = bundle.descriptor.descriptor.stages.find(item => item.id === stage);
128
+ if (!declared)
129
+ refuse("unselected_preflight_source");
130
+ selectedAccepted = true;
131
+ const index = JSON.parse(selectRun().index_json);
132
+ const acceptedStage = index.stage_runs?.some((item) => item.stage === stage && item.status === "done");
133
+ if (acceptedStage)
134
+ readAcceptedStageData(context, { projectId: ready.projectId, runId: bundle.manifest.run_id, stage: declared.id });
135
+ if (index.current_stage === stage || acceptedStage) {
136
+ const input = readDescriptorStageInput(context, { projectId: ready.projectId, runId: bundle.manifest.run_id, stage: declared.id }, bundle, true, acceptedStage);
137
+ acceptedReferences.set(`${declared.directory}/stage-input.json`, input.inputSha256);
138
+ }
139
+ const visited = new Set();
140
+ while (stage && !visited.has(stage)) {
141
+ visited.add(stage);
142
+ stage = bundle.descriptor.descriptor.edges.find(edge => edge.to === stage && edge.on === "accepted")?.from;
143
+ if (stage && index.stage_runs?.some((item) => item.stage === stage && item.status === "done")) {
144
+ const accepted = readAcceptedStageData(context, { projectId: ready.projectId, runId: bundle.manifest.run_id, stage });
145
+ const result = JSON.parse(accepted.bytes.toString("utf8"));
146
+ if (result.schema_id !== `dd-flow/mb-init-${stage}-result@1` || result.run_id !== bundle.manifest.run_id
147
+ || result.stage !== stage || !(result.outcome === "accepted" || stage === "verify" && result.outcome === "needs_repair" && bundle.descriptor.successor("verify", "needs_repair") === "review"))
148
+ refuse("unselected_preflight_source");
149
+ acceptedReferences.set(accepted.result.path, accepted.result.sha256);
150
+ const input = readDescriptorStageInput(context, { projectId: ready.projectId, runId: bundle.manifest.run_id, stage }, bundle, true, true);
151
+ acceptedReferences.set(`${bundle.descriptor.stage(stage).directory}/stage-input.json`, input.inputSha256);
152
+ }
153
+ }
154
+ }
155
+ selected = acceptedReferences.get(record.path);
156
+ }
157
+ }
158
+ if (record.root === "canon")
159
+ selected = owned.canon.get(record.path);
160
+ }
161
+ if (selected === undefined)
162
+ return rejectProposal("unselected_preflight_source", { root: record.root, path: record.path }, "Remove or replace this unselected reference with an admitted project source, preflight result or Stage input; Git metadata is not project source evidence");
163
+ if (selected !== record.sha256) {
164
+ if (registeredBlueprint)
165
+ refuse("registered_source_sha256_mismatch");
166
+ proposedMismatches.push({ root: record.root, path: record.path });
167
+ }
168
+ const key = memorySourceKey(record.root, record.path);
169
+ if (registeredBlueprint && !entry.original && ["evidence", "artifacts"].includes(entry.role)
170
+ && ["project", "workspace"].includes(record.root) && !allowed.has(record.path) && owned.artifacts.get(record.path) === selected) {
171
+ historical.set(key, selected);
172
+ }
173
+ else {
174
+ expected.set(key, selected);
175
+ locations.set(key, { root: record.root, path: record.path });
176
+ }
177
+ }
178
+ for (const [key, child] of Object.entries(record))
179
+ pending.push({ value: child, role: ["evidence", "artifacts"].includes(key) ? key : entry.role,
180
+ original: entry.original || key === "inventory" });
181
+ }
182
+ const selectedRun = [...locations.values()].some(location => location.root === "run") ? selectRun() : null;
183
+ const observation = ObservedMemorySources.capture({ project: scope.projectRoot, workspace: scope.workspace,
184
+ canon: path.join(scope.workspace, ".memory-bank"), ...(selectedRun ? { run: selectedRun.run_root ?? selectedRun.run_dir } : {}) }, [...locations.values()]);
185
+ const hashes = observation.hashes();
186
+ for (const [key, sha256] of expected)
187
+ if (hashes.get(key) !== sha256)
188
+ refuse("preflight_source_changed");
189
+ preservation.assertCustody(context);
190
+ if (proposedMismatches.length) {
191
+ rejectProposal("proposed_source_sha256_mismatch", proposedMismatches[0], "Proposed evidence SHA differs from the CLI-selected source; correct the result reference without changing the source");
192
+ }
193
+ return { sources: observation, historical };
194
+ }
195
+ /** The bootstrap-specific acceptance part of the preflight handler. It does
196
+ * not establish RUN/input/coordinator authority; finishMemoryPreflight supplies
197
+ * those independently. Kept separate for actual bootstrap qualification.
198
+ */
199
+ export class PreparedMemoryPreflightAcceptance {
200
+ #bundle;
201
+ #result;
202
+ #bootstrap;
203
+ constructor(bundle, result, bootstrap) {
204
+ this.#bundle = bundle;
205
+ this.#result = result;
206
+ this.#bootstrap = bootstrap;
207
+ Object.freeze(this);
208
+ }
209
+ static prepare(context, input) {
210
+ if (!(input.bundle instanceof RetainedExecutionBundle) || !(input.result instanceof PreparedMemoryStageResult))
211
+ refuse("prepared_bundle_and_result_required");
212
+ const value = JSON.parse(input.result.bytes().toString("utf8"));
213
+ // Preliminary units/minor findings are allowed by the frozen contract;
214
+ // DISCOVER establishes final inventory. Material blockers cannot advance.
215
+ if (value.stage !== "preflight" || value.outcome !== "accepted"
216
+ || value.findings.some((finding) => finding.severity !== "minor" && finding.status !== "resolved"))
217
+ refuse("preflight_not_accepted");
218
+ const bootstrap = PreparedMemoryPreflightBootstrapCustody.preparePhysical(context, { execution: input.bundle.execution, result: input.result, engine: input.bundle.engine() });
219
+ const prepared = new PreparedMemoryPreflightAcceptance(input.bundle, input.result, bootstrap);
220
+ prepared.assertCustody(context);
221
+ return prepared;
222
+ }
223
+ revalidate(context) { this.#bootstrap.revalidate(context); this.assertCustody(context); }
224
+ assertCustody(context) { this.#bootstrap.assertBundleReference(context, this.#bundle, this.#result); }
225
+ }
226
+ /** Handler implementation awaiting the complete memory-handler registry. No
227
+ * RUN allocation, profile mutation, installation fallback or provider dispatch.
228
+ * Returns the retained prompt for the controller's separately fenced dispatch.
229
+ */
230
+ export function startMemoryPreflight(context, input) {
231
+ bounded(input.bytes, true);
232
+ const { bundle, accepted } = selected(context, input);
233
+ if (accepted)
234
+ refuse("use_accepted_finish_replay");
235
+ const preservation = PreparedMemoryBaselinePreservation.prepare(context, bundle.execution);
236
+ const start = PreparedDescriptorStageStart.prepare(context, { ...input, stage: "preflight" });
237
+ preservation.revalidate(context);
238
+ const stage = start.apply(context, writer => preservation.assertCustody(writer));
239
+ const coordinator = PreparedDescriptorStageCoordinator.prepare(context, { ...input, stage: "preflight" });
240
+ preservation.revalidate(context);
241
+ const work = coordinator.apply(context, writer => preservation.assertCustody(writer));
242
+ return { ...stage, ...work };
243
+ }
244
+ export function finishMemoryPreflight(context, input) {
245
+ bounded(input.bytes);
246
+ const { bundle, scope, accepted } = selected(context, input);
247
+ const sources = captureMemoryPreflightSources(context, bundle, input.bytes);
248
+ const binding = PreparedMemoryResultBinding.prepare(context, { ...scope, flow: bundle.descriptor, execution: bundle.execution, bundle,
249
+ sources, acceptedReplay: accepted });
250
+ const replay = binding.acceptedBytes();
251
+ if (replay && !replay.equals(input.bytes))
252
+ refuse("accepted_result_changed");
253
+ const result = PreparedMemoryStageResult.prepare(input.bytes, bundle.descriptor, binding.binding());
254
+ const acceptance = PreparedMemoryPreflightAcceptance.prepare(context, { bundle, result });
255
+ const settlement = PreparedDescriptorStageSettlement.prepare(context, { ...input, stage: "preflight", bytes: result.bytes() });
256
+ binding.revalidate(context);
257
+ acceptance.revalidate(context);
258
+ return settlement.apply(context, writer => { binding.assertCustody(writer); acceptance.assertCustody(writer); });
259
+ }