@intentius/chant 0.124.46 → 0.124.48
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/dist/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/dist/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +13 -0
- package/dist/__golden__/wave-loop/op-denied-source.json +16 -0
- package/dist/__golden__/wave-loop/op-denied.json +16 -0
- package/dist/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/dist/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/dist/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/dist/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/dist/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on.json +16 -0
- package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/dist/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/dist/__golden__/wave-loop/op-overridden.json +16 -0
- package/dist/__golden__/wave-loop/op-per-run.json +20 -0
- package/dist/__golden__/wave-loop/op-point.json +13 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +10 -0
- package/dist/__golden__/wave-loop/op-sealed.json +10 -0
- package/dist/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/dist/__golden__/wave-loop/op-spend.json +10 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/dist/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/dist/__golden__/wave-loop/op-wide.json +39 -0
- package/dist/action-pins.d.ts +61 -0
- package/dist/action-pins.d.ts.map +1 -0
- package/dist/action-pins.js +77 -0
- package/dist/cli/commands/carve.d.ts +3 -0
- package/dist/cli/commands/carve.d.ts.map +1 -1
- package/dist/cli/commands/carve.js +36 -7
- package/dist/cli/commands/import-report.d.ts +26 -0
- package/dist/cli/commands/import-report.d.ts.map +1 -0
- package/dist/cli/commands/import-report.js +65 -0
- package/dist/cli/commands/import.d.ts +11 -1
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/import.js +22 -3
- package/dist/cli/commands/migrate.d.ts +13 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +134 -10
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +21 -2
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +6 -1
- package/dist/cli/handlers/ledger.d.ts +3 -0
- package/dist/cli/handlers/ledger.d.ts.map +1 -0
- package/dist/cli/handlers/ledger.js +55 -0
- package/dist/cli/handlers/migrate.d.ts.map +1 -1
- package/dist/cli/handlers/migrate.js +18 -11
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +12 -1
- package/dist/cli/handlers/pr-env.js +2 -2
- package/dist/cli/handlers/pr.d.ts +15 -1
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +143 -39
- package/dist/cli/handlers/query.d.ts +7 -2
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +16 -4
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +6 -3
- package/dist/cli/handlers/search.d.ts +2 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +13 -39
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +65 -14
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +36 -2
- package/dist/cli/registry.d.ts +14 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/builders.d.ts +5 -1
- package/dist/components/builders.d.ts.map +1 -1
- package/dist/components/builders.js +5 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +16 -1
- package/dist/components/capability-plugin.d.ts +14 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/pr-hooks.d.ts +21 -1
- package/dist/components/pr-hooks.d.ts.map +1 -1
- package/dist/components/pr-hooks.js +72 -4
- package/dist/components/pr-pipeline.d.ts +45 -10
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +47 -14
- package/dist/components/pr-policy.d.ts +36 -0
- package/dist/components/pr-policy.d.ts.map +1 -1
- package/dist/components/pr-policy.js +36 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +5 -1
- package/dist/components/verbs/index.d.ts +2 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +2 -0
- package/dist/components/verbs/publish-artifact.d.ts +65 -0
- package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
- package/dist/components/verbs/publish-artifact.js +74 -0
- package/dist/components/verbs/publish-image.d.ts +129 -0
- package/dist/components/verbs/publish-image.d.ts.map +1 -0
- package/dist/components/verbs/publish-image.js +145 -0
- package/dist/config-environments.d.ts +20 -0
- package/dist/config-environments.d.ts.map +1 -1
- package/dist/config-environments.js +12 -0
- package/dist/config.d.ts +9 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -2
- package/dist/gate-decision.d.ts +11 -2
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +15 -3
- package/dist/graph-ir.d.ts +25 -0
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-walk.d.ts +66 -0
- package/dist/graph-walk.d.ts.map +1 -0
- package/dist/graph-walk.js +70 -0
- package/dist/import/parser.d.ts +19 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/lexicon.d.ts +71 -6
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +11 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +2 -5
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/ledger-read.d.ts +65 -0
- package/dist/lifecycle/ledger-read.d.ts.map +1 -0
- package/dist/lifecycle/ledger-read.js +160 -0
- package/dist/lifecycle/release-workstation.d.ts +7 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -1
- package/dist/lifecycle/release-workstation.js +25 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -3
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +1 -0
- package/dist/lint/discover.js +3 -1
- package/dist/lint/post-synth.d.ts +127 -1
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/post-synth.js +84 -2
- package/dist/lint/rules/op/index.d.ts +1 -0
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.js +2 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
- package/dist/op/activities/activity-contracts.d.ts +5 -2
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +5 -2
- package/dist/op/activities/index.d.ts +2 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +1 -1
- package/dist/op/activities/review-agent.d.ts +90 -4
- package/dist/op/activities/review-agent.d.ts.map +1 -1
- package/dist/op/activities/review-agent.js +217 -19
- package/dist/op/activities/work-evidence.d.ts +8 -1
- package/dist/op/activities/work-evidence.d.ts.map +1 -1
- package/dist/op/activities/work-evidence.js +1 -0
- package/dist/op/builders.d.ts +9 -5
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -5
- package/dist/op/composites/apply-op.d.ts +29 -2
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/apply-op.js +20 -1
- package/dist/op/gate-approval.d.ts +11 -5
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-approval.js +11 -6
- package/dist/op/gate-quorum.d.ts +100 -3
- package/dist/op/gate-quorum.d.ts.map +1 -1
- package/dist/op/gate-quorum.js +108 -6
- package/dist/op/gate-review.d.ts +9 -0
- package/dist/op/gate-review.d.ts.map +1 -1
- package/dist/op/gate-review.js +13 -0
- package/dist/op/gate.d.ts +44 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +25 -4
- package/dist/op/index.d.ts +3 -3
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +38 -3
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +48 -6
- package/dist/op/op-waves-run.d.ts +26 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +259 -13
- package/dist/op/op-waves.d.ts +72 -5
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +110 -15
- package/dist/op/runtime.d.ts +11 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/schedule-overdue.d.ts +16 -0
- package/dist/op/schedule-overdue.d.ts.map +1 -1
- package/dist/op/schedule-overdue.js +36 -0
- package/dist/op/stage-hooks.d.ts +9 -2
- package/dist/op/stage-hooks.d.ts.map +1 -1
- package/dist/op/stage-hooks.js +7 -5
- package/dist/op/workspace-run-env.d.ts +22 -0
- package/dist/op/workspace-run-env.d.ts.map +1 -0
- package/dist/op/workspace-run-env.js +21 -0
- package/dist/pr-forge.d.ts +24 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +47 -0
- package/dist/pr-post.d.ts +42 -0
- package/dist/pr-post.d.ts.map +1 -1
- package/dist/pr-post.js +67 -1
- package/dist/read-filter.d.ts +65 -0
- package/dist/read-filter.d.ts.map +1 -0
- package/dist/read-filter.js +179 -0
- package/dist/run-event.d.ts +1 -1
- package/dist/run-event.d.ts.map +1 -1
- package/dist/terraform/carve.d.ts +24 -3
- package/dist/terraform/carve.d.ts.map +1 -1
- package/dist/terraform/carve.js +32 -14
- package/dist/terraform/cuts.d.ts +97 -0
- package/dist/terraform/cuts.d.ts.map +1 -0
- package/dist/terraform/cuts.js +138 -0
- package/dist/terraform/folds.d.ts +26 -0
- package/dist/terraform/folds.d.ts.map +1 -0
- package/dist/terraform/folds.js +38 -0
- package/dist/terraform/graph.d.ts.map +1 -1
- package/dist/terraform/graph.js +10 -0
- package/dist/terraform/reach.d.ts +140 -0
- package/dist/terraform/reach.d.ts.map +1 -0
- package/dist/terraform/reach.js +170 -0
- package/dist/terraform/score.d.ts +14 -0
- package/dist/terraform/score.d.ts.map +1 -1
- package/dist/terraform/score.js +14 -31
- package/dist/terraform/state.d.ts.map +1 -1
- package/dist/terraform/state.js +4 -2
- package/dist/terraform/types.d.ts +8 -0
- package/dist/terraform/types.d.ts.map +1 -1
- package/dist/wave-blocked.d.ts +10 -1
- package/dist/wave-blocked.d.ts.map +1 -1
- package/dist/wave-blocked.js +31 -3
- package/dist/wave-runtime.mjs +263 -254
- package/dist/workspace/check.schema.json +11 -2
- package/dist/workspace/checks/ci-branch.d.ts +44 -0
- package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
- package/dist/workspace/checks/ci-branch.js +133 -0
- package/dist/workspace/checks/links.d.ts +3 -0
- package/dist/workspace/checks/links.d.ts.map +1 -1
- package/dist/workspace/checks/links.js +12 -1
- package/dist/workspace/checks/org.d.ts +48 -0
- package/dist/workspace/checks/org.d.ts.map +1 -0
- package/dist/workspace/checks/org.js +156 -0
- package/dist/workspace/checks.d.ts +11 -1
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +59 -7
- package/dist/workspace/ci-branches.d.ts +16 -0
- package/dist/workspace/ci-branches.d.ts.map +1 -1
- package/dist/workspace/ci-branches.js +27 -0
- package/dist/workspace/ci-green-cli.js +7 -7
- package/dist/workspace/ci-green-workflow.d.ts +1 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +13 -8
- package/dist/workspace/ci-green.d.ts +14 -0
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +44 -11
- package/dist/workspace/ci-run.d.ts +9 -1
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +67 -6
- package/dist/workspace/ci-serve.d.ts +9 -0
- package/dist/workspace/ci-serve.d.ts.map +1 -1
- package/dist/workspace/ci-serve.js +114 -76
- package/dist/workspace/compose-graph.d.ts +14 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +4 -1
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/composites.js +5 -2
- package/dist/workspace/composites.schema.json +22 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
- package/dist/workspace/cross-root-lint.d.ts +56 -0
- package/dist/workspace/cross-root-lint.d.ts.map +1 -0
- package/dist/workspace/cross-root-lint.js +111 -0
- package/dist/workspace/dbt-models-reader.d.ts +44 -0
- package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
- package/dist/workspace/dbt-models-reader.js +356 -0
- package/dist/workspace/dbt-project-common.d.ts +40 -0
- package/dist/workspace/dbt-project-common.d.ts.map +1 -0
- package/dist/workspace/dbt-project-common.js +106 -0
- package/dist/workspace/dbt-project-reader.d.ts +4 -3
- package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
- package/dist/workspace/dbt-project-reader.js +14 -108
- package/dist/workspace/decision-rank.d.ts +26 -0
- package/dist/workspace/decision-rank.d.ts.map +1 -0
- package/dist/workspace/decision-rank.js +16 -0
- package/dist/workspace/declaration.d.ts +43 -2
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +45 -11
- package/dist/workspace/declaration.schema.json +133 -24
- package/dist/workspace/environments.d.ts +26 -2
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/environments.js +26 -2
- package/dist/workspace/flyway-dir.d.ts +39 -0
- package/dist/workspace/flyway-dir.d.ts.map +1 -0
- package/dist/workspace/flyway-dir.js +104 -0
- package/dist/workspace/flyway-layout.d.ts +96 -0
- package/dist/workspace/flyway-layout.d.ts.map +1 -0
- package/dist/workspace/flyway-layout.js +308 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +26 -8
- package/dist/workspace/graph.schema.json +34 -0
- package/dist/workspace/intent.d.ts +2 -3
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +5 -9
- package/dist/workspace/kind-link-readers.d.ts +59 -2
- package/dist/workspace/kind-link-readers.d.ts.map +1 -1
- package/dist/workspace/kind-link-readers.js +17 -1
- package/dist/workspace/kinds.d.ts +66 -2
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +98 -4
- package/dist/workspace/ledger.schema.json +158 -0
- package/dist/workspace/lexicon-outputs.d.ts +20 -1
- package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
- package/dist/workspace/lexicon-outputs.js +102 -10
- package/dist/workspace/lineage-check.d.ts +3 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-check.js +23 -4
- package/dist/workspace/links.d.ts +8 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/links.js +25 -1
- package/dist/workspace/ls.d.ts +8 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +7 -1
- package/dist/workspace/ls.schema.json +7 -0
- package/dist/workspace/member-commands.d.ts.map +1 -1
- package/dist/workspace/member-commands.js +54 -5
- package/dist/workspace/migrate-links.d.ts +45 -0
- package/dist/workspace/migrate-links.d.ts.map +1 -0
- package/dist/workspace/migrate-links.js +100 -0
- package/dist/workspace/migration-dirs.d.ts +74 -0
- package/dist/workspace/migration-dirs.d.ts.map +1 -0
- package/dist/workspace/migration-dirs.js +254 -0
- package/dist/workspace/reason-codes.d.ts +8 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +11 -0
- package/dist/workspace/records-cli.d.ts +11 -0
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-cli.js +57 -5
- package/dist/workspace/records.schema.json +5 -0
- package/dist/workspace/release-candidates.d.ts +2 -0
- package/dist/workspace/release-candidates.d.ts.map +1 -1
- package/dist/workspace/release-candidates.js +5 -2
- package/dist/workspace/release-train.d.ts +53 -0
- package/dist/workspace/release-train.d.ts.map +1 -0
- package/dist/workspace/release-train.js +134 -0
- package/dist/workspace/release-workflow.d.ts.map +1 -1
- package/dist/workspace/release-workflow.js +4 -3
- package/dist/workspace/repo-ref.d.ts +45 -0
- package/dist/workspace/repo-ref.d.ts.map +1 -0
- package/dist/workspace/repo-ref.js +114 -0
- package/dist/workspace/run-event.schema.json +2 -2
- package/dist/workspace/runs-cli.d.ts +9 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -1
- package/dist/workspace/runs-cli.js +48 -3
- package/dist/workspace/runs.schema.json +7 -0
- package/dist/workspace/search-contract.d.ts +1 -1
- package/dist/workspace/search-contract.d.ts.map +1 -1
- package/dist/workspace/status-decisions.d.ts +37 -0
- package/dist/workspace/status-decisions.d.ts.map +1 -0
- package/dist/workspace/status-decisions.js +147 -0
- package/dist/workspace/status-gates.d.ts +9 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +4 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +14 -2
- package/dist/workspace/status.schema.json +6 -0
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-cli.js +5 -3
- package/dist/workspace/work-evidence-ops.d.ts +83 -0
- package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
- package/dist/workspace/work-evidence-ops.js +169 -0
- package/dist/workspace/work-evidence.d.ts +12 -2
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-evidence.js +21 -3
- package/dist/workspace/work-evidence.schema.json +49 -2
- package/dist/workspace/workspace-gates.d.ts +110 -0
- package/dist/workspace/workspace-gates.d.ts.map +1 -0
- package/dist/workspace/workspace-gates.js +140 -0
- package/dist/workspace/workspace-kinds.schema.json +58 -3
- package/dist/workspace/workspace-ledger.d.ts +76 -0
- package/dist/workspace/workspace-ledger.d.ts.map +1 -0
- package/dist/workspace/workspace-ledger.js +91 -0
- package/dist/workspace/workspace-run.d.ts +112 -0
- package/dist/workspace/workspace-run.d.ts.map +1 -0
- package/dist/workspace/workspace-run.js +432 -0
- package/package.json +1 -1
- package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/src/__golden__/wave-loop/op-cost-member.json +13 -0
- package/src/__golden__/wave-loop/op-denied-source.json +16 -0
- package/src/__golden__/wave-loop/op-denied.json +16 -0
- package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/src/__golden__/wave-loop/op-held-on.json +16 -0
- package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/src/__golden__/wave-loop/op-overridden.json +16 -0
- package/src/__golden__/wave-loop/op-per-run.json +20 -0
- package/src/__golden__/wave-loop/op-point.json +13 -0
- package/src/__golden__/wave-loop/op-pr-review.json +10 -0
- package/src/__golden__/wave-loop/op-sealed.json +10 -0
- package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/src/__golden__/wave-loop/op-spend.json +10 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/src/__golden__/wave-loop/op-wide.json +39 -0
- package/src/action-pins.test.ts +78 -0
- package/src/action-pins.ts +92 -0
- package/src/cli/commands/carve-score-once.test.ts +99 -0
- package/src/cli/commands/carve.ts +37 -6
- package/src/cli/commands/check-lexicon.test.ts +2 -2
- package/src/cli/commands/import-report.ts +71 -0
- package/src/cli/commands/import.ts +33 -3
- package/src/cli/commands/migrate-dialect.test.ts +145 -0
- package/src/cli/commands/migrate.ts +132 -11
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
- package/src/cli/handlers/approve.ts +23 -2
- package/src/cli/handlers/build.ts +7 -1
- package/src/cli/handlers/ledger.ts +54 -0
- package/src/cli/handlers/migrate.ts +21 -12
- package/src/cli/handlers/misc.ts +10 -1
- package/src/cli/handlers/pr-env.ts +2 -2
- package/src/cli/handlers/pr.ts +138 -36
- package/src/cli/handlers/query.ts +16 -4
- package/src/cli/handlers/release.ts +6 -3
- package/src/cli/handlers/search.ts +13 -34
- package/src/cli/main.test.ts +15 -0
- package/src/cli/main.ts +65 -14
- package/src/cli/parse-args.ts +27 -2
- package/src/cli/registry.ts +14 -4
- package/src/components/builders.ts +8 -0
- package/src/components/capability-plugin-loader.ts +13 -1
- package/src/components/capability-plugin.ts +16 -0
- package/src/components/pr-hooks.test.ts +73 -5
- package/src/components/pr-hooks.ts +95 -5
- package/src/components/pr-pipeline.ts +64 -16
- package/src/components/pr-policy.test.ts +64 -1
- package/src/components/pr-policy.ts +53 -0
- package/src/components/registry.test.ts +1 -1
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +2 -0
- package/src/components/verbs/publish-artifact.test.ts +60 -0
- package/src/components/verbs/publish-artifact.ts +122 -0
- package/src/components/verbs/publish-image.test.ts +101 -0
- package/src/components/verbs/publish-image.ts +265 -0
- package/src/config-environments.ts +28 -1
- package/src/config.ts +8 -1
- package/src/gate-decision-bundle.test.ts +1 -0
- package/src/gate-decision-identity.test.ts +9 -0
- package/src/gate-decision.ts +26 -3
- package/src/graph-ir.ts +27 -0
- package/src/graph-walk.test.ts +44 -0
- package/src/graph-walk.ts +102 -0
- package/src/import/parser.ts +20 -0
- package/src/lexicon.ts +74 -6
- package/src/lifecycle/gate-ledger.ts +8 -0
- package/src/lifecycle/git.ts +2 -2
- package/src/lifecycle/ledger-read.test.ts +107 -0
- package/src/lifecycle/ledger-read.ts +195 -0
- package/src/lifecycle/release-workstation.ts +24 -0
- package/src/lifecycle/run-ledger.ts +5 -2
- package/src/lint/cross-root.test.ts +122 -0
- package/src/lint/discover.ts +3 -1
- package/src/lint/post-synth.ts +212 -2
- package/src/lint/rules/op/index.ts +2 -0
- package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
- package/src/op/activities/activity-contracts.ts +5 -2
- package/src/op/activities/index.ts +2 -2
- package/src/op/activities/review-agent.test.ts +221 -4
- package/src/op/activities/review-agent.ts +265 -22
- package/src/op/activities/work-evidence.ts +9 -1
- package/src/op/builders.ts +9 -5
- package/src/op/composites/apply-op.test.ts +108 -0
- package/src/op/composites/apply-op.ts +37 -2
- package/src/op/gate-approval.test.ts +6 -1
- package/src/op/gate-approval.ts +12 -6
- package/src/op/gate-quorum-at-base.test.ts +211 -0
- package/src/op/gate-quorum.ts +156 -8
- package/src/op/gate-review.ts +14 -0
- package/src/op/gate.ts +67 -8
- package/src/op/index.ts +3 -2
- package/src/op/local-executor.ts +69 -9
- package/src/op/op-waves-depends-on.test.ts +81 -0
- package/src/op/op-waves-hook-targets.test.ts +4 -2
- package/src/op/op-waves-quorum-product.test.ts +158 -0
- package/src/op/op-waves-run.ts +288 -14
- package/src/op/op-waves.ts +143 -14
- package/src/op/runtime.ts +8 -0
- package/src/op/schedule-overdue.ts +33 -0
- package/src/op/stage-hooks.ts +13 -5
- package/src/op/workspace-run-env.ts +29 -0
- package/src/pr-forge-bundle.test.ts +2 -2
- package/src/pr-forge.test.ts +47 -0
- package/src/pr-forge.ts +68 -0
- package/src/pr-post-open.e2e.test.ts +36 -0
- package/src/pr-post.test.ts +102 -3
- package/src/pr-post.ts +89 -1
- package/src/read-filter.test.ts +54 -0
- package/src/read-filter.ts +193 -0
- package/src/run-event.ts +1 -1
- package/src/stage-hooks-bundle.test.ts +1 -0
- package/src/terraform/carve.ts +52 -15
- package/src/terraform/cuts.test.ts +173 -0
- package/src/terraform/cuts.ts +188 -0
- package/src/terraform/folds.ts +44 -0
- package/src/terraform/graph.ts +9 -0
- package/src/terraform/radius.test.ts +90 -0
- package/src/terraform/reach.test.ts +146 -0
- package/src/terraform/reach.ts +247 -0
- package/src/terraform/score.ts +27 -29
- package/src/terraform/state.ts +3 -1
- package/src/terraform/types.ts +8 -0
- package/src/wave-blocked.ts +28 -3
- package/src/wave-loop-golden.test.ts +4 -3
- package/src/workspace/behold-kinds.test.ts +1 -1
- package/src/workspace/check-contract.test.ts +7 -6
- package/src/workspace/check.schema.json +11 -2
- package/src/workspace/checks/ci-branch.test.ts +128 -0
- package/src/workspace/checks/ci-branch.ts +141 -0
- package/src/workspace/checks/links.ts +12 -1
- package/src/workspace/checks/org.ts +169 -0
- package/src/workspace/checks.ts +64 -7
- package/src/workspace/ci-branches.ts +31 -0
- package/src/workspace/ci-green-branches.test.ts +153 -0
- package/src/workspace/ci-green-cli.ts +7 -7
- package/src/workspace/ci-green-workflow.test.ts +4 -3
- package/src/workspace/ci-green-workflow.ts +13 -9
- package/src/workspace/ci-green.ts +49 -12
- package/src/workspace/ci-run.test.ts +72 -1
- package/src/workspace/ci-run.ts +68 -8
- package/src/workspace/ci-serve.test.ts +95 -0
- package/src/workspace/ci-serve.ts +106 -65
- package/src/workspace/component-environments.test.ts +25 -2
- package/src/workspace/compose-graph.ts +9 -2
- package/src/workspace/composites.schema.json +22 -0
- package/src/workspace/composites.test.ts +39 -8
- package/src/workspace/composites.ts +6 -2
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
- package/src/workspace/cross-root-lint.test.ts +90 -0
- package/src/workspace/cross-root-lint.ts +126 -0
- package/src/workspace/dbt-kind.test.ts +3 -2
- package/src/workspace/dbt-models-reader.ts +362 -0
- package/src/workspace/dbt-models.test.ts +248 -0
- package/src/workspace/dbt-project-common.ts +113 -0
- package/src/workspace/dbt-project-reader.ts +29 -112
- package/src/workspace/decision-rank.ts +40 -0
- package/src/workspace/declaration.schema.json +133 -24
- package/src/workspace/declaration.ts +84 -15
- package/src/workspace/environments.ts +40 -4
- package/src/workspace/flyway-dir.ts +113 -0
- package/src/workspace/flyway-layout.ts +337 -0
- package/src/workspace/graph-cli.ts +25 -10
- package/src/workspace/graph-contract.test.ts +4 -2
- package/src/workspace/graph.schema.json +34 -0
- package/src/workspace/identity.test.ts +14 -2
- package/src/workspace/intent.ts +6 -14
- package/src/workspace/kind-link-readers.ts +68 -3
- package/src/workspace/kinds.test.ts +12 -7
- package/src/workspace/kinds.ts +132 -7
- package/src/workspace/ledger.schema.json +158 -0
- package/src/workspace/lexicon-outputs.ts +132 -13
- package/src/workspace/lineage-check.ts +30 -7
- package/src/workspace/links.ts +24 -1
- package/src/workspace/ls-contract.test.ts +1 -1
- package/src/workspace/ls.schema.json +7 -0
- package/src/workspace/ls.ts +10 -1
- package/src/workspace/member-commands.ts +60 -2
- package/src/workspace/member-file-schema.test.ts +124 -0
- package/src/workspace/migrate-links.test.ts +99 -0
- package/src/workspace/migrate-links.ts +108 -0
- package/src/workspace/migration-dirs.test.ts +272 -0
- package/src/workspace/migration-dirs.ts +267 -0
- package/src/workspace/org-scope.test.ts +238 -0
- package/src/workspace/reason-codes.test.ts +6 -1
- package/src/workspace/reason-codes.ts +11 -0
- package/src/workspace/records-cli.ts +58 -5
- package/src/workspace/records.schema.json +5 -0
- package/src/workspace/release-candidates.ts +7 -2
- package/src/workspace/release-train.ts +157 -0
- package/src/workspace/release-workflow.ts +4 -3
- package/src/workspace/repo-ref.ts +113 -0
- package/src/workspace/run-event.schema.json +2 -2
- package/src/workspace/runs-cli.ts +48 -4
- package/src/workspace/runs.schema.json +7 -0
- package/src/workspace/status-contract.test.ts +46 -1
- package/src/workspace/status-decisions.test.ts +100 -0
- package/src/workspace/status-decisions.ts +151 -0
- package/src/workspace/status-gates.ts +9 -0
- package/src/workspace/status.schema.json +6 -0
- package/src/workspace/status.ts +17 -3
- package/src/workspace/where-filters.test.ts +39 -0
- package/src/workspace/work-cli.ts +5 -3
- package/src/workspace/work-evidence-ops.test.ts +176 -0
- package/src/workspace/work-evidence-ops.ts +189 -0
- package/src/workspace/work-evidence.schema.json +49 -2
- package/src/workspace/work-evidence.ts +22 -3
- package/src/workspace/workspace-gates.ts +200 -0
- package/src/workspace/workspace-kinds.schema.json +58 -3
- package/src/workspace/workspace-ledger.ts +130 -0
- package/src/workspace/workspace-run.test.ts +322 -0
- package/src/workspace/workspace-run.ts +461 -0
|
@@ -17,6 +17,7 @@ import { MEMBER_RUN_REASON_CODES } from "./compose-graph";
|
|
|
17
17
|
import {
|
|
18
18
|
COMPOSITES_CONTRACT_VERSION,
|
|
19
19
|
COMPOSITES_ENVIRONMENT_REASON_CODES,
|
|
20
|
+
COMPOSITES_EXECUTOR_REASON_CODES,
|
|
20
21
|
COMPOSITES_ERROR_CODES,
|
|
21
22
|
COMPOSITES_OUTPUT_SCHEMA_ID,
|
|
22
23
|
COMPOSITES_REASON_CODES,
|
|
@@ -30,6 +31,8 @@ import {
|
|
|
30
31
|
import { GRAPH_ERROR_CODES } from "./graph-cli";
|
|
31
32
|
import schema from "./composites.schema.json";
|
|
32
33
|
|
|
34
|
+
const NO_EXECUTOR = { forge: null, workflow: null, reason: { code: "executor-none-declared", message: expect.any(String) } };
|
|
35
|
+
|
|
33
36
|
afterAll(cleanScratch);
|
|
34
37
|
|
|
35
38
|
const { expectValid } = contract(schema);
|
|
@@ -61,7 +64,7 @@ const componentIr = (components: { name: string; composites?: string[]; archetyp
|
|
|
61
64
|
const local = (name: string) => ({ name: "local", lexicon: null, default: true, command: `chant run --components ${name}` });
|
|
62
65
|
|
|
63
66
|
/** The default environment, named by nothing but chant itself. */
|
|
64
|
-
const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", site: null, command: `chant run --components ${name}` });
|
|
67
|
+
const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", site: null, executor: NO_EXECUTOR, command: `chant run --components ${name}` });
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
70
|
* app declares three instances and exports ImageUri; delivery links to it and
|
|
@@ -117,6 +120,7 @@ describe("composites output schema", () => {
|
|
|
117
120
|
expect(schema.$defs.member.properties.reason.oneOf[1].properties!.code.enum).toEqual([...MEMBER_RUN_REASON_CODES]);
|
|
118
121
|
expect(schema.$defs.member.properties.runtimeReasons.items.properties.code.enum).toEqual([...COMPOSITES_RUNTIME_REASON_CODES]);
|
|
119
122
|
expect(schema.$defs.member.properties.environmentReasons.items.properties.code.enum).toEqual([...COMPOSITES_ENVIRONMENT_REASON_CODES]);
|
|
123
|
+
expect(schema.$defs.environment.properties.executor.properties.reason.oneOf[1].properties!.code.enum).toEqual([...COMPOSITES_EXECUTOR_REASON_CODES]);
|
|
120
124
|
});
|
|
121
125
|
});
|
|
122
126
|
|
|
@@ -381,11 +385,11 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
381
385
|
const g = result((await workspaceComposites({ cwd: declared() })).doc);
|
|
382
386
|
expectValid(g);
|
|
383
387
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
|
|
384
|
-
{ name: "local", default: true, source: "builtin", site: null, command: "chant run --components queue-runner" },
|
|
385
|
-
{ name: "staging", default: false, source: "config", site: null, command: "chant run --components queue-runner --env staging" },
|
|
386
|
-
{ name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
|
|
388
|
+
{ name: "local", default: true, source: "builtin", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner" },
|
|
389
|
+
{ name: "staging", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env staging" },
|
|
390
|
+
{ name: "prod", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env prod" },
|
|
387
391
|
// The pattern pr-* is no environment by itself, and it covers the ledger's pr-42.
|
|
388
|
-
{ name: "pr-42", default: false, source: "ledger", site: null, command: "chant run --components queue-runner --env pr-42" },
|
|
392
|
+
{ name: "pr-42", default: false, source: "ledger", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env pr-42" },
|
|
389
393
|
]);
|
|
390
394
|
const jobs = g.members.find((m) => m.name === "jobs")!;
|
|
391
395
|
expect(jobs.environmentReasons).toEqual([{ code: "environments-ledger-undeclared", message: expect.stringContaining("retired") }]);
|
|
@@ -397,7 +401,7 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
397
401
|
// delivery has no _members/delivery, so the flat staging ledger is its; its config declares nothing, so anything goes.
|
|
398
402
|
expect(g.components.find((c) => c.id === "delivery/edge")!.environments).toEqual([
|
|
399
403
|
localEnv("edge"),
|
|
400
|
-
{ name: "staging", default: false, source: "ledger", site: null, command: "chant run --components edge --env staging" },
|
|
404
|
+
{ name: "staging", default: false, source: "ledger", site: null, executor: NO_EXECUTOR, command: "chant run --components edge --env staging" },
|
|
401
405
|
]);
|
|
402
406
|
expect(g.members.find((m) => m.name === "delivery")!.environmentReasons.map((r) => r.code)).toEqual(["environments-none-declared"]);
|
|
403
407
|
expect(g.members.find((m) => m.name === "docs")!.environmentReasons).toEqual([]);
|
|
@@ -409,8 +413,8 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
409
413
|
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
410
414
|
expectValid(g);
|
|
411
415
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
|
|
412
|
-
{ name: "local", default: true, source: "config", site: null, command: "chant run --components queue-runner" },
|
|
413
|
-
{ name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
|
|
416
|
+
{ name: "local", default: true, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner" },
|
|
417
|
+
{ name: "prod", default: false, source: "config", site: null, executor: NO_EXECUTOR, command: "chant run --components queue-runner --env prod" },
|
|
414
418
|
]);
|
|
415
419
|
expect(g.members.find((m) => m.name === "jobs")!.environmentReasons).toEqual([]);
|
|
416
420
|
});
|
|
@@ -445,4 +449,31 @@ describe("the environments each component may deploy to (#2695)", () => {
|
|
|
445
449
|
expect(g.members.find((m) => m.name === "jobs")!.environmentReasons).toEqual([{ code: "environments-ledger-unreadable", message: "boom" }]);
|
|
446
450
|
expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments.map((e) => e.name)).toEqual(["local", "prod"]);
|
|
447
451
|
});
|
|
452
|
+
|
|
453
|
+
test("each environment names the forge workflow the config declares for it, a literal before a pattern (#4402)", async () => {
|
|
454
|
+
const root = declared();
|
|
455
|
+
writeFileSync(
|
|
456
|
+
join(root, "jobs", "chant.config.ts"),
|
|
457
|
+
'export default { environments: ["staging", { name: "prod", executor: { forge: "github", workflow: "deploy-prod.yml" } }, { name: "pr-*", executor: { forge: "forgejo", workflow: "preview.yml" } }] };\n',
|
|
458
|
+
);
|
|
459
|
+
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
460
|
+
expectValid(g);
|
|
461
|
+
const executors = Object.fromEntries(g.components.find((c) => c.id === "jobs/queue-runner")!.environments.map((e) => [e.name, e.executor]));
|
|
462
|
+
expect(executors).toEqual({
|
|
463
|
+
local: NO_EXECUTOR,
|
|
464
|
+
staging: NO_EXECUTOR,
|
|
465
|
+
prod: { forge: "github", workflow: "deploy-prod.yml", reason: null },
|
|
466
|
+
"pr-42": { forge: "forgejo", workflow: "preview.yml", reason: null },
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
test("a config that can't be read says no executor is known (#4402)", async () => {
|
|
471
|
+
const root = declared();
|
|
472
|
+
writeFileSync(join(root, "jobs", "chant.config.ts"), 'throw new Error("no config here");\nexport default {};\n');
|
|
473
|
+
const g = result((await workspaceComposites({ cwd: root })).doc);
|
|
474
|
+
expectValid(g);
|
|
475
|
+
for (const e of g.components.find((c) => c.id === "jobs/queue-runner")!.environments) {
|
|
476
|
+
expect(e.executor).toEqual({ forge: null, workflow: null, reason: { code: "executor-config-unreadable", message: expect.stringContaining(e.name) } });
|
|
477
|
+
}
|
|
478
|
+
});
|
|
448
479
|
});
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
* And each component lists the environments it may deploy to (#2695,
|
|
37
37
|
* `environments.ts`): `local`, the environments its member's config declares,
|
|
38
38
|
* and those with a release in the member's ledger on `chant/lifecycle`, with
|
|
39
|
-
* the command line for each
|
|
39
|
+
* the command line for each, and the forge workflow that deploys each one
|
|
40
|
+
* when the member's config names it (#4402).
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
43
|
import { formatError } from "../cli/format";
|
|
@@ -50,7 +51,7 @@ import { emitDocument, type UnitResult } from "./member-commands";
|
|
|
50
51
|
import { readerVersion, WORKSPACE_ERROR_CODES, type ErrorLocation, type WorkspaceErrorCode } from "./declaration";
|
|
51
52
|
import type { ReasonCode } from "./reason-codes";
|
|
52
53
|
import type { ComponentEnvironmentDeclaration } from "../components/component";
|
|
53
|
-
import { componentEnvironments, ENVIRONMENT_REASON_CODES, memberEnvironments, readLedgerEnvironments, type ComponentEnvironment, type EnvironmentReason, type LedgerEnvironmentReader, type MemberEnvironments } from "./environments";
|
|
54
|
+
import { componentEnvironments, ENVIRONMENT_REASON_CODES, EXECUTOR_REASON_CODES, memberEnvironments, readLedgerEnvironments, type ComponentEnvironment, type EnvironmentReason, type LedgerEnvironmentReader, type MemberEnvironments } from "./environments";
|
|
54
55
|
import { componentRuntimes, readRuntimesIn, RUNTIME_REASON_CODES, type ComponentRuntime, type MemberRuntimes, type PluginLoader, type RuntimeReason } from "./runtimes";
|
|
55
56
|
|
|
56
57
|
/** `$id` of the JSON Schema for the document, shipped beside this file. */
|
|
@@ -83,6 +84,9 @@ export const COMPOSITES_RUNTIME_REASON_CODES = RUNTIME_REASON_CODES;
|
|
|
83
84
|
/** Why a member's environments are only `local`, or leave out one its ledger has (#2695). Closed. */
|
|
84
85
|
export const COMPOSITES_ENVIRONMENT_REASON_CODES = ENVIRONMENT_REASON_CODES;
|
|
85
86
|
|
|
87
|
+
/** Why an environment row's executor names no forge workflow (#4402). Closed. */
|
|
88
|
+
export const COMPOSITES_EXECUTOR_REASON_CODES = EXECUTOR_REASON_CODES;
|
|
89
|
+
|
|
86
90
|
export interface CompositesMember {
|
|
87
91
|
name: string;
|
|
88
92
|
dir: string;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"uniqueItems": true
|
|
80
80
|
},
|
|
81
81
|
"evidence": {
|
|
82
|
-
"description": "The proof of done: public links,
|
|
82
|
+
"description": "The proof of done: public links, workspace files pinned by the hash of their bytes (chant workspace records pin <path>), or ops results on the chant/lifecycle branch (#3171). May be empty while the work is open; a done item with none gets the warning work-done-unpinned. An entry that names a criterion from acceptance carries the verification it is and its result, and a manual verdict names who gave it in by (#2772).",
|
|
83
83
|
"type": "array",
|
|
84
84
|
"items": {
|
|
85
85
|
"oneOf": [
|
|
@@ -88,6 +88,9 @@
|
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"$ref": "#/definitions/evidencePin"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"$ref": "#/definitions/evidenceOps"
|
|
91
94
|
}
|
|
92
95
|
]
|
|
93
96
|
}
|
|
@@ -305,6 +308,107 @@
|
|
|
305
308
|
]
|
|
306
309
|
}
|
|
307
310
|
},
|
|
311
|
+
"evidenceOps": {
|
|
312
|
+
"description": "An ops result on the chant/lifecycle branch (#3171): a run, a deploy, a gate answer or a release plan, named the way graph --intent's trace names a link. chant workspace work evidence and the workEvidence activity check it against the ledger before writing it, and a cited run's outcome agrees with result.",
|
|
313
|
+
"type": "object",
|
|
314
|
+
"additionalProperties": false,
|
|
315
|
+
"required": [
|
|
316
|
+
"title",
|
|
317
|
+
"ops"
|
|
318
|
+
],
|
|
319
|
+
"properties": {
|
|
320
|
+
"title": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"minLength": 1
|
|
323
|
+
},
|
|
324
|
+
"ops": {
|
|
325
|
+
"type": "object",
|
|
326
|
+
"additionalProperties": false,
|
|
327
|
+
"required": [
|
|
328
|
+
"ledger",
|
|
329
|
+
"ref",
|
|
330
|
+
"field",
|
|
331
|
+
"value",
|
|
332
|
+
"sha256"
|
|
333
|
+
],
|
|
334
|
+
"properties": {
|
|
335
|
+
"ledger": {
|
|
336
|
+
"description": "Which ledger: an Op run, a deploy record, a gate answer or a release plan.",
|
|
337
|
+
"enum": [
|
|
338
|
+
"run",
|
|
339
|
+
"deploy",
|
|
340
|
+
"gate",
|
|
341
|
+
"plan"
|
|
342
|
+
]
|
|
343
|
+
},
|
|
344
|
+
"ref": {
|
|
345
|
+
"description": "The ledger file, as chant/lifecycle:<path>.",
|
|
346
|
+
"type": "string",
|
|
347
|
+
"pattern": "^chant/lifecycle:"
|
|
348
|
+
},
|
|
349
|
+
"field": {
|
|
350
|
+
"description": "The field of the record that picks it out of the file, such as id, runId, timestamp or digest.",
|
|
351
|
+
"type": "string",
|
|
352
|
+
"minLength": 1
|
|
353
|
+
},
|
|
354
|
+
"value": {
|
|
355
|
+
"description": "That field's value.",
|
|
356
|
+
"type": "string",
|
|
357
|
+
"minLength": 1
|
|
358
|
+
},
|
|
359
|
+
"sha256": {
|
|
360
|
+
"description": "Hex SHA-256 of the record as the ledger stores it: the line, or the plan file.",
|
|
361
|
+
"type": "string",
|
|
362
|
+
"pattern": "^[0-9a-f]{64}$"
|
|
363
|
+
},
|
|
364
|
+
"env": {
|
|
365
|
+
"description": "The environment, for a run or a deploy.",
|
|
366
|
+
"type": "string"
|
|
367
|
+
},
|
|
368
|
+
"outcome": {
|
|
369
|
+
"description": "The run's status, for a run.",
|
|
370
|
+
"enum": [
|
|
371
|
+
"ok",
|
|
372
|
+
"fail"
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
"as_of": {
|
|
378
|
+
"description": "When the result was cited, as an ISO 8601 timestamp.",
|
|
379
|
+
"type": [
|
|
380
|
+
"string",
|
|
381
|
+
"null"
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
"criterion": {
|
|
385
|
+
"description": "The acceptance criterion this evidence is for, by id (#2772).",
|
|
386
|
+
"type": "string",
|
|
387
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
|
388
|
+
},
|
|
389
|
+
"verification": {
|
|
390
|
+
"$ref": "#/definitions/verification"
|
|
391
|
+
},
|
|
392
|
+
"result": {
|
|
393
|
+
"description": "Whether the evidence shows the criterion met.",
|
|
394
|
+
"enum": [
|
|
395
|
+
"pass",
|
|
396
|
+
"fail"
|
|
397
|
+
]
|
|
398
|
+
},
|
|
399
|
+
"by": {
|
|
400
|
+
"description": "Who produced the evidence: the lease holder for a steward's, the person for a manual verdict.",
|
|
401
|
+
"type": "string",
|
|
402
|
+
"minLength": 1
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
"dependencies": {
|
|
406
|
+
"criterion": [
|
|
407
|
+
"verification",
|
|
408
|
+
"result"
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
},
|
|
308
412
|
"evidencePin": {
|
|
309
413
|
"description": "A file in the workspace, pinned by the hash of its bytes. chant workspace records reports a file that changed or went missing since.",
|
|
310
414
|
"type": "object",
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The disagreement lint (#2549, #2524 D6) in #1939's cross-build-root mode:
|
|
3
|
+
* LNK001 over the composed graph's links, and the cross-root checks the
|
|
4
|
+
* members' lexicons ship.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, test, expect } from "vitest";
|
|
7
|
+
import { createCrossRootContext, type CrossRootCheck } from "../lint/post-synth";
|
|
8
|
+
import type { WorkspaceGraph } from "./compose-graph";
|
|
9
|
+
import { crossRootLinks, crossRootLint, lnk001 } from "./cross-root-lint";
|
|
10
|
+
import { crossRootInputs } from "./workspace-run";
|
|
11
|
+
|
|
12
|
+
function member(name: string, status: "composed" | "skipped" = "composed") {
|
|
13
|
+
return { name, dir: name, kind: "chant", status, reason: null, chant: null, irVersion: 1, live: false };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const declared = (consumer: string, producer: string, output: string) => ({ consumer, producer, output, kind: "output", origin: "declared", resolves: "source", status: "resolved", label: "exact", input: null, reason: null });
|
|
17
|
+
const inferred = (consumer: string, producer: string, output: string, input: string) => ({ consumer, producer, output, kind: "output", origin: "inferred:joinKey", resolves: "source", status: "resolved", label: "exact", input, reason: null });
|
|
18
|
+
|
|
19
|
+
function graph(links: unknown[]): WorkspaceGraph {
|
|
20
|
+
return {
|
|
21
|
+
version: 1,
|
|
22
|
+
workspace: { name: "acme", root: "." },
|
|
23
|
+
members: [member("network"), member("legacy-net"), member("api")],
|
|
24
|
+
nodes: [
|
|
25
|
+
{ id: "network/vpc", kind: "AWS::EC2::VPC", lexicon: "aws", member: "network", attrs: {} },
|
|
26
|
+
{ id: "api/fn", kind: "AWS::Lambda::Function", lexicon: "aws", member: "api", attrs: {} },
|
|
27
|
+
{ id: "api/svc", kind: "Deployment", lexicon: "k8s", member: "api", attrs: {} },
|
|
28
|
+
],
|
|
29
|
+
edges: [],
|
|
30
|
+
groups: { byMember: {} },
|
|
31
|
+
exports: [],
|
|
32
|
+
imports: [],
|
|
33
|
+
links,
|
|
34
|
+
collectors: [],
|
|
35
|
+
records: [],
|
|
36
|
+
} as unknown as WorkspaceGraph;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe("LNK001: a declared link and the graph's join disagree", () => {
|
|
40
|
+
test("flags a declaration that names another producer than the one the consumer's graph joins", () => {
|
|
41
|
+
const g = graph([declared("api", "legacy-net", "vpcId"), inferred("api", "network", "VpcId", "vpcId")]);
|
|
42
|
+
const ctx = createCrossRootContext(crossRootInputs(g), { links: crossRootLinks(g.links) });
|
|
43
|
+
const found = lnk001.check(ctx);
|
|
44
|
+
expect(found).toHaveLength(1);
|
|
45
|
+
expect(found[0]).toMatchObject({ checkId: "LNK001", severity: "warning", root: "api", entity: "vpcId" });
|
|
46
|
+
expect(found[0]!.message).toContain("declares a link to legacy-net's output vpcId");
|
|
47
|
+
expect(found[0]!.message).toContain("network's output VpcId");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("agrees when the declaration names the producer the graph joins, or a handle the join doesn't touch", () => {
|
|
51
|
+
for (const links of [
|
|
52
|
+
[declared("api", "network", "subnetIds"), inferred("api", "network", "VpcId", "vpcId")],
|
|
53
|
+
[declared("api", "legacy-net", "dnsZone"), inferred("api", "network", "VpcId", "vpcId")],
|
|
54
|
+
]) {
|
|
55
|
+
const g = graph(links);
|
|
56
|
+
expect(lnk001.check(createCrossRootContext(crossRootInputs(g), { links: crossRootLinks(g.links) }))).toEqual([]);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("says nothing about a consumer whose graph was not read, or with no links passed", () => {
|
|
61
|
+
const g = graph([declared("api", "legacy-net", "vpcId"), inferred("api", "network", "VpcId", "vpcId")]);
|
|
62
|
+
g.members = g.members.map((m) => (m.name === "api" ? { ...m, status: "skipped" as const } : m));
|
|
63
|
+
expect(lnk001.check(createCrossRootContext(crossRootInputs(g), { links: crossRootLinks(g.links) }))).toEqual([]);
|
|
64
|
+
expect(lnk001.check(createCrossRootContext(crossRootInputs(graph([]))))).toEqual([]);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe("crossRootLint", () => {
|
|
69
|
+
test("runs LNK001 and the cross-root checks of each lexicon the members' graphs name, and reports a lexicon it can't load", async () => {
|
|
70
|
+
const asked: string[] = [];
|
|
71
|
+
const awsCheck: CrossRootCheck = {
|
|
72
|
+
id: "AWSX01",
|
|
73
|
+
description: "sees every root",
|
|
74
|
+
scope: "cross-root",
|
|
75
|
+
check: (ctx) => [{ checkId: "AWSX01", severity: "info", message: `${ctx.roots.length} roots, ${ctx.links?.length ?? 0} links` }],
|
|
76
|
+
};
|
|
77
|
+
const result = await crossRootLint(graph([declared("api", "legacy-net", "vpcId"), inferred("api", "network", "VpcId", "vpcId")]), {
|
|
78
|
+
load: async (lexicon) => {
|
|
79
|
+
asked.push(lexicon);
|
|
80
|
+
if (lexicon === "k8s") throw new Error("Cannot find package '@intentius/chant-lexicon-k8s'");
|
|
81
|
+
return [awsCheck, { id: "PLAIN", description: "per-build, never run here", check: () => [] }];
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
expect(asked).toEqual(["aws", "k8s"]);
|
|
85
|
+
expect(result.checks).toEqual(["LNK001", "AWSX01"]);
|
|
86
|
+
expect(result.findings.map((f) => f.checkId)).toEqual(["LNK001", "AWSX01"]);
|
|
87
|
+
expect(result.findings[1]!.message).toBe("3 roots, 2 links");
|
|
88
|
+
expect(result.unloaded).toEqual([{ lexicon: "k8s", reason: "Cannot find package '@intentius/chant-lexicon-k8s'" }]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The disagreement lint (#2549, #2524 D6): `chant workspace lint --cross-root`.
|
|
3
|
+
*
|
|
4
|
+
* A member link is written down once, on the consumer. The members' graphs
|
|
5
|
+
* can surface the same relation on their own: a consumer's parameter that
|
|
6
|
+
* joins another member's output by name, or any relation a lexicon puts in
|
|
7
|
+
* its IR. The lint reports where the two disagree.
|
|
8
|
+
*
|
|
9
|
+
* It uses #1939's cross-build-root mode. Each composed member is one build
|
|
10
|
+
* root, read under the member's own toolchain as `chant workspace graph`
|
|
11
|
+
* reads it (`crossRootInputs` in `./workspace-run.ts`), and the composed
|
|
12
|
+
* graph's link table goes to every check as `ctx.links`. The checks are:
|
|
13
|
+
*
|
|
14
|
+
* - LNK001, core's own: the consumer declares a link to one member's output
|
|
15
|
+
* while its graph joins a parameter of the same name to another member's.
|
|
16
|
+
* - every cross-root check a lexicon ships through `crossRootChecks()`, for
|
|
17
|
+
* the lexicons the members' graphs name. A lexicon applies its own rule
|
|
18
|
+
* once it surfaces the relation in its IR. One that can't be loaded here
|
|
19
|
+
* is reported and skipped.
|
|
20
|
+
*
|
|
21
|
+
* Nothing runs unless `--cross-root` asks, so a plain `workspace lint`, and
|
|
22
|
+
* level 0, pay nothing for it.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { joinKey } from "../join-key";
|
|
26
|
+
import type { CrossRootCheck, CrossRootLink, PostSynthCheck, PostSynthDiagnostic } from "../lint/post-synth";
|
|
27
|
+
import { runCrossRootChecks } from "../lint/post-synth";
|
|
28
|
+
import type { WorkspaceGraph } from "./compose-graph";
|
|
29
|
+
import { crossRootInputs } from "./workspace-run";
|
|
30
|
+
|
|
31
|
+
export const LNK001_ID = "LNK001";
|
|
32
|
+
|
|
33
|
+
/** The links of the composed graph, as a cross-root check reads them. Ambiguous rows and record links are left out. */
|
|
34
|
+
export function crossRootLinks(links: WorkspaceGraph["links"]): CrossRootLink[] {
|
|
35
|
+
const out: CrossRootLink[] = [];
|
|
36
|
+
for (const row of links) {
|
|
37
|
+
const r = row as { consumer?: unknown; producer?: unknown; output?: unknown; origin?: unknown; input?: unknown; status?: unknown; kind?: unknown };
|
|
38
|
+
if (typeof r.consumer !== "string" || typeof r.producer !== "string" || typeof r.output !== "string" || typeof r.origin !== "string") continue;
|
|
39
|
+
out.push({
|
|
40
|
+
consumer: r.consumer,
|
|
41
|
+
producer: r.producer,
|
|
42
|
+
output: r.output,
|
|
43
|
+
origin: r.origin,
|
|
44
|
+
...(typeof r.input === "string" || r.input === null ? { input: r.input as string | null } : {}),
|
|
45
|
+
...(typeof r.status === "string" ? { status: r.status } : {}),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* LNK001: a declared link and a join the graph surfaces name different
|
|
53
|
+
* producers for the same handle. The consumer must be one of the run's roots,
|
|
54
|
+
* so its graph was read.
|
|
55
|
+
*/
|
|
56
|
+
export const lnk001: CrossRootCheck = {
|
|
57
|
+
id: LNK001_ID,
|
|
58
|
+
description: "A declared member link and the join the members' graphs surface name different producers for the same output",
|
|
59
|
+
scope: "cross-root",
|
|
60
|
+
check(ctx) {
|
|
61
|
+
const links = ctx.links ?? [];
|
|
62
|
+
const findings: PostSynthDiagnostic[] = [];
|
|
63
|
+
const declared = links.filter((l) => l.origin === "declared" && l.status !== "invalid");
|
|
64
|
+
for (const inferred of links) {
|
|
65
|
+
if (!inferred.origin.startsWith("inferred:") || inferred.status !== "resolved") continue;
|
|
66
|
+
if (!ctx.root(inferred.consumer)) continue;
|
|
67
|
+
const keys = new Set([joinKey(inferred.output), ...(inferred.input ? [joinKey(inferred.input)] : [])]);
|
|
68
|
+
for (const d of declared) {
|
|
69
|
+
if (d.consumer !== inferred.consumer || d.producer === inferred.producer) continue;
|
|
70
|
+
if (!keys.has(joinKey(d.output))) continue;
|
|
71
|
+
findings.push({
|
|
72
|
+
checkId: LNK001_ID,
|
|
73
|
+
severity: "warning",
|
|
74
|
+
message:
|
|
75
|
+
`${d.consumer} declares a link to ${d.producer}'s output ${d.output}, but its graph joins ` +
|
|
76
|
+
`${inferred.input ? `parameter ${inferred.input}` : "a parameter"} to ${inferred.producer}'s output ${inferred.output}. ` +
|
|
77
|
+
`Point the link at the member the graph reads from, or rename the parameter so it joins the declared output.`,
|
|
78
|
+
root: d.consumer,
|
|
79
|
+
entity: inferred.input ?? undefined,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return findings;
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/** What a cross-root lint run found. */
|
|
88
|
+
export interface CrossRootLintResult {
|
|
89
|
+
findings: PostSynthDiagnostic[];
|
|
90
|
+
/** The checks that ran, by id. */
|
|
91
|
+
checks: string[];
|
|
92
|
+
/** Lexicons whose cross-root checks could not be loaded here, and why. */
|
|
93
|
+
unloaded: { lexicon: string; reason: string }[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Loads a lexicon's cross-root checks; the plugin loader by default. */
|
|
97
|
+
export type CrossRootCheckLoader = (lexicon: string) => Promise<ReadonlyArray<CrossRootCheck | PostSynthCheck>>;
|
|
98
|
+
|
|
99
|
+
async function pluginChecks(lexicon: string): Promise<ReadonlyArray<CrossRootCheck | PostSynthCheck>> {
|
|
100
|
+
const { loadPlugin } = await import("../cli/plugins");
|
|
101
|
+
const plugin = await loadPlugin(lexicon);
|
|
102
|
+
return plugin.crossRootChecks?.() ?? [];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Run the disagreement lint over a composed graph: one root per composed
|
|
107
|
+
* member, LNK001, and the cross-root checks of every lexicon the roots name.
|
|
108
|
+
*/
|
|
109
|
+
export async function crossRootLint(graph: WorkspaceGraph, opts: { env?: string; load?: CrossRootCheckLoader } = {}): Promise<CrossRootLintResult> {
|
|
110
|
+
const roots = crossRootInputs(graph, opts.env);
|
|
111
|
+
const lexicons = [...new Set(roots.flatMap((r) => [...r.buildResult.entities.values()].map((e) => e.lexicon)))]
|
|
112
|
+
.filter((l) => typeof l === "string" && l !== "chant")
|
|
113
|
+
.sort();
|
|
114
|
+
const checks: Array<CrossRootCheck | PostSynthCheck> = [lnk001];
|
|
115
|
+
const unloaded: CrossRootLintResult["unloaded"] = [];
|
|
116
|
+
for (const lexicon of lexicons) {
|
|
117
|
+
try {
|
|
118
|
+
checks.push(...(await (opts.load ?? pluginChecks)(lexicon)));
|
|
119
|
+
} catch (err) {
|
|
120
|
+
unloaded.push({ lexicon, reason: err instanceof Error ? err.message.split("\n")[0]! : String(err) });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const findings = runCrossRootChecks(checks, roots, { ...(opts.env ? { env: opts.env } : {}), links: crossRootLinks(graph.links) });
|
|
124
|
+
const ran = checks.filter((c) => (c as CrossRootCheck).scope === "cross-root").map((c) => c.id);
|
|
125
|
+
return { findings, checks: ran, unloaded };
|
|
126
|
+
}
|
|
@@ -75,8 +75,9 @@ describe("the dbt kind in the sql lexicon's kinds file (#3932)", () => {
|
|
|
75
75
|
test("validates, probes dbt_project.yml and names the dbt-project reader", () => {
|
|
76
76
|
const { kinds, problems } = parseKindData(SQL_KINDS, "@intentius/chant-lexicon-sql");
|
|
77
77
|
expect(problems).toEqual([]);
|
|
78
|
-
expect(kinds.map((k) => [k.name, k.reader, k.probe])).toEqual([["dbt", "dbt-project", { anyFile: ["dbt_project.yml"] }]]);
|
|
79
|
-
expect(
|
|
78
|
+
expect(kinds.filter((k) => k.name === "dbt").map((k) => [k.name, k.reader, k.probe])).toEqual([["dbt", "dbt-project", { anyFile: ["dbt_project.yml"] }]]);
|
|
79
|
+
expect(kinds.map((k) => [k.name, k.reader])).toEqual([["dbt", "dbt-project"], ["goose", "goose-dir"], ["golang-migrate", "golang-migrate-dir"], ["clickhouse-migrations", "clickhouse-migrations-dir"], ["flyway", "flyway-dir"]]);
|
|
80
|
+
expect(Object.keys(kinds[0].fields ?? {})).toEqual(["sqlMember", "dialect", "modelSchema"]);
|
|
80
81
|
});
|
|
81
82
|
|
|
82
83
|
test("a reader this chant doesn't have keeps the kind without one, and says so", () => {
|