@intentius/chant 0.124.27 → 0.124.29
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/README.md +1 -1
- package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/dist/__golden__/wave-loop/op-held-on.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/dist/__golden__/wave-loop/op-per-run.json +7 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
- package/dist/__golden__/wave-loop/op-sealed.json +3 -0
- package/dist/__golden__/wave-loop/op-spend.json +3 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/dist/build-params.d.ts +34 -1
- package/dist/build-params.d.ts.map +1 -1
- package/dist/build-params.js +31 -1
- package/dist/change-set-graph.d.ts +63 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +130 -0
- package/dist/change-set.d.ts +62 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +36 -4
- package/dist/chant-version.d.ts +9 -0
- package/dist/chant-version.d.ts.map +1 -0
- package/dist/chant-version.js +16 -0
- package/dist/cli/build-params-cli.d.ts +7 -1
- package/dist/cli/build-params-cli.d.ts.map +1 -1
- package/dist/cli/build-params-cli.js +17 -8
- package/dist/cli/commands/build.d.ts +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +15 -11
- package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.js +30 -2
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.js +13 -2
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.js +17 -8
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +64 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +43 -4
- package/dist/cli/handlers/change-set.d.ts +10 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.js +51 -1
- package/dist/cli/handlers/fan-out.d.ts +10 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +54 -6
- package/dist/cli/handlers/lifecycle-gc.d.ts +19 -0
- package/dist/cli/handlers/lifecycle-gc.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-gc.js +143 -0
- package/dist/cli/handlers/pr.d.ts +16 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +269 -37
- package/dist/cli/handlers/promote.d.ts +7 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +440 -28
- package/dist/cli/handlers/release.d.ts +91 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +589 -0
- package/dist/cli/handlers/run.d.ts +38 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +234 -16
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +143 -17
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -5
- package/dist/cli/registry.d.ts +43 -5
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +30 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +49 -0
- package/dist/cli/version.d.ts +3 -5
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +3 -13
- package/dist/codegen/docs-in-site.d.ts +71 -0
- package/dist/codegen/docs-in-site.d.ts.map +1 -0
- package/dist/codegen/docs-in-site.js +177 -0
- package/dist/codegen/docs-types.d.ts +14 -1
- package/dist/codegen/docs-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts +18 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +40 -7
- package/dist/codegen/rehype-base-url.mjs +15 -9
- package/dist/components/auto-release.d.ts +6 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +3 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +6 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +10 -9
- package/dist/components/driver.d.ts +50 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +116 -54
- package/dist/components/fan-out-inputs.d.ts +69 -0
- package/dist/components/fan-out-inputs.d.ts.map +1 -0
- package/dist/components/fan-out-inputs.js +169 -0
- package/dist/components/fan-out-record.d.ts +13 -0
- package/dist/components/fan-out-record.d.ts.map +1 -1
- package/dist/components/fan-out-record.js +16 -0
- package/dist/components/fan-out-run.d.ts +7 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +85 -26
- package/dist/components/fan-out.d.ts +4 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/pr-pipeline.d.ts +25 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +22 -4
- package/dist/components/pr-run.d.ts +11 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +20 -1
- package/dist/components/promote-order.d.ts +38 -0
- package/dist/components/promote-order.d.ts.map +1 -0
- package/dist/components/promote-order.js +62 -0
- package/dist/components/promote.d.ts +38 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +77 -2
- package/dist/components/release-compile.d.ts +142 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +382 -0
- package/dist/components/release-gate.d.ts +135 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +288 -0
- package/dist/components/release-promote.d.ts +96 -0
- package/dist/components/release-promote.d.ts.map +1 -0
- package/dist/components/release-promote.js +204 -0
- package/dist/components/run-progress.d.ts +7 -0
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +8 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +11 -3
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/flag-params.d.ts +54 -0
- package/dist/flag-params.d.ts.map +1 -0
- package/dist/flag-params.js +130 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts +120 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.js +304 -0
- package/dist/lifecycle/change-set-store.d.ts +68 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +97 -0
- package/dist/lifecycle/commit-sha.d.ts +13 -0
- package/dist/lifecycle/commit-sha.d.ts.map +1 -0
- package/dist/lifecycle/commit-sha.js +21 -0
- package/dist/lifecycle/delivery-metrics.d.ts +139 -0
- package/dist/lifecycle/delivery-metrics.d.ts.map +1 -0
- package/dist/lifecycle/delivery-metrics.js +145 -0
- package/dist/lifecycle/deploy-outcome.d.ts +81 -0
- package/dist/lifecycle/deploy-outcome.d.ts.map +1 -0
- package/dist/lifecycle/deploy-outcome.js +101 -0
- package/dist/lifecycle/gate-change-set.d.ts +78 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +138 -0
- package/dist/lifecycle/gate-ledger.d.ts +51 -4
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- package/dist/lifecycle/git.d.ts +30 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +31 -5
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/mixed-environment.d.ts +95 -0
- package/dist/lifecycle/mixed-environment.d.ts.map +1 -0
- package/dist/lifecycle/mixed-environment.js +154 -0
- package/dist/lifecycle/publish-attachments.d.ts +79 -0
- package/dist/lifecycle/publish-attachments.d.ts.map +1 -0
- package/dist/lifecycle/publish-attachments.js +179 -0
- package/dist/lifecycle/publish-credentials.d.ts +37 -0
- package/dist/lifecycle/publish-credentials.d.ts.map +1 -0
- package/dist/lifecycle/publish-credentials.js +69 -0
- package/dist/lifecycle/publish-declaration.d.ts +97 -0
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -0
- package/dist/lifecycle/publish-declaration.js +83 -0
- package/dist/lifecycle/publish-forge.d.ts +53 -0
- package/dist/lifecycle/publish-forge.d.ts.map +1 -0
- package/dist/lifecycle/publish-forge.js +298 -0
- package/dist/lifecycle/publish-npm.d.ts +61 -0
- package/dist/lifecycle/publish-npm.d.ts.map +1 -0
- package/dist/lifecycle/publish-npm.js +242 -0
- package/dist/lifecycle/publish-oci.d.ts +64 -0
- package/dist/lifecycle/publish-oci.d.ts.map +1 -0
- package/dist/lifecycle/publish-oci.js +383 -0
- package/dist/lifecycle/publish-record.d.ts +66 -0
- package/dist/lifecycle/publish-record.d.ts.map +1 -0
- package/dist/lifecycle/publish-record.js +84 -0
- package/dist/lifecycle/publish-targets.d.ts +45 -0
- package/dist/lifecycle/publish-targets.d.ts.map +1 -0
- package/dist/lifecycle/publish-targets.js +85 -0
- package/dist/lifecycle/release-cut.d.ts +154 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +366 -0
- package/dist/lifecycle/release-join.d.ts +95 -0
- package/dist/lifecycle/release-join.d.ts.map +1 -0
- package/dist/lifecycle/release-join.js +139 -0
- package/dist/lifecycle/release-ledger.d.ts +54 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +53 -20
- package/dist/lifecycle/release-publish.d.ts +312 -0
- package/dist/lifecycle/release-publish.d.ts.map +1 -0
- package/dist/lifecycle/release-publish.js +335 -0
- package/dist/lifecycle/release-revocation.d.ts +80 -0
- package/dist/lifecycle/release-revocation.d.ts.map +1 -0
- package/dist/lifecycle/release-revocation.js +123 -0
- package/dist/lifecycle/release-store.d.ts +200 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +320 -0
- package/dist/lifecycle/release-verify.d.ts +61 -0
- package/dist/lifecycle/release-verify.d.ts.map +1 -0
- package/dist/lifecycle/release-verify.js +92 -0
- package/dist/lifecycle/release-workstation.d.ts +91 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -0
- package/dist/lifecycle/release-workstation.js +180 -0
- package/dist/lifecycle/retention-policy.d.ts +45 -0
- package/dist/lifecycle/retention-policy.d.ts.map +1 -0
- package/dist/lifecycle/retention-policy.js +43 -0
- package/dist/lifecycle/retention.d.ts +185 -0
- package/dist/lifecycle/retention.d.ts.map +1 -0
- package/dist/lifecycle/retention.js +400 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +2 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.js +4 -2
- package/dist/op/activities/source-release.d.ts.map +1 -1
- package/dist/op/activities/source-release.js +7 -3
- package/dist/op/activities/source-rollback.d.ts.map +1 -1
- package/dist/op/activities/source-rollback.js +7 -3
- package/dist/op/gate-name.d.ts +11 -2
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +12 -3
- package/dist/op/gate-run-locator.d.ts +22 -0
- package/dist/op/gate-run-locator.d.ts.map +1 -1
- package/dist/op/gate-run-locator.js +31 -0
- package/dist/op/gate.d.ts +27 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +57 -3
- package/dist/op/local-executor.d.ts +36 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +158 -52
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +4 -0
- package/dist/op/run-live.d.ts +2 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/run-live.js +1 -1
- package/dist/op/runtime.d.ts +46 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/runtimes/local.js +8 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/pr-loop.d.ts +7 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +23 -4
- package/dist/pr-report-url.d.ts +82 -0
- package/dist/pr-report-url.d.ts.map +1 -0
- package/dist/pr-report-url.js +174 -0
- package/dist/provenance.d.ts +2 -2
- package/dist/provenance.d.ts.map +1 -1
- package/dist/run-event-store.d.ts +104 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +251 -0
- package/dist/run-event-stream.d.ts +133 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +242 -0
- package/dist/run-event.d.ts +285 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +209 -0
- package/dist/wave-runtime.mjs +262 -226
- package/dist/workspace/__fixtures__/flag-workspace.d.ts +31 -0
- package/dist/workspace/__fixtures__/flag-workspace.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/flag-workspace.js +114 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts +19 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/run-event-check.js +59 -0
- package/dist/workspace/change-set-show.d.ts +56 -0
- package/dist/workspace/change-set-show.d.ts.map +1 -0
- package/dist/workspace/change-set-show.js +54 -0
- package/dist/workspace/change-set-show.schema.json +102 -0
- package/dist/workspace/change-set.schema.json +32 -1
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes-cli.js +10 -1
- package/dist/workspace/changes.d.ts +37 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/changes.js +49 -2
- package/dist/workspace/changes.schema.json +135 -0
- package/dist/workspace/check.schema.json +4 -2
- package/dist/workspace/checks/records.d.ts +9 -1
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks/records.js +35 -1
- package/dist/workspace/checks.d.ts +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +2 -1
- package/dist/workspace/ci-green-cli.d.ts +19 -4
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +75 -12
- package/dist/workspace/ci-green-forge.d.ts +20 -3
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +6 -4
- package/dist/workspace/ci-green-workflow.d.ts +11 -0
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +6 -0
- package/dist/workspace/ci-green.d.ts +281 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +456 -38
- package/dist/workspace/ci-last-green.schema.json +32 -2
- package/dist/workspace/ci-list.schema.json +525 -0
- package/dist/workspace/commit-links.d.ts +85 -0
- package/dist/workspace/commit-links.d.ts.map +1 -0
- package/dist/workspace/commit-links.js +163 -0
- package/dist/workspace/declaration.d.ts +35 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +27 -1
- package/dist/workspace/declaration.schema.json +76 -0
- package/dist/workspace/declared-kinds.d.ts +16 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/declared-kinds.js +25 -0
- package/dist/workspace/delivery-metrics.d.ts +91 -0
- package/dist/workspace/delivery-metrics.d.ts.map +1 -0
- package/dist/workspace/delivery-metrics.js +217 -0
- package/dist/workspace/delivery-metrics.schema.json +519 -0
- package/dist/workspace/flags-read.d.ts +37 -0
- package/dist/workspace/flags-read.d.ts.map +1 -0
- package/dist/workspace/flags-read.js +103 -0
- package/dist/workspace/flags.d.ts +100 -0
- package/dist/workspace/flags.d.ts.map +1 -0
- package/dist/workspace/flags.js +98 -0
- package/dist/workspace/graph-cli.js +1 -1
- package/dist/workspace/identity-gate-rule.d.ts +37 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +72 -7
- package/dist/workspace/identity.d.ts +12 -0
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/identity.js +13 -1
- package/dist/workspace/intent-cli.d.ts +11 -2
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-cli.js +54 -5
- package/dist/workspace/intent-trace.d.ts +219 -0
- package/dist/workspace/intent-trace.d.ts.map +1 -0
- package/dist/workspace/intent-trace.js +314 -0
- package/dist/workspace/intent.d.ts +36 -7
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +192 -22
- package/dist/workspace/intent.schema.json +702 -6
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +2 -0
- package/dist/workspace/ls.schema.json +3 -1
- package/dist/workspace/member-pipeline.d.ts +6 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +6 -0
- package/dist/workspace/overlap.d.ts +146 -0
- package/dist/workspace/overlap.d.ts.map +1 -0
- package/dist/workspace/overlap.js +276 -0
- package/dist/workspace/promotion-order.d.ts +41 -0
- package/dist/workspace/promotion-order.d.ts.map +1 -0
- package/dist/workspace/promotion-order.js +95 -0
- package/dist/workspace/reason-codes.d.ts +4 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +7 -1
- package/dist/workspace/records.d.ts +15 -2
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/records.js +32 -0
- package/dist/workspace/records.schema.json +21 -2
- package/dist/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/dist/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/dist/workspace/releases.d.ts +81 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +103 -0
- package/dist/workspace/releases.schema.json +513 -0
- package/dist/workspace/run-event.schema.json +295 -0
- package/dist/workspace/status-gates.d.ts +34 -1
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +31 -2
- package/dist/workspace/status-stewards.d.ts +4 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +2 -0
- package/dist/workspace/status.d.ts +117 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +218 -4
- package/dist/workspace/status.schema.json +268 -2
- package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
- package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
- package/dist/workspace/trust/ci-tag-statement.js +123 -0
- package/dist/workspace/trust/op-run-statement.d.ts +91 -0
- package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/op-run-statement.js +143 -0
- package/dist/workspace/trust/rotation.d.ts +18 -2
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.js +65 -16
- package/dist/workspace/trust/seal.d.ts +11 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +9 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/ssh-commit.js +10 -10
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/src/__golden__/wave-loop/fan-out-only.json +6 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/src/__golden__/wave-loop/op-cost-member.json +3 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/src/__golden__/wave-loop/op-held-on.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/src/__golden__/wave-loop/op-per-run.json +7 -0
- package/src/__golden__/wave-loop/op-pr-review.json +7 -0
- package/src/__golden__/wave-loop/op-sealed.json +3 -0
- package/src/__golden__/wave-loop/op-spend.json +3 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +141 -0
- package/src/change-set.ts +87 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +25 -11
- package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
- package/src/cli/commands/check-lexicon-docs.ts +39 -2
- package/src/cli/commands/check-lexicon.ts +14 -2
- package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
- package/src/cli/commands/init-lexicon.test.ts +25 -0
- package/src/cli/commands/init-lexicon.ts +18 -8
- package/src/cli/handlers/approve-release.test.ts +84 -0
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +65 -2
- package/src/cli/handlers/build.test.ts +67 -0
- package/src/cli/handlers/build.ts +46 -4
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +228 -1
- package/src/cli/handlers/fan-out.ts +53 -6
- package/src/cli/handlers/intent-trace.e2e.test.ts +201 -0
- package/src/cli/handlers/lifecycle-gc.test.ts +126 -0
- package/src/cli/handlers/lifecycle-gc.ts +146 -0
- package/src/cli/handlers/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +341 -0
- package/src/cli/handlers/pr.ts +292 -47
- package/src/cli/handlers/promote.test.ts +669 -7
- package/src/cli/handlers/promote.ts +464 -29
- package/src/cli/handlers/release-implicit.e2e.test.ts +161 -0
- package/src/cli/handlers/release-join.e2e.test.ts +185 -0
- package/src/cli/handlers/release-publish-targets.e2e.test.ts +295 -0
- package/src/cli/handlers/release-verify.e2e.test.ts +117 -0
- package/src/cli/handlers/release-workstation-ci.e2e.test.ts +135 -0
- package/src/cli/handlers/release.e2e.test.ts +199 -0
- package/src/cli/handlers/release.ts +593 -0
- package/src/cli/handlers/run-auto-release.test.ts +80 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +243 -18
- package/src/cli/main.test.ts +8 -0
- package/src/cli/main.ts +143 -17
- package/src/cli/mcp/never-over-mcp.test.ts +2 -0
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +56 -5
- package/src/cli/registry.ts +43 -5
- package/src/cli/run-events.ts +57 -0
- package/src/cli/version.ts +3 -13
- package/src/codegen/docs-in-site.test.ts +166 -0
- package/src/codegen/docs-in-site.ts +182 -0
- package/src/codegen/docs-site/AgentPrompt.astro +26 -1
- package/src/codegen/docs-types.ts +14 -1
- package/src/codegen/docs.ts +60 -7
- package/src/codegen/rehype-base-url.d.mts +3 -1
- package/src/codegen/rehype-base-url.mjs +15 -9
- package/src/codegen/rehype-base-url.test.ts +34 -0
- package/src/components/auto-release.test.ts +30 -0
- package/src/components/auto-release.ts +9 -1
- package/src/components/capability.ts +9 -0
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +165 -56
- package/src/components/fan-out-inputs.test.ts +85 -0
- package/src/components/fan-out-inputs.ts +192 -0
- package/src/components/fan-out-record.test.ts +10 -0
- package/src/components/fan-out-record.ts +19 -0
- package/src/components/fan-out-run.ts +104 -35
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +35 -4
- package/src/components/pr-run.ts +30 -1
- package/src/components/promote-order.test.ts +90 -0
- package/src/components/promote-order.ts +75 -0
- package/src/components/promote.test.ts +10 -1
- package/src/components/promote.ts +94 -3
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +459 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +355 -0
- package/src/components/release-promote.test.ts +159 -0
- package/src/components/release-promote.ts +232 -0
- package/src/components/run-progress.ts +7 -0
- package/src/components/wave-plan.ts +16 -3
- package/src/config.ts +15 -1
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/index.ts +2 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +113 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +164 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +68 -3
- package/src/lifecycle/git.ts +61 -8
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/mixed-environment.test.ts +97 -0
- package/src/lifecycle/mixed-environment.ts +204 -0
- package/src/lifecycle/publish-attachments.ts +196 -0
- package/src/lifecycle/publish-credentials.ts +84 -0
- package/src/lifecycle/publish-declaration.ts +95 -0
- package/src/lifecycle/publish-forge.ts +325 -0
- package/src/lifecycle/publish-npm.ts +259 -0
- package/src/lifecycle/publish-oci.ts +396 -0
- package/src/lifecycle/publish-record.ts +113 -0
- package/src/lifecycle/publish-resume.test.ts +168 -0
- package/src/lifecycle/publish-targets.test.ts +494 -0
- package/src/lifecycle/publish-targets.ts +100 -0
- package/src/lifecycle/release-cut-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +483 -0
- package/src/lifecycle/release-cut.ts +503 -0
- package/src/lifecycle/release-flag.test.ts +112 -0
- package/src/lifecycle/release-join.test.ts +68 -0
- package/src/lifecycle/release-join.ts +182 -0
- package/src/lifecycle/release-ledger.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- package/src/lifecycle/release-publish.test.ts +225 -0
- package/src/lifecycle/release-publish.ts +568 -0
- package/src/lifecycle/release-revocation.ts +147 -0
- package/src/lifecycle/release-store.ts +434 -0
- package/src/lifecycle/release-verify.test.ts +110 -0
- package/src/lifecycle/release-verify.ts +120 -0
- package/src/lifecycle/release-workstation.test.ts +204 -0
- package/src/lifecycle/release-workstation.ts +216 -0
- package/src/lifecycle/retention-growth.e2e.test.ts +279 -0
- package/src/lifecycle/retention-policy.ts +63 -0
- package/src/lifecycle/retention.test.ts +363 -0
- package/src/lifecycle/retention.ts +508 -0
- package/src/lifecycle/run-ledger.test.ts +10 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/op/activities/change-coverage.ts +4 -1
- package/src/op/activities/source-release.ts +8 -3
- package/src/op/activities/source-rollback.ts +8 -4
- package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
- package/src/op/gate-name.ts +13 -3
- package/src/op/gate-release.test.ts +126 -0
- package/src/op/gate-run-locator.test.ts +110 -0
- package/src/op/gate-run-locator.ts +35 -0
- package/src/op/gate.ts +88 -6
- package/src/op/local-executor.ts +207 -52
- package/src/op/op-waves-run.ts +4 -0
- package/src/op/run-events.test.ts +166 -0
- package/src/op/run-live.ts +1 -1
- package/src/op/runtime.ts +39 -0
- package/src/op/runtimes/local.test.ts +16 -0
- package/src/op/runtimes/local.ts +9 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/point-decision.ts +12 -2
- package/src/pr-loop.ts +25 -4
- package/src/pr-report-url.test.ts +131 -0
- package/src/pr-report-url.ts +209 -0
- package/src/provenance.ts +2 -2
- package/src/run-event-store.test.ts +144 -0
- package/src/run-event-store.ts +273 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +309 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +471 -0
- package/src/wave-loop-golden.test.ts +9 -0
- package/src/workspace/__fixtures__/flag-workspace.ts +132 -0
- package/src/workspace/__fixtures__/older-records/change-set-984534ea9.json +100 -0
- package/src/workspace/__fixtures__/older-records/older-records.json +326 -0
- package/src/workspace/__fixtures__/run-event-check.ts +58 -0
- package/src/workspace/ancestry-index.test.ts +93 -0
- package/src/workspace/change-set-show.schema.json +102 -0
- package/src/workspace/change-set-show.ts +72 -0
- package/src/workspace/change-set.schema.json +32 -1
- package/src/workspace/changes-cli.ts +10 -1
- package/src/workspace/changes.schema.json +135 -0
- package/src/workspace/changes.test.ts +1 -1
- package/src/workspace/changes.ts +84 -2
- package/src/workspace/check.schema.json +4 -2
- package/src/workspace/checks/records.ts +35 -1
- package/src/workspace/checks.ts +2 -1
- package/src/workspace/ci-green-cli.ts +75 -13
- package/src/workspace/ci-green-forge.ts +24 -4
- package/src/workspace/ci-green-runs.test.ts +242 -0
- package/src/workspace/ci-green-signed.test.ts +302 -0
- package/src/workspace/ci-green-workflow.test.ts +16 -0
- package/src/workspace/ci-green-workflow.ts +12 -0
- package/src/workspace/ci-green.test.ts +131 -2
- package/src/workspace/ci-green.ts +635 -42
- package/src/workspace/ci-last-green.schema.json +32 -2
- package/src/workspace/ci-list.schema.json +525 -0
- package/src/workspace/commit-links.test.ts +279 -0
- package/src/workspace/commit-links.ts +183 -0
- package/src/workspace/declaration.schema.json +76 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +60 -2
- package/src/workspace/declared-kinds.ts +40 -1
- package/src/workspace/delivery-metrics.schema.json +519 -0
- package/src/workspace/delivery-metrics.test.ts +236 -0
- package/src/workspace/delivery-metrics.ts +286 -0
- package/src/workspace/flags-read.ts +121 -0
- package/src/workspace/flags.test.ts +141 -0
- package/src/workspace/flags.ts +157 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -1
- package/src/workspace/intent-cli.ts +46 -5
- package/src/workspace/intent-trace.test.ts +173 -0
- package/src/workspace/intent-trace.ts +484 -0
- package/src/workspace/intent.schema.json +702 -6
- package/src/workspace/intent.ts +196 -26
- package/src/workspace/ls.schema.json +3 -1
- package/src/workspace/ls.ts +6 -0
- package/src/workspace/member-pipeline.test.ts +17 -0
- package/src/workspace/member-pipeline.ts +9 -0
- package/src/workspace/older-records.test.ts +412 -0
- package/src/workspace/overlap.test.ts +165 -0
- package/src/workspace/overlap.ts +340 -0
- package/src/workspace/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +5 -1
- package/src/workspace/reason-codes.test.ts +7 -1
- package/src/workspace/reason-codes.ts +7 -1
- package/src/workspace/record-assets.test.ts +2 -1
- package/src/workspace/records-contract.e2e.test.ts +2 -1
- package/src/workspace/records.schema.json +21 -2
- package/src/workspace/records.ts +36 -2
- package/src/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/src/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/src/workspace/releases.schema.json +513 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +133 -0
- package/src/workspace/run-event.schema.json +295 -0
- package/src/workspace/status-contract.test.ts +81 -1
- package/src/workspace/status-gates.ts +64 -1
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +268 -2
- package/src/workspace/status.ts +334 -4
- package/src/workspace/trust/ci-tag-statement.ts +151 -0
- package/src/workspace/trust/op-run-statement.ts +148 -0
- package/src/workspace/trust/rotation.ts +61 -14
- package/src/workspace/trust/seal.ts +10 -0
- package/src/workspace/trust/ssh-commit.ts +10 -9
- package/src/workspace/wip.ts +11 -2
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
package/src/components/driver.ts
CHANGED
|
@@ -56,7 +56,9 @@ import type { PendingGateRecord } from "../lifecycle/gate-ledger";
|
|
|
56
56
|
import type { CapabilityRegistry, DeployContext } from "./capability";
|
|
57
57
|
import { isPromotedArtifact } from "./auto-release";
|
|
58
58
|
import type { ReleaseIdentity } from "../telemetry-attribution";
|
|
59
|
-
import type { RunProgressEvent
|
|
59
|
+
import type { RunProgressEvent } from "./run-progress";
|
|
60
|
+
import type { RunEventSettleStatus } from "../run-event";
|
|
61
|
+
import { gateEventsOf, joinRunEventSinks, progressSinkOf, type RunEventSink } from "../run-event-stream";
|
|
60
62
|
|
|
61
63
|
export type { RunProgressEvent } from "./run-progress";
|
|
62
64
|
|
|
@@ -153,7 +155,16 @@ export interface DriverStepRecord {
|
|
|
153
155
|
output?: unknown;
|
|
154
156
|
error?: string;
|
|
155
157
|
/** Set on a `gate` step that passed (#2119): who resolved it, when, and at what address. */
|
|
156
|
-
approval?: {
|
|
158
|
+
approval?: {
|
|
159
|
+
gate: string;
|
|
160
|
+
resolvedBy: string;
|
|
161
|
+
timestamp: string;
|
|
162
|
+
url?: string;
|
|
163
|
+
/** The gate ledger the approval is in, when it isn't the component's own: a release gate's (#4045). */
|
|
164
|
+
op?: string;
|
|
165
|
+
/** Set when the gate passed over an empty change set (#4045) rather than on a person's approval. */
|
|
166
|
+
empty?: true;
|
|
167
|
+
};
|
|
157
168
|
}
|
|
158
169
|
|
|
159
170
|
export interface DriverComponentResult {
|
|
@@ -334,6 +345,42 @@ export function resolveStepInput(
|
|
|
334
345
|
return walk(input) as Record<string, unknown>;
|
|
335
346
|
}
|
|
336
347
|
|
|
348
|
+
/**
|
|
349
|
+
* The components (or stacks) whose outputs `input` reads through
|
|
350
|
+
* cross-component wiring, `stackOutput()` or `@<component>.publish.*`, and
|
|
351
|
+
* which have no value for it in `componentOutputs`, sorted and each once
|
|
352
|
+
* (#4084). {@link resolveStepInput} turns each such reference into
|
|
353
|
+
* `undefined`; a plan uses this to say whose outputs it is waiting on.
|
|
354
|
+
*/
|
|
355
|
+
export function unresolvedWiringSources(
|
|
356
|
+
input: Record<string, unknown>,
|
|
357
|
+
componentOutputs: Record<string, Record<string, unknown>>,
|
|
358
|
+
): string[] {
|
|
359
|
+
const found = new Set<string>();
|
|
360
|
+
const walk = (value: unknown): void => {
|
|
361
|
+
if (typeof value === "string") {
|
|
362
|
+
if (PRIOR_STEP_REF.test(value)) return;
|
|
363
|
+
const ref = value.match(COMPONENT_ARTIFACT_REF);
|
|
364
|
+
if (ref && resolvePath(componentOutputs[ref[1]]?.publish, ref[2]) === undefined) found.add(ref[1]);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (Array.isArray(value)) {
|
|
368
|
+
value.forEach(walk);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (value && typeof value === "object") {
|
|
372
|
+
if ("stackOutput" in value) {
|
|
373
|
+
const { stack, name } = (value as { stackOutput: { stack: string; name: string } }).stackOutput;
|
|
374
|
+
if (resolvePath(componentOutputs[stack], name) === undefined) found.add(stack);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
Object.values(value as Record<string, unknown>).forEach(walk);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
walk(input);
|
|
381
|
+
return [...found].sort();
|
|
382
|
+
}
|
|
383
|
+
|
|
337
384
|
// ── Step + phase execution ───────────────────────────────────────────────
|
|
338
385
|
|
|
339
386
|
/**
|
|
@@ -378,8 +425,8 @@ class GateStop extends Error {
|
|
|
378
425
|
}
|
|
379
426
|
}
|
|
380
427
|
|
|
381
|
-
/** A result status as the
|
|
382
|
-
function progressStatus(status: DriverComponentResult["status"]):
|
|
428
|
+
/** A result status as the event stream spells it — the only difference is `fail` vs `failed`, which the two vocabularies have always disagreed on. */
|
|
429
|
+
function progressStatus(status: DriverComponentResult["status"]): RunEventSettleStatus {
|
|
383
430
|
return status === "fail" ? "failed" : status;
|
|
384
431
|
}
|
|
385
432
|
|
|
@@ -395,6 +442,27 @@ export interface GateContext {
|
|
|
395
442
|
releases?: ReadonlyMap<string, string>;
|
|
396
443
|
/** This component's plan digest. Set by {@link runComponentDeploy}, never by a caller. */
|
|
397
444
|
planDigest?: string;
|
|
445
|
+
/**
|
|
446
|
+
* The release gate binding (#4045): set by a promote under a release.
|
|
447
|
+
* Every gate the run reaches is then decided in `op`'s ledger against the
|
|
448
|
+
* change-set document's digest, the release and the environment, in place
|
|
449
|
+
* of the component's own ledger and composition digest.
|
|
450
|
+
*/
|
|
451
|
+
releaseGate?: ReleaseGateBinding;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* What a release gate binds (#4045, ws-104 question 2): the change-set
|
|
456
|
+
* document's digest, the release, and (from the run) the environment.
|
|
457
|
+
*/
|
|
458
|
+
export interface ReleaseGateBinding {
|
|
459
|
+
/** The gate ledger the release gate is recorded in, for every component of the promote. */
|
|
460
|
+
op: string;
|
|
461
|
+
/** The digest of the change-set document planned for this release and environment. */
|
|
462
|
+
planDigest: string;
|
|
463
|
+
releaseDigest: string;
|
|
464
|
+
/** Reads the document stored under a digest and says whether it is empty (`evaluateGate`'s `verifyEmpty`). */
|
|
465
|
+
verifyEmpty?: (planDigest: string) => Promise<boolean>;
|
|
398
466
|
}
|
|
399
467
|
|
|
400
468
|
/** Run a single capability step. Never throws for a capability-run failure; returns a fail record instead. */
|
|
@@ -451,14 +519,16 @@ async function runCapabilityStep(
|
|
|
451
519
|
* gate is a read of the ledger rather than work, and starting activities a
|
|
452
520
|
* pending gate is about to strand defeats the point of stopping at it.
|
|
453
521
|
*
|
|
454
|
-
* `
|
|
455
|
-
* step runs, a `step`
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
522
|
+
* `emit`, when supplied, gets the phase's run events (#4041): `phase-start`
|
|
523
|
+
* before any step runs, a `step-start` and a `step-settle` around each gate
|
|
524
|
+
* and each capability invocation, the gate's `gate-resolved` or
|
|
525
|
+
* `gate-waiting`, a `skipped` settle with `skip: "not-run"` for each step a
|
|
526
|
+
* failure or a gate stopped, and `phase-settle` once the phase settles. It
|
|
527
|
+
* is observation only, never consulted for control flow. Recursion into a
|
|
528
|
+
* nested fan-out phase passes the same sink through, so a nested phase's
|
|
529
|
+
* events use its own name. `--progress-json` reads the same events through
|
|
530
|
+
* `progressOfRunEvent` (../run-event-stream.ts), which keeps the older
|
|
531
|
+
* stream's shape.
|
|
462
532
|
*/
|
|
463
533
|
async function runPhase(
|
|
464
534
|
phaseDef: DriverPhase,
|
|
@@ -467,22 +537,34 @@ async function runPhase(
|
|
|
467
537
|
phaseOutputs: Record<string, Record<string, unknown>>,
|
|
468
538
|
componentOutputs: Record<string, Record<string, unknown>>,
|
|
469
539
|
gates: GateContext,
|
|
470
|
-
|
|
540
|
+
emit?: RunEventSink,
|
|
471
541
|
): Promise<{ records: DriverStepRecord[]; executed: ExecutedStep[] }> {
|
|
542
|
+
/** Where a step of this phase sits, for its events. */
|
|
543
|
+
const stepAt = (entry: DriverStep | DriverGate | DriverPhase, step: string) => ({
|
|
544
|
+
component: ctx.component,
|
|
545
|
+
phase: phaseDef.phase,
|
|
546
|
+
step,
|
|
547
|
+
index: phaseDef.steps.indexOf(entry),
|
|
548
|
+
});
|
|
472
549
|
/** Decide this phase's gates against the ledger, in authored order, before any of its work starts. Throws `GateStop` at the first one nobody has approved. */
|
|
473
550
|
const decideGates = async (): Promise<DriverStepRecord[]> => {
|
|
474
551
|
const gateRecords: DriverStepRecord[] = [];
|
|
475
552
|
for (const gate of phaseDef.steps.filter(isGateStep)) {
|
|
476
553
|
const start = Date.now();
|
|
477
554
|
const base = { component: ctx.component, phase: phaseDef.phase, kind: `gate:${gateName(gate)}` };
|
|
555
|
+
const at = stepAt(gate, base.kind);
|
|
556
|
+
emit?.({ type: "step-start", ...at });
|
|
478
557
|
let check: Awaited<ReturnType<typeof evaluateGate>>;
|
|
479
558
|
try {
|
|
480
559
|
check = await evaluateGate(gates.port, {
|
|
481
|
-
op: ctx.component,
|
|
560
|
+
op: gates.releaseGate?.op ?? ctx.component,
|
|
482
561
|
gate: gateName(gate),
|
|
483
562
|
// #2574: an approval counts only for this environment and this plan.
|
|
484
563
|
environment: ctx.env,
|
|
485
564
|
...(gates.planDigest !== undefined ? { planDigest: gates.planDigest } : {}),
|
|
565
|
+
// #4045: and under a release, only for that release.
|
|
566
|
+
...(gates.releaseGate ? { releaseDigest: gates.releaseGate.releaseDigest } : {}),
|
|
567
|
+
...(gates.releaseGate?.verifyEmpty ? { verifyEmpty: gates.releaseGate.verifyEmpty } : {}),
|
|
486
568
|
...(gate.description ? { description: gate.description } : {}),
|
|
487
569
|
...(gate.timeout ? { timeout: gate.timeout } : {}),
|
|
488
570
|
...(gates.now ? { now: gates.now } : {}),
|
|
@@ -492,11 +574,22 @@ async function runPhase(
|
|
|
492
574
|
// executor's gate step does, and the component unwinds like any failure.
|
|
493
575
|
if (!(err instanceof GateNotRecordableError)) throw err;
|
|
494
576
|
gateRecords.push({ ...base, status: "fail" as const, durationMs: Date.now() - start, error: err.message });
|
|
577
|
+
emit?.({ type: "step-settle", ...at, status: "failed", durationMs: Date.now() - start, error: err.message });
|
|
495
578
|
for (const skipped of phaseDef.steps.filter((s): s is DriverStep | DriverPhase => !isGateStep(s))) {
|
|
496
579
|
gateRecords.push(skippedRecord(skipped));
|
|
497
580
|
}
|
|
498
581
|
throw new StepFailure(gateRecords, []);
|
|
499
582
|
}
|
|
583
|
+
for (const body of gateEventsOf(
|
|
584
|
+
check,
|
|
585
|
+
{ ...at, op: gates.releaseGate?.op ?? ctx.component, gate: gateName(gate) },
|
|
586
|
+
{
|
|
587
|
+
durationMs: Date.now() - start,
|
|
588
|
+
...(!check.satisfied && check.mismatch ? { message: "an approval stands for this gate, but for another environment or plan" } : {}),
|
|
589
|
+
},
|
|
590
|
+
)) {
|
|
591
|
+
emit?.(body);
|
|
592
|
+
}
|
|
500
593
|
if (!check.satisfied) {
|
|
501
594
|
gateRecords.push({ ...base, status: "skipped" as const, durationMs: Date.now() - start });
|
|
502
595
|
for (const skipped of phaseDef.steps.filter((s): s is DriverStep | DriverPhase => !isGateStep(s))) {
|
|
@@ -513,6 +606,8 @@ async function runPhase(
|
|
|
513
606
|
resolvedBy: check.resolution.resolvedBy,
|
|
514
607
|
timestamp: check.resolution.timestamp,
|
|
515
608
|
...(check.resolution.url ? { url: check.resolution.url } : {}),
|
|
609
|
+
...(gates.releaseGate ? { op: gates.releaseGate.op } : {}),
|
|
610
|
+
...(check.via === "empty" ? { empty: true as const } : {}),
|
|
516
611
|
},
|
|
517
612
|
});
|
|
518
613
|
}
|
|
@@ -534,7 +629,7 @@ async function runPhase(
|
|
|
534
629
|
}> => {
|
|
535
630
|
if (isPhaseStep(entry)) {
|
|
536
631
|
try {
|
|
537
|
-
const nested = await runPhase(entry, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
632
|
+
const nested = await runPhase(entry, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
538
633
|
return { ...nested, failed: false };
|
|
539
634
|
} catch (err) {
|
|
540
635
|
if (err instanceof StepFailure) return { records: err.records, executed: err.executed, failed: true };
|
|
@@ -554,7 +649,8 @@ async function runPhase(
|
|
|
554
649
|
throw err;
|
|
555
650
|
}
|
|
556
651
|
}
|
|
557
|
-
|
|
652
|
+
const at = stepAt(entry, entry.kind);
|
|
653
|
+
emit?.({ type: "step-start", ...at });
|
|
558
654
|
const { record, resolvedInput, output } = await runCapabilityStep(
|
|
559
655
|
entry,
|
|
560
656
|
phaseDef.phase,
|
|
@@ -563,12 +659,11 @@ async function runPhase(
|
|
|
563
659
|
phaseOutputs,
|
|
564
660
|
componentOutputs,
|
|
565
661
|
);
|
|
566
|
-
|
|
567
|
-
type: "step",
|
|
568
|
-
|
|
569
|
-
phase: phaseDef.phase,
|
|
570
|
-
step: entry.kind,
|
|
662
|
+
emit?.({
|
|
663
|
+
type: "step-settle",
|
|
664
|
+
...at,
|
|
571
665
|
status: record.status === "ok" ? "ok" : "failed",
|
|
666
|
+
durationMs: record.durationMs,
|
|
572
667
|
...(record.error !== undefined ? { error: record.error } : {}),
|
|
573
668
|
});
|
|
574
669
|
if (record.status === "ok") {
|
|
@@ -586,13 +681,12 @@ async function runPhase(
|
|
|
586
681
|
};
|
|
587
682
|
};
|
|
588
683
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
phase:
|
|
592
|
-
|
|
593
|
-
status: "skipped",
|
|
594
|
-
|
|
595
|
-
});
|
|
684
|
+
/** A step a failure or a gate stopped before it started: recorded, and settled `skipped` with `skip: "not-run"`. */
|
|
685
|
+
const skippedRecord = (entry: DriverStep | DriverPhase): DriverStepRecord => {
|
|
686
|
+
const kind = isPhaseStep(entry) ? entry.phase : (entry as DriverStep).kind;
|
|
687
|
+
emit?.({ type: "step-settle", ...stepAt(entry, kind), status: "skipped", skip: "not-run", durationMs: null });
|
|
688
|
+
return { component: ctx.component, phase: phaseDef.phase, kind, status: "skipped", durationMs: 0 };
|
|
689
|
+
};
|
|
596
690
|
|
|
597
691
|
const runEntries = async (): Promise<{ records: DriverStepRecord[]; executed: ExecutedStep[] }> => {
|
|
598
692
|
const gateRecords = await decideGates();
|
|
@@ -626,16 +720,16 @@ async function runPhase(
|
|
|
626
720
|
return { records, executed };
|
|
627
721
|
};
|
|
628
722
|
|
|
629
|
-
|
|
723
|
+
emit?.({ type: "phase-start", component: ctx.component, phase: phaseDef.phase });
|
|
630
724
|
try {
|
|
631
725
|
const result = await runEntries();
|
|
632
|
-
|
|
726
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "ok" });
|
|
633
727
|
return result;
|
|
634
728
|
} catch (err) {
|
|
635
729
|
if (err instanceof GateStop) {
|
|
636
|
-
|
|
730
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "gated" });
|
|
637
731
|
} else if (err instanceof StepFailure) {
|
|
638
|
-
|
|
732
|
+
emit?.({ type: "phase-settle", component: ctx.component, phase: phaseDef.phase, status: "failed" });
|
|
639
733
|
}
|
|
640
734
|
throw err;
|
|
641
735
|
}
|
|
@@ -710,14 +804,14 @@ async function rollbackExecuted(
|
|
|
710
804
|
* any) are recorded into `componentOutputs` under its own name so downstream
|
|
711
805
|
* components can reference `@<name>.publish.*`.
|
|
712
806
|
*
|
|
713
|
-
* `onProgress
|
|
714
|
-
*
|
|
715
|
-
* `
|
|
716
|
-
* `
|
|
717
|
-
* unwind step-by-step compensation
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
807
|
+
* `onProgress` (the older `RunProgressEvent` stream) and `onRunEvent` (run
|
|
808
|
+
* events, #4041), when supplied, are forwarded to every `runPhase` call (both
|
|
809
|
+
* the forward `deploy` phases and, on failure, the component's own authored
|
|
810
|
+
* `rollback` phases), so a consumer sees the phase and step events of
|
|
811
|
+
* whichever phases actually ran. The saga unwind step-by-step compensation
|
|
812
|
+
* (`rollbackExecuted` below) stays silent: it isn't a `deploy` phase, and
|
|
813
|
+
* its record statuses (`rolled-back`/`rollback-opted-out`) are not step
|
|
814
|
+
* statuses either stream has.
|
|
721
815
|
*/
|
|
722
816
|
export async function runComponentDeploy(
|
|
723
817
|
component: DriverComponent,
|
|
@@ -726,7 +820,9 @@ export async function runComponentDeploy(
|
|
|
726
820
|
componentOutputs: Record<string, Record<string, unknown>>,
|
|
727
821
|
onProgress?: (event: RunProgressEvent) => void,
|
|
728
822
|
gateContext: GateContext = { port: gitGateLedgerPort() },
|
|
823
|
+
onRunEvent?: RunEventSink,
|
|
729
824
|
): Promise<DriverComponentResult> {
|
|
825
|
+
const emit = joinRunEventSinks(onRunEvent, progressSinkOf(onProgress));
|
|
730
826
|
// Each component tracks its own release: a digest one component promoted never stamps another's deploy.
|
|
731
827
|
if (ctx.release) ctx = { ...ctx, release: { ...ctx.release } };
|
|
732
828
|
const phaseOutputs: Record<string, Record<string, unknown>> = {};
|
|
@@ -738,19 +834,22 @@ export async function runComponentDeploy(
|
|
|
738
834
|
if (ctx.release && release !== undefined && ctx.release.version === undefined) ctx.release.version = release;
|
|
739
835
|
const gates: GateContext = {
|
|
740
836
|
...gateContext,
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
837
|
+
// #4045: a release gate binds the release's change set, not this composition.
|
|
838
|
+
planDigest:
|
|
839
|
+
gateContext.releaseGate?.planDigest ??
|
|
840
|
+
componentPlanDigest({
|
|
841
|
+
environment: ctx.env,
|
|
842
|
+
component,
|
|
843
|
+
...(ctx.vars ? { vars: ctx.vars } : {}),
|
|
844
|
+
...(release !== undefined ? { release } : {}),
|
|
845
|
+
}),
|
|
747
846
|
};
|
|
748
847
|
const records: DriverStepRecord[] = [];
|
|
749
848
|
const allExecuted: ExecutedStep[] = [];
|
|
750
849
|
|
|
751
850
|
try {
|
|
752
851
|
for (const phaseDef of component.deploy) {
|
|
753
|
-
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
852
|
+
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
754
853
|
records.push(...result.records);
|
|
755
854
|
allExecuted.push(...result.executed);
|
|
756
855
|
}
|
|
@@ -784,7 +883,7 @@ export async function runComponentDeploy(
|
|
|
784
883
|
|
|
785
884
|
for (const phaseDef of [...(component.rollback ?? [])].reverse()) {
|
|
786
885
|
try {
|
|
787
|
-
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates,
|
|
886
|
+
const result = await runPhase(phaseDef, ctx, registry, phaseOutputs, componentOutputs, gates, emit);
|
|
788
887
|
records.push(...result.records);
|
|
789
888
|
} catch (compErr) {
|
|
790
889
|
if (compErr instanceof StepFailure || compErr instanceof GateStop) records.push(...compErr.records);
|
|
@@ -919,12 +1018,20 @@ export interface InterpretRunOptions {
|
|
|
919
1018
|
* byte-for-byte the same as before this option existed.
|
|
920
1019
|
*/
|
|
921
1020
|
onProgress?: (event: RunProgressEvent) => void;
|
|
1021
|
+
/**
|
|
1022
|
+
* Where the run's events go (#4041, `chant run --components --events-json`):
|
|
1023
|
+
* the run-event bodies the stream in ../run-event-stream.ts stamps. Like
|
|
1024
|
+
* `onProgress`, never consulted for control flow.
|
|
1025
|
+
*/
|
|
1026
|
+
onRunEvent?: RunEventSink;
|
|
922
1027
|
/** Where a `gate` step's facts are read and written (#2119). Defaults to the `chant/lifecycle` orphan branch; a test passes `memoryGateLedgerPort()` from `../op/gate.ts`. */
|
|
923
1028
|
gates?: GateLedgerPort;
|
|
924
1029
|
/** ISO-8601 "now" for gate decisions, so a test is deterministic. */
|
|
925
1030
|
now?: string;
|
|
926
1031
|
/** The recorded digest a promote or rollback deploys, per component (#2574). Part of the plan a gate approval is bound to. */
|
|
927
1032
|
releases?: ReadonlyMap<string, string>;
|
|
1033
|
+
/** A promote under a release (#4045): what every gate the run reaches binds. See {@link GateContext.releaseGate}. */
|
|
1034
|
+
releaseGate?: ReleaseGateBinding;
|
|
928
1035
|
/**
|
|
929
1036
|
* The release each component deploys (#3061, ws-081), threaded into its
|
|
930
1037
|
* `DeployContext.release`. The driver fills in `version` when a publish
|
|
@@ -969,14 +1076,15 @@ export async function runInterpretDriver(
|
|
|
969
1076
|
const { order, waves } = resolveComponentGraph(components);
|
|
970
1077
|
const byName = new Map(components.map((c) => [c.name, c]));
|
|
971
1078
|
const componentOutputs: Record<string, Record<string, unknown>> = { ...(options.componentOutputs ?? {}) };
|
|
972
|
-
const
|
|
1079
|
+
const emit = joinRunEventSinks(options.onRunEvent, progressSinkOf(options.onProgress));
|
|
973
1080
|
const gates: GateContext = {
|
|
974
1081
|
port: options.gates ?? gitGateLedgerPort(),
|
|
975
1082
|
...(options.now ? { now: options.now } : {}),
|
|
976
1083
|
...(options.releases ? { releases: options.releases } : {}),
|
|
1084
|
+
...(options.releaseGate ? { releaseGate: options.releaseGate } : {}),
|
|
977
1085
|
};
|
|
978
1086
|
|
|
979
|
-
|
|
1087
|
+
emit?.({ type: "run-start", waves });
|
|
980
1088
|
|
|
981
1089
|
const results: DriverComponentResult[] = [];
|
|
982
1090
|
let failedComponent: string | undefined;
|
|
@@ -984,26 +1092,27 @@ export async function runInterpretDriver(
|
|
|
984
1092
|
|
|
985
1093
|
waveLoop: for (const [waveIndex, wave] of waves.entries()) {
|
|
986
1094
|
const waveNum = waveIndex + 1;
|
|
987
|
-
|
|
1095
|
+
emit?.({ type: "wave-start", wave: waveNum, components: wave });
|
|
988
1096
|
const waveComponents = wave.map((name) => byName.get(name)!);
|
|
989
1097
|
const waveResults = await Promise.all(
|
|
990
1098
|
waveComponents.map(async (component) => {
|
|
991
|
-
|
|
1099
|
+
emit?.({ type: "component-start", wave: waveNum, component: component.name });
|
|
992
1100
|
const result = await runComponentDeploy(
|
|
993
1101
|
component,
|
|
994
1102
|
deployContext(options, component.name),
|
|
995
1103
|
registry,
|
|
996
1104
|
componentOutputs,
|
|
997
|
-
|
|
1105
|
+
undefined,
|
|
998
1106
|
gates,
|
|
1107
|
+
emit,
|
|
999
1108
|
);
|
|
1000
|
-
|
|
1109
|
+
emit?.({ type: "component-settle", wave: waveNum, component: component.name, status: progressStatus(result.status) });
|
|
1001
1110
|
return result;
|
|
1002
1111
|
}),
|
|
1003
1112
|
);
|
|
1004
1113
|
results.push(...waveResults);
|
|
1005
1114
|
const stopped = waveResults.find((r) => r.status !== "ok");
|
|
1006
|
-
|
|
1115
|
+
emit?.({ type: "wave-settle", wave: waveNum, status: progressStatus(stopped?.status ?? "ok") });
|
|
1007
1116
|
if (stopped) {
|
|
1008
1117
|
// A failure in the same wave outranks a gate: something is actually
|
|
1009
1118
|
// broken, and reporting the run as "waiting on a human" would hide it.
|
|
@@ -1016,7 +1125,7 @@ export async function runInterpretDriver(
|
|
|
1016
1125
|
|
|
1017
1126
|
const status: DriverRunResult["status"] = failedComponent ? "fail" : gated ? "gated" : "ok";
|
|
1018
1127
|
const ok = status === "ok";
|
|
1019
|
-
|
|
1128
|
+
emit?.({ type: "run-settle", status: progressStatus(status), durationMs: null });
|
|
1020
1129
|
const result: DriverRunResult = {
|
|
1021
1130
|
order, waves, results, ok, status, failedComponent, componentOutputs,
|
|
1022
1131
|
...(gated
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each component would apply, as a digest (#4081), and which of an
|
|
3
|
+
* earlier attempt's progress holds against it.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from "vitest";
|
|
7
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { componentInputDigests, progressThatCarries } from "./fan-out-inputs";
|
|
11
|
+
import type { DriverComponent } from "./driver";
|
|
12
|
+
|
|
13
|
+
function project(): string {
|
|
14
|
+
const root = mkdtempSync(join(tmpdir(), "fan-out-inputs-"));
|
|
15
|
+
mkdirSync(join(root, "dist"));
|
|
16
|
+
for (const name of ["net", "cluster", "app"]) writeFileSync(join(root, "dist", `${name}.json`), `{"name":"${name}"}`);
|
|
17
|
+
return root;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const component = (name: string, dependsOn: string[] = [], extra: Record<string, unknown> = {}): DriverComponent => ({
|
|
21
|
+
name,
|
|
22
|
+
dependsOn,
|
|
23
|
+
deploy: [{ phase: "Apply", steps: [{ kind: "cfn-deploy", stack: name, template: `dist/${name}.json`, ...extra }] }],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const estate = [component("net"), component("cluster", ["net"]), component("app", ["cluster"])];
|
|
27
|
+
|
|
28
|
+
describe("componentInputDigests", () => {
|
|
29
|
+
test("is stable for the same project, environment and files", () => {
|
|
30
|
+
const root = project();
|
|
31
|
+
expect(componentInputDigests(estate, { projectRoot: root, env: "prod" })).toEqual(
|
|
32
|
+
componentInputDigests(estate, { projectRoot: root, env: "prod" }),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("covers the bytes of a file a step input names, and everything downstream of it", () => {
|
|
37
|
+
const root = project();
|
|
38
|
+
const before = componentInputDigests(estate, { projectRoot: root, env: "prod" });
|
|
39
|
+
writeFileSync(join(root, "dist", "cluster.json"), `{"name":"cluster","queue":true}`);
|
|
40
|
+
const after = componentInputDigests(estate, { projectRoot: root, env: "prod" });
|
|
41
|
+
expect(after.net).toBe(before.net);
|
|
42
|
+
expect(after.cluster).not.toBe(before.cluster);
|
|
43
|
+
expect(after.app).not.toBe(before.app);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("covers a directory a step names, by its files", () => {
|
|
47
|
+
const root = project();
|
|
48
|
+
const chart = [component("chart", [], { chart: "dist" })];
|
|
49
|
+
const before = componentInputDigests(chart, { projectRoot: root, env: "prod" });
|
|
50
|
+
writeFileSync(join(root, "dist", "app.json"), "{}");
|
|
51
|
+
expect(componentInputDigests(chart, { projectRoot: root, env: "prod" }).chart).not.toBe(before.chart);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("covers the environment and the authored steps", () => {
|
|
55
|
+
const root = project();
|
|
56
|
+
const prod = componentInputDigests(estate, { projectRoot: root, env: "prod" });
|
|
57
|
+
expect(componentInputDigests(estate, { projectRoot: root, env: "staging" }).net).not.toBe(prod.net);
|
|
58
|
+
const moved = [component("net", [], { inputs: { size: 2 } }), ...estate.slice(1)];
|
|
59
|
+
expect(componentInputDigests(moved, { projectRoot: root, env: "prod" }).net).not.toBe(prod.net);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("ignores a string that is not a file, a path outside the project, and the phase name", () => {
|
|
63
|
+
const root = project();
|
|
64
|
+
mkdirSync(join(root, "Apply"));
|
|
65
|
+
const before = componentInputDigests(estate, { projectRoot: root, env: "prod" });
|
|
66
|
+
writeFileSync(join(root, "Apply", "x"), "changes nothing");
|
|
67
|
+
expect(componentInputDigests(estate, { projectRoot: root, env: "prod" })).toEqual(before);
|
|
68
|
+
const outside = [component("net", [], { other: "../elsewhere.json" })];
|
|
69
|
+
expect(() => componentInputDigests(outside, { projectRoot: root, env: "prod" })).not.toThrow();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("progressThatCarries", () => {
|
|
74
|
+
test("carries a component only when its recorded input is the one it has now", () => {
|
|
75
|
+
const split = progressThatCarries(
|
|
76
|
+
{ completed: ["net", "cluster", "app"], inputs: { net: "a", cluster: "b" } },
|
|
77
|
+
{ net: "a", cluster: "B", app: "c" },
|
|
78
|
+
);
|
|
79
|
+
expect(split).toEqual({ carried: ["net"], changed: ["app", "cluster"], unrecorded: false });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("a record with no input digests carries nothing", () => {
|
|
83
|
+
expect(progressThatCarries({ completed: ["net"] }, { net: "a" })).toEqual({ carried: [], changed: ["net"], unrecorded: true });
|
|
84
|
+
});
|
|
85
|
+
});
|