@deksden-com/dd-flow-cli 0.9.0-beta.16 → 0.9.0-beta.161
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 +965 -0
- package/README.md +139 -10
- package/dist/build-info.json +8 -8
- package/dist/cli/argument-values.js +38 -0
- package/dist/cli/command-inputs.js +417 -0
- package/dist/cli/command-metadata.js +303 -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/delivery.js +108 -0
- package/dist/cli/diagnostic-invocation.js +62 -0
- package/dist/cli/diagnostic.js +131 -0
- package/dist/cli/error-output.js +62 -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 +521 -19
- package/dist/cli/hook-ingress.js +89 -0
- package/dist/cli/input-preparation.js +193 -0
- package/dist/cli/interactive-invocation.js +33 -0
- package/dist/cli/interactive.js +114 -0
- package/dist/cli/memory-fix-invocation.js +52 -0
- package/dist/cli/memory-fix.js +100 -0
- package/dist/cli/memory-flow-admission.js +54 -0
- package/dist/cli/memory-init-invocation.js +85 -0
- package/dist/cli/memory-init.js +250 -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 +94 -0
- package/dist/cli/native-hook-preparation.js +82 -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 +2020 -555
- 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 +103 -2
- package/dist/domain/delivery-flows.js +8 -0
- package/dist/domain/diagnostic-aspects.js +103 -0
- package/dist/domain/diagnostic-flows.js +8 -0
- package/dist/domain/distill-flow.js +20 -0
- package/dist/domain/interactive-flow.js +1 -0
- package/dist/domain/memory-fix-flow.js +2 -0
- package/dist/domain/review-fix-flow.js +2 -0
- package/dist/domain/source-snapshot-flows.js +4 -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 +71 -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 +50 -0
- package/dist/harness-runtime/bin/dd-opencode.mjs +22 -0
- package/dist/harness-runtime/bin/dd-zcode.mjs +95 -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 +87 -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 +225 -0
- package/dist/harness-runtime/lib/agy-native-inventory.mjs +19 -0
- package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
- package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +74 -0
- package/dist/harness-runtime/lib/agy-transcript-stream.mjs +54 -0
- package/dist/harness-runtime/lib/daemon-observation.d.mts +3 -0
- package/dist/harness-runtime/lib/daemon-observation.mjs +171 -0
- package/dist/harness-runtime/lib/daemon-operations.d.mts +2 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +512 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.d.mts +7 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +1362 -0
- package/dist/harness-runtime/lib/dd-agy.mjs +105 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +271 -0
- package/dist/harness-runtime/lib/dd-codex.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-codex.mjs +986 -0
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +155 -0
- package/dist/harness-runtime/lib/dd-droid.mjs +739 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +667 -0
- package/dist/harness-runtime/lib/dd-grok.mjs +182 -0
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +772 -0
- package/dist/harness-runtime/lib/dd-opencode.mjs +411 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.d.mts +1 -0
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +845 -0
- package/dist/harness-runtime/lib/dd-zcode.mjs +1239 -0
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +16 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +179 -0
- package/dist/harness-runtime/lib/delivery-command.mjs +84 -0
- package/dist/harness-runtime/lib/dispatch-fence.mjs +14 -0
- package/dist/harness-runtime/lib/driver-recovery.mjs +121 -0
- package/dist/harness-runtime/lib/droid-observation.mjs +70 -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 +11 -0
- package/dist/harness-runtime/lib/lifecycle-contract.mjs +20 -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 +113 -0
- package/dist/harness-runtime/lib/native-children.d.mts +34 -0
- package/dist/harness-runtime/lib/native-children.mjs +265 -0
- package/dist/harness-runtime/lib/native-hook-command.d.mts +8 -0
- package/dist/harness-runtime/lib/native-hook-command.mjs +306 -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 +38 -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 +112 -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 +140 -0
- package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
- package/dist/harness-runtime/lib/operation-progress.mjs +118 -0
- package/dist/harness-runtime/lib/process-json.d.mts +5 -0
- package/dist/harness-runtime/lib/process-json.mjs +200 -0
- package/dist/harness-runtime/lib/process-snapshot.mjs +10 -0
- package/dist/harness-runtime/lib/provider-overload-policy.d.mts +23 -0
- package/dist/harness-runtime/lib/provider-overload-policy.mjs +242 -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 +238 -0
- package/dist/harness-runtime/lib/zcode-native-hook-ownership.mjs +109 -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/code-work-result.schema.json +2 -1
- package/dist/schemas/delivery-stage-result.schema.json +286 -0
- 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/distill-stage-result.schema.json +667 -0
- package/dist/schemas/distill-work-result.schema.json +428 -0
- package/dist/schemas/execution-bundle.schema.json +215 -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/interactive-stage-result.schema.json +47 -0
- package/dist/schemas/interactive-work-result.schema.json +63 -0
- package/dist/schemas/mb-fix-stage-result.schema.json +93 -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 +2 -2
- package/dist/schemas/release-impact.schema.json +3 -3
- package/dist/schemas/release-manifest.schema.json +291 -0
- package/dist/schemas/review-fix-stage-result.schema.json +210 -0
- package/dist/schemas/run-control-receipt.schema.json +119 -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 +3 -3
- package/dist/services/accepted-intent.js +139 -0
- package/dist/services/assigned-lifecycle.js +382 -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 +344 -0
- package/dist/services/check-runner-proof.js +373 -0
- package/dist/services/cleanup.js +133 -40
- package/dist/services/cli-operation-classifier.js +32 -64
- package/dist/services/cli-upgrade-allowlist.js +27 -0
- package/dist/services/code-checks.js +1426 -121
- package/dist/services/codex-capacity.js +367 -0
- package/dist/services/codex-hook-delivery.js +41 -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 +25 -0
- package/dist/services/controller-child-capacity.js +71 -0
- package/dist/services/controller-child-observer.js +121 -0
- package/dist/services/controller-child-repair.js +117 -0
- package/dist/services/controller-execution.js +97 -0
- package/dist/services/controller-fanout.js +277 -0
- package/dist/services/controller-memory-task.js +45 -0
- package/dist/services/controller-memory-worker.js +51 -0
- package/dist/services/controller-result-authority.js +127 -0
- package/dist/services/controller-work-failure.js +198 -0
- package/dist/services/dashboard.js +145 -58
- package/dist/services/delivery-access.js +123 -0
- package/dist/services/delivery-approval.js +68 -0
- package/dist/services/delivery-artifact.js +86 -0
- package/dist/services/delivery-checks.js +178 -0
- package/dist/services/delivery-execution.js +181 -0
- package/dist/services/delivery-intents.js +212 -0
- package/dist/services/delivery-operation.js +81 -0
- package/dist/services/delivery-policy.js +91 -0
- package/dist/services/delivery-procedures.js +43 -0
- package/dist/services/delivery-request.js +99 -0
- package/dist/services/delivery-result.js +144 -0
- package/dist/services/delivery-stage-commands.js +26 -0
- package/dist/services/delivery-stage-entry.js +56 -0
- package/dist/services/delivery-stage-handlers.js +135 -0
- package/dist/services/delivery-stage-results.js +94 -0
- package/dist/services/descriptor-coordinator-session.js +37 -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 +495 -0
- package/dist/services/descriptor-stage-coordinator.js +318 -0
- package/dist/services/descriptor-stage-settlement.js +268 -0
- package/dist/services/descriptor-stage-start.js +175 -0
- package/dist/services/diagnostic-evidence.js +73 -0
- package/dist/services/diagnostic-repair-intake.js +123 -0
- package/dist/services/diagnostic-repair-source-intake.js +102 -0
- package/dist/services/diagnostic-report-publication.js +72 -0
- package/dist/services/diagnostic-report.js +97 -0
- package/dist/services/diagnostic-run-bundle.js +113 -0
- package/dist/services/diagnostic-snapshot.js +159 -0
- package/dist/services/diagnostic-stage-handlers.js +109 -0
- package/dist/services/diagnostic-stage-results.js +158 -0
- package/dist/services/diagnostic-start.js +134 -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/distill-document-publication.js +280 -0
- package/dist/services/distill-promotion.js +197 -0
- package/dist/services/distill-publication-custody.js +162 -0
- package/dist/services/distill-stage-handlers.js +249 -0
- package/dist/services/distill-stage-results.js +105 -0
- package/dist/services/distill-user-inputs.js +4 -0
- package/dist/services/distill-work-batch.js +42 -0
- package/dist/services/distill-work-collection.js +74 -0
- package/dist/services/distill-work-registration.js +93 -0
- package/dist/services/distill-work-results.js +98 -0
- package/dist/services/engines.js +354 -163
- package/dist/services/eval-snapshots.js +1326 -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 +316 -0
- package/dist/services/flow-catalog.js +54 -0
- package/dist/services/flow-descriptors.js +82 -0
- package/dist/services/frozen-engine.js +404 -0
- package/dist/services/generic-execution.js +165 -0
- package/dist/services/harness-adapter.js +342 -35
- 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 +813 -327
- package/dist/services/hybrid-contracts.js +479 -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 +261 -0
- package/dist/services/interactive-attached-session.js +215 -0
- package/dist/services/interactive-baseline-custody.js +54 -0
- package/dist/services/interactive-before-versions.js +148 -0
- package/dist/services/interactive-bundle-data.js +85 -0
- package/dist/services/interactive-checks.js +179 -0
- package/dist/services/interactive-execution.js +33 -0
- package/dist/services/interactive-finish-integration.js +236 -0
- package/dist/services/interactive-git-baseline.js +230 -0
- package/dist/services/interactive-git-dispatch.js +278 -0
- package/dist/services/interactive-input-delivery.js +82 -0
- package/dist/services/interactive-mutation-scope.js +231 -0
- package/dist/services/interactive-request.js +287 -0
- package/dist/services/interactive-run-bundle.js +109 -0
- package/dist/services/interactive-stage-entry.js +41 -0
- package/dist/services/interactive-stage-handlers.js +289 -0
- package/dist/services/interactive-stage-observation.js +136 -0
- package/dist/services/interactive-stage-results.js +111 -0
- package/dist/services/interactive-user-inputs.js +142 -0
- package/dist/services/interactive-work-batch.js +43 -0
- package/dist/services/interactive-work-collection.js +119 -0
- package/dist/services/interactive-work-completion.js +180 -0
- package/dist/services/interactive-work-context.js +249 -0
- package/dist/services/interactive-work-history.js +112 -0
- package/dist/services/interactive-work-registration.js +124 -0
- package/dist/services/interactive-work-results.js +115 -0
- package/dist/services/interactive-work-start.js +155 -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 +2549 -0
- package/dist/services/managed-daemon-binding.js +129 -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 +380 -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 +491 -0
- package/dist/services/memory-finish-readiness.js +169 -0
- package/dist/services/memory-fix-finish-integration.js +129 -0
- package/dist/services/memory-fix-git-dispatch.js +139 -0
- package/dist/services/memory-fix-intake-custody.js +11 -0
- package/dist/services/memory-fix-intake-settlement.js +127 -0
- package/dist/services/memory-fix-publication.js +196 -0
- package/dist/services/memory-fix-repair-admission.js +116 -0
- package/dist/services/memory-fix-request.js +141 -0
- package/dist/services/memory-fix-run-bundle.js +83 -0
- package/dist/services/memory-fix-scope.js +78 -0
- package/dist/services/memory-fix-sources.js +85 -0
- package/dist/services/memory-fix-stage-entry.js +24 -0
- package/dist/services/memory-fix-stage-handlers.js +282 -0
- package/dist/services/memory-fix-stage-results.js +106 -0
- package/dist/services/memory-fix-workspace.js +127 -0
- package/dist/services/memory-flow-user-inputs.js +88 -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 +181 -0
- package/dist/services/memory-init-controller-start.js +119 -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 +225 -0
- package/dist/services/memory-lint-config.js +194 -0
- package/dist/services/memory-native-review-copy.js +127 -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 +489 -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-flow-source.js +195 -0
- package/dist/services/project-git-integration.js +92 -0
- 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 +463 -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 +29 -0
- package/dist/services/repair-receipt.js +13 -0
- package/dist/services/retained-native-hook.js +274 -0
- package/dist/services/review-copy.js +165 -0
- package/dist/services/review-deferral.js +23 -0
- package/dist/services/review-fix-handoff.js +82 -0
- package/dist/services/review-fix-intake-custody.js +17 -0
- package/dist/services/review-fix-stage-entry.js +43 -0
- package/dist/services/review-fix-stage-handlers.js +176 -0
- package/dist/services/review-fix-stage-results.js +86 -0
- package/dist/services/run-control-receipt.js +56 -0
- package/dist/services/run-control-worker.js +469 -0
- package/dist/services/run-control.js +1109 -0
- package/dist/services/run-controller-adapter.js +434 -0
- package/dist/services/run-controller-capture.js +186 -0
- package/dist/services/run-controller-process.js +226 -0
- package/dist/services/run-controller-recovery.js +335 -0
- package/dist/services/run-controller-state.js +106 -0
- package/dist/services/run-controller.js +1717 -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 +485 -0
- package/dist/services/run-start-custody.js +189 -0
- package/dist/services/run-timeline.js +59 -0
- package/dist/services/runs.js +996 -271
- 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 +37 -91
- package/dist/services/setup.js +427 -0
- package/dist/services/stage-blocker.js +17 -7
- package/dist/services/stage-context.js +240 -18
- package/dist/services/stage-handlers.js +141 -0
- package/dist/services/stage-lifecycle.js +156 -119
- package/dist/services/stage-pause.js +222 -94
- package/dist/services/stage-report-renderer.js +230 -6
- package/dist/services/stage-work-graph.js +52 -0
- package/dist/services/technical-notes.js +31 -0
- package/dist/services/tooling.js +111 -44
- 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 +302 -91
- package/dist/services/vnext-code.js +325 -251
- package/dist/services/vnext-contracts.js +10 -1
- package/dist/services/vnext-execution-profile.js +80 -5
- package/dist/services/vnext-fanout.js +399 -20
- package/dist/services/vnext-merge.js +336 -114
- package/dist/services/vnext-plan-review.js +288 -133
- package/dist/services/vnext-plan.js +257 -110
- package/dist/services/vnext-protocolize.js +534 -96
- package/dist/services/vnext-specify.js +131 -84
- package/dist/services/vnext-workspace-policy.js +7 -2
- package/dist/services/work-registry.js +1950 -215
- package/dist/services/work-retry-context.js +55 -0
- package/dist/services/workspace-bootstrap.js +53 -15
- package/dist/services/workspace-files.js +85 -0
- package/dist/services/worktrees.js +108 -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 +931 -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/dist/verification-components.json +384 -0
- package/package.json +52 -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
- package/tools/verification-jobs.mjs +342 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { AppError } from "../shared/errors.js";
|
|
3
|
+
import { storageSessionId } from "./session-identity.js";
|
|
4
|
+
import { runtimeHarness } from "./execution-policy.js";
|
|
5
|
+
import { requireManagedDaemonBinding } from "./managed-daemon-binding.js";
|
|
6
|
+
import { appendAudit } from "./audit.js";
|
|
7
|
+
import { commandOption, commandPosition, continuationCommand, parseLifecycleCommand } from "./lifecycle-command.js";
|
|
8
|
+
import { processStartedAt } from "./managed-processes.js";
|
|
9
|
+
import { stageGraphScope } from "./stage-work-graph.js";
|
|
10
|
+
import { hookSessionIdentity, assertStageStartHookEvent, claimStageStartHookEvent } from "./hooks.js";
|
|
11
|
+
const owned = new WeakMap();
|
|
12
|
+
const assignmentEvent = "lifecycle.controller_assignment";
|
|
13
|
+
function refuse(reason) { throw new AppError("invocation_assignment_unproven", "Managed command has no current assigned execution", 1, { reason, effect: "no_effect", recoverable: false, reconciliation_required: true }); }
|
|
14
|
+
function parsed(command) { const value = parseLifecycleCommand(command); return value.kind === "standalone" ? value.invocation : null; }
|
|
15
|
+
function stageEntryFence(context, scope, stage) {
|
|
16
|
+
const row = context.db.get("SELECT index_json FROM runs WHERE id=? AND project_root=?", [scope.runId, scope.projectRoot]);
|
|
17
|
+
const index = row ? JSON.parse(row.index_json) : null;
|
|
18
|
+
return JSON.stringify([index?.current_stage ?? null, index?.stage_runs?.find((item) => item.stage === stage) ?? null, index?.variables?.["merge.source_repair"]?.cycle ?? null]);
|
|
19
|
+
}
|
|
20
|
+
/** Called by the controller after native creation/resolution, before dispatch. */
|
|
21
|
+
export function retainControllerStageAssignment(context, command, input) {
|
|
22
|
+
const scope = JSON.parse(context.env.DD_FLOW_INVOCATION_SCOPE ?? "null");
|
|
23
|
+
const invocation = parsed(command);
|
|
24
|
+
if (!scope?.runId || !invocation || invocation.operation !== "stage_start" || commandOption(invocation, "stage") !== input.stage)
|
|
25
|
+
refuse("stage_issuance_scope");
|
|
26
|
+
const rows = context.db.all("SELECT * FROM lifecycle_invocations WHERE scope_json=? AND status='issued'", [JSON.stringify(scope)])
|
|
27
|
+
.filter(row => { const item = parsed(row.command); return item?.operation === "stage_start" && commandOption(item, "stage") === input.stage && commandOption(item, "context-sha256") === input.contextSha256; });
|
|
28
|
+
if (rows.length !== 1)
|
|
29
|
+
refuse("stage_issuance_ambiguous");
|
|
30
|
+
const controller = context.db.get("SELECT * FROM run_controllers WHERE controller_id=?", [input.controllerId]);
|
|
31
|
+
if (!controller || controller.run_id !== scope.runId || controller.generation !== scope.generation || ["completed", "cancelled", "superseded"].includes(controller.status))
|
|
32
|
+
refuse("controller_stale");
|
|
33
|
+
const state = JSON.parse(controller.state_json);
|
|
34
|
+
const session = state.current_session === null ? undefined : state.sessions[state.current_session];
|
|
35
|
+
if (!session || session.id !== input.sessionId || session.state_dir !== input.stateDir || session.stopped || session.retired)
|
|
36
|
+
refuse("controller_session_changed");
|
|
37
|
+
const binding = requireManagedDaemonBinding(context, { stateDir: input.stateDir, projectId: controller.project_id, runId: controller.run_id, ownerId: input.controllerId });
|
|
38
|
+
const native = binding.state.sessions?.find(item => typeof item === "string" ? item === input.sessionId : item.adapter_session_id === input.sessionId || item.provider_session_id === input.sessionId);
|
|
39
|
+
const nativeId = typeof native === "string" ? native : native?.provider_session_id;
|
|
40
|
+
const rootId = typeof native === "string" ? native : native?.root_provider_session_id ?? native?.provider_session_id;
|
|
41
|
+
if (!nativeId || rootId !== scope.rootSessionId || binding.state.daemon_id !== scope.daemonId)
|
|
42
|
+
refuse("native_create_mapping_unavailable");
|
|
43
|
+
const harness = runtimeHarness(session.profile);
|
|
44
|
+
const identity = { source: "controller_assignment", hookEventId: null, harness, providerSessionId: nativeId,
|
|
45
|
+
parentSessionId: null, daemonId: scope.daemonId, agentId: null, sessionId: storageSessionId({ harness_id: harness, session_id: nativeId }), nativeSessionId: nativeId,
|
|
46
|
+
turnId: null, transcriptPath: null, provider: session.profile.provider ?? null, model: null, reasoning: null, mode: null, agentType: null, cwd: session.cwd };
|
|
47
|
+
const payload = { invocation_id: rows[0].id, scope, controller_id: input.controllerId, owner_token: controller.owner_token,
|
|
48
|
+
stage_entry_fence: stageEntryFence(context, scope, input.stage), adapter_session_id: input.sessionId,
|
|
49
|
+
stage: input.stage, context_sha256: input.contextSha256, attempt: input.attempt ?? null, cycle: input.cycle ?? null, identity };
|
|
50
|
+
const prior = context.db.get("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.invocation_id')=?", [controller.project_id, assignmentEvent, rows[0].id]);
|
|
51
|
+
if (prior) {
|
|
52
|
+
if (prior.payload_json !== JSON.stringify(payload))
|
|
53
|
+
refuse("stage_assignment_changed");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
appendAudit(context, { projectId: controller.project_id, eventType: assignmentEvent, payload });
|
|
57
|
+
}
|
|
58
|
+
/** Resolve immutable packet membership; a readable UUID or env is not ownership. */
|
|
59
|
+
export function assignedLifecycleBinding(context, row) {
|
|
60
|
+
const scope = JSON.parse(row.scope_json);
|
|
61
|
+
const invocation = parsed(row.command);
|
|
62
|
+
if (!invocation || !scope.runId)
|
|
63
|
+
return null;
|
|
64
|
+
const operation = invocation.operation;
|
|
65
|
+
if (operation === "stage_start") {
|
|
66
|
+
const retained = context.db.get("SELECT payload_json FROM audit_events WHERE event_type=? AND json_extract(payload_json,'$.invocation_id')=?", [assignmentEvent, row.id]);
|
|
67
|
+
if (!retained)
|
|
68
|
+
return null;
|
|
69
|
+
const launch = JSON.parse(retained.payload_json);
|
|
70
|
+
if (JSON.stringify(launch.scope) !== row.scope_json || launch.stage !== commandOption(invocation, "stage") || launch.context_sha256 !== commandOption(invocation, "context-sha256"))
|
|
71
|
+
refuse("stage_packet_changed");
|
|
72
|
+
const owner = context.db.get("SELECT generation,owner_token,status,state_json FROM run_controllers WHERE controller_id=?", [launch.controller_id]);
|
|
73
|
+
const state = owner && JSON.parse(owner.state_json);
|
|
74
|
+
if (!owner || owner.owner_token !== launch.owner_token || stageEntryFence(context, scope, launch.stage) !== launch.stage_entry_fence || owner.generation !== scope.generation || ["completed", "cancelled", "superseded"].includes(owner.status) || !state || state.current_session === null || state.sessions[state.current_session]?.id !== launch.adapter_session_id || state.sessions[state.current_session]?.stopped || state.sessions[state.current_session]?.retired)
|
|
75
|
+
refuse("stage_owner_changed");
|
|
76
|
+
return { schema_id: "dd-flow/assigned-lifecycle-admission@1", kind: "managed_assignment", invocation_id: row.id, scope, operation,
|
|
77
|
+
work_id: null, work_session_id: null, controller_id: launch.controller_id, controller_owner: { token: launch.owner_token, session_id: launch.adapter_session_id }, stage: launch.stage, identity: launch.identity };
|
|
78
|
+
}
|
|
79
|
+
if (!["work_finish", "work_fail", "stage_finish", "stage_pause", "stage_resume"].includes(operation))
|
|
80
|
+
return null;
|
|
81
|
+
const stage = commandOption(invocation, "stage") ?? null;
|
|
82
|
+
const target = operation.startsWith("work_") ? commandPosition(invocation, 0) : commandOption(invocation, "work");
|
|
83
|
+
const matches = context.db.all(`SELECT DISTINCT ws.id,ws.work_id,ws.session_id,ws.start_receipt_json,s.harness,s.provider_session_id,s.parent_session_id,s.cwd,he.daemon_id
|
|
84
|
+
FROM lifecycle_packet_assignments pa JOIN work_sessions ws ON (pa.packet_sha256=json_extract(ws.start_receipt_json,'$.prompt_sha256')
|
|
85
|
+
OR EXISTS (SELECT 1 FROM audit_events a WHERE a.event_type='lifecycle.coordinator_packet'
|
|
86
|
+
AND json_extract(a.payload_json,'$.work_session_id')=ws.id AND json_extract(a.payload_json,'$.packet_sha256')=pa.packet_sha256))
|
|
87
|
+
JOIN works w ON w.work_id=ws.work_id JOIN projects p ON p.id=w.project_id
|
|
88
|
+
JOIN sessions s ON s.project_id=w.project_id AND s.session_id=ws.session_id
|
|
89
|
+
LEFT JOIN hook_events he ON he.project_id=w.project_id AND he.event_key=ws.hook_event_id
|
|
90
|
+
WHERE pa.invocation_id=? AND p.root=? AND w.run_id=? AND ws.status='running' AND ws.start_publication_status='published'
|
|
91
|
+
AND w.status IN ('running','paused')`, [row.id, scope.projectRoot, scope.runId])
|
|
92
|
+
.filter(item => (!target || item.work_id === target || item.work_id.match(/^WRK-\d+/)?.[0] === target));
|
|
93
|
+
if (!matches.length)
|
|
94
|
+
return null;
|
|
95
|
+
if (matches.length !== 1)
|
|
96
|
+
refuse("ambiguous_packet_owner");
|
|
97
|
+
const item = matches[0];
|
|
98
|
+
if (operation !== "stage_resume" && item.daemon_id && item.daemon_id !== scope.daemonId)
|
|
99
|
+
refuse("work_daemon_changed");
|
|
100
|
+
const projectId = context.db.get("SELECT id FROM projects WHERE root=?", [scope.projectRoot])?.id;
|
|
101
|
+
if (!projectId)
|
|
102
|
+
refuse("assignment_project_missing");
|
|
103
|
+
const owners = context.db.get("SELECT 1 FROM sqlite_master WHERE name='run_controllers'")
|
|
104
|
+
? context.db.all("SELECT controller_id,owner_token,state_json FROM run_controllers WHERE project_id=? AND run_id=? AND generation=? AND status NOT IN ('completed','cancelled','superseded')", [projectId, scope.runId, scope.generation]) : [];
|
|
105
|
+
if (owners.length > 1)
|
|
106
|
+
refuse("controller_owner_ambiguous");
|
|
107
|
+
const controller = owners[0];
|
|
108
|
+
const controllerState = controller && JSON.parse(controller.state_json);
|
|
109
|
+
const current = controllerState && controllerState.current_session !== null ? controllerState.sessions[controllerState.current_session] : null;
|
|
110
|
+
if (controller && (!current || current.retired || current.stopped))
|
|
111
|
+
refuse("controller_session_retired");
|
|
112
|
+
if (stage && !context.db.get("SELECT 1 FROM sessions WHERE project_id=? AND session_id=? AND run_id=? AND current_stage=?", [projectId, item.session_id, scope.runId, stage]))
|
|
113
|
+
refuse("inactive_stage_assignment");
|
|
114
|
+
if (stage) {
|
|
115
|
+
const project = context.db.get("SELECT id FROM projects WHERE root=?", [scope.projectRoot]);
|
|
116
|
+
const graph = stageGraphScope(context, project.id, scope.runId, stage);
|
|
117
|
+
const packet = context.db.get(`SELECT a.payload_json FROM audit_events a JOIN lifecycle_packet_assignments pa
|
|
118
|
+
ON pa.packet_sha256=json_extract(a.payload_json,'$.packet_sha256') WHERE a.event_type='lifecycle.coordinator_packet'
|
|
119
|
+
AND pa.invocation_id=? AND json_extract(a.payload_json,'$.work_session_id')=? ORDER BY a.id DESC LIMIT 1`, [row.id, item.id]);
|
|
120
|
+
if (!packet || JSON.stringify(JSON.parse(packet.payload_json).stage_scope) !== JSON.stringify(graph))
|
|
121
|
+
refuse("stage_attempt_changed");
|
|
122
|
+
}
|
|
123
|
+
let identity = { source: "controller_assignment", hookEventId: null, harness: item.harness,
|
|
124
|
+
providerSessionId: item.provider_session_id, nativeSessionId: item.provider_session_id, sessionId: item.session_id,
|
|
125
|
+
parentSessionId: item.parent_session_id, daemonId: scope.daemonId, agentId: null, turnId: null, transcriptPath: null,
|
|
126
|
+
provider: null, model: null, reasoning: null, mode: null, agentType: null, cwd: item.cwd };
|
|
127
|
+
if (operation === "stage_resume") {
|
|
128
|
+
const retained = context.db.get("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type='lifecycle.resume_assignment' AND json_extract(payload_json,'$.invocation_id')=?", [projectId, row.id]);
|
|
129
|
+
const run = context.db.get("SELECT index_json FROM runs WHERE project_id=? AND id=?", [projectId, scope.runId]);
|
|
130
|
+
const pause = run && JSON.parse(run.index_json).stage_runs.find((entry) => entry.stage === stage)?.pause;
|
|
131
|
+
if (!retained || JSON.parse(retained.payload_json).pause_id !== pause?.id)
|
|
132
|
+
refuse("resume_pause_changed");
|
|
133
|
+
const assignedSession = JSON.parse(retained.payload_json).work_session_id;
|
|
134
|
+
if (assignedSession !== item.id) {
|
|
135
|
+
const receipt = JSON.parse(item.start_receipt_json);
|
|
136
|
+
const recovered = receipt.recovered_from_work_session_id === assignedSession && receipt.recovery_id && context.db.get(`SELECT 1 FROM run_recovery_bindings b JOIN run_recovery_guards g ON g.recovery_id=b.recovery_id
|
|
137
|
+
WHERE g.project_id=? AND g.run_id=? AND g.generation=? AND g.status='recovered' AND b.status='accepted'
|
|
138
|
+
AND b.recovery_id=? AND b.prior_work_session_id=? AND b.work_id=? AND b.session_id=?`, [projectId, scope.runId, scope.generation, receipt.recovery_id, assignedSession, item.work_id, item.session_id]);
|
|
139
|
+
if (!recovered)
|
|
140
|
+
refuse("resume_session_changed");
|
|
141
|
+
}
|
|
142
|
+
if (controller && current) {
|
|
143
|
+
const harness = runtimeHarness(current.profile), nativeId = scope.rootSessionId;
|
|
144
|
+
identity = { ...identity, harness, nativeSessionId: nativeId, providerSessionId: nativeId,
|
|
145
|
+
sessionId: storageSessionId({ harness_id: harness, session_id: nativeId }), parentSessionId: null, cwd: current.cwd };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { schema_id: "dd-flow/assigned-lifecycle-admission@1", kind: "managed_assignment", invocation_id: row.id, scope,
|
|
149
|
+
operation, work_id: item.work_id, work_session_id: item.id, controller_id: controller?.controller_id ?? null, stage, identity,
|
|
150
|
+
...(controller && current ? { controller_owner: { token: controller.owner_token, session_id: current.id } } : {}) };
|
|
151
|
+
}
|
|
152
|
+
/** A pause and its current published coordinator packet authorize its exact answer command. */
|
|
153
|
+
export function bindAssignedStageResume(context, row) {
|
|
154
|
+
const command = parsed(row.command), scope = JSON.parse(row.scope_json);
|
|
155
|
+
if (command?.operation !== "stage_resume" || !scope.runId)
|
|
156
|
+
return;
|
|
157
|
+
const project = context.db.get("SELECT id FROM projects WHERE root=?", [scope.projectRoot]);
|
|
158
|
+
const stage = commandOption(command, "stage"), work = commandOption(command, "work");
|
|
159
|
+
const run = project && context.db.get("SELECT index_json FROM runs WHERE project_id=? AND id=?", [project.id, scope.runId]);
|
|
160
|
+
const entry = run && JSON.parse(run.index_json).stage_runs.find((item) => item.stage === stage);
|
|
161
|
+
if (!project || !entry?.pause || !work || ![entry.pause.work_id, entry.pause.work_id.match(/^WRK-\d+/)?.[0]].includes(work))
|
|
162
|
+
return;
|
|
163
|
+
const links = context.db.all("SELECT ws.id,ws.start_receipt_json FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id WHERE w.project_id=? AND w.run_id=? AND w.work_id=? AND w.status='paused' AND ws.status='running' AND ws.start_publication_status='published'", [project.id, scope.runId, entry.pause.work_id]);
|
|
164
|
+
if (links.length !== 1)
|
|
165
|
+
return;
|
|
166
|
+
const link = links[0];
|
|
167
|
+
const hashes = context.db.all("SELECT json_extract(payload_json,'$.packet_sha256') AS packet FROM audit_events WHERE project_id=? AND event_type='lifecycle.coordinator_packet' AND json_extract(payload_json,'$.work_session_id')=? AND json_extract(payload_json,'$.stage')=?", [project.id, link.id, stage]);
|
|
168
|
+
const startHash = JSON.parse(link.start_receipt_json).prompt_sha256;
|
|
169
|
+
for (const hash of new Set([...hashes.map(item => item.packet), ...(startHash ? [startHash] : [])]))
|
|
170
|
+
context.db.run("INSERT OR IGNORE INTO lifecycle_packet_assignments(packet_sha256,invocation_id) VALUES (?,?)", [hash, row.id]);
|
|
171
|
+
appendAudit(context, { projectId: project.id, eventType: "lifecycle.resume_assignment", payload: { run_id: scope.runId,
|
|
172
|
+
invocation_id: row.id, work_session_id: link.id, stage, pause_id: entry.pause.id, answer_file: commandOption(command, "answer-file") ?? null, generation: scope.generation } });
|
|
173
|
+
}
|
|
174
|
+
export function claimAssignedLifecycle(context, row) {
|
|
175
|
+
const binding = assignedLifecycleBinding(context, row);
|
|
176
|
+
if (!binding)
|
|
177
|
+
return null;
|
|
178
|
+
// Physical observation can spawn ps; never hold the RUN writer while doing it.
|
|
179
|
+
const executor = { pid: process.pid, birth: processStartedAt(process.pid), cwd: process.cwd() };
|
|
180
|
+
return context.db.writeTransaction(() => {
|
|
181
|
+
const current = assignedLifecycleBinding(context, row);
|
|
182
|
+
if (!current || JSON.stringify(current) !== JSON.stringify(binding))
|
|
183
|
+
refuse("assignment_changed");
|
|
184
|
+
assertTerminalSettlementUnreserved(context, row, binding.work_session_id);
|
|
185
|
+
const admission = { ...binding, executor: { ...executor, admitted_at: context.now() } };
|
|
186
|
+
if (context.db.run("UPDATE lifecycle_invocations SET status='executing',admission_json=?,updated_at=? WHERE id=? AND status IN ('issued','observed')", [JSON.stringify(admission), admission.executor.admitted_at, row.id]).changes !== 1)
|
|
187
|
+
return null;
|
|
188
|
+
let map = owned.get(context.db);
|
|
189
|
+
if (!map) {
|
|
190
|
+
map = new Map();
|
|
191
|
+
owned.set(context.db, map);
|
|
192
|
+
}
|
|
193
|
+
map.set(row.id, admission);
|
|
194
|
+
return admission;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/** Both native and assigned claims reserve the same current WorkSession before checks. SQL-only. */
|
|
198
|
+
export function assertTerminalSettlementUnreserved(context, row, assignedSession) {
|
|
199
|
+
const sessions = (attempt) => {
|
|
200
|
+
const command = parsed(attempt.command), scope = JSON.parse(attempt.scope_json);
|
|
201
|
+
if (!command || !scope.runId || !["work_finish", "work_fail", "stage_finish", "stage_pause", "stage_resume"].includes(command.operation))
|
|
202
|
+
return [];
|
|
203
|
+
const retained = attempt.admission_json && JSON.parse(attempt.admission_json).work_session_id;
|
|
204
|
+
if (retained)
|
|
205
|
+
return [retained];
|
|
206
|
+
const target = command.operation.startsWith("work_") ? commandPosition(command, 0) : commandOption(command, "work");
|
|
207
|
+
const stage = commandOption(command, "stage");
|
|
208
|
+
const identity = context.db.get(`SELECT he.session_id FROM hook_events he JOIN projects p ON p.id=he.project_id
|
|
209
|
+
JOIN lifecycle_invocations li ON li.event_key=he.event_key WHERE li.id=? AND p.root=?`, [attempt.id, scope.projectRoot]);
|
|
210
|
+
return context.db.all(`SELECT ws.id,w.work_id,ws.session_id,w.parent_work_id,s.current_stage
|
|
211
|
+
FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id JOIN projects p ON p.id=w.project_id
|
|
212
|
+
JOIN sessions s ON s.project_id=w.project_id AND s.session_id=ws.session_id
|
|
213
|
+
WHERE p.root=? AND w.run_id=? AND ws.status='running' AND w.status IN ('running','paused')`, [scope.projectRoot, scope.runId])
|
|
214
|
+
.filter(link => target ? link.work_id === target || link.work_id.match(/^WRK-\d+/)?.[0] === target
|
|
215
|
+
: Boolean(stage && link.current_stage === stage && (identity ? link.session_id === identity.session_id : link.parent_work_id === null)))
|
|
216
|
+
.map(link => link.id);
|
|
217
|
+
};
|
|
218
|
+
const scope = JSON.parse(row.scope_json);
|
|
219
|
+
const targets = assignedSession ? [assignedSession] : sessions(row);
|
|
220
|
+
if (!targets.length)
|
|
221
|
+
return;
|
|
222
|
+
const peers = context.db.all("SELECT * FROM lifecycle_invocations WHERE id<>? AND status='executing' AND json_extract(scope_json,'$.projectRoot')=? AND json_extract(scope_json,'$.runId')=?", [row.id, scope.projectRoot, scope.runId]);
|
|
223
|
+
const busy = peers.find(peer => sessions(peer).some(id => targets.includes(id)));
|
|
224
|
+
if (busy)
|
|
225
|
+
throw new AppError("invocation_outcome_pending", "Another settlement of this Work Session is executing; observe that attempt", 1, { invocation_id: busy.id, effect: "no_effect", recoverable: true, reconciliation_required: true });
|
|
226
|
+
}
|
|
227
|
+
export function currentAssignedLifecycle(context) {
|
|
228
|
+
const id = context.env?.DD_FLOW_CURRENT_INVOCATION;
|
|
229
|
+
if (!id)
|
|
230
|
+
return null;
|
|
231
|
+
const admission = owned.get(context.db)?.get(id);
|
|
232
|
+
if (!admission || admission.executor.pid !== process.pid || admission.executor.cwd !== process.cwd())
|
|
233
|
+
return null;
|
|
234
|
+
const row = context.db.get("SELECT status,admission_json FROM lifecycle_invocations WHERE id=?", [id]);
|
|
235
|
+
return row?.status === "executing" && row.admission_json === JSON.stringify(admission) ? admission : null;
|
|
236
|
+
}
|
|
237
|
+
/** Result consumers can use launch facts without manufacturing a native Hook. */
|
|
238
|
+
export function assignedSessionIdentity(context) { return currentAssignedLifecycle(context)?.identity ?? null; }
|
|
239
|
+
export function lifecycleSessionIdentity(context, projectId, eventKey) {
|
|
240
|
+
const assigned = assignedSessionIdentity(context);
|
|
241
|
+
if (assigned)
|
|
242
|
+
return assigned;
|
|
243
|
+
if (!eventKey)
|
|
244
|
+
refuse("native_or_assigned_identity_required");
|
|
245
|
+
return hookSessionIdentity(context, projectId, eventKey);
|
|
246
|
+
}
|
|
247
|
+
/** Historical launch custody remains readable without a fresh native event. */
|
|
248
|
+
export function hasAssignedCoordinatorLaunch(context, input) {
|
|
249
|
+
const rows = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type='stage.coordinator_binding' AND json_extract(payload_json,'$.run_id')=? AND json_extract(payload_json,'$.scope.stage')=? AND json_extract(payload_json,'$.work_session_id')=?", [input.projectId, input.runId, input.stage, input.workSessionId]);
|
|
250
|
+
return rows.some(row => {
|
|
251
|
+
const payload = JSON.parse(row.payload_json);
|
|
252
|
+
if (!payload.launch_invocation_id || payload.session_id !== input.sessionId)
|
|
253
|
+
return false;
|
|
254
|
+
const invocation = context.db.get("SELECT admission_json,status FROM lifecycle_invocations WHERE id=?", [payload.launch_invocation_id]);
|
|
255
|
+
if (!invocation?.admission_json || !["executing", "settled"].includes(invocation.status))
|
|
256
|
+
return false;
|
|
257
|
+
const admission = JSON.parse(invocation.admission_json);
|
|
258
|
+
return admission.kind === "managed_assignment" && admission.operation === "stage_start" && admission.identity.sessionId === input.sessionId
|
|
259
|
+
&& admission.scope.runId === input.runId && admission.stage === input.stage
|
|
260
|
+
&& context.db.get("SELECT id FROM projects WHERE root=?", [admission.scope.projectRoot])?.id === input.projectId;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
export function assertAssignedStageStart(context, input) {
|
|
264
|
+
const assigned = currentAssignedLifecycle(context);
|
|
265
|
+
if (assigned) {
|
|
266
|
+
if (assigned.operation !== "stage_start" || assigned.scope.runId !== input.runId || assigned.stage !== input.stage || assigned.scope.projectRoot !== input.projectRoot)
|
|
267
|
+
refuse("stage_launch_target");
|
|
268
|
+
return assigned.identity;
|
|
269
|
+
}
|
|
270
|
+
if (!input.eventKey)
|
|
271
|
+
refuse("stage_launch_identity_missing");
|
|
272
|
+
return assertStageStartHookEvent(context, { ...input, eventKey: input.eventKey });
|
|
273
|
+
}
|
|
274
|
+
export function claimAssignedStageStart(context, input) {
|
|
275
|
+
if (currentAssignedLifecycle(context))
|
|
276
|
+
return assertAssignedStageStart(context, input);
|
|
277
|
+
if (!input.eventKey)
|
|
278
|
+
refuse("stage_launch_identity_missing");
|
|
279
|
+
return claimStageStartHookEvent(context, { ...input, eventKey: input.eventKey });
|
|
280
|
+
}
|
|
281
|
+
export function bindAssignedCoordinatorPacket(context, prompt) {
|
|
282
|
+
const admitted = currentAssignedLifecycle(context);
|
|
283
|
+
if (!admitted || !["stage_start", "stage_resume"].includes(admitted.operation))
|
|
284
|
+
return;
|
|
285
|
+
const digest = crypto.createHash("sha256").update(prompt).digest("hex");
|
|
286
|
+
const projectId = context.db.get("SELECT id FROM projects WHERE root=?", [admitted.scope.projectRoot])?.id;
|
|
287
|
+
if (!projectId)
|
|
288
|
+
refuse("assignment_project_missing");
|
|
289
|
+
const links = context.db.all("SELECT ws.id,w.project_id,ws.start_receipt_json FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id WHERE w.project_id=? AND w.run_id=? AND ws.session_id=? AND ws.status='running'", [projectId, admitted.scope.runId, admitted.identity.sessionId]);
|
|
290
|
+
if (links.length !== 1)
|
|
291
|
+
refuse("coordinator_packet_owner");
|
|
292
|
+
const link = links[0];
|
|
293
|
+
// Retain original launch bytes. Later stage/resume packets are independent
|
|
294
|
+
// immutable publications, not replacements of a Work start receipt.
|
|
295
|
+
if (!link.start_receipt_json)
|
|
296
|
+
context.db.run("UPDATE work_sessions SET start_receipt_json=?,start_publication_status='published' WHERE id=? AND status='running' AND start_receipt_json IS NULL", [JSON.stringify({ version: 3, prompt, prompt_sha256: digest, generation: admitted.scope.generation, invocation_id: admitted.invocation_id, source: "controller_assignment" }), link.id]);
|
|
297
|
+
const prior = context.db.get("SELECT 1 FROM audit_events WHERE project_id=? AND event_type='lifecycle.coordinator_packet' AND json_extract(payload_json,'$.work_session_id')=? AND json_extract(payload_json,'$.packet_sha256')=?", [link.project_id, link.id, digest]);
|
|
298
|
+
if (!prior)
|
|
299
|
+
appendAudit(context, { projectId: link.project_id, eventType: "lifecycle.coordinator_packet", payload: { run_id: admitted.scope.runId,
|
|
300
|
+
work_session_id: link.id, packet_sha256: digest, generation: admitted.scope.generation, invocation_id: admitted.invocation_id, stage: admitted.stage,
|
|
301
|
+
controller_id: admitted.controller_id, controller_owner: admitted.controller_owner ?? null,
|
|
302
|
+
daemon_id: admitted.scope.daemonId, root_session_id: admitted.scope.rootSessionId,
|
|
303
|
+
stage_scope: admitted.stage ? stageGraphScope(context, link.project_id, admitted.scope.runId, admitted.stage) : null,
|
|
304
|
+
auxiliary_operations: ["stage_block", ...(admitted.stage === "code" ? ["work_repair_add"] : [])], prompt } });
|
|
305
|
+
}
|
|
306
|
+
/** These two coordinator mutations are scoped permits, not generic shell authority. */
|
|
307
|
+
export function admitAssignedAuxiliary(context, command, scope, projectRoot) {
|
|
308
|
+
const operation = continuationCommand(command);
|
|
309
|
+
if (!operation || !scope.runId || projectRoot !== scope.projectRoot)
|
|
310
|
+
return false;
|
|
311
|
+
const runTarget = operation.args.options.get("run")?.[0] ?? operation.args.positional[2];
|
|
312
|
+
const stage = operation.args.options.get("stage")?.[0] ?? (operation.operation === "work_repair_add" ? "code" : undefined);
|
|
313
|
+
if (!runTarget || !stage)
|
|
314
|
+
refuse("auxiliary_target_missing");
|
|
315
|
+
const run = context.db.get("SELECT r.id,r.project_id FROM runs r JOIN projects p ON p.id=r.project_id WHERE p.root=? AND r.id=? AND (r.id=? OR r.short_id=?)", [scope.projectRoot, scope.runId, runTarget, runTarget]);
|
|
316
|
+
if (!run)
|
|
317
|
+
refuse("auxiliary_run_changed");
|
|
318
|
+
const links = context.db.all(`SELECT w.work_id,a.payload_json FROM audit_events a
|
|
319
|
+
JOIN work_sessions ws ON ws.id=json_extract(a.payload_json,'$.work_session_id') JOIN works w ON w.work_id=ws.work_id
|
|
320
|
+
JOIN sessions s ON s.project_id=w.project_id AND s.session_id=ws.session_id
|
|
321
|
+
WHERE a.event_type='lifecycle.coordinator_packet' AND w.project_id=? AND a.project_id=w.project_id AND w.run_id=? AND ws.status='running' AND ws.start_publication_status='published' AND w.status IN ('running','paused')
|
|
322
|
+
AND s.current_stage=? AND json_extract(a.payload_json,'$.generation')=?`, [run.project_id, scope.runId, stage, scope.generation]);
|
|
323
|
+
const work = operation.args.options.get("work")?.[0];
|
|
324
|
+
const matches = links.filter(link => {
|
|
325
|
+
const packet = JSON.parse(link.payload_json);
|
|
326
|
+
if (packet.daemon_id !== scope.daemonId || packet.root_session_id !== scope.rootSessionId
|
|
327
|
+
|| JSON.stringify(packet.stage_scope) !== JSON.stringify(stageGraphScope(context, run.project_id, scope.runId, stage)))
|
|
328
|
+
return false;
|
|
329
|
+
if (!packet.controller_id || !packet.controller_owner)
|
|
330
|
+
return false;
|
|
331
|
+
const controller = context.db.get("SELECT owner_token,status,state_json,generation FROM run_controllers WHERE controller_id=? AND project_id=? AND run_id=?", [packet.controller_id, run.project_id, scope.runId]);
|
|
332
|
+
const state = controller && JSON.parse(controller.state_json);
|
|
333
|
+
const active = state && state.current_session !== null ? state.sessions[state.current_session] : null;
|
|
334
|
+
if (!controller || controller.owner_token !== packet.controller_owner.token || controller.generation !== scope.generation
|
|
335
|
+
|| ["completed", "cancelled", "superseded"].includes(controller.status) || !active || active.id !== packet.controller_owner.session_id || active.retired || active.stopped)
|
|
336
|
+
return false;
|
|
337
|
+
return packet.auxiliary_operations?.includes(operation.operation) && (!work || link.work_id === work || link.work_id.match(/^WRK-\d+/)?.[0] === work);
|
|
338
|
+
});
|
|
339
|
+
if (new Set(matches.map(item => item.work_id)).size !== 1)
|
|
340
|
+
refuse("auxiliary_assignment_missing");
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
export function assertAssignedSettlementCurrent(context, workSessionId) {
|
|
344
|
+
const admission = currentAssignedLifecycle(context);
|
|
345
|
+
if (!admission)
|
|
346
|
+
return;
|
|
347
|
+
if (workSessionId && admission.work_session_id && admission.work_session_id !== workSessionId)
|
|
348
|
+
refuse("settlement_session_changed");
|
|
349
|
+
const guard = context.db.get("SELECT g.generation,g.status FROM run_recovery_guards g JOIN projects p ON p.id=g.project_id WHERE p.root=? AND g.run_id=? ORDER BY g.generation DESC LIMIT 1", [admission.scope.projectRoot, admission.scope.runId]);
|
|
350
|
+
if (guard && guard.generation !== admission.scope.generation && !(guard.status === "draining" && guard.generation === admission.scope.generation + 1))
|
|
351
|
+
refuse("settlement_generation_changed");
|
|
352
|
+
if (admission.controller_id && admission.controller_owner) {
|
|
353
|
+
const owner = context.db.get("SELECT owner_token,generation,state_json,status FROM run_controllers WHERE controller_id=?", [admission.controller_id]);
|
|
354
|
+
const state = owner && JSON.parse(owner.state_json);
|
|
355
|
+
if (!owner || owner.owner_token !== admission.controller_owner.token || owner.generation !== admission.scope.generation
|
|
356
|
+
|| ["completed", "cancelled", "superseded"].includes(owner.status) || !state || state.current_session === null
|
|
357
|
+
|| state.sessions[state.current_session]?.id !== admission.controller_owner.session_id || state.sessions[state.current_session]?.retired)
|
|
358
|
+
refuse("settlement_controller_changed");
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
export function inheritAssignedPackets(context, priorId, successorId) {
|
|
362
|
+
context.db.run("INSERT OR IGNORE INTO lifecycle_packet_assignments(packet_sha256,invocation_id) SELECT packet_sha256,? FROM lifecycle_packet_assignments WHERE invocation_id=?", [successorId, priorId]);
|
|
363
|
+
}
|
|
364
|
+
/** Exact SQL acceptance, independent of stdout or derivative result publication. */
|
|
365
|
+
export function readAcceptedAssignedWork(context, invocationId) {
|
|
366
|
+
const rows = context.db.all("SELECT project_id,payload_json FROM audit_events WHERE event_type='lifecycle.work_settlement' AND json_extract(payload_json,'$.invocation_id')=? LIMIT 2", [invocationId]);
|
|
367
|
+
if (!rows.length)
|
|
368
|
+
return null;
|
|
369
|
+
if (rows.length !== 1)
|
|
370
|
+
throw new AppError("invocation_outcome_pending", "Assigned Work has ambiguous settlement evidence", 1, { effect: "unknown" });
|
|
371
|
+
const invocation = context.db.get("SELECT admission_json FROM lifecycle_invocations WHERE id=?", [invocationId]);
|
|
372
|
+
if (!invocation?.admission_json)
|
|
373
|
+
return null;
|
|
374
|
+
const admission = JSON.parse(invocation.admission_json);
|
|
375
|
+
const retained = JSON.parse(rows[0].payload_json);
|
|
376
|
+
if (admission.work_id !== retained.work_id || admission.work_session_id !== retained.work_session_id || admission.scope.runId !== retained.run_id)
|
|
377
|
+
refuse("accepted_assignment_changed");
|
|
378
|
+
const accepted = context.db.get("SELECT w.result,w.status FROM works w JOIN work_sessions ws ON ws.work_id=w.work_id AND ws.status=w.status JOIN projects p ON p.id=w.project_id WHERE p.root=? AND w.project_id=? AND w.run_id=? AND w.work_id=? AND ws.id=?", [admission.scope.projectRoot, rows[0].project_id, retained.run_id, retained.work_id, retained.work_session_id]);
|
|
379
|
+
if (!accepted || crypto.createHash("sha256").update(accepted.result).digest("hex") !== retained.result_sha256 || accepted.status !== retained.response.status)
|
|
380
|
+
throw new AppError("invocation_outcome_pending", "Assigned Work settlement no longer matches retained result", 1, { effect: "unknown" });
|
|
381
|
+
return retained.response;
|
|
382
|
+
}
|
|
@@ -166,11 +166,11 @@ function gitFacts(workspacePath) {
|
|
|
166
166
|
if (!fs.existsSync(workspacePath)) {
|
|
167
167
|
return { status: "missing_workspace", actual_branch: null, dirty: null, path: workspacePath };
|
|
168
168
|
}
|
|
169
|
-
const branch = spawnSync("git", ["-C", workspacePath, "rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf8" });
|
|
169
|
+
const branch = spawnSync("git", ["-C", workspacePath, "rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf8", timeout: 5000 });
|
|
170
170
|
if (branch.status !== 0) {
|
|
171
|
-
return { status: "not_git_checkout", actual_branch: null, dirty: null, path: workspacePath };
|
|
171
|
+
return { status: branch.error || branch.signal ? "observation_unavailable" : "not_git_checkout", actual_branch: null, dirty: null, path: workspacePath };
|
|
172
172
|
}
|
|
173
|
-
const status = spawnSync("git", ["-C", workspacePath, "status", "--porcelain"], { encoding: "utf8" });
|
|
173
|
+
const status = spawnSync("git", ["-C", workspacePath, "status", "--porcelain"], { encoding: "utf8", timeout: 5000 });
|
|
174
174
|
return {
|
|
175
175
|
status: "ok",
|
|
176
176
|
actual_branch: branch.stdout.trim() || null,
|
package/dist/services/canon.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { AppError } from "../shared/errors.js";
|
|
5
|
+
import { prepareError } from "../cli/input-preparation.js";
|
|
6
|
+
import { resolveDdFlowHome } from "../storage/paths.js";
|
|
7
|
+
import { readSetupStatus } from "./setup.js";
|
|
4
8
|
const canonRootKey = "canon.root";
|
|
5
|
-
export function
|
|
9
|
+
export function prepareCanonRegistration(context, input) {
|
|
10
|
+
if (typeof input.root !== "string" || !input.root.trim())
|
|
11
|
+
return prepareError(new AppError("validation", "Canon root must be a non-empty path", 2));
|
|
6
12
|
const resolution = resolveCanonRoot(context, { explicitRoot: input.root, allowRegistered: false });
|
|
7
13
|
if (!resolution.ok || !resolution.canon) {
|
|
8
|
-
return {
|
|
9
|
-
...resolution,
|
|
10
|
-
action: "register",
|
|
11
|
-
exit_code: 1
|
|
12
|
-
};
|
|
14
|
+
return prepareError(new AppError("validation", "Canon root cannot be registered", 2, { root: input.root, blockers: resolution.blockers, candidates: resolution.candidates, bootstrap: resolution.bootstrap }));
|
|
13
15
|
}
|
|
16
|
+
return resolution.canon;
|
|
17
|
+
}
|
|
18
|
+
export function registerCanonRoot(context, input, canon = prepareCanonRegistration(context, input)) {
|
|
14
19
|
const now = context.now();
|
|
15
20
|
context.db.run(`INSERT INTO runtime_config (key, value_json, created_at, updated_at)
|
|
16
21
|
VALUES (?, ?, ?, ?)
|
|
17
22
|
ON CONFLICT(key) DO UPDATE SET
|
|
18
23
|
value_json = excluded.value_json,
|
|
19
|
-
updated_at = excluded.updated_at`, [canonRootKey, JSON.stringify({ root:
|
|
24
|
+
updated_at = excluded.updated_at`, [canonRootKey, JSON.stringify({ root: canon.root }), now, now]);
|
|
20
25
|
return {
|
|
21
26
|
ok: true,
|
|
22
27
|
action: "register",
|
|
23
28
|
canon: {
|
|
24
|
-
...
|
|
29
|
+
...canon,
|
|
25
30
|
source: "registered"
|
|
26
31
|
},
|
|
27
32
|
db_path: context.db.path
|
|
@@ -38,16 +43,21 @@ export function getCanonStatus(context, input = {}) {
|
|
|
38
43
|
export function resolveCanonRoot(context, input = {}) {
|
|
39
44
|
return resolveCanonCandidates(canonCandidates(context, input));
|
|
40
45
|
}
|
|
41
|
-
/** Read only: resolve
|
|
46
|
+
/** Read only: resolve canonical data without opening SQLite or running migrations. */
|
|
42
47
|
export function resolveCanonRootBeforeContext(env, input = {}) {
|
|
43
48
|
const candidates = [];
|
|
44
49
|
if (input.explicitRoot)
|
|
45
50
|
candidates.push(validateCanonCandidate("explicit", input.explicitRoot));
|
|
46
51
|
else if (env.DD_MEMORYBANK)
|
|
47
52
|
candidates.push(validateCanonCandidate("env", env.DD_MEMORYBANK));
|
|
48
|
-
else
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
else {
|
|
54
|
+
const installed = installedCanonCandidate(resolveDdFlowHome(env));
|
|
55
|
+
if (installed)
|
|
56
|
+
candidates.push(installed);
|
|
57
|
+
else
|
|
58
|
+
for (const known of knownCanonRoots())
|
|
59
|
+
candidates.push(validateCanonCandidate("known", known));
|
|
60
|
+
}
|
|
51
61
|
return resolveCanonCandidates(uniqueBy(candidates, (candidate) => `${candidate.source}:${candidate.root}`));
|
|
52
62
|
}
|
|
53
63
|
function resolveCanonCandidates(candidates) {
|
|
@@ -64,7 +74,7 @@ function resolveCanonCandidates(candidates) {
|
|
|
64
74
|
const memorybankRoot = candidate.memorybank_root ?? root;
|
|
65
75
|
const mbbRoot = candidate.mbb_root ?? path.join(memorybankRoot, "mbb");
|
|
66
76
|
const layout = candidate.layout ?? "legacy_root";
|
|
67
|
-
const metadata = readCanonMetadata(root, flowRoot);
|
|
77
|
+
const metadata = candidate.metadata ?? readCanonMetadata(root, flowRoot);
|
|
68
78
|
return {
|
|
69
79
|
ok: true,
|
|
70
80
|
canon: {
|
|
@@ -111,6 +121,30 @@ function resolveCanonCandidates(candidates) {
|
|
|
111
121
|
]
|
|
112
122
|
};
|
|
113
123
|
}
|
|
124
|
+
/** Archive provenance belongs to the selected release, not an ancestor Git
|
|
125
|
+
* checkout. A damaged installation is not permission to select nearby code. */
|
|
126
|
+
function installedCanonCandidate(home) {
|
|
127
|
+
if (!fs.existsSync(path.join(home, "installation.json")))
|
|
128
|
+
return null;
|
|
129
|
+
const status = readSetupStatus(home), installation = status.installation;
|
|
130
|
+
const invalid = (root, reason) => ({
|
|
131
|
+
source: "installed", root, realpath: null, valid: false, blockers: [reason]
|
|
132
|
+
});
|
|
133
|
+
if (!installation || status.installation_readiness !== "installed")
|
|
134
|
+
return invalid(home, "Installed canonical release is degraded; reconcile setup before selecting its canon.");
|
|
135
|
+
const roots = fs.readdirSync(installation.canon_root);
|
|
136
|
+
if (roots.length !== 1)
|
|
137
|
+
return invalid(installation.canon_root, "Installed canonical archive has no unique root.");
|
|
138
|
+
const candidate = validateCanonCandidate("installed", path.join(installation.canon_root, roots[0]));
|
|
139
|
+
if (!candidate.valid)
|
|
140
|
+
return candidate;
|
|
141
|
+
const version = readTrimmed(path.join(candidate.root, "VERSION"));
|
|
142
|
+
const flowContract = readFlowContractId(candidate.flow_root);
|
|
143
|
+
if (version !== installation.manifest.canon.version || !flowContract)
|
|
144
|
+
return invalid(candidate.root, "Installed canonical metadata differs from its release selection.");
|
|
145
|
+
return { ...candidate, metadata: { version, commit: installation.manifest.canon.commit,
|
|
146
|
+
flow_contract: flowContract, status: "present", diagnostics: [] } };
|
|
147
|
+
}
|
|
114
148
|
function canonCandidates(context, input) {
|
|
115
149
|
const candidates = [];
|
|
116
150
|
if (input.explicitRoot) {
|
|
@@ -126,8 +160,13 @@ function canonCandidates(context, input) {
|
|
|
126
160
|
candidates.push(validateCanonCandidate("registered", registered.root));
|
|
127
161
|
}
|
|
128
162
|
}
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
if (!candidates.length) {
|
|
164
|
+
const installed = installedCanonCandidate(context.ddFlowHome);
|
|
165
|
+
if (installed)
|
|
166
|
+
return [installed];
|
|
167
|
+
for (const known of knownCanonRoots()) {
|
|
168
|
+
candidates.push(validateCanonCandidate("known", known));
|
|
169
|
+
}
|
|
131
170
|
}
|
|
132
171
|
return uniqueBy(candidates, (candidate) => `${candidate.source}:${candidate.root}`);
|
|
133
172
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AppError } from "../shared/errors.js";
|
|
3
|
+
export function validateCheckEnvironment(value) {
|
|
4
|
+
if (value === undefined)
|
|
5
|
+
return undefined;
|
|
6
|
+
const entries = value && typeof value === "object" && !Array.isArray(value) ? Object.entries(value) : [];
|
|
7
|
+
if (!entries.length || entries.some(([key, selected]) => !["CODEX_HOME", "PLAYWRIGHT_BROWSERS_PATH"].includes(key)
|
|
8
|
+
|| typeof selected !== "string" || !selected || selected.length > 4096 || selected.includes("\0") || !path.isAbsolute(selected)))
|
|
9
|
+
throw new AppError("invalid_check_environment", "Owned checks require absolute known resource paths", 2, { effect: "no_effect" });
|
|
10
|
+
return { ...value };
|
|
11
|
+
}
|
|
12
|
+
export function retainedBrowserEnvironment(environment) {
|
|
13
|
+
return environment.PLAYWRIGHT_BROWSERS_PATH === undefined ? undefined
|
|
14
|
+
: validateCheckEnvironment({ PLAYWRIGHT_BROWSERS_PATH: environment.PLAYWRIGHT_BROWSERS_PATH });
|
|
15
|
+
}
|
|
16
|
+
export function ownedCheckEnvironment(environment, requested) {
|
|
17
|
+
const selected = validateCheckEnvironment(requested), retained = retainedBrowserEnvironment(environment);
|
|
18
|
+
if (retained?.PLAYWRIGHT_BROWSERS_PATH && selected?.PLAYWRIGHT_BROWSERS_PATH && retained.PLAYWRIGHT_BROWSERS_PATH !== selected.PLAYWRIGHT_BROWSERS_PATH)
|
|
19
|
+
throw new AppError("invalid_check_environment", "Owned browser resource cannot be rebound", 2, { effect: "no_effect" });
|
|
20
|
+
return retained || selected ? { ...retained, ...selected } : undefined;
|
|
21
|
+
}
|