@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/op/local-executor.ts
CHANGED
|
@@ -54,7 +54,11 @@ import { RunWorkLease, LEASE_LOST, workLeaseProblems, workLeaseNeedsRunItem, typ
|
|
|
54
54
|
import { WORK_LEASE_STEP_ID } from "./types";
|
|
55
55
|
import { LiveRun, currentLiveRun, withLiveRun } from "./run-live";
|
|
56
56
|
import { runEnvOf } from "../lifecycle/run-ledger";
|
|
57
|
-
import {
|
|
57
|
+
import { resolveCommitSha } from "../lifecycle/commit-sha";
|
|
58
|
+
import { resolveCiRun, type RunOrigin } from "../lifecycle/release-ledger";
|
|
59
|
+
import { runEventsOfStepRecord, type RunEventRuntime, type RunEventSkipReason } from "../run-event";
|
|
60
|
+
import { openRunEventStore, teeLines } from "../run-event-store";
|
|
61
|
+
import { openRunEventStream, runEventRunOf, type RunEventSink, type RunEventStream } from "../run-event-stream";
|
|
58
62
|
import { describePlanDigest, samePlanDigest } from "../lifecycle/plan-digest";
|
|
59
63
|
import type { GateCheckpoint } from "../lifecycle/gate-checkpoint";
|
|
60
64
|
import type { ActivityContract } from "./activity-contract";
|
|
@@ -64,6 +68,16 @@ export { parseDuration } from "./duration";
|
|
|
64
68
|
|
|
65
69
|
// ── Records ─────────────────────────────────────────────────────────────────
|
|
66
70
|
|
|
71
|
+
/**
|
|
72
|
+
* One settled step of an Op run, as `OpRunResult.records` holds it.
|
|
73
|
+
*
|
|
74
|
+
* As a `chant run <op> --progress-json` line it is deprecated: read
|
|
75
|
+
* `RunEvent` (`../run-event.ts`, exported from `@intentius/chant`)
|
|
76
|
+
* instead, whose `step-settle` carries the run id, commit and runtime too,
|
|
77
|
+
* and whose step statuses are `ok`, `failed`, `skipped`, `cached`, `gated`
|
|
78
|
+
* and `waiting` (#4019). `runEventsOfStepRecord` maps a record onto it.
|
|
79
|
+
* `--progress-json` keeps printing records until #4041 moves it.
|
|
80
|
+
*/
|
|
67
81
|
export interface StepRecord {
|
|
68
82
|
phase: string;
|
|
69
83
|
fn: string;
|
|
@@ -94,7 +108,7 @@ export interface StepRecord {
|
|
|
94
108
|
* On a gate with an `approval` block (#2508): whether a quorum or a policy permit passed it. `"point"` on a gate that asks a decision point (#3170).
|
|
95
109
|
* `"alias"` (#3949) when an approval recorded under one of the gate's aliases counted, on any gate.
|
|
96
110
|
*/
|
|
97
|
-
via?: "quorum" | "policy" | "point" | "alias";
|
|
111
|
+
via?: "quorum" | "policy" | "point" | "alias" | "empty";
|
|
98
112
|
/** On a gate with a quorum (#2508): every approver who counted toward it. */
|
|
99
113
|
approvers?: string[];
|
|
100
114
|
/** On a gate that asks a decision point (#3170): the answer record that passed it, which the gate ledger's resolution cites too. */
|
|
@@ -557,9 +571,29 @@ function receiptReadStep(step: EffectStep, outputs?: string): ActivityStep {
|
|
|
557
571
|
};
|
|
558
572
|
}
|
|
559
573
|
|
|
560
|
-
/**
|
|
561
|
-
|
|
562
|
-
|
|
574
|
+
/**
|
|
575
|
+
* What the run-event stream (#4041) says about a record that the record
|
|
576
|
+
* itself does not: the step's place in its phase, why a bare skipped record
|
|
577
|
+
* skipped, and the gate a gate step stopped at. Kept beside the record
|
|
578
|
+
* rather than on it, so `--json`, the run ledger and `--progress-json` print
|
|
579
|
+
* what they printed before.
|
|
580
|
+
*/
|
|
581
|
+
interface RecordHint {
|
|
582
|
+
index?: number;
|
|
583
|
+
skip?: RunEventSkipReason;
|
|
584
|
+
gate?: { op: string; gate: string };
|
|
585
|
+
}
|
|
586
|
+
const recordHints = new WeakMap<StepRecord, RecordHint>();
|
|
587
|
+
|
|
588
|
+
/** Note `hint` against `record` for its run events, and hand the record back. */
|
|
589
|
+
function hinted(record: StepRecord, hint: RecordHint): StepRecord {
|
|
590
|
+
recordHints.set(record, { ...recordHints.get(record), ...hint });
|
|
591
|
+
return record;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/** A skipped-record for a step that will not run: one an earlier failure or stop left, unless `skip` says otherwise. */
|
|
595
|
+
function skippedRecord(phaseName: string, fn: string, args?: Record<string, unknown>, skip: RunEventSkipReason = "not-run"): StepRecord {
|
|
596
|
+
return hinted({ phase: phaseName, fn, args: args ?? {}, status: "skipped", durationMs: 0 }, { skip });
|
|
563
597
|
}
|
|
564
598
|
|
|
565
599
|
// ── Gate steps (#2119) ───────────────────────────────────────────────────────
|
|
@@ -570,8 +604,12 @@ interface GateContext {
|
|
|
570
604
|
port: GateLedgerPort;
|
|
571
605
|
now?: string;
|
|
572
606
|
runId?: string;
|
|
607
|
+
/** The commit the run is at (#4020), recorded on the gate facts it writes and on the run record. */
|
|
608
|
+
gitSha?: string;
|
|
573
609
|
/** Called once per settled step, in production order (#2121) — what `--progress-json` streams from. */
|
|
574
610
|
onRecord?: (record: StepRecord) => void;
|
|
611
|
+
/** Where the run's events go (#4041): a step's start, its settle and its gate's decision. */
|
|
612
|
+
emit?: RunEventSink;
|
|
575
613
|
/** The run context's list of passed gates (#2522). A gate that passes is appended here. */
|
|
576
614
|
passed?: PassedGate[];
|
|
577
615
|
/** The run's hold on its work item's lease (#2748). Absent in compensation phases, which run whatever the lease did. */
|
|
@@ -608,6 +646,7 @@ async function workBoundary(
|
|
|
608
646
|
if (!work) return undefined;
|
|
609
647
|
if (work.due(resultsById)) {
|
|
610
648
|
const start = Date.now();
|
|
649
|
+
startStep(ctx, phaseName, "workLease:claim");
|
|
611
650
|
let claimed: Awaited<ReturnType<RunWorkLease["claim"]>>;
|
|
612
651
|
try {
|
|
613
652
|
claimed = await work.claim(resultsById);
|
|
@@ -656,7 +695,25 @@ async function workBoundary(
|
|
|
656
695
|
/** Collect records and hand each to the caller's progress sink in one move. */
|
|
657
696
|
function pushRecord(sink: StepRecord[], ctx: GateContext, ...recs: StepRecord[]): void {
|
|
658
697
|
sink.push(...recs);
|
|
659
|
-
for (const r of recs) ctx
|
|
698
|
+
for (const r of recs) announce(ctx, r);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/** Hand a settled record to the progress sink and its run events to the event sink. */
|
|
702
|
+
function announce(ctx: GateContext, record: StepRecord): void {
|
|
703
|
+
ctx.onRecord?.(record);
|
|
704
|
+
if (!ctx.emit) return;
|
|
705
|
+
const hint = recordHints.get(record);
|
|
706
|
+
for (const body of runEventsOfStepRecord(record, { op: ctx.op, ...hint })) ctx.emit(body);
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/** A step is about to run: its `step-start` event (#4041). */
|
|
710
|
+
function startStep(ctx: GateContext, phase: string, step: string, index?: number): void {
|
|
711
|
+
ctx.emit?.({ type: "step-start", component: null, phase, step, ...(index !== undefined ? { index } : {}) });
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
/** A gate step's record, hinted with its place and, when nobody has approved it, the gate it stopped at. */
|
|
715
|
+
function gateRecordOf(ran: { record: StepRecord; pending?: PendingGateRecord }, index: number): StepRecord {
|
|
716
|
+
return hinted(ran.record, { index, ...(ran.pending ? { gate: { op: ran.pending.op, gate: ran.pending.gate } } : {}) });
|
|
660
717
|
}
|
|
661
718
|
|
|
662
719
|
/** The record name a gate step lands under, so a reader (and a JSON consumer) can pick it out of `records`. */
|
|
@@ -746,6 +803,7 @@ async function runGateStep(
|
|
|
746
803
|
...(step.description ? { description: step.description } : {}),
|
|
747
804
|
...(step.timeout ? { timeout: step.timeout } : {}),
|
|
748
805
|
...(gates.runId ? { runId: gates.runId } : {}),
|
|
806
|
+
...(gates.gitSha ? { gitSha: gates.gitSha } : {}),
|
|
749
807
|
...(planDigest !== undefined ? { planDigest } : {}),
|
|
750
808
|
...(approval ? { approval } : {}),
|
|
751
809
|
...(gates.now ? { now: gates.now } : {}),
|
|
@@ -848,6 +906,7 @@ async function runPointGateStep(
|
|
|
848
906
|
...(step.description ? { description: step.description } : {}),
|
|
849
907
|
...(step.timeout ? { timeout: step.timeout } : {}),
|
|
850
908
|
...(gates.runId ? { runId: gates.runId } : {}),
|
|
909
|
+
...(gates.gitSha ? { gitSha: gates.gitSha } : {}),
|
|
851
910
|
...(planDigest !== undefined ? { planDigest } : {}),
|
|
852
911
|
...(gates.env !== undefined ? { env: gates.env } : {}),
|
|
853
912
|
...(gates.now ? { now: gates.now } : {}),
|
|
@@ -891,7 +950,8 @@ async function runEffectStep(
|
|
|
891
950
|
profiles: Record<string, ActivityProfile>,
|
|
892
951
|
resultsById: Map<string, unknown>,
|
|
893
952
|
gates: GateContext,
|
|
894
|
-
signal
|
|
953
|
+
signal: AbortSignal | undefined,
|
|
954
|
+
index: number,
|
|
895
955
|
): Promise<{
|
|
896
956
|
records: StepRecord[];
|
|
897
957
|
failed: boolean;
|
|
@@ -907,23 +967,26 @@ async function runEffectStep(
|
|
|
907
967
|
outputs = effectOutputsDigest(step, resultsById);
|
|
908
968
|
} catch (err) {
|
|
909
969
|
// A resolved value JSON cannot hold (canonicalJson refuses it) would be a wrong expectation.
|
|
910
|
-
|
|
970
|
+
startStep(gates, phaseName, `effect:${step.receipt.name}`, index);
|
|
971
|
+
pushRecord(records, gates, hinted({ phase: phaseName, fn: `effect:${step.receipt.name}`, args: {}, status: "fail", durationMs: 0, error: errMessage(err) }, { index }));
|
|
911
972
|
return { records, failed: true };
|
|
912
973
|
}
|
|
974
|
+
startStep(gates, phaseName, "receiptRead", index);
|
|
913
975
|
const read = await runStep(receiptReadStep(step, outputs), phaseName, activities, profiles, resultsById, signal);
|
|
914
|
-
pushRecord(records, gates, read.record);
|
|
976
|
+
pushRecord(records, gates, hinted(read.record, { index }));
|
|
915
977
|
if (read.record.status === "fail") return { records, failed: true };
|
|
916
978
|
|
|
917
979
|
const result = read.result as Partial<ReceiptReadResult> | undefined;
|
|
918
980
|
if (typeof result?.expectation !== "string") {
|
|
919
|
-
|
|
981
|
+
startStep(gates, phaseName, `effect:${step.receipt.name}`, index);
|
|
982
|
+
pushRecord(records, gates, hinted({
|
|
920
983
|
phase: phaseName,
|
|
921
984
|
fn: `effect:${step.receipt.name}`,
|
|
922
985
|
args: {},
|
|
923
986
|
status: "fail",
|
|
924
987
|
durationMs: 0,
|
|
925
988
|
error: "receiptRead returned no expectation — the receipt store activity must return { current, expectation }",
|
|
926
|
-
});
|
|
989
|
+
}, { index }));
|
|
927
990
|
return { records, failed: true };
|
|
928
991
|
}
|
|
929
992
|
const expectation = result.expectation;
|
|
@@ -932,9 +995,9 @@ async function runEffectStep(
|
|
|
932
995
|
// Effect already applied — skip the nested steps, write nothing.
|
|
933
996
|
for (const nested of step.steps) {
|
|
934
997
|
pushRecord(records, gates,
|
|
935
|
-
nested.kind === "activity"
|
|
936
|
-
? skippedRecord(phaseName, nested.fn, nested.args)
|
|
937
|
-
: skippedRecord(phaseName, gateFn(nested)),
|
|
998
|
+
hinted(nested.kind === "activity"
|
|
999
|
+
? skippedRecord(phaseName, nested.fn, nested.args, "receipt")
|
|
1000
|
+
: skippedRecord(phaseName, gateFn(nested), undefined, "receipt"), { index }),
|
|
938
1001
|
);
|
|
939
1002
|
}
|
|
940
1003
|
return { records, failed: false };
|
|
@@ -943,19 +1006,21 @@ async function runEffectStep(
|
|
|
943
1006
|
const skipRest = (from: number) => {
|
|
944
1007
|
for (const skipped of step.steps.slice(from)) {
|
|
945
1008
|
pushRecord(records, gates,
|
|
946
|
-
skipped.kind === "activity"
|
|
1009
|
+
hinted(skipped.kind === "activity"
|
|
947
1010
|
? skippedRecord(phaseName, skipped.fn, skipped.args)
|
|
948
|
-
: skippedRecord(phaseName, gateFn(skipped)),
|
|
1011
|
+
: skippedRecord(phaseName, gateFn(skipped)), { index }),
|
|
949
1012
|
);
|
|
950
1013
|
}
|
|
951
|
-
pushRecord(records, gates, skippedRecord(phaseName, "receiptWrite"));
|
|
1014
|
+
pushRecord(records, gates, hinted(skippedRecord(phaseName, "receiptWrite"), { index }));
|
|
952
1015
|
};
|
|
953
1016
|
|
|
954
1017
|
for (let i = 0; i < step.steps.length; i++) {
|
|
955
1018
|
const nested = step.steps[i];
|
|
956
1019
|
if (isGate(nested)) {
|
|
957
|
-
|
|
958
|
-
|
|
1020
|
+
startStep(gates, phaseName, gateFn(nested), index);
|
|
1021
|
+
const decided = await runGateStep(nested, phaseName, gates, resultsById);
|
|
1022
|
+
const { record, pending, pushed, pushWarning } = decided;
|
|
1023
|
+
pushRecord(records, gates, gateRecordOf(decided, index));
|
|
959
1024
|
if (record.status === "fail") {
|
|
960
1025
|
// Receipt left untouched, as for any other failing nested step
|
|
961
1026
|
// (#2301) — the effect is not applied and the next run re-proposes it.
|
|
@@ -975,8 +1040,9 @@ async function runEffectStep(
|
|
|
975
1040
|
}
|
|
976
1041
|
continue;
|
|
977
1042
|
}
|
|
1043
|
+
startStep(gates, phaseName, nested.fn, index);
|
|
978
1044
|
const ran = await runStep(nested, phaseName, activities, profiles, resultsById, signal);
|
|
979
|
-
pushRecord(records, gates, ran.record);
|
|
1045
|
+
pushRecord(records, gates, hinted(ran.record, { index }));
|
|
980
1046
|
if (ran.pending) {
|
|
981
1047
|
// A command's own gate (#2779): the receipt is left untouched, as for a
|
|
982
1048
|
// pending gate step.
|
|
@@ -997,6 +1063,7 @@ async function runEffectStep(
|
|
|
997
1063
|
}
|
|
998
1064
|
|
|
999
1065
|
// Sole writer of the receipt: on success of every nested step, last.
|
|
1066
|
+
startStep(gates, phaseName, "receiptWrite", index);
|
|
1000
1067
|
const wrote = await runStep(
|
|
1001
1068
|
{
|
|
1002
1069
|
kind: "activity",
|
|
@@ -1010,7 +1077,7 @@ async function runEffectStep(
|
|
|
1010
1077
|
resultsById,
|
|
1011
1078
|
signal,
|
|
1012
1079
|
);
|
|
1013
|
-
pushRecord(records, gates, wrote.record);
|
|
1080
|
+
pushRecord(records, gates, hinted(wrote.record, { index }));
|
|
1014
1081
|
return { records, failed: wrote.record.status === "fail" };
|
|
1015
1082
|
}
|
|
1016
1083
|
|
|
@@ -1041,44 +1108,48 @@ async function runPhase(
|
|
|
1041
1108
|
// gate is about to strand would defeat the point of stopping at it.
|
|
1042
1109
|
const gateRecords: StepRecord[] = [];
|
|
1043
1110
|
const stop = await workBoundary(phase.name, gates, resultsById, gateRecords);
|
|
1111
|
+
const at = (step: StepDefinition) => phase.steps.indexOf(step);
|
|
1112
|
+
const skipActivities = () => {
|
|
1113
|
+
for (const skipped of phase.steps.filter(isActivity)) {
|
|
1114
|
+
pushRecord(gateRecords, gates, hinted(skippedRecord(phase.name, skipped.fn, skipped.args), { index: at(skipped) }));
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1044
1117
|
if (stop) {
|
|
1045
1118
|
for (const skipped of phase.steps) {
|
|
1046
|
-
pushRecord(gateRecords, gates, isGate(skipped) ? skippedRecord(phase.name, gateFn(skipped)) : skippedRecord(phase.name, (skipped as ActivityStep).fn, (skipped as ActivityStep).args));
|
|
1119
|
+
pushRecord(gateRecords, gates, hinted(isGate(skipped) ? skippedRecord(phase.name, gateFn(skipped)) : skippedRecord(phase.name, (skipped as ActivityStep).fn, (skipped as ActivityStep).args), { index: at(skipped) }));
|
|
1047
1120
|
}
|
|
1048
1121
|
throw new WorkStop(gateRecords, phase.name, stop === "lost");
|
|
1049
1122
|
}
|
|
1050
1123
|
for (const step of phase.steps.filter(isGate)) {
|
|
1051
|
-
|
|
1052
|
-
|
|
1124
|
+
startStep(gates, phase.name, gateFn(step), at(step));
|
|
1125
|
+
const decided = await runGateStep(step, phase.name, gates, resultsById);
|
|
1126
|
+
const { record, pending, pushed, pushWarning } = decided;
|
|
1127
|
+
pushRecord(gateRecords, gates, gateRecordOf(decided, at(step)));
|
|
1053
1128
|
if (record.status === "fail") {
|
|
1054
1129
|
// The gate could not be decided at all (#2301). Same treatment as a
|
|
1055
1130
|
// pending one: nothing fans out, the activities are recorded skipped.
|
|
1056
|
-
|
|
1057
|
-
pushRecord(gateRecords, gates, skippedRecord(phase.name, skipped.fn, skipped.args));
|
|
1058
|
-
}
|
|
1131
|
+
skipActivities();
|
|
1059
1132
|
throw new PhaseFailure(gateRecords);
|
|
1060
1133
|
}
|
|
1061
1134
|
if (pending) {
|
|
1062
|
-
|
|
1063
|
-
pushRecord(gateRecords, gates, skippedRecord(phase.name, skipped.fn, skipped.args));
|
|
1064
|
-
}
|
|
1135
|
+
skipActivities();
|
|
1065
1136
|
throw new GateStop(gateRecords, pending, phase.name, pushed, pushWarning);
|
|
1066
1137
|
}
|
|
1067
1138
|
if (record.point) {
|
|
1068
1139
|
// A gate's open decision point (#3170): nothing fans out.
|
|
1069
|
-
|
|
1070
|
-
pushRecord(gateRecords, gates, skippedRecord(phase.name, skipped.fn, skipped.args));
|
|
1071
|
-
}
|
|
1140
|
+
skipActivities();
|
|
1072
1141
|
throw new PointStop(gateRecords, record.point, phase.name);
|
|
1073
1142
|
}
|
|
1074
1143
|
}
|
|
1075
1144
|
const steps = phase.steps.filter(isActivity);
|
|
1076
1145
|
const settled = await Promise.all(steps.map((s) => {
|
|
1077
1146
|
const source = gates.compensating ? unfinishedSource(s, resultsById) : undefined;
|
|
1078
|
-
|
|
1147
|
+
if (source) return { record: unfinishedSourceRecord(s, phase.name, source) } as RanStep;
|
|
1148
|
+
startStep(gates, phase.name, s.fn, at(s));
|
|
1149
|
+
return runStep(s, phase.name, activities, profiles, resultsById, signal);
|
|
1079
1150
|
}));
|
|
1080
|
-
const ran = settled.map((r) => r.record);
|
|
1081
|
-
for (const r of ran) gates
|
|
1151
|
+
const ran = settled.map((r, k) => hinted(r.record, { index: at(steps[k]!) }));
|
|
1152
|
+
for (const r of ran) announce(gates, r);
|
|
1082
1153
|
const records = gateRecords.concat(ran);
|
|
1083
1154
|
if (records.some((r) => r.status === "fail")) throw new PhaseFailure(records);
|
|
1084
1155
|
// A step whose command stopped at its own gate (#2779) stops the run at
|
|
@@ -1096,13 +1167,14 @@ async function runPhase(
|
|
|
1096
1167
|
const records: StepRecord[] = [];
|
|
1097
1168
|
|
|
1098
1169
|
const skipRemaining = (from: number) => {
|
|
1099
|
-
for (const skipped of steps.slice(from)) {
|
|
1170
|
+
for (const [k, skipped] of steps.slice(from).entries()) {
|
|
1171
|
+
const index = { index: from + k };
|
|
1100
1172
|
if (isEffect(skipped)) {
|
|
1101
|
-
pushRecord(records, gates, skippedRecord(phase.name, `effect:${skipped.receipt.name}`));
|
|
1173
|
+
pushRecord(records, gates, hinted(skippedRecord(phase.name, `effect:${skipped.receipt.name}`), index));
|
|
1102
1174
|
} else if (isGate(skipped)) {
|
|
1103
|
-
pushRecord(records, gates, skippedRecord(phase.name, gateFn(skipped)));
|
|
1175
|
+
pushRecord(records, gates, hinted(skippedRecord(phase.name, gateFn(skipped)), index));
|
|
1104
1176
|
} else {
|
|
1105
|
-
pushRecord(records, gates, skippedRecord(phase.name, skipped.fn, skipped.args));
|
|
1177
|
+
pushRecord(records, gates, hinted(skippedRecord(phase.name, skipped.fn, skipped.args), index));
|
|
1106
1178
|
}
|
|
1107
1179
|
}
|
|
1108
1180
|
};
|
|
@@ -1117,8 +1189,10 @@ async function runPhase(
|
|
|
1117
1189
|
throw new WorkStop(records, phase.name, stop === "lost");
|
|
1118
1190
|
}
|
|
1119
1191
|
if (isGate(step)) {
|
|
1120
|
-
|
|
1121
|
-
|
|
1192
|
+
startStep(gates, phase.name, gateFn(step), i);
|
|
1193
|
+
const decided = await runGateStep(step, phase.name, gates, resultsById);
|
|
1194
|
+
const { record, pending, pushed, pushWarning } = decided;
|
|
1195
|
+
pushRecord(records, gates, gateRecordOf(decided, i));
|
|
1122
1196
|
if (record.status === "fail") {
|
|
1123
1197
|
// A gate that could not be decided is a failed step, not a pending
|
|
1124
1198
|
// one (#2301) — the run failed, and the record says why.
|
|
@@ -1139,12 +1213,12 @@ async function runPhase(
|
|
|
1139
1213
|
}
|
|
1140
1214
|
const source = gates.compensating ? unfinishedSource(step, resultsById) : undefined;
|
|
1141
1215
|
if (source) {
|
|
1142
|
-
pushRecord(records, gates, unfinishedSourceRecord(step, phase.name, source));
|
|
1216
|
+
pushRecord(records, gates, hinted(unfinishedSourceRecord(step, phase.name, source), { index: i }));
|
|
1143
1217
|
continue;
|
|
1144
1218
|
}
|
|
1145
1219
|
if (isEffect(step)) {
|
|
1146
1220
|
const { records: effRecords, failed, pending, pushed, pushWarning, point } = await runEffectStep(
|
|
1147
|
-
step, phase.name, activities, profiles, resultsById, gates, signal,
|
|
1221
|
+
step, phase.name, activities, profiles, resultsById, gates, signal, i,
|
|
1148
1222
|
);
|
|
1149
1223
|
records.push(...effRecords); // already emitted by runEffectStep
|
|
1150
1224
|
if (point) {
|
|
@@ -1161,8 +1235,9 @@ async function runPhase(
|
|
|
1161
1235
|
}
|
|
1162
1236
|
continue;
|
|
1163
1237
|
}
|
|
1238
|
+
startStep(gates, phase.name, step.fn, i);
|
|
1164
1239
|
const { record, pending } = await runStep(step, phase.name, activities, profiles, resultsById, signal);
|
|
1165
|
-
pushRecord(records, gates, record);
|
|
1240
|
+
pushRecord(records, gates, hinted(record, { index: i }));
|
|
1166
1241
|
if (pending) {
|
|
1167
1242
|
// The step's command stopped at its own gate (#2779): the run ends
|
|
1168
1243
|
// `gated` there, as at a pending gate step.
|
|
@@ -1216,6 +1291,15 @@ export interface RunOpOptions {
|
|
|
1216
1291
|
* `--progress-json` from. Side-effect free when omitted.
|
|
1217
1292
|
*/
|
|
1218
1293
|
onRecord?: (record: StepRecord) => void;
|
|
1294
|
+
/**
|
|
1295
|
+
* Where the run's event stream goes (#4041, `chant run <op> --events-json`),
|
|
1296
|
+
* one `run-event.schema.json` line at a time: the run's start and settle,
|
|
1297
|
+
* each phase's, each step's start and settle, and each gate's decision.
|
|
1298
|
+
* `runtime` and `runOrigin` name where the run happened when the executor
|
|
1299
|
+
* cannot tell: by default it is `ci` in a CI job, `steward` in a steward's
|
|
1300
|
+
* turn and `local` otherwise. Omitted, nothing is written.
|
|
1301
|
+
*/
|
|
1302
|
+
runEvents?: { write: (line: string) => void; runtime?: RunEventRuntime; runOrigin?: RunOrigin };
|
|
1219
1303
|
/**
|
|
1220
1304
|
* Append the run's {@link OpRunRecord} to the run ledger
|
|
1221
1305
|
* (`../lifecycle/run-ledger.ts`) when the run settles (#2118). Opt-in on
|
|
@@ -1225,6 +1309,16 @@ export interface RunOpOptions {
|
|
|
1225
1309
|
* `chant operator` pass it; nothing else does.
|
|
1226
1310
|
*/
|
|
1227
1311
|
ledger?: { cwd?: string };
|
|
1312
|
+
/**
|
|
1313
|
+
* Signs the run's record when it settles (#4044): given the record without
|
|
1314
|
+
* a statement, returns the DSSE envelope stored on it as `statement`
|
|
1315
|
+
* (`../workspace/trust/op-run-statement.ts`). `chant run <op> --key` and
|
|
1316
|
+
* `CHANT_RUNNER_KEY` pass one made from a runner key. When it throws, the
|
|
1317
|
+
* record is written unsigned and `onSignError` hears why.
|
|
1318
|
+
*/
|
|
1319
|
+
signRecord?: (record: OpRunRecord) => NonNullable<OpRunRecord["statement"]>;
|
|
1320
|
+
/** Called when {@link signRecord} throws. The run's outcome stands. */
|
|
1321
|
+
onSignError?: (err: unknown) => void;
|
|
1228
1322
|
/**
|
|
1229
1323
|
* Called when the ledger append itself fails. The run's own outcome is
|
|
1230
1324
|
* already decided by then, so a ledger failure is reported to the caller,
|
|
@@ -1320,6 +1414,9 @@ export async function runOpLocally(
|
|
|
1320
1414
|
...(steward ? { steward } : {}),
|
|
1321
1415
|
})
|
|
1322
1416
|
: undefined;
|
|
1417
|
+
// The run's event stream (#4041), opened once the commit is known; held
|
|
1418
|
+
// here so a run that throws before it settles still ends its stream.
|
|
1419
|
+
const events: { stream?: RunEventStream } = {};
|
|
1323
1420
|
try {
|
|
1324
1421
|
const stepConsole = options.stepOutput
|
|
1325
1422
|
? { write: options.stepOutput, ...(options.stepHeartbeatMs !== undefined ? { heartbeatMs: options.stepHeartbeatMs } : {}) }
|
|
@@ -1327,10 +1424,13 @@ export async function runOpLocally(
|
|
|
1327
1424
|
return await withLiveRun(live, () =>
|
|
1328
1425
|
withRunConsole(stepConsole, () =>
|
|
1329
1426
|
withOpRunContext(run, () =>
|
|
1330
|
-
runOpInTurn(config, activities, profiles, signal, { ...options, runId, ...(steward ? { steward } : {}) }, run),
|
|
1427
|
+
runOpInTurn(config, activities, profiles, signal, { ...options, runId, ...(steward ? { steward } : {}) }, run, events),
|
|
1331
1428
|
),
|
|
1332
1429
|
),
|
|
1333
1430
|
);
|
|
1431
|
+
} catch (err) {
|
|
1432
|
+
events.stream?.settle("failed", errMessage(err));
|
|
1433
|
+
throw err;
|
|
1334
1434
|
} finally {
|
|
1335
1435
|
live?.close();
|
|
1336
1436
|
restore?.();
|
|
@@ -1344,15 +1444,49 @@ async function runOpInTurn(
|
|
|
1344
1444
|
signal: AbortSignal | undefined,
|
|
1345
1445
|
options: RunOpOptions & { runId: string },
|
|
1346
1446
|
run: OpRunContext,
|
|
1447
|
+
events: { stream?: RunEventStream },
|
|
1347
1448
|
): Promise<OpRunResult> {
|
|
1348
1449
|
const runId = options.runId;
|
|
1450
|
+
// #4020: the commit the run builds from, on its record and on the gate facts it writes.
|
|
1451
|
+
const commit = options.commit ?? (await resolveCommitSha(options.cwd ? { cwd: options.cwd } : {}));
|
|
1452
|
+
// #4020: the CI run this one is in, in the shape a deploy record carries it.
|
|
1453
|
+
const ciRun = resolveCiRun();
|
|
1454
|
+
// #4041: the run's events name it the way its run record does: its own id,
|
|
1455
|
+
// the commit, and the CI run it is in.
|
|
1456
|
+
// #4042: a run that writes to the ledger also keeps its events on this host,
|
|
1457
|
+
// beside its in-flight record, so `chant run events <run>` can replay it and
|
|
1458
|
+
// `--follow` can tail it. The stream is opened for that even without
|
|
1459
|
+
// `--events-json`; a run that records nothing (`--no-record`) keeps nothing.
|
|
1460
|
+
const store = options.ledger
|
|
1461
|
+
? await openRunEventStore(options.ledger.cwd ?? options.cwd ?? process.cwd(), runId)
|
|
1462
|
+
: undefined;
|
|
1463
|
+
const eventsWrite = teeLines(options.runEvents?.write, store?.write.bind(store));
|
|
1464
|
+
const stream = eventsWrite
|
|
1465
|
+
? openRunEventStream(
|
|
1466
|
+
runEventRunOf({
|
|
1467
|
+
kind: "op",
|
|
1468
|
+
name: config.name,
|
|
1469
|
+
runId,
|
|
1470
|
+
...(commit ? { gitSha: commit } : {}),
|
|
1471
|
+
...(ciRun ? { ci: ciRun } : {}),
|
|
1472
|
+
steward: options.steward !== undefined,
|
|
1473
|
+
...(options.runEvents?.runtime ? { runtime: options.runEvents.runtime } : {}),
|
|
1474
|
+
...(options.runEvents?.runOrigin ? { runOrigin: options.runEvents.runOrigin } : {}),
|
|
1475
|
+
}),
|
|
1476
|
+
eventsWrite,
|
|
1477
|
+
)
|
|
1478
|
+
: undefined;
|
|
1479
|
+
events.stream = stream;
|
|
1480
|
+
stream?.emit({ type: "run-start", waves: null });
|
|
1349
1481
|
|
|
1350
1482
|
const gates: GateContext = {
|
|
1351
1483
|
op: config.name,
|
|
1352
1484
|
port: options.gates ?? gitGateLedgerPort(options.cwd ? { cwd: options.cwd } : undefined),
|
|
1353
1485
|
...(options.now ? { now: options.now } : {}),
|
|
1354
1486
|
runId,
|
|
1487
|
+
...(commit ? { gitSha: commit } : {}),
|
|
1355
1488
|
...(options.onRecord ? { onRecord: options.onRecord } : {}),
|
|
1489
|
+
...(stream ? { emit: stream.emit } : {}),
|
|
1356
1490
|
passed: run.passedGates,
|
|
1357
1491
|
points: options.points ?? workspaceGatePointAsker(options.cwd ?? process.cwd()),
|
|
1358
1492
|
...(options.env !== undefined ? { env: options.env } : {}),
|
|
@@ -1440,10 +1574,16 @@ async function runOpInTurn(
|
|
|
1440
1574
|
const live = currentLiveRun();
|
|
1441
1575
|
const t0 = Date.now();
|
|
1442
1576
|
live?.phaseStarted(phase.name);
|
|
1577
|
+
stream?.emit({ type: "phase-start", component: null, phase: phase.name });
|
|
1443
1578
|
try {
|
|
1444
1579
|
const ran = await runPhase(phase, activities, profiles, resultsById, ctx, phaseSignal, from);
|
|
1445
1580
|
live?.phaseEnded(phase.name, phaseVerdict(ran), Date.now() - t0);
|
|
1581
|
+
stream?.emit({ type: "phase-settle", component: null, phase: phase.name, status: "ok" });
|
|
1446
1582
|
return ran;
|
|
1583
|
+
} catch (err) {
|
|
1584
|
+
const status = err instanceof GateStop ? "gated" : err instanceof PointStop ? "waiting" : err instanceof WorkStop && !err.lost ? "ok" : "failed";
|
|
1585
|
+
stream?.emit({ type: "phase-settle", component: null, phase: phase.name, status });
|
|
1586
|
+
throw err;
|
|
1447
1587
|
} finally {
|
|
1448
1588
|
phaseDurations[phase.name] = (phaseDurations[phase.name] ?? 0) + (Date.now() - t0);
|
|
1449
1589
|
}
|
|
@@ -1471,9 +1611,23 @@ async function runOpInTurn(
|
|
|
1471
1611
|
...(point ? { point: { ...point, since: ended } } : {}),
|
|
1472
1612
|
...(options.steward ? { steward: options.steward } : {}),
|
|
1473
1613
|
...(resumed ? { resumed } : {}),
|
|
1614
|
+
...(commit ? { gitSha: commit } : {}),
|
|
1615
|
+
...(ciRun ? { runOrigin: ciRun.runOrigin } : {}),
|
|
1474
1616
|
phaseDurations,
|
|
1475
1617
|
});
|
|
1476
|
-
|
|
1618
|
+
let record: OpRunRecord = { version: 1, ...input, id: runId };
|
|
1619
|
+
if (options.signRecord) {
|
|
1620
|
+
try {
|
|
1621
|
+
const statement = options.signRecord(record);
|
|
1622
|
+
input.statement = statement;
|
|
1623
|
+
record = { ...record, statement };
|
|
1624
|
+
} catch (err) {
|
|
1625
|
+
options.onSignError?.(err);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
// The stream settles as the run does, with the first failing step's error.
|
|
1629
|
+
const firstError = status === "fail" ? settled.find((r) => r.status === "fail")?.error : undefined;
|
|
1630
|
+
stream?.settle(status === "fail" ? "failed" : status, firstError);
|
|
1477
1631
|
if (!options.ledger) return record;
|
|
1478
1632
|
try {
|
|
1479
1633
|
return (await appendRunRecord(input, options.ledger)).record;
|
|
@@ -1497,7 +1651,7 @@ async function runOpInTurn(
|
|
|
1497
1651
|
gates.resume = {
|
|
1498
1652
|
config,
|
|
1499
1653
|
gates: new Map(resumeGates.map((g) => [g.step, g])),
|
|
1500
|
-
commit
|
|
1654
|
+
commit,
|
|
1501
1655
|
...(options.contracts ? { contracts: options.contracts } : {}),
|
|
1502
1656
|
note: (line) => resumeNotes.push(line),
|
|
1503
1657
|
};
|
|
@@ -1525,10 +1679,11 @@ async function runOpInTurn(
|
|
|
1525
1679
|
const steps = pi < gate.phaseIndex ? phase.steps : phase.parallel ? [] : phase.steps.slice(0, gate.stepIndex);
|
|
1526
1680
|
for (const [si, step] of steps.entries()) {
|
|
1527
1681
|
if (gate.planStep && pi === gate.planStep.phaseIndex && si === gate.planStep.stepIndex) {
|
|
1682
|
+
startStep(gates, phase.name, gate.planStep.step.fn, si);
|
|
1528
1683
|
const ran = await runStep(gate.planStep.step, phase.name, activities, profiles, resultsById, stepSignal);
|
|
1529
|
-
prefix.push(ran.record);
|
|
1684
|
+
prefix.push(hinted(ran.record, { index: si }));
|
|
1530
1685
|
if (ran.record.status === "fail" || ran.pending || ran.record.point) {
|
|
1531
|
-
for (const r of prefix) gates
|
|
1686
|
+
for (const r of prefix) announce(gates, r);
|
|
1532
1687
|
if (ran.pending) throw new GateStop(prefix, ran.pending, phase.name);
|
|
1533
1688
|
if (ran.record.point) throw new PointStop(prefix, ran.record.point, phase.name);
|
|
1534
1689
|
throw new PhaseFailure(prefix);
|
|
@@ -1540,7 +1695,7 @@ async function runOpInTurn(
|
|
|
1540
1695
|
: isGate(step)
|
|
1541
1696
|
? skippedRecord(phase.name, gateFn(step))
|
|
1542
1697
|
: skippedRecord(phase.name, step.fn, step.args);
|
|
1543
|
-
prefix.push({ ...skipped, resumed: marker });
|
|
1698
|
+
prefix.push(hinted({ ...skipped, resumed: marker }, { index: si }));
|
|
1544
1699
|
}
|
|
1545
1700
|
}
|
|
1546
1701
|
// The plan the run would approve now against the one approved: a moved
|
|
@@ -1556,7 +1711,7 @@ async function runOpInTurn(
|
|
|
1556
1711
|
return undefined;
|
|
1557
1712
|
}
|
|
1558
1713
|
records.push(...prefix);
|
|
1559
|
-
for (const r of prefix) gates
|
|
1714
|
+
for (const r of prefix) announce(gates, r);
|
|
1560
1715
|
resumed = { gate: gate.name, run: checkpoint.runId, checkpoint: decision.digest };
|
|
1561
1716
|
return { phaseIndex: gate.phaseIndex, stepIndex: config.phases[gate.phaseIndex]!.parallel ? 0 : gate.stepIndex };
|
|
1562
1717
|
};
|
package/src/op/op-waves-run.ts
CHANGED
|
@@ -71,6 +71,7 @@ import { isApprovalSpent, type AppliedGateRecord } from "../lifecycle/gate-appli
|
|
|
71
71
|
import type { HeadPlans, MergedReview, ReviewSource } from "./gate-review";
|
|
72
72
|
import type { TrustPolicy } from "../workspace/trust/policy";
|
|
73
73
|
import type { GateSigners } from "../workspace/trust/gate-seal";
|
|
74
|
+
import { ciRunIdFromEnv } from "./gate-run-locator";
|
|
74
75
|
import {
|
|
75
76
|
OP_WAVE_DEFAULT_APPLY,
|
|
76
77
|
OP_WAVE_GATE_POLICIES,
|
|
@@ -2228,6 +2229,9 @@ async function approveByReview(
|
|
|
2228
2229
|
timestamp: at.now,
|
|
2229
2230
|
planDigest: at.digest,
|
|
2230
2231
|
approver: { kind: "human" },
|
|
2232
|
+
// #4020: the commit the wave applies, and the CI run applying it.
|
|
2233
|
+
gitSha: head,
|
|
2234
|
+
...(ciRunIdFromEnv() ? { runId: ciRunIdFromEnv()! } : {}),
|
|
2231
2235
|
note,
|
|
2232
2236
|
...(merged.url ? { url: merged.url } : {}),
|
|
2233
2237
|
review: { pr: merged.pr, head: merged.head, approvers: merged.approvers },
|