@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/run-event.ts
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The run-event contract (#4019, behold #678): one stream of events for Op
|
|
3
|
+
* runs, component runs and pipeline runs, so anything that shows a run reads
|
|
4
|
+
* the same fields wherever the run happened.
|
|
5
|
+
*
|
|
6
|
+
* `workspace/run-event.schema.json` is the contract. These types
|
|
7
|
+
* mirror it, and {@link createRunEventWriter} and {@link writeRunEvent} are
|
|
8
|
+
* the one writer: every emitter hands a writer the type-specific body and
|
|
9
|
+
* the writer stamps the run's identity, the sequence number, the time and the
|
|
10
|
+
* contract fields on it, then writes one JSON line. The emitters themselves
|
|
11
|
+
* are in `./run-event-stream.ts` and the runtimes (#4041); the files
|
|
12
|
+
* they are kept in, replay and `--follow` are `./run-event-store.ts` (#4042).
|
|
13
|
+
*
|
|
14
|
+
* Two older streams predate this one and keep their shape behind
|
|
15
|
+
* `--progress-json`, while `--events-json` prints this one (#4041):
|
|
16
|
+
* `RunProgressEvent` (`./components/run-progress.ts`, from `chant run
|
|
17
|
+
* --components --progress-json`) and the Op path's `StepRecord` lines
|
|
18
|
+
* (`./op/local-executor.ts`, from `chant run <op> --progress-json`).
|
|
19
|
+
* {@link runEventOfProgress} and {@link runEventsOfStepRecord} say how each
|
|
20
|
+
* maps onto this contract.
|
|
21
|
+
*
|
|
22
|
+
* This module imports no runtime code beyond the chant version (`./chant-version.ts`), so a consumer
|
|
23
|
+
* can import the types and the writer without loading the rest of chant. It
|
|
24
|
+
* lives outside `workspace/` so that a level-0 import of `@intentius/chant`
|
|
25
|
+
* loads no workspace module (#2526).
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { RunProgressEvent } from "./components/run-progress";
|
|
29
|
+
import type { RunOrigin } from "./lifecycle/release-ledger";
|
|
30
|
+
import type { StepRecord } from "./op/local-executor";
|
|
31
|
+
import { CHANT_VERSION } from "./chant-version";
|
|
32
|
+
|
|
33
|
+
/** The schema's `$id`, which every event carries as `$schema`. */
|
|
34
|
+
export const RUN_EVENT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/run-event/v1/run-event.schema.json";
|
|
35
|
+
|
|
36
|
+
/** The contract version every event carries as `contract`. */
|
|
37
|
+
export const RUN_EVENT_CONTRACT_VERSION = 1;
|
|
38
|
+
|
|
39
|
+
/** The first chant that writes contract version 1 of the run-event stream. */
|
|
40
|
+
export const RUN_EVENT_FLOOR = "0.124.28";
|
|
41
|
+
|
|
42
|
+
/** What ran: an Op, a component selection (`chant run --components`), or a CI pipeline. */
|
|
43
|
+
export type RunEventKind = "op" | "component" | "pipeline";
|
|
44
|
+
|
|
45
|
+
/** Where the run happened: in the process that started it, on a steward, or in a forge's CI. */
|
|
46
|
+
export type RunEventRuntime = "local" | "steward" | "ci";
|
|
47
|
+
|
|
48
|
+
/** How a run, wave, component or phase settled. `gated` and `waiting` wait on a person and are not failures. */
|
|
49
|
+
export type RunEventSettleStatus = "ok" | "failed" | "gated" | "waiting";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* How a step settled. `skipped` says why in {@link RunEventStepSettle.skip};
|
|
53
|
+
* `cached` is for a cache hit standing in for the step (#4015).
|
|
54
|
+
*/
|
|
55
|
+
export type RunEventStepStatus = "ok" | "failed" | "skipped" | "cached" | "gated" | "waiting";
|
|
56
|
+
|
|
57
|
+
/** Why a step was skipped. */
|
|
58
|
+
export type RunEventSkipReason = "receipt" | "resumed" | "refused" | "not-run";
|
|
59
|
+
|
|
60
|
+
/** How a gate's approval passed, when it was more than one person's approval of that gate. */
|
|
61
|
+
export type RunEventGateVia = "quorum" | "policy" | "point" | "alias" | "empty";
|
|
62
|
+
|
|
63
|
+
/** The run every event of a stream names: the same on every line. */
|
|
64
|
+
export interface RunEventRun {
|
|
65
|
+
/**
|
|
66
|
+
* The run's own id: an Op run's id, a component run's id (the id its
|
|
67
|
+
* release records carry), or the CI run id for a pipeline run.
|
|
68
|
+
*/
|
|
69
|
+
runId: string;
|
|
70
|
+
kind: RunEventKind;
|
|
71
|
+
/** The Op's name, the component selection as given, or the pipeline's name. */
|
|
72
|
+
name: string;
|
|
73
|
+
/** The commit the run built from, or null when it did not start in a git checkout. */
|
|
74
|
+
gitSha: string | null;
|
|
75
|
+
runtime: RunEventRuntime;
|
|
76
|
+
/**
|
|
77
|
+
* Where the run ran and how to reach it, the shape a release record's
|
|
78
|
+
* `runOrigin` has. For an Op run in CI it locates the CI run, as the run
|
|
79
|
+
* record does (#4020), while `runId` stays the Op run's own id.
|
|
80
|
+
*/
|
|
81
|
+
runOrigin: RunOrigin;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** What every event carries besides its body. */
|
|
85
|
+
export interface RunEventEnvelope extends RunEventRun {
|
|
86
|
+
$schema: typeof RUN_EVENT_SCHEMA_ID;
|
|
87
|
+
contract: typeof RUN_EVENT_CONTRACT_VERSION;
|
|
88
|
+
/** The version of the chant that wrote the event. */
|
|
89
|
+
chant: string;
|
|
90
|
+
/** The event's place in its run's stream, from 0 at `run-start`. */
|
|
91
|
+
seq: number;
|
|
92
|
+
/** When it happened, ISO-8601. */
|
|
93
|
+
at: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface RunEventRunStart {
|
|
97
|
+
type: "run-start";
|
|
98
|
+
/** In a component run, the waves the run will attempt, in order. Null in an Op or pipeline run. */
|
|
99
|
+
waves: string[][] | null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** The last event of a stream. Its `status` is the run's verdict. */
|
|
103
|
+
export interface RunEventRunSettle {
|
|
104
|
+
type: "run-settle";
|
|
105
|
+
status: RunEventSettleStatus;
|
|
106
|
+
durationMs: number | null;
|
|
107
|
+
error?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface RunEventWaveStart {
|
|
111
|
+
type: "wave-start";
|
|
112
|
+
/** 1-based, into `run-start`'s `waves`. */
|
|
113
|
+
wave: number;
|
|
114
|
+
components: string[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface RunEventWaveSettle {
|
|
118
|
+
type: "wave-settle";
|
|
119
|
+
wave: number;
|
|
120
|
+
status: RunEventSettleStatus;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface RunEventComponentStart {
|
|
124
|
+
type: "component-start";
|
|
125
|
+
wave: number;
|
|
126
|
+
component: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* How a component settled: a {@link RunEventSettleStatus}, or one of two
|
|
131
|
+
* statuses for a component the run did not start (#4007), added within
|
|
132
|
+
* contract 1 by chant 0.124.29. `blocked`: a dependency failed or stopped at
|
|
133
|
+
* a gate, so it never ran. `already-applied`: an earlier attempt that this
|
|
134
|
+
* run resumed applied it. Neither has a `component-start` before it. A reader
|
|
135
|
+
* that knows only the four settle statuses reads either as a component that
|
|
136
|
+
* did not run in this run.
|
|
137
|
+
*/
|
|
138
|
+
export type RunEventComponentSettleStatus = RunEventSettleStatus | "blocked" | "already-applied";
|
|
139
|
+
|
|
140
|
+
/** The first chant that writes `blocked`, `already-applied` and `blockedBy` on `component-settle` (#4007). */
|
|
141
|
+
export const RUN_EVENT_COMPONENT_SKIP_FLOOR = "0.124.29";
|
|
142
|
+
|
|
143
|
+
export interface RunEventComponentSettle {
|
|
144
|
+
type: "component-settle";
|
|
145
|
+
/**
|
|
146
|
+
* 1-based, into `run-start`'s `waves`. On an `already-applied` settle it is
|
|
147
|
+
* the wave the component had in the derivation the earlier attempt ran.
|
|
148
|
+
*/
|
|
149
|
+
wave: number;
|
|
150
|
+
component: string;
|
|
151
|
+
status: RunEventComponentSettleStatus;
|
|
152
|
+
/** With `blocked`: the failed or gated component the run reached this one from. */
|
|
153
|
+
blockedBy?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** An Op's phase, a component composition's phase, or a pipeline's stage. `component` is null outside a component run. */
|
|
157
|
+
export interface RunEventPhaseStart {
|
|
158
|
+
type: "phase-start";
|
|
159
|
+
component: string | null;
|
|
160
|
+
phase: string;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface RunEventPhaseSettle {
|
|
164
|
+
type: "phase-settle";
|
|
165
|
+
component: string | null;
|
|
166
|
+
phase: string;
|
|
167
|
+
status: RunEventSettleStatus;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** An Op or composition step, or a pipeline's job. */
|
|
171
|
+
export interface RunEventStepStart {
|
|
172
|
+
type: "step-start";
|
|
173
|
+
component: string | null;
|
|
174
|
+
phase: string;
|
|
175
|
+
/** The activity, `gate:<name>`, `effect:<name>`, or the job's name. */
|
|
176
|
+
step: string;
|
|
177
|
+
/**
|
|
178
|
+
* The step's place in its phase as authored, from 0, so two steps of one
|
|
179
|
+
* phase that share a name stay apart. Optional: added within contract 1 by
|
|
180
|
+
* chant 0.124.28 (#4041), and left out where the writer has no authored
|
|
181
|
+
* position, such as a step the executor adds itself.
|
|
182
|
+
*/
|
|
183
|
+
index?: number;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface RunEventStepSettle {
|
|
187
|
+
type: "step-settle";
|
|
188
|
+
component: string | null;
|
|
189
|
+
phase: string;
|
|
190
|
+
step: string;
|
|
191
|
+
/** As on {@link RunEventStepStart.index}. */
|
|
192
|
+
index?: number;
|
|
193
|
+
status: RunEventStepStatus;
|
|
194
|
+
/** With `skipped`: why, or null when the writer does not know. */
|
|
195
|
+
skip?: RunEventSkipReason | null;
|
|
196
|
+
durationMs: number | null;
|
|
197
|
+
/** With `failed`: what failed. */
|
|
198
|
+
error?: string;
|
|
199
|
+
/** Why the step skipped, gated or waited, for a person. */
|
|
200
|
+
message?: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** The run stopped at a gate nobody has approved, or a decision point nobody has answered. */
|
|
204
|
+
export interface RunEventGateWaiting {
|
|
205
|
+
type: "gate-waiting";
|
|
206
|
+
component: string | null;
|
|
207
|
+
phase: string;
|
|
208
|
+
step: string;
|
|
209
|
+
/** As on {@link RunEventStepStart.index}. */
|
|
210
|
+
index?: number;
|
|
211
|
+
/** The op the gate is recorded under, which `chant approve` takes. */
|
|
212
|
+
op: string;
|
|
213
|
+
/** The gate's name, or null when the step waits on a decision point alone. */
|
|
214
|
+
gate: string | null;
|
|
215
|
+
/** The open question's answer record id, or null. */
|
|
216
|
+
point: string | null;
|
|
217
|
+
message?: string;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface RunEventGateResolved {
|
|
221
|
+
type: "gate-resolved";
|
|
222
|
+
component: string | null;
|
|
223
|
+
phase: string;
|
|
224
|
+
step: string;
|
|
225
|
+
/** As on {@link RunEventStepStart.index}. */
|
|
226
|
+
index?: number;
|
|
227
|
+
op: string;
|
|
228
|
+
gate: string;
|
|
229
|
+
resolvedBy: string;
|
|
230
|
+
resolvedAt: string;
|
|
231
|
+
via: RunEventGateVia | null;
|
|
232
|
+
url?: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** The type-specific part of an event: what an emitter hands the writer. */
|
|
236
|
+
export type RunEventBody =
|
|
237
|
+
| RunEventRunStart
|
|
238
|
+
| RunEventRunSettle
|
|
239
|
+
| RunEventWaveStart
|
|
240
|
+
| RunEventWaveSettle
|
|
241
|
+
| RunEventComponentStart
|
|
242
|
+
| RunEventComponentSettle
|
|
243
|
+
| RunEventPhaseStart
|
|
244
|
+
| RunEventPhaseSettle
|
|
245
|
+
| RunEventStepStart
|
|
246
|
+
| RunEventStepSettle
|
|
247
|
+
| RunEventGateWaiting
|
|
248
|
+
| RunEventGateResolved;
|
|
249
|
+
|
|
250
|
+
export type RunEventType = RunEventBody["type"];
|
|
251
|
+
|
|
252
|
+
/** Every event type, in the order a reader meets them. Closed: part of the contract. */
|
|
253
|
+
export const RUN_EVENT_TYPES = [
|
|
254
|
+
"run-start",
|
|
255
|
+
"wave-start",
|
|
256
|
+
"component-start",
|
|
257
|
+
"phase-start",
|
|
258
|
+
"step-start",
|
|
259
|
+
"gate-waiting",
|
|
260
|
+
"gate-resolved",
|
|
261
|
+
"step-settle",
|
|
262
|
+
"phase-settle",
|
|
263
|
+
"component-settle",
|
|
264
|
+
"wave-settle",
|
|
265
|
+
"run-settle",
|
|
266
|
+
] as const satisfies readonly RunEventType[];
|
|
267
|
+
|
|
268
|
+
/** One line of a run's stream. */
|
|
269
|
+
export type RunEvent = RunEventBody extends infer B ? (B extends RunEventBody ? RunEventEnvelope & B : never) : never;
|
|
270
|
+
|
|
271
|
+
/** One event as its line: JSON with the envelope first, then the body, and a newline. */
|
|
272
|
+
export function serializeRunEvent(event: RunEvent): string {
|
|
273
|
+
return JSON.stringify(event) + "\n";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** What {@link writeRunEvent} and {@link createRunEventWriter} need besides the body. */
|
|
277
|
+
export interface RunEventStamp {
|
|
278
|
+
run: RunEventRun;
|
|
279
|
+
seq: number;
|
|
280
|
+
/** When it happened. Defaults to now. */
|
|
281
|
+
at?: Date | string;
|
|
282
|
+
/** Defaults to this chant's version. */
|
|
283
|
+
chant?: string;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Build one event from its body and the run it belongs to. The envelope's
|
|
288
|
+
* fields come first, so every line reads the same way. No body names an
|
|
289
|
+
* envelope field, so neither overrides the other.
|
|
290
|
+
*/
|
|
291
|
+
export function buildRunEvent(body: RunEventBody, stamp: RunEventStamp): RunEvent {
|
|
292
|
+
const at = stamp.at === undefined ? new Date().toISOString() : typeof stamp.at === "string" ? stamp.at : stamp.at.toISOString();
|
|
293
|
+
const { runId, kind, name, gitSha, runtime, runOrigin } = stamp.run;
|
|
294
|
+
const envelope: RunEventEnvelope = {
|
|
295
|
+
$schema: RUN_EVENT_SCHEMA_ID,
|
|
296
|
+
contract: RUN_EVENT_CONTRACT_VERSION,
|
|
297
|
+
chant: stamp.chant ?? CHANT_VERSION,
|
|
298
|
+
seq: stamp.seq,
|
|
299
|
+
at,
|
|
300
|
+
runId,
|
|
301
|
+
kind,
|
|
302
|
+
name,
|
|
303
|
+
gitSha,
|
|
304
|
+
runtime,
|
|
305
|
+
runOrigin,
|
|
306
|
+
};
|
|
307
|
+
return { ...envelope, ...body } as RunEvent;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Build one event and hand its line to `write`. Returns the event written. */
|
|
311
|
+
export function writeRunEvent(body: RunEventBody, stamp: RunEventStamp, write: (line: string) => void): RunEvent {
|
|
312
|
+
const event = buildRunEvent(body, stamp);
|
|
313
|
+
write(serializeRunEvent(event));
|
|
314
|
+
return event;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** A run's writer: it keeps the run and the sequence, so an emitter hands it bodies only. */
|
|
318
|
+
export interface RunEventWriter {
|
|
319
|
+
/** Write the next event of the run and return it. */
|
|
320
|
+
emit(body: RunEventBody): RunEvent;
|
|
321
|
+
/** The `seq` the next event gets. */
|
|
322
|
+
readonly next: number;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export interface RunEventWriterOptions {
|
|
326
|
+
run: RunEventRun;
|
|
327
|
+
/** Where each line goes. Defaults to standard output. */
|
|
328
|
+
write?: (line: string) => void;
|
|
329
|
+
/** The clock. Defaults to `new Date()`. */
|
|
330
|
+
now?: () => Date;
|
|
331
|
+
/** The `seq` of the first event, for a writer that carries on a stream. Defaults to 0. */
|
|
332
|
+
seq?: number;
|
|
333
|
+
/** Defaults to this chant's version. */
|
|
334
|
+
chant?: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** The one writer of a run's stream (#4019). Each `emit` writes one line and moves the sequence on. */
|
|
338
|
+
export function createRunEventWriter(opts: RunEventWriterOptions): RunEventWriter {
|
|
339
|
+
const write = opts.write ?? ((line: string) => void process.stdout.write(line));
|
|
340
|
+
const now = opts.now ?? (() => new Date());
|
|
341
|
+
let seq = opts.seq ?? 0;
|
|
342
|
+
return {
|
|
343
|
+
emit(body) {
|
|
344
|
+
return writeRunEvent(body, { run: opts.run, seq: seq++, at: now(), chant: opts.chant }, write);
|
|
345
|
+
},
|
|
346
|
+
get next() {
|
|
347
|
+
return seq;
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ── The older streams, in terms of this one ─────────────────────────────────
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* A `RunProgressEvent` (`chant run --components --progress-json`) as a
|
|
356
|
+
* run-event body. The older stream has no step timings, so `durationMs` is
|
|
357
|
+
* null on the settles it maps to.
|
|
358
|
+
*/
|
|
359
|
+
export function runEventOfProgress(event: RunProgressEvent): RunEventBody {
|
|
360
|
+
switch (event.type) {
|
|
361
|
+
case "run-start":
|
|
362
|
+
return { type: "run-start", waves: event.waves };
|
|
363
|
+
case "wave-start":
|
|
364
|
+
return { type: "wave-start", wave: event.wave, components: event.components };
|
|
365
|
+
case "component-start":
|
|
366
|
+
return { type: "component-start", wave: event.wave, component: event.component };
|
|
367
|
+
case "phase-start":
|
|
368
|
+
return { type: "phase-start", component: event.component, phase: event.phase };
|
|
369
|
+
case "step":
|
|
370
|
+
if (event.status === "running") return { type: "step-start", component: event.component, phase: event.phase, step: event.step };
|
|
371
|
+
return {
|
|
372
|
+
type: "step-settle",
|
|
373
|
+
component: event.component,
|
|
374
|
+
phase: event.phase,
|
|
375
|
+
step: event.step,
|
|
376
|
+
status: event.status,
|
|
377
|
+
durationMs: null,
|
|
378
|
+
...(event.error !== undefined ? { error: event.error } : {}),
|
|
379
|
+
};
|
|
380
|
+
case "phase-done":
|
|
381
|
+
return { type: "phase-settle", component: event.component, phase: event.phase, status: event.status };
|
|
382
|
+
case "component-done":
|
|
383
|
+
return { type: "component-settle", wave: event.wave, component: event.component, status: event.status };
|
|
384
|
+
case "wave-done":
|
|
385
|
+
return { type: "wave-settle", wave: event.wave, status: event.status };
|
|
386
|
+
case "run-done":
|
|
387
|
+
return { type: "run-settle", status: event.status, durationMs: null };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const GATE_PREFIX = "gate:";
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* A settled `StepRecord` (`chant run <op> --progress-json`) as run-event
|
|
395
|
+
* bodies: a gate's `gate-resolved` or `gate-waiting` when the record carries
|
|
396
|
+
* one, then the `step-settle`. `op` is the run's Op, which a gate is recorded
|
|
397
|
+
* under unless the record names another.
|
|
398
|
+
*
|
|
399
|
+
* A record skipped with nothing to say why maps to `skip: null`. The local
|
|
400
|
+
* executor writes the same record for a gate nobody has approved, for a step
|
|
401
|
+
* of an effect whose receipt matched and for a step an earlier failure
|
|
402
|
+
* stopped, so only an emitter that knows which can say `gated`, `receipt` or
|
|
403
|
+
* `not-run`. The run's own status still says `gated`. The local executor
|
|
404
|
+
* (#4041) knows, and passes `skip` for a bare skipped record and `gate` for
|
|
405
|
+
* a gate step nobody has approved; it passes `index`, the step's place in
|
|
406
|
+
* its phase, too.
|
|
407
|
+
*/
|
|
408
|
+
export function runEventsOfStepRecord(
|
|
409
|
+
record: StepRecord,
|
|
410
|
+
ctx: {
|
|
411
|
+
op: string;
|
|
412
|
+
component?: string | null;
|
|
413
|
+
skip?: RunEventSkipReason;
|
|
414
|
+
index?: number;
|
|
415
|
+
/** The gate a skipped gate step stopped at, when the emitter knows it. */
|
|
416
|
+
gate?: { op: string; gate: string };
|
|
417
|
+
},
|
|
418
|
+
): RunEventBody[] {
|
|
419
|
+
const component = ctx.component ?? null;
|
|
420
|
+
const at = { component, phase: record.phase, step: record.fn, ...(ctx.index !== undefined ? { index: ctx.index } : {}) };
|
|
421
|
+
const out: RunEventBody[] = [];
|
|
422
|
+
const settle = (status: RunEventStepStatus, extra: Partial<RunEventStepSettle> = {}): RunEventStepSettle => ({
|
|
423
|
+
type: "step-settle",
|
|
424
|
+
...at,
|
|
425
|
+
status,
|
|
426
|
+
durationMs: record.durationMs,
|
|
427
|
+
...extra,
|
|
428
|
+
});
|
|
429
|
+
const gateOfFn = record.fn.startsWith(GATE_PREFIX) ? record.fn.slice(GATE_PREFIX.length) : null;
|
|
430
|
+
|
|
431
|
+
if (record.approval) {
|
|
432
|
+
const a = record.approval;
|
|
433
|
+
out.push({
|
|
434
|
+
type: "gate-resolved",
|
|
435
|
+
...at,
|
|
436
|
+
op: ctx.op,
|
|
437
|
+
gate: a.gate,
|
|
438
|
+
resolvedBy: a.resolvedBy,
|
|
439
|
+
resolvedAt: a.timestamp,
|
|
440
|
+
via: a.via ?? null,
|
|
441
|
+
...(a.url !== undefined ? { url: a.url } : {}),
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
if (record.status === "ok") {
|
|
445
|
+
out.push(settle("ok"));
|
|
446
|
+
return out;
|
|
447
|
+
}
|
|
448
|
+
if (record.status === "fail") {
|
|
449
|
+
out.push(settle("failed", record.error !== undefined ? { error: record.error } : {}));
|
|
450
|
+
return out;
|
|
451
|
+
}
|
|
452
|
+
const message = record.refusal !== undefined ? { message: record.refusal } : {};
|
|
453
|
+
const stoppedAt = record.gate ?? ctx.gate;
|
|
454
|
+
if (record.point) {
|
|
455
|
+
out.push({ type: "gate-waiting", ...at, op: ctx.op, gate: gateOfFn, point: record.point.id, ...message });
|
|
456
|
+
out.push(settle("waiting", message));
|
|
457
|
+
} else if (stoppedAt) {
|
|
458
|
+
out.push({ type: "gate-waiting", ...at, op: stoppedAt.op, gate: stoppedAt.gate, point: null, ...message });
|
|
459
|
+
out.push(settle("gated", message));
|
|
460
|
+
} else if (gateOfFn !== null && record.refusal !== undefined) {
|
|
461
|
+
out.push({ type: "gate-waiting", ...at, op: ctx.op, gate: gateOfFn, point: null, ...message });
|
|
462
|
+
out.push(settle("gated", message));
|
|
463
|
+
} else if (record.resumed) {
|
|
464
|
+
out.push(settle("skipped", { skip: "resumed", message: `resumed at gate ${record.resumed.gate} from run ${record.resumed.run}` }));
|
|
465
|
+
} else if (record.refusal !== undefined) {
|
|
466
|
+
out.push(settle("skipped", { skip: "refused", ...message }));
|
|
467
|
+
} else {
|
|
468
|
+
out.push(settle("skipped", { skip: ctx.skip ?? null }));
|
|
469
|
+
}
|
|
470
|
+
return out;
|
|
471
|
+
}
|
|
@@ -34,6 +34,9 @@ import type { DriverComponent } from "./components/driver";
|
|
|
34
34
|
import type { RunProgressEvent } from "./components/run-progress";
|
|
35
35
|
import type { WaveRecord } from "./gated-waves";
|
|
36
36
|
|
|
37
|
+
// #4020: every pending fact names the commit it was recorded at. The transcripts pin one.
|
|
38
|
+
vi.mock("./lifecycle/commit-sha", () => ({ resolveCommitSha: async () => "1".repeat(40) }));
|
|
39
|
+
|
|
37
40
|
const digest = (n: string) => `sha256:${n.repeat(64)}`;
|
|
38
41
|
const NOW = "2026-10-11T00:00:00.000Z";
|
|
39
42
|
const BEFORE = "2026-10-10T00:00:00Z";
|
|
@@ -46,6 +49,12 @@ beforeEach(() => {
|
|
|
46
49
|
// A pull request's address would land on every pending fact too.
|
|
47
50
|
vi.stubEnv("GITHUB_REF_NAME", "");
|
|
48
51
|
vi.stubEnv("CI_MERGE_REQUEST_IID", "");
|
|
52
|
+
// A CI run's id would land on them as well (#4020).
|
|
53
|
+
vi.stubEnv("GITHUB_RUN_ID", "");
|
|
54
|
+
vi.stubEnv("CI_PIPELINE_ID", "");
|
|
55
|
+
// And the commit the CI job started for, which a decision point's gate reads from the environment.
|
|
56
|
+
vi.stubEnv("GITHUB_SHA", "");
|
|
57
|
+
vi.stubEnv("CI_COMMIT_SHA", "");
|
|
49
58
|
});
|
|
50
59
|
afterEach(() => vi.unstubAllEnvs());
|
|
51
60
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A workspace with feature flags (#4024), for the flag tests: a throwaway git
|
|
3
|
+
* repository with a decision kind, the reference workspace's work kind, and
|
|
4
|
+
* the canonical flag kind chant ships at `reference-kinds/flag`.
|
|
5
|
+
*
|
|
6
|
+
* - The decision kind closes `confirmed` and `superseded`. d-001 is
|
|
7
|
+
* confirmed, d-002 is only decided.
|
|
8
|
+
* - W-001 implements d-001, so its work is settled. W-002 implements d-002.
|
|
9
|
+
* - The flag `old-banner` hides W-001, so it is due for removal (stale).
|
|
10
|
+
* - The flag `new-checkout` hides W-002 and backs the build parameter
|
|
11
|
+
* `newCheckout` of member `shop`: on in dev, off in prod, and no value in
|
|
12
|
+
* staging.
|
|
13
|
+
* - Member `shop` has a component whose deploy declares a gate, so every
|
|
14
|
+
* environment it builds for has one. Member `blog` has a component with
|
|
15
|
+
* no gate.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
import { git, repo } from "./contract-repo";
|
|
21
|
+
|
|
22
|
+
const HERE = import.meta.dirname;
|
|
23
|
+
const REPO_ROOT = join(HERE, "..", "..", "..", "..", "..");
|
|
24
|
+
const REF = join(REPO_ROOT, "reference-workspace");
|
|
25
|
+
const ref = (path: string) => readFileSync(join(REF, path), "utf-8");
|
|
26
|
+
const canonical = (file: string) => readFileSync(join(HERE, "..", "reference-kinds", "flag", file), "utf-8");
|
|
27
|
+
|
|
28
|
+
const DECISION_KIND = `export const recordKind = {
|
|
29
|
+
name: "decision",
|
|
30
|
+
location: { dir: ".", match: "^d-[0-9]{3}-.+\\\\.md$" },
|
|
31
|
+
format: "markdown-front-matter",
|
|
32
|
+
schema: { id: "urn:test:decision:1", path: "decision.schema.json" },
|
|
33
|
+
idField: "id",
|
|
34
|
+
stateField: "state",
|
|
35
|
+
states: ["proposed", "decided", "confirmed", "superseded"],
|
|
36
|
+
closedStates: ["confirmed", "superseded"],
|
|
37
|
+
approval: { proposed: 0, decided: 1, confirmed: 2, superseded: 2 },
|
|
38
|
+
supersedes: { field: "supersedes" },
|
|
39
|
+
};
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const DECISION_SCHEMA = JSON.stringify(
|
|
43
|
+
{
|
|
44
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
45
|
+
$id: "urn:test:decision:1",
|
|
46
|
+
type: "object",
|
|
47
|
+
required: ["id", "state"],
|
|
48
|
+
properties: { id: { type: "string" }, state: { type: "string" }, supersedes: { type: "array", items: { type: "string" } } },
|
|
49
|
+
},
|
|
50
|
+
null,
|
|
51
|
+
2,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const decision = (id: string, state: string) => `---\nid: "${id}"\nstate: "${state}"\nsupersedes: []\n---\n\n# ${id}\n`;
|
|
55
|
+
|
|
56
|
+
export function workItem(id: string, implementsIds: string[], state = "in-progress"): string {
|
|
57
|
+
const data = {
|
|
58
|
+
schema: 1,
|
|
59
|
+
id,
|
|
60
|
+
title: `Work ${id}`,
|
|
61
|
+
state,
|
|
62
|
+
implements: implementsIds,
|
|
63
|
+
needs: [],
|
|
64
|
+
constrains: ["member:shop"],
|
|
65
|
+
evidence: [],
|
|
66
|
+
owner: "alice",
|
|
67
|
+
opened_on: "2026-10-01",
|
|
68
|
+
...(state === "done" ? { closed_on: "2026-10-10" } : {}),
|
|
69
|
+
source: { kind: "workspace", member: "shop" },
|
|
70
|
+
supersedes: [],
|
|
71
|
+
};
|
|
72
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function flagRecord(id: string, fields: { work: string; member: string; param: string; values: Record<string, string | number | boolean>; owner?: string }): string {
|
|
76
|
+
const data = { schema: 1, id, owner: fields.owner ?? "alice", work: fields.work, member: fields.member, param: fields.param, values: fields.values };
|
|
77
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** A component file whose deploy declares a gate when `gated` is set. */
|
|
81
|
+
export function componentFile(name: string, gated: boolean): string {
|
|
82
|
+
const steps = gated ? `[{ kind: "gate", gate: "prod-release" }, { kind: "apply", template: "dist/${name}.json" }]` : `[{ kind: "apply", template: "dist/${name}.json" }]`;
|
|
83
|
+
return `export const ${name} = { name: "${name}", dependsOn: [], deploy: [{ phase: "Apply", steps: ${steps} }] };\n`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The flag workspace's files, with `overrides` laid over them (a null value removes a file). */
|
|
87
|
+
export function flagWorkspaceFiles(overrides: Record<string, string | null> = {}): Record<string, string> {
|
|
88
|
+
const files: Record<string, string | null> = {
|
|
89
|
+
"chant.workspace.json": JSON.stringify(
|
|
90
|
+
{
|
|
91
|
+
name: "flags",
|
|
92
|
+
schema: 1,
|
|
93
|
+
members: [
|
|
94
|
+
{ name: "shop", dir: "shop", kind: "chant" },
|
|
95
|
+
{ name: "blog", dir: "blog", kind: "chant" },
|
|
96
|
+
],
|
|
97
|
+
records: [{ kind: "decisions/decision.kind.mjs" }, { kind: "work/work.kind.mjs" }, { kind: "flags/flag.kind.mjs" }],
|
|
98
|
+
},
|
|
99
|
+
null,
|
|
100
|
+
2,
|
|
101
|
+
),
|
|
102
|
+
"shop/chant.config.ts": `export default { environments: ["dev", "staging", "prod"] };\n`,
|
|
103
|
+
"shop/shop.component.ts": componentFile("shop", true),
|
|
104
|
+
"blog/chant.config.ts": `export default { environments: ["dev", "prod"] };\n`,
|
|
105
|
+
"blog/blog.component.ts": componentFile("blog", false),
|
|
106
|
+
"decisions/decision.kind.mjs": DECISION_KIND,
|
|
107
|
+
"decisions/decision.schema.json": DECISION_SCHEMA,
|
|
108
|
+
"decisions/d-001-the-banner.md": decision("d-001", "confirmed"),
|
|
109
|
+
"decisions/d-002-the-checkout.md": decision("d-002", "decided"),
|
|
110
|
+
"work/work.kind.mjs": ref("work/work.kind.mjs").replace(' answers: "../answers/answer.kind.mjs",\n', ""),
|
|
111
|
+
"work/work.schema.json": ref("work/work.schema.json"),
|
|
112
|
+
"work/W-001-the-banner.md": workItem("W-001", ["d-001"], "done"),
|
|
113
|
+
"work/W-002-the-checkout.md": workItem("W-002", ["d-002"]),
|
|
114
|
+
"flags/flag.kind.mjs": canonical("flag.kind.mjs"),
|
|
115
|
+
"flags/flag.schema.json": canonical("flag.schema.json"),
|
|
116
|
+
"flags/old-banner.flag.md": flagRecord("old-banner", { work: "W-001", member: "blog", param: "banner", values: { dev: true, prod: true } }),
|
|
117
|
+
"flags/new-checkout.flag.md": flagRecord("new-checkout", { work: "W-002", member: "shop", param: "newCheckout", values: { dev: true, prod: false } }),
|
|
118
|
+
...overrides,
|
|
119
|
+
};
|
|
120
|
+
return Object.fromEntries(Object.entries(files).filter((e): e is [string, string] => e[1] !== null));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The flag workspace in a new git repository, committed. */
|
|
124
|
+
export function flagWorkspace(overrides: Record<string, string | null> = {}): string {
|
|
125
|
+
const root = repo(flagWorkspaceFiles(overrides));
|
|
126
|
+
git(root, "config", "user.name", "t");
|
|
127
|
+
git(root, "config", "user.email", "t@example.com");
|
|
128
|
+
git(root, "config", "commit.gpgsign", "false");
|
|
129
|
+
git(root, "add", "-A");
|
|
130
|
+
git(root, "commit", "-q", "-m", "flags");
|
|
131
|
+
return root;
|
|
132
|
+
}
|