@deksden-com/dd-flow-cli 0.9.0-beta.137 → 0.9.0-beta.139
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.
- package/CHANGELOG.md +19 -0
- package/README.md +9 -0
- package/dist/build-info.json +6 -6
- package/dist/cli/argument-values.js +5 -5
- package/dist/cli/command-inputs.js +89 -20
- package/dist/cli/command-metadata.js +197 -0
- package/dist/cli/command-option-descriptions.js +191 -0
- package/dist/cli/completion-cli.js +70 -0
- package/dist/cli/completion.js +57 -0
- package/dist/cli/error-output.js +52 -0
- package/dist/cli/executor-onboarding.js +76 -0
- package/dist/cli/flows.js +29 -0
- package/dist/cli/harnesses.js +84 -0
- package/dist/cli/help.js +240 -6
- package/dist/cli/input-preparation.js +54 -5
- package/dist/cli/memory-flow-admission.js +44 -0
- package/dist/cli/memory-init-invocation.js +78 -0
- package/dist/cli/memory-init.js +240 -0
- package/dist/cli/memory-storage-admission.js +53 -0
- package/dist/cli/models.js +39 -0
- package/dist/cli/native-hook-ingress.js +1 -1
- package/dist/cli/operator-profiles.js +61 -0
- package/dist/cli/output-options.js +35 -0
- package/dist/cli/response-file.js +71 -0
- package/dist/cli/run-cli.js +283 -160
- package/dist/cli/runtime-process.js +1 -1
- package/dist/cli/setup.js +149 -0
- package/dist/cli.js +56 -2
- package/dist/domain/stage-handler-identities.js +20 -0
- package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +4 -3
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +53 -22
- package/dist/harness-runtime/lib/dd-agy.mjs +16 -5
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +12 -6
- package/dist/harness-runtime/lib/dd-codex.mjs +24 -12
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +2 -1
- package/dist/harness-runtime/lib/dd-droid.mjs +32 -9
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +11 -3
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +100 -15
- package/dist/harness-runtime/lib/dd-opencode.mjs +51 -20
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +22 -10
- package/dist/harness-runtime/lib/dd-zcode.mjs +17 -4
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +1 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +16 -3
- package/dist/harness-runtime/lib/lease-renewal.mjs +2 -1
- package/dist/harness-runtime/lib/lifecycle-command.mjs +1 -0
- package/dist/harness-runtime/lib/managed-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/managed-daemon.mjs +50 -15
- package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
- package/dist/harness-runtime/lib/native-children.d.mts +2 -0
- package/dist/harness-runtime/lib/native-children.mjs +20 -1
- package/dist/harness-runtime/lib/native-hook-command.mjs +1 -1
- package/dist/harness-runtime/lib/native-request-proof.d.mts +2 -0
- package/dist/harness-runtime/lib/native-request-proof.mjs +65 -0
- package/dist/harness-runtime/lib/opencode-plugin.mjs +32 -9
- package/dist/harness-runtime/lib/operation-progress.mjs +3 -1
- package/dist/harness-runtime/lib/provider-overload-policy.d.mts +13 -0
- package/dist/harness-runtime/lib/provider-overload-policy.mjs +138 -0
- package/dist/runtime/context.js +1 -1
- package/dist/schemas/discovery-result.schema.json +184 -0
- package/dist/schemas/execution-bundle.schema.json +205 -0
- package/dist/schemas/execution-settings.schema.json +162 -0
- package/dist/schemas/flow-descriptor.schema.json +54 -0
- package/dist/schemas/flow-run.schema.json +26 -0
- package/dist/schemas/harness-catalog.schema.json +80 -0
- package/dist/schemas/mb-init-compose-result.schema.json +457 -0
- package/dist/schemas/mb-init-discover-result.schema.json +500 -0
- package/dist/schemas/mb-init-finish-result.schema.json +422 -0
- package/dist/schemas/mb-init-preflight-result.schema.json +367 -0
- package/dist/schemas/mb-init-review-result.schema.json +396 -0
- package/dist/schemas/mb-init-verify-result.schema.json +391 -0
- package/dist/schemas/memory-bootstrap-receipt-v2.schema.json +67 -0
- package/dist/schemas/memory-bootstrap-receipt.schema.json +354 -0
- package/dist/schemas/memory-composition-work-result.schema.json +38 -0
- package/dist/schemas/memory-repair-work-result.schema.json +49 -0
- package/dist/schemas/memory-review-correction-plan.schema.json +30 -0
- package/dist/schemas/memory-review-work-result.schema.json +43 -0
- package/dist/schemas/model-catalog.schema.json +153 -0
- package/dist/schemas/profile-settings.schema.json +122 -0
- package/dist/schemas/release-manifest.schema.json +291 -0
- package/dist/schemas/run-engine-binding.schema.json +1 -1
- package/dist/services/check-runner-evidence.js +51 -4
- package/dist/services/cli-operation-classifier.js +8 -47
- package/dist/services/cli-upgrade-allowlist.js +27 -0
- package/dist/services/code-checks.js +387 -34
- package/dist/services/controller-child-capacity.js +13 -0
- package/dist/services/controller-child-observer.js +18 -2
- package/dist/services/controller-execution.js +88 -0
- package/dist/services/controller-fanout.js +71 -12
- package/dist/services/dashboard.js +8 -2
- package/dist/services/descriptor-coordinator-session.js +35 -0
- package/dist/services/descriptor-root-work.js +53 -0
- package/dist/services/descriptor-run-settlement.js +105 -0
- package/dist/services/descriptor-run-start.js +449 -0
- package/dist/services/descriptor-stage-coordinator.js +197 -0
- package/dist/services/descriptor-stage-settlement.js +222 -0
- package/dist/services/descriptor-stage-start.js +139 -0
- package/dist/services/discovery/agy-discovery.js +2 -0
- package/dist/services/discovery/codex-discovery.js +2 -0
- package/dist/services/discovery/droid-discovery.js +2 -0
- package/dist/services/discovery/grok-discovery.js +2 -0
- package/dist/services/discovery/opencode-discovery.js +2 -0
- package/dist/services/discovery/static.js +31 -0
- package/dist/services/discovery/zcode-discovery.js +2 -0
- package/dist/services/engines.js +39 -22
- package/dist/services/eval-snapshots.js +83 -25
- package/dist/services/execution-bundles.js +263 -0
- package/dist/services/execution-policy.js +20 -16
- package/dist/services/executor-onboarding.js +56 -0
- package/dist/services/external-work-launch.js +93 -15
- package/dist/services/flow-catalog.js +21 -0
- package/dist/services/flow-descriptors.js +82 -0
- package/dist/services/frozen-engine.js +250 -0
- package/dist/services/generic-execution.js +164 -0
- package/dist/services/harness-adapter.js +28 -2
- package/dist/services/harness-discovery.js +29 -0
- package/dist/services/harness-doctor.js +75 -0
- package/dist/services/harness-probe-effects.js +51 -0
- package/dist/services/harness-version-probe.js +100 -0
- package/dist/services/hooks.js +24 -6
- package/dist/services/hybrid-contracts.js +483 -0
- package/dist/services/ids.js +29 -1
- package/dist/services/installation-lock.js +95 -0
- package/dist/services/installed-flow-source.js +183 -0
- package/dist/services/lifecycle-invocations.js +257 -78
- package/dist/services/managed-processes.js +31 -10
- package/dist/services/memory-accepted-composition.js +77 -0
- package/dist/services/memory-baseline-preservation.js +65 -0
- package/dist/services/memory-completed-correction-wave.js +320 -0
- package/dist/services/memory-compose-handler.js +258 -0
- package/dist/services/memory-composition-acceptance.js +199 -0
- package/dist/services/memory-composition-graph.js +134 -0
- package/dist/services/memory-composition-registration.js +146 -0
- package/dist/services/memory-composition-work-custody.js +151 -0
- package/dist/services/memory-composition-work-results.js +96 -0
- package/dist/services/memory-corrected-review-acceptance.js +129 -0
- package/dist/services/memory-corrected-review-batch.js +30 -0
- package/dist/services/memory-corrected-review-findings.js +106 -0
- package/dist/services/memory-corrected-review-inputs.js +210 -0
- package/dist/services/memory-corrected-review-projection.js +78 -0
- package/dist/services/memory-corrected-review-receipt.js +170 -0
- package/dist/services/memory-corrected-review-registration.js +191 -0
- package/dist/services/memory-correction-check-receipt.js +219 -0
- package/dist/services/memory-correction-input-owner.js +6 -0
- package/dist/services/memory-discover-handler.js +104 -0
- package/dist/services/memory-finish-evidence.js +435 -0
- package/dist/services/memory-finish-handler.js +215 -0
- package/dist/services/memory-finish-integration.js +280 -0
- package/dist/services/memory-finish-readiness.js +122 -0
- package/dist/services/memory-git-integration.js +151 -0
- package/dist/services/memory-historical-corrected-review.js +206 -0
- package/dist/services/memory-historical-original-review.js +130 -0
- package/dist/services/memory-historical-repair-registration.js +99 -0
- package/dist/services/memory-historical-second-review.js +128 -0
- package/dist/services/memory-init-bootstrap-readiness.js +210 -0
- package/dist/services/memory-init-contexts.js +89 -0
- package/dist/services/memory-init-controller-start.js +84 -0
- package/dist/services/memory-init-engine-release.js +223 -0
- package/dist/services/memory-init-git-policy.js +136 -0
- package/dist/services/memory-init-lint-capability.js +185 -0
- package/dist/services/memory-init-native-capacity.js +296 -0
- package/dist/services/memory-init-preflight.js +330 -0
- package/dist/services/memory-init-project-bootstrap.js +599 -0
- package/dist/services/memory-init-request-candidate.js +157 -0
- package/dist/services/memory-init-request-input.js +66 -0
- package/dist/services/memory-init-resource-storage.js +125 -0
- package/dist/services/memory-init-run-allocation.js +81 -0
- package/dist/services/memory-init-run-bundle.js +98 -0
- package/dist/services/memory-init-start.js +181 -0
- package/dist/services/memory-init-startup-custody.js +80 -0
- package/dist/services/memory-init-startup-input.js +240 -0
- package/dist/services/memory-init-storage.js +81 -0
- package/dist/services/memory-init-stores.js +359 -0
- package/dist/services/memory-init-worktrunk-capability.js +178 -0
- package/dist/services/memory-layer-publication.js +611 -0
- package/dist/services/memory-layer.js +156 -0
- package/dist/services/memory-lint-config.js +85 -0
- package/dist/services/memory-native-review-copy.js +165 -0
- package/dist/services/memory-normal-flow-entry.js +75 -0
- package/dist/services/memory-ordinary-defaults.js +112 -0
- package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
- package/dist/services/memory-preflight-handler.js +259 -0
- package/dist/services/memory-repair-current-view.js +299 -0
- package/dist/services/memory-repair-document-delta.js +451 -0
- package/dist/services/memory-repair-history.js +491 -0
- package/dist/services/memory-repair-physical-binding.js +312 -0
- package/dist/services/memory-repair-publication-files.js +152 -0
- package/dist/services/memory-repair-publication-intent.js +27 -0
- package/dist/services/memory-repair-publication-plan.js +160 -0
- package/dist/services/memory-repair-publication-source.js +225 -0
- package/dist/services/memory-repair-publication.js +794 -0
- package/dist/services/memory-repair-registration.js +239 -0
- package/dist/services/memory-repair-work-baseline.js +413 -0
- package/dist/services/memory-repair-work-completion.js +97 -0
- package/dist/services/memory-repair-work-custody.js +73 -0
- package/dist/services/memory-repair-work-results.js +89 -0
- package/dist/services/memory-repair-workspace.js +252 -0
- package/dist/services/memory-repair-writer-copy.js +735 -0
- package/dist/services/memory-result-binding.js +173 -0
- package/dist/services/memory-retained-review-authority.js +129 -0
- package/dist/services/memory-retained-review-results.js +70 -0
- package/dist/services/memory-retained-second-baseline.js +102 -0
- package/dist/services/memory-retained-second-repairs.js +156 -0
- package/dist/services/memory-review-acceptance.js +214 -0
- package/dist/services/memory-review-correction-plan.js +171 -0
- package/dist/services/memory-review-handler.js +585 -0
- package/dist/services/memory-review-inputs.js +200 -0
- package/dist/services/memory-review-receipt.js +180 -0
- package/dist/services/memory-review-registration.js +108 -0
- package/dist/services/memory-review-work-custody.js +124 -0
- package/dist/services/memory-review-work-input.js +72 -0
- package/dist/services/memory-review-work-results.js +73 -0
- package/dist/services/memory-second-corrected-review-inputs.js +165 -0
- package/dist/services/memory-second-correction-plan.js +76 -0
- package/dist/services/memory-second-repair-baseline.js +91 -0
- package/dist/services/memory-second-repair-launch.js +614 -0
- package/dist/services/memory-second-repair-registration.js +88 -0
- package/dist/services/memory-second-repair-source.js +187 -0
- package/dist/services/memory-second-review-acceptance.js +115 -0
- package/dist/services/memory-source-observations.js +117 -0
- package/dist/services/memory-stage-dispatch.js +28 -0
- package/dist/services/memory-stage-results.js +199 -0
- package/dist/services/memory-verification-acceptance.js +135 -0
- package/dist/services/memory-verification-checks.js +252 -0
- package/dist/services/memory-verification-receipt.js +159 -0
- package/dist/services/memory-verify-handler.js +135 -0
- package/dist/services/memory-work-result-preparation.js +63 -0
- package/dist/services/merge-server.js +2 -4
- package/dist/services/model-catalog.js +109 -0
- package/dist/services/model-discovery.js +46 -0
- package/dist/services/operator-profiles.js +236 -0
- package/dist/services/projects.js +17 -2
- package/dist/services/{codex-capacity.js → provider-capacity.js} +34 -16
- package/dist/services/recovery-snapshot-database.js +417 -2
- package/dist/services/release-archive-producer.js +52 -0
- package/dist/services/release-archive.js +143 -0
- package/dist/services/release-cache.js +142 -0
- package/dist/services/release-compatibility.js +18 -0
- package/dist/services/release-download.js +67 -0
- package/dist/services/release-envelope.js +104 -0
- package/dist/services/release-manifest.js +45 -0
- package/dist/services/release-payload.js +114 -0
- package/dist/services/release-producer.js +63 -0
- package/dist/services/release-provenance.js +160 -0
- package/dist/services/release-registry.js +66 -0
- package/dist/services/release-source.js +194 -0
- package/dist/services/repair-intents.js +1 -1
- package/dist/services/review-copy.js +10 -2
- package/dist/services/run-control.js +80 -9
- package/dist/services/run-controller-adapter.js +1 -1
- package/dist/services/run-controller-capture.js +10 -3
- package/dist/services/run-controller-process.js +21 -0
- package/dist/services/run-controller-recovery.js +5 -5
- package/dist/services/run-controller-state.js +1 -1
- package/dist/services/run-controller.js +158 -64
- package/dist/services/run-recovery-guard.js +5 -3
- package/dist/services/run-recovery-runtime.js +3 -3
- package/dist/services/run-recovery.js +145 -5
- package/dist/services/run-start-custody.js +177 -0
- package/dist/services/runs.js +413 -30
- package/dist/services/setup.js +377 -0
- package/dist/services/stage-context.js +9 -1
- package/dist/services/stage-handlers.js +74 -0
- package/dist/services/stage-report-renderer.js +63 -0
- package/dist/services/stage-work-graph.js +17 -0
- package/dist/services/vnext-code-review.js +1 -1
- package/dist/services/vnext-code.js +6 -6
- package/dist/services/vnext-execution-profile.js +2 -2
- package/dist/services/vnext-fanout.js +73 -11
- package/dist/services/vnext-merge.js +8 -3
- package/dist/services/vnext-plan-review.js +7 -5
- package/dist/services/vnext-plan.js +3 -3
- package/dist/services/vnext-protocolize.js +20 -6
- package/dist/services/vnext-workspace-policy.js +7 -2
- package/dist/services/work-registry.js +616 -71
- package/dist/services/workspace-files.js +1 -1
- package/dist/storage/database.js +84 -6
- package/dist/storage/writer-contract.js +11 -7
- package/package.json +13 -3
- package/tools/create-canon-release.mjs +33 -0
- package/tools/produce-hybrid-release.mjs +41 -0
- package/dist/harness-runtime/lib/codex-capacity-policy.d.mts +0 -10
- package/dist/harness-runtime/lib/codex-capacity-policy.mjs +0 -102
|
@@ -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
|
+
}
|