@deksden-com/dd-flow-cli 0.9.0-beta.14 → 0.9.0-beta.141
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 +740 -0
- package/README.md +143 -1
- package/dist/build-info.json +8 -8
- package/dist/cli/argument-values.js +38 -0
- package/dist/cli/command-inputs.js +376 -0
- 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 +328 -18
- package/dist/cli/hook-ingress.js +78 -0
- package/dist/cli/input-preparation.js +165 -0
- 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 +80 -0
- 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 +1689 -545
- package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
- package/dist/cli/runtime-maintenance-ingress.js +52 -0
- package/dist/cli/runtime-process.js +153 -0
- package/dist/cli/setup.js +149 -0
- package/dist/cli.js +71 -2
- package/dist/domain/stage-catalog.js +1 -1
- package/dist/domain/stage-handler-identities.js +20 -0
- package/dist/harness-runtime/DD-ZCODE.md +112 -0
- package/dist/harness-runtime/OPENCODE-LICENSE.txt +24 -0
- package/dist/harness-runtime/bin/dd-agy.mjs +56 -0
- package/dist/harness-runtime/bin/dd-codex.mjs +27 -0
- package/dist/harness-runtime/bin/dd-droid.mjs +34 -0
- package/dist/harness-runtime/bin/dd-grok.mjs +40 -0
- package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
- package/dist/harness-runtime/bin/dd-zcode.mjs +87 -0
- package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
- package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
- package/dist/harness-runtime/lib/agy-hooks.d.mts +1 -0
- package/dist/harness-runtime/lib/agy-hooks.mjs +9 -0
- package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
- package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
- package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +371 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +728 -0
- package/dist/harness-runtime/lib/dd-agy.mjs +70 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +196 -0
- package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex.mjs +817 -0
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +140 -0
- package/dist/harness-runtime/lib/dd-droid.mjs +584 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +498 -0
- package/dist/harness-runtime/lib/dd-grok.mjs +177 -0
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +557 -0
- package/dist/harness-runtime/lib/dd-opencode.mjs +363 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +751 -0
- package/dist/harness-runtime/lib/dd-zcode.mjs +1145 -0
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +157 -0
- package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
- package/dist/harness-runtime/lib/driver-recovery.mjs +139 -0
- package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
- package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
- package/dist/harness-runtime/lib/lease-renewal.mjs +37 -0
- package/dist/harness-runtime/lib/lifecycle-command.d.mts +20 -0
- package/dist/harness-runtime/lib/lifecycle-command.mjs +273 -0
- package/dist/harness-runtime/lib/lifecycle-contract.d.mts +10 -0
- package/dist/harness-runtime/lib/lifecycle-contract.mjs +19 -0
- package/dist/harness-runtime/lib/managed-daemon.d.mts +16 -0
- package/dist/harness-runtime/lib/managed-daemon.mjs +683 -0
- package/dist/harness-runtime/lib/managed-flow-env.mjs +15 -0
- package/dist/harness-runtime/lib/model-observations.mjs +101 -0
- package/dist/harness-runtime/lib/native-children.d.mts +16 -0
- package/dist/harness-runtime/lib/native-children.mjs +113 -0
- package/dist/harness-runtime/lib/native-hook-command.d.mts +7 -0
- package/dist/harness-runtime/lib/native-hook-command.mjs +251 -0
- 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/native-streams.mjs +45 -0
- package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
- package/dist/harness-runtime/lib/observation-clock.mjs +92 -0
- package/dist/harness-runtime/lib/opencode-plugin.mjs +85 -0
- package/dist/harness-runtime/lib/operation-context.mjs +5 -0
- package/dist/harness-runtime/lib/operation-errors.d.mts +16 -0
- package/dist/harness-runtime/lib/operation-errors.mjs +127 -0
- package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
- package/dist/harness-runtime/lib/operation-progress.mjs +114 -0
- package/dist/harness-runtime/lib/process-json.d.mts +5 -0
- package/dist/harness-runtime/lib/process-json.mjs +201 -0
- package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
- 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/harness-runtime/lib/runner-events.mjs +200 -0
- package/dist/harness-runtime/lib/runner-lock.mjs +42 -0
- package/dist/harness-runtime/lib/session-settlement.mjs +30 -0
- package/dist/harness-runtime/lib/setup-progress.d.mts +9 -0
- package/dist/harness-runtime/lib/setup-progress.mjs +51 -0
- package/dist/harness-runtime/lib/tool-observations.d.mts +21 -0
- package/dist/harness-runtime/lib/tool-observations.mjs +228 -0
- package/dist/harness-runtime/lib/zcode-usage.mjs +55 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-1y4a697q.js +81 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-2ny4vxct.js +92 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-6mptkzbc.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-7x67cf1q.js +52 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9rqn6x4v.js +16 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-9vdz0zwn.js +1661 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ecs5ftka.js +1466 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-frbwqjmf.js +145 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gne7h7mq.js +50 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-gx9wnkzr.js +105 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-m2eywc8w.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-nwcpakzx.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-q4g3afnw.js +623 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-qav6mfdz.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-sxt88q69.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-t1xa31vm.js +39 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ve4aws36.js +103 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vmytr4q8.js +4 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vt9jbch8.js +36 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-vyas3vgt.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-wjyeq25y.js +30 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-xgnj2w4v.js +20 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-y2etg5bs.js +9 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-ydhz1zrh.js +238 -0
- package/dist/harness-runtime/vendor/opencode-client/chunks/service-probe-z6qdwcsf.js +62 -0
- package/dist/harness-runtime/vendor/opencode-client/contract.d.ts +1 -0
- package/dist/harness-runtime/vendor/opencode-client/contract.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api/api.d.ts +2806 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api.d.ts +4 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/client.d.ts +2530 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/client.js +15 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.d.ts +7 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client-error.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.d.ts +2529 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/client.js +8 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.d.ts +2 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/generated/index.js +12 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/index.d.ts +35 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/index.js +75 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/rpc.d.ts +20 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/rpc.js +11 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/service.d.ts +90 -0
- package/dist/harness-runtime/vendor/opencode-client/effect/service.js +187 -0
- package/dist/harness-runtime/vendor/opencode-client/package.json +84 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/api.d.ts +21 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/api.js +0 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/client.d.ts +252 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/client.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.d.ts +8 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client-error.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.d.ts +259 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/client.js +7 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.d.ts +3 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/index.js +79 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.d.ts +8932 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/generated/types.js +70 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/index.d.ts +6 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/index.js +83 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/rpc.d.ts +32 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/rpc.js +7 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/service.d.ts +24 -0
- package/dist/harness-runtime/vendor/opencode-client/promise/service.js +187 -0
- package/dist/harness-runtime/vendor/opencode-client/pty-handoff.d.ts +12 -0
- package/dist/harness-runtime/vendor/opencode-client/pty-handoff.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.d.ts +20 -0
- package/dist/harness-runtime/vendor/opencode-client/rpc-runtime.js +14 -0
- package/dist/harness-runtime/vendor/opencode-client/service-contender.d.ts +37 -0
- package/dist/harness-runtime/vendor/opencode-client/service-contender.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/service-probe.d.ts +70 -0
- package/dist/harness-runtime/vendor/opencode-client/service-probe.js +16 -0
- package/dist/harness-runtime/vendor/opencode-client/service-timing.d.ts +12 -0
- package/dist/harness-runtime/vendor/opencode-client/service-timing.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/service-version.d.ts +2 -0
- package/dist/harness-runtime/vendor/opencode-client/service-version.js +6 -0
- package/dist/harness-runtime/vendor/opencode-client/service.d.ts +52 -0
- package/dist/harness-runtime/vendor/opencode-client/service.js +1 -0
- package/dist/harness-runtime/vendor/opencode-client/shared-events.d.ts +11 -0
- package/dist/harness-runtime/vendor/opencode-client/shared-events.js +8 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/connection.d.ts +37 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/connection.js +10 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/data.d.ts +211 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/data.js +18 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/index.d.ts +3 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/index.js +32 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/pty.d.ts +22 -0
- package/dist/harness-runtime/vendor/opencode-client/solid/pty.js +8 -0
- package/dist/harness-runtime/vendor/opencode-plugin.mjs +3 -0
- package/dist/protocol/local-files.js +18 -9
- package/dist/runtime/context.js +8 -4
- package/dist/schemas/agent-profile.schema.json +1 -1
- package/dist/schemas/code-review-result.schema.json +1 -1
- package/dist/schemas/code-verification.schema.json +7 -5
- package/dist/schemas/code-work-batch.schema.json +2 -2
- 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 +28 -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/plan-review-decision.schema.json +3 -3
- package/dist/schemas/plan-review-result.schema.json +2 -2
- package/dist/schemas/profile-settings.schema.json +122 -0
- package/dist/schemas/release-manifest.schema.json +291 -0
- package/dist/schemas/run-control-receipt.schema.json +118 -0
- package/dist/schemas/run-control-request.schema.json +36 -0
- package/dist/schemas/run-engine-binding.schema.json +1 -1
- package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
- package/dist/services/branch-context.js +3 -3
- package/dist/services/canon.js +11 -8
- package/dist/services/check-runner-evidence.js +250 -0
- package/dist/services/cleanup.js +133 -40
- package/dist/services/cli-operation-classifier.js +25 -62
- package/dist/services/cli-upgrade-allowlist.js +27 -0
- package/dist/services/code-checks.js +1168 -107
- package/dist/services/codex-hook-delivery.js +32 -0
- package/dist/services/command-context.js +80 -0
- package/dist/services/compatibility-preflight.js +13 -3
- package/dist/services/config.js +11 -8
- package/dist/services/continuation-outcome.js +20 -0
- package/dist/services/controller-child-capacity.js +13 -0
- package/dist/services/controller-child-observer.js +115 -0
- package/dist/services/controller-execution.js +88 -0
- package/dist/services/controller-fanout.js +202 -0
- package/dist/services/dashboard.js +143 -58
- 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 +294 -153
- package/dist/services/eval-snapshots.js +1215 -116
- package/dist/services/execution-bundles.js +263 -0
- package/dist/services/execution-policy.js +185 -0
- package/dist/services/executor-onboarding.js +56 -0
- package/dist/services/external-work-launch.js +308 -0
- 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 +355 -36
- package/dist/services/harness-config.js +2 -0
- 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 +771 -325
- 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/lanes.js +78 -65
- package/dist/services/lifecycle-command.js +1 -288
- package/dist/services/lifecycle-contract.js +1 -0
- package/dist/services/lifecycle-invocations.js +2007 -0
- package/dist/services/managed-daemon-binding.js +38 -0
- package/dist/services/managed-lease-monitor.js +133 -0
- package/dist/services/managed-processes.js +475 -55
- 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-queue.js +228 -149
- package/dist/services/merge-server.js +161 -35
- package/dist/services/migrations.js +37 -16
- package/dist/services/model-catalog.js +109 -0
- package/dist/services/model-discovery.js +46 -0
- package/dist/services/native-daemon-history.js +49 -0
- package/dist/services/native-session-control.js +39 -0
- package/dist/services/operator-profiles.js +236 -0
- package/dist/services/plan-runtime.js +26 -11
- package/dist/services/plans.js +28 -25
- package/dist/services/projects.js +37 -17
- package/dist/services/prompts.js +28 -17
- package/dist/services/protocols.js +163 -87
- package/dist/services/provider-capacity.js +385 -0
- package/dist/services/recovery-observation-budget.js +121 -0
- package/dist/services/recovery-snapshot-database.js +560 -0
- 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 +42 -0
- package/dist/services/review-copy.js +165 -0
- package/dist/services/review-deferral.js +23 -0
- package/dist/services/run-control-receipt.js +56 -0
- package/dist/services/run-control-worker.js +411 -0
- package/dist/services/run-control.js +1056 -0
- package/dist/services/run-controller-adapter.js +399 -0
- package/dist/services/run-controller-capture.js +186 -0
- package/dist/services/run-controller-process.js +208 -0
- package/dist/services/run-controller-recovery.js +289 -0
- package/dist/services/run-controller-state.js +97 -0
- package/dist/services/run-controller.js +1205 -0
- package/dist/services/run-engine-bindings.js +1 -1
- package/dist/services/run-fork.js +147 -0
- package/dist/services/run-health.js +149 -0
- package/dist/services/run-observations.js +152 -0
- package/dist/services/run-projection.js +22 -64
- package/dist/services/run-recovery-guard.js +77 -0
- package/dist/services/run-recovery-runtime.js +112 -0
- package/dist/services/run-recovery.js +489 -0
- package/dist/services/run-start-custody.js +177 -0
- package/dist/services/runs.js +1019 -247
- package/dist/services/runtime-budget.js +430 -0
- package/dist/services/runtime-command.js +43 -0
- package/dist/services/runtime-scope-capture.js +52 -0
- package/dist/services/runtime-scope-control.js +468 -0
- package/dist/services/runtime-scope-resume.js +599 -0
- package/dist/services/runtime-scope-stop.js +210 -0
- package/dist/services/runtime-scope-worker.js +287 -0
- package/dist/services/runtime-service.js +96 -0
- package/dist/services/schema-validation.js +10 -8
- package/dist/services/scope-writer-cleanup.js +27 -0
- package/dist/services/sessions.js +35 -69
- package/dist/services/setup.js +377 -0
- package/dist/services/stage-blocker.js +17 -7
- package/dist/services/stage-context.js +193 -19
- package/dist/services/stage-handlers.js +74 -0
- package/dist/services/stage-lifecycle.js +152 -116
- package/dist/services/stage-pause.js +89 -75
- package/dist/services/stage-report-renderer.js +234 -6
- package/dist/services/stage-work-graph.js +52 -0
- package/dist/services/tooling.js +41 -30
- package/dist/services/usage.js +49 -101
- package/dist/services/verification-matrix.js +375 -0
- package/dist/services/vnext-code-review.js +223 -88
- package/dist/services/vnext-code.js +327 -226
- package/dist/services/vnext-contracts.js +10 -1
- package/dist/services/vnext-execution-profile.js +80 -5
- package/dist/services/vnext-fanout.js +311 -19
- package/dist/services/vnext-merge.js +332 -111
- package/dist/services/vnext-plan-review.js +279 -127
- package/dist/services/vnext-plan.js +228 -104
- package/dist/services/vnext-protocolize.js +531 -95
- package/dist/services/vnext-specify.js +119 -81
- package/dist/services/vnext-workspace-policy.js +7 -2
- package/dist/services/work-registry.js +1627 -199
- package/dist/services/workspace-bootstrap.js +52 -15
- package/dist/services/workspace-files.js +85 -0
- package/dist/services/worktrees.js +105 -48
- package/dist/shared/entity-references.js +8 -0
- package/dist/shared/errors.js +27 -0
- package/dist/storage/agent-output.js +26 -0
- package/dist/storage/database.js +891 -39
- package/dist/storage/foreign-key-transaction.js +39 -0
- package/dist/storage/immutable-input.js +45 -0
- package/dist/storage/import-guard.js +102 -0
- package/dist/storage/native-cleanup.js +52 -0
- package/dist/storage/paths.js +17 -4
- package/dist/storage/projection-lock.js +73 -0
- package/dist/storage/work-references.js +23 -0
- package/dist/storage/writer-contract.js +89 -0
- package/dist/storage/writer-migration.js +85 -0
- package/package.json +43 -13
- package/tools/create-canon-release.mjs +33 -0
- package/tools/produce-hybrid-release.mjs +41 -0
- package/tools/repair-paused-run-status.mjs +84 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
4
|
+
import { AppError } from "../shared/errors.js";
|
|
5
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
6
|
+
import { validateMemoryCompositionGraph } from "./memory-composition-graph.js";
|
|
7
|
+
import { FrozenGenericExecution } from "./generic-execution.js";
|
|
8
|
+
const stages = ["preflight", "discover", "compose", "verify", "review", "finish"];
|
|
9
|
+
const sha = (value) => /^[a-f0-9]{64}$/.test(value);
|
|
10
|
+
function refuse(reason) {
|
|
11
|
+
throw new AppError("memory_stage_result_invalid", "Memory stage result is not bound to its retained input", 2, { reason, phase: "prepare", effect: "no_effect" });
|
|
12
|
+
}
|
|
13
|
+
function contained(logical, allowRoot = false) {
|
|
14
|
+
if (allowRoot && logical === ".")
|
|
15
|
+
return;
|
|
16
|
+
if (!logical || path.posix.isAbsolute(logical) || path.win32.isAbsolute(logical) || logical.includes("\\")
|
|
17
|
+
|| logical.includes("\0") || logical.split("/").some(segment => !segment || segment === "." || segment === ".."))
|
|
18
|
+
refuse("unsafe_reference_path");
|
|
19
|
+
}
|
|
20
|
+
export function memorySourceKey(root, logical) { return `${root}\0${logical}`; }
|
|
21
|
+
function unique(values, reason) {
|
|
22
|
+
if (new Set(values).size !== values.length)
|
|
23
|
+
refuse(reason);
|
|
24
|
+
return new Set(values);
|
|
25
|
+
}
|
|
26
|
+
/** Read-only result preparation. The stage handler must still establish physical check,
|
|
27
|
+
* Work/reviewer, bootstrap, integration and readiness custody before settlement.
|
|
28
|
+
* Schema validity and source identity are not semantic completeness or finish authority.
|
|
29
|
+
*/
|
|
30
|
+
export class PreparedMemoryStageResult {
|
|
31
|
+
sha256;
|
|
32
|
+
#bytes;
|
|
33
|
+
#value;
|
|
34
|
+
#routes;
|
|
35
|
+
#executionSha256;
|
|
36
|
+
#preflight;
|
|
37
|
+
constructor(bytes, value, routes, executionSha256, preflight) {
|
|
38
|
+
this.#bytes = Buffer.from(bytes);
|
|
39
|
+
this.#value = structuredClone(value);
|
|
40
|
+
this.#routes = structuredClone(routes);
|
|
41
|
+
this.#executionSha256 = executionSha256;
|
|
42
|
+
this.#preflight = structuredClone(preflight);
|
|
43
|
+
this.sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
44
|
+
Object.freeze(this);
|
|
45
|
+
}
|
|
46
|
+
static prepare(input, flow, binding) {
|
|
47
|
+
try {
|
|
48
|
+
if (input.byteLength < 1 || input.byteLength > 1024 * 1024 || flow.descriptor.id !== "mb-init"
|
|
49
|
+
|| !stages.includes(binding.stage) || !binding.runId || !sha(binding.inputSha256))
|
|
50
|
+
refuse("invalid_input_binding");
|
|
51
|
+
const bytes = Buffer.from(input), value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
52
|
+
const schema = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(flow.stageBlob(binding.stage, "result_schema")));
|
|
53
|
+
if (schema.$id !== `dd-flow/mb-init-${binding.stage}-result@1`)
|
|
54
|
+
refuse("invalid_result_schema");
|
|
55
|
+
const validate = new Ajv2020({ strict: true, strictRequired: false, validateFormats: false }).compile(schema);
|
|
56
|
+
if (!validate(value))
|
|
57
|
+
throw new AppError("memory_stage_result_invalid", "Memory stage result proposal does not match its schema", 2, { reason: "invalid_result_schema", phase: "prepare", effect: "no_effect", recoverable: true,
|
|
58
|
+
errors: structuredClone(validate.errors), result_sha256: createHash("sha256").update(bytes).digest("hex") });
|
|
59
|
+
if (value.run_id !== binding.runId || value.stage !== binding.stage || value.input_sha256 !== binding.inputSha256)
|
|
60
|
+
refuse("foreign_result_identity");
|
|
61
|
+
const isEntry = flow.descriptor.entry_stage === binding.stage;
|
|
62
|
+
if (binding.predecessors.length !== (isEntry ? 0 : 1))
|
|
63
|
+
refuse("incomplete_predecessor_binding");
|
|
64
|
+
for (const predecessor of binding.predecessors) {
|
|
65
|
+
contained(predecessor.result.path);
|
|
66
|
+
if (!sha(predecessor.result.sha256) || !sha(predecessor.input_sha256)
|
|
67
|
+
|| flow.successor(predecessor.stage, "accepted") !== binding.stage)
|
|
68
|
+
refuse("foreign_predecessor_binding");
|
|
69
|
+
}
|
|
70
|
+
if (hybridDigest(value.predecessors) !== hybridDigest(binding.predecessors))
|
|
71
|
+
refuse("foreign_predecessor_reference");
|
|
72
|
+
const units = unique(value.units.map(unit => unit.id), "duplicate_unit");
|
|
73
|
+
if (binding.unitIds === null) {
|
|
74
|
+
if (!["preflight", "discover"].includes(binding.stage))
|
|
75
|
+
refuse("missing_unit_inventory");
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const expected = unique(binding.unitIds, "duplicate_bound_unit");
|
|
79
|
+
if (units.size !== expected.size || [...units].some(id => !expected.has(id)))
|
|
80
|
+
refuse("changed_unit_coverage");
|
|
81
|
+
}
|
|
82
|
+
unique(value.findings.map(finding => finding.id), "duplicate_finding");
|
|
83
|
+
if (value.findings.some(finding => !units.has(finding.unit_id)))
|
|
84
|
+
refuse("foreign_finding_unit");
|
|
85
|
+
const facts = value.details.facts;
|
|
86
|
+
if (binding.stage === "discover") {
|
|
87
|
+
unique(facts.map(fact => fact.id), "duplicate_fact");
|
|
88
|
+
if (facts.some(fact => !units.has(fact.unit_id)))
|
|
89
|
+
refuse("foreign_fact_unit");
|
|
90
|
+
}
|
|
91
|
+
const visit = (node, role = "source") => {
|
|
92
|
+
if (Array.isArray(node)) {
|
|
93
|
+
node.forEach(child => visit(child, role));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!node || typeof node !== "object")
|
|
97
|
+
return;
|
|
98
|
+
const record = node;
|
|
99
|
+
if (typeof record.unit_id === "string" && !units.has(record.unit_id))
|
|
100
|
+
refuse("foreign_unit_reference");
|
|
101
|
+
if (Array.isArray(record.unit_ids) && record.unit_ids.some(id => typeof id !== "string" || !units.has(id)))
|
|
102
|
+
refuse("foreign_unit_reference");
|
|
103
|
+
if (typeof record.path === "string" && (typeof record.root === "string" || typeof record.sha256 === "string"))
|
|
104
|
+
contained(record.path, typeof record.root === "string" && record.sha256 === undefined);
|
|
105
|
+
if (typeof record.root === "string" && typeof record.path === "string" && typeof record.sha256 === "string") {
|
|
106
|
+
const key = memorySourceKey(record.root, record.path);
|
|
107
|
+
if (binding.sources.get(key) !== record.sha256 && !(role === "evidence" && binding.historicalEvidence?.has(`${key}\0${record.sha256}`)))
|
|
108
|
+
refuse("unobserved_or_changed_source");
|
|
109
|
+
}
|
|
110
|
+
Object.entries(record).forEach(([key, child]) => visit(child, key === "evidence" || key === "artifacts" ? key : role));
|
|
111
|
+
};
|
|
112
|
+
visit(value);
|
|
113
|
+
let routes = null;
|
|
114
|
+
if (binding.stage === "compose") {
|
|
115
|
+
validateMemoryCompositionGraph(value);
|
|
116
|
+
if (!(binding.execution instanceof FrozenGenericExecution) || binding.execution.settings.flow_id !== flow.descriptor.id
|
|
117
|
+
|| binding.execution.settings.descriptor_sha256 !== flow.sha256 || binding.execution.sha256 !== binding.executionSha256)
|
|
118
|
+
refuse("missing_or_foreign_composition_execution");
|
|
119
|
+
const works = value.details.works;
|
|
120
|
+
try {
|
|
121
|
+
routes = works.map(work => ({ key: work.key, execution: binding.execution.work("compose", work.profile_id ?? undefined) }));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
refuse("unapproved_composition_profile");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (binding.preflight) {
|
|
128
|
+
contained(binding.preflight.result.path);
|
|
129
|
+
if (!sha(binding.preflight.result.sha256) || !sha(binding.preflight.input_sha256)
|
|
130
|
+
|| typeof binding.preflight.semantic_scope !== "string" || !binding.preflight.semantic_scope.trim()
|
|
131
|
+
|| Buffer.byteLength(binding.preflight.semantic_scope) > 16384 || binding.preflight.semantic_scope.includes("\0"))
|
|
132
|
+
refuse("invalid_preflight_binding");
|
|
133
|
+
if (binding.preflight.preserved_paths !== undefined) {
|
|
134
|
+
if (!Array.isArray(binding.preflight.preserved_paths) || binding.preflight.preserved_paths.length > 4096)
|
|
135
|
+
refuse("invalid_preflight_binding");
|
|
136
|
+
unique(binding.preflight.preserved_paths, "duplicate_preserved_path");
|
|
137
|
+
for (const logical of binding.preflight.preserved_paths) {
|
|
138
|
+
if (typeof logical !== "string" || logical.length > 4096)
|
|
139
|
+
refuse("invalid_preflight_binding");
|
|
140
|
+
contained(logical);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return new PreparedMemoryStageResult(bytes, value, routes, routes ? binding.executionSha256 : null, binding.preflight ?? null);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (error instanceof AppError && error.code === "memory_stage_result_invalid")
|
|
148
|
+
throw error;
|
|
149
|
+
return refuse("invalid_result_or_binding");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
bytes() { return Buffer.from(this.#bytes); }
|
|
153
|
+
value() { return structuredClone(this.#value); }
|
|
154
|
+
compositionRoutes() {
|
|
155
|
+
if (!this.#routes)
|
|
156
|
+
refuse("not_a_composition_result");
|
|
157
|
+
return structuredClone(this.#routes);
|
|
158
|
+
}
|
|
159
|
+
/** Pure registration input, not allocation, dispatch or stage completion authority.
|
|
160
|
+
* The handler must select a registered result schema and independently bind
|
|
161
|
+
* this result's predecessor/source custody before passing the batch to its writer.
|
|
162
|
+
*/
|
|
163
|
+
compositionBatch(binding) {
|
|
164
|
+
if (!this.#routes || this.#value.stage !== "compose")
|
|
165
|
+
refuse("not_a_composition_result");
|
|
166
|
+
// Registration assigns unfinished authoring; only final acceptance attests
|
|
167
|
+
// settled outputs. A repairable blueprint is not a blocked dispatch.
|
|
168
|
+
if (this.#value.outcome === "blocked")
|
|
169
|
+
refuse("composition_not_accepted");
|
|
170
|
+
// Unknown facts may survive DISCOVER with a reason/next action. Unknown
|
|
171
|
+
// target applicability must be resolved before immutable Work assignment,
|
|
172
|
+
// rather than dispatching a graph that cannot later accept its own units.
|
|
173
|
+
if (this.#value.units.some(unit => unit.applicability === "unknown"))
|
|
174
|
+
refuse("unresolved_composition_applicability");
|
|
175
|
+
if (binding.runId !== this.#value.run_id || binding.inputSha256 !== this.#value.input_sha256
|
|
176
|
+
|| binding.executionSha256 !== this.#executionSha256)
|
|
177
|
+
refuse("foreign_composition_batch_binding");
|
|
178
|
+
if (typeof binding.resultSchema !== "string" || !/^dd-flow\/[A-Za-z0-9][A-Za-z0-9._-]*@[1-9][0-9]*$/.test(binding.resultSchema))
|
|
179
|
+
refuse("invalid_composition_work_schema");
|
|
180
|
+
const routes = new Map(this.#routes.map(route => [route.key, route]));
|
|
181
|
+
const works = this.#value.details.works;
|
|
182
|
+
return { works: works.map(work => {
|
|
183
|
+
// Historical retained schemas can still be read, but cannot invent tasks.
|
|
184
|
+
if (typeof work.task !== "string" || !work.task.trim() || work.task.length > 16384)
|
|
185
|
+
refuse("missing_composition_work_task");
|
|
186
|
+
const packet = { schema_id: "dd-flow/memory-composition-work-packet@1", run_id: binding.runId,
|
|
187
|
+
stage: "compose", key: work.key, role: work.role, unit_ids: work.unit_ids,
|
|
188
|
+
task: work.task, depends_on: work.depends_on, result_schema: binding.resultSchema,
|
|
189
|
+
read_scopes: work.read_scopes, write_scopes: work.write_scopes,
|
|
190
|
+
compose_result_sha256: this.sha256, compose_input_sha256: binding.inputSha256,
|
|
191
|
+
execution_sha256: binding.executionSha256, predecessors: this.#value.predecessors };
|
|
192
|
+
const scopedPacket = { ...packet, ...(this.#preflight ? { preflight: structuredClone(this.#preflight) } : {}) };
|
|
193
|
+
return { key: work.key, task: work.task, depends_on: [...work.depends_on],
|
|
194
|
+
launch_policy: "fresh_agent_required", result_schema: binding.resultSchema,
|
|
195
|
+
payload: structuredClone({ memory_composition: { ...scopedPacket, packet_sha256: hybridDigest(scopedPacket) },
|
|
196
|
+
execution_override: { agent_profile_id: routes.get(work.key).execution.worker.id } }) };
|
|
197
|
+
}) };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { AppError } from "../shared/errors.js";
|
|
2
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
3
|
+
import { PreparedCheckEvidence } from "./code-checks.js";
|
|
4
|
+
import { PreparedMemoryStageResult, memorySourceKey } from "./memory-stage-results.js";
|
|
5
|
+
import { PreparedAcceptedMemoryComposition } from "./memory-accepted-composition.js";
|
|
6
|
+
function refuse(reason) {
|
|
7
|
+
throw new AppError("memory_verification_acceptance_invalid", "Verification lacks current check proof or accepted per-unit assessments", 2, { reason, effect: "no_effect" });
|
|
8
|
+
}
|
|
9
|
+
/** Check references are a CLI projection of the selected current owner, not
|
|
10
|
+
* agent-generated proof. Admit an optional echo only when it names those bytes. */
|
|
11
|
+
export function projectMemoryVerificationChecks(value, references, directory, resultSha256) {
|
|
12
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
13
|
+
return value;
|
|
14
|
+
const candidate = value;
|
|
15
|
+
if (!candidate.details || typeof candidate.details !== "object" || Array.isArray(candidate.details))
|
|
16
|
+
return value;
|
|
17
|
+
if (candidate.details.checks !== undefined && (!Array.isArray(candidate.details.checks) || candidate.details.checks.some(reference => {
|
|
18
|
+
if (!reference || typeof reference !== "object" || Array.isArray(reference) || Object.keys(reference).some(key => !["path", "sha256"].includes(key)))
|
|
19
|
+
return true;
|
|
20
|
+
const matches = references.filter(current => current.sha256 === reference.sha256 && (current.path === reference.path
|
|
21
|
+
|| current.path.startsWith(`${directory}/checks/`) && current.path.slice(directory.length + 1) === reference.path));
|
|
22
|
+
return new Set(matches.map(current => hybridDigest(current))).size !== 1;
|
|
23
|
+
})))
|
|
24
|
+
throw new AppError("memory_verification_acceptance_invalid", "Use only the selected current CLI check references; correct the proposed result without rerunning settled checks", 2, { reason: "checks_not_selected_current_receipts", phase: "prepare", effect: "no_effect", recoverable: true, check_references: references, result_sha256: resultSha256 });
|
|
25
|
+
return { ...candidate, details: { ...candidate.details, checks: references } };
|
|
26
|
+
}
|
|
27
|
+
/** Pure reference comparison; the caller must obtain admitted outputs from
|
|
28
|
+
* the current accepted composition owner, never from proposed result bytes. */
|
|
29
|
+
export function assertMemoryVerificationArtifactReferences(original, proposed, outputs) {
|
|
30
|
+
const identities = (sources) => sources.map(source => hybridDigest(source));
|
|
31
|
+
const declared = new Set(identities(proposed)), accepted = new Set(identities([...original, ...outputs]));
|
|
32
|
+
if (identities(original).some(identity => !declared.has(identity))
|
|
33
|
+
|| [...declared].some(identity => !accepted.has(identity)))
|
|
34
|
+
refuse("changed_composed_artifacts");
|
|
35
|
+
}
|
|
36
|
+
/** Accepted compose owns these associations; the verifier owns assessments. */
|
|
37
|
+
export function projectMemoryVerificationArtifacts(value, units, outputs, resultSha256) {
|
|
38
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
39
|
+
return value;
|
|
40
|
+
const candidate = value;
|
|
41
|
+
if (!Array.isArray(candidate.units))
|
|
42
|
+
return value;
|
|
43
|
+
const originals = new Map(units.map(unit => [unit.id, unit.artifacts]));
|
|
44
|
+
return { ...candidate, units: candidate.units.map(unit => {
|
|
45
|
+
if (!unit || typeof unit !== "object" || Array.isArray(unit) || unit.artifacts !== undefined && !Array.isArray(unit.artifacts))
|
|
46
|
+
return unit;
|
|
47
|
+
const original = originals.get(unit.id);
|
|
48
|
+
if (!original)
|
|
49
|
+
return unit;
|
|
50
|
+
const allowed = new Set([...original, ...outputs].map(reference => hybridDigest(reference)));
|
|
51
|
+
const provided = unit.artifacts ?? [];
|
|
52
|
+
if (provided.some((reference) => !allowed.has(hybridDigest(reference)))) {
|
|
53
|
+
if (resultSha256 === undefined)
|
|
54
|
+
refuse("changed_composed_artifacts");
|
|
55
|
+
throw new AppError("memory_verification_acceptance_invalid", "Omit units[].artifacts: the CLI preserves accepted compose outputs. Cite preserved source documents in semantic assessment evidence, not as new artifacts; correct the proposal without rerunning settled checks", 2, { reason: "changed_composed_artifacts", phase: "prepare", effect: "no_effect", recoverable: true, unit_id: unit.id,
|
|
56
|
+
output_references: structuredClone(original), result_sha256: resultSha256 });
|
|
57
|
+
}
|
|
58
|
+
const merged = new Map([...original, ...provided].map(reference => [hybridDigest(reference), reference]));
|
|
59
|
+
return { ...unit, artifacts: [...merged.values()] };
|
|
60
|
+
}) };
|
|
61
|
+
}
|
|
62
|
+
/** Admission of the verifier's claims, not an independent judgment of their
|
|
63
|
+
* semantic truth. The handler must independently select and fence accepted
|
|
64
|
+
* compose SQL custody and current output observations; REVIEW/Eval still own
|
|
65
|
+
* their separate gates. Lint alone cannot supply these unit assessments.
|
|
66
|
+
*/
|
|
67
|
+
export class PreparedMemoryVerificationAcceptance {
|
|
68
|
+
#resultSha256;
|
|
69
|
+
#checks;
|
|
70
|
+
constructor(result, checks) {
|
|
71
|
+
this.#resultSha256 = result.sha256;
|
|
72
|
+
this.#checks = checks;
|
|
73
|
+
Object.freeze(this);
|
|
74
|
+
}
|
|
75
|
+
static prepare(input) {
|
|
76
|
+
if (!(input.result instanceof PreparedMemoryStageResult) || !(input.compose instanceof PreparedMemoryStageResult)
|
|
77
|
+
|| !(input.checks instanceof PreparedCheckEvidence))
|
|
78
|
+
refuse("prepared_authority_required");
|
|
79
|
+
const result = input.result.value(), compose = input.compose.value();
|
|
80
|
+
if (input.composition !== undefined && (!(input.composition instanceof PreparedAcceptedMemoryComposition)
|
|
81
|
+
|| input.composition.result().sha256 !== input.compose.sha256))
|
|
82
|
+
refuse("prepared_authority_required");
|
|
83
|
+
const outputs = input.composition?.outputReferences() ?? [];
|
|
84
|
+
input.checks.assertOwner({ ...input.scope, scope: "aggregate" });
|
|
85
|
+
const diagnostic = result.outcome === "needs_repair";
|
|
86
|
+
if (compose.stage !== "compose" || compose.outcome !== "accepted" || result.stage !== "verify" || !["accepted", "needs_repair"].includes(result.outcome)
|
|
87
|
+
|| result.run_id !== compose.run_id || result.run_id !== input.scope.runId || result.predecessors.length !== 1 || result.predecessors[0].stage !== "compose"
|
|
88
|
+
|| result.predecessors[0].input_sha256 !== compose.input_sha256 || result.predecessors[0].result.sha256 !== input.compose.sha256
|
|
89
|
+
|| compose.findings.some(finding => finding.severity !== "minor" && finding.status !== "resolved")
|
|
90
|
+
|| (!diagnostic && (!input.checks.qualityPassed() || result.findings.some(finding => finding.severity !== "minor" && finding.status !== "resolved"))))
|
|
91
|
+
refuse("unaccepted_or_foreign_predecessor");
|
|
92
|
+
const expected = input.checks.resultReferences().map(reference => hybridDigest(reference)), actual = result.details.checks.map(reference => hybridDigest(reference));
|
|
93
|
+
const allowedChecks = new Set(input.checks.sourceReferences().map(({ path, sha256 }) => hybridDigest({ path, sha256 })));
|
|
94
|
+
if (expected.some(reference => !actual.includes(reference))
|
|
95
|
+
|| actual.some(reference => !allowedChecks.has(reference)))
|
|
96
|
+
refuse("checks_not_selected_current_receipts");
|
|
97
|
+
const units = new Map(compose.units.map(unit => [unit.id, unit]));
|
|
98
|
+
if (result.units.length !== units.size || new Set(result.units.map(unit => unit.id)).size !== units.size)
|
|
99
|
+
refuse("changed_unit_coverage");
|
|
100
|
+
const assessments = new Map(result.details.semantic_assessments.map(assessment => [assessment.unit_id, assessment]));
|
|
101
|
+
if (assessments.size !== result.details.semantic_assessments.length || [...assessments.keys()].some(id => !units.has(id))
|
|
102
|
+
|| compose.units.some(unit => unit.applicability !== "not-applicable" && !assessments.has(unit.id)))
|
|
103
|
+
refuse("incomplete_or_duplicate_assessments");
|
|
104
|
+
const key = (source) => memorySourceKey(input.roots && input.roots.projectRoot === input.roots.workspace && source.root === "project" ? "workspace" : source.root, source.path);
|
|
105
|
+
for (const unit of result.units) {
|
|
106
|
+
const original = units.get(unit.id), assessment = assessments.get(unit.id);
|
|
107
|
+
if (!original || unit.aspect !== original.aspect || unit.applicability !== original.applicability || unit.applicability === "unknown"
|
|
108
|
+
|| (unit.applicability === "not-applicable" ? unit.outcome !== "not-applicable" : !["accepted", ...(diagnostic ? ["needs_repair"] : [])].includes(unit.outcome))
|
|
109
|
+
|| (assessment && (!["accepted", ...(diagnostic ? ["needs_repair"] : [])].includes(assessment.verdict) || !assessment.summary.trim())))
|
|
110
|
+
refuse("unit_not_accepted_or_changed");
|
|
111
|
+
assertMemoryVerificationArtifactReferences(original.artifacts, unit.artifacts, outputs);
|
|
112
|
+
if (!assessment)
|
|
113
|
+
continue;
|
|
114
|
+
// PreparedMemoryStageResult already binds every evidence reference to
|
|
115
|
+
// admitted bytes. Cross-unit and earlier-stage evidence is useful context,
|
|
116
|
+
// but cannot replace examination of this unit's own composed output.
|
|
117
|
+
if (unit.applicability !== "not-applicable" && !assessment.evidence.some(source => original.artifacts.some(artifact => key(artifact) === key(source) && artifact.sha256 === source.sha256))) {
|
|
118
|
+
throw new AppError("memory_verification_acceptance_invalid", "Assess the composed documents themselves and cite a direct output reference for EACH applicable unit; the listed references identify this unit's outputs. Work result receipts do not replace direct output examination", 2, { reason: "assessment_does_not_examine_composed_output", phase: "prepare", effect: "no_effect", recoverable: true,
|
|
119
|
+
unit_id: unit.id, output_references: structuredClone(original.artifacts), result_sha256: input.result.sha256 });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (diagnostic && !result.findings.some(finding => finding.severity !== "minor" && finding.status === "open")) {
|
|
123
|
+
throw new AppError("memory_verification_acceptance_invalid", "needs_repair requires an open material finding; correct the proposed outcome and unit assessments without inventing severity", 2, { reason: "repair_requires_material_finding", phase: "prepare", effect: "no_effect", recoverable: true });
|
|
124
|
+
}
|
|
125
|
+
return new PreparedMemoryVerificationAcceptance(input.result, input.checks);
|
|
126
|
+
}
|
|
127
|
+
assertCustody(context, result, checks) {
|
|
128
|
+
if (!(result instanceof PreparedMemoryStageResult) || result.sha256 !== this.#resultSha256)
|
|
129
|
+
refuse("verification_result_changed");
|
|
130
|
+
if (checks !== undefined && checks !== this.#checks)
|
|
131
|
+
refuse("foreign_check_owner");
|
|
132
|
+
this.#checks.assertCustody(context);
|
|
133
|
+
}
|
|
134
|
+
revalidate(context) { this.#checks.revalidate(context); }
|
|
135
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
6
|
+
import { AppError } from "../shared/errors.js";
|
|
7
|
+
import { FrozenGenericExecution } from "./generic-execution.js";
|
|
8
|
+
import { ResolvedFlowDescriptor } from "./flow-descriptors.js";
|
|
9
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
10
|
+
import { readAcceptedStageData } from "./stage-report-renderer.js";
|
|
11
|
+
import { readMemoryInitBootstrapReadiness } from "./memory-init-bootstrap-readiness.js";
|
|
12
|
+
import { readMemoryInitProjectBootstrapLintCapability } from "./memory-init-project-bootstrap.js";
|
|
13
|
+
import { PreparedMemoryBaselinePreservation } from "./memory-baseline-preservation.js";
|
|
14
|
+
import { readBoundedReleaseFile } from "./release-source.js";
|
|
15
|
+
import { codeCheckProfileHash, projectPolicyCheckDeclarationsFromProfile, readCodeCheckProfile, runCodeChecks, PreparedCheckEvidence } from "./code-checks.js";
|
|
16
|
+
import { ObservedMemorySources } from "./memory-source-observations.js";
|
|
17
|
+
import { memoryVerificationActivePaths, validateMemoryLintConfig } from "./memory-lint-config.js";
|
|
18
|
+
import { isMemoryCorrectionInputOwner } from "./memory-correction-input-owner.js";
|
|
19
|
+
const token = Symbol("memory-verification-checks");
|
|
20
|
+
const hash = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
21
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
22
|
+
const profilePath = ".memory-bank/spec/engineering/code-check-profile.json";
|
|
23
|
+
function refuse(reason) {
|
|
24
|
+
throw new AppError("memory_verification_checks_invalid", "Verification checks lack admitted tool, policy or accepted composition custody", 2, { reason, effect: "no_effect" });
|
|
25
|
+
}
|
|
26
|
+
/** Finite project checks use the original Codex home, never a temporary
|
|
27
|
+
* provider Session overlay. Keep every other application environment input. */
|
|
28
|
+
export function memoryCheckEnvironment(context, projectId, runId) {
|
|
29
|
+
if (!context.db.get("SELECT 1 FROM sqlite_schema WHERE type='table' AND name='run_controllers'"))
|
|
30
|
+
return undefined;
|
|
31
|
+
const controllers = context.db.all("SELECT state_json FROM run_controllers WHERE project_id=? AND run_id=?", [projectId, runId]);
|
|
32
|
+
const targets = new Set();
|
|
33
|
+
for (const controller of controllers) {
|
|
34
|
+
const state = JSON.parse(controller.state_json);
|
|
35
|
+
const session = state.current_session === null ? undefined : state.sessions?.[state.current_session];
|
|
36
|
+
if (session?.codex_home)
|
|
37
|
+
targets.add(session.codex_home);
|
|
38
|
+
}
|
|
39
|
+
if (!targets.size)
|
|
40
|
+
return undefined;
|
|
41
|
+
const current = process.env.CODEX_HOME;
|
|
42
|
+
if (current && !targets.has(current) && context.db.get("SELECT 1 FROM sqlite_schema WHERE type='table' AND name='work_launches'")) {
|
|
43
|
+
const launches = context.db.all("SELECT l.state_dir FROM work_launches l JOIN works w ON w.work_id=l.work_id WHERE w.project_id=? AND w.run_id=?", [projectId, runId]);
|
|
44
|
+
if (launches.some(launch => path.join(launch.state_dir, "codex-home") === current))
|
|
45
|
+
targets.add(current);
|
|
46
|
+
}
|
|
47
|
+
const sources = new Set();
|
|
48
|
+
for (const target of targets) {
|
|
49
|
+
const rows = context.db.all("SELECT source_home,target_home FROM codex_home_profiles WHERE project_id=? AND target_home=? AND status='ready'", [projectId, target]);
|
|
50
|
+
if (rows.length !== 1)
|
|
51
|
+
refuse("managed_check_home_unavailable");
|
|
52
|
+
const row = rows[0], marker = JSON.parse(readBoundedReleaseFile(path.join(target, ".dd-flow-home.json"), 1024 * 1024).toString("utf8"));
|
|
53
|
+
if (marker.managed_by !== "dd-flow-cli" || marker.project_id !== projectId || marker.source_home !== row.source_home || marker.target_home !== target
|
|
54
|
+
|| !path.isAbsolute(row.source_home))
|
|
55
|
+
refuse("managed_check_home_changed");
|
|
56
|
+
sources.add(row.source_home);
|
|
57
|
+
}
|
|
58
|
+
if (sources.size !== 1)
|
|
59
|
+
refuse("ambiguous_managed_check_home");
|
|
60
|
+
const base = [...sources][0];
|
|
61
|
+
if (current === undefined ? base !== path.join(os.homedir(), ".codex") : current !== base && !targets.has(current))
|
|
62
|
+
refuse("foreign_check_home");
|
|
63
|
+
return { CODEX_HOME: base };
|
|
64
|
+
}
|
|
65
|
+
function lintConfig(workspace) {
|
|
66
|
+
const file = path.join(workspace, ".mb-lint.json");
|
|
67
|
+
try {
|
|
68
|
+
fs.lstatSync(file);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error.code === "ENOENT")
|
|
72
|
+
return null;
|
|
73
|
+
refuse("lint_config_unavailable");
|
|
74
|
+
}
|
|
75
|
+
return readBoundedReleaseFile(file, 1024 * 1024);
|
|
76
|
+
}
|
|
77
|
+
function accepted(context, input) {
|
|
78
|
+
if (input.corrected !== undefined) {
|
|
79
|
+
if (!isMemoryCorrectionInputOwner(input.corrected))
|
|
80
|
+
refuse("prepared_corrected_inputs_required");
|
|
81
|
+
input.corrected.assertCustody(context);
|
|
82
|
+
const view = input.corrected.value(), bundle = input.corrected.bundle();
|
|
83
|
+
if (view.scope.project_id !== input.projectId || view.scope.run_id !== input.runId
|
|
84
|
+
|| bundle.execution.sha256 !== input.execution.sha256 || bundle.descriptor.sha256 !== input.flow.sha256)
|
|
85
|
+
refuse("foreign_corrected_inputs");
|
|
86
|
+
}
|
|
87
|
+
const frozen = input.execution.snapshot(), scope = { requestId: frozen.scope.requestId, projectRoot: frozen.scope.projectRoot, workspaceRoot: frozen.scope.workspace };
|
|
88
|
+
const run = context.db.get("SELECT workspace_root,project_root,run_root,run_dir,index_json FROM runs WHERE project_id=? AND id=?", [input.projectId, input.runId]);
|
|
89
|
+
const bootstrap = readMemoryInitBootstrapReadiness(context, scope), lint = readMemoryInitProjectBootstrapLintCapability(context, scope);
|
|
90
|
+
if (!run || run.project_root !== scope.projectRoot || run.workspace_root !== scope.workspaceRoot || !bootstrap || !lint
|
|
91
|
+
|| bootstrap.projectId !== input.projectId || bootstrap.authority.binding.execution_sha256 !== input.execution.sha256)
|
|
92
|
+
refuse("accepted_bootstrap_scope_required");
|
|
93
|
+
const compose = readAcceptedStageData(context, { projectId: input.projectId, runId: input.runId, stage: "compose" });
|
|
94
|
+
if (compose.data_schema_id !== "dd-flow/mb-init-compose-result@1")
|
|
95
|
+
refuse("accepted_composition_required");
|
|
96
|
+
const active = input.corrected ? "review" : "verify";
|
|
97
|
+
const { index_json, ...roots } = run, index = JSON.parse(index_json), stage = index.stage_runs.find((stage) => stage.stage === active);
|
|
98
|
+
if (index.current_stage !== active || stage?.status !== "running" || typeof stage.input_sha256 !== "string" || !/^[a-f0-9]{64}$/.test(stage.input_sha256))
|
|
99
|
+
refuse(input.corrected ? "active_corrected_review_required" : "active_verification_required");
|
|
100
|
+
const phase = { attempt: stage.attempt ?? null, cycle: stage.cycle ?? null, input_sha256: stage.input_sha256 };
|
|
101
|
+
return { run: roots, bootstrap, lint, compose, scope, authority: hybridDigest({ run: roots, phase, bootstrap: bootstrap.authority, lint, compose: compose.authority_sha256,
|
|
102
|
+
...(input.corrected ? { corrected_sha256: input.corrected.sha256 } : {}) }) };
|
|
103
|
+
}
|
|
104
|
+
/** Owning CLI policy, not agent-proposed commands. The bootstrap-selected
|
|
105
|
+
* functional linter supplies schema/frontmatter/link checks; project readiness
|
|
106
|
+
* declarations supplement it. Absence of an optional alias profile does not
|
|
107
|
+
* waive the mandatory linter. The complete finish handler still owns composed
|
|
108
|
+
* output/check-result acceptance and semantic assessments.
|
|
109
|
+
*/
|
|
110
|
+
export class PreparedMemoryVerificationChecks {
|
|
111
|
+
static isPrepared(value) {
|
|
112
|
+
return typeof value === "object" && value !== null && #input in value;
|
|
113
|
+
}
|
|
114
|
+
#input;
|
|
115
|
+
#authority;
|
|
116
|
+
#executable;
|
|
117
|
+
#executableSha256;
|
|
118
|
+
#profileSha256;
|
|
119
|
+
#profile;
|
|
120
|
+
#lintConfigSha256;
|
|
121
|
+
#preservation;
|
|
122
|
+
#checks;
|
|
123
|
+
#runHome;
|
|
124
|
+
#directory;
|
|
125
|
+
#workspace;
|
|
126
|
+
#checkEnvironment;
|
|
127
|
+
constructor(key, input, selected, profile, preservation, checks, configSha256) {
|
|
128
|
+
if (key !== token)
|
|
129
|
+
refuse("verification_policy_token_required");
|
|
130
|
+
this.#input = { ...input };
|
|
131
|
+
this.#authority = selected.authority;
|
|
132
|
+
this.#executable = selected.lint.facts.executable;
|
|
133
|
+
this.#executableSha256 = selected.lint.facts.executable_sha256;
|
|
134
|
+
this.#profile = profile;
|
|
135
|
+
this.#lintConfigSha256 = configSha256;
|
|
136
|
+
this.#preservation = preservation;
|
|
137
|
+
this.#checks = structuredClone(checks);
|
|
138
|
+
this.#workspace = selected.run.workspace_root;
|
|
139
|
+
this.#runHome = selected.run.run_root ?? selected.run.run_dir;
|
|
140
|
+
this.#directory = input.corrected ? `${input.flow.stage("review").directory}/checks-wave-${input.corrected.value().wave}` : input.flow.stage("verify").directory;
|
|
141
|
+
this.#profileSha256 = codeCheckProfileHash(this.#workspace, checks);
|
|
142
|
+
Object.freeze(this);
|
|
143
|
+
}
|
|
144
|
+
static prepare(context, input) {
|
|
145
|
+
if (input.corrected !== undefined && !isMemoryCorrectionInputOwner(input.corrected))
|
|
146
|
+
refuse("prepared_corrected_inputs_required");
|
|
147
|
+
if (context.db.isOwnedWriteTransaction?.())
|
|
148
|
+
refuse("preparation_outside_writer_required");
|
|
149
|
+
if (!(input.execution instanceof FrozenGenericExecution) || !(input.flow instanceof ResolvedFlowDescriptor)
|
|
150
|
+
|| input.flow.descriptor.id !== "mb-init" || input.execution.settings.flow_id !== "mb-init"
|
|
151
|
+
|| input.execution.settings.descriptor_sha256 !== input.flow.sha256)
|
|
152
|
+
refuse("frozen_memory_selection_required");
|
|
153
|
+
input.corrected?.revalidate(context);
|
|
154
|
+
const selected = context.db.readSnapshot(() => accepted(context, input)), value = JSON.parse(selected.compose.bytes.toString("utf8"));
|
|
155
|
+
const schema = JSON.parse(input.flow.stageBlob("compose", "result_schema").toString("utf8"));
|
|
156
|
+
if (!new Ajv2020({ strict: true, strictRequired: false, validateFormats: false }).compile(schema)(value))
|
|
157
|
+
refuse("accepted_composition_required");
|
|
158
|
+
const compose = value;
|
|
159
|
+
if (compose.run_id !== input.runId || compose.stage !== "compose" || compose.outcome !== "accepted")
|
|
160
|
+
refuse("accepted_composition_required");
|
|
161
|
+
const probe = selected.bootstrap.authority.binding.target.tool_probes?.["mb-lint"];
|
|
162
|
+
if (!probe || selected.bootstrap.authority.binding.target.tools["mb-lint"] !== selected.lint.facts.executable
|
|
163
|
+
|| probe.executable_sha256 !== selected.lint.facts.executable_sha256 || probe.version !== selected.lint.facts.version
|
|
164
|
+
|| hash(readBoundedReleaseFile(selected.lint.facts.executable, 64 * 1024 * 1024)) !== probe.executable_sha256)
|
|
165
|
+
refuse("selected_linter_changed");
|
|
166
|
+
const preservation = PreparedMemoryBaselinePreservation.prepare(context, input.execution);
|
|
167
|
+
const workspace = selected.run.workspace_root;
|
|
168
|
+
const config = lintConfig(workspace);
|
|
169
|
+
const corrected = input.corrected?.value();
|
|
170
|
+
if (config)
|
|
171
|
+
validateMemoryLintConfig(config, corrected
|
|
172
|
+
? memoryVerificationActivePaths(corrected.unit_inventory, corrected.assignments)
|
|
173
|
+
: memoryVerificationActivePaths(compose.units));
|
|
174
|
+
let observed = null;
|
|
175
|
+
let exists = false;
|
|
176
|
+
try {
|
|
177
|
+
fs.lstatSync(path.join(workspace, profilePath));
|
|
178
|
+
exists = true;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (error.code !== "ENOENT")
|
|
182
|
+
refuse("profile_unavailable");
|
|
183
|
+
}
|
|
184
|
+
const profileRefs = input.corrected ? input.corrected.value().run_inputs : compose.units.flatMap(unit => unit.artifacts);
|
|
185
|
+
const expectedProfiles = new Set(profileRefs.filter(artifact => artifact.root === "workspace" && artifact.path === profilePath).map(artifact => artifact.sha256));
|
|
186
|
+
if (expectedProfiles.size !== (exists ? 1 : 0))
|
|
187
|
+
refuse("profile_presence_differs_from_composition");
|
|
188
|
+
if (exists) {
|
|
189
|
+
observed = ObservedMemorySources.capture({ workspace }, [{ root: "workspace", path: profilePath }]);
|
|
190
|
+
const sha256 = observed.hashes().get(`workspace\0${profilePath}`);
|
|
191
|
+
if (!expectedProfiles.has(sha256))
|
|
192
|
+
refuse("profile_not_accepted_composed_artifact");
|
|
193
|
+
}
|
|
194
|
+
const { profile: policy, hash: profileHash } = readCodeCheckProfile(workspace);
|
|
195
|
+
if (profileHash !== (observed?.hashes().get(`workspace\0${profilePath}`) ?? null))
|
|
196
|
+
refuse("profile_changed_during_preparation");
|
|
197
|
+
const checks = [{ id: "MEMORY/verify/lint-schema-links", canonical_ref: "MEMORY/verify/lint-schema-links",
|
|
198
|
+
command: `${quote(selected.lint.facts.executable)} --root ${quote(workspace)} --format json > "$DD_FLOW_EVIDENCE_DIR/mb-lint.json"`,
|
|
199
|
+
purpose: "Mandatory bootstrap-selected Memory Bank lint, frontmatter/schema and Markdown target checks", run_at: "readiness", availability: "available", required_artifacts: ["mb-lint.json"], inputs: ["."],
|
|
200
|
+
// The pinned linter reads project files/config and invokes Git; provider
|
|
201
|
+
// Session configuration is not one of its execution dependencies.
|
|
202
|
+
environment_inputs: ["PATH", "PATHEXT", "HOME", "XDG_CONFIG_HOME", "NODE_*", "UV_*", "GIT_*", "LANG", "LC_*", "TZ", "DYLD_*", "LD_*", "SYSTEMROOT", "COMSPEC", "TMPDIR", "TMP", "TEMP"] },
|
|
203
|
+
...projectPolicyCheckDeclarationsFromProfile(policy, "readiness")];
|
|
204
|
+
if (input.corrected && codeCheckProfileHash(workspace, checks) !== input.corrected.verificationProfileHash(context))
|
|
205
|
+
refuse("correction_policy_requires_readmission");
|
|
206
|
+
const prepared = new PreparedMemoryVerificationChecks(token, input, selected, observed, preservation, checks, config ? hash(config) : null);
|
|
207
|
+
prepared.#checkEnvironment = memoryCheckEnvironment(context, input.projectId, input.runId);
|
|
208
|
+
prepared.revalidate(context);
|
|
209
|
+
return prepared;
|
|
210
|
+
}
|
|
211
|
+
declarations() { return structuredClone(this.#checks); }
|
|
212
|
+
assertCorrectionOwner(corrected) {
|
|
213
|
+
if (!isMemoryCorrectionInputOwner(corrected) || this.#input.corrected !== corrected)
|
|
214
|
+
refuse("foreign_correction_check_owner");
|
|
215
|
+
}
|
|
216
|
+
checkInput() {
|
|
217
|
+
return { projectId: this.#input.projectId, runId: this.#input.runId, runHome: this.#runHome, workspaceRoot: this.#workspace, scope: "aggregate",
|
|
218
|
+
checks: this.declarations(), expectedProfileHash: this.#profileSha256, artifactDir: this.#directory,
|
|
219
|
+
...(this.#checkEnvironment ? { checkEnvironment: this.#checkEnvironment } : {}),
|
|
220
|
+
...(this.#input.corrected ? { evidenceContext: `memory-review:wave-${this.#input.corrected.value().wave}:${this.#input.corrected.sha256}` } : {}) };
|
|
221
|
+
}
|
|
222
|
+
assertCustody(context) {
|
|
223
|
+
this.#preservation.assertCustody(context);
|
|
224
|
+
if (context.db.readSnapshot(() => accepted(context, this.#input)).authority !== this.#authority)
|
|
225
|
+
refuse("verification_policy_custody_changed");
|
|
226
|
+
}
|
|
227
|
+
revalidate(context) {
|
|
228
|
+
if (hybridDigest(memoryCheckEnvironment(context, this.#input.projectId, this.#input.runId) ?? null) !== hybridDigest(this.#checkEnvironment ?? null))
|
|
229
|
+
refuse("managed_check_home_changed");
|
|
230
|
+
this.#input.corrected?.revalidate(context);
|
|
231
|
+
if (hash(readBoundedReleaseFile(this.#executable, 64 * 1024 * 1024)) !== this.#executableSha256)
|
|
232
|
+
refuse("selected_linter_changed");
|
|
233
|
+
this.#profile?.revalidate();
|
|
234
|
+
const config = lintConfig(this.#workspace);
|
|
235
|
+
if ((config ? hash(config) : null) !== this.#lintConfigSha256)
|
|
236
|
+
refuse("lint_config_changed");
|
|
237
|
+
if (codeCheckProfileHash(this.#workspace, this.#checks) !== this.#profileSha256)
|
|
238
|
+
refuse("verification_profile_changed");
|
|
239
|
+
this.#preservation.revalidate(context);
|
|
240
|
+
this.assertCustody(context);
|
|
241
|
+
}
|
|
242
|
+
async execute(context) {
|
|
243
|
+
this.revalidate(context);
|
|
244
|
+
const receipts = await runCodeChecks(context, this.checkInput());
|
|
245
|
+
this.revalidate(context);
|
|
246
|
+
return receipts;
|
|
247
|
+
}
|
|
248
|
+
evidence(context, mode) {
|
|
249
|
+
this.revalidate(context);
|
|
250
|
+
return PreparedCheckEvidence.prepare(context, { ...this.checkInput(), ...(mode ? { mode } : {}) });
|
|
251
|
+
}
|
|
252
|
+
}
|