@deksden-com/dd-flow-cli 0.9.0-beta.15 → 0.9.0-beta.151
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 +907 -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 +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 +79 -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/agy-terminal-envelope.mjs +67 -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 +1092 -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 +627 -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 +1200 -0
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +14 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +166 -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 +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 +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 +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 +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 +277 -0
- package/dist/services/check-runner-proof.js +305 -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 +1401 -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 +71 -0
- package/dist/services/controller-child-observer.js +121 -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 +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 +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 +1395 -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 +240 -18
- 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/dist/verification-components.json +299 -0
- package/package.json +51 -13
- package/tools/create-canon-release.mjs +33 -0
- package/tools/probe-codex-history.mjs +37 -0
- package/tools/produce-hybrid-release.mjs +41 -0
- package/tools/repair-paused-run-status.mjs +84 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { commandResult } from '../harness-runtime/lib/process-json.mjs';
|
|
4
|
+
import { SETUP_STARTUP_MS } from '../harness-runtime/lib/setup-progress.mjs';
|
|
4
5
|
import { isActiveProtocolStatus, isActiveQueueStatus, isQueueHistoryStatus } from "../domain/contracts.js";
|
|
5
6
|
import { AppError } from "../shared/errors.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
7
|
+
import { prepareOutputFile } from "../cli/input-preparation.js";
|
|
8
|
+
import { ensureDir, resolveProjectRoot, resolveProtocolPlanPath } from "../storage/paths.js";
|
|
9
|
+
import { dashboardMarkdownPath, globalDashboardHtmlPath, globalDashboardJsonPath, globalDashboardMarkdownPath, projectDashboardHtmlPath, projectDashboardJsonPath, projectDashboardDir, projectSummaryJsonPath, protocolDashboardHtmlPath, protocolDashboardJsonPath, readProjectConfig } from "./config.js";
|
|
8
10
|
import { queueForProject } from "./merge-queue.js";
|
|
9
11
|
import { publishProjectSummary } from "./project-summary.js";
|
|
10
12
|
import { requireProjectByRoot } from "./projects.js";
|
|
@@ -13,70 +15,82 @@ import { activeFlowSessionsForProject } from "./sessions.js";
|
|
|
13
15
|
import { usageForRun } from "./usage.js";
|
|
14
16
|
import { normalizeProtocolLifecycle } from "./protocol-lifecycle.js";
|
|
15
17
|
import { planSummary, planWithProgress } from "./plan-runtime.js";
|
|
16
|
-
export function getCmuxStatus(context, input) {
|
|
18
|
+
export async function getCmuxStatus(context, input) {
|
|
17
19
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
18
|
-
return { ok: true, project_root: project.root, cmux: detectCmux(context) };
|
|
20
|
+
return { ok: true, project_root: project.root, cmux: await detectCmux(context) };
|
|
19
21
|
}
|
|
20
|
-
export function
|
|
22
|
+
export function prepareDashboardRender(context, input) {
|
|
21
23
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
24
|
+
if (projectRecoveryGuarded(context, project.id))
|
|
25
|
+
throw new AppError("run_recovery_guarded", "Project dashboard is frozen while its RUN is retained for recovery", 1);
|
|
22
26
|
const format = parseDashboardFormat(input.format);
|
|
27
|
+
if (input.protocol)
|
|
28
|
+
requireProtocol(context, input.protocol, project.id);
|
|
29
|
+
const config = readProjectConfig(context, project.id);
|
|
30
|
+
const output = input.output
|
|
31
|
+
? path.resolve(project.root, input.output)
|
|
32
|
+
: format === "html"
|
|
33
|
+
? input.protocol ? protocolDashboardHtmlPath(context, project.id, input.protocol) : projectDashboardHtmlPath(context, project.id)
|
|
34
|
+
: dashboardMarkdownPath(project.root, config);
|
|
35
|
+
prepareOutputFile(output);
|
|
36
|
+
if (format === "html")
|
|
37
|
+
prepareOutputFile(input.protocol ? protocolDashboardJsonPath(context, project.id, input.protocol) : projectDashboardJsonPath(context, project.id));
|
|
38
|
+
return { project, format, output };
|
|
39
|
+
}
|
|
40
|
+
export function renderDashboard(context, input) {
|
|
41
|
+
const { project, format, output } = prepareDashboardRender(context, input);
|
|
23
42
|
if (format === "html") {
|
|
24
43
|
if (input.protocol) {
|
|
25
44
|
return renderProtocolDashboardHtml(context, project, input.protocol, input.output);
|
|
26
45
|
}
|
|
27
46
|
return renderProjectDashboardHtml(context, project, input.output);
|
|
28
47
|
}
|
|
29
|
-
const config = readProjectConfig(context, project.id);
|
|
30
|
-
const output = input.output
|
|
31
|
-
? path.resolve(path.isAbsolute(input.output) ? input.output : path.join(project.root, input.output))
|
|
32
|
-
: dashboardMarkdownPath(project.root, config);
|
|
33
48
|
const markdown = renderProjectDashboardMarkdown(context, project, output);
|
|
34
49
|
writeMarkdown(output, markdown);
|
|
35
50
|
return { ok: true, project_root: project.root, dashboard: { path: output, bytes: Buffer.byteLength(markdown) } };
|
|
36
51
|
}
|
|
37
|
-
export function
|
|
52
|
+
export function prepareGlobalDashboardRender(context, input = {}) {
|
|
38
53
|
const format = parseDashboardFormat(input.format);
|
|
54
|
+
const output = input.output ? path.resolve(input.output) : format === "html" ? globalDashboardHtmlPath(context) : globalDashboardMarkdownPath(context);
|
|
55
|
+
prepareOutputFile(output);
|
|
56
|
+
if (format === "html")
|
|
57
|
+
prepareOutputFile(globalDashboardJsonPath(context));
|
|
58
|
+
return { format, output };
|
|
59
|
+
}
|
|
60
|
+
export function renderGlobalDashboard(context, input = {}) {
|
|
61
|
+
const { format, output } = prepareGlobalDashboardRender(context, input);
|
|
39
62
|
if (format === "html") {
|
|
40
63
|
return renderGlobalDashboardHtml(context, input.output);
|
|
41
64
|
}
|
|
42
|
-
const output = input.output
|
|
43
|
-
? path.resolve(input.output)
|
|
44
|
-
: globalDashboardMarkdownPath(context);
|
|
45
65
|
const markdown = renderGlobalDashboardMarkdown(context, output);
|
|
46
66
|
writeMarkdown(output, markdown);
|
|
47
67
|
return { ok: true, dashboard: { path: output, bytes: Buffer.byteLength(markdown) } };
|
|
48
68
|
}
|
|
49
|
-
export function openDashboard(context, input) {
|
|
69
|
+
export async function openDashboard(context, input) {
|
|
70
|
+
prepareDashboardOptions(input);
|
|
50
71
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
51
72
|
const config = readProjectConfig(context, project.id);
|
|
52
73
|
const format = parseDashboardFormat(input.format, "html");
|
|
53
|
-
if (input.viewer && input.viewer !== "cmux") {
|
|
54
|
-
throw new AppError("validation", "--viewer must be cmux", 2);
|
|
55
|
-
}
|
|
56
74
|
const dashboardPath = format === "html" ? projectDashboardHtmlPath(context, project.id) : dashboardMarkdownPath(project.root, config);
|
|
57
75
|
return {
|
|
58
76
|
ok: true,
|
|
59
77
|
project_root: project.root,
|
|
60
78
|
dashboard: { path: dashboardPath },
|
|
61
|
-
open: openCmuxDashboard(context, project.root, dashboardPath, format)
|
|
79
|
+
open: await openCmuxDashboard(context, project.root, dashboardPath, format)
|
|
62
80
|
};
|
|
63
81
|
}
|
|
64
|
-
export function openGlobalDashboard(context, input = {}) {
|
|
65
|
-
|
|
66
|
-
throw new AppError("validation", "--viewer must be cmux", 2);
|
|
67
|
-
}
|
|
82
|
+
export async function openGlobalDashboard(context, input = {}) {
|
|
83
|
+
prepareDashboardOptions(input);
|
|
68
84
|
const format = parseDashboardFormat(input.format, "html");
|
|
69
85
|
const rendered = renderGlobalDashboard(context, { format });
|
|
70
86
|
return {
|
|
71
87
|
ok: true,
|
|
72
88
|
dashboard: rendered.dashboard,
|
|
73
|
-
open: openDashboardPath(context, rendered.dashboard.path, format)
|
|
89
|
+
open: await openDashboardPath(context, rendered.dashboard.path, format)
|
|
74
90
|
};
|
|
75
91
|
}
|
|
76
|
-
export function openProtocolDashboard(context, input) {
|
|
77
|
-
|
|
78
|
-
throw new AppError("validation", "--viewer must be cmux", 2);
|
|
79
|
-
}
|
|
92
|
+
export async function openProtocolDashboard(context, input) {
|
|
93
|
+
prepareDashboardOptions(input);
|
|
80
94
|
const format = parseDashboardFormat(input.format, "html");
|
|
81
95
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
82
96
|
if (format !== "html") {
|
|
@@ -90,17 +104,43 @@ export function openProtocolDashboard(context, input) {
|
|
|
90
104
|
project_root: project.root,
|
|
91
105
|
protocol_id: input.protocol,
|
|
92
106
|
dashboard: rendered.dashboard,
|
|
93
|
-
open: openCmuxDashboard(context, project.root, rendered.dashboard.path, format)
|
|
107
|
+
open: await openCmuxDashboard(context, project.root, rendered.dashboard.path, format)
|
|
94
108
|
};
|
|
95
109
|
}
|
|
96
|
-
export function
|
|
110
|
+
export function prepareDashboardRefresh(context, input) {
|
|
111
|
+
prepareDashboardOptions(input);
|
|
97
112
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
98
113
|
const config = readProjectConfig(context, project.id);
|
|
99
114
|
const format = parseDashboardFormat(input.format);
|
|
100
115
|
const openMode = input.open ?? "auto";
|
|
101
|
-
if (
|
|
102
|
-
|
|
116
|
+
if (config.dashboard.project) {
|
|
117
|
+
if (projectRecoveryGuarded(context, project.id))
|
|
118
|
+
throw new AppError("run_recovery_guarded", "Project dashboard is frozen while its RUN is retained for recovery", 1);
|
|
119
|
+
if (input.protocol)
|
|
120
|
+
requireProtocol(context, input.protocol, project.id);
|
|
121
|
+
prepareRefreshOutputs(context, project, config, format, input.protocol);
|
|
103
122
|
}
|
|
123
|
+
return { project, config, format, openMode };
|
|
124
|
+
}
|
|
125
|
+
function prepareRefreshOutputs(context, project, config, format, protocol) {
|
|
126
|
+
if (config.dashboard.project) {
|
|
127
|
+
if (!protocol)
|
|
128
|
+
prepareOutputFile(projectSummaryJsonPath(context, project.id));
|
|
129
|
+
if (format === "html") {
|
|
130
|
+
prepareOutputFile(protocol ? protocolDashboardHtmlPath(context, project.id, protocol) : projectDashboardHtmlPath(context, project.id));
|
|
131
|
+
prepareOutputFile(protocol ? protocolDashboardJsonPath(context, project.id, protocol) : projectDashboardJsonPath(context, project.id));
|
|
132
|
+
}
|
|
133
|
+
else
|
|
134
|
+
prepareOutputFile(dashboardMarkdownPath(project.root, config));
|
|
135
|
+
}
|
|
136
|
+
if (config.dashboard.global) {
|
|
137
|
+
prepareOutputFile(format === "html" ? globalDashboardHtmlPath(context) : globalDashboardMarkdownPath(context, config));
|
|
138
|
+
if (format === "html")
|
|
139
|
+
prepareOutputFile(globalDashboardJsonPath(context));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export async function refreshDashboard(context, input) {
|
|
143
|
+
const { project, config, format, openMode } = prepareDashboardRefresh(context, input);
|
|
104
144
|
if (!config.dashboard.project) {
|
|
105
145
|
return {
|
|
106
146
|
ok: true,
|
|
@@ -124,7 +164,7 @@ export function refreshDashboard(context, input) {
|
|
|
124
164
|
dashboard: rendered.dashboard,
|
|
125
165
|
project_summary: projectSummary,
|
|
126
166
|
global_dashboard: global.dashboard,
|
|
127
|
-
open: shouldOpen ? openCmuxDashboard(context, project.root, rendered.dashboard.path, format) : { ok: true, skipped: true, reason: "open_disabled" }
|
|
167
|
+
open: shouldOpen ? await openCmuxDashboard(context, project.root, rendered.dashboard.path, format) : { ok: true, skipped: true, reason: "open_disabled" }
|
|
128
168
|
};
|
|
129
169
|
}
|
|
130
170
|
export function refreshGlobalDashboard(context, input = {}) {
|
|
@@ -143,8 +183,9 @@ export function refreshAllDashboards(context, input = {}) {
|
|
|
143
183
|
return { ok: true, project_id: project.id, project_root: project.root, skipped: true, reason: "dashboard_project_disabled" };
|
|
144
184
|
}
|
|
145
185
|
try {
|
|
146
|
-
|
|
186
|
+
prepareRefreshOutputs(context, project, { ...config, dashboard: { ...config.dashboard, global: false } }, format);
|
|
147
187
|
const rendered = renderDashboard(context, { projectRoot: project.root, format });
|
|
188
|
+
const projectSummary = publishProjectSummary(context, { project });
|
|
148
189
|
return { ok: true, project_id: project.id, project_root: project.root, dashboard: rendered.dashboard, project_summary: projectSummary };
|
|
149
190
|
}
|
|
150
191
|
catch (error) {
|
|
@@ -170,10 +211,21 @@ export function refreshAllDashboards(context, input = {}) {
|
|
|
170
211
|
}
|
|
171
212
|
export function autoRefreshDashboards(context, input) {
|
|
172
213
|
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot));
|
|
173
|
-
|
|
214
|
+
// Hooks and usage ingestion continue to record receipts after capture.
|
|
215
|
+
// Their derived timestamp must not mutate the captured workspace.
|
|
216
|
+
if (projectRecoveryGuarded(context, project.id))
|
|
217
|
+
return { ok: true, skipped: true, reason: "run_recovery_guarded" };
|
|
218
|
+
const configured = readProjectConfig(context, project.id);
|
|
219
|
+
// Automatic observation must not change a memory or diagnostic source baseline.
|
|
220
|
+
// Keep projections in Home; do not hide runtime-created paths in Git or
|
|
221
|
+
// weaken source preservation by excluding user-owned .tasks directories.
|
|
222
|
+
const initializing = context.db.get("SELECT 1 FROM runs WHERE project_id=? AND flow_kind IN ('mb-init','mb-upgrade','mb-audit','project-review') AND (id=? OR status IN ('created','running','paused','waiting_for_user','blocked')) LIMIT 1", [project.id, input.runId ?? null]);
|
|
223
|
+
const config = initializing ? { ...configured, dashboard: { ...configured.dashboard,
|
|
224
|
+
markdown_path: path.join(projectDashboardDir(context.ddFlowHome, project.id), "project-dashboard.md") } } : configured;
|
|
174
225
|
if (!config.dashboard.auto_refresh) {
|
|
175
226
|
return { ok: true, skipped: true, reason: "dashboard_auto_refresh_disabled" };
|
|
176
227
|
}
|
|
228
|
+
prepareRefreshOutputs(context, project, config, "markdown");
|
|
177
229
|
const result = { ok: true, project_root: project.root };
|
|
178
230
|
if (config.dashboard.project) {
|
|
179
231
|
publishProjectSummary(context, { project });
|
|
@@ -196,6 +248,9 @@ export function autoRefreshDashboards(context, input) {
|
|
|
196
248
|
}
|
|
197
249
|
return result;
|
|
198
250
|
}
|
|
251
|
+
function projectRecoveryGuarded(context, projectId) {
|
|
252
|
+
return Boolean(context.db.get("SELECT 1 FROM run_recovery_guards WHERE project_id = ? AND status IN ('draining', 'sealed', 'resuming') LIMIT 1", [projectId]));
|
|
253
|
+
}
|
|
199
254
|
export function dashboardSummary(context, projectId, projectRoot) {
|
|
200
255
|
const config = readProjectConfig(context, projectId);
|
|
201
256
|
return {
|
|
@@ -221,13 +276,13 @@ export function dashboardData(context, input) {
|
|
|
221
276
|
}
|
|
222
277
|
return { ok: true, dashboard: buildProjectDashboardData(context, project, projectDashboardHtmlPath(context, project.id)) };
|
|
223
278
|
}
|
|
224
|
-
function openCmuxDashboard(context, projectRoot, dashboardPath, format = "markdown") {
|
|
279
|
+
async function openCmuxDashboard(context, projectRoot, dashboardPath, format = "markdown") {
|
|
225
280
|
const project = requireProjectByRoot(context, resolveProjectRoot(projectRoot));
|
|
226
281
|
const config = readProjectConfig(context, project.id);
|
|
227
282
|
if (config.integrations.cmux.mode === "off") {
|
|
228
283
|
return { ok: true, skipped: true, reason: "cmux_off" };
|
|
229
284
|
}
|
|
230
|
-
const cmux = detectCmux(context);
|
|
285
|
+
const cmux = await detectCmux(context);
|
|
231
286
|
if (!cmux.available) {
|
|
232
287
|
if (config.integrations.cmux.mode === "required") {
|
|
233
288
|
throw new AppError("cmux_unavailable", "cmux is required by project config but is unavailable", 1, { cmux });
|
|
@@ -238,20 +293,20 @@ function openCmuxDashboard(context, projectRoot, dashboardPath, format = "markdo
|
|
|
238
293
|
return { ok: true, opened: false, dry_run: true, command: cmuxOpenCommand(format, dashboardPath) };
|
|
239
294
|
}
|
|
240
295
|
const command = cmuxOpenCommand(format, dashboardPath);
|
|
241
|
-
const result =
|
|
242
|
-
if (result.
|
|
296
|
+
const result = await commandResult(command[0], command.slice(1), { startupMs: SETUP_STARTUP_MS });
|
|
297
|
+
if (result.exit_code !== 0) {
|
|
243
298
|
if (config.integrations.cmux.mode === "required") {
|
|
244
299
|
throw new AppError("cmux_open_failed", "cmux markdown open failed", 1, {
|
|
245
|
-
status: result.
|
|
300
|
+
status: result.exit_code,
|
|
246
301
|
stderr: result.stderr.trim()
|
|
247
302
|
});
|
|
248
303
|
}
|
|
249
|
-
return { ok: true, skipped: true, reason: "cmux_open_failed", status: result.
|
|
304
|
+
return { ok: true, skipped: true, reason: "cmux_open_failed", status: result.exit_code, stderr: result.stderr.trim() };
|
|
250
305
|
}
|
|
251
306
|
return { ok: true, opened: true, command };
|
|
252
307
|
}
|
|
253
|
-
function openDashboardPath(context, dashboardPath, format) {
|
|
254
|
-
const cmux = detectCmux(context);
|
|
308
|
+
async function openDashboardPath(context, dashboardPath, format) {
|
|
309
|
+
const cmux = await detectCmux(context);
|
|
255
310
|
if (!cmux.available) {
|
|
256
311
|
return { ok: true, skipped: true, reason: "cmux_unavailable", cmux };
|
|
257
312
|
}
|
|
@@ -259,9 +314,9 @@ function openDashboardPath(context, dashboardPath, format) {
|
|
|
259
314
|
return { ok: true, opened: false, dry_run: true, command: cmuxOpenCommand(format, dashboardPath) };
|
|
260
315
|
}
|
|
261
316
|
const command = cmuxOpenCommand(format, dashboardPath);
|
|
262
|
-
const result =
|
|
263
|
-
if (result.
|
|
264
|
-
return { ok: true, skipped: true, reason: "cmux_open_failed", status: result.
|
|
317
|
+
const result = await commandResult(command[0], command.slice(1), { startupMs: SETUP_STARTUP_MS });
|
|
318
|
+
if (result.exit_code !== 0) {
|
|
319
|
+
return { ok: true, skipped: true, reason: "cmux_open_failed", status: result.exit_code, stderr: result.stderr.trim() };
|
|
265
320
|
}
|
|
266
321
|
return { ok: true, opened: true, command };
|
|
267
322
|
}
|
|
@@ -270,17 +325,31 @@ function cmuxOpenCommand(format, dashboardPath) {
|
|
|
270
325
|
? ["cmux", "browser", "open", pathToFileUrl(dashboardPath)]
|
|
271
326
|
: ["cmux", "markdown", "open", dashboardPath];
|
|
272
327
|
}
|
|
273
|
-
function detectCmux(context) {
|
|
328
|
+
async function detectCmux(context) {
|
|
274
329
|
if (context.env.DD_FLOW_CMUX_AVAILABLE === "true") {
|
|
275
330
|
return { available: true, source: "env" };
|
|
276
331
|
}
|
|
277
332
|
if (context.env.DD_FLOW_CMUX_AVAILABLE === "false") {
|
|
278
333
|
return { available: false, source: "env", reason: "forced_unavailable" };
|
|
279
334
|
}
|
|
280
|
-
|
|
281
|
-
|
|
335
|
+
let result;
|
|
336
|
+
try {
|
|
337
|
+
result = await commandResult("cmux", ["--version"], { startupMs: SETUP_STARTUP_MS, phase: 'native-version' });
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
return { available: false, source: 'path', reason: error instanceof Error ? error.message : String(error) };
|
|
341
|
+
}
|
|
342
|
+
return result.exit_code === 0
|
|
282
343
|
? { available: true, source: "path", version: result.stdout.trim() }
|
|
283
|
-
: { available: false, source: "path", reason: result.
|
|
344
|
+
: { available: false, source: "path", reason: result.stderr.trim() || "cmux not found" };
|
|
345
|
+
}
|
|
346
|
+
export function prepareDashboardOptions(input) {
|
|
347
|
+
if (input.format !== undefined)
|
|
348
|
+
parseDashboardFormat(input.format);
|
|
349
|
+
if (input.viewer !== undefined && input.viewer !== "cmux")
|
|
350
|
+
throw new AppError("validation", "--viewer must be cmux", 2);
|
|
351
|
+
if (input.open !== undefined && !["auto", "true", "false"].includes(input.open))
|
|
352
|
+
throw new AppError("validation", "--open must be auto, true, or false", 2);
|
|
284
353
|
}
|
|
285
354
|
function parseDashboardFormat(value, defaultFormat = "markdown") {
|
|
286
355
|
const format = value ?? defaultFormat;
|
|
@@ -294,15 +363,18 @@ function renderProjectDashboardHtml(context, project, output) {
|
|
|
294
363
|
? path.resolve(path.isAbsolute(output) ? output : path.join(project.root, output))
|
|
295
364
|
: projectDashboardHtmlPath(context, project.id);
|
|
296
365
|
const jsonPath = projectDashboardJsonPath(context, project.id);
|
|
366
|
+
prepareOutputFile(htmlPath);
|
|
367
|
+
prepareOutputFile(jsonPath);
|
|
297
368
|
const data = buildProjectDashboardData(context, project, htmlPath);
|
|
298
369
|
const html = renderDashboardHtmlPage(data);
|
|
299
|
-
writeJsonFile(jsonPath, data);
|
|
300
|
-
writeTextFile(htmlPath, html);
|
|
301
370
|
const protocolCards = Array.isArray(data.protocol_cards) ? data.protocol_cards : [];
|
|
302
|
-
const
|
|
371
|
+
const preparedPages = protocolCards
|
|
303
372
|
.filter((card) => card.generate_page !== false)
|
|
304
373
|
.slice(0, 24)
|
|
305
|
-
.map((card) =>
|
|
374
|
+
.map((card) => prepareProtocolDashboardHtml(context, project, String(card.id)));
|
|
375
|
+
writeJsonFile(jsonPath, data);
|
|
376
|
+
writeTextFile(htmlPath, html);
|
|
377
|
+
const protocolPages = preparedPages.map(writeProtocolDashboardHtml)
|
|
306
378
|
.map((result) => ({
|
|
307
379
|
id: String(result.protocol_id),
|
|
308
380
|
path: result.dashboard.path,
|
|
@@ -321,12 +393,23 @@ function renderProjectDashboardHtml(context, project, output) {
|
|
|
321
393
|
};
|
|
322
394
|
}
|
|
323
395
|
function renderProtocolDashboardHtml(context, project, protocolId, output) {
|
|
396
|
+
return writeProtocolDashboardHtml(prepareProtocolDashboardHtml(context, project, protocolId, output));
|
|
397
|
+
}
|
|
398
|
+
function prepareProtocolDashboardHtml(context, project, protocolId, output) {
|
|
399
|
+
if (projectRecoveryGuarded(context, project.id))
|
|
400
|
+
throw new AppError("run_recovery_guarded", "Project dashboard is frozen while its RUN is retained for recovery", 1);
|
|
324
401
|
const htmlPath = output
|
|
325
402
|
? path.resolve(path.isAbsolute(output) ? output : path.join(project.root, output))
|
|
326
403
|
: protocolDashboardHtmlPath(context, project.id, protocolId);
|
|
327
404
|
const jsonPath = protocolDashboardJsonPath(context, project.id, protocolId);
|
|
405
|
+
prepareOutputFile(htmlPath);
|
|
406
|
+
prepareOutputFile(jsonPath);
|
|
328
407
|
const data = buildProtocolDashboardData(context, project, protocolId, htmlPath);
|
|
329
408
|
const html = renderDashboardHtmlPage(data);
|
|
409
|
+
return { project, protocolId, htmlPath, jsonPath, data, html };
|
|
410
|
+
}
|
|
411
|
+
function writeProtocolDashboardHtml(prepared) {
|
|
412
|
+
const { project, protocolId, htmlPath, jsonPath, data, html } = prepared;
|
|
330
413
|
writeJsonFile(jsonPath, data);
|
|
331
414
|
writeTextFile(htmlPath, html);
|
|
332
415
|
return {
|
|
@@ -344,6 +427,8 @@ function renderProtocolDashboardHtml(context, project, protocolId, output) {
|
|
|
344
427
|
function renderGlobalDashboardHtml(context, output) {
|
|
345
428
|
const htmlPath = output ? path.resolve(output) : globalDashboardHtmlPath(context);
|
|
346
429
|
const jsonPath = globalDashboardJsonPath(context);
|
|
430
|
+
prepareOutputFile(htmlPath);
|
|
431
|
+
prepareOutputFile(jsonPath);
|
|
347
432
|
const data = buildGlobalDashboardData(context, htmlPath);
|
|
348
433
|
const html = renderDashboardHtmlPage(data);
|
|
349
434
|
writeJsonFile(jsonPath, data);
|
|
@@ -888,12 +973,12 @@ function protocolsForProject(context, projectId) {
|
|
|
888
973
|
FROM protocols WHERE project_id = ? ORDER BY updated_at DESC`, [projectId]);
|
|
889
974
|
}
|
|
890
975
|
function planSummaryForProtocol(context, projectId, protocolId) {
|
|
891
|
-
const protocol = context.db.get("SELECT plan_path FROM protocols WHERE project_id = ? AND id = ?", [projectId, protocolId]);
|
|
976
|
+
const protocol = context.db.get("SELECT plan_path, project_root FROM protocols WHERE project_id = ? AND id = ?", [projectId, protocolId]);
|
|
892
977
|
if (!protocol) {
|
|
893
978
|
return { plan_id: "none", total: 0, done: 0, blocked: 0 };
|
|
894
979
|
}
|
|
895
980
|
try {
|
|
896
|
-
const summary = planSummary(context, { projectId, protocolId, planPath: protocol.plan_path }, { bind: false });
|
|
981
|
+
const summary = planSummary(context, { projectId, protocolId, planPath: resolveProtocolPlanPath(protocol.project_root, protocolId, protocol.plan_path) }, { bind: false });
|
|
897
982
|
return { plan_id: summary.plan_id, total: summary.total, done: summary.done, blocked: summary.blocked };
|
|
898
983
|
}
|
|
899
984
|
catch {
|
|
@@ -903,13 +988,13 @@ function planSummaryForProtocol(context, projectId, protocolId) {
|
|
|
903
988
|
function activePlanItems(context, projectId, protocols) {
|
|
904
989
|
const items = [];
|
|
905
990
|
for (const protocol of protocols) {
|
|
906
|
-
const record = context.db.get("SELECT plan_path FROM protocols WHERE project_id = ? AND id = ?", [projectId, protocol.id]);
|
|
991
|
+
const record = context.db.get("SELECT plan_path, project_root FROM protocols WHERE project_id = ? AND id = ?", [projectId, protocol.id]);
|
|
907
992
|
if (!record) {
|
|
908
993
|
continue;
|
|
909
994
|
}
|
|
910
995
|
let plan;
|
|
911
996
|
try {
|
|
912
|
-
plan = planWithProgress(context, { projectId, protocolId: protocol.id, planPath: record.plan_path }, { bind: false }).plan;
|
|
997
|
+
plan = planWithProgress(context, { projectId, protocolId: protocol.id, planPath: resolveProtocolPlanPath(record.project_root, protocol.id, record.plan_path) }, { bind: false }).plan;
|
|
913
998
|
}
|
|
914
999
|
catch {
|
|
915
1000
|
continue;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AppError } from "../shared/errors.js";
|
|
3
|
+
import { readDescriptorStageInput, readDescriptorStageInputForRecovery } from "./descriptor-stage-coordinator.js";
|
|
4
|
+
import { runtimeHarness } from "./execution-policy.js";
|
|
5
|
+
import { stageGraphScope } from "./stage-work-graph.js";
|
|
6
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
7
|
+
/** SQL-only physical coordinator proof, independent of allocation/prompt
|
|
8
|
+
* custody. It creates no Session, hook claim or provider operation.
|
|
9
|
+
*/
|
|
10
|
+
export function readDescriptorCoordinatorSession(context, input, refuse = reason => {
|
|
11
|
+
throw new AppError("descriptor_coordinator_session_invalid", "Coordinator has no matching physical Session custody", 1, { reason, effect: "no_effect" });
|
|
12
|
+
}) {
|
|
13
|
+
const { scope, bundle, workId } = input;
|
|
14
|
+
const rows = context.db.all("SELECT ws.id,ws.session_id,ws.hook_event_id,ws.prompt_path,ws.result_path,s.harness,s.provider_session_id FROM work_sessions ws JOIN sessions s ON s.session_id=ws.session_id AND s.project_id=? WHERE ws.work_id=? AND ws.status='running' AND s.run_id=? AND s.current_stage=? AND s.status='active' LIMIT 2", [scope.projectId, workId, scope.runId, scope.stage]);
|
|
15
|
+
if (rows.length !== 1)
|
|
16
|
+
refuse("active_coordinator_session_required");
|
|
17
|
+
const session = rows[0], route = bundle.execution.stage(scope.stage);
|
|
18
|
+
const selected = input.recoveryRead ? readDescriptorStageInputForRecovery(context, scope, bundle, input.recoveryRead) : readDescriptorStageInput(context, scope, bundle), directory = bundle.descriptor.stage(scope.stage).directory;
|
|
19
|
+
if (session.prompt_path !== path.join(selected.runRoot, directory, "coordinator-prompt.md")
|
|
20
|
+
|| session.result_path !== path.join(selected.runRoot, directory, "result-input.json"))
|
|
21
|
+
refuse("coordinator_packet_link_changed");
|
|
22
|
+
if (session.harness !== runtimeHarness(route.profile)
|
|
23
|
+
|| !context.db.get("SELECT 1 FROM hook_events WHERE project_id=? AND event_key=? AND session_id=? AND harness=? AND provider_session_id=? AND status='claimed' AND event_name='PreToolUse'", [scope.projectId, session.hook_event_id, session.session_id, session.harness, session.provider_session_id]))
|
|
24
|
+
refuse("coordinator_start_custody_missing");
|
|
25
|
+
const bindings = 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')=? LIMIT 33", [scope.projectId, scope.runId, scope.stage, session.id]);
|
|
26
|
+
if (!bindings.length || bindings.length > 32 || bindings.some(row => Buffer.byteLength(row.payload_json) > 32768))
|
|
27
|
+
refuse("physical_binding_missing");
|
|
28
|
+
const binding = JSON.parse(bindings[0].payload_json);
|
|
29
|
+
if (bindings.some(row => hybridDigest(JSON.parse(row.payload_json)) !== hybridDigest(binding))
|
|
30
|
+
|| binding.work_id !== workId || binding.session_id !== session.session_id || binding.harness !== session.harness || binding.provider_session_id !== session.provider_session_id
|
|
31
|
+
|| binding.execution_sha256 !== bundle.execution.sha256 || binding.profile_id !== route.profile.id || binding.profile_sha256 !== hybridDigest(route.profile)
|
|
32
|
+
|| binding.session_mode !== route.session_mode || hybridDigest(binding.scope) !== hybridDigest({ ...stageGraphScope(context, scope.projectId, scope.runId, scope.stage), stage: scope.stage }))
|
|
33
|
+
refuse("physical_binding_changed");
|
|
34
|
+
return hybridDigest({ session, binding });
|
|
35
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { AppError } from "../shared/errors.js";
|
|
2
|
+
import { assertPreparedRunBundleSqlAuthority } from "./runs.js";
|
|
3
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
4
|
+
import { nextWorkId } from "./ids.js";
|
|
5
|
+
import { appendAudit } from "./audit.js";
|
|
6
|
+
const event = "flow_run.descriptor_root_work";
|
|
7
|
+
function refuse(reason) {
|
|
8
|
+
throw new AppError("descriptor_root_work_invalid", "RUN root Work lacks independent allocation custody", 1, { reason, effect: "no_effect" });
|
|
9
|
+
}
|
|
10
|
+
const binding = (scope, bundle) => ({ projectId: scope.projectId, runId: scope.runId, bundle_sha256: bundle.sha256 });
|
|
11
|
+
/** SQL-only read. Root identity is retained independently, never discovered
|
|
12
|
+
* from an arbitrary root row or reconstructed after receipt loss.
|
|
13
|
+
*/
|
|
14
|
+
export function readDescriptorRootWork(context, scope, bundle) {
|
|
15
|
+
return context.db.readSnapshot(() => {
|
|
16
|
+
const run = assertPreparedRunBundleSqlAuthority(context, scope, bundle);
|
|
17
|
+
const receipts = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? LIMIT 2", [scope.projectId, event, scope.runId]);
|
|
18
|
+
if (receipts.length !== 1 || Buffer.byteLength(receipts[0].payload_json) > 16 * 1024)
|
|
19
|
+
refuse("root_work_receipt_missing");
|
|
20
|
+
const receipt = JSON.parse(receipts[0].payload_json);
|
|
21
|
+
const expected = binding(scope, bundle);
|
|
22
|
+
if (typeof receipt.work_id !== "string" || hybridDigest(receipt) !== hybridDigest({ run_id: scope.runId, work_id: receipt.work_id, binding: expected }))
|
|
23
|
+
refuse("root_work_changed");
|
|
24
|
+
const roots = context.db.all("SELECT work_id,task,payload_json,status,launch_policy,result_schema,depends_on_json FROM works WHERE project_id=? AND run_id=? AND parent_work_id IS NULL LIMIT 2", [scope.projectId, scope.runId]);
|
|
25
|
+
if (roots.length !== 1)
|
|
26
|
+
refuse("ambiguous_root_work");
|
|
27
|
+
const root = roots[0];
|
|
28
|
+
if (root.work_id !== receipt.work_id || root.task !== `Coordinate ${bundle.descriptor.descriptor.id}`
|
|
29
|
+
|| root.payload_json !== JSON.stringify({ descriptor_run_coordinator: expected })
|
|
30
|
+
|| root.launch_policy !== "reuse_allowed" || root.result_schema !== null || root.depends_on_json !== "[]")
|
|
31
|
+
refuse("root_work_custody_missing");
|
|
32
|
+
if (JSON.parse(run.index_json).root_work_id !== root.work_id)
|
|
33
|
+
refuse("root_work_anchor_missing");
|
|
34
|
+
return { workId: root.work_id, status: root.status };
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Called only in the same writer as fresh descriptor RUN allocation. Stage
|
|
38
|
+
* handlers consume this identity; they never allocate a second RUN root.
|
|
39
|
+
*/
|
|
40
|
+
export function allocateDescriptorRootWork(context, scope, bundle) {
|
|
41
|
+
assertPreparedRunBundleSqlAuthority(context, scope, bundle);
|
|
42
|
+
if (context.db.get("SELECT 1 FROM works WHERE project_id=? AND run_id=? AND parent_work_id IS NULL", [scope.projectId, scope.runId])
|
|
43
|
+
|| context.db.get("SELECT 1 FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=?", [scope.projectId, event, scope.runId]))
|
|
44
|
+
refuse("root_work_already_allocated");
|
|
45
|
+
const workId = nextWorkId(context, scope.projectId, bundle.descriptor.descriptor.id), now = context.now();
|
|
46
|
+
const expected = binding(scope, bundle);
|
|
47
|
+
context.db.run("INSERT INTO works (work_id,project_id,run_id,parent_work_id,task,launch_policy,depends_on_json,status,payload_json,created_at,updated_at) VALUES (?,?,?,NULL,?,'reuse_allowed','[]','created',?,?,?)", [workId, scope.projectId, scope.runId, `Coordinate ${bundle.descriptor.descriptor.id}`, JSON.stringify({ descriptor_run_coordinator: expected }), now, now]);
|
|
48
|
+
context.db.run("UPDATE runs SET index_json=json_set(index_json,'$.root_work_id',?) WHERE project_id=? AND id=?", [workId, scope.projectId, scope.runId]);
|
|
49
|
+
appendAudit(context, { projectId: scope.projectId, eventType: event, payload: { run_id: scope.runId, work_id: workId, binding: expected } });
|
|
50
|
+
if (readDescriptorRootWork(context, scope, bundle).workId !== workId)
|
|
51
|
+
refuse("root_work_not_retained");
|
|
52
|
+
return workId;
|
|
53
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { AppError } from "../shared/errors.js";
|
|
2
|
+
import { requireProjectByRoot } from "./projects.js";
|
|
3
|
+
import { resolveProjectRoot } from "../storage/paths.js";
|
|
4
|
+
import { appendFlowRunTimelineEvent, assertPreparedRunBundleSqlAuthority, completeDescriptorRunState, gitFacts, publishRunProjections, readFlowRunExecutionBundle, withStageSettlement } from "./runs.js";
|
|
5
|
+
import { readDescriptorRootWork } from "./descriptor-root-work.js";
|
|
6
|
+
import { readAcceptedDescriptorStageSettlement } from "./descriptor-stage-settlement.js";
|
|
7
|
+
import { entityReferenceVariants } from "../shared/entity-references.js";
|
|
8
|
+
import { stageLifecycleMatchKey } from "./hooks.js";
|
|
9
|
+
import { readAcceptedStageData } from "./stage-report-renderer.js";
|
|
10
|
+
import { assertRunMutationAllowed } from "./run-recovery-guard.js";
|
|
11
|
+
import { appendAudit } from "./audit.js";
|
|
12
|
+
import { hybridDigest } from "./hybrid-contracts.js";
|
|
13
|
+
const event = "flow_run.descriptor_run_settlement";
|
|
14
|
+
function refuse(reason) {
|
|
15
|
+
throw new AppError("descriptor_run_settlement_invalid", "Terminal descriptor RUN lacks exact settlement custody", 1, { reason, effect: "no_effect" });
|
|
16
|
+
}
|
|
17
|
+
function selected(context, scope, bundle, matchKeys) {
|
|
18
|
+
assertPreparedRunBundleSqlAuthority(context, scope, bundle);
|
|
19
|
+
const root = readDescriptorRootWork(context, scope, bundle);
|
|
20
|
+
const run = context.db.get("SELECT status,index_json FROM runs WHERE project_id=? AND id=?", [scope.projectId, scope.runId]);
|
|
21
|
+
const index = JSON.parse(run.index_json);
|
|
22
|
+
const terminal = index.stage_runs.at(-1);
|
|
23
|
+
if (!bundle.descriptor.descriptor.terminal_stages.includes(scope.stage)
|
|
24
|
+
|| terminal?.stage !== scope.stage || terminal.status !== "done")
|
|
25
|
+
refuse("terminal_stage_not_accepted");
|
|
26
|
+
const data = readAcceptedStageData(context, scope);
|
|
27
|
+
const stageReceipt = readAcceptedDescriptorStageSettlement(context, scope, bundle, matchKeys);
|
|
28
|
+
if (context.db.get("SELECT 1 FROM works WHERE project_id=? AND run_id=? AND work_id<>? AND status IN ('created','running','paused') LIMIT 1", [scope.projectId, scope.runId, root.workId])
|
|
29
|
+
|| context.db.get("SELECT 1 FROM work_sessions ws JOIN works w ON w.work_id=ws.work_id WHERE w.project_id=? AND w.run_id=? AND ws.status='running' LIMIT 1", [scope.projectId, scope.runId]))
|
|
30
|
+
refuse("work_still_active");
|
|
31
|
+
const prior = context.db.all("SELECT payload_json FROM audit_events WHERE project_id=? AND event_type=? AND json_extract(payload_json,'$.run_id')=? LIMIT 2", [scope.projectId, event, scope.runId]);
|
|
32
|
+
if (prior.length > 1 || prior.some(row => Buffer.byteLength(row.payload_json) > 32 * 1024))
|
|
33
|
+
refuse("ambiguous_receipt");
|
|
34
|
+
if (root.status !== (prior.length ? "completed" : "running") || run.status !== (prior.length ? "done" : "running"))
|
|
35
|
+
refuse("terminal_state_changed");
|
|
36
|
+
return { rootId: root.workId, result: data.bytes.toString("utf8"), binding: { ...scope, work_id: root.workId, bundle_sha256: bundle.sha256, result_sha256: data.result.sha256, input_sha256: data.input_sha256, stage_receipt_sha256: hybridDigest(stageReceipt) }, prior: prior[0] ? JSON.parse(prior[0].payload_json) : null };
|
|
37
|
+
}
|
|
38
|
+
/** Runtime closure only. A terminal handler must first verify semantic/check/
|
|
39
|
+
* review/Git acceptance, revalidate physical proof, and supply its SQL fence.
|
|
40
|
+
* Transcript usage collection is deliberately outside this atomic writer.
|
|
41
|
+
*/
|
|
42
|
+
export class PreparedDescriptorRunSettlement {
|
|
43
|
+
#scope;
|
|
44
|
+
#bundle;
|
|
45
|
+
#owner;
|
|
46
|
+
#git;
|
|
47
|
+
#generation;
|
|
48
|
+
#matchKeys;
|
|
49
|
+
constructor(scope, bundle, owner, git, generation, matchKeys) {
|
|
50
|
+
this.#scope = scope;
|
|
51
|
+
this.#bundle = bundle;
|
|
52
|
+
this.#owner = owner;
|
|
53
|
+
this.#git = git;
|
|
54
|
+
this.#generation = generation;
|
|
55
|
+
this.#matchKeys = matchKeys;
|
|
56
|
+
Object.freeze(this);
|
|
57
|
+
}
|
|
58
|
+
static prepare(context, input) {
|
|
59
|
+
const project = requireProjectByRoot(context, resolveProjectRoot(input.projectRoot)), bundle = readFlowRunExecutionBundle(context, input);
|
|
60
|
+
if (!bundle)
|
|
61
|
+
refuse("bundle_required");
|
|
62
|
+
const scope = { projectId: project.id, runId: input.runId, stage: input.stage };
|
|
63
|
+
const matchKeys = entityReferenceVariants(input.runId).map(reference => stageLifecycleMatchKey("stage_finish", reference, input.stage, input.projectRoot));
|
|
64
|
+
const snapshot = context.db.readSnapshot(() => ({ owner: selected(context, scope, bundle, matchKeys), generation: assertRunMutationAllowed(context, scope.projectId, scope.runId) }));
|
|
65
|
+
const operational = assertPreparedRunBundleSqlAuthority(context, scope, bundle);
|
|
66
|
+
const git = snapshot.owner.prior?.git ?? gitFacts(operational.workspace_root ?? operational.project_root);
|
|
67
|
+
return new PreparedDescriptorRunSettlement(scope, bundle, snapshot.owner, git, snapshot.generation, matchKeys);
|
|
68
|
+
}
|
|
69
|
+
apply(context, assertHandlerCustody) {
|
|
70
|
+
if (typeof assertHandlerCustody !== "function")
|
|
71
|
+
refuse("handler_fence_required");
|
|
72
|
+
const operational = assertPreparedRunBundleSqlAuthority(context, this.#scope, this.#bundle);
|
|
73
|
+
const bundle = readFlowRunExecutionBundle(context, { projectRoot: operational.project_root, runId: this.#scope.runId });
|
|
74
|
+
if (!bundle || bundle.sha256 !== this.#bundle.sha256)
|
|
75
|
+
refuse("bundle_changed");
|
|
76
|
+
const observed = context.db.readSnapshot(() => selected(context, this.#scope, this.#bundle, this.#matchKeys));
|
|
77
|
+
if (!observed.prior && hybridDigest(gitFacts(operational.workspace_root ?? operational.project_root)) !== hybridDigest(this.#git))
|
|
78
|
+
refuse("git_observation_changed");
|
|
79
|
+
const receipt = { run_id: this.#scope.runId, work_id: this.#owner.rootId, binding: this.#owner.binding, git: this.#git };
|
|
80
|
+
const changed = withStageSettlement(context, () => {
|
|
81
|
+
assertRunMutationAllowed(context, this.#scope.projectId, this.#scope.runId, this.#generation);
|
|
82
|
+
assertHandlerCustody(context);
|
|
83
|
+
const current = selected(context, this.#scope, this.#bundle, this.#matchKeys);
|
|
84
|
+
if (hybridDigest(current.binding) !== hybridDigest(this.#owner.binding) || current.result !== this.#owner.result)
|
|
85
|
+
refuse("terminal_custody_changed");
|
|
86
|
+
if (current.prior) {
|
|
87
|
+
if (hybridDigest(current.prior) !== hybridDigest(receipt)
|
|
88
|
+
|| context.db.get("SELECT result FROM works WHERE work_id=?", [current.rootId])?.result !== current.result)
|
|
89
|
+
refuse("settlement_changed");
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (this.#owner.prior)
|
|
93
|
+
refuse("settlement_receipt_missing");
|
|
94
|
+
const now = context.now();
|
|
95
|
+
if (context.db.run("UPDATE works SET status='completed',result=?,completed_at=?,updated_at=? WHERE work_id=? AND project_id=? AND run_id=? AND status='running'", [current.result, now, now, current.rootId, this.#scope.projectId, this.#scope.runId]).changes !== 1)
|
|
96
|
+
refuse("root_changed");
|
|
97
|
+
appendFlowRunTimelineEvent(context, this.#scope.projectId, this.#scope.runId, { at: now, type: "work_completed", work_id: current.rootId, descriptor_terminal: true });
|
|
98
|
+
completeDescriptorRunState(context, this.#scope, this.#bundle, this.#git);
|
|
99
|
+
appendAudit(context, { projectId: this.#scope.projectId, eventType: event, payload: receipt });
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
// A committed terminal receipt can outlive an interrupted file publisher.
|
|
103
|
+
// Replay restores projections from current SQL, without settling again.
|
|
104
|
+
publishRunProjections(context, this.#scope.projectId, this.#scope.runId);
|
|
105
|
+
return { changed, run_id: this.#scope.runId, work_id: this.#owner.rootId, status: "done" };
|
|
106
|
+
}
|
|
107
|
+
}
|