@deksden-com/dd-flow-cli 0.9.0-beta.137 → 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 (260) hide show
  1. package/CHANGELOG.md +4 -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 +197 -0
  7. package/dist/cli/command-option-descriptions.js +191 -0
  8. package/dist/cli/completion-cli.js +70 -0
  9. package/dist/cli/completion.js +57 -0
  10. package/dist/cli/error-output.js +52 -0
  11. package/dist/cli/executor-onboarding.js +76 -0
  12. package/dist/cli/flows.js +29 -0
  13. package/dist/cli/harnesses.js +84 -0
  14. package/dist/cli/help.js +240 -6
  15. package/dist/cli/input-preparation.js +54 -5
  16. package/dist/cli/memory-flow-admission.js +44 -0
  17. package/dist/cli/memory-init-invocation.js +78 -0
  18. package/dist/cli/memory-init.js +240 -0
  19. package/dist/cli/memory-storage-admission.js +53 -0
  20. package/dist/cli/models.js +39 -0
  21. package/dist/cli/native-hook-ingress.js +1 -1
  22. package/dist/cli/operator-profiles.js +61 -0
  23. package/dist/cli/output-options.js +35 -0
  24. package/dist/cli/response-file.js +71 -0
  25. package/dist/cli/run-cli.js +283 -160
  26. package/dist/cli/setup.js +149 -0
  27. package/dist/cli.js +54 -2
  28. package/dist/domain/stage-handler-identities.js +20 -0
  29. package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
  30. package/dist/harness-runtime/lib/daemon-operations.mjs +4 -3
  31. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +4 -2
  32. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +11 -5
  33. package/dist/harness-runtime/lib/dd-codex.mjs +22 -10
  34. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +2 -1
  35. package/dist/harness-runtime/lib/dd-droid.mjs +2 -1
  36. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +4 -2
  37. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +6 -4
  38. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +9 -9
  39. package/dist/harness-runtime/lib/delegation-instructions.mjs +5 -3
  40. package/dist/harness-runtime/lib/lifecycle-command.mjs +1 -0
  41. package/dist/harness-runtime/lib/managed-daemon.d.mts +1 -0
  42. package/dist/harness-runtime/lib/managed-daemon.mjs +50 -15
  43. package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
  44. package/dist/harness-runtime/lib/native-hook-command.mjs +1 -1
  45. package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
  46. package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
  47. package/dist/harness-runtime/lib/opencode-plugin.mjs +2 -0
  48. package/dist/harness-runtime/lib/operation-progress.mjs +3 -1
  49. package/dist/runtime/context.js +1 -1
  50. package/dist/schemas/discovery-result.schema.json +184 -0
  51. package/dist/schemas/execution-bundle.schema.json +205 -0
  52. package/dist/schemas/execution-settings.schema.json +162 -0
  53. package/dist/schemas/flow-descriptor.schema.json +54 -0
  54. package/dist/schemas/flow-run.schema.json +22 -0
  55. package/dist/schemas/harness-catalog.schema.json +80 -0
  56. package/dist/schemas/mb-init-compose-result.schema.json +457 -0
  57. package/dist/schemas/mb-init-discover-result.schema.json +500 -0
  58. package/dist/schemas/mb-init-finish-result.schema.json +422 -0
  59. package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
  60. package/dist/schemas/mb-init-review-result.schema.json +396 -0
  61. package/dist/schemas/mb-init-verify-result.schema.json +391 -0
  62. package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
  63. package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
  64. package/dist/schemas/memory-composition-work-result.schema.json +38 -0
  65. package/dist/schemas/memory-repair-work-result.schema.json +49 -0
  66. package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
  67. package/dist/schemas/memory-review-work-result.schema.json +43 -0
  68. package/dist/schemas/model-catalog.schema.json +153 -0
  69. package/dist/schemas/profile-settings.schema.json +122 -0
  70. package/dist/schemas/release-manifest.schema.json +291 -0
  71. package/dist/schemas/run-engine-binding.schema.json +1 -1
  72. package/dist/services/check-runner-evidence.js +51 -4
  73. package/dist/services/cli-operation-classifier.js +8 -47
  74. package/dist/services/cli-upgrade-allowlist.js +27 -0
  75. package/dist/services/code-checks.js +387 -34
  76. package/dist/services/controller-execution.js +88 -0
  77. package/dist/services/controller-fanout.js +71 -12
  78. package/dist/services/dashboard.js +8 -2
  79. package/dist/services/descriptor-coordinator-session.js +35 -0
  80. package/dist/services/descriptor-root-work.js +53 -0
  81. package/dist/services/descriptor-run-settlement.js +105 -0
  82. package/dist/services/descriptor-run-start.js +449 -0
  83. package/dist/services/descriptor-stage-coordinator.js +197 -0
  84. package/dist/services/descriptor-stage-settlement.js +222 -0
  85. package/dist/services/descriptor-stage-start.js +139 -0
  86. package/dist/services/discovery/agy-discovery.js +2 -0
  87. package/dist/services/discovery/codex-discovery.js +2 -0
  88. package/dist/services/discovery/droid-discovery.js +2 -0
  89. package/dist/services/discovery/grok-discovery.js +2 -0
  90. package/dist/services/discovery/opencode-discovery.js +2 -0
  91. package/dist/services/discovery/static.js +31 -0
  92. package/dist/services/discovery/zcode-discovery.js +2 -0
  93. package/dist/services/engines.js +39 -22
  94. package/dist/services/eval-snapshots.js +83 -25
  95. package/dist/services/execution-bundles.js +263 -0
  96. package/dist/services/execution-policy.js +20 -16
  97. package/dist/services/executor-onboarding.js +56 -0
  98. package/dist/services/external-work-launch.js +91 -11
  99. package/dist/services/flow-catalog.js +21 -0
  100. package/dist/services/flow-descriptors.js +82 -0
  101. package/dist/services/frozen-engine.js +242 -0
  102. package/dist/services/generic-execution.js +164 -0
  103. package/dist/services/harness-adapter.js +28 -2
  104. package/dist/services/harness-discovery.js +29 -0
  105. package/dist/services/harness-doctor.js +75 -0
  106. package/dist/services/harness-probe-effects.js +51 -0
  107. package/dist/services/harness-version-probe.js +100 -0
  108. package/dist/services/hooks.js +24 -6
  109. package/dist/services/hybrid-contracts.js +483 -0
  110. package/dist/services/ids.js +29 -1
  111. package/dist/services/installation-lock.js +95 -0
  112. package/dist/services/installed-flow-source.js +183 -0
  113. package/dist/services/lifecycle-invocations.js +257 -78
  114. package/dist/services/memory-accepted-composition.js +77 -0
  115. package/dist/services/memory-baseline-preservation.js +65 -0
  116. package/dist/services/memory-completed-correction-wave.js +320 -0
  117. package/dist/services/memory-compose-handler.js +258 -0
  118. package/dist/services/memory-composition-acceptance.js +199 -0
  119. package/dist/services/memory-composition-graph.js +134 -0
  120. package/dist/services/memory-composition-registration.js +146 -0
  121. package/dist/services/memory-composition-work-custody.js +151 -0
  122. package/dist/services/memory-composition-work-results.js +96 -0
  123. package/dist/services/memory-corrected-review-acceptance.js +129 -0
  124. package/dist/services/memory-corrected-review-batch.js +30 -0
  125. package/dist/services/memory-corrected-review-findings.js +106 -0
  126. package/dist/services/memory-corrected-review-inputs.js +210 -0
  127. package/dist/services/memory-corrected-review-projection.js +78 -0
  128. package/dist/services/memory-corrected-review-receipt.js +170 -0
  129. package/dist/services/memory-corrected-review-registration.js +191 -0
  130. package/dist/services/memory-correction-check-receipt.js +219 -0
  131. package/dist/services/memory-correction-input-owner.js +6 -0
  132. package/dist/services/memory-discover-handler.js +104 -0
  133. package/dist/services/memory-finish-evidence.js +435 -0
  134. package/dist/services/memory-finish-handler.js +215 -0
  135. package/dist/services/memory-finish-integration.js +280 -0
  136. package/dist/services/memory-finish-readiness.js +122 -0
  137. package/dist/services/memory-git-integration.js +151 -0
  138. package/dist/services/memory-historical-corrected-review.js +206 -0
  139. package/dist/services/memory-historical-original-review.js +130 -0
  140. package/dist/services/memory-historical-repair-registration.js +99 -0
  141. package/dist/services/memory-historical-second-review.js +128 -0
  142. package/dist/services/memory-init-bootstrap-readiness.js +210 -0
  143. package/dist/services/memory-init-contexts.js +89 -0
  144. package/dist/services/memory-init-controller-start.js +84 -0
  145. package/dist/services/memory-init-engine-release.js +223 -0
  146. package/dist/services/memory-init-git-policy.js +136 -0
  147. package/dist/services/memory-init-lint-capability.js +185 -0
  148. package/dist/services/memory-init-native-capacity.js +241 -0
  149. package/dist/services/memory-init-preflight.js +312 -0
  150. package/dist/services/memory-init-project-bootstrap.js +599 -0
  151. package/dist/services/memory-init-request-candidate.js +157 -0
  152. package/dist/services/memory-init-request-input.js +66 -0
  153. package/dist/services/memory-init-resource-storage.js +125 -0
  154. package/dist/services/memory-init-run-allocation.js +81 -0
  155. package/dist/services/memory-init-run-bundle.js +98 -0
  156. package/dist/services/memory-init-start.js +175 -0
  157. package/dist/services/memory-init-startup-custody.js +80 -0
  158. package/dist/services/memory-init-startup-input.js +240 -0
  159. package/dist/services/memory-init-storage.js +81 -0
  160. package/dist/services/memory-init-stores.js +359 -0
  161. package/dist/services/memory-init-worktrunk-capability.js +172 -0
  162. package/dist/services/memory-layer-publication.js +611 -0
  163. package/dist/services/memory-layer.js +156 -0
  164. package/dist/services/memory-lint-config.js +85 -0
  165. package/dist/services/memory-native-review-copy.js +165 -0
  166. package/dist/services/memory-normal-flow-entry.js +75 -0
  167. package/dist/services/memory-ordinary-defaults.js +112 -0
  168. package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
  169. package/dist/services/memory-preflight-handler.js +259 -0
  170. package/dist/services/memory-repair-current-view.js +299 -0
  171. package/dist/services/memory-repair-document-delta.js +451 -0
  172. package/dist/services/memory-repair-history.js +491 -0
  173. package/dist/services/memory-repair-physical-binding.js +312 -0
  174. package/dist/services/memory-repair-publication-files.js +152 -0
  175. package/dist/services/memory-repair-publication-intent.js +27 -0
  176. package/dist/services/memory-repair-publication-plan.js +160 -0
  177. package/dist/services/memory-repair-publication-source.js +225 -0
  178. package/dist/services/memory-repair-publication.js +794 -0
  179. package/dist/services/memory-repair-registration.js +239 -0
  180. package/dist/services/memory-repair-work-baseline.js +413 -0
  181. package/dist/services/memory-repair-work-completion.js +97 -0
  182. package/dist/services/memory-repair-work-custody.js +73 -0
  183. package/dist/services/memory-repair-work-results.js +89 -0
  184. package/dist/services/memory-repair-workspace.js +252 -0
  185. package/dist/services/memory-repair-writer-copy.js +735 -0
  186. package/dist/services/memory-result-binding.js +173 -0
  187. package/dist/services/memory-retained-review-authority.js +129 -0
  188. package/dist/services/memory-retained-review-results.js +70 -0
  189. package/dist/services/memory-retained-second-baseline.js +102 -0
  190. package/dist/services/memory-retained-second-repairs.js +156 -0
  191. package/dist/services/memory-review-acceptance.js +214 -0
  192. package/dist/services/memory-review-correction-plan.js +171 -0
  193. package/dist/services/memory-review-handler.js +585 -0
  194. package/dist/services/memory-review-inputs.js +200 -0
  195. package/dist/services/memory-review-receipt.js +180 -0
  196. package/dist/services/memory-review-registration.js +108 -0
  197. package/dist/services/memory-review-work-custody.js +124 -0
  198. package/dist/services/memory-review-work-input.js +72 -0
  199. package/dist/services/memory-review-work-results.js +73 -0
  200. package/dist/services/memory-second-corrected-review-inputs.js +165 -0
  201. package/dist/services/memory-second-correction-plan.js +76 -0
  202. package/dist/services/memory-second-repair-baseline.js +91 -0
  203. package/dist/services/memory-second-repair-launch.js +614 -0
  204. package/dist/services/memory-second-repair-registration.js +88 -0
  205. package/dist/services/memory-second-repair-source.js +187 -0
  206. package/dist/services/memory-second-review-acceptance.js +115 -0
  207. package/dist/services/memory-source-observations.js +117 -0
  208. package/dist/services/memory-stage-dispatch.js +28 -0
  209. package/dist/services/memory-stage-results.js +199 -0
  210. package/dist/services/memory-verification-acceptance.js +135 -0
  211. package/dist/services/memory-verification-checks.js +252 -0
  212. package/dist/services/memory-verification-receipt.js +159 -0
  213. package/dist/services/memory-verify-handler.js +135 -0
  214. package/dist/services/memory-work-result-preparation.js +63 -0
  215. package/dist/services/model-catalog.js +109 -0
  216. package/dist/services/model-discovery.js +46 -0
  217. package/dist/services/operator-profiles.js +236 -0
  218. package/dist/services/projects.js +17 -2
  219. package/dist/services/recovery-snapshot-database.js +416 -1
  220. package/dist/services/release-archive-producer.js +52 -0
  221. package/dist/services/release-archive.js +143 -0
  222. package/dist/services/release-cache.js +142 -0
  223. package/dist/services/release-compatibility.js +18 -0
  224. package/dist/services/release-download.js +67 -0
  225. package/dist/services/release-envelope.js +104 -0
  226. package/dist/services/release-manifest.js +45 -0
  227. package/dist/services/release-payload.js +114 -0
  228. package/dist/services/release-producer.js +63 -0
  229. package/dist/services/release-provenance.js +160 -0
  230. package/dist/services/release-registry.js +66 -0
  231. package/dist/services/release-source.js +194 -0
  232. package/dist/services/repair-intents.js +1 -1
  233. package/dist/services/review-copy.js +10 -2
  234. package/dist/services/run-control.js +80 -9
  235. package/dist/services/run-controller-capture.js +10 -3
  236. package/dist/services/run-controller-process.js +21 -0
  237. package/dist/services/run-controller-recovery.js +3 -1
  238. package/dist/services/run-controller-state.js +1 -1
  239. package/dist/services/run-controller.js +101 -40
  240. package/dist/services/run-recovery-guard.js +2 -0
  241. package/dist/services/run-recovery.js +145 -5
  242. package/dist/services/run-start-custody.js +177 -0
  243. package/dist/services/runs.js +319 -25
  244. package/dist/services/setup.js +377 -0
  245. package/dist/services/stage-context.js +9 -1
  246. package/dist/services/stage-handlers.js +74 -0
  247. package/dist/services/stage-report-renderer.js +63 -0
  248. package/dist/services/stage-work-graph.js +17 -0
  249. package/dist/services/vnext-code.js +3 -3
  250. package/dist/services/vnext-execution-profile.js +2 -2
  251. package/dist/services/vnext-fanout.js +70 -9
  252. package/dist/services/vnext-merge.js +8 -3
  253. package/dist/services/vnext-plan-review.js +6 -4
  254. package/dist/services/work-registry.js +616 -71
  255. package/dist/services/workspace-files.js +1 -1
  256. package/dist/storage/database.js +84 -6
  257. package/dist/storage/writer-contract.js +11 -7
  258. package/package.json +13 -3
  259. package/tools/create-canon-release.mjs +33 -0
  260. package/tools/produce-hybrid-release.mjs +41 -0
@@ -0,0 +1,219 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { AppError } from "../shared/errors.js";
3
+ import { hybridDigest } from "./hybrid-contracts.js";
4
+ import { appendAudit } from "./audit.js";
5
+ import { PreparedRetainedCheckEvidence } from "./code-checks.js";
6
+ import { isMemoryCorrectionInputOwner } from "./memory-correction-input-owner.js";
7
+ import { PreparedMemoryVerificationChecks } from "./memory-verification-checks.js";
8
+ import { runtimeCommand } from "./runtime-command.js";
9
+ const token = Symbol("memory-correction-check-receipt");
10
+ const event = "memory.correction_checks";
11
+ function refuse(reason) {
12
+ throw new AppError("memory_correction_checks_invalid", "Correction checks lack independent current-view and policy custody", 2, { reason, effect: "no_effect" });
13
+ }
14
+ function stored(context, corrected) {
15
+ corrected.assertCustody(context);
16
+ const view = corrected.value();
17
+ const rows = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.wave')=? LIMIT 2", [view.scope.project_id, event, view.scope.run_id, view.wave]);
18
+ if (!rows.length)
19
+ return null;
20
+ if (rows.length !== 1 || Buffer.byteLength(rows[0].payload_json) > 2 * 1024 * 1024)
21
+ refuse("ambiguous_or_unbounded_check_receipt");
22
+ let value;
23
+ try {
24
+ value = JSON.parse(rows[0].payload_json);
25
+ }
26
+ catch {
27
+ return refuse("invalid_check_receipt");
28
+ }
29
+ if (!value || typeof value !== "object" || Array.isArray(value))
30
+ refuse("invalid_check_receipt");
31
+ return value;
32
+ }
33
+ /** Independent finite-check acceptance, not reviewer or Stage acceptance.
34
+ * Registration and reconnect use exact current-view evidence. They never
35
+ * execute a command, allocate Work or declare semantic completeness. */
36
+ export class PreparedMemoryCorrectionCheckReceipt {
37
+ static isPrepared(value) {
38
+ return typeof value === "object" && value !== null && #corrected in value;
39
+ }
40
+ sha256;
41
+ #corrected;
42
+ #policy;
43
+ #evidence;
44
+ #receipt;
45
+ #registered;
46
+ constructor(key, corrected, policy, evidence, receipt, registered) {
47
+ if (key !== token)
48
+ refuse("check_receipt_token_required");
49
+ this.#corrected = corrected;
50
+ this.#policy = policy;
51
+ this.#evidence = evidence;
52
+ this.#receipt = structuredClone(receipt);
53
+ this.#registered = registered;
54
+ this.sha256 = hybridDigest(receipt);
55
+ Object.freeze(this);
56
+ }
57
+ static prepare(context, corrected, policy) {
58
+ if (!isMemoryCorrectionInputOwner(corrected) || !PreparedMemoryVerificationChecks.isPrepared(policy))
59
+ refuse("prepared_check_owners_required");
60
+ if (context.db.isOwnedWriteTransaction?.())
61
+ refuse("preparation_outside_writer_required");
62
+ policy.assertCorrectionOwner(corrected);
63
+ // evidence() revalidates the policy and its exact bound correction owner.
64
+ const view = corrected.value(), evidence = policy.evidence(context);
65
+ evidence.assertOwner({ projectId: view.scope.project_id, runId: view.scope.run_id, scope: "aggregate" });
66
+ const receipt = { schema_id: "dd-flow/memory-correction-checks@1", project_id: view.scope.project_id, run_id: view.scope.run_id,
67
+ wave: view.wave, review_input_sha256: view.scope.input_sha256, corrected_input_sha256: corrected.sha256,
68
+ completed_correction_sha256: view.completed_correction_sha256, profile_sha256: corrected.verificationProfileHash(context),
69
+ declarations_sha256: hybridDigest(policy.declarations()), checks: evidence.retainedReferences(context) };
70
+ if (!receipt.checks.length || receipt.checks.length > 4096 || Buffer.byteLength(JSON.stringify(receipt)) > 2 * 1024 * 1024)
71
+ refuse("unbounded_check_receipt");
72
+ const existing = context.db.readSnapshot(() => stored(context, corrected));
73
+ if (existing && hybridDigest(existing) !== hybridDigest(receipt))
74
+ refuse("registered_check_receipt_changed");
75
+ const prepared = new PreparedMemoryCorrectionCheckReceipt(token, corrected, policy, evidence, receipt, Boolean(existing));
76
+ prepared.assertCustody(context);
77
+ return prepared;
78
+ }
79
+ static restore(context, corrected) {
80
+ if (!isMemoryCorrectionInputOwner(corrected))
81
+ refuse("prepared_check_owners_required");
82
+ if (context.db.isOwnedWriteTransaction?.())
83
+ refuse("preparation_outside_writer_required");
84
+ if (!context.db.readSnapshot(() => stored(context, corrected))) {
85
+ const view = corrected.value(), projectRoot = corrected.bundle().execution.snapshot().scope.projectRoot;
86
+ const args = ["--run", view.scope.run_id, "--project-root", projectRoot, "--wave", String(view.wave), "--json"];
87
+ throw new AppError("memory_correction_checks_invalid", "Correction checks have not been registered for the settled corrected view", 2, { reason: "registered_check_receipt_required", phase: "prepare", effect: "no_effect", recoverable: true,
88
+ correction_instruction: `Run ${runtimeCommand(context, ["memory", "corrections", "checks", ...args])}, then ${runtimeCommand(context, ["memory", "review", "selective-register", ...args])}. End this Turn so the controller can dispatch the independent reviewers. Use retry_command only after their selective review completes; do not retry Finish before checks and selective review.` });
89
+ }
90
+ const bundle = corrected.bundle(), scope = corrected.value().scope;
91
+ const policy = PreparedMemoryVerificationChecks.prepare(context, { projectId: scope.project_id, runId: scope.run_id,
92
+ execution: bundle.execution, flow: bundle.descriptor, corrected });
93
+ return PreparedMemoryCorrectionCheckReceipt.prepare(context, corrected, policy);
94
+ }
95
+ value() {
96
+ return structuredClone(this.#receipt);
97
+ }
98
+ assertOwner(corrected) {
99
+ if (!isMemoryCorrectionInputOwner(corrected) || corrected.sha256 !== this.#corrected.sha256)
100
+ refuse("foreign_corrected_check_receipt");
101
+ }
102
+ assertRegisteredCustody(context) {
103
+ if (!this.#registered)
104
+ refuse("registered_check_receipt_required");
105
+ this.assertCustody(context);
106
+ }
107
+ assertCustody(context) {
108
+ this.#corrected.assertCustody(context);
109
+ this.#policy.assertCustody(context);
110
+ this.#evidence.assertCustody(context);
111
+ const existing = stored(context, this.#corrected);
112
+ if ((this.#registered && !existing) || (existing && hybridDigest(existing) !== this.sha256))
113
+ refuse("registered_check_receipt_changed");
114
+ if (hybridDigest(this.#evidence.retainedReferences(context)) !== hybridDigest(this.#receipt.checks))
115
+ refuse("selected_check_evidence_changed");
116
+ }
117
+ revalidate(context) {
118
+ this.#policy.revalidate(context);
119
+ this.#evidence.revalidate(context);
120
+ this.assertCustody(context);
121
+ }
122
+ register(context) {
123
+ this.revalidate(context);
124
+ const replay = context.db.writeTransaction(() => {
125
+ if (!context.db.isOwnedWriteTransaction?.())
126
+ refuse("owned_check_writer_required");
127
+ this.assertCustody(context);
128
+ const existing = stored(context, this.#corrected);
129
+ if (existing)
130
+ return true;
131
+ appendAudit(context, { projectId: this.#receipt.project_id, eventType: event, payload: this.#receipt });
132
+ return false;
133
+ }, "memory.registerCorrectionChecks");
134
+ this.#registered = true;
135
+ this.assertCustody(context);
136
+ try {
137
+ this.revalidate(context);
138
+ }
139
+ catch (error) {
140
+ throw new AppError("memory_correction_checks_pending", "Check receipt committed but current-view revalidation needs recovery", 1, { effect: "committed", receipt_sha256: this.sha256, cause: error instanceof Error ? error.message : String(error) });
141
+ }
142
+ return { receipt: this.value(), receipt_sha256: this.sha256, replay };
143
+ }
144
+ }
145
+ function historicalReceipt(context, scope) {
146
+ const rows = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.wave')=? LIMIT 2", [scope.projectId, event, scope.runId, scope.wave]);
147
+ if (rows.length !== 1 || Buffer.byteLength(rows[0].payload_json) > 2 * 1024 * 1024)
148
+ refuse("historical_check_receipt_missing");
149
+ let value;
150
+ try {
151
+ value = JSON.parse(rows[0].payload_json);
152
+ }
153
+ catch {
154
+ return refuse("invalid_check_receipt");
155
+ }
156
+ if (!value || typeof value !== "object" || Array.isArray(value)
157
+ || value.schema_id !== "dd-flow/memory-correction-checks@1" || value.project_id !== scope.projectId
158
+ || value.run_id !== scope.runId || value.wave !== scope.wave || value.corrected_input_sha256 !== scope.correctedInputSha256
159
+ || hybridDigest(value) !== scope.receiptSha256
160
+ || [value.review_input_sha256, value.corrected_input_sha256, value.completed_correction_sha256, value.declarations_sha256]
161
+ .some(hash => typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash))
162
+ || (value.profile_sha256 !== null && (typeof value.profile_sha256 !== "string" || !/^[a-f0-9]{64}$/.test(value.profile_sha256)))
163
+ || Object.keys(value).some(key => !["schema_id", "project_id", "run_id", "wave", "review_input_sha256", "corrected_input_sha256",
164
+ "completed_correction_sha256", "profile_sha256", "declarations_sha256", "checks"].includes(key))
165
+ || !Array.isArray(value.checks) || !value.checks.length || value.checks.length > 4096
166
+ || value.checks.some(ref => !ref || typeof ref !== "object" || Array.isArray(ref)
167
+ || typeof ref.id !== "string" || !ref.id || typeof ref.path !== "string"
168
+ || Object.keys(ref).some(key => !["id", "path", "sha256", "sql_sha256"].includes(key))
169
+ || [ref.sha256, ref.sql_sha256].some(hash => typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash))))
170
+ refuse("historical_check_receipt_changed");
171
+ for (const reference of value.checks) {
172
+ const row = context.db.get("SELECT profile_hash FROM check_receipts WHERE project_id=? AND run_id=? AND id=?", [scope.projectId, scope.runId, reference?.id]);
173
+ if (!row || row.profile_hash !== value.profile_sha256)
174
+ refuse("historical_check_policy_changed");
175
+ }
176
+ return value;
177
+ }
178
+ /** Retained finite-check proof for accepted-review replay. Expected hashes
179
+ * must come from the independent reviewer/Stage receipt, not a caller claim.
180
+ * This owner proves only the scoped historical check receipt and executions;
181
+ * it grants no current-view, reviewer allocation or Stage acceptance rights. */
182
+ export class PreparedRetainedMemoryCorrectionChecks {
183
+ #scope;
184
+ #checks;
185
+ constructor(key, scope, checks) {
186
+ if (key !== token)
187
+ refuse("check_receipt_token_required");
188
+ this.#scope = { ...scope };
189
+ this.#checks = checks;
190
+ Object.freeze(this);
191
+ }
192
+ static prepare(context, scope) {
193
+ return this.prepareWave(context, scope, 1);
194
+ }
195
+ static prepareSecond(context, scope) {
196
+ return this.prepareWave(context, scope, 2);
197
+ }
198
+ static prepareWave(context, scope, wave) {
199
+ if (wave !== 1 && wave !== 2)
200
+ refuse("historical_check_wave_required");
201
+ if (!scope || typeof scope.projectId !== "string" || !scope.projectId || typeof scope.runId !== "string" || !scope.runId
202
+ || [scope.receiptSha256, scope.correctedInputSha256].some(hash => typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash)))
203
+ refuse("historical_check_scope_required");
204
+ if (context.db.isOwnedWriteTransaction?.())
205
+ refuse("preparation_outside_writer_required");
206
+ const selectedScope = { ...scope, wave };
207
+ const receipt = context.db.readSnapshot(() => historicalReceipt(context, selectedScope));
208
+ const checks = PreparedRetainedCheckEvidence.prepare(context, { projectId: scope.projectId, runId: scope.runId, references: receipt.checks });
209
+ const prepared = new PreparedRetainedMemoryCorrectionChecks(token, selectedScope, checks);
210
+ prepared.assertCustody(context);
211
+ return prepared;
212
+ }
213
+ assertCustody(context) {
214
+ historicalReceipt(context, this.#scope);
215
+ this.#checks.assertCustody(context);
216
+ }
217
+ value(context) { this.assertCustody(context); return structuredClone(historicalReceipt(context, this.#scope)); }
218
+ revalidate(context) { this.#checks.revalidate(context); this.assertCustody(context); }
219
+ }
@@ -0,0 +1,6 @@
1
+ import { PreparedCorrectedMemoryReviewInputs } from "./memory-corrected-review-inputs.js";
2
+ import { PreparedSecondCorrectedMemoryReviewInputs } from "./memory-second-corrected-review-inputs.js";
3
+ /** Only the two sealed wave owners, never a structural evidence interface. */
4
+ export function isMemoryCorrectionInputOwner(value) {
5
+ return PreparedCorrectedMemoryReviewInputs.isPrepared(value) || PreparedSecondCorrectedMemoryReviewInputs.isPrepared(value);
6
+ }
@@ -0,0 +1,104 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { PreparedMemoryStageResult, memorySourceKey } from "./memory-stage-results.js";
3
+ import { PreparedMemoryResultBinding } from "./memory-result-binding.js";
4
+ import { PreparedMemoryBaselinePreservation } from "./memory-baseline-preservation.js";
5
+ import { captureMemoryPreflightSources } from "./memory-preflight-handler.js";
6
+ import { PreparedDescriptorStageStart } from "./descriptor-stage-start.js";
7
+ import { PreparedDescriptorStageCoordinator } from "./descriptor-stage-coordinator.js";
8
+ import { PreparedDescriptorStageSettlement } from "./descriptor-stage-settlement.js";
9
+ import { readAcceptedStageData } from "./stage-report-renderer.js";
10
+ import { assertPreparedRunBundleSqlAuthority, readFlowRunExecutionBundle } from "./runs.js";
11
+ import { requireProjectByRoot } from "./projects.js";
12
+ import { resolveProjectRoot } from "../storage/paths.js";
13
+ function refuse(reason) {
14
+ throw new AppError("memory_discover_handler_invalid", "Memory discovery lacks accepted scope or bounded evidence", 2, { reason, effect: "no_effect" });
15
+ }
16
+ function selected(context, input) {
17
+ if (!(input.bytes instanceof Uint8Array) || input.bytes.length > 1024 * 1024)
18
+ refuse("invalid_input_bytes");
19
+ const bundle = readFlowRunExecutionBundle(context, input);
20
+ if (!bundle || bundle.descriptor.descriptor.id !== "mb-init" || bundle.descriptor.successor("preflight", "accepted") !== "discover")
21
+ refuse("registered_memory_bundle_required");
22
+ const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot)), scope = { projectId: project.id, runId: input.runId, stage: "discover" };
23
+ const run = assertPreparedRunBundleSqlAuthority(context, scope, bundle), index = JSON.parse(run.index_json);
24
+ return { bundle, scope, accepted: index.stage_runs.find((stage) => stage.stage === "discover")?.status === "done" };
25
+ }
26
+ /** Result-level discovery checks, not physical/RUN or semantic completeness
27
+ * authority. The handler separately supplies independently selected SQL scope
28
+ * and physical baseline observations. Unknown facts remain valid with their
29
+ * frozen-schema reason/next-action rather than being converted to confirmations.
30
+ */
31
+ export class PreparedMemoryDiscoveryAcceptance {
32
+ #sha256;
33
+ constructor(result) { this.#sha256 = result.sha256; Object.freeze(this); }
34
+ static prepare(result) {
35
+ if (!(result instanceof PreparedMemoryStageResult))
36
+ refuse("prepared_result_required");
37
+ const value = JSON.parse(result.bytes().toString("utf8"));
38
+ if (value.stage !== "discover" || value.outcome !== "accepted"
39
+ || value.findings.some((finding) => finding.severity !== "minor" && finding.status !== "resolved"))
40
+ refuse("discovery_not_accepted");
41
+ const inventory = new Map();
42
+ for (const source of value.details.inventory) {
43
+ const key = memorySourceKey(source.root, source.path);
44
+ if (inventory.has(key))
45
+ refuse("duplicate_inventory_source");
46
+ inventory.set(key, source.sha256);
47
+ }
48
+ const exclusions = new Set();
49
+ for (const exclusion of value.details.exclusions) {
50
+ if (!exclusion.reason.trim() || exclusions.has(exclusion.path))
51
+ refuse("invalid_or_duplicate_exclusion");
52
+ exclusions.add(exclusion.path);
53
+ const excluded = exclusion.path.replace(/\/+$/, "");
54
+ if (value.details.inventory.some((source) => source.path === excluded || source.path.startsWith(`${excluded}/`)))
55
+ refuse("observed_source_excluded");
56
+ }
57
+ return new PreparedMemoryDiscoveryAcceptance(result);
58
+ }
59
+ assertResult(result) {
60
+ if (!(result instanceof PreparedMemoryStageResult) || result.sha256 !== this.#sha256)
61
+ refuse("discovery_result_changed");
62
+ }
63
+ }
64
+ /** Unregistered implementation until the complete memory registry is ready.
65
+ * Entry inherits accepted preflight and preserves its independent bootstrap
66
+ * baseline through Stage/coordinator writers, without dispatching a provider.
67
+ */
68
+ export function startMemoryDiscovery(context, input) {
69
+ const { bundle, scope, accepted } = selected(context, input);
70
+ if (accepted)
71
+ refuse("use_accepted_finish_replay");
72
+ const preservation = PreparedMemoryBaselinePreservation.prepare(context, bundle.execution);
73
+ const preflight = context.db.readSnapshot(() => readAcceptedStageData(context, { ...scope, stage: "preflight" }));
74
+ const value = JSON.parse(preflight.bytes.toString("utf8"));
75
+ if (value.schema_id !== "dd-flow/mb-init-preflight-result@1" || value.outcome !== "accepted" || value.run_id !== input.runId)
76
+ refuse("foreign_preflight_baseline");
77
+ const fence = (writer) => {
78
+ preservation.assertCustody(writer);
79
+ if (readAcceptedStageData(writer, { ...scope, stage: "preflight" }).authority_sha256 !== preflight.authority_sha256)
80
+ refuse("preflight_custody_changed");
81
+ };
82
+ const start = PreparedDescriptorStageStart.prepare(context, { ...input, stage: "discover" });
83
+ preservation.revalidate(context);
84
+ const stage = start.apply(context, fence);
85
+ const coordinator = PreparedDescriptorStageCoordinator.prepare(context, { ...input, stage: "discover" });
86
+ preservation.revalidate(context);
87
+ return { ...stage, ...coordinator.apply(context, fence) };
88
+ }
89
+ export function finishMemoryDiscovery(context, input) {
90
+ const { bundle, scope, accepted } = selected(context, input);
91
+ const sources = captureMemoryPreflightSources(context, bundle, input.bytes);
92
+ const binding = PreparedMemoryResultBinding.prepare(context, { ...scope, flow: bundle.descriptor, execution: bundle.execution, bundle, sources, acceptedReplay: accepted });
93
+ const replay = binding.acceptedBytes();
94
+ if (replay && !replay.equals(input.bytes))
95
+ refuse("accepted_result_changed");
96
+ const result = PreparedMemoryStageResult.prepare(input.bytes, bundle.descriptor, binding.binding());
97
+ const acceptance = PreparedMemoryDiscoveryAcceptance.prepare(result);
98
+ const settlement = PreparedDescriptorStageSettlement.prepare(context, { ...input, stage: "discover", bytes: result.bytes() });
99
+ binding.revalidate(context);
100
+ return settlement.apply(context, writer => {
101
+ binding.assertCustody(writer);
102
+ acceptance.assertResult(result);
103
+ });
104
+ }