@deksden-com/dd-flow-cli 0.9.0-beta.15 → 0.9.0-beta.150
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 +895 -0
- package/README.md +140 -6
- package/dist/build-info.json +8 -8
- package/dist/cli/argument-values.js +38 -0
- package/dist/cli/command-inputs.js +386 -0
- package/dist/cli/command-metadata.js +232 -0
- package/dist/cli/command-option-descriptions.js +192 -0
- package/dist/cli/completion-cli.js +70 -0
- package/dist/cli/completion.js +57 -0
- package/dist/cli/diagnostic-invocation.js +46 -0
- package/dist/cli/diagnostic.js +120 -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 +396 -19
- package/dist/cli/hook-ingress.js +102 -0
- package/dist/cli/input-preparation.js +165 -0
- package/dist/cli/memory-flow-admission.js +50 -0
- package/dist/cli/memory-init-invocation.js +85 -0
- package/dist/cli/memory-init.js +249 -0
- package/dist/cli/memory-storage-admission.js +54 -0
- package/dist/cli/memory-storage-qualification.js +105 -0
- package/dist/cli/memory-storage-transition.js +123 -0
- package/dist/cli/memory-upgrade.js +189 -0
- package/dist/cli/models.js +39 -0
- package/dist/cli/native-hook-ingress.js +90 -0
- package/dist/cli/native-hook-preparation.js +55 -0
- package/dist/cli/operator-profiles.js +61 -0
- package/dist/cli/output-options.js +35 -0
- package/dist/cli/response-file.js +72 -0
- package/dist/cli/run-cli.js +1734 -550
- 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 +150 -0
- package/dist/cli.js +89 -2
- package/dist/domain/diagnostic-aspects.js +103 -0
- package/dist/domain/diagnostic-flows.js +8 -0
- package/dist/domain/stage-catalog.js +1 -1
- package/dist/domain/stage-handler-identities.js +28 -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-error-boundary.mjs +58 -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/agy-native-inspection.mjs +216 -0
- package/dist/harness-runtime/lib/agy-native_pb.js +117 -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 +2 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +462 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +6 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1096 -0
- package/dist/harness-runtime/lib/dd-agy.mjs +86 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +231 -0
- package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex.mjs +954 -0
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +141 -0
- package/dist/harness-runtime/lib/dd-droid.mjs +626 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +555 -0
- package/dist/harness-runtime/lib/dd-grok.mjs +180 -0
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +622 -0
- package/dist/harness-runtime/lib/dd-opencode.mjs +390 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +752 -0
- package/dist/harness-runtime/lib/dd-zcode.mjs +1175 -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 +140 -0
- package/dist/harness-runtime/lib/droid-observation.mjs +66 -0
- package/dist/harness-runtime/lib/entity-references.d.mts +2 -0
- package/dist/harness-runtime/lib/entity-references.mjs +9 -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 +698 -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 +23 -0
- package/dist/harness-runtime/lib/native-children.mjs +219 -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 +95 -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 +15 -0
- package/dist/harness-runtime/lib/provider-overload-policy.mjs +151 -0
- package/dist/harness-runtime/lib/runner-events.mjs +202 -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 +53 -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-decision.schema.json +9 -0
- 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/diagnostic-stage-result.schema.json +354 -0
- package/dist/schemas/diagnostic-work-result.schema.json +296 -0
- package/dist/schemas/discovery-result.schema.json +184 -0
- package/dist/schemas/execution-bundle.schema.json +211 -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 +29 -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/mb-upgrade-stage-result.schema.json +863 -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 +56 -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 +12 -3
- package/dist/schemas/plan-review-result.schema.json +2 -2
- package/dist/schemas/profile-settings.schema.json +122 -0
- package/dist/schemas/project-flow-pack-manifest.schema.json +1 -1
- package/dist/schemas/release-impact.schema.json +3 -3
- 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/stage-start-response.schema.json +4 -0
- package/dist/schemas/vnext-protocol-plan.schema.json +2 -2
- package/dist/services/accepted-intent.js +139 -0
- package/dist/services/branch-context.js +3 -3
- package/dist/services/canon.js +54 -15
- package/dist/services/check-environment.js +21 -0
- package/dist/services/check-runner-evidence.js +562 -0
- package/dist/services/cleanup.js +133 -40
- package/dist/services/cli-operation-classifier.js +26 -63
- package/dist/services/cli-upgrade-allowlist.js +27 -0
- package/dist/services/code-checks.js +1398 -119
- package/dist/services/codex-hook-delivery.js +32 -0
- package/dist/services/command-context.js +80 -0
- package/dist/services/compatibility-preflight.js +16 -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 +94 -0
- package/dist/services/controller-fanout.js +226 -0
- package/dist/services/controller-memory-task.js +45 -0
- package/dist/services/controller-memory-worker.js +49 -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 +107 -0
- package/dist/services/descriptor-run-start.js +475 -0
- package/dist/services/descriptor-stage-coordinator.js +250 -0
- package/dist/services/descriptor-stage-settlement.js +223 -0
- package/dist/services/descriptor-stage-start.js +175 -0
- package/dist/services/diagnostic-evidence.js +73 -0
- package/dist/services/diagnostic-report-publication.js +72 -0
- package/dist/services/diagnostic-report.js +67 -0
- package/dist/services/diagnostic-run-bundle.js +74 -0
- package/dist/services/diagnostic-snapshot.js +159 -0
- package/dist/services/diagnostic-stage-handlers.js +108 -0
- package/dist/services/diagnostic-stage-results.js +132 -0
- package/dist/services/diagnostic-start.js +84 -0
- package/dist/services/diagnostic-work-batch.js +34 -0
- package/dist/services/diagnostic-work-collection.js +97 -0
- package/dist/services/diagnostic-work-registration.js +101 -0
- package/dist/services/diagnostic-work-results.js +93 -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 +354 -163
- package/dist/services/eval-snapshots.js +1316 -150
- package/dist/services/execution-bundles.js +275 -0
- package/dist/services/execution-policy.js +185 -0
- package/dist/services/executor-onboarding.js +56 -0
- package/dist/services/external-work-launch.js +310 -0
- package/dist/services/flow-catalog.js +30 -0
- package/dist/services/flow-descriptors.js +82 -0
- package/dist/services/frozen-engine.js +387 -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/hook-memory-routing.js +188 -0
- package/dist/services/hook-recovery-guard.js +14 -0
- package/dist/services/hook-session-observation.js +24 -0
- package/dist/services/hooks.js +791 -326
- package/dist/services/hybrid-contracts.js +474 -0
- package/dist/services/hybrid-digest.js +14 -0
- package/dist/services/ids.js +29 -1
- package/dist/services/installation-lock.js +95 -0
- package/dist/services/installed-flow-source.js +226 -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 +2148 -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 +449 -69
- package/dist/services/memory-accepted-composition.js +78 -0
- package/dist/services/memory-baseline-preservation.js +65 -0
- package/dist/services/memory-completed-correction-wave.js +328 -0
- package/dist/services/memory-compose-handler.js +400 -0
- package/dist/services/memory-composition-acceptance.js +375 -0
- package/dist/services/memory-composition-graph.js +165 -0
- package/dist/services/memory-composition-registration.js +161 -0
- package/dist/services/memory-composition-work-custody.js +156 -0
- package/dist/services/memory-composition-work-results.js +108 -0
- package/dist/services/memory-corrected-review-acceptance.js +129 -0
- package/dist/services/memory-corrected-review-batch.js +37 -0
- package/dist/services/memory-corrected-review-findings.js +108 -0
- package/dist/services/memory-corrected-review-inputs.js +215 -0
- package/dist/services/memory-corrected-review-projection.js +78 -0
- package/dist/services/memory-corrected-review-receipt.js +178 -0
- package/dist/services/memory-corrected-review-registration.js +192 -0
- package/dist/services/memory-correction-check-receipt.js +235 -0
- package/dist/services/memory-correction-input-owner.js +6 -0
- package/dist/services/memory-custody-snapshot.js +36 -0
- package/dist/services/memory-discover-handler.js +104 -0
- package/dist/services/memory-finish-evidence.js +457 -0
- package/dist/services/memory-finish-handler.js +229 -0
- package/dist/services/memory-finish-integration.js +450 -0
- package/dist/services/memory-finish-readiness.js +169 -0
- package/dist/services/memory-git-integration.js +220 -0
- package/dist/services/memory-historical-corrected-review.js +212 -0
- package/dist/services/memory-historical-original-review.js +143 -0
- package/dist/services/memory-historical-repair-registration.js +105 -0
- package/dist/services/memory-historical-second-review.js +147 -0
- package/dist/services/memory-init-bootstrap-readiness.js +210 -0
- package/dist/services/memory-init-contexts.js +131 -0
- package/dist/services/memory-init-controller-start.js +103 -0
- package/dist/services/memory-init-engine-release.js +223 -0
- package/dist/services/memory-init-git-policy.js +165 -0
- package/dist/services/memory-init-lint-capability.js +203 -0
- package/dist/services/memory-init-native-capacity.js +309 -0
- package/dist/services/memory-init-preflight.js +334 -0
- package/dist/services/memory-init-project-bootstrap.js +599 -0
- package/dist/services/memory-init-request-candidate.js +213 -0
- package/dist/services/memory-init-request-input.js +82 -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 +135 -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 +91 -0
- package/dist/services/memory-init-stores.js +359 -0
- package/dist/services/memory-init-worktrunk-capability.js +174 -0
- package/dist/services/memory-layer-publication.js +611 -0
- package/dist/services/memory-layer.js +221 -0
- package/dist/services/memory-lint-config.js +194 -0
- package/dist/services/memory-native-review-copy.js +103 -0
- package/dist/services/memory-normal-flow-entry.js +87 -0
- package/dist/services/memory-ordinary-defaults.js +129 -0
- package/dist/services/memory-preflight-bootstrap-custody.js +115 -0
- package/dist/services/memory-preflight-handler.js +274 -0
- package/dist/services/memory-repair-current-view.js +299 -0
- package/dist/services/memory-repair-document-delta.js +488 -0
- package/dist/services/memory-repair-history.js +496 -0
- package/dist/services/memory-repair-physical-binding.js +194 -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 +162 -0
- package/dist/services/memory-repair-publication-source.js +225 -0
- package/dist/services/memory-repair-publication.js +795 -0
- package/dist/services/memory-repair-registration.js +240 -0
- package/dist/services/memory-repair-work-baseline.js +415 -0
- package/dist/services/memory-repair-work-completion.js +117 -0
- package/dist/services/memory-repair-work-custody.js +73 -0
- package/dist/services/memory-repair-work-results.js +108 -0
- package/dist/services/memory-repair-workspace.js +261 -0
- package/dist/services/memory-repair-writer-copy.js +736 -0
- package/dist/services/memory-result-binding.js +239 -0
- package/dist/services/memory-retained-review-authority.js +138 -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 +162 -0
- package/dist/services/memory-review-acceptance.js +214 -0
- package/dist/services/memory-review-correction-plan.js +206 -0
- package/dist/services/memory-review-handler.js +585 -0
- package/dist/services/memory-review-inputs.js +246 -0
- package/dist/services/memory-review-limits.js +10 -0
- package/dist/services/memory-review-receipt.js +180 -0
- package/dist/services/memory-review-registration.js +117 -0
- package/dist/services/memory-review-work-custody.js +126 -0
- package/dist/services/memory-review-work-input.js +91 -0
- package/dist/services/memory-review-work-results.js +95 -0
- package/dist/services/memory-second-corrected-review-inputs.js +167 -0
- package/dist/services/memory-second-correction-plan.js +77 -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 +65 -0
- package/dist/services/memory-stage-results.js +290 -0
- package/dist/services/memory-tool-probe.js +25 -0
- package/dist/services/memory-upgrade-analysis-handler.js +243 -0
- package/dist/services/memory-upgrade-bootstrap-readiness.js +251 -0
- package/dist/services/memory-upgrade-evidence.js +100 -0
- package/dist/services/memory-upgrade-inventory.js +442 -0
- package/dist/services/memory-upgrade-publication-custody.js +73 -0
- package/dist/services/memory-upgrade-publication.js +413 -0
- package/dist/services/memory-upgrade-selection.js +430 -0
- package/dist/services/memory-upgrade-start.js +60 -0
- package/dist/services/memory-upgrade-storage-readiness.js +340 -0
- package/dist/services/memory-verification-acceptance.js +156 -0
- package/dist/services/memory-verification-checks.js +317 -0
- package/dist/services/memory-verification-receipt.js +160 -0
- package/dist/services/memory-verify-handler.js +137 -0
- package/dist/services/memory-work-result-json.js +12 -0
- package/dist/services/memory-work-result-preparation.js +64 -0
- package/dist/services/merge-queue.js +228 -149
- package/dist/services/merge-server.js +163 -35
- package/dist/services/migrations.js +164 -114
- package/dist/services/model-catalog.js +109 -0
- package/dist/services/model-discovery.js +46 -0
- package/dist/services/native-daemon-history.js +50 -0
- package/dist/services/native-session-control.js +39 -0
- package/dist/services/operator-profiles.js +236 -0
- package/dist/services/physical-startup.js +45 -0
- package/dist/services/plan-runtime.js +26 -11
- package/dist/services/plans.js +28 -25
- package/dist/services/project-registry.js +97 -0
- package/dist/services/project-summary.js +1 -1
- package/dist/services/projects.js +17 -87
- package/dist/services/prompt-delivery.js +71 -0
- package/dist/services/prompts.js +28 -17
- package/dist/services/protocols.js +163 -87
- package/dist/services/provider-capacity.js +455 -0
- package/dist/services/recovery-observation-budget.js +121 -0
- package/dist/services/recovery-snapshot-database.js +588 -0
- package/dist/services/release-archive-producer.js +52 -0
- package/dist/services/release-archive.js +143 -0
- package/dist/services/release-cache.js +150 -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 +31 -0
- package/dist/services/repair-receipt.js +13 -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 +428 -0
- package/dist/services/run-control.js +1092 -0
- package/dist/services/run-controller-adapter.js +400 -0
- package/dist/services/run-controller-capture.js +186 -0
- package/dist/services/run-controller-process.js +205 -0
- package/dist/services/run-controller-recovery.js +295 -0
- package/dist/services/run-controller-state.js +97 -0
- package/dist/services/run-controller.js +1326 -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 +107 -0
- package/dist/services/run-recovery-runtime.js +112 -0
- package/dist/services/run-recovery.js +456 -0
- package/dist/services/run-start-custody.js +189 -0
- package/dist/services/runs.js +1023 -246
- package/dist/services/runtime-budget.js +446 -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 +605 -0
- package/dist/services/runtime-scope-stop.js +211 -0
- package/dist/services/runtime-scope-worker.js +314 -0
- package/dist/services/runtime-service.js +19 -14
- package/dist/services/schema-validation.js +10 -8
- package/dist/services/scope-writer-cleanup.js +27 -0
- package/dist/services/sessions.js +36 -91
- package/dist/services/setup.js +427 -0
- package/dist/services/stage-blocker.js +17 -7
- package/dist/services/stage-context.js +193 -19
- package/dist/services/stage-handlers.js +89 -0
- package/dist/services/stage-lifecycle.js +152 -116
- package/dist/services/stage-pause.js +202 -91
- 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 +393 -0
- package/dist/services/version-status.js +1 -1
- package/dist/services/vnext-code-review.js +235 -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 +355 -21
- package/dist/services/vnext-merge.js +332 -111
- package/dist/services/vnext-plan-review.js +287 -132
- package/dist/services/vnext-plan.js +228 -104
- package/dist/services/vnext-protocolize.js +533 -95
- package/dist/services/vnext-specify.js +123 -81
- package/dist/services/vnext-workspace-policy.js +7 -2
- package/dist/services/work-registry.js +1706 -200
- package/dist/services/workspace-bootstrap.js +53 -15
- package/dist/services/workspace-files.js +85 -0
- package/dist/services/worktrees.js +105 -48
- package/dist/shared/entity-references.js +1 -0
- package/dist/shared/errors.js +27 -0
- package/dist/storage/agent-output.js +26 -0
- package/dist/storage/data-preservation.js +65 -0
- package/dist/storage/database.js +930 -40
- package/dist/storage/foreign-key-transaction.js +39 -0
- package/dist/storage/immutable-input.js +45 -0
- package/dist/storage/import-guard.js +159 -0
- package/dist/storage/memory-upgrade-schema-bootstrap.js +38 -0
- package/dist/storage/native-cleanup.js +52 -0
- package/dist/storage/paired-writer-migration.js +424 -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 +96 -0
- package/dist/storage/writer-migration.js +346 -0
- package/dist/storage/writer-restore.js +217 -0
- package/package.json +50 -13
- package/tools/create-canon-release.mjs +33 -0
- package/tools/probe-codex-history.mjs +37 -0
- package/tools/produce-hybrid-release.mjs +41 -0
- package/tools/repair-paused-run-status.mjs +84 -0
|
@@ -1,44 +1,73 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { managedLifecycleCommand } from "./lifecycle-invocations.js";
|
|
2
|
+
import { stageLifecycleInstruction } from "../harness-runtime/lib/delegation-instructions.mjs";
|
|
3
|
+
import { ensureAggregateRepair, ensureRepairIntent } from "./repair-intents.js";
|
|
2
4
|
import { runWorkspaceBootstrap } from "./workspace-bootstrap.js";
|
|
5
|
+
import crypto from "node:crypto";
|
|
3
6
|
import fs from "node:fs";
|
|
7
|
+
import { prepareAgentOutputFile } from "../storage/agent-output.js";
|
|
4
8
|
import path from "node:path";
|
|
5
9
|
import { AppError } from "../shared/errors.js";
|
|
10
|
+
import { assertSourceRepairEligible } from "./check-runner-evidence.js";
|
|
6
11
|
import { resolveProjectRoot } from "../storage/paths.js";
|
|
7
|
-
import { aggregateCheckDeclarations, checkReceipts, finalCodeCheckDeclarations, runCodeChecks,
|
|
12
|
+
import { aggregateCheckDeclarations, checkReceipts, effectiveCheckDeclarations, finalCodeCheckDeclarations, runCodeChecks, validateFailedCheckRetry, workspaceChangedPaths } from "./code-checks.js";
|
|
8
13
|
import { requireProjectByRoot } from "./projects.js";
|
|
9
|
-
import { appendFlowRunTimelineEvent, advanceFlowRun, attachFlowRunStage, completeFlowRunStage, completeFlowRun, getFlowRunVariables, gitFacts } from "./runs.js";
|
|
14
|
+
import { appendFlowRunTimelineEvent, advanceFlowRun, attachFlowRunStage, prepareFlowRunStageAttachment, completeFlowRunStage, prepareFlowRunStageCompletion, completeFlowRun, withStageSettlement, getFlowRunVariables, gitFacts } from "./runs.js";
|
|
10
15
|
import { validateSchema } from "./schema-validation.js";
|
|
11
|
-
import {
|
|
16
|
+
import { runtimeCommand, checkRetryArgs } from "./runtime-command.js";
|
|
17
|
+
import { stageCycle, stageGraphScope } from "./stage-work-graph.js";
|
|
12
18
|
import { validateVnextCodeHandoff } from "./vnext-plan.js";
|
|
13
19
|
import { requireVnextWorkspaceRoute } from "./vnext-workspace-policy.js";
|
|
14
20
|
import { readVnextSpecifyResult } from "./vnext-specify.js";
|
|
15
|
-
import { addWorkBatch, bindStageCoordinatorWork, codeWorkGraph,
|
|
21
|
+
import { addWorkBatch, prepareWorkBatch, bindStageCoordinatorWork, codeWorkGraph, finishStageCoordinatorWork, refreshRunWorkProjection, validateWorkBatchFile, workStartCommand } from "./work-registry.js";
|
|
16
22
|
import { vnextStageDirectory } from "../domain/stage-catalog.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
23
|
+
import { acceptStageReport, prepareStageReport } from "./stage-report-renderer.js";
|
|
24
|
+
import { prepareVnextMergeRequest } from "./vnext-merge.js";
|
|
19
25
|
import { assertStageStartHookEvent } from "./hooks.js";
|
|
20
|
-
import { applyExternalStageContext } from "./stage-context.js";
|
|
26
|
+
import { currentStagePrompt, applyExternalStageContext, prepareExternalStageContext } from "./stage-context.js";
|
|
21
27
|
import { readFanoutDescriptor, writeFanoutDescriptor } from "./vnext-fanout.js";
|
|
28
|
+
import { assertRunMutationAllowed } from "./run-recovery.js";
|
|
29
|
+
import { prepareJsonSchema, prepareOutputFile } from "../cli/input-preparation.js";
|
|
30
|
+
import { prepareRunVerificationMatrix, acceptVerificationMatrix, commitVerificationMatrixStart, resumeVerificationMatrix, verificationMatrixInstruction, publishVerificationMatrix, latestRunVerificationMatrix } from "./verification-matrix.js";
|
|
31
|
+
import { stageSuccessor } from "./vnext-contracts.js";
|
|
22
32
|
const stage = "code";
|
|
23
33
|
const stageDir = vnextStageDirectory("code");
|
|
24
|
-
|
|
34
|
+
/** A controller prepares slow, deterministic project tooling before it asks an
|
|
35
|
+
* agent to enter CODE or a restored CODE_REVIEW. The subsequent lifecycle tool call remains the sole
|
|
36
|
+
* authority for attaching and binding the Stage. */
|
|
37
|
+
export async function prepareVnextCodeWorkspace(context, input) {
|
|
38
|
+
if (context.env.DD_FLOW_CODE_READINESS_OWNER !== input.ownerId) {
|
|
39
|
+
throw new AppError("code_readiness_owner_mismatch", "CODE readiness preparation must use its controller's frozen owner", 1, { owner_id: input.ownerId });
|
|
40
|
+
}
|
|
25
41
|
const projectRoot = resolveProjectRoot(input.projectRoot);
|
|
26
42
|
const project = requireProjectByRoot(context, projectRoot);
|
|
27
43
|
const run = requireRun(context, project.id, input.runId);
|
|
28
|
-
|
|
44
|
+
assertRunMutationAllowed(context, project.id, run.id);
|
|
45
|
+
requireVnextWorkspaceRoute(context, { projectRoot, runId: run.id, runHome: requireHome(run), workspaceRoot: run.workspace_root, stage: input.stage ?? stage });
|
|
46
|
+
const root = path.join(requireHome(run), stageDir);
|
|
47
|
+
fs.mkdirSync(root, { recursive: true });
|
|
48
|
+
return ensureCodeWorkspaceReady(context, project.id, run, root, [], input.progress, { force: input.stage !== "code-review" });
|
|
49
|
+
}
|
|
50
|
+
export function prepareVnextCodeStart(context, input) {
|
|
51
|
+
const projectRoot = resolveProjectRoot(input.projectRoot);
|
|
52
|
+
const project = requireProjectByRoot(context, projectRoot);
|
|
53
|
+
const run = requireRun(context, project.id, input.runId);
|
|
54
|
+
assertRunMutationAllowed(context, project.id, run.id);
|
|
29
55
|
const home = requireHome(run);
|
|
30
|
-
requireVnextWorkspaceRoute({ projectRoot, runId: input.runId, runHome: home, workspaceRoot: run.workspace_root, stage });
|
|
56
|
+
requireVnextWorkspaceRoute(context, { projectRoot, runId: input.runId, runHome: home, workspaceRoot: run.workspace_root, stage });
|
|
31
57
|
const existingRoot = path.join(home, stageDir);
|
|
32
58
|
const existingPrompt = path.join(existingRoot, "stage-prompt.md");
|
|
33
59
|
const existingStage = stageStatus(run, stage);
|
|
34
60
|
const sourceRepairAttempt = isMergeSourceRepairAttempt(run);
|
|
61
|
+
const rootWork = requireRootWork(context, project.id, input.runId);
|
|
62
|
+
if (input.externalContext)
|
|
63
|
+
prepareExternalStageContext({ stageRoot: existingRoot, loaded: input.externalContext });
|
|
64
|
+
prepareOutputFile(existingPrompt);
|
|
65
|
+
prepareOutputFile(path.join(existingRoot, "fanout.json"));
|
|
66
|
+
const common = { projectRoot, project, run, home, root: existingRoot, promptPath: existingPrompt, rootWork, sourceRepairAttempt };
|
|
35
67
|
if (existingStage && fs.existsSync(existingPrompt)) {
|
|
36
|
-
|
|
37
|
-
const prompt = fs.readFileSync(existingPrompt, "utf8");
|
|
38
|
-
const rootWork = requireRootWork(context, project.id, input.runId);
|
|
39
|
-
const orchestration = readFanoutDescriptor(existingRoot) ?? writeFanoutDescriptor(existingRoot, { stage, parent_work_id: rootWork.work_id, dispatch: "none", capacity_required: true });
|
|
40
|
-
return { ok: true, resumed: true, run_id: run.id, stage, stage_status: existingStage, prompt_path: existingPrompt, worker_prompt_markdown: prompt, ...(externalContext ? { external_context: externalContext } : {}), orchestration, graph: codeWorkGraph(context, project.id, run.id), next: { refresh_graph_command: `${flowCommand(context)} work ls --run ${run.id} --ready --project-root ${JSON.stringify(projectRoot)} --json`, finish_command: finishCommand(context, input.runId, projectRoot, path.join(existingRoot, "code-verification.json")) } };
|
|
68
|
+
return { ...common, resumed: true, existingStage, prompt: fs.readFileSync(existingPrompt, "utf8"), orchestration: readFanoutDescriptor(existingRoot) };
|
|
41
69
|
}
|
|
70
|
+
const attachment = sourceRepairAttempt ? null : prepareFlowRunStageAttachment(context, { projectRoot, runId: run.id, stage, dir: stageDir, status: "running", dataSchemaId: "dd-flow/stage-report@1" });
|
|
42
71
|
const batch = path.join(home, "03-plan", "code-work-batch.json");
|
|
43
72
|
const handoffFailures = validateVnextCodeHandoff(context, {
|
|
44
73
|
projectRoot,
|
|
@@ -58,14 +87,32 @@ export async function startVnextCode(context, input) {
|
|
|
58
87
|
runRoot: home
|
|
59
88
|
});
|
|
60
89
|
validateWorkBatchFile(batch);
|
|
61
|
-
const
|
|
90
|
+
const template = fs.readFileSync(path.join(run.workspace_root, ".memory-bank", "dd-flow", "vnext", "code.md"), "utf8");
|
|
91
|
+
const variables = getFlowRunVariables(context, { projectRoot, runId: run.id });
|
|
92
|
+
const matrix = prepareRunVerificationMatrix(context, { projectId: project.id, runId: run.id, stage, role: "input", completeness: "declared", ...(attachment ? { stageAttempt: attachment.attempt } : {}) });
|
|
93
|
+
return { ...common, resumed: false, template, capacity: variables.variables?.["runtime.subagent.available_slots"], matrix };
|
|
94
|
+
}
|
|
95
|
+
export async function startVnextCode(context, input, prepared = prepareVnextCodeStart(context, input)) {
|
|
96
|
+
const { projectRoot, project, run, root, promptPath, rootWork, sourceRepairAttempt } = prepared;
|
|
97
|
+
assertRunMutationAllowed(context, project.id, run.id);
|
|
98
|
+
assertStageStartHookEvent(context, { projectId: project.id, eventKey: input.hookEventId, runId: run.id, stage, projectRoot, ...(input.contextSha256 ? { contextSha256: input.contextSha256 } : {}) });
|
|
99
|
+
prepareAgentOutputFile(path.join(requireHome(run), "works", rootWork.work_id, "block-summary.md"));
|
|
100
|
+
if (prepared.resumed) {
|
|
101
|
+
resumeVerificationMatrix(context, project.id, run.id, stage);
|
|
102
|
+
const externalContext = applyExternalStageContext({ context, stageRoot: root, promptPath, ...(input.externalContext ? { loaded: input.externalContext } : {}) });
|
|
103
|
+
bindStageCoordinatorWork(context, { workId: rootWork.work_id, hookEventId: input.hookEventId, stage, promptPath, resultPath: path.join(root, "stage-report.json"), ...(input.contextSha256 ? { contextSha256: input.contextSha256 } : {}) });
|
|
104
|
+
const orchestration = prepared.orchestration ?? writeFanoutDescriptor(root, { stage, parent_work_id: rootWork.work_id, dispatch: "none", capacity_required: true, scope: stageGraphScope(context, project.id, run.id, stage) });
|
|
105
|
+
return { ok: true, resumed: true, run_id: run.id, stage, stage_status: prepared.existingStage, ...currentStagePrompt(context, promptPath), ...(externalContext ? { external_context: externalContext } : {}), orchestration, graph: codeWorkGraph(context, project.id, run.id), next: { refresh_graph_command: runtimeCommand(context, ["work", "ls", "--run", run.id, "--ready", "--project-root", projectRoot, "--json"]), finish_command: finishCommand(context, input.runId, projectRoot, path.join(root, "code-verification.json")) } };
|
|
106
|
+
}
|
|
107
|
+
if (!sourceRepairAttempt)
|
|
108
|
+
prepareFlowRunStageAttachment(context, { projectRoot, runId: run.id, stage, dir: stageDir, status: "running", dataSchemaId: "dd-flow/stage-report@1" }, true);
|
|
62
109
|
fs.mkdirSync(root, { recursive: true });
|
|
63
110
|
const readiness = await ensureCodeWorkspaceReady(context, project.id, run, root, [], input.progress);
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const prompt = coordinatorPrompt(context, { projectRoot, run, root, rootWork, readiness })
|
|
111
|
+
// Graph rendering may issue managed child commands; it belongs to execution.
|
|
112
|
+
const graph = codeWorkGraph(context, project.id, run.id);
|
|
113
|
+
const prompt = `${coordinatorPrompt(context, { projectRoot, run, root, rootWork, readiness, template: prepared.template, capacity: prepared.capacity, graph })}\n${stageLifecycleInstruction}\n${verificationMatrixInstruction(prepared.matrix?.metadata ?? null, prepared.home, "implementation and code-verification.json")}\n`;
|
|
67
114
|
fs.writeFileSync(promptPath, prompt);
|
|
68
|
-
const externalContext = applyExternalStageContext({ stageRoot: root, promptPath, ...(input.externalContext ? { loaded: input.externalContext } : {}) });
|
|
115
|
+
const externalContext = applyExternalStageContext({ context, stageRoot: root, promptPath, ...(input.externalContext ? { loaded: input.externalContext } : {}) });
|
|
69
116
|
const binding = bindStageCoordinatorWork(context, {
|
|
70
117
|
workId: rootWork.work_id,
|
|
71
118
|
hookEventId: input.hookEventId,
|
|
@@ -75,17 +122,20 @@ export async function startVnextCode(context, input) {
|
|
|
75
122
|
...(input.contextSha256 ? { contextSha256: input.contextSha256 } : {})
|
|
76
123
|
});
|
|
77
124
|
if (!sourceRepairAttempt) {
|
|
78
|
-
|
|
125
|
+
const attachmentInput = {
|
|
79
126
|
projectRoot,
|
|
80
127
|
runId: input.runId,
|
|
81
128
|
stage,
|
|
82
129
|
dir: stageDir,
|
|
83
130
|
status: "running",
|
|
84
131
|
dataSchemaId: "dd-flow/stage-report@1"
|
|
85
|
-
}
|
|
132
|
+
};
|
|
133
|
+
const attachment = prepareFlowRunStageAttachment(context, attachmentInput);
|
|
134
|
+
commitVerificationMatrixStart(context, prepared.matrix, () => attachFlowRunStage(context, attachmentInput, attachment));
|
|
86
135
|
}
|
|
87
|
-
|
|
88
|
-
|
|
136
|
+
else
|
|
137
|
+
commitVerificationMatrixStart(context, prepared.matrix, () => undefined);
|
|
138
|
+
const orchestration = writeFanoutDescriptor(root, { stage, parent_work_id: rootWork.work_id, dispatch: "none", capacity_required: true, scope: stageGraphScope(context, project.id, run.id, stage) });
|
|
89
139
|
appendFlowRunTimelineEvent(context, project.id, input.runId, { type: "code_started", work_id: rootWork.work_id, graph });
|
|
90
140
|
return {
|
|
91
141
|
ok: true,
|
|
@@ -93,13 +143,12 @@ export async function startVnextCode(context, input) {
|
|
|
93
143
|
stage,
|
|
94
144
|
root_work_id: rootWork.work_id,
|
|
95
145
|
id: binding.work_session_id,
|
|
96
|
-
|
|
97
|
-
worker_prompt_markdown: fs.readFileSync(promptPath, "utf8"),
|
|
146
|
+
...currentStagePrompt(context, promptPath),
|
|
98
147
|
...(externalContext ? { external_context: externalContext } : {}),
|
|
99
148
|
graph,
|
|
100
149
|
orchestration,
|
|
101
150
|
readiness,
|
|
102
|
-
next: { refresh_graph_command:
|
|
151
|
+
next: { refresh_graph_command: runtimeCommand(context, ["work", "ls", "--run", run.id, "--ready", "--project-root", projectRoot, "--json"]), finish_command: finishCommand(context, input.runId, projectRoot, path.join(root, "code-verification.json")) }
|
|
103
152
|
};
|
|
104
153
|
}
|
|
105
154
|
export async function finishVnextCode(context, input) {
|
|
@@ -108,8 +157,10 @@ export async function finishVnextCode(context, input) {
|
|
|
108
157
|
const run = requireRun(context, project.id, input.runId);
|
|
109
158
|
const home = requireHome(run);
|
|
110
159
|
const root = path.join(home, stageDir);
|
|
111
|
-
|
|
160
|
+
const generation = assertRunMutationAllowed(context, project.id, run.id);
|
|
161
|
+
requireVnextWorkspaceRoute(context, { projectRoot, runId: run.id, runHome: home, workspaceRoot: run.workspace_root, stage });
|
|
112
162
|
if (stageStatus(run, stage) === "done" && fs.existsSync(path.join(root, "stage-report.json"))) {
|
|
163
|
+
resumeAcceptedCodeStage(context, run, projectRoot, stage, JSON.parse(fs.readFileSync(path.join(root, "stage-report.json"), "utf8")), nextAction(run, changedPathsFromReport(path.join(root, "stage-report.json"))));
|
|
113
164
|
return { ok: true, resumed: true, run_id: run.id, stage, outcome: "accepted", report_path: path.join(root, "stage-report.json"), next_action: nextAction(run, changedPathsFromReport(path.join(root, "stage-report.json"))) };
|
|
114
165
|
}
|
|
115
166
|
const handoffFailures = validateVnextCodeHandoff(context, {
|
|
@@ -138,9 +189,12 @@ export async function finishVnextCode(context, input) {
|
|
|
138
189
|
throw new AppError("obligation_coverage_incomplete", "CODE graph does not cover every accepted obligation", 2, { missing });
|
|
139
190
|
}
|
|
140
191
|
// Reject a malformed semantic receipt before running the expensive gate.
|
|
141
|
-
const verification = verificationForFinish(context, { file: input.verificationFile, projectRoot: run.workspace_root, runId: run.id, runRoot: home });
|
|
192
|
+
const verification = input.verification ?? verificationForFinish(context, { file: input.verificationFile, projectRoot: run.workspace_root, runId: run.id, runRoot: home });
|
|
193
|
+
validateSchema({ schemaName: "code-verification", file: input.verificationFile, data: verification, projectRoot: run.workspace_root, ddFlowHome: context.ddFlowHome, runId: run.id, runRoot: home });
|
|
194
|
+
const retainedMatrix = latestRunVerificationMatrix(context, project.id, run.id, stage);
|
|
195
|
+
const retainedMatrixInstruction = verificationMatrixInstruction(retainedMatrix?.metadata ?? null, home, "the current semantic verification and repair");
|
|
142
196
|
if (verification.verdict === "blocked") {
|
|
143
|
-
return { ok: true, run_id: run.id, stage, outcome: "blocked", verification, instruction:
|
|
197
|
+
return { ok: true, run_id: run.id, stage, outcome: "blocked", verification, ...(retainedMatrix ? { verification_matrix: retainedMatrix.metadata } : {}), instruction: `CODE remains running. Resolve the stated external or user-input blocker in this same coordinator session, update code-verification.json, then invoke next.finish_command. Do not repeat while the blocker remains unresolved.\n${retainedMatrixInstruction}`, next: { finish_command: finishCommand(context, run.id, projectRoot, input.verificationFile) } };
|
|
144
198
|
}
|
|
145
199
|
if (verification.verdict === "passed" && verification.unresolved.length > 0) {
|
|
146
200
|
throw new AppError("verification_contradictory", "A passed CODE verification cannot contain unresolved obligations", 2, { unresolved: verification.unresolved });
|
|
@@ -152,58 +206,59 @@ export async function finishVnextCode(context, input) {
|
|
|
152
206
|
originWorkIds: works.filter((work) => work.status === "completed").map((work) => work.work_id),
|
|
153
207
|
semanticUnresolved: verification.unresolved.length ? verification.unresolved : [verification.summary],
|
|
154
208
|
verificationPath: input.verificationFile,
|
|
209
|
+
verification,
|
|
155
210
|
objective: verification.summary
|
|
156
211
|
});
|
|
157
|
-
return { ok: true, run_id: run.id, stage, outcome: "repair_required", verification, repair, instruction:
|
|
212
|
+
return { ok: true, run_id: run.id, stage, outcome: "repair_required", verification, repair, ...(retainedMatrix ? { verification_matrix: retainedMatrix.metadata } : {}), instruction: `The semantic verification is not accepted. The repair Work is already registered: do not invoke its start_command in this coordinator Session. End this Turn so the controller can launch it in a fresh child Session. After that Work completes, update code-verification.json and invoke next.finish_command.\n${retainedMatrixInstruction}`, next: { finish_command: finishCommand(context, run.id, projectRoot, input.verificationFile) } };
|
|
158
213
|
}
|
|
159
214
|
const checks = finalCodeCheckDeclarations(run.workspace_root, works.flatMap((work) => packet(work)?.checks ?? []));
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
receipts = reusableAggregateGateReceipts(context, { projectId: project.id, runId: run.id, workspaceRoot: run.workspace_root, checks }) ?? await runCodeChecks(context, {
|
|
170
|
-
projectId: project.id,
|
|
171
|
-
runId: run.id,
|
|
172
|
-
runHome: home,
|
|
173
|
-
workspaceRoot: run.workspace_root,
|
|
174
|
-
scope: "aggregate",
|
|
175
|
-
checks,
|
|
176
|
-
...(input.progress ? { progress: input.progress } : {})
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
finally {
|
|
180
|
-
release();
|
|
181
|
-
}
|
|
182
|
-
}
|
|
215
|
+
if (input.retryCheckId) {
|
|
216
|
+
validateFailedCheckRetry(context, { projectId: project.id, runId: run.id, receiptId: input.retryCheckId, declarations: checks, reason: input.retryReason });
|
|
217
|
+
appendFlowRunTimelineEvent(context, project.id, run.id, { type: "check_retry_requested", check_receipt_id: input.retryCheckId, stage, reason: input.retryReason ?? "operator retry" });
|
|
218
|
+
}
|
|
219
|
+
const receipts = await runCodeChecks(context, {
|
|
220
|
+
projectId: project.id, runId: run.id, runHome: home, workspaceRoot: run.workspace_root, scope: "aggregate", checks,
|
|
221
|
+
...(input.retryCheckId ? { retryReceiptId: input.retryCheckId, retryReason: input.retryReason } : {}),
|
|
222
|
+
...(input.progress ? { progress: input.progress } : {})
|
|
223
|
+
});
|
|
183
224
|
const failed = receipts.filter((receipt) => receipt.status !== "passed");
|
|
225
|
+
const matrix = prepareRunVerificationMatrix(context, { projectId: project.id, runId: run.id, stage, role: "output", receipts, semanticFile: input.verificationFile });
|
|
226
|
+
const matrixInstruction = matrix ? verificationMatrixInstruction(matrix.metadata, home, "semantic verification in code-verification.json") : "";
|
|
184
227
|
if (failed.length) {
|
|
228
|
+
assertSourceRepairEligible(failed);
|
|
229
|
+
context.db.writeTransaction(() => acceptVerificationMatrix(context, matrix));
|
|
230
|
+
publishVerificationMatrix(context, matrix);
|
|
231
|
+
const continuation = registerAggregateCodeRepair(context, { projectRoot, runId: run.id, stage, failures: failed, checks, generation });
|
|
185
232
|
throw new AppError("code_gate_failed", "CODE remains running because the aggregate project gate failed", 2, {
|
|
186
233
|
failures: failed,
|
|
187
234
|
outcome: "repair_required",
|
|
188
235
|
retry_after_workspace_change: true,
|
|
189
236
|
workspace_fingerprint: failed[0].workspace_fingerprint,
|
|
190
|
-
|
|
237
|
+
continuation,
|
|
238
|
+
...(matrix ? { verification_matrix: matrix.metadata, verification_matrix_instruction: matrixInstruction } : {}),
|
|
239
|
+
instruction: `Repair Work is already registered. End this coordinator Turn; the controller will launch a fresh child. After it completes, update semantic verification and finish the Stage.\n${matrixInstruction}`
|
|
191
240
|
});
|
|
192
241
|
}
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
242
|
+
const finalReceipts = receipts;
|
|
243
|
+
if (verification.verdict === "needs_checks") {
|
|
244
|
+
context.db.writeTransaction(() => acceptVerificationMatrix(context, matrix));
|
|
245
|
+
publishVerificationMatrix(context, matrix);
|
|
246
|
+
return { ok: true, run_id: run.id, stage, outcome: "verification_required", verification,
|
|
247
|
+
...(matrix ? { verification_matrix: matrix.metadata, verification_matrix_instruction: matrixInstruction } : {}),
|
|
248
|
+
receipts: finalReceipts.map(receipt => ({ id: receipt.id, receipt_path: receipt.receipt_path, input_hash: receipt.input_hash, status: receipt.status })),
|
|
249
|
+
next: { kind: "verification_required", finish_command: finishCommand(context, run.id, projectRoot, input.verificationFile) },
|
|
250
|
+
instruction: `Aggregate receipts are available. Keep CODE running. Inspect them, update code-verification.json to passed or needs_repair, then invoke only the issued successor finish_command. A material document change belongs to the registered fresh repair Work, not this coordinator Session.\n${matrixInstruction}` };
|
|
251
|
+
}
|
|
252
|
+
const projectedVerification = verificationProjection(works, finalReceipts, { historicalReceipts: finalReceipts, runId: run.id, runHome: home });
|
|
196
253
|
const unresolvedAcceptance = (projectedVerification.acceptance ?? []).filter((item) => item.status === "unresolved");
|
|
197
254
|
if (unresolvedAcceptance.length)
|
|
198
255
|
throw new AppError("code_acceptance_unresolved", "CODE cannot finish until every due acceptance criterion has current checks and evidence", 2, { unresolved: unresolvedAcceptance });
|
|
199
256
|
const now = context.now();
|
|
200
257
|
const timing = stageTiming(home, stage, now);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
if (missingReportedPaths.length)
|
|
206
|
-
throw new AppError("changed_path_not_materialized", "CODE Work reported paths that are not changed in the accepted workspace", 2, { paths: missingReportedPaths });
|
|
258
|
+
// Work result paths are provenance, not a mutable filesystem oracle. The
|
|
259
|
+
// stage reports one shared Git observation; ignored machine repairs are
|
|
260
|
+
// rejected before a Work can become completed.
|
|
261
|
+
const changedPaths = workspaceChangedPaths(run.workspace_root);
|
|
207
262
|
const next = nextAction(run, changedPaths);
|
|
208
263
|
const report = {
|
|
209
264
|
schema_id: "dd-flow/stage-report@1",
|
|
@@ -233,8 +288,8 @@ export async function finishVnextCode(context, input) {
|
|
|
233
288
|
wall_clock_ms: timing.wall_clock_ms,
|
|
234
289
|
git: gitFacts(run.workspace_root),
|
|
235
290
|
graph: codeWorkGraph(context, project.id, run.id),
|
|
236
|
-
session_stats_command:
|
|
237
|
-
usage_stats_command:
|
|
291
|
+
session_stats_command: runtimeCommand(context, ["stat", "run", "sessions", "ls", "--run", run.id, "--project-root", projectRoot, "--json"]),
|
|
292
|
+
usage_stats_command: runtimeCommand(context, ["stat", "usage", "--run", run.id, "--project-root", projectRoot, "--json"])
|
|
238
293
|
},
|
|
239
294
|
artifacts: { json: "stage-report.json", markdown: "stage-report.md", html: "stage-report.html", summary: "stage-report.md" },
|
|
240
295
|
validation: { permission_scope: "known_targets_only", memory_bank_scope: "changed_files_and_links_only", status: "passed" }
|
|
@@ -242,31 +297,38 @@ export async function finishVnextCode(context, input) {
|
|
|
242
297
|
// Creating the MERGE request is part of accepting this terminal handoff.
|
|
243
298
|
// Do it before materialising a terminal stage report or changing RUN state,
|
|
244
299
|
// so an invalid merge policy leaves CODE safely running and retryable.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
300
|
+
let mergeRequest = null;
|
|
301
|
+
assertRunMutationAllowed(context, project.id, run.id, generation);
|
|
302
|
+
const prepareMerge = next === "start_merge" ? prepareVnextMergeRequest(context, { projectRoot, runId: run.id, acceptedPaths: changedPaths }) : null;
|
|
303
|
+
if (matrix)
|
|
304
|
+
Object.assign(report.semantic, { verification_matrix: matrix.metadata });
|
|
305
|
+
const preparedReport = prepareStageReport(report);
|
|
306
|
+
const completionInput = { projectRoot, runId: run.id, stage, status: "done", data: "stage-report.json", dataSchemaId: "dd-flow/stage-report@1", report: "stage-report.md", stageReport: "stage-report.html", dataSha256: preparedReport.sha256, git: report.mechanical.git };
|
|
307
|
+
withStageSettlement(context, () => {
|
|
308
|
+
assertRunMutationAllowed(context, project.id, run.id, generation);
|
|
309
|
+
const currentWorks = codeWorks(context, project.id, run.id);
|
|
310
|
+
if (currentWorks.length !== works.length || currentWorks.some(work => work.status !== "completed" || !works.some(accepted => accepted.work_id === work.work_id && accepted.result === work.result))) {
|
|
311
|
+
throw new AppError("code_graph_incomplete", "CODE results changed while the final checks were running", 2);
|
|
312
|
+
}
|
|
313
|
+
mergeRequest = prepareMerge?.() ?? null;
|
|
314
|
+
const preparedCompletion = prepareFlowRunStageCompletion(context, completionInput);
|
|
315
|
+
acceptVerificationMatrix(context, matrix);
|
|
316
|
+
acceptStageReport(context, { projectId: project.id, runId: run.id, stage, root, prepared: preparedReport });
|
|
317
|
+
completeFlowRunStage(context, completionInput, preparedCompletion);
|
|
318
|
+
const rootWork = requireRootWork(context, project.id, run.id);
|
|
319
|
+
appendFlowRunTimelineEvent(context, project.id, run.id, {
|
|
320
|
+
type: "code_accepted",
|
|
321
|
+
work_id: rootWork.work_id,
|
|
322
|
+
checks: finalReceipts.map((receipt) => receipt.id)
|
|
323
|
+
});
|
|
324
|
+
if (next === "code_completed") {
|
|
325
|
+
finishStageCoordinatorWork(context, rootWork.work_id, JSON.stringify(report, null, 2));
|
|
326
|
+
completeFlowRun(context, { projectRoot, runId: run.id, status: "done", verdict: "code_completed", nextAction: undefined });
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
advanceFlowRun(context, { settlementStage: "code", projectRoot, runId: run.id, status: "running", verdict: "code_completed", nextAction: next });
|
|
330
|
+
}
|
|
262
331
|
});
|
|
263
|
-
if (next === "code_completed") {
|
|
264
|
-
await finishWork(context, rootWork.work_id, JSON.stringify(report, null, 2));
|
|
265
|
-
completeFlowRun(context, { projectRoot, runId: run.id, status: "done", verdict: "code_completed", nextAction: undefined });
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
advanceFlowRun(context, { projectRoot, runId: run.id, status: "running", verdict: "code_completed", nextAction: next });
|
|
269
|
-
}
|
|
270
332
|
return {
|
|
271
333
|
ok: true,
|
|
272
334
|
run_id: run.id,
|
|
@@ -274,19 +336,69 @@ export async function finishVnextCode(context, input) {
|
|
|
274
336
|
outcome: "accepted",
|
|
275
337
|
report_path: path.join(root, "stage-report.json"),
|
|
276
338
|
next_action: next,
|
|
277
|
-
...(next === "start_code_review" ? { next: {
|
|
339
|
+
...(next === "start_code_review" ? { next: stageSuccessor(context, { projectRoot, runId: run.id, stage: "code-review", command: runtimeCommand(context, ["stage", "start", run.id, "--stage", "code-review", "--project-root", projectRoot, "--json"]) }) } : next === "start_merge" ? { merge_request: mergeRequest, next: stageSuccessor(context, { projectRoot, runId: run.id, stage: "merge", command: runtimeCommand(context, ["stage", "start", run.id, "--stage", "merge", "--project-root", projectRoot, "--json", "--progress-jsonl"]) }) } : {})
|
|
278
340
|
};
|
|
279
341
|
}
|
|
280
|
-
export function
|
|
342
|
+
export function registerAggregateCodeRepair(context, input) {
|
|
343
|
+
const project = requireProjectByRoot(context, input.projectRoot);
|
|
344
|
+
const origins = codeWorks(context, project.id, input.runId).filter(work => !packet(work)?.repair && work.status === "completed");
|
|
345
|
+
const failedDeclarations = new Set(input.failures.flatMap(receipt => [receipt.declaration_id, ...receipt.check_refs]));
|
|
346
|
+
const objective = ["Investigate and repair all retained aggregate check failures while preserving accepted requirements and non-goals. If evidence proves an external blocker or a contradiction, report it; do not invent a product change.", ...input.failures.map(receipt => `Receipt: ${receipt.receipt_path}\nstdout: ${receipt.stdout_path}\nstderr: ${receipt.stderr_path}`)].join("\n\n");
|
|
347
|
+
try {
|
|
348
|
+
return ensureAggregateRepair(context, { projectId: project.id, runId: input.runId, stage: input.stage, failures: input.failures, origins: origins.map(work => work.work_id), ...(input.generation !== undefined ? { generation: input.generation } : {}) }, () => String(addVnextCodeRepair(context, { registrationOwned: true, projectRoot: input.projectRoot, runId: input.runId, stage: input.stage, ...(input.stage === "code-review" ? { reviewCycle: stageCycle(context, project.id, input.runId, input.stage) } : {}), checkReceiptId: input.failures[0].id, originWorkIds: origins.map(work => work.work_id), objective, reviewChecks: input.checks.filter(check => failedDeclarations.has(check.id) || failedDeclarations.has(check.canonical_ref ?? "")) }).repair_work_id));
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
if (!(error instanceof AppError))
|
|
352
|
+
throw error;
|
|
353
|
+
throw new AppError(error.code, error.message, error.exitCode, { ...error.details, stage: input.stage, run_id: input.runId, failures: input.failures, cause: { code: input.stage === "code" ? "code_gate_failed" : "code_review_gate_failed", message: "Aggregate checks failed; repair registration was rejected" } });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
export function prepareVnextCodeRepair(context, input) {
|
|
281
357
|
const projectRoot = resolveProjectRoot(input.projectRoot);
|
|
282
358
|
const project = requireProjectByRoot(context, projectRoot);
|
|
283
359
|
const run = requireRun(context, project.id, input.runId);
|
|
284
360
|
const home = requireHome(run);
|
|
285
|
-
if (
|
|
361
|
+
if (input.reviewCycle) {
|
|
362
|
+
const previous = codeWorks(context, project.id, run.id).find((work) => packet(work)?.review_cycle === input.reviewCycle && (input.checkReceiptId ? packet(work)?.repair?.check_receipt_id === input.checkReceiptId : Boolean(packet(work)?.repair?.review_findings?.length)));
|
|
363
|
+
if (previous)
|
|
364
|
+
return { kind: "replay", project, run, previous };
|
|
365
|
+
}
|
|
366
|
+
if (input.semanticUnresolved?.length && input.verificationPath) {
|
|
367
|
+
const previous = codeWorks(context, project.id, run.id).find(work => {
|
|
368
|
+
const repair = packet(work)?.repair;
|
|
369
|
+
return Boolean(repair && repair.verification_path === input.verificationPath
|
|
370
|
+
&& JSON.stringify(repair.semantic_unresolved) === JSON.stringify(unique(input.semanticUnresolved ?? [])));
|
|
371
|
+
});
|
|
372
|
+
if (previous)
|
|
373
|
+
return { kind: "replay", project, run, previous };
|
|
374
|
+
}
|
|
375
|
+
if (typeof input.objective !== "string" || !input.objective.trim())
|
|
286
376
|
throw new AppError("validation", "Repair objective must not be empty", 2);
|
|
377
|
+
if (input.semanticUnresolved !== undefined && (!Array.isArray(input.semanticUnresolved) || input.semanticUnresolved.some(value => typeof value !== "string" || !value.trim())))
|
|
378
|
+
throw new AppError("validation", "Semantic unresolved items must be nonempty strings", 2);
|
|
379
|
+
if (input.reviewFindings !== undefined && !Array.isArray(input.reviewFindings))
|
|
380
|
+
throw new AppError("validation", "Review findings must be an array", 2);
|
|
381
|
+
if (input.reviewChecks !== undefined && !Array.isArray(input.reviewChecks))
|
|
382
|
+
throw new AppError("validation", "Review checks must be an array", 2);
|
|
383
|
+
if (!Array.isArray(input.originWorkIds) || !input.originWorkIds.length || input.originWorkIds.some(id => typeof id !== "string" || !id.trim()))
|
|
384
|
+
throw new AppError("validation", "Repair requires at least one origin Work", 2);
|
|
287
385
|
if (!input.checkReceiptId && !input.reviewFindings?.length && !input.semanticUnresolved?.length) {
|
|
288
386
|
throw new AppError("validation", "Repair needs failed check evidence, a CODE-REVIEW finding, or an unresolved CODE verification", 2);
|
|
289
387
|
}
|
|
388
|
+
if ([Boolean(input.checkReceiptId), Boolean(input.reviewFindings?.length), Boolean(input.semanticUnresolved?.length)].filter(Boolean).length !== 1)
|
|
389
|
+
throw new AppError("validation", "Repair requires exactly one evidence source", 2);
|
|
390
|
+
let semanticVerification = input.verification;
|
|
391
|
+
if (input.semanticUnresolved?.length) {
|
|
392
|
+
if (!input.verificationPath)
|
|
393
|
+
throw new AppError("usage", "Semantic repair requires a verification file", 2);
|
|
394
|
+
const verification = input.verification ?? readVerification(context, { file: input.verificationPath, projectRoot: run.workspace_root, runId: run.id, runRoot: home });
|
|
395
|
+
semanticVerification = verification;
|
|
396
|
+
if (input.verification !== undefined)
|
|
397
|
+
validateSchema({ schemaName: "code-verification", file: input.verificationPath, data: verification, projectRoot: run.workspace_root, ddFlowHome: context.ddFlowHome, runId: run.id, runRoot: home });
|
|
398
|
+
const unresolved = verification.unresolved.length ? verification.unresolved : [verification.summary];
|
|
399
|
+
if (verification.verdict !== "needs_repair" || input.semanticUnresolved.some(value => !unresolved.includes(value)))
|
|
400
|
+
throw new AppError("validation", "Semantic repair must reference unresolved items from a needs_repair verification", 2);
|
|
401
|
+
}
|
|
290
402
|
const receipt = input.checkReceiptId ? context.db.get("SELECT id, declaration_id, run_id, command, status, receipt_path, stdout_path, stderr_path FROM check_receipts WHERE project_id = ? AND id = ?", [
|
|
291
403
|
project.id,
|
|
292
404
|
input.checkReceiptId
|
|
@@ -296,6 +408,8 @@ export function addVnextCodeRepair(context, input) {
|
|
|
296
408
|
check_receipt_id: input.checkReceiptId
|
|
297
409
|
});
|
|
298
410
|
}
|
|
411
|
+
if (input.checkReceiptId)
|
|
412
|
+
assertSourceRepairEligible(checkReceipts(context, { projectId: project.id, runId: run.id }).filter(item => item.id === input.checkReceiptId));
|
|
299
413
|
const origins = [...new Set(input.originWorkIds)].map((id) => requireCodeWork(context, project.id, run.id, id));
|
|
300
414
|
const packets = origins.map((work) => packet(work));
|
|
301
415
|
const invariantPackets = receipt || input.semanticUnresolved?.length
|
|
@@ -307,10 +421,10 @@ export function addVnextCodeRepair(context, input) {
|
|
|
307
421
|
// repair that fixes one failed aggregate check can make a second, already
|
|
308
422
|
// declared aggregate failure impossible to repair. The immutable source
|
|
309
423
|
// of repair eligibility is the original CODE graph.
|
|
310
|
-
const declaredChecks =
|
|
424
|
+
const declaredChecks = effectiveCheckDeclarations(run.workspace_root, codeWorks(context, project.id, run.id)
|
|
311
425
|
.map((work) => packet(work))
|
|
312
426
|
.filter((value) => !value.repair)
|
|
313
|
-
.flatMap((value) => value.checks));
|
|
427
|
+
.flatMap((value) => value.checks), ["work", "code", "readiness", "merge"]);
|
|
314
428
|
const failedCheck = receipt ? declaredChecks.find((check) => check.id === receipt.declaration_id) : undefined;
|
|
315
429
|
if (receipt && !failedCheck) {
|
|
316
430
|
throw new AppError("repair_check_declaration_missing", "Repair receipt is not backed by an accepted CODE check declaration", 2, {
|
|
@@ -330,7 +444,11 @@ export function addVnextCodeRepair(context, input) {
|
|
|
330
444
|
origin_work_ids: origins.map((work) => work.work_id),
|
|
331
445
|
...(receipt ? { check_receipt_id: receipt.id, failure_receipt_path: receipt.receipt_path } : {}),
|
|
332
446
|
...(input.reviewFindings?.length ? { review_findings: input.reviewFindings } : {}),
|
|
333
|
-
...(semanticRepair ? { semantic_unresolved: unique(input.semanticUnresolved ?? []), verification_path: input.verificationPath } : {})
|
|
447
|
+
...(semanticRepair ? { semantic_unresolved: unique(input.semanticUnresolved ?? []), verification_path: input.verificationPath } : {}),
|
|
448
|
+
// `run_at` remains the accepted aggregate placement. This separate
|
|
449
|
+
// repair obligation is deliberately executed before this repair Work is
|
|
450
|
+
// accepted, so a local fix cannot close without re-proving its cause.
|
|
451
|
+
verification_check_refs: selectRepairChecks({ ...(failedCheck ? { failedCheck } : {}), ...(input.reviewChecks ? { reviewChecks: input.reviewChecks } : {}), ...(semanticRepair ? { semanticChecks: declaredChecks } : {}) })
|
|
334
452
|
},
|
|
335
453
|
task: input.objective,
|
|
336
454
|
semantic_spine: {
|
|
@@ -344,7 +462,17 @@ export function addVnextCodeRepair(context, input) {
|
|
|
344
462
|
acceptance: uniqueBy(invariantPackets.flatMap((value) => value.acceptance), (value) => JSON.stringify(value)),
|
|
345
463
|
// A CODE-REVIEW repair changes delivered code/evidence, never the
|
|
346
464
|
// already accepted PLAN or its ownership declaration.
|
|
347
|
-
document_updates: []
|
|
465
|
+
document_updates: semanticRepair ? uniqueBy((semanticVerification?.document_updates ?? []).map(relative => {
|
|
466
|
+
const declared = invariantPackets.flatMap(value => value.document_updates).find(value => value.path === relative);
|
|
467
|
+
if (!declared)
|
|
468
|
+
throw new AppError("document_update_unknown", "CODE verification selected a document absent from accepted Work ownership", 2, { path: relative });
|
|
469
|
+
const file = path.resolve(run.workspace_root, relative);
|
|
470
|
+
if (!file.startsWith(`${path.resolve(run.workspace_root)}${path.sep}`))
|
|
471
|
+
throw new AppError("document_update_invalid", "CODE verification document path escapes the workspace", 2, { path: relative });
|
|
472
|
+
const exists = fs.existsSync(file);
|
|
473
|
+
return { ...declared, action: exists ? "update" : "create",
|
|
474
|
+
baseline_sha256: exists ? crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex") : null };
|
|
475
|
+
}), value => value.path) : [],
|
|
348
476
|
required_read: unique([...(receipt ? [receipt.receipt_path] : input.reviewFindings?.flatMap((finding) => finding.evidence_refs) ?? []), ...(semanticRepair && input.verificationPath ? [input.verificationPath] : []), ...packets.flatMap((value) => value.required_read)]),
|
|
349
477
|
discovery_boundary: unique(packets.flatMap((value) => value.discovery_boundary)),
|
|
350
478
|
// These are collision-avoidance hints. Receipt paths enrich the coordinator
|
|
@@ -363,33 +491,33 @@ export function addVnextCodeRepair(context, input) {
|
|
|
363
491
|
result_schema: "dd-flow/code-work-result@3",
|
|
364
492
|
...(input.reviewCycle ? { review_cycle: input.reviewCycle } : {})
|
|
365
493
|
};
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
const id =
|
|
494
|
+
const parentWorkId = requireRootWork(context, project.id, run.id).work_id;
|
|
495
|
+
const items = prepareWorkBatch(context, { parentWorkId, value: { works: [repair] } });
|
|
496
|
+
return { kind: "create", project, run, input, parentWorkId, items, key, receipt };
|
|
497
|
+
}
|
|
498
|
+
export function addVnextCodeRepair(context, input, prepared = prepareVnextCodeRepair(context, input)) {
|
|
499
|
+
const { project, run } = prepared;
|
|
500
|
+
if (prepared.kind === "replay")
|
|
501
|
+
return { ok: true, run_id: run.id, repair_work_id: prepared.previous.work_id, start_command: workStartCommand(context, prepared.previous, { preview: true }), reused: true };
|
|
502
|
+
const { parentWorkId, items, key, receipt } = prepared;
|
|
503
|
+
const create = () => String(addWorkBatch(context, { parentWorkId, prepared: items, stage: input.stage ?? (input.reviewCycle ? "code-review" : "code"), ...(input.reviewCycle ? { cycle: input.reviewCycle } : {}) }).work_ids[key]);
|
|
504
|
+
const id = input.registrationOwned ? create() : ensureRepairIntent(context, {
|
|
505
|
+
projectId: project.id, runId: run.id, stage: input.stage ?? (input.reviewCycle ? "code-review" : "code"),
|
|
506
|
+
causes: input.checkReceiptId ? { receipt: input.checkReceiptId, origins: [...input.originWorkIds].sort() } : input.reviewCycle ? { review_cycle: input.reviewCycle, findings: input.reviewFindings } : { verification: input.verification, unresolved: input.semanticUnresolved, origins: [...input.originWorkIds].sort() }
|
|
507
|
+
}, create).work_id;
|
|
377
508
|
const work = context.db.get("SELECT * FROM works WHERE work_id = ?", [id]);
|
|
378
509
|
appendFlowRunTimelineEvent(context, project.id, run.id, {
|
|
379
510
|
type: "code_repair_created",
|
|
380
511
|
work_id: id,
|
|
381
|
-
origin_work_ids: input.originWorkIds,
|
|
382
|
-
...(receipt ? { check_receipt_id: receipt.id } : input.reviewFindings?.length ? { review_finding_ids: input.reviewFindings.map((finding) => finding.finding_ref) } : { semantic_unresolved: input.semanticUnresolved })
|
|
512
|
+
origin_work_ids: prepared.input.originWorkIds,
|
|
513
|
+
...(receipt ? { check_receipt_id: receipt.id } : prepared.input.reviewFindings?.length ? { review_finding_ids: prepared.input.reviewFindings.map((finding) => finding.finding_ref) } : { semantic_unresolved: prepared.input.semanticUnresolved })
|
|
383
514
|
});
|
|
384
515
|
refreshRunWorkProjection(context, project.id, run.id);
|
|
385
|
-
return { ok: true, run_id: run.id, repair_work_id: id, start_command: workStartCommand(context, work) };
|
|
516
|
+
return { ok: true, run_id: run.id, repair_work_id: id, start_command: workStartCommand(context, work, { preview: true }) };
|
|
386
517
|
}
|
|
387
|
-
/** Retain the causal declaration for worker context; run_at
|
|
518
|
+
/** Retain the causal declaration for worker context; run_at still records its original gate. */
|
|
388
519
|
export function selectRepairChecks(input) {
|
|
389
|
-
|
|
390
|
-
// work-scoped entries, while retaining the aggregate declaration tells the
|
|
391
|
-
// worker exactly what will be rerun by the coordinator.
|
|
392
|
-
const candidates = input.failedCheck ? [input.failedCheck] : input.reviewChecks ?? input.semanticChecks ?? [];
|
|
520
|
+
const candidates = input.failedCheck ? [input.failedCheck, ...(input.reviewChecks ?? [])] : input.reviewChecks ?? input.semanticChecks ?? [];
|
|
393
521
|
const checks = candidates.map((check) => ({ ...check, purpose: `${input.semanticChecks ? "Prove the CODE verification repair" : "Prove the CODE-REVIEW repair"}: ${check.purpose}` }));
|
|
394
522
|
return uniqueBy(checks, (check) => check.id);
|
|
395
523
|
}
|
|
@@ -417,16 +545,14 @@ function receiptRepairPaths(workspaceRoot, receipt) {
|
|
|
417
545
|
}
|
|
418
546
|
return [...paths].sort();
|
|
419
547
|
}
|
|
420
|
-
function coordinatorPrompt(context, input) {
|
|
421
|
-
const graph
|
|
422
|
-
const variables = getFlowRunVariables(context, { projectRoot: input.projectRoot, runId: input.run.id });
|
|
423
|
-
const capacity = variables.variables?.["runtime.subagent.available_slots"];
|
|
424
|
-
const template = fs.readFileSync(path.join(input.run.workspace_root, ".memory-bank", "dd-flow", "vnext", "code.md"), "utf8");
|
|
548
|
+
export function coordinatorPrompt(context, input) {
|
|
549
|
+
const { graph, capacity, template } = input;
|
|
425
550
|
return [
|
|
426
551
|
"<stage_identity>",
|
|
427
552
|
`- RUN: ${input.run.id}`,
|
|
428
553
|
`- root Work: ${input.rootWork.work_id}`,
|
|
429
554
|
"- stage: code",
|
|
555
|
+
"Before any project edit, change into the immutable write workspace shown below with cd --. Write only that workspace and the named CODE verification artifacts under the stage workspace; never another RUN/native home or Git/worktree control data.",
|
|
430
556
|
"</stage_identity>",
|
|
431
557
|
"",
|
|
432
558
|
"<trusted_runtime_context>",
|
|
@@ -443,17 +569,18 @@ function coordinatorPrompt(context, input) {
|
|
|
443
569
|
"</code_graph>",
|
|
444
570
|
"",
|
|
445
571
|
"<execution_commands>",
|
|
446
|
-
"
|
|
447
|
-
"A quiet child is still running until the harness reports its turn completed, failed, cancelled or explicitly needs attention. An elapsed nominal wait, silence, or no new artifact is not an unresponsive-worker failure. Never interrupt, replace, relaunch, or stage-block a still-running child for that reason, even if an external controller asks. Long work finish and stage finish commands emit check progress on stderr. After you issue the exact CODE stage finish command, wait for that same command to return:
|
|
448
|
-
`A repairable engine, harness, or environment failure is not a user question.
|
|
449
|
-
`When every CODE and repair Work is completed, write ${path.join(input.root, "code-verification.json")} using the exact contract below. Mark passed only when all accepted requirements and current-gate acceptance criteria are implemented or explicitly evidenced; list every remaining issue in unresolved. Every evidence_refs item must already exist as a relative workspace path or run://${input.run.id}/ path. Do not claim a browser or other check receipt that was not retained. Then finish: ${finishCommand(context, input.run.id, input.projectRoot, path.join(input.root, "code-verification.json"))}`,
|
|
450
|
-
"
|
|
572
|
+
"Do not choose a provider delegation tool from this stage prompt. At each work_fanout boundary, stop at the Work-graph boundary; the shared controller supplies the selected adapter's native tool, exact parameters, child task, and wait contract. It launches only entries listed in graph.ready and uses at most the qualified capacity. Every registered CODE Work runs in a fresh child Session, including a serial dependency chain. The coordinator launches those children only through the controller-supplied native delegation instruction; it must never invoke a Work start_command itself. Each child receives its complete packet from dd-flow and runs its own exact start_command. After a Work finishes, the controller uses the graph returned by work finish to launch newly ready Work. To refresh the parent graph yourself use the exact command: " + runtimeCommand(context, ["work", "ls", "--run", input.run.id, "--ready", "--project-root", input.projectRoot, "--json"]),
|
|
573
|
+
"A quiet child is still running until the harness reports its turn completed, failed, cancelled or explicitly needs attention. An elapsed nominal wait, silence, or no new artifact is not an unresponsive-worker failure. Never interrupt, replace, relaunch, or stage-block a still-running child for that reason, even if an external controller asks. Long work finish and stage finish commands emit check progress on stderr. After you issue the exact CODE stage finish command, wait for that same command to return once: a completed command with a non-zero exit and structured `code_gate_failed` output is its terminal result, not a reason to keep waiting. A repair_required continuation already registered the repair: end this Turn. Do not invoke that Work's start_command from the coordinator Session, inspect its PID, start a second finish command, or infer failure from quiet output. Close a disposable child only after its Work is accepted or explicitly failed/cancelled and the harness reports the turn settled.",
|
|
574
|
+
`A repairable engine, harness, or environment failure is not a user question. Write the evidence summary to ${path.join(requireHome(input.run), "works", input.rootWork.work_id, "block-summary.md")}, then record it with a separate command: ${runtimeCommand(context, ["stage", "block", input.run.id, "--stage", "code", "--work", input.rootWork.work_id, "--kind", "<engine|harness|environment>", "--code", "<stable-code>", "--summary-file", `@run/works/${input.rootWork.work_id}/block-summary.md`, "--retryable", "--project-root", input.projectRoot, "--json"])}. Choose kind and stable-code from evidence; this example is not an executable continuation. Repair it externally, then run the exact unblock_command returned by dd-flow and continue this same stage.`,
|
|
575
|
+
`When every CODE and repair Work is completed, write ${path.join(input.root, "code-verification.json")} using the exact contract below. If closing an accepted document depends on aggregate checks that have not run yet, use verdict needs_checks; the first finish returns receipts and a successor finish_command while CODE remains open. After checking those receipts, use needs_repair with document_updates naming only assigned documents that must change, or passed if the current documents already prove acceptance. Mark passed only when all accepted requirements and current-gate acceptance criteria are implemented or explicitly evidenced; list every remaining issue in unresolved. Every evidence_refs item must already exist as a relative workspace path or run://${input.run.id}/ path. Do not claim a browser or other check receipt that was not retained. Then finish: ${finishCommand(context, input.run.id, input.projectRoot, path.join(input.root, "code-verification.json"))}`,
|
|
576
|
+
"A code_gate_failed response with continuation.kind=repair_required has already registered one repair Work with all failed receipts. End this Turn so the controller can dispatch it in a fresh child. Do not recreate the repair, copy origin IDs, write a repair task file or execute the child start command yourself. After repair, update semantic verification and finish again.",
|
|
451
577
|
"</execution_commands>",
|
|
452
578
|
"",
|
|
453
579
|
"<verification_contract>",
|
|
454
580
|
"```json",
|
|
455
|
-
JSON.stringify({ schema_id: "dd-flow/code-verification@
|
|
581
|
+
JSON.stringify({ schema_id: "dd-flow/code-verification@3", verdict: "passed", summary: "Evidence-backed conclusion.", unresolved: [], deviations: [], document_updates: [] }, null, 2),
|
|
456
582
|
"```",
|
|
583
|
+
"Allowed verdict values are passed, needs_checks, needs_repair, and blocked. The example is valid JSON using passed; choose exactly one value. A verification_required result is successful receipt gathering, not Stage completion; use its issued successor command after updating this file.",
|
|
457
584
|
"The CLI verifies graph coverage and executes all deterministic checks. Do not duplicate its report; record only your semantic conclusion and evidence.",
|
|
458
585
|
"</verification_contract>",
|
|
459
586
|
"",
|
|
@@ -466,76 +593,6 @@ function coordinatorPrompt(context, input) {
|
|
|
466
593
|
export function profileCommands(workspaceRoot) {
|
|
467
594
|
return aggregateCheckDeclarations(workspaceRoot).map((check) => check.command);
|
|
468
595
|
}
|
|
469
|
-
function latestReceiptsByCommand(receipts) {
|
|
470
|
-
const latest = new Map();
|
|
471
|
-
for (const receipt of receipts)
|
|
472
|
-
for (const ref of receipt.check_refs)
|
|
473
|
-
latest.set(ref, receipt);
|
|
474
|
-
return [...new Set(latest.values())];
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* A CODE finish may be retried after a client loses the long command's output.
|
|
478
|
-
* Reusing complete, same-workspace receipts is correct; rerunning them is both
|
|
479
|
-
* expensive and can race the still-settling original invocation.
|
|
480
|
-
*/
|
|
481
|
-
export function reusableAggregateGateReceipts(context, input) {
|
|
482
|
-
const expected = new Set(input.checks.map((check) => check.id));
|
|
483
|
-
const current = workspaceFingerprint(input.workspaceRoot);
|
|
484
|
-
const latest = new Map();
|
|
485
|
-
for (const receipt of checkReceipts(context, { projectId: input.projectId, runId: input.runId })) {
|
|
486
|
-
if (receipt.scope === "aggregate")
|
|
487
|
-
for (const ref of receipt.check_refs)
|
|
488
|
-
if (expected.has(ref))
|
|
489
|
-
latest.set(ref, receipt);
|
|
490
|
-
}
|
|
491
|
-
if (latest.size !== expected.size)
|
|
492
|
-
return null;
|
|
493
|
-
const receipts = input.checks.map((check) => latest.get(check.id));
|
|
494
|
-
return receipts.every((receipt) => receipt.status === "passed" && receipt.workspace_fingerprint === current) ? receipts : null;
|
|
495
|
-
}
|
|
496
|
-
/** One aggregate gate per RUN; a second invocation must wait, never duplicate it. */
|
|
497
|
-
function acquireAggregateGateLock(root) {
|
|
498
|
-
const directory = path.join(root, "checks");
|
|
499
|
-
const lock = path.join(directory, ".aggregate-gate.lock");
|
|
500
|
-
fs.mkdirSync(directory, { recursive: true });
|
|
501
|
-
try {
|
|
502
|
-
const descriptor = fs.openSync(lock, "wx");
|
|
503
|
-
fs.writeFileSync(descriptor, JSON.stringify({ pid: process.pid, started_at: new Date().toISOString() }));
|
|
504
|
-
fs.closeSync(descriptor);
|
|
505
|
-
}
|
|
506
|
-
catch (error) {
|
|
507
|
-
if (!isExistingLock(error))
|
|
508
|
-
throw error;
|
|
509
|
-
const activePid = lockPid(lock);
|
|
510
|
-
if (activePid && processAlive(activePid)) {
|
|
511
|
-
throw new AppError("code_gate_in_progress", "CODE aggregate gate is already running; wait for that exact stage finish command to return", 1, { pid: activePid, lock });
|
|
512
|
-
}
|
|
513
|
-
fs.rmSync(lock, { force: true });
|
|
514
|
-
return acquireAggregateGateLock(root);
|
|
515
|
-
}
|
|
516
|
-
return () => fs.rmSync(lock, { force: true });
|
|
517
|
-
}
|
|
518
|
-
function isExistingLock(error) {
|
|
519
|
-
return Boolean(error && typeof error === "object" && error.code === "EEXIST");
|
|
520
|
-
}
|
|
521
|
-
function lockPid(lock) {
|
|
522
|
-
try {
|
|
523
|
-
const parsed = JSON.parse(fs.readFileSync(lock, "utf8"));
|
|
524
|
-
return Number.isInteger(parsed.pid) && Number(parsed.pid) > 0 ? Number(parsed.pid) : null;
|
|
525
|
-
}
|
|
526
|
-
catch {
|
|
527
|
-
return null;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
function processAlive(pid) {
|
|
531
|
-
try {
|
|
532
|
-
process.kill(pid, 0);
|
|
533
|
-
return true;
|
|
534
|
-
}
|
|
535
|
-
catch {
|
|
536
|
-
return false;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
596
|
/**
|
|
540
597
|
* The immutable Work result is a repair history. The stage report is a current
|
|
541
598
|
* acceptance projection, so a registered receipt from an older check epoch
|
|
@@ -552,7 +609,13 @@ export function verificationProjection(works, receipts, options = {}) {
|
|
|
552
609
|
if (item.obligation_ref)
|
|
553
610
|
rawEvidence.set(item.obligation_ref, unique([...(rawEvidence.get(item.obligation_ref) ?? []), ...(item.refs ?? [])]));
|
|
554
611
|
}
|
|
555
|
-
const
|
|
612
|
+
const byCriterionGate = new Map();
|
|
613
|
+
for (const entry of packets.flatMap((value) => value.acceptance)) {
|
|
614
|
+
const key = JSON.stringify([entry.criterion_id, entry.gate]);
|
|
615
|
+
const previous = byCriterionGate.get(key);
|
|
616
|
+
byCriterionGate.set(key, { criterion_id: entry.criterion_id, gate: entry.gate, check_refs: unique([...(previous?.check_refs ?? []), ...entry.check_refs]) });
|
|
617
|
+
}
|
|
618
|
+
const acceptance = [...byCriterionGate.values()];
|
|
556
619
|
const historicalReceiptRefs = new Set((options.historicalReceipts ?? receipts).flatMap((receipt) => receiptReferences(receipt, options)));
|
|
557
620
|
const acceptanceEvidence = new Map(acceptance.map((item) => {
|
|
558
621
|
const reported = rawEvidence.get(item.criterion_id) ?? [];
|
|
@@ -565,18 +628,16 @@ export function verificationProjection(works, receipts, options = {}) {
|
|
|
565
628
|
return [item.criterion_id, { evidenceRefs, historical }];
|
|
566
629
|
}));
|
|
567
630
|
const hasEvidence = (criterionId) => (acceptanceEvidence.get(criterionId)?.evidenceRefs.length ?? 0) > 0;
|
|
568
|
-
const isPassed = (checkId
|
|
631
|
+
const isPassed = (checkId) => receiptByDeclaration.get(checkId)?.status === "passed";
|
|
569
632
|
return {
|
|
570
633
|
checks: declarations.map((check) => {
|
|
571
634
|
const receipt = receiptByDeclaration.get(check.id);
|
|
572
|
-
|
|
573
|
-
return { id: check.id, run_at: check.run_at, status: receipt?.status ?? (externallyEvidenced ? "evidence_recorded" : ["work", "code", "readiness"].includes(check.run_at) ? "failed" : "not_due"), receipt_ref: receipt?.receipt_path ?? null };
|
|
635
|
+
return { id: check.id, run_at: check.run_at, status: receipt?.status ?? (["work", "code", "readiness"].includes(check.run_at) ? "failed" : "not_due"), receipt_ref: receipt?.receipt_path ?? null };
|
|
574
636
|
}),
|
|
575
637
|
acceptance: acceptance.map((item) => {
|
|
576
|
-
const
|
|
577
|
-
const confirmed = item.check_refs.every((id) => isPassed(id, item.criterion_id)) && hasEvidence(item.criterion_id);
|
|
638
|
+
const confirmed = item.check_refs.every((id) => isPassed(id)) && hasEvidence(item.criterion_id);
|
|
578
639
|
const evidence = acceptanceEvidence.get(item.criterion_id) ?? { evidenceRefs: [], historical: [] };
|
|
579
|
-
return { criterion_id: item.criterion_id, gate: item.gate, status: confirmed ?
|
|
640
|
+
return { criterion_id: item.criterion_id, gate: item.gate, status: confirmed ? "confirmed" : ["work", "code", "readiness"].includes(item.gate) ? "unresolved" : "not_due", check_refs: item.check_refs, evidence_refs: evidence.evidenceRefs, ...(evidence.historical.length ? { reported_evidence_refs: evidence.historical } : {}) };
|
|
580
641
|
})
|
|
581
642
|
};
|
|
582
643
|
}
|
|
@@ -646,15 +707,45 @@ function requireRun(context, projectId, runId) {
|
|
|
646
707
|
return run;
|
|
647
708
|
}
|
|
648
709
|
/** CODE, not PROTOCOLIZE, makes a checkout ready for project tooling. */
|
|
649
|
-
|
|
710
|
+
export function isReusablePreparedCodeReadiness(value, expected) {
|
|
711
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
712
|
+
return false;
|
|
713
|
+
const receipt = value;
|
|
714
|
+
return receipt.schema_id === "dd-flow/workspace-readiness@2"
|
|
715
|
+
&& receipt.status === "passed"
|
|
716
|
+
&& receipt.prepared_by === expected.ownerId
|
|
717
|
+
&& receipt.workspace_root === expected.workspaceRoot
|
|
718
|
+
&& receipt.command === expected.command
|
|
719
|
+
&& receipt.policy_ref === expected.policyRef;
|
|
720
|
+
}
|
|
721
|
+
function readPreparedReadiness(file) {
|
|
722
|
+
try {
|
|
723
|
+
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
724
|
+
}
|
|
725
|
+
catch {
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async function ensureCodeWorkspaceReady(context, projectId, run, root, readinessChecks, progress, options = {}) {
|
|
650
730
|
const profile = JSON.parse(run.index_json);
|
|
651
731
|
const bootstrap = profile.execution_profile?.settings?.code_bootstrap;
|
|
652
732
|
if (!bootstrap || typeof bootstrap.command !== "string" || typeof bootstrap.policy_ref !== "string") {
|
|
653
|
-
throw new AppError("execution_profile_invalid", "CODE requires
|
|
733
|
+
throw new AppError("execution_profile_invalid", "CODE requires an evidenced bootstrap command and policy in the frozen RUN profile; configure code_bootstrap before starting a code-ready RUN", 1, { run_id: run.id });
|
|
654
734
|
}
|
|
655
735
|
const receiptPath = path.join(root, "workspace-readiness.json");
|
|
656
|
-
|
|
657
|
-
|
|
736
|
+
const ownerId = context.env.DD_FLOW_CODE_READINESS_OWNER;
|
|
737
|
+
if (!options.force && ownerId && isReusablePreparedCodeReadiness(readPreparedReadiness(receiptPath), {
|
|
738
|
+
ownerId,
|
|
739
|
+
workspaceRoot: run.workspace_root,
|
|
740
|
+
command: bootstrap.command,
|
|
741
|
+
policyRef: bootstrap.policy_ref
|
|
742
|
+
})) {
|
|
743
|
+
progress?.("workspace bootstrap already prepared by this controller");
|
|
744
|
+
return readPreparedReadiness(receiptPath);
|
|
745
|
+
}
|
|
746
|
+
// Unowned and stale receipts are never trusted: a direct stage entry still
|
|
747
|
+
// performs its own readiness check. Only the same controller can hand a
|
|
748
|
+
// freshly prepared workspace to its immediately following lifecycle call.
|
|
658
749
|
const startedAt = new Date().toISOString();
|
|
659
750
|
progress?.(`workspace bootstrap started: ${bootstrap.command}`);
|
|
660
751
|
const result = await runWorkspaceBootstrap(context, { projectId, runId: run.id, runHome: requireHome(run), workspaceRoot: run.workspace_root, command: bootstrap.command, artifactDir: "05-code/readiness", progress });
|
|
@@ -662,7 +753,7 @@ async function ensureCodeWorkspaceReady(context, projectId, run, root, readiness
|
|
|
662
753
|
const checks = bootstrapPassed && readinessChecks.length
|
|
663
754
|
? await runCodeChecks(context, { projectId, runId: run.id, runHome: requireHome(run), workspaceRoot: run.workspace_root, scope: "aggregate", artifactDir: "05-code/readiness", checks: readinessChecks, ...(progress ? { progress } : {}) })
|
|
664
755
|
: [];
|
|
665
|
-
const receipt = { schema_id: "dd-flow/workspace-readiness@2", workspace_root: run.workspace_root, command: bootstrap.command, policy_ref: bootstrap.policy_ref, started_at: startedAt, finished_at: new Date().toISOString(), status: bootstrapPassed && checks.every((check) => check.status === "passed") ? "passed" : "failed", process_id: result.process_id, stdout_path: result.stdout_path, stderr_path: result.stderr_path, completion_path: result.completion_path, exit_code: result.exit_code, stdout: result.stdout, stderr: result.stderr, check_declarations: readinessChecks, checks: checks.map((check) => ({ id: check.id, status: check.status, receipt_path: check.receipt_path })), ...(result.error ? { error: result.error } : {}), receipt_path: receiptPath };
|
|
756
|
+
const receipt = { schema_id: "dd-flow/workspace-readiness@2", workspace_root: run.workspace_root, command: bootstrap.command, policy_ref: bootstrap.policy_ref, started_at: startedAt, finished_at: new Date().toISOString(), status: bootstrapPassed && checks.every((check) => check.status === "passed") ? "passed" : "failed", ...(ownerId ? { prepared_by: ownerId } : {}), process_id: result.process_id, stdout_path: result.stdout_path, stderr_path: result.stderr_path, completion_path: result.completion_path, exit_code: result.exit_code, stdout: result.stdout, stderr: result.stderr, check_declarations: readinessChecks, checks: checks.map((check) => ({ id: check.id, status: check.status, receipt_path: check.receipt_path })), ...(result.error ? { error: result.error } : {}), receipt_path: receiptPath };
|
|
666
757
|
fs.writeFileSync(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
|
|
667
758
|
if (receipt.status !== "passed")
|
|
668
759
|
throw new AppError("workspace_readiness_failed", "CODE workspace bootstrap failed", 1, receipt);
|
|
@@ -674,13 +765,13 @@ function requireHome(run) {
|
|
|
674
765
|
throw new AppError("runtime_missing", "RUN artifact root is unavailable", 1);
|
|
675
766
|
return run.run_root;
|
|
676
767
|
}
|
|
677
|
-
function finishCommand(context, runId, projectRoot, verificationFile) {
|
|
678
|
-
return
|
|
768
|
+
export function finishCommand(context, runId, projectRoot, verificationFile, retryCheckId) {
|
|
769
|
+
return managedLifecycleCommand(context, runtimeCommand(context, ["stage", "finish", runId, "--stage", "code", "--verification-file", verificationFile, "--project-root", projectRoot, "--json", "--progress-jsonl", ...checkRetryArgs(context, projectRoot, runId, retryCheckId)]));
|
|
679
770
|
}
|
|
680
771
|
function readVerification(context, input) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
772
|
+
return prepareJsonSchema(input.file, "CODE verification", {
|
|
773
|
+
schemaName: "code-verification", projectRoot: input.projectRoot, ddFlowHome: context.ddFlowHome, runId: input.runId, runRoot: input.runRoot
|
|
774
|
+
}).value;
|
|
684
775
|
}
|
|
685
776
|
function verificationForFinish(context, input) {
|
|
686
777
|
return readVerification(context, input);
|
|
@@ -737,15 +828,6 @@ function changedPathsFromReport(file) {
|
|
|
737
828
|
return [];
|
|
738
829
|
}
|
|
739
830
|
}
|
|
740
|
-
function resultPaths(result) {
|
|
741
|
-
try {
|
|
742
|
-
const value = JSON.parse(result ?? "");
|
|
743
|
-
return Array.isArray(value.changed_paths) ? value.changed_paths.filter((item) => typeof item === "string") : [];
|
|
744
|
-
}
|
|
745
|
-
catch {
|
|
746
|
-
return [];
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
831
|
function unique(values) {
|
|
750
832
|
return [...new Set(values)];
|
|
751
833
|
}
|
|
@@ -759,6 +841,25 @@ function uniqueBy(values, key) {
|
|
|
759
841
|
return true;
|
|
760
842
|
});
|
|
761
843
|
}
|
|
762
|
-
|
|
763
|
-
|
|
844
|
+
/** Repair pre-atomic terminal stages without repeating accepted checks or rewinding a successor. */
|
|
845
|
+
export function resumeAcceptedCodeStage(context, run, projectRoot, stage, report, next) {
|
|
846
|
+
const index = JSON.parse(run.index_json);
|
|
847
|
+
if ((index.current_stage ?? index.stage_runs.at(-1)?.stage) !== stage)
|
|
848
|
+
return;
|
|
849
|
+
const terminal = next === "code_completed" || next === "code_review_completed";
|
|
850
|
+
if (!terminal && index.next_action === next)
|
|
851
|
+
return;
|
|
852
|
+
withStageSettlement(context, () => {
|
|
853
|
+
if (!terminal) {
|
|
854
|
+
advanceFlowRun(context, { settlementStage: stage, projectRoot, runId: run.id, status: "running", verdict: `${stage.replaceAll("-", "_")}_completed`, nextAction: next });
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
const work = context.db.get("SELECT * FROM works WHERE project_id = ? AND run_id = ? AND parent_work_id IS NULL ORDER BY created_at LIMIT 1", [run.project_id, run.id]);
|
|
858
|
+
if (!work)
|
|
859
|
+
throw new AppError("runtime_missing", "Accepted stage has no root coordinator", 1);
|
|
860
|
+
if (work.status !== "completed")
|
|
861
|
+
finishStageCoordinatorWork(context, work.work_id, JSON.stringify(report, null, 2));
|
|
862
|
+
if (index.status !== "done")
|
|
863
|
+
completeFlowRun(context, { projectRoot, runId: run.id, status: "done", verdict: next });
|
|
864
|
+
});
|
|
764
865
|
}
|