@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,206 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { hybridDigest } from "./hybrid-contracts.js";
3
+ import { PreparedHistoricalOriginalMemoryReview } from "./memory-historical-original-review.js";
4
+ import { PreparedHistoricalMemoryRepairRegistration } from "./memory-historical-repair-registration.js";
5
+ import { PreparedSettledMemoryRepair } from "./memory-repair-history.js";
6
+ import { readRetainedCorrectedMemoryReviewRegistration } from "./memory-corrected-review-registration.js";
7
+ import { PreparedRetainedMemoryCorrectionChecks } from "./memory-correction-check-receipt.js";
8
+ import { readMemoryReviewWorkSettlement } from "./memory-review-acceptance.js";
9
+ import { validateMemoryReviewWorkResult } from "./memory-review-work-results.js";
10
+ import { memoryCorrectedReviewBatch } from "./memory-corrected-review-batch.js";
11
+ import { correctedMemoryReviewAssignments } from "./memory-corrected-review-inputs.js";
12
+ import { memoryCorrectionAffectedUnits } from "./memory-completed-correction-wave.js";
13
+ import { correctedMemoryReviewUnits } from "./memory-corrected-review-projection.js";
14
+ import { correctedMemoryReviewFindings } from "./memory-corrected-review-findings.js";
15
+ import { readAcceptedStageData } from "./stage-report-renderer.js";
16
+ import { runtimeHarness } from "./execution-policy.js";
17
+ import { ObservedMemorySources } from "./memory-source-observations.js";
18
+ import { memorySourceKey } from "./memory-stage-results.js";
19
+ const token = Symbol("historical-corrected-memory-review");
20
+ function refuse(reason) {
21
+ throw new AppError("memory_historical_corrected_review_invalid", "Historical selective review lacks independent correction and reviewer custody", 2, { reason, effect: "no_effect" });
22
+ }
23
+ /** Retained metadata consistency only, not SQL/Session/Stage authority. */
24
+ export function assertHistoricalMemoryReviewSources(histories, paths, runInputs, anchor) {
25
+ if (!Array.isArray(histories) || !histories.length || histories.length > 256
26
+ || !Array.isArray(runInputs) || runInputs.length > 4096)
27
+ refuse("invalid_historical_source_inventory");
28
+ const retainedHistories = histories;
29
+ let baseline = (anchor ?? retainedHistories[0].before()).withWritePaths(paths);
30
+ const visibleMemory = new Set(retainedHistories[0].workspaceManifest().entries()
31
+ .filter(entry => entry.kind === "file" && entry.path.startsWith(".memory-bank/")).map(entry => entry.path));
32
+ const prefixes = new Set([hybridDigest(baseline.entries())]);
33
+ for (const history of retainedHistories) {
34
+ if (!prefixes.has(hybridDigest(history.before().entries())))
35
+ refuse("historical_input_prefix_changed");
36
+ baseline = baseline.composeSettledDelta(history.before(), history.after());
37
+ prefixes.add(hybridDigest(baseline.entries()));
38
+ const before = new Map(history.before().entries().map(entry => [entry.path, entry]));
39
+ for (const entry of history.after().entries())
40
+ if (entry.kind === "file" && hybridDigest(before.get(entry.path) ?? null) !== hybridDigest(entry))
41
+ visibleMemory.add(entry.path);
42
+ }
43
+ const memory = (path) => path === ".memory-bank" || path.startsWith(".memory-bank/");
44
+ const finalFiles = new Map(baseline.entries().filter(entry => entry.kind === "file" && visibleMemory.has(entry.path)).map(entry => [entry.path, entry.sha256]));
45
+ const nonMemory = retainedHistories[0].workspaceManifest().entries().filter(entry => !memory(entry.path));
46
+ const files = (entries) => entries.filter(entry => entry.kind === "file").map(entry => ({ path: entry.path, sha256: entry.sha256 }));
47
+ const sort = (entries) => [...entries].sort((a, b) => a.path.localeCompare(b.path, "en"));
48
+ const workspace = runInputs.filter(ref => ref.root === "workspace");
49
+ if (retainedHistories.some(history => hybridDigest(history.workspaceManifest().entries().filter(entry => !memory(entry.path))) !== hybridDigest(nonMemory))
50
+ || hybridDigest(sort(files(nonMemory))) !== hybridDigest(sort(workspace.filter(ref => !memory(ref.path)).map(ref => ({ path: ref.path, sha256: ref.sha256 }))))
51
+ || hybridDigest(sort([...finalFiles].map(([path, sha256]) => ({ path, sha256 }))))
52
+ !== hybridDigest(sort(workspace.filter(ref => memory(ref.path)).map(ref => ({ path: ref.path, sha256: ref.sha256 }))))
53
+ || new Set(runInputs.map(ref => `${ref.root}:${ref.path}`)).size !== runInputs.length)
54
+ refuse("historical_workspace_projection_changed");
55
+ }
56
+ /** Historical full projection only, not Stage receipt acceptance. Expected
57
+ * input/check hashes must be selected from the independent accepted receipt.
58
+ * Current workspace/copies/policy are never adopted or used for re-admission. */
59
+ export class PreparedHistoricalCorrectedMemoryReview {
60
+ static isPrepared(value) {
61
+ return typeof value === "object" && value !== null && #original in value;
62
+ }
63
+ #original;
64
+ #repairs;
65
+ #histories;
66
+ #checks;
67
+ #registration;
68
+ #workers;
69
+ #projection;
70
+ #observed;
71
+ #effective;
72
+ #reviewSha256;
73
+ constructor(key, original, repairs, histories, checks, registration, workers, projection, observed, effective, results) {
74
+ if (key !== token)
75
+ refuse("historical_review_token_required");
76
+ this.#original = original;
77
+ this.#repairs = repairs;
78
+ this.#histories = histories;
79
+ this.#checks = checks;
80
+ this.#registration = structuredClone(registration);
81
+ this.#workers = workers;
82
+ this.#projection = structuredClone(projection);
83
+ this.#observed = observed;
84
+ this.#effective = structuredClone(effective);
85
+ this.#reviewSha256 = hybridDigest({ registration_sha256: hybridDigest(this.#registration), workers: this.#workers.map(worker => ({
86
+ work_id: worker.workId, authority_sha256: worker.authority, result: worker.result
87
+ })), results });
88
+ Object.freeze(this);
89
+ }
90
+ static prepare(context, input) {
91
+ if (!PreparedHistoricalOriginalMemoryReview.isPrepared(input.original))
92
+ refuse("historical_original_required");
93
+ if (context.db.isOwnedWriteTransaction?.())
94
+ refuse("preparation_outside_writer_required");
95
+ const original = input.original, initial = original.registration(), scope = initial.scope, bundle = original.bundle();
96
+ original.revalidate(context);
97
+ const registration = context.db.readSnapshot(() => readRetainedCorrectedMemoryReviewRegistration(context, scope, input.correctedInputSha256, input.checkReceiptSha256));
98
+ if (!registration)
99
+ refuse("historical_registration_required");
100
+ const view = registration.view, repairs = PreparedHistoricalMemoryRepairRegistration.prepare(context, original);
101
+ const histories = repairs.completedWorkOrder(context).map(id => PreparedSettledMemoryRepair.prepare(context, repairs, id));
102
+ const repairReceipt = repairs.receipt(), repairBatch = repairs.batch();
103
+ const paths = [...new Set(repairBatch.works.flatMap(item => item.payload.memory_repair.write_paths))].sort();
104
+ assertHistoricalMemoryReviewSources(histories, paths, view.run_inputs);
105
+ const repairResults = histories.map(history => ({ work_id: history.workId, result: history.result(), reference: history.reference(), authority_sha256: history.sha256,
106
+ unit_ids: repairBatch.works.find(item => repairReceipt.work_ids[item.key] === history.workId).payload.memory_repair.unit_ids }));
107
+ const compose = readAcceptedStageData(context, { projectId: scope.project_id, runId: scope.run_id, stage: "compose" });
108
+ const affected = memoryCorrectionAffectedUnits(initial.view.unit_inventory, repairResults, JSON.parse(compose.bytes.toString("utf8")).details.works);
109
+ const assignments = correctedMemoryReviewAssignments({ units: initial.view.unit_inventory, initialAssignments: initial.view.assignments, affected,
110
+ files: view.run_inputs.filter(ref => ref.root === "workspace"), repairs: repairResults });
111
+ if (view.schema_id !== "dd-flow/memory-corrected-review-inputs@1" || view.source_policy !== initial.view.source_policy
112
+ || view.original_review_sha256 !== original.reviewSha256() || view.base !== initial.view.base
113
+ || hybridDigest(view.unit_inventory) !== hybridDigest(initial.view.unit_inventory)
114
+ || hybridDigest(view.instruction) !== hybridDigest(initial.view.instruction)
115
+ || hybridDigest(view.affected_unit_ids) !== hybridDigest(affected) || hybridDigest(view.assignments) !== hybridDigest(assignments)
116
+ || hybridDigest(view.repairs) !== hybridDigest(repairResults.map(repair => ({ work_id: repair.work_id, authority_sha256: repair.authority_sha256, result: repair.reference }))))
117
+ refuse("historical_correction_projection_changed");
118
+ const checks = PreparedRetainedMemoryCorrectionChecks.prepare(context, { projectId: scope.project_id, runId: scope.run_id,
119
+ correctedInputSha256: registration.input_sha256, receiptSha256: registration.check_receipt_sha256 });
120
+ if (checks.value(context).completed_correction_sha256 !== view.completed_correction_sha256)
121
+ refuse("historical_check_wave_changed");
122
+ const batch = memoryCorrectedReviewBatch(view), harness = runtimeHarness(bundle.execution.work("review").worker);
123
+ const workers = context.db.readSnapshot(() => batch.works.map(item => readMemoryReviewWorkSettlement(context, registration, registration.work_ids[item.key], harness)));
124
+ const engine = bundle.engine();
125
+ const results = workers.map((worker, index) => validateMemoryReviewWorkResult(worker.bytes, engine, {
126
+ workId: worker.workId, packet: batch.works[index].payload.memory_review, references: view.run_inputs
127
+ }));
128
+ const references = workers.map((worker, index) => ({ reviewer_work_id: worker.workId, input_sha256: registration.input_sha256,
129
+ result: worker.result, unit_ids: [results[index].unit_id] }));
130
+ const projection = { ...correctedMemoryReviewUnits({ view, original: original.results(), current: results, originalReferences: original.references(),
131
+ currentReferences: references, repairWorkIds: histories.map(history => history.workId) }),
132
+ ...correctedMemoryReviewFindings({ original: original.results(), current: results, affected, originalReferences: original.references(), currentReferences: references, repairs: repairResults,
133
+ diagnostics: original.registration().view.diagnostic_findings, diagnosticReference: original.registration().view.run_inputs.find(ref => ref.root === "run" && ref.path === `${bundle.descriptor.stage("verify").directory}/result.json`) }) };
134
+ const observed = ObservedMemorySources.capture({ run: workers[0].root }, workers.map(worker => ({ root: "run", path: worker.result.path })));
135
+ const hashes = observed.hashes();
136
+ if (workers.some(worker => hashes.get(memorySourceKey("run", worker.result.path)) !== worker.result.sha256))
137
+ refuse("historical_reviewer_artifact_changed");
138
+ const originalReferences = original.references();
139
+ const effectiveResults = original.results().map(old => results.find(result => result.unit_id === old.unit_id) ?? old);
140
+ const effectiveReferences = effectiveResults.map(result => references.find(reference => reference.reviewer_work_id === result.work_id)
141
+ ?? originalReferences.find(reference => reference.reviewer_work_id === result.work_id));
142
+ if (effectiveReferences.some(reference => !reference))
143
+ refuse("effective_review_reference_missing");
144
+ const prepared = new PreparedHistoricalCorrectedMemoryReview(token, original, repairs, histories, checks, registration, workers, projection, observed, { results: effectiveResults, references: effectiveReferences, projection }, results);
145
+ prepared.assertCustody(context);
146
+ return prepared;
147
+ }
148
+ projection() { return structuredClone(this.#projection); }
149
+ /** Retained complete protected document state after the first repair graph.
150
+ * Not a physical current-source or write-permission admission. */
151
+ settledDocumentBaseline() {
152
+ const paths = [...new Set(this.#repairs.batch().works.flatMap(item => item.payload.memory_repair.write_paths))].sort();
153
+ let baseline = this.#histories[0].before().withWritePaths(paths);
154
+ const prefixes = new Set([hybridDigest(baseline.entries())]);
155
+ for (const history of this.#histories) {
156
+ if (!prefixes.has(hybridDigest(history.before().entries())))
157
+ refuse("historical_input_prefix_changed");
158
+ baseline = baseline.composeSettledDelta(history.before(), history.after());
159
+ prefixes.add(hybridDigest(baseline.entries()));
160
+ }
161
+ return baseline;
162
+ }
163
+ retainedInputView() { return structuredClone(this.#registration.view); }
164
+ finalChecks(context) { this.assertCustody(context); return this.#checks.value(context).checks; }
165
+ /** Effective full review inventory after selective wave one. Results and
166
+ * references come from retained settlements, never workspace recapture. */
167
+ effectiveReviewProof(context) {
168
+ this.assertCustody(context);
169
+ return structuredClone(this.#effective);
170
+ }
171
+ bundle() { return this.#original.bundle(); }
172
+ verificationProfileHash(context) { this.assertCustody(context); return this.#original.verificationProfileHash(context); }
173
+ /** Exact live fan-in identity reconstructed from retained settlements.
174
+ * A digest is an identity, not independent plan or Stage acceptance. */
175
+ reviewSha256() {
176
+ return this.#reviewSha256;
177
+ }
178
+ settlementProof(context) {
179
+ this.assertCustody(context);
180
+ return { registration_scope: structuredClone(this.#registration.scope), registration_sha256: hybridDigest(this.#registration), wave: 1,
181
+ check_receipt_sha256: this.#registration.check_receipt_sha256, workers: this.#workers.map(worker => ({ work_id: worker.workId,
182
+ authority_sha256: worker.authority, result: { ...worker.result } })) };
183
+ }
184
+ assertCustody(context) {
185
+ this.#original.assertCustody(context);
186
+ this.#repairs.assertCustody(context);
187
+ this.#checks.assertCustody(context);
188
+ if (hybridDigest(readRetainedCorrectedMemoryReviewRegistration(context, this.#registration.scope, this.#registration.input_sha256, this.#registration.check_receipt_sha256)) !== hybridDigest(this.#registration))
189
+ refuse("historical_registration_changed");
190
+ for (const history of this.#histories)
191
+ history.assertCustody(context);
192
+ const harness = runtimeHarness(this.#original.bundle().execution.work("review").worker);
193
+ for (const worker of this.#workers)
194
+ if (readMemoryReviewWorkSettlement(context, this.#registration, worker.workId, harness).authority !== worker.authority)
195
+ refuse("historical_reviewer_settlement_changed");
196
+ }
197
+ revalidate(context) {
198
+ this.#original.revalidate(context);
199
+ this.#repairs.revalidate(context);
200
+ this.#checks.revalidate(context);
201
+ for (const history of this.#histories)
202
+ history.revalidate(context);
203
+ this.#observed.revalidate();
204
+ this.assertCustody(context);
205
+ }
206
+ }
@@ -0,0 +1,130 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { hybridDigest } from "./hybrid-contracts.js";
3
+ import { RetainedExecutionBundle } from "./execution-bundles.js";
4
+ import { assertPreparedRunBundleSqlAuthority } from "./runs.js";
5
+ import { readDescriptorRootWork } from "./descriptor-root-work.js";
6
+ import { readAcceptedStageData } from "./stage-report-renderer.js";
7
+ import { readRegisteredMemoryReview, memoryReviewBatch } from "./memory-review-registration.js";
8
+ import { readMemoryReviewWorkSettlement } from "./memory-review-acceptance.js";
9
+ import { validateMemoryReviewWorkResult } from "./memory-review-work-results.js";
10
+ import { PreparedAcceptedMemoryVerification } from "./memory-verification-receipt.js";
11
+ import { runtimeHarness } from "./execution-policy.js";
12
+ import { ObservedMemorySources } from "./memory-source-observations.js";
13
+ import { memorySourceKey } from "./memory-stage-results.js";
14
+ const token = Symbol("historical-original-memory-review");
15
+ function refuse(reason) {
16
+ throw new AppError("memory_historical_original_review_invalid", "Closed review lacks retained original reviewer custody", 2, { reason, effect: "no_effect" });
17
+ }
18
+ function selected(context, scope, bundle, mode) {
19
+ const run = assertPreparedRunBundleSqlAuthority(context, scope, bundle), index = JSON.parse(run.index_json);
20
+ const stage = index.stage_runs?.find((item) => item.stage === "review");
21
+ if (stage?.status !== (mode === "closed" ? "done" : "running") || typeof stage.attempt !== "string" || !/^try-[0-9]{3,}$/.test(stage.attempt)
22
+ || typeof stage.input_sha256 !== "string" || !/^[a-f0-9]{64}$/.test(stage.input_sha256))
23
+ refuse(mode === "closed" ? "closed_review_required" : "open_review_required");
24
+ const root = readDescriptorRootWork(context, scope, bundle);
25
+ if (mode === "open" && (run.status !== "running" || index.current_stage !== "review" || root.status !== "running"))
26
+ refuse("open_review_required");
27
+ const phase = { project_id: scope.projectId, run_id: scope.runId, stage: "review", attempt: stage.attempt,
28
+ input_sha256: stage.input_sha256, parent_work_id: root.workId, execution_sha256: bundle.execution.sha256, bundle_sha256: bundle.sha256 };
29
+ const registration = readRegisteredMemoryReview(context, phase, 0), view = registration.view;
30
+ const compose = readAcceptedStageData(context, { ...scope, stage: "compose" }), verify = readAcceptedStageData(context, { ...scope, stage: "verify" });
31
+ const review = mode === "closed" ? readAcceptedStageData(context, { ...scope, stage: "review" }) : null;
32
+ const composed = JSON.parse(compose.bytes.toString("utf8"));
33
+ if (compose.data_schema_id !== "dd-flow/mb-init-compose-result@1" || composed.schema_id !== compose.data_schema_id
34
+ || composed.stage !== "compose" || composed.run_id !== scope.runId || composed.outcome !== "accepted"
35
+ || composed.input_sha256 !== compose.input_sha256 || hybridDigest(composed.units) !== hybridDigest(view.unit_inventory)
36
+ || (review !== null && (review.data_schema_id !== "dd-flow/mb-init-review-result@1" || review.input_sha256 !== phase.input_sha256))
37
+ || view.source_policy !== "review-inputs@1" || hybridDigest(view.instruction) !== hybridDigest({
38
+ sha256: bundle.descriptor.stage("review").instruction.sha256, base64: bundle.descriptor.stageBlob("review", "instruction").toString("base64")
39
+ }))
40
+ refuse("historical_original_binding_changed");
41
+ for (const data of [compose, verify]) {
42
+ const refs = view.run_inputs.filter(ref => ref.root === "run" && ref.path === data.result.path);
43
+ if (refs.length !== 1 || refs[0].sha256 !== data.result.sha256)
44
+ refuse("historical_predecessor_changed");
45
+ }
46
+ const batch = memoryReviewBatch(view), harness = runtimeHarness(bundle.execution.work("review").worker);
47
+ const workers = batch.works.map(item => readMemoryReviewWorkSettlement(context, registration, registration.work_ids[item.key], harness));
48
+ return { mode, registration, batch, workers, compose, verify, review, runRoot: run.run_root ?? run.run_dir };
49
+ }
50
+ /** Original wave proof after Stage closure, not accepted corrected-review or
51
+ * repair authority. Never reused by fresh Work allocation or current-view
52
+ * admission. Only retained RUN files and scoped SQL are observed; no active
53
+ * coordinator Session or obsolete workspace copy is required. */
54
+ export class PreparedHistoricalOriginalMemoryReview {
55
+ static isPrepared(value) {
56
+ return typeof value === "object" && value !== null && #scope in value;
57
+ }
58
+ #scope;
59
+ #bundle;
60
+ #value;
61
+ #verification;
62
+ #observed;
63
+ #authority;
64
+ #results;
65
+ constructor(key, scope, bundle, value, verification, observed, results) {
66
+ if (key !== token)
67
+ refuse("historical_token_required");
68
+ this.#scope = { ...scope };
69
+ this.#bundle = bundle;
70
+ this.#value = value;
71
+ this.#verification = verification;
72
+ this.#observed = observed;
73
+ this.#results = structuredClone(results);
74
+ this.#authority = hybridDigest(value);
75
+ Object.freeze(this);
76
+ }
77
+ static prepare(context, input) {
78
+ return this.#prepare(context, input, "closed");
79
+ }
80
+ /** Read-only settled original history while review remains open. This does
81
+ * not admit current source bytes, coordinator mutation or Stage acceptance.
82
+ * The mode is pinned for every custody revalidation, not caller-switchable. */
83
+ static prepareWhileReviewOpen(context, input) {
84
+ return this.#prepare(context, input, "open");
85
+ }
86
+ static #prepare(context, input, mode) {
87
+ if (!(input.bundle instanceof RetainedExecutionBundle) || input.bundle.descriptor.descriptor.id !== "mb-init")
88
+ refuse("registered_memory_bundle_required");
89
+ if (context.db.isOwnedWriteTransaction?.())
90
+ refuse("preparation_outside_writer_required");
91
+ const value = context.db.readSnapshot(() => selected(context, input.scope, input.bundle, mode));
92
+ const verification = PreparedAcceptedMemoryVerification.prepare(context, { ...input.scope, bytes: value.verify.bytes });
93
+ const engine = input.bundle.engine();
94
+ const results = value.workers.map((worker, index) => validateMemoryReviewWorkResult(worker.bytes, engine, {
95
+ workId: worker.workId, packet: value.batch.works[index].payload.memory_review, references: value.registration.view.run_inputs
96
+ }));
97
+ const refs = [value.compose.result, value.verify.result, ...value.workers.map(worker => worker.result)];
98
+ const observed = ObservedMemorySources.capture({ run: value.runRoot }, refs.map(ref => ({ root: "run", path: ref.path })));
99
+ const hashes = observed.hashes();
100
+ if (refs.some(ref => hashes.get(memorySourceKey("run", ref.path)) !== ref.sha256))
101
+ refuse("historical_result_artifact_changed");
102
+ const prepared = new PreparedHistoricalOriginalMemoryReview(token, input.scope, input.bundle, value, verification, observed, results);
103
+ prepared.assertCustody(context);
104
+ return prepared;
105
+ }
106
+ registration() { return structuredClone(this.#value.registration); }
107
+ bundle() { return this.#bundle; }
108
+ verificationProfileHash(context) { this.assertCustody(context); return this.#verification.profileHash(context); }
109
+ reviewSha256() {
110
+ const value = this.#value, registration = value.registration, phase = registration.scope;
111
+ const original = hybridDigest({ phase, registration, compose: value.compose.authority_sha256, verify: value.verify.authority_sha256 });
112
+ const owner = hybridDigest({ registration, original });
113
+ return hybridDigest({ original: owner, workers: value.workers.map(worker => ({ work_id: worker.workId, authority: worker.authority, result: worker.result })),
114
+ results: this.results() });
115
+ }
116
+ // These bytes were admitted at preparation. Physical artifacts and SQL
117
+ // settlements remain independently checked by revalidate/assertCustody.
118
+ results() { return structuredClone(this.#results); }
119
+ references() {
120
+ const results = this.results();
121
+ return this.#value.workers.map((worker, index) => ({ reviewer_work_id: worker.workId, input_sha256: this.#value.registration.input_sha256,
122
+ result: { ...worker.result }, unit_ids: [results[index].unit_id] }));
123
+ }
124
+ assertCustody(context) {
125
+ this.#verification.assertCustody(context);
126
+ if (hybridDigest(selected(context, this.#scope, this.#bundle, this.#value.mode)) !== this.#authority)
127
+ refuse("historical_original_custody_changed");
128
+ }
129
+ revalidate(context) { this.#verification.revalidate(context); this.#observed.revalidate(); this.assertCustody(context); }
130
+ }
@@ -0,0 +1,99 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { hybridDigest } from "./hybrid-contracts.js";
3
+ import { PreparedHistoricalOriginalMemoryReview } from "./memory-historical-original-review.js";
4
+ import { readRetainedMemoryRepairRegistration, assertRetainedMemoryRepairAllocation, memoryRepairBatch, memoryRepairWorkerSchema } from "./memory-repair-registration.js";
5
+ import { validateMemoryReviewCorrectionPlan } from "./memory-review-correction-plan.js";
6
+ import { memoryReviewWaveProjection } from "./memory-review-acceptance.js";
7
+ const token = Symbol("historical-memory-repair-registration");
8
+ function refuse(reason) {
9
+ throw new AppError("memory_historical_repair_registration_invalid", "Closed review lacks retained repair graph custody", 2, { reason, effect: "no_effect" });
10
+ }
11
+ function selected(context, original) {
12
+ original.assertCustody(context);
13
+ const registration = original.registration(), receipt = readRetainedMemoryRepairRegistration(context, registration.scope);
14
+ const results = original.results(), bundle = original.bundle();
15
+ if (receipt.original_registration_sha256 !== hybridDigest(registration) || receipt.review_sha256 !== original.reviewSha256()
16
+ || results.some(result => result.outcome === "blocked"))
17
+ refuse("historical_original_review_changed");
18
+ const engine = bundle.engine();
19
+ const plan = validateMemoryReviewCorrectionPlan(Buffer.from(receipt.plan_base64, "base64"), engine, {
20
+ runId: registration.run_id, wave: 1, reviewSha256: original.reviewSha256(), units: registration.view.unit_inventory,
21
+ findings: memoryReviewWaveProjection(results, registration.view.diagnostic_findings).findings
22
+ });
23
+ for (const item of plan.works)
24
+ bundle.execution.work("review", item.profile_id ?? undefined);
25
+ if (JSON.parse(engine.schema("memory-repair-work-result").toString("utf8")).$id !== memoryRepairWorkerSchema)
26
+ refuse("frozen_repair_schema_required");
27
+ const batch = memoryRepairBatch({ scope: registration.scope, plan, planSha256: receipt.plan_sha256,
28
+ originalRegistrationSha256: hybridDigest(registration), references: [...registration.view.run_inputs,
29
+ ...original.references().map(ref => ({ root: "run", ...ref.result }))], findings: memoryReviewWaveProjection(results, registration.view.diagnostic_findings).findings });
30
+ assertRetainedMemoryRepairAllocation(context, receipt, batch);
31
+ return { receipt, batch };
32
+ }
33
+ /** Closed-Stage repair graph only. Deliberately a distinct private-branded
34
+ * type: fresh repair baseline/copy/start/allocation APIs do not accept it.
35
+ * Settled-history validation may consume it without requiring live review. */
36
+ export class PreparedHistoricalMemoryRepairRegistration {
37
+ static isPrepared(value) {
38
+ return typeof value === "object" && value !== null && #original in value;
39
+ }
40
+ sha256;
41
+ #original;
42
+ #receipt;
43
+ #batch;
44
+ constructor(key, original, value) {
45
+ if (key !== token)
46
+ refuse("historical_registration_token_required");
47
+ this.#original = original;
48
+ this.#receipt = structuredClone(value.receipt);
49
+ this.#batch = structuredClone(value.batch);
50
+ this.sha256 = hybridDigest(value.receipt);
51
+ Object.freeze(this);
52
+ }
53
+ static prepare(context, original) {
54
+ if (!PreparedHistoricalOriginalMemoryReview.isPrepared(original))
55
+ refuse("historical_original_owner_required");
56
+ if (context.db.isOwnedWriteTransaction?.())
57
+ refuse("preparation_outside_writer_required");
58
+ original.revalidate(context);
59
+ const value = context.db.readSnapshot(() => selected(context, original));
60
+ const prepared = new PreparedHistoricalMemoryRepairRegistration(token, original, value);
61
+ prepared.assertCustody(context);
62
+ return prepared;
63
+ }
64
+ receipt() { return structuredClone(this.#receipt); }
65
+ batch() { return structuredClone(this.#batch); }
66
+ review() { return { original: () => this.#original }; }
67
+ completedWorkOrder(context) {
68
+ this.assertCustody(context);
69
+ const receipt = this.#receipt, scope = receipt.scope, batch = this.#batch;
70
+ const all = context.db.all("SELECT id,json_extract(payload_json,'$.work_id') AS work_id FROM audit_events WHERE project_id=? AND event_type='memory.repair_work_settlement' AND json_extract(payload_json,'$.run_id')=? ORDER BY id LIMIT 257", [scope.project_id, scope.run_id]);
71
+ if (all.length > 256)
72
+ refuse("unbounded_historical_settlements");
73
+ const ids = new Set(Object.values(receipt.work_ids)), rows = all.filter(row => ids.has(row.work_id));
74
+ if (rows.length !== batch.works.length || new Set(rows.map(row => row.work_id)).size !== batch.works.length
75
+ || rows.some(row => !Number.isSafeInteger(row.id) || row.id <= 0))
76
+ refuse("historical_settlement_coverage_changed");
77
+ const order = new Map(rows.map((row, index) => [row.work_id, index]));
78
+ for (const item of batch.works) {
79
+ const workId = receipt.work_ids[item.key];
80
+ const work = context.db.get("SELECT status FROM works WHERE project_id=? AND run_id=? AND work_id=? AND parent_work_id=?", [scope.project_id, scope.run_id, workId, scope.parent_work_id]);
81
+ if (work?.status !== "completed" || item.depends_on.some(key => {
82
+ const dependency = receipt.work_ids[key];
83
+ return !dependency || order.get(dependency) >= order.get(workId);
84
+ }))
85
+ refuse("historical_dependency_order_changed");
86
+ }
87
+ return rows.map(row => row.work_id);
88
+ }
89
+ assertCustody(context) {
90
+ this.#original.assertCustody(context);
91
+ const receipt = readRetainedMemoryRepairRegistration(context, this.#receipt.scope);
92
+ if (hybridDigest(receipt) !== this.sha256)
93
+ refuse("historical_repair_registration_changed");
94
+ // The immutable plan/batch was admitted by prepare. Custody checks reread
95
+ // scoped SQL allocation, not the same frozen engine and plan again.
96
+ assertRetainedMemoryRepairAllocation(context, receipt, this.#batch);
97
+ }
98
+ revalidate(context) { this.#original.revalidate(context); this.assertCustody(context); }
99
+ }
@@ -0,0 +1,128 @@
1
+ import { AppError } from "../shared/errors.js";
2
+ import { hybridDigest } from "./hybrid-contracts.js";
3
+ import { PreparedHistoricalSecondMemoryCorrectionWave } from "./memory-completed-correction-wave.js";
4
+ import { assertHistoricalMemoryReviewSources } from "./memory-historical-corrected-review.js";
5
+ import { readRetainedSecondCorrectedMemoryReviewRegistration } from "./memory-corrected-review-registration.js";
6
+ import { PreparedRetainedMemoryCorrectionChecks } from "./memory-correction-check-receipt.js";
7
+ import { secondCorrectedMemoryReviewAssignments, secondCorrectedMemoryReviewReferences } from "./memory-second-corrected-review-inputs.js";
8
+ import { memoryCorrectedReviewBatch } from "./memory-corrected-review-batch.js";
9
+ import { runtimeHarness } from "./execution-policy.js";
10
+ import { readMemoryReviewWorkSettlement } from "./memory-review-acceptance.js";
11
+ import { validateMemoryReviewWorkResult } from "./memory-review-work-results.js";
12
+ import { assertSelectiveMemoryReviewCoverage } from "./memory-corrected-review-acceptance.js";
13
+ import { correctedMemoryReviewUnits } from "./memory-corrected-review-projection.js";
14
+ import { correctedMemoryReviewFindings } from "./memory-corrected-review-findings.js";
15
+ import { ObservedMemorySources } from "./memory-source-observations.js";
16
+ import { memorySourceKey } from "./memory-stage-results.js";
17
+ const token = Symbol("historical-second-memory-review");
18
+ function refuse(reason) {
19
+ throw new AppError("memory_historical_second_review_invalid", "Closed final review lacks independent second-wave custody", 2, { reason, effect: "no_effect" });
20
+ }
21
+ /** Reconstructs closed wave-two fan-in from retained proofs. Expected hashes
22
+ * come from an independently accepted receipt, not current workspace policy.
23
+ * This owner alone neither accepts a Stage nor admits another correction. */
24
+ export class PreparedHistoricalSecondMemoryReview {
25
+ static isPrepared(value) {
26
+ return typeof value === "object" && value !== null && #wave in value;
27
+ }
28
+ #wave;
29
+ #registration;
30
+ #checks;
31
+ #workers;
32
+ #previous;
33
+ #projection;
34
+ #observed;
35
+ constructor(key, wave, registration, checks, workers, previous, projection, observed) {
36
+ if (key !== token)
37
+ refuse("historical_second_review_token_required");
38
+ this.#wave = wave;
39
+ this.#registration = structuredClone(registration);
40
+ this.#checks = checks;
41
+ this.#workers = workers;
42
+ this.#previous = structuredClone(previous);
43
+ this.#projection = structuredClone(projection);
44
+ this.#observed = observed;
45
+ Object.freeze(this);
46
+ }
47
+ static prepare(context, input) {
48
+ if (context.db.isOwnedWriteTransaction?.())
49
+ refuse("preparation_outside_writer_required");
50
+ const wave = PreparedHistoricalSecondMemoryCorrectionWave.prepare(context, input), repairs = wave.repairResults();
51
+ const retained = wave.registration(), first = retained.initialInputView(), receipt = retained.receipt();
52
+ const registration = context.db.readSnapshot(() => readRetainedSecondCorrectedMemoryReviewRegistration(context, first.scope, input.correctedInputSha256, input.checkReceiptSha256));
53
+ if (!registration)
54
+ refuse("historical_second_registration_required");
55
+ const view = registration.view, paths = [...new Set(retained.plan().works.flatMap(work => work.write_paths))].sort();
56
+ assertHistoricalMemoryReviewSources(wave.histories(), paths, view.run_inputs, retained.initialDocumentBaseline());
57
+ const files = view.run_inputs.filter(ref => ref.root === "workspace");
58
+ const projected = secondCorrectedMemoryReviewAssignments({ first, affected: wave.affectedUnitIds(), files, repairs });
59
+ const runInputs = secondCorrectedMemoryReviewReferences({ firstInputs: first.run_inputs,
60
+ firstWorkers: retained.firstReviewProof(context).workers, repairs, files });
61
+ if (view.schema_id !== "dd-flow/memory-corrected-review-inputs@2" || view.wave !== 2
62
+ || view.original_review_sha256 !== receipt.review_sha256 || view.base !== first.base || view.source_policy !== first.source_policy
63
+ || view.first_review_input_sha256 !== receipt.first_review_input_sha256
64
+ || view.first_check_receipt_sha256 !== receipt.first_check_receipt_sha256
65
+ || view.first_review_registration_sha256 !== receipt.first_review_registration_sha256
66
+ || hybridDigest(view.instruction) !== hybridDigest(first.instruction)
67
+ || hybridDigest(view.unit_inventory) !== hybridDigest(projected.units)
68
+ || hybridDigest(view.assignments) !== hybridDigest(projected.assignments)
69
+ || hybridDigest(view.affected_unit_ids) !== hybridDigest(wave.affectedUnitIds())
70
+ || hybridDigest(view.run_inputs) !== hybridDigest(runInputs)
71
+ || hybridDigest(view.repairs) !== hybridDigest(repairs.map(repair => ({ work_id: repair.work_id,
72
+ authority_sha256: repair.authority_sha256, result: repair.reference }))))
73
+ refuse("historical_second_input_projection_changed");
74
+ const checks = PreparedRetainedMemoryCorrectionChecks.prepareSecond(context, { ...input.scope,
75
+ correctedInputSha256: registration.input_sha256, receiptSha256: registration.check_receipt_sha256 });
76
+ if (checks.value(context).completed_correction_sha256 !== view.completed_correction_sha256)
77
+ refuse("historical_second_check_wave_changed");
78
+ const batch = memoryCorrectedReviewBatch(view), harness = runtimeHarness(input.bundle.execution.work("review").worker);
79
+ const workers = context.db.readSnapshot(() => batch.works.map(item => readMemoryReviewWorkSettlement(context, registration, registration.work_ids[item.key], harness)));
80
+ const results = workers.map((worker, index) => validateMemoryReviewWorkResult(worker.bytes, input.bundle.engine(), {
81
+ workId: worker.workId, packet: batch.works[index].payload.memory_review, references: view.run_inputs
82
+ }));
83
+ assertSelectiveMemoryReviewCoverage(view.affected_unit_ids, results);
84
+ const references = workers.map((worker, index) => ({ reviewer_work_id: worker.workId, input_sha256: registration.input_sha256,
85
+ result: worker.result, unit_ids: [results[index].unit_id] }));
86
+ const previous = retained.firstEffectiveReviewProof(context);
87
+ const coverage = correctedMemoryReviewUnits({ view, original: previous.results, current: results,
88
+ originalReferences: previous.references, currentReferences: references, repairWorkIds: repairs.map(repair => repair.work_id) });
89
+ const findings = correctedMemoryReviewFindings({ original: previous.results, current: results, affected: view.affected_unit_ids,
90
+ originalReferences: previous.references, currentReferences: references, findingHistory: previous.projection.findings, repairs });
91
+ const projection = { ...coverage, ...findings, outcome: findings.outcome === "accepted" ? "accepted" : "blocked" };
92
+ const observed = ObservedMemorySources.capture({ run: workers[0].root }, workers.map(worker => ({ root: "run", path: worker.result.path })));
93
+ const hashes = observed.hashes();
94
+ if (workers.some(worker => hashes.get(memorySourceKey("run", worker.result.path)) !== worker.result.sha256))
95
+ refuse("historical_second_reviewer_artifact_changed");
96
+ const prepared = new PreparedHistoricalSecondMemoryReview(token, wave, registration, checks, workers, previous, projection, observed);
97
+ prepared.assertCustody(context);
98
+ return prepared;
99
+ }
100
+ projection() { return structuredClone(this.#projection); }
101
+ retainedInputView() { return structuredClone(this.#registration.view); }
102
+ finalChecks(context) { this.assertCustody(context); return this.#checks.value(context).checks; }
103
+ settlementProof(context) {
104
+ this.assertCustody(context);
105
+ return { registration_scope: structuredClone(this.#registration.scope), registration_sha256: hybridDigest(this.#registration), wave: 2,
106
+ check_receipt_sha256: this.#registration.check_receipt_sha256, first_review_proof_sha256: hybridDigest(this.#previous),
107
+ workers: this.#workers.map(worker => ({ work_id: worker.workId, authority_sha256: worker.authority, result: { ...worker.result } })) };
108
+ }
109
+ assertCustody(context) {
110
+ this.#wave.assertCustody(context);
111
+ this.#checks.assertCustody(context);
112
+ const receipt = this.#registration;
113
+ if (hybridDigest(readRetainedSecondCorrectedMemoryReviewRegistration(context, receipt.scope, receipt.input_sha256, receipt.check_receipt_sha256)) !== hybridDigest(receipt))
114
+ refuse("historical_second_registration_changed");
115
+ if (hybridDigest(this.#wave.registration().firstEffectiveReviewProof(context)) !== hybridDigest(this.#previous))
116
+ refuse("first_review_history_changed");
117
+ const harness = runtimeHarness(this.#wave.registration().bundle().execution.work("review").worker);
118
+ for (const worker of this.#workers)
119
+ if (readMemoryReviewWorkSettlement(context, receipt, worker.workId, harness).authority !== worker.authority)
120
+ refuse("historical_second_reviewer_settlement_changed");
121
+ }
122
+ revalidate(context) {
123
+ this.#wave.revalidate(context);
124
+ this.#checks.revalidate(context);
125
+ this.#observed.revalidate();
126
+ this.assertCustody(context);
127
+ }
128
+ }