@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
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
5
|
+
import { AppError } from "../shared/errors.js";
|
|
6
|
+
import { ResolvedFlowDescriptor } from "./flow-descriptors.js";
|
|
7
|
+
import { AdmittedFrozenEngine } from "./frozen-engine.js";
|
|
8
|
+
import { FrozenGenericExecution } from "./generic-execution.js";
|
|
9
|
+
import { hybridDigest, validateHybridContract, validateHybridShape } from "./hybrid-contracts.js";
|
|
10
|
+
import { readBoundedReleaseFile } from "./release-source.js";
|
|
11
|
+
import { acquireInstallationLock } from "./installation-lock.js";
|
|
12
|
+
import { projectPacketLocators } from "./stage-context.js";
|
|
13
|
+
const hash = (bytes) => crypto.createHash("sha256").update(bytes).digest("hex");
|
|
14
|
+
const limit = 1024 * 1024;
|
|
15
|
+
function refuse(reason, issues) {
|
|
16
|
+
throw new AppError("execution_bundle_invalid", "Execution bundle cannot be admitted", 1, { reason, phase: "prepare", effect: "no_effect", ...(issues ? { issues } : {}) });
|
|
17
|
+
}
|
|
18
|
+
function json(bytes) {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return refuse("invalid_utf8_json");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function frozen(value) {
|
|
27
|
+
if (value !== null && typeof value === "object") {
|
|
28
|
+
for (const child of Object.values(value))
|
|
29
|
+
frozen(child);
|
|
30
|
+
Object.freeze(value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function directory(file) {
|
|
34
|
+
if (!fs.lstatSync(file).isDirectory())
|
|
35
|
+
refuse("non_regular_bundle_directory");
|
|
36
|
+
}
|
|
37
|
+
function fileIn(root, logical, create = false) {
|
|
38
|
+
const parts = logical.split("/");
|
|
39
|
+
let current = root;
|
|
40
|
+
for (const part of parts.slice(0, -1)) {
|
|
41
|
+
current = path.join(current, part);
|
|
42
|
+
if (create && !fs.existsSync(current))
|
|
43
|
+
fs.mkdirSync(current, { mode: 0o700 });
|
|
44
|
+
directory(current);
|
|
45
|
+
}
|
|
46
|
+
return path.join(current, parts.at(-1));
|
|
47
|
+
}
|
|
48
|
+
/** Retained contract data only. RUN generation, physical ownership and writer admission remain separate. */
|
|
49
|
+
export class RetainedExecutionBundle {
|
|
50
|
+
sha256;
|
|
51
|
+
manifest;
|
|
52
|
+
descriptor;
|
|
53
|
+
execution;
|
|
54
|
+
#bytes;
|
|
55
|
+
#blobs;
|
|
56
|
+
#admission;
|
|
57
|
+
#engine;
|
|
58
|
+
#engineRelocation;
|
|
59
|
+
constructor(bytes, manifest, blobs, admission, descriptor, execution, engineRelocation) {
|
|
60
|
+
frozen(manifest);
|
|
61
|
+
this.manifest = manifest;
|
|
62
|
+
this.sha256 = hash(bytes);
|
|
63
|
+
this.#bytes = bytes;
|
|
64
|
+
this.#blobs = blobs;
|
|
65
|
+
this.#admission = admission;
|
|
66
|
+
this.descriptor = descriptor;
|
|
67
|
+
this.execution = execution;
|
|
68
|
+
this.#engineRelocation = engineRelocation && structuredClone(engineRelocation);
|
|
69
|
+
Object.freeze(this);
|
|
70
|
+
}
|
|
71
|
+
static admit(input, expectedSha256, sourceBlobs, selected, engineRelocation) {
|
|
72
|
+
if (input.byteLength > limit || !/^[a-f0-9]{64}$/.test(expectedSha256))
|
|
73
|
+
refuse("invalid_bundle_identity");
|
|
74
|
+
const bytes = Buffer.from(input);
|
|
75
|
+
if (hash(bytes) !== expectedSha256)
|
|
76
|
+
refuse("manifest_bytes_changed");
|
|
77
|
+
const value = json(bytes), shape = validateHybridShape("execution-bundle", value);
|
|
78
|
+
if (shape.length)
|
|
79
|
+
refuse("invalid_bundle_shape", shape);
|
|
80
|
+
const manifest = value;
|
|
81
|
+
if (manifest.run_id !== selected.runId || selected.executionScope.projectRoot !== selected.bundleProjectRoot)
|
|
82
|
+
refuse("foreign_run_identity");
|
|
83
|
+
const admission = structuredClone(selected);
|
|
84
|
+
const names = manifest.inventory.map(ref => ref.path), folded = new Set();
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
const normalized = name.toLowerCase();
|
|
87
|
+
if (folded.has(normalized) || ["manifest.json", "publication.json"].includes(normalized)
|
|
88
|
+
|| names.some(other => other !== name && other.toLowerCase().startsWith(`${normalized}/`)))
|
|
89
|
+
refuse("conflicting_bundle_path");
|
|
90
|
+
folded.add(normalized);
|
|
91
|
+
}
|
|
92
|
+
const blobs = new Map();
|
|
93
|
+
let total = 0;
|
|
94
|
+
for (const reference of manifest.inventory) {
|
|
95
|
+
const source = sourceBlobs.get(reference.path);
|
|
96
|
+
if (!source || source.byteLength === 0 || source.byteLength > limit || (total += source.byteLength) > 32 * limit)
|
|
97
|
+
refuse("missing_or_unbounded_blob");
|
|
98
|
+
blobs.set(reference.path, Buffer.from(source));
|
|
99
|
+
}
|
|
100
|
+
const context = { ...admission, blobs };
|
|
101
|
+
const issues = validateHybridContract("execution-bundle", manifest, context);
|
|
102
|
+
if (issues.length)
|
|
103
|
+
refuse("invalid_bundle_context", issues);
|
|
104
|
+
if (!admission.descriptorContext)
|
|
105
|
+
refuse("missing_handler_context");
|
|
106
|
+
const descriptor = ResolvedFlowDescriptor.admit(blobs.get(manifest.descriptor.path), manifest.descriptor.sha256, { ...admission.descriptorContext, blobs });
|
|
107
|
+
for (const stage of descriptor.descriptor.stages) {
|
|
108
|
+
try {
|
|
109
|
+
new TextDecoder("utf-8", { fatal: true }).decode(descriptor.stageBlob(stage.id, "instruction"));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
refuse("invalid_instruction_encoding");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const profiles = json(blobs.get(manifest.profile_settings.path));
|
|
116
|
+
const snapshot = { schema_id: "dd-flow/frozen-execution@1", scope: admission.executionScope,
|
|
117
|
+
settings: json(blobs.get(manifest.execution_settings.path)), profiles: profiles.profiles };
|
|
118
|
+
const execution = FrozenGenericExecution.restore(snapshot, hybridDigest(snapshot), descriptor, admission.executionScope, admission.receipts);
|
|
119
|
+
const admitted = new RetainedExecutionBundle(bytes, manifest, blobs, admission, descriptor, execution, engineRelocation);
|
|
120
|
+
admitted.engine();
|
|
121
|
+
return admitted;
|
|
122
|
+
}
|
|
123
|
+
/** Read only the retained inventory. Mutable canon/profile sources are never consulted. */
|
|
124
|
+
static read(root, expectedSha256, admission, engineRelocation) {
|
|
125
|
+
try {
|
|
126
|
+
directory(root);
|
|
127
|
+
const bytes = readBoundedReleaseFile(path.join(root, "manifest.json"), limit);
|
|
128
|
+
if (hash(bytes) !== expectedSha256)
|
|
129
|
+
refuse("manifest_bytes_changed");
|
|
130
|
+
const value = json(bytes), issues = validateHybridShape("execution-bundle", value);
|
|
131
|
+
if (issues.length)
|
|
132
|
+
refuse("invalid_bundle_shape", issues);
|
|
133
|
+
const manifest = value, blobs = new Map();
|
|
134
|
+
for (const ref of manifest.inventory)
|
|
135
|
+
blobs.set(ref.path, readBoundedReleaseFile(fileIn(root, ref.path), limit));
|
|
136
|
+
return RetainedExecutionBundle.admit(bytes, expectedSha256, blobs, admission, engineRelocation);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error instanceof AppError && ["execution_bundle_invalid", "frozen_engine_invalid"].includes(error.code))
|
|
140
|
+
throw error;
|
|
141
|
+
return refuse("retained_bundle_unavailable");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
manifestBytes() { return Buffer.from(this.#bytes); }
|
|
145
|
+
blob(logical) {
|
|
146
|
+
const bytes = this.#blobs.get(logical);
|
|
147
|
+
if (!bytes)
|
|
148
|
+
refuse("unlisted_bundle_blob");
|
|
149
|
+
return Buffer.from(bytes);
|
|
150
|
+
}
|
|
151
|
+
admission() { return structuredClone(this.#admission); }
|
|
152
|
+
engine() {
|
|
153
|
+
// An issued bundle already admitted this exact immutable engine. Fresh
|
|
154
|
+
// read/admit creates a new owner; publication explicitly rechecks below.
|
|
155
|
+
return this.#engine ??= this.#admitEngine();
|
|
156
|
+
}
|
|
157
|
+
#admitEngine() {
|
|
158
|
+
const binding = json(this.blob(this.manifest.engine_binding.path));
|
|
159
|
+
const retainedManifest = this.blob(this.manifest.engine_manifest.path), relocation = this.#engineRelocation;
|
|
160
|
+
if (relocation) {
|
|
161
|
+
const root = JSON.parse(projectPacketLocators(JSON.stringify({ root: binding.engine.snapshot_root }), relocation.relocations)).root;
|
|
162
|
+
if (!relocation.relocations.length || root === binding.engine.snapshot_root || root !== relocation.binding.engine.snapshot_root
|
|
163
|
+
|| relocation.binding.run_id !== this.manifest.run_id)
|
|
164
|
+
refuse("foreign_engine_relocation");
|
|
165
|
+
}
|
|
166
|
+
const engine = relocation
|
|
167
|
+
? AdmittedFrozenEngine.admitRelocation(binding, retainedManifest, this.manifest.engine_manifest.sha256, relocation.binding)
|
|
168
|
+
: AdmittedFrozenEngine.admit(binding, this.manifest.engine_manifest.sha256);
|
|
169
|
+
if (!relocation && !engine.manifestBytes().equals(retainedManifest))
|
|
170
|
+
refuse("engine_manifest_bytes_changed");
|
|
171
|
+
const manifest = engine.manifest(), contracts = new Set(Object.values(manifest.supports_contracts).flat());
|
|
172
|
+
for (const id of ["dd-flow/flow-descriptor@1", "dd-flow/execution-settings@1", "dd-flow/execution-bundle@1"]) {
|
|
173
|
+
if (!contracts.has(id))
|
|
174
|
+
refuse("engine_contract_not_supported");
|
|
175
|
+
}
|
|
176
|
+
for (const reference of this.manifest.bootstrap_receipts) {
|
|
177
|
+
const receipt = json(this.blob(reference.path));
|
|
178
|
+
if (receipt.schema_id !== "dd-flow/memory-bootstrap-receipt@2")
|
|
179
|
+
continue;
|
|
180
|
+
if (!contracts.has(receipt.schema_id))
|
|
181
|
+
refuse("engine_contract_not_supported");
|
|
182
|
+
const entries = manifest.schema_registry.entries.filter(entry => entry.id === receipt.schema_id);
|
|
183
|
+
const entry = entries[0];
|
|
184
|
+
if (entries.length !== 1 || !entry)
|
|
185
|
+
refuse("unregistered_bootstrap_schema");
|
|
186
|
+
try {
|
|
187
|
+
const validate = new Ajv2020({ strict: true, validateFormats: false }).compile(json(engine.schema(entry.name)));
|
|
188
|
+
if (!validate(receipt))
|
|
189
|
+
refuse("invalid_frozen_bootstrap_shape", validate.errors);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (error instanceof AppError)
|
|
193
|
+
throw error;
|
|
194
|
+
refuse("invalid_frozen_bootstrap_schema");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (const stage of this.descriptor.descriptor.stages) {
|
|
198
|
+
const bytes = this.descriptor.stageBlob(stage.id, "result_schema"), schema = json(bytes);
|
|
199
|
+
if (!manifest.schema_registry.entries.some(entry => entry.id === schema.$id && entry.checksum === hash(bytes)))
|
|
200
|
+
refuse("unregistered_stage_schema");
|
|
201
|
+
}
|
|
202
|
+
return engine;
|
|
203
|
+
}
|
|
204
|
+
/** Deterministic publication under the RUN's existing root and immutable engine binding. */
|
|
205
|
+
materialize(runRoot) {
|
|
206
|
+
this.#admitEngine();
|
|
207
|
+
directory(runRoot);
|
|
208
|
+
if (hash(readBoundedReleaseFile(path.join(runRoot, "engine-binding.json"), limit)) !== this.manifest.engine_binding.sha256)
|
|
209
|
+
refuse("run_engine_binding_changed");
|
|
210
|
+
const target = path.join(runRoot, "execution-bundle"), pending = path.join(runRoot, `.execution-bundle.pending-${this.sha256}`);
|
|
211
|
+
const lock = acquireInstallationLock(path.join(runRoot, "execution-bundle.lock"), this.sha256);
|
|
212
|
+
let publicationStarted = false;
|
|
213
|
+
try {
|
|
214
|
+
if (fs.existsSync(target)) {
|
|
215
|
+
RetainedExecutionBundle.read(target, this.sha256, this.#admission);
|
|
216
|
+
return { path: target, sha256: this.sha256, changed: false };
|
|
217
|
+
}
|
|
218
|
+
const owner = Buffer.from(JSON.stringify({ schema_id: "dd-flow/bundle-publication@1", sha256: this.sha256, run_id: this.manifest.run_id }));
|
|
219
|
+
publicationStarted = true;
|
|
220
|
+
if (!fs.existsSync(pending)) {
|
|
221
|
+
fs.mkdirSync(pending, { mode: 0o700 });
|
|
222
|
+
fs.writeFileSync(path.join(pending, "publication.json"), owner, { flag: "wx", mode: 0o600 });
|
|
223
|
+
}
|
|
224
|
+
directory(pending);
|
|
225
|
+
if (!readBoundedReleaseFile(path.join(pending, "publication.json"), limit).equals(owner))
|
|
226
|
+
refuse("foreign_pending_publication");
|
|
227
|
+
const write = (logical, bytes) => {
|
|
228
|
+
const file = fileIn(pending, logical, true);
|
|
229
|
+
if (fs.existsSync(file)) {
|
|
230
|
+
if (!readBoundedReleaseFile(file, limit).equals(bytes))
|
|
231
|
+
refuse("retained_blob_changed");
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const temporary = path.join(pending, `.write-${hash(Buffer.from(logical))}.tmp`);
|
|
235
|
+
if (fs.existsSync(temporary)) {
|
|
236
|
+
const stat = fs.lstatSync(temporary);
|
|
237
|
+
if (!stat.isFile() || stat.nlink !== 1)
|
|
238
|
+
refuse("foreign_pending_write");
|
|
239
|
+
fs.unlinkSync(temporary);
|
|
240
|
+
}
|
|
241
|
+
// This temporary is owned by the exact publication receipt and lock.
|
|
242
|
+
// A crashed partial write is deterministic; no productive operation is retried.
|
|
243
|
+
const fd = fs.openSync(temporary, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW ?? 0), 0o600);
|
|
244
|
+
try {
|
|
245
|
+
fs.writeFileSync(fd, bytes);
|
|
246
|
+
fs.fsyncSync(fd);
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
fs.closeSync(fd);
|
|
250
|
+
}
|
|
251
|
+
fs.renameSync(temporary, file);
|
|
252
|
+
};
|
|
253
|
+
for (const [logical, bytes] of this.#blobs)
|
|
254
|
+
write(logical, bytes);
|
|
255
|
+
write("manifest.json", this.#bytes);
|
|
256
|
+
RetainedExecutionBundle.read(pending, this.sha256, this.#admission);
|
|
257
|
+
if (fs.existsSync(target))
|
|
258
|
+
refuse("concurrent_bundle_publication");
|
|
259
|
+
fs.renameSync(pending, target);
|
|
260
|
+
return { path: target, sha256: this.sha256, changed: true };
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
if (!publicationStarted)
|
|
264
|
+
throw error;
|
|
265
|
+
throw new AppError("execution_bundle_publication_failed", "Execution bundle publication requires recovery", 1, {
|
|
266
|
+
phase: "publication", effect: "partial", run_id: this.manifest.run_id,
|
|
267
|
+
sha256: this.sha256, pending_path: pending,
|
|
268
|
+
reason: error instanceof AppError ? error.code : "publication_io_failure",
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
lock.release();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { AppError } from "../shared/errors.js";
|
|
5
|
+
import { harnessKey } from "./harness-config.js";
|
|
6
|
+
import { vnextStages } from "../domain/stage-catalog.js";
|
|
7
|
+
import { prepareFileBytes, prepareJsonText } from "../cli/input-preparation.js";
|
|
8
|
+
import { operatorSettingsPath, readOperatorProfiles, readOperatorProfileInput, resolveOperatorProfile } from "./operator-profiles.js";
|
|
9
|
+
import { selectOnboardingExecutor } from "./executor-onboarding.js";
|
|
10
|
+
/** Read once so the frozen policy and its provenance describe the same bytes. */
|
|
11
|
+
export function loadExecutionRoutingInput(file) {
|
|
12
|
+
const { file: source_path, bytes } = prepareFileBytes(file, "execution routing");
|
|
13
|
+
const value = prepareJsonText(bytes.toString("utf8"), { file: source_path, label: "execution routing" }).value;
|
|
14
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
15
|
+
throw new AppError("execution_profile_invalid", "Execution routing input must be an object", 2, { source_path, phase: "prepare", effect: "no_effect", recoverable: true });
|
|
16
|
+
}
|
|
17
|
+
const input = value;
|
|
18
|
+
if (input.schema_id !== "dd-flow/execution-routing@1"
|
|
19
|
+
|| Object.keys(input).some(key => key !== "schema_id" && key !== "execution")
|
|
20
|
+
|| !isExecutionRouting(input.execution)) {
|
|
21
|
+
throw new AppError("execution_profile_invalid", "Execution routing input does not match dd-flow/execution-routing@1", 2, { source_path, phase: "prepare", effect: "no_effect", recoverable: true });
|
|
22
|
+
}
|
|
23
|
+
return { execution: input.execution, bytes, source_path, source_checksum: crypto.createHash("sha256").update(bytes).digest("hex") };
|
|
24
|
+
}
|
|
25
|
+
/** One routing validator for project defaults and explicit RUN inputs. */
|
|
26
|
+
export function isExecutionRouting(value) {
|
|
27
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
28
|
+
return false;
|
|
29
|
+
const { stage_overrides: stages, ...root } = value;
|
|
30
|
+
if (typeof root.agent_profile_id !== "string")
|
|
31
|
+
return false;
|
|
32
|
+
try {
|
|
33
|
+
validateExecutionOverride(root);
|
|
34
|
+
if (stages !== undefined) {
|
|
35
|
+
if (!stages || typeof stages !== "object" || Array.isArray(stages))
|
|
36
|
+
return false;
|
|
37
|
+
for (const [stage, override] of Object.entries(stages)) {
|
|
38
|
+
if (!vnextStages.some(item => item.id === stage))
|
|
39
|
+
return false;
|
|
40
|
+
validateExecutionOverride(override);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Reads one complete profile. A policy selects profiles; it never field-merges them. */
|
|
50
|
+
export function loadAgentProfile(ddFlowHome, id) {
|
|
51
|
+
if (typeof id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id))
|
|
52
|
+
throw new AppError("agent_profile_invalid", "Agent profile id is invalid", 2, { id });
|
|
53
|
+
if (fs.existsSync(operatorSettingsPath(ddFlowHome)))
|
|
54
|
+
return resolveOperatorProfile(readOperatorProfiles(ddFlowHome), id);
|
|
55
|
+
const file = path.join(ddFlowHome, "agent-profiles", `${id}.json`);
|
|
56
|
+
if (!fs.existsSync(file))
|
|
57
|
+
throw new AppError("agent_profile_missing", "Agent profile is unavailable", 1, { id });
|
|
58
|
+
let profile;
|
|
59
|
+
try {
|
|
60
|
+
profile = readOperatorProfileInput(file);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new AppError("agent_profile_invalid", "Agent profile must be a bounded valid regular JSON file", 2, { id });
|
|
64
|
+
}
|
|
65
|
+
if (profile.id !== id) {
|
|
66
|
+
throw new AppError("agent_profile_invalid", "Agent profile does not match its selected ID", 2, { id });
|
|
67
|
+
}
|
|
68
|
+
// Only execution settings enter RUN evidence; never copy arbitrary profile fields.
|
|
69
|
+
return { schema_id: profile.schema_id, id, harness: profile.harness, provider: profile.provider, model: profile.model, reasoning: profile.reasoning, mode: profile.mode, permission: profile.permission };
|
|
70
|
+
}
|
|
71
|
+
export function snapshotAgentProfiles(ddFlowHome, policy) {
|
|
72
|
+
if (!isExecutionRouting(policy))
|
|
73
|
+
throw new AppError("execution_profile_invalid", "Execution routing contains an invalid stage, profile or delegation policy", 2);
|
|
74
|
+
const profiles = Object.create(null);
|
|
75
|
+
const settings = fs.existsSync(operatorSettingsPath(ddFlowHome)) ? readOperatorProfiles(ddFlowHome) : undefined;
|
|
76
|
+
for (const override of [policy, ...Object.values(policy.stage_overrides ?? {})]) {
|
|
77
|
+
for (const id of [override.agent_profile_id, override.delegation?.agent_profile_id]) {
|
|
78
|
+
if (id !== undefined && !Object.hasOwn(profiles, id)) {
|
|
79
|
+
const profile = settings ? selectOnboardingExecutor({}, () => settings, { allowSkip: false, projectProfileId: id }).profile : loadAgentProfile(ddFlowHome, id);
|
|
80
|
+
profiles[id] = profile;
|
|
81
|
+
// Routing labels may be aliases. Default worker resolution uses the
|
|
82
|
+
// complete coordinator's canonical ID, which must also be frozen.
|
|
83
|
+
profiles[profile.id] = profile;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Validate every declared route now, including stages not reached by this run.
|
|
88
|
+
for (const stage of [undefined, ...Object.keys(policy.stage_overrides ?? {})]) {
|
|
89
|
+
resolveExecutionPolicy({ ddFlowHome, policy, profiles, ...(stage ? { stage } : {}) });
|
|
90
|
+
}
|
|
91
|
+
return profiles;
|
|
92
|
+
}
|
|
93
|
+
/** Resolves a frozen policy with explicit topology. Same profiles do not turn external work into native work. */
|
|
94
|
+
export function resolveExecutionPolicy(input) {
|
|
95
|
+
if (input.work !== undefined)
|
|
96
|
+
validateExecutionOverride(input.work);
|
|
97
|
+
const profile = (id) => {
|
|
98
|
+
if (!input.profiles)
|
|
99
|
+
return loadAgentProfile(input.ddFlowHome, id);
|
|
100
|
+
if (!Object.hasOwn(input.profiles, id))
|
|
101
|
+
throw new AppError("execution_profile_not_frozen", "Profile is not in this RUN's frozen execution snapshot", 1, { id });
|
|
102
|
+
return input.profiles[id];
|
|
103
|
+
};
|
|
104
|
+
const stage = input.stage ? input.policy.stage_overrides?.[input.stage] : undefined;
|
|
105
|
+
const coordinatorId = stage?.agent_profile_id ?? input.policy.agent_profile_id;
|
|
106
|
+
if (!coordinatorId)
|
|
107
|
+
throw new AppError("execution_profile_missing", "Execution policy needs agent_profile_id before external dispatch", 1, { stage: input.stage ?? null });
|
|
108
|
+
const coordinator = profile(coordinatorId);
|
|
109
|
+
const delegation = input.work?.delegation ?? stage?.delegation ?? input.policy.delegation ?? { mode: "native" };
|
|
110
|
+
validateDelegation(delegation);
|
|
111
|
+
if (input.work?.agent_profile_id && input.work.delegation?.agent_profile_id && input.work.agent_profile_id !== input.work.delegation.agent_profile_id)
|
|
112
|
+
throw new AppError("execution_profile_invalid", "Work selects conflicting worker profiles", 2);
|
|
113
|
+
const worker = profile(input.work?.agent_profile_id ?? delegation.agent_profile_id ?? coordinator.id);
|
|
114
|
+
if (delegation.mode === "native" && harnessKey(worker.harness) !== harnessKey(coordinator.harness)) {
|
|
115
|
+
throw new AppError("native_harness_mismatch", "Native delegation cannot change harness", 2, { coordinator_harness: coordinator.harness, worker_harness: worker.harness });
|
|
116
|
+
}
|
|
117
|
+
if (delegation.mode === "native" && !sameSessionProfile(coordinator, worker))
|
|
118
|
+
throw new AppError("native_profile_override_unqualified", "Native worker profile overrides require qualified adapter support; select external delegation", 2, { coordinator_profile_id: coordinator.id, worker_profile_id: worker.id });
|
|
119
|
+
const resolved = {
|
|
120
|
+
coordinator,
|
|
121
|
+
worker,
|
|
122
|
+
delegation: { mode: delegation.mode, max_parallel: delegation.mode === "external" ? delegation.max_parallel ?? 1 : null }
|
|
123
|
+
};
|
|
124
|
+
return { ...resolved, profile_hash: digest(resolved) };
|
|
125
|
+
}
|
|
126
|
+
export function runtimeHarness(profile) { return harnessKey(profile.harness); }
|
|
127
|
+
/** Profile labels are not execution identity; every session-affecting value is. */
|
|
128
|
+
export function sameSessionProfile(left, right) {
|
|
129
|
+
const settings = (profile) => ({ harness: runtimeHarness(profile), provider: profile.provider, model: profile.model, reasoning: profile.reasoning, mode: profile.mode, permission: profile.permission });
|
|
130
|
+
return digest(settings(left)) === digest(settings(right));
|
|
131
|
+
}
|
|
132
|
+
export function assertSameSessionMerge(input) {
|
|
133
|
+
const merge = resolveExecutionPolicy({ ...input, stage: "merge" }).coordinator;
|
|
134
|
+
for (const stage of input.previousStages) {
|
|
135
|
+
const previous = resolveExecutionPolicy({ ...input, stage }).coordinator;
|
|
136
|
+
if (!sameSessionProfile(previous, merge))
|
|
137
|
+
throw new AppError("merge_profile_session_conflict", "Same-session MERGE cannot switch execution profiles; select a compatible profile or server MERGE", 2, { previous_stage: stage, previous_profile_id: previous.id, merge_profile_id: merge.id });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** The RUN identity root and a native Session's fixed launch directory are distinct. */
|
|
141
|
+
export function stageExecutionCwd(input) {
|
|
142
|
+
return path.resolve(input.stage === "specify" || input.stage === "protocolize" ? input.projectRoot
|
|
143
|
+
: input.stage === "merge" ? input.mergeTargetWorkspace ?? input.projectRoot
|
|
144
|
+
: input.workspaceRoot);
|
|
145
|
+
}
|
|
146
|
+
export function resolveStageTransition(input) {
|
|
147
|
+
const target = resolveExecutionPolicy(input);
|
|
148
|
+
const previous = input.fromStage ? resolveExecutionPolicy({ ...input, stage: input.fromStage }).coordinator : null;
|
|
149
|
+
const compatible = !previous || sameSessionProfile(previous, target.coordinator);
|
|
150
|
+
const previousCwd = input.fromStage ? stageExecutionCwd({ ...input, stage: input.fromStage }) : null;
|
|
151
|
+
const targetCwd = stageExecutionCwd(input);
|
|
152
|
+
const sameWorkspace = previousCwd === null || previousCwd === targetCwd;
|
|
153
|
+
if (input.stage === "merge" && input.mergeMode === "same_session") {
|
|
154
|
+
if (!compatible)
|
|
155
|
+
throw new AppError("merge_profile_session_conflict", "Same-session MERGE cannot replace its current coordinator", 2);
|
|
156
|
+
if (!sameWorkspace)
|
|
157
|
+
throw new AppError("merge_session_workspace_conflict", "Same-session MERGE cannot change the native coordinator workspace", 2, { source_workspace: previousCwd, target_workspace: targetCwd });
|
|
158
|
+
return { ...target, session_mode: "same_session" };
|
|
159
|
+
}
|
|
160
|
+
return { ...target, session_mode: !compatible || !sameWorkspace || (input.stage === "merge" && input.mergeMode === "server") ? "new_session" : input.stageSessionMode };
|
|
161
|
+
}
|
|
162
|
+
function validateDelegation(value) {
|
|
163
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some(key => !["mode", "agent_profile_id", "max_parallel"].includes(key)))
|
|
164
|
+
throw new AppError("execution_profile_invalid", "Delegation has unsupported fields", 2);
|
|
165
|
+
if (value.mode !== "native" && value.mode !== "external")
|
|
166
|
+
throw new AppError("execution_profile_invalid", "Delegation mode must be native or external", 2);
|
|
167
|
+
if (value.agent_profile_id !== undefined && (typeof value.agent_profile_id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(value.agent_profile_id)))
|
|
168
|
+
throw new AppError("execution_profile_invalid", "Delegation profile id is invalid", 2);
|
|
169
|
+
if (value.max_parallel !== undefined && (!Number.isInteger(value.max_parallel) || value.max_parallel < 1))
|
|
170
|
+
throw new AppError("execution_profile_invalid", "External max_parallel must be a positive integer", 2);
|
|
171
|
+
if (value.mode === "native" && value.max_parallel !== undefined)
|
|
172
|
+
throw new AppError("execution_profile_invalid", "Native delegation does not accept max_parallel", 2);
|
|
173
|
+
}
|
|
174
|
+
export function validateExecutionOverride(value) {
|
|
175
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some(key => !["agent_profile_id", "delegation"].includes(key)))
|
|
176
|
+
throw new AppError("execution_profile_invalid", "Work execution override has unsupported fields", 2);
|
|
177
|
+
const override = value;
|
|
178
|
+
if (override.agent_profile_id === undefined && override.delegation === undefined)
|
|
179
|
+
throw new AppError("execution_profile_invalid", "Work execution override is empty", 2);
|
|
180
|
+
if (override.agent_profile_id !== undefined && (typeof override.agent_profile_id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(override.agent_profile_id)))
|
|
181
|
+
throw new AppError("execution_profile_invalid", "Work profile id is invalid", 2);
|
|
182
|
+
if (override.delegation !== undefined)
|
|
183
|
+
validateDelegation(override.delegation);
|
|
184
|
+
}
|
|
185
|
+
function digest(value) { return crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex"); }
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AppError } from "../shared/errors.js";
|
|
2
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
3
|
+
import { prepareOperatorProfile, readOperatorProfileInput, resolveOperatorProfile, validateProfileCreationIntent } from "./operator-profiles.js";
|
|
4
|
+
function refuse(code, message, exitCode = 2) {
|
|
5
|
+
throw new AppError(code, message, exitCode, { phase: "executor_onboarding", effect: "no_effect", help: "profiles" });
|
|
6
|
+
}
|
|
7
|
+
/** Shared setup/first-flow admission; settings are read lazily, never written. */
|
|
8
|
+
export function selectOnboardingExecutor(choice, readSettings, policy) {
|
|
9
|
+
if (!choice || typeof choice !== "object" || Array.isArray(choice)
|
|
10
|
+
|| Object.keys(choice).some(key => !["profileId", "profile", "profileFile", "skip", "profileCreation"].includes(key))
|
|
11
|
+
|| choice.profileFile !== undefined && (typeof choice.profileFile !== "string" || !choice.profileFile.trim())
|
|
12
|
+
|| choice.skip !== undefined && typeof choice.skip !== "boolean"
|
|
13
|
+
|| choice.profileId !== undefined && (typeof choice.profileId !== "string" || !choice.profileId.trim())) {
|
|
14
|
+
refuse("usage", "Invalid executor selection");
|
|
15
|
+
}
|
|
16
|
+
if ([choice.profileId !== undefined, choice.profile !== undefined, choice.profileFile !== undefined, choice.skip === true].filter(Boolean).length > 1) {
|
|
17
|
+
refuse("usage", "Executor profile, profile ID and skip are mutually exclusive");
|
|
18
|
+
}
|
|
19
|
+
if (choice.profileCreation !== undefined) {
|
|
20
|
+
validateProfileCreationIntent(choice.profileCreation);
|
|
21
|
+
if (choice.profile === undefined || hybridDigest(choice.profile) !== hybridDigest(choice.profileCreation.profile))
|
|
22
|
+
refuse("usage", "Profile save intent requires its exact explicit profile");
|
|
23
|
+
}
|
|
24
|
+
if (choice.skip) {
|
|
25
|
+
if (!policy.allowSkip)
|
|
26
|
+
refuse("agent_profile_missing", "This operation requires an executor profile", 1);
|
|
27
|
+
return { profile: null, revision: null, source: "skip" };
|
|
28
|
+
}
|
|
29
|
+
const explicit = choice.profile !== undefined || choice.profileFile !== undefined || choice.profileId !== undefined;
|
|
30
|
+
if (!explicit && policy.projectProfileId !== undefined && (typeof policy.projectProfileId !== "string" || !policy.projectProfileId.trim())) {
|
|
31
|
+
refuse("usage", "Invalid project executor profile selection");
|
|
32
|
+
}
|
|
33
|
+
const profile = prepareOperatorProfile(choice.profile !== undefined ? choice.profile : choice.profileFile !== undefined
|
|
34
|
+
? readOperatorProfileInput(choice.profileFile) : resolveOperatorProfile(readSettings(), choice.profileId ?? policy.projectProfileId));
|
|
35
|
+
return { profile: structuredClone(profile), revision: hybridDigest(profile),
|
|
36
|
+
...(choice.profileCreation ? { profileCreation: structuredClone(choice.profileCreation) } : {}),
|
|
37
|
+
source: choice.profile !== undefined ? "explicit-profile" : choice.profileFile !== undefined ? "explicit-file" : choice.profileId !== undefined ? "explicit-id" : policy.projectProfileId !== undefined ? "project-default" : "default" };
|
|
38
|
+
}
|
|
39
|
+
/** Interactive decisions use exactly the same admission as headless choices. */
|
|
40
|
+
export async function onboardExecutor(choice, readSettings, policy, ask) {
|
|
41
|
+
try {
|
|
42
|
+
return selectOnboardingExecutor(choice, readSettings, policy);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (!(error instanceof AppError) || error.code !== "agent_profile_missing"
|
|
46
|
+
|| choice.profileId !== undefined || choice.profile !== undefined || choice.profileFile !== undefined || choice.skip === true
|
|
47
|
+
|| policy.projectProfileId !== undefined || policy.nonInteractive || !ask)
|
|
48
|
+
throw error;
|
|
49
|
+
// No speculative defaults or writes: the human supplies a concrete choice.
|
|
50
|
+
const decision = await ask(structuredClone(readSettings()));
|
|
51
|
+
if (decision.profileId === undefined && decision.profile === undefined && decision.profileFile === undefined && decision.skip !== true) {
|
|
52
|
+
refuse("agent_profile_missing", "Onboarding requires an explicit choice", 1);
|
|
53
|
+
}
|
|
54
|
+
return selectOnboardingExecutor(decision, readSettings, policy);
|
|
55
|
+
}
|
|
56
|
+
}
|