@intentius/chant 0.56.0 → 0.58.0
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/audit/catalog.d.ts +51 -1
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/core.d.ts +20 -1
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +14 -8
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/lineage.d.ts +10 -0
- package/dist/audit/lineage.d.ts.map +1 -0
- package/dist/audit/prior-art.d.ts +385 -0
- package/dist/audit/prior-art.d.ts.map +1 -0
- package/dist/audit/proof.d.ts +16 -0
- package/dist/audit/proof.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +8 -1
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts +3 -0
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/audit/secrets.d.ts +15 -0
- package/dist/audit/secrets.d.ts.map +1 -1
- package/dist/audit/terraform-state.d.ts +46 -0
- package/dist/audit/terraform-state.d.ts.map +1 -0
- package/dist/build.d.ts +17 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/claimed-fields.d.ts +161 -0
- package/dist/claimed-fields.d.ts.map +1 -0
- package/dist/cli/build-params-cli.d.ts +2 -2
- package/dist/cli/command-group.d.ts +14 -0
- package/dist/cli/command-group.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +17 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.d.ts +1 -1
- package/dist/cli/commands/check-lexicon-examples.d.ts +16 -6
- package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/codegen.d.ts +1 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/project.d.ts +7 -0
- package/dist/cli/commands/init-lexicon/templates/project.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +2 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +82 -16
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts +49 -42
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts +28 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts +16 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resources/context.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +26 -9
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/generate-post-synth-barrel.d.ts +1 -1
- package/dist/components/auto-release.d.ts +10 -20
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability.d.ts +4 -4
- package/dist/components/cli-support.d.ts +20 -21
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +3 -3
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/driver-output.d.ts.map +1 -1
- package/dist/components/driver.d.ts +66 -36
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/manifest-persistence.d.ts +1 -9
- package/dist/components/manifest-persistence.d.ts.map +1 -1
- package/dist/components/run-progress.d.ts +6 -6
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts +9 -15
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts +2 -2
- package/dist/deep-observation.d.ts +17 -0
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/discovery/files.d.ts +4 -4
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +33 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
- package/dist/discovery/sandbox/config-wire.d.ts +2 -2
- package/dist/fold/foldable-helpers.d.ts +5 -1
- package/dist/fold/foldable-helpers.d.ts.map +1 -1
- package/dist/fold-provenance.d.ts +236 -0
- package/dist/fold-provenance.d.ts.map +1 -0
- package/dist/graph-ops.d.ts +1 -1
- package/dist/held-elsewhere.d.ts +85 -0
- package/dist/held-elsewhere.d.ts.map +1 -0
- package/dist/import/ir-utils.d.ts +1 -1
- package/dist/import/ir-utils.d.ts.map +1 -1
- package/dist/import/parser.d.ts +33 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts +3 -3
- package/dist/lexicon-config.d.ts +4 -4
- package/dist/lexicon-plugin-helpers.d.ts +1 -1
- package/dist/lexicon.d.ts +104 -14
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/change-set.d.ts +13 -0
- package/dist/lifecycle/change-set.d.ts.map +1 -1
- package/dist/lifecycle/deep-diff.d.ts +133 -6
- package/dist/lifecycle/deep-diff.d.ts.map +1 -1
- package/dist/lifecycle/deep-observe.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +71 -3
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts +2 -2
- package/dist/lifecycle/run-ledger.d.ts +53 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -0
- package/dist/lifecycle/symptoms.d.ts +3 -3
- package/dist/lifecycle/symptoms.d.ts.map +1 -1
- package/dist/lint/config.d.ts +81 -2
- package/dist/lint/config.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +55 -2
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -1
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts +44 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts.map +1 -0
- package/dist/lint/rules/comp/index.d.ts +1 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +16 -0
- package/dist/lint/rules/op/index.d.ts.map +1 -0
- package/dist/lint/rules/op/ops012-activity-contract.d.ts +27 -0
- package/dist/lint/rules/op/ops012-activity-contract.d.ts.map +1 -0
- package/dist/lint/rules/op/ops013-step-output-ref.d.ts +61 -0
- package/dist/lint/rules/op/ops013-step-output-ref.d.ts.map +1 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts +55 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -0
- package/dist/lint/rules/op/support.d.ts +12 -0
- package/dist/lint/rules/op/support.d.ts.map +1 -0
- package/dist/lint/suppressions.d.ts +108 -0
- package/dist/lint/suppressions.d.ts.map +1 -0
- package/dist/live-endpoint.d.ts +1 -1
- package/dist/op/activities/activity-contracts.d.ts +54 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -0
- package/dist/op/activities/apply.d.ts +262 -0
- package/dist/op/activities/apply.d.ts.map +1 -0
- package/dist/op/activities/build.d.ts +13 -0
- package/dist/op/activities/build.d.ts.map +1 -0
- package/dist/op/activities/converge.d.ts +110 -0
- package/dist/op/activities/converge.d.ts.map +1 -0
- package/dist/op/activities/env-teardown.d.ts +76 -0
- package/dist/op/activities/env-teardown.d.ts.map +1 -0
- package/dist/op/activities/guard-validate.d.ts +64 -0
- package/dist/op/activities/guard-validate.d.ts.map +1 -0
- package/dist/op/activities/http-check.d.ts +34 -0
- package/dist/op/activities/http-check.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +31 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/activities/lexicon-upgrade.d.ts +182 -0
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -0
- package/dist/op/activities/lifecycle.d.ts +42 -0
- package/dist/op/activities/lifecycle.d.ts.map +1 -0
- package/dist/op/activities/pipeline-audit.d.ts +84 -0
- package/dist/op/activities/pipeline-audit.d.ts.map +1 -0
- package/dist/op/activities/policy.d.ts +17 -0
- package/dist/op/activities/policy.d.ts.map +1 -0
- package/dist/op/activities/reconcile.d.ts +89 -0
- package/dist/op/activities/reconcile.d.ts.map +1 -0
- package/dist/op/activities/shell.d.ts +13 -0
- package/dist/op/activities/shell.d.ts.map +1 -0
- package/dist/op/activities/teardown.d.ts +10 -0
- package/dist/op/activities/teardown.d.ts.map +1 -0
- package/dist/op/activities/util.d.ts +7 -0
- package/dist/op/activities/util.d.ts.map +1 -0
- package/dist/op/activities/wait.d.ts +28 -0
- package/dist/op/activities/wait.d.ts.map +1 -0
- package/dist/op/activities/workflow-audit.d.ts +92 -0
- package/dist/op/activities/workflow-audit.d.ts.map +1 -0
- package/dist/op/activity-contract-registry.d.ts +76 -0
- package/dist/op/activity-contract-registry.d.ts.map +1 -0
- package/dist/op/activity-contract.d.ts +25 -18
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-failure.d.ts +28 -0
- package/dist/op/activity-failure.d.ts.map +1 -0
- package/dist/op/activity-profiles.d.ts +118 -0
- package/dist/op/activity-profiles.d.ts.map +1 -0
- package/dist/op/activity-registry.d.ts +22 -38
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/activity-runtime.d.ts +3 -14
- package/dist/op/activity-runtime.d.ts.map +1 -1
- package/dist/op/builders.d.ts +84 -29
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +113 -0
- package/dist/op/composites/apply-op.d.ts.map +1 -0
- package/dist/op/composites/converge-op.d.ts +120 -0
- package/dist/op/composites/converge-op.d.ts.map +1 -0
- package/dist/op/composites/index.d.ts +26 -0
- package/dist/op/composites/index.d.ts.map +1 -0
- package/dist/op/composites/lexicon-upgrade-op.d.ts +78 -0
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -0
- package/dist/op/composites/pipeline-audit-op.d.ts +50 -0
- package/dist/op/composites/pipeline-audit-op.d.ts.map +1 -0
- package/dist/op/composites/reconcile-op.d.ts +57 -0
- package/dist/op/composites/reconcile-op.d.ts.map +1 -0
- package/dist/op/composites/watch-op.d.ts +60 -0
- package/dist/op/composites/watch-op.d.ts.map +1 -0
- package/dist/op/composites/workflow-audit-op.d.ts +57 -0
- package/dist/op/composites/workflow-audit-op.d.ts.map +1 -0
- package/dist/op/converge-rule.d.ts +12 -10
- package/dist/op/converge-rule.d.ts.map +1 -1
- package/dist/op/cron.d.ts +51 -0
- package/dist/op/cron.d.ts.map +1 -0
- package/dist/op/discover.d.ts +9 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/duration.d.ts +11 -0
- package/dist/op/duration.d.ts.map +1 -0
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/gate.d.ts +90 -0
- package/dist/op/gate.d.ts.map +1 -0
- package/dist/op/generate-pipeline.d.ts +9 -0
- package/dist/op/generate-pipeline.d.ts.map +1 -1
- package/dist/op/index.d.ts +23 -7
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +114 -28
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-output.d.ts +11 -1
- package/dist/op/local-output.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +184 -0
- package/dist/op/op-ir.d.ts.map +1 -0
- package/dist/op/op-verb-class.d.ts +10 -2
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/operator.d.ts +30 -5
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/receipt-store.d.ts +1 -1
- package/dist/op/receipt-store.d.ts.map +1 -1
- package/dist/op/resource.d.ts +15 -1
- package/dist/op/resource.d.ts.map +1 -1
- package/dist/op/runtime.d.ts +200 -0
- package/dist/op/runtime.d.ts.map +1 -0
- package/dist/op/runtimes/local.d.ts +29 -0
- package/dist/op/runtimes/local.d.ts.map +1 -0
- package/dist/op/step-output-ref.d.ts +15 -13
- package/dist/op/step-output-ref.d.ts.map +1 -1
- package/dist/op/types.d.ts +79 -27
- package/dist/op/types.d.ts.map +1 -1
- package/dist/ownership.d.ts +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/serializer-walker.d.ts.map +1 -1
- package/dist/stack-output.d.ts +5 -0
- package/dist/stack-output.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/audit/catalog.test.ts +79 -3
- package/src/audit/catalog.ts +111 -13
- package/src/audit/core.test.ts +26 -0
- package/src/audit/core.ts +61 -17
- package/src/audit/discover.test.ts +39 -0
- package/src/audit/discover.ts +91 -15
- package/src/audit/lineage.ts +100 -0
- package/src/audit/prior-art.ts +153 -0
- package/src/audit/proof.test.ts +67 -0
- package/src/audit/proof.ts +70 -0
- package/src/audit/report-html.ts +9 -4
- package/src/audit/report-model.ts +16 -2
- package/src/audit/report.test.ts +33 -0
- package/src/audit/report.ts +5 -3
- package/src/audit/rules-doc.test.ts +34 -2
- package/src/audit/rules-doc.ts +82 -9
- package/src/audit/secrets.ts +15 -3
- package/src/audit/terraform-state.test.ts +144 -0
- package/src/audit/terraform-state.ts +131 -0
- package/src/build.ts +31 -1
- package/src/claimed-fields.test.ts +145 -0
- package/src/claimed-fields.ts +208 -0
- package/src/cli/build-params-cli.ts +2 -2
- package/src/cli/command-group.ts +14 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/.terraform/providers/lock.txt +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/main.tf +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/modules/foo/main.tf +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/variables.tf +3 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +13 -4
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs-cli.ts +4 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +1 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/package-cli.ts +21 -0
- package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +1 -0
- package/src/cli/commands/audit.test.ts +189 -11
- package/src/cli/commands/audit.ts +73 -27
- package/src/cli/commands/build.test.ts +292 -9
- package/src/cli/commands/build.ts +156 -24
- package/src/cli/commands/check-lexicon-docs.ts +1 -1
- package/src/cli/commands/check-lexicon-examples.test.ts +29 -1
- package/src/cli/commands/check-lexicon-examples.ts +42 -10
- package/src/cli/commands/import.ts +6 -0
- package/src/cli/commands/init-lexicon/templates/codegen.ts +9 -0
- package/src/cli/commands/init-lexicon/templates/project.ts +44 -4
- package/src/cli/commands/init-lexicon.test.ts +97 -2
- package/src/cli/commands/init-lexicon.ts +4 -2
- package/src/cli/commands/init.test.ts +35 -1
- package/src/cli/commands/init.ts +14 -3
- package/src/cli/commands/lint.test.ts +48 -0
- package/src/cli/commands/lint.ts +123 -0
- package/src/cli/commands/onboard.test.ts +75 -0
- package/src/cli/commands/onboard.ts +54 -23
- package/src/cli/handlers/build.test.ts +81 -1
- package/src/cli/handlers/build.ts +15 -1
- package/src/cli/handlers/graph.test.ts +3 -3
- package/src/cli/handlers/lifecycle.test.ts +195 -12
- package/src/cli/handlers/lifecycle.ts +123 -6
- package/src/cli/handlers/misc.ts +1 -1
- package/src/cli/handlers/operator.test.ts +183 -11
- package/src/cli/handlers/operator.ts +260 -55
- package/src/cli/handlers/run.test.ts +431 -1287
- package/src/cli/handlers/run.ts +365 -915
- package/src/cli/main.test.ts +23 -15
- package/src/cli/main.ts +88 -33
- package/src/cli/mcp/op-tools.ts +147 -88
- package/src/cli/mcp/resource-handlers.ts +10 -37
- package/src/cli/mcp/resources/context.ts +11 -12
- package/src/cli/mcp/server.test.ts +25 -27
- package/src/cli/mcp/server.ts +2 -2
- package/src/cli/registry.ts +26 -9
- package/src/codegen/docs.ts +1 -1
- package/src/codegen/generate-post-synth-barrel.test.ts +1 -1
- package/src/codegen/generate-post-synth-barrel.ts +1 -1
- package/src/components/README.md +3 -2
- package/src/components/auto-release.test.ts +4 -20
- package/src/components/auto-release.ts +17 -42
- package/src/components/capability.ts +4 -4
- package/src/components/cli-support.test.ts +10 -5
- package/src/components/cli-support.ts +52 -44
- package/src/components/component.schema.json +2 -2
- package/src/components/component.ts +3 -3
- package/src/components/driver-output.ts +14 -2
- package/src/components/driver.test.ts +92 -22
- package/src/components/driver.ts +193 -83
- package/src/components/index.ts +1 -6
- package/src/components/manifest-persistence.test.ts +2 -20
- package/src/components/manifest-persistence.ts +4 -24
- package/src/components/pilots/pilots-lint-clean.test.ts +11 -10
- package/src/components/run-progress.ts +6 -6
- package/src/components/verbs/run-agent.ts +11 -17
- package/src/components/verbs/verify.ts +2 -2
- package/src/deep-observation.test.ts +75 -0
- package/src/deep-observation.ts +48 -0
- package/src/discovery/collect.test.ts +3 -3
- package/src/discovery/files.ts +4 -4
- package/src/discovery/fold-import.ts +105 -2
- package/src/discovery/param-deps.test.ts +112 -1
- package/src/discovery/param-deps.ts +193 -0
- package/src/discovery/sandbox/bundle.ts +15 -1
- package/src/discovery/sandbox/config-wire.test.ts +2 -2
- package/src/discovery/sandbox/config-wire.ts +2 -2
- package/src/fold/fold.test.ts +56 -0
- package/src/fold/foldable-helpers.ts +81 -1
- package/src/fold-provenance-exclusion.test.ts +186 -0
- package/src/fold-provenance.test.ts +495 -0
- package/src/fold-provenance.ts +441 -0
- package/src/graph-ops.test.ts +2 -2
- package/src/graph-ops.ts +1 -1
- package/src/held-elsewhere.test.ts +102 -0
- package/src/held-elsewhere.ts +114 -0
- package/src/import/ir-utils.ts +11 -1
- package/src/import/parser.ts +35 -0
- package/src/index.ts +3 -0
- package/src/kubectl-context.ts +3 -3
- package/src/lexicon-config.test.ts +5 -5
- package/src/lexicon-config.ts +4 -4
- package/src/lexicon-plugin-helpers.ts +1 -1
- package/src/lexicon.ts +120 -14
- package/src/lifecycle/change-set.test.ts +49 -0
- package/src/lifecycle/change-set.ts +67 -0
- package/src/lifecycle/converge-ledger.ts +1 -1
- package/src/lifecycle/deep-diff.test.ts +267 -14
- package/src/lifecycle/deep-diff.ts +217 -14
- package/src/lifecycle/deep-observe.test.ts +3 -1
- package/src/lifecycle/deep-observe.ts +16 -6
- package/src/lifecycle/gate-ledger.test.ts +74 -2
- package/src/lifecycle/gate-ledger.ts +143 -36
- package/src/lifecycle/index.ts +1 -0
- package/src/lifecycle/release-ledger.ts +2 -2
- package/src/lifecycle/run-ledger.test.ts +268 -0
- package/src/lifecycle/run-ledger.ts +201 -0
- package/src/lifecycle/symptoms.ts +3 -3
- package/src/lint/config.test.ts +82 -1
- package/src/lint/config.ts +112 -3
- package/src/lint/policy.test.ts +1 -1
- package/src/lint/post-synth.test.ts +31 -0
- package/src/lint/post-synth.ts +54 -1
- package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +2 -2
- package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +1 -1
- package/src/lint/rules/comp/comp.test.ts +1 -1
- package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +74 -0
- package/src/lint/rules/comp/index.ts +3 -3
- package/src/lint/rules/op/index.ts +23 -0
- package/src/lint/rules/op/ops012-activity-contract.test.ts +161 -0
- package/src/lint/rules/op/ops012-activity-contract.ts +64 -0
- package/src/lint/rules/op/ops013-step-output-ref.test.ts +237 -0
- package/src/lint/rules/op/ops013-step-output-ref.ts +98 -0
- package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +263 -0
- package/src/lint/rules/op/ops014-converge-rule-refusals.ts +179 -0
- package/src/lint/rules/op/support.ts +11 -0
- package/src/lint/suppressions.test.ts +163 -0
- package/src/lint/suppressions.ts +204 -0
- package/src/live-endpoint.ts +1 -1
- package/src/op/activities/activity-contracts.ts +66 -0
- package/src/op/activities/apply.test.ts +567 -0
- package/src/op/activities/apply.ts +662 -0
- package/src/op/activities/build.ts +26 -0
- package/src/op/activities/converge.test.ts +330 -0
- package/src/op/activities/converge.ts +449 -0
- package/src/op/activities/env-teardown.test.ts +187 -0
- package/src/op/activities/env-teardown.ts +171 -0
- package/src/op/activities/guard-validate.test.ts +139 -0
- package/src/op/activities/guard-validate.ts +223 -0
- package/src/op/activities/http-check.test.ts +48 -0
- package/src/op/activities/http-check.ts +55 -0
- package/src/op/activities/index.ts +119 -0
- package/src/op/activities/lexicon-upgrade.test.ts +492 -0
- package/src/op/activities/lexicon-upgrade.ts +673 -0
- package/src/op/activities/lifecycle.ts +85 -0
- package/src/op/activities/pipeline-audit.test.ts +67 -0
- package/src/op/activities/pipeline-audit.ts +201 -0
- package/src/op/activities/policy.test.ts +19 -0
- package/src/op/activities/policy.ts +37 -0
- package/src/op/activities/reconcile.test.ts +81 -0
- package/src/op/activities/reconcile.ts +187 -0
- package/src/op/activities/shell.ts +26 -0
- package/src/op/activities/teardown.ts +22 -0
- package/src/op/activities/util.ts +6 -0
- package/src/op/activities/wait.ts +69 -0
- package/src/op/activities/workflow-audit.test.ts +90 -0
- package/src/op/activities/workflow-audit.ts +203 -0
- package/src/op/activity-contract-registry.test.ts +98 -0
- package/src/op/activity-contract-registry.ts +114 -0
- package/src/op/activity-contract.test.ts +1 -1
- package/src/op/activity-contract.ts +37 -33
- package/src/op/activity-failure.ts +34 -0
- package/src/op/activity-profiles.test.ts +56 -0
- package/src/op/activity-profiles.ts +116 -0
- package/src/op/activity-registry.test.ts +37 -28
- package/src/op/activity-registry.ts +27 -56
- package/src/op/activity-runtime.ts +3 -47
- package/src/op/builders-exports.test.ts +0 -49
- package/src/op/builders-typed.test.ts +164 -0
- package/src/op/builders.ts +123 -39
- package/src/op/composites/apply-op.ts +208 -0
- package/src/op/composites/composites.test.ts +366 -0
- package/src/op/composites/converge-op.test.ts +168 -0
- package/src/op/composites/converge-op.ts +214 -0
- package/src/op/composites/index.ts +26 -0
- package/src/op/composites/lexicon-upgrade-op.test.ts +68 -0
- package/src/op/composites/lexicon-upgrade-op.ts +134 -0
- package/src/op/composites/pipeline-audit-op.test.ts +25 -0
- package/src/op/composites/pipeline-audit-op.ts +78 -0
- package/src/op/composites/reconcile-op.test.ts +51 -0
- package/src/op/composites/reconcile-op.ts +107 -0
- package/src/op/composites/watch-op.ts +108 -0
- package/src/op/composites/workflow-audit-op.test.ts +25 -0
- package/src/op/composites/workflow-audit-op.ts +88 -0
- package/src/op/converge-rule.ts +12 -10
- package/src/op/cron.test.ts +128 -0
- package/src/op/cron.ts +149 -0
- package/src/op/discover-root.test.ts +105 -1
- package/src/op/discover.test.ts +6 -2
- package/src/op/discover.ts +84 -16
- package/src/op/duration.ts +21 -0
- package/src/op/effect-step.test.ts +26 -11
- package/src/op/emulator-lifecycle.ts +1 -2
- package/src/op/gate.ts +155 -0
- package/src/op/generate-pipeline.test.ts +65 -3
- package/src/op/generate-pipeline.ts +19 -2
- package/src/op/index.ts +39 -6
- package/src/op/local-executor.test.ts +163 -34
- package/src/op/local-executor.ts +370 -102
- package/src/op/local-output.test.ts +95 -11
- package/src/op/local-output.ts +33 -4
- package/src/op/op-ir.test.ts +281 -0
- package/src/op/op-ir.ts +417 -0
- package/src/op/op-verb-class.ts +19 -5
- package/src/op/op.test.ts +26 -5
- package/src/op/operator.test.ts +175 -6
- package/src/op/operator.ts +63 -16
- package/src/op/receipt-store.ts +1 -1
- package/src/op/resource.ts +20 -2
- package/src/op/runtime.ts +203 -0
- package/src/op/runtimes/local.test.ts +181 -0
- package/src/op/runtimes/local.ts +212 -0
- package/src/op/step-output-ref.ts +15 -13
- package/src/op/types.ts +84 -24
- package/src/ownership.ts +1 -1
- package/src/provenance.test.ts +6 -0
- package/src/provenance.ts +21 -1
- package/src/serializer-walker.test.ts +42 -0
- package/src/serializer-walker.ts +21 -2
- package/src/stack-output.ts +6 -1
- package/dist/cli/handlers/op-progress.d.ts +0 -90
- package/dist/cli/handlers/op-progress.d.ts.map +0 -1
- package/dist/cli/handlers/run-client.d.ts +0 -127
- package/dist/cli/handlers/run-client.d.ts.map +0 -1
- package/dist/cli/handlers/run-report.d.ts +0 -5
- package/dist/cli/handlers/run-report.d.ts.map +0 -1
- package/dist/components/temporal-codegen-loader.d.ts +0 -27
- package/dist/components/temporal-codegen-loader.d.ts.map +0 -1
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +0 -37
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +0 -1
- package/src/cli/handlers/op-progress.test.ts +0 -268
- package/src/cli/handlers/op-progress.ts +0 -248
- package/src/cli/handlers/run-client.test.ts +0 -82
- package/src/cli/handlers/run-client.ts +0 -219
- package/src/cli/handlers/run-report.test.ts +0 -62
- package/src/cli/handlers/run-report.ts +0 -122
- package/src/components/temporal-codegen-loader.ts +0 -41
- package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +0 -66
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The typed step-builder wrappers over core's own base activities (chant #1288
|
|
3
|
+
* Stage 2, moved here from a hosting lexicon by #2114). `opts` in each is
|
|
4
|
+
* the activity's own `*Args` interface (`./activities/*.ts`) via `Omit`/
|
|
5
|
+
* `WithStepRefs`, never a hand-restated mirror, so a signature change in the
|
|
6
|
+
* activity is a compile error at the builder rather than a silently-dropped arg.
|
|
7
|
+
*
|
|
8
|
+
* These are asserted against the `ActivityStep` they emit — the fixed profiles
|
|
9
|
+
* (`policyGate`/`guardValidate` on `policyCheck`, `teardown` on `longInfra`)
|
|
10
|
+
* and defaults (`waitForStack` → `k8sWait`, `httpCheck`/`envTeardown`) are
|
|
11
|
+
* pinned here, since there is no longer a second, untyped implementation to
|
|
12
|
+
* compare against.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { describe, test, expect } from "vitest";
|
|
16
|
+
import {
|
|
17
|
+
build,
|
|
18
|
+
shell,
|
|
19
|
+
waitForStack,
|
|
20
|
+
lifecycleSnapshot,
|
|
21
|
+
teardown,
|
|
22
|
+
envTeardown,
|
|
23
|
+
httpCheck,
|
|
24
|
+
policyGate,
|
|
25
|
+
guardValidate,
|
|
26
|
+
stepOutput,
|
|
27
|
+
type StepOutputRef,
|
|
28
|
+
} from "./index";
|
|
29
|
+
|
|
30
|
+
describe("typed step builders over the base activities", () => {
|
|
31
|
+
test("build: names chantBuild, path is positional, opts spread into args", () => {
|
|
32
|
+
expect(build("examples/gitlab-aws-alb-infra")).toMatchObject({
|
|
33
|
+
kind: "activity",
|
|
34
|
+
fn: "chantBuild",
|
|
35
|
+
args: { path: "examples/gitlab-aws-alb-infra" },
|
|
36
|
+
});
|
|
37
|
+
expect(build(".", { script: "build:aws", env: { NODE_ENV: "production" } })).toMatchObject({
|
|
38
|
+
fn: "chantBuild",
|
|
39
|
+
args: { path: ".", script: "build:aws", env: { NODE_ENV: "production" } },
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("shell: names shellCmd; env and profile route where they belong", () => {
|
|
44
|
+
expect(shell("npm run db:seed")).toMatchObject({ fn: "shellCmd", args: { cmd: "npm run db:seed" } });
|
|
45
|
+
const step = shell("docker push image", { env: { FOO: "bar" }, profile: "longInfra" });
|
|
46
|
+
expect(step.args).toEqual({ cmd: "docker push image", env: { FOO: "bar" } });
|
|
47
|
+
expect(step.profile).toBe("longInfra");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("shell: cwd is reachable (the untyped builder this replaced dropped it)", () => {
|
|
51
|
+
const step = shell("ls", { cwd: "/tmp" });
|
|
52
|
+
expect(step.args?.cwd).toBe("/tmp");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("waitForStack: defaults to the k8sWait profile", () => {
|
|
56
|
+
const step = waitForStack("alb-api", { namespace: "alb" });
|
|
57
|
+
expect(step).toMatchObject({ fn: "waitForStack", args: { name: "alb-api", namespace: "alb" } });
|
|
58
|
+
expect(step.profile).toBe("k8sWait");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("lifecycleSnapshot: env is the only arg", () => {
|
|
62
|
+
expect(lifecycleSnapshot("staging")).toMatchObject({
|
|
63
|
+
fn: "lifecycleSnapshot",
|
|
64
|
+
args: { env: "staging" },
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("lifecycleSnapshot: .out is reachable via an id", () => {
|
|
69
|
+
const step = lifecycleSnapshot("staging", { id: "snap" });
|
|
70
|
+
const ref: StepOutputRef = step.out.env;
|
|
71
|
+
expect(ref.step).toBe("snap");
|
|
72
|
+
expect(ref.path).toBe("env");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("teardown: fixed longInfra profile", () => {
|
|
76
|
+
const step = teardown("examples/getting-started");
|
|
77
|
+
expect(step).toMatchObject({ fn: "chantTeardown", args: { path: "examples/getting-started" } });
|
|
78
|
+
expect(step.profile).toBe("longInfra");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("envTeardown: defaults to longInfra, confirmProd passes through", () => {
|
|
82
|
+
const step = envTeardown("prod", { confirmProd: true });
|
|
83
|
+
expect(step.args).toEqual({ env: "prod", confirmProd: true });
|
|
84
|
+
expect(step.profile).toBe("longInfra");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("httpCheck: defaults to fastIdempotent", () => {
|
|
88
|
+
const step = httpCheck("https://example.com/health", { status: 200, contains: "ok" });
|
|
89
|
+
expect(step.args).toEqual({ url: "https://example.com/health", status: 200, contains: "ok" });
|
|
90
|
+
expect(step.profile).toBe("fastIdempotent");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("policyGate: fixed policyCheck profile, path defaults to '.'", () => {
|
|
94
|
+
expect(policyGate()).toMatchObject({ fn: "policyGate", args: { path: "." }, profile: "policyCheck" });
|
|
95
|
+
expect(policyGate({ env: "staging" }).args).toEqual({ path: ".", env: "staging" });
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("waitForStack: accepts a StepOutputRef in a typed slot", () => {
|
|
99
|
+
const ref = stepOutput("build-step", "namespace");
|
|
100
|
+
const step = waitForStack("alb-api", { namespace: ref });
|
|
101
|
+
expect(step.args?.namespace).toBe(ref);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("guardValidate: builds an activity step naming the guardValidate activity", () => {
|
|
105
|
+
const step = guardValidate("rules.guard");
|
|
106
|
+
expect(step.kind).toBe("activity");
|
|
107
|
+
expect(step.fn).toBe("guardValidate");
|
|
108
|
+
expect(step.args).toEqual({ rules: "rules.guard" });
|
|
109
|
+
expect(step.profile).toBe("policyCheck");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("guardValidate: template/binary/onFinding pass through as args; id routes to the step, not args", () => {
|
|
113
|
+
const step = guardValidate("rules.guard", { template: "dist/out.json", binary: "/opt/bin/cfn-guard", onFinding: "report", id: "guard" });
|
|
114
|
+
expect(step.args).toEqual({
|
|
115
|
+
rules: "rules.guard",
|
|
116
|
+
template: "dist/out.json",
|
|
117
|
+
binary: "/opt/bin/cfn-guard",
|
|
118
|
+
onFinding: "report",
|
|
119
|
+
});
|
|
120
|
+
expect(step.id).toBe("guard");
|
|
121
|
+
expect(step.profile).toBe("policyCheck");
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("guardValidate: .out is reachable once the step is given an id", () => {
|
|
125
|
+
const step = guardValidate("rules.guard", { id: "guard" });
|
|
126
|
+
const ref: StepOutputRef = step.out.findings;
|
|
127
|
+
expect(ref.step).toBe("guard");
|
|
128
|
+
expect(ref.path).toBe("findings");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("guardValidate: accepts a StepOutputRef in a typed slot", () => {
|
|
132
|
+
const ref = stepOutput("build-step", "outPath");
|
|
133
|
+
const step = guardValidate("rules.guard", { template: ref });
|
|
134
|
+
expect(step.args?.template).toBe(ref);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// ── Compile-time-only: authoring-time type errors (never executed) ──────────
|
|
139
|
+
function _typeChecksOnly(): void {
|
|
140
|
+
// @ts-expect-error — "environment" is not a key of ChantBuildArgs (the
|
|
141
|
+
// exact typo class chant #1288 names: `env` is the field, not
|
|
142
|
+
// `environment` — e.g. activity("lifecycleDiff", { environment: "prod" })
|
|
143
|
+
// silently ignored the whole arg before this).
|
|
144
|
+
build(".", { environment: "prod" });
|
|
145
|
+
|
|
146
|
+
// @ts-expect-error — waitForStack's intervalMs must be a number.
|
|
147
|
+
waitForStack("alb-api", { intervalMs: "5000" });
|
|
148
|
+
|
|
149
|
+
// @ts-expect-error — httpCheck's status must be a number.
|
|
150
|
+
httpCheck("https://example.com", { status: "200" });
|
|
151
|
+
|
|
152
|
+
// @ts-expect-error — policyGate has no `profile` override (fixed to
|
|
153
|
+
// policyCheck, single-attempt).
|
|
154
|
+
policyGate({ profile: "fastIdempotent" });
|
|
155
|
+
|
|
156
|
+
// @ts-expect-error — guardValidate has no `profile` override either
|
|
157
|
+
// (fixed to policyCheck, same reasoning as policyGate).
|
|
158
|
+
guardValidate("rules.guard", { profile: "fastIdempotent" });
|
|
159
|
+
|
|
160
|
+
// @ts-expect-error — onFinding only admits "report" today (#522 leaves
|
|
161
|
+
// issue/pull-request modes to a follow-up).
|
|
162
|
+
guardValidate("rules.guard", { onFinding: "issue" });
|
|
163
|
+
}
|
|
164
|
+
void _typeChecksOnly;
|
package/src/op/builders.ts
CHANGED
|
@@ -2,7 +2,17 @@ import { OpResource } from "./resource";
|
|
|
2
2
|
import type { OpConfig, PhaseDefinition, StepDefinition, ActivityStep, GateStep, EffectStep } from "./types";
|
|
3
3
|
import { isEffectReceipt, type EffectReceiptDeclaration } from "../effect-receipt";
|
|
4
4
|
import { receiptCheckInput } from "./receipt-store";
|
|
5
|
-
import { makeOutProxy, type StepOutputRef } from "./step-output-ref";
|
|
5
|
+
import { makeOutProxy, type StepOutputRef, type WithStepRefs } from "./step-output-ref";
|
|
6
|
+
import type { ChantBuildArgs } from "./activities/build";
|
|
7
|
+
import type { ShellCmdArgs } from "./activities/shell";
|
|
8
|
+
import type { WaitForStackArgs } from "./activities/wait";
|
|
9
|
+
import type { LifecycleSnapshotArgs } from "./activities/lifecycle";
|
|
10
|
+
import type { ChantTeardownArgs } from "./activities/teardown";
|
|
11
|
+
import type { EnvTeardownArgs } from "./activities/env-teardown";
|
|
12
|
+
import type { HttpCheckArgs } from "./activities/http-check";
|
|
13
|
+
import type { PolicyGateArgs } from "./activities/policy";
|
|
14
|
+
import type { GuardValidateArgs } from "./activities/guard-validate";
|
|
15
|
+
import { isValidCronExpression, cronSyntaxMessage } from "./cron";
|
|
6
16
|
|
|
7
17
|
/** An `activity()` result — the plain `ActivityStep` shape plus the `.out` reference sugar (#1290). */
|
|
8
18
|
export interface NamedActivityStep extends ActivityStep {
|
|
@@ -18,7 +28,7 @@ export interface NamedActivityStep extends ActivityStep {
|
|
|
18
28
|
// ── Core builders ─────────────────────────────────────────────────────────────
|
|
19
29
|
|
|
20
30
|
/**
|
|
21
|
-
* Declare a named, phased
|
|
31
|
+
* Declare a named, phased Op.
|
|
22
32
|
*
|
|
23
33
|
* @example
|
|
24
34
|
* ```ts
|
|
@@ -31,8 +41,15 @@ export interface NamedActivityStep extends ActivityStep {
|
|
|
31
41
|
* ],
|
|
32
42
|
* });
|
|
33
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* A `schedule` may be supplied for an Op that runs on a cadence (#2120); its
|
|
46
|
+
* cron is validated here, at construction, so a typo fails on `chant build`
|
|
47
|
+
* rather than becoming a schedule that silently never fires.
|
|
34
48
|
*/
|
|
35
49
|
export function Op(config: OpConfig): InstanceType<typeof OpResource> {
|
|
50
|
+
if (config.schedule && !isValidCronExpression(config.schedule.cron)) {
|
|
51
|
+
throw new Error(`Op "${config.name}": ${cronSyntaxMessage(config.schedule.cron)}`);
|
|
52
|
+
}
|
|
36
53
|
return new OpResource(config as unknown as Record<string, unknown>);
|
|
37
54
|
}
|
|
38
55
|
|
|
@@ -85,7 +102,12 @@ export function activity(
|
|
|
85
102
|
return step;
|
|
86
103
|
}
|
|
87
104
|
|
|
88
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Insert a human gate. A gate is a fact on the gate ledger, not a wait: a run
|
|
107
|
+
* that reaches this step with no resolution newer than its pending fact
|
|
108
|
+
* records the pending fact and ends `gated`. `chant approve <op> <signalName>`
|
|
109
|
+
* writes the resolution, and the next run walks through carrying the approver.
|
|
110
|
+
*/
|
|
89
111
|
export function gate(
|
|
90
112
|
signalName: string,
|
|
91
113
|
opts?: { timeout?: string; description?: string },
|
|
@@ -113,9 +135,10 @@ export function gate(
|
|
|
113
135
|
* would sever the step from the declaration that lint, plan, and the lexicon
|
|
114
136
|
* row all key on.
|
|
115
137
|
*
|
|
116
|
-
* A gate authored inside `steps`
|
|
117
|
-
* matched path never reaches it). The receipt-store activities
|
|
118
|
-
* `receiptWrite`) are provided by the receipt row's lexicon
|
|
138
|
+
* A gate authored inside `steps` is reached only when the effect will fire
|
|
139
|
+
* (the matched path never reaches it). The receipt-store activities
|
|
140
|
+
* (`receiptRead`, `receiptWrite`) are provided by the receipt row's lexicon
|
|
141
|
+
* (#1835, aws).
|
|
119
142
|
*
|
|
120
143
|
* @example
|
|
121
144
|
* ```ts
|
|
@@ -190,10 +213,25 @@ export function takeProfileAndId(
|
|
|
190
213
|
return { args, profile, id };
|
|
191
214
|
}
|
|
192
215
|
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Extra opts every typed base-activity wrapper below accepts alongside its
|
|
218
|
+
* activity's own fields: the step's `profile` override and its `id` (which
|
|
219
|
+
* routes to the step, never into args, so `.out` works — chant #1290).
|
|
220
|
+
*/
|
|
221
|
+
type StepOpts = { profile?: ActivityStep["profile"]; id?: string };
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Run an npm build script in the given project directory. `opts` is
|
|
225
|
+
* {@link ChantBuildArgs} itself, minus the positional `path` — `script`
|
|
226
|
+
* selects the npm script (default `build`, e.g. `build:aws`), `env` adds
|
|
227
|
+
* env vars.
|
|
228
|
+
*/
|
|
229
|
+
export const build = (
|
|
230
|
+
path: string,
|
|
231
|
+
opts?: WithStepRefs<Omit<ChantBuildArgs, "path">> & StepOpts,
|
|
232
|
+
): NamedActivityStep => {
|
|
233
|
+
const { args, profile, id } = takeProfileAndId(opts as Record<string, unknown> | undefined);
|
|
234
|
+
return activity("chantBuild", { path, ...args }, { ...(profile ? { profile } : {}), ...(id ? { id } : {}) });
|
|
197
235
|
};
|
|
198
236
|
|
|
199
237
|
/** Run `kubectl apply -f <manifest>`. Defaults to the `longInfra` profile (override via `opts.profile`). */
|
|
@@ -228,10 +266,17 @@ export const helmInstallPinned = (
|
|
|
228
266
|
return activity("helmInstall", { name, contentDigest, ...args }, profile ?? "longInfra");
|
|
229
267
|
};
|
|
230
268
|
|
|
231
|
-
/**
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Poll until a Kubernetes Deployment/StatefulSet is fully rolled out. `opts` is
|
|
271
|
+
* {@link WaitForStackArgs} itself, minus the positional `name`. Defaults to the
|
|
272
|
+
* `k8sWait` profile (override via `opts.profile`).
|
|
273
|
+
*/
|
|
274
|
+
export const waitForStack = (
|
|
275
|
+
name: string,
|
|
276
|
+
opts?: WithStepRefs<Omit<WaitForStackArgs, "name">> & StepOpts,
|
|
277
|
+
): NamedActivityStep => {
|
|
278
|
+
const { args, profile, id } = takeProfileAndId(opts as Record<string, unknown> | undefined);
|
|
279
|
+
return activity("waitForStack", { name, ...args }, { profile: profile ?? "k8sWait", ...(id ? { id } : {}) });
|
|
235
280
|
};
|
|
236
281
|
|
|
237
282
|
/** Poll any operator-backed Kubernetes resource until it reports ready, driven by a data-only readiness spec (CRD-aware; #365). Defaults to the `k8sWait` profile (override via `opts.profile`). */
|
|
@@ -246,20 +291,26 @@ export const gitlabPipeline = (name: string, opts?: Record<string, unknown>): Ac
|
|
|
246
291
|
return activity("gitlabPipeline", { name, ...args }, profile ?? "longInfra");
|
|
247
292
|
};
|
|
248
293
|
|
|
249
|
-
/**
|
|
250
|
-
|
|
251
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Take a chant lifecycle snapshot for the given environment.
|
|
296
|
+
* {@link LifecycleSnapshotArgs} has only `env`, which is positional here, so
|
|
297
|
+
* `opts` carries nothing but the step's `id` (for `.out`).
|
|
298
|
+
*/
|
|
299
|
+
export const lifecycleSnapshot = (env: string, opts?: { id?: string }): NamedActivityStep =>
|
|
300
|
+
activity("lifecycleSnapshot", { env } satisfies LifecycleSnapshotArgs, opts?.id ? { id: opts.id } : undefined);
|
|
252
301
|
|
|
253
302
|
/**
|
|
254
303
|
* Run an arbitrary shell command. Tag long-running commands with a `profile`
|
|
255
304
|
* (e.g. `longInfra` for a multi-GB image push) so they get the right
|
|
256
|
-
* start-to-close timeout
|
|
305
|
+
* start-to-close timeout on whichever runtime hosts the run.
|
|
257
306
|
*/
|
|
258
307
|
export const shell = (
|
|
259
308
|
cmd: string,
|
|
260
|
-
opts?:
|
|
261
|
-
):
|
|
262
|
-
|
|
309
|
+
opts?: WithStepRefs<Omit<ShellCmdArgs, "cmd">> & StepOpts,
|
|
310
|
+
): NamedActivityStep => {
|
|
311
|
+
const { args, profile, id } = takeProfileAndId(opts as Record<string, unknown> | undefined);
|
|
312
|
+
return activity("shellCmd", { cmd, ...args }, { ...(profile ? { profile } : {}), ...(id ? { id } : {}) });
|
|
313
|
+
};
|
|
263
314
|
|
|
264
315
|
/**
|
|
265
316
|
* Ensure a `generated-once` secret exists in the target store (#1829, epic
|
|
@@ -283,9 +334,17 @@ export const ensureSecret = (
|
|
|
283
334
|
return activity("ensureSecret", { name, keys, ...args }, profile);
|
|
284
335
|
};
|
|
285
336
|
|
|
286
|
-
/**
|
|
287
|
-
|
|
288
|
-
|
|
337
|
+
/**
|
|
338
|
+
* Run `chant teardown` in the given project directory. Fixed `longInfra`
|
|
339
|
+
* profile (not overridable). {@link ChantTeardownArgs} has only `path`
|
|
340
|
+
* (positional), so `opts` is just the step's `id` (for `.out`).
|
|
341
|
+
*/
|
|
342
|
+
export const teardown = (path: string, opts?: { id?: string }): NamedActivityStep =>
|
|
343
|
+
activity(
|
|
344
|
+
"chantTeardown",
|
|
345
|
+
{ path } satisfies ChantTeardownArgs,
|
|
346
|
+
{ profile: "longInfra", ...(opts?.id ? { id: opts.id } : {}) },
|
|
347
|
+
);
|
|
289
348
|
|
|
290
349
|
/**
|
|
291
350
|
* Tear down one environment's marker-owned resources — the durable form of
|
|
@@ -309,13 +368,16 @@ export const teardown = (path: string): ActivityStep =>
|
|
|
309
368
|
* ]),
|
|
310
369
|
* ```
|
|
311
370
|
*
|
|
312
|
-
* `opts` also accepts `path` (the chant project directory, default the
|
|
313
|
-
*
|
|
371
|
+
* `opts` also accepts `path` (the chant project directory, default the chant
|
|
372
|
+
* process's cwd). Defaults to the `longInfra` profile (override via
|
|
314
373
|
* `opts.profile`).
|
|
315
374
|
*/
|
|
316
|
-
export const envTeardown = (
|
|
317
|
-
|
|
318
|
-
|
|
375
|
+
export const envTeardown = (
|
|
376
|
+
env: string,
|
|
377
|
+
opts?: WithStepRefs<Omit<EnvTeardownArgs, "env">> & StepOpts,
|
|
378
|
+
): NamedActivityStep => {
|
|
379
|
+
const { args, profile, id } = takeProfileAndId(opts as Record<string, unknown> | undefined);
|
|
380
|
+
return activity("envTeardown", { env, ...args }, { profile: profile ?? "longInfra", ...(id ? { id } : {}) });
|
|
319
381
|
};
|
|
320
382
|
|
|
321
383
|
/**
|
|
@@ -455,9 +517,12 @@ export const flociGcpDown = (opts?: Record<string, unknown>): ActivityStep => {
|
|
|
455
517
|
* Defaults to the `fastIdempotent` profile. `opts` accepts `method`, `status`
|
|
456
518
|
* (default any 2xx), `contains` (body substring), `retries`, `intervalMs`.
|
|
457
519
|
*/
|
|
458
|
-
export const httpCheck = (
|
|
459
|
-
|
|
460
|
-
|
|
520
|
+
export const httpCheck = (
|
|
521
|
+
url: string,
|
|
522
|
+
opts?: WithStepRefs<Omit<HttpCheckArgs, "url">> & StepOpts,
|
|
523
|
+
): NamedActivityStep => {
|
|
524
|
+
const { args, profile, id } = takeProfileAndId(opts as Record<string, unknown> | undefined);
|
|
525
|
+
return activity("httpCheck", { url, ...args }, { profile: profile ?? "fastIdempotent", ...(id ? { id } : {}) });
|
|
461
526
|
};
|
|
462
527
|
|
|
463
528
|
/**
|
|
@@ -546,7 +611,7 @@ export const gcpDelete = (manifestPath: string, opts?: Record<string, unknown>):
|
|
|
546
611
|
// The builder and the executor-side activity function share a name (e.g.
|
|
547
612
|
// `spriteCreate`), and that is intentional: the builder here returns an
|
|
548
613
|
// `activity("spriteCreate", ...)` step; `loadActivities` loads the function of
|
|
549
|
-
// the same name from the
|
|
614
|
+
// the same name from the fly lexicon to run the HTTP. They live in
|
|
550
615
|
// different modules and are both exported — exactly how `flapsUp`/`flapsDown`
|
|
551
616
|
// already work. Op files import these builders; the executor resolves the
|
|
552
617
|
// function by name. Endpoint override + bearer are read by the activity from
|
|
@@ -806,14 +871,33 @@ export const spritesDown = (args: {
|
|
|
806
871
|
|
|
807
872
|
/**
|
|
808
873
|
* Gate an apply on organizational policy: build the project and run its
|
|
809
|
-
* `lint.policies` over the resolved resources,
|
|
810
|
-
* violation. Place it before the apply phase. `env` (or `ownership.env`) lets a
|
|
874
|
+
* `lint.policies` over the resolved resources, failing the step on any
|
|
875
|
+
* violation so no later phase runs. Place it before the apply phase. `env` (or `ownership.env`) lets a
|
|
811
876
|
* policy branch on environment. Single-attempt (`policyCheck` profile) — a
|
|
812
877
|
* deterministic violation is not retried.
|
|
813
878
|
*/
|
|
814
|
-
export const policyGate = (opts?:
|
|
815
|
-
|
|
879
|
+
export const policyGate = (opts?: WithStepRefs<PolicyGateArgs> & { id?: string }): NamedActivityStep => {
|
|
880
|
+
const path = (opts?.path as PolicyGateArgs["path"] | undefined) ?? ".";
|
|
881
|
+
const env = opts?.env;
|
|
882
|
+
return activity(
|
|
816
883
|
"policyGate",
|
|
817
|
-
{ path
|
|
818
|
-
"policyCheck",
|
|
884
|
+
{ path, ...(env !== undefined ? { env } : {}) },
|
|
885
|
+
{ profile: "policyCheck", ...(opts?.id ? { id: opts.id } : {}) },
|
|
819
886
|
);
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Run an external CloudFormation Guard rules pack against the project's built
|
|
891
|
+
* CloudFormation template (chant #522). `opts` is {@link GuardValidateArgs}
|
|
892
|
+
* itself, minus the positional `rules`; `template` defaults (inside the
|
|
893
|
+
* activity) to `<path>/template.json`. Fixed `policyCheck` profile — same
|
|
894
|
+
* reasoning as {@link policyGate}: a deterministic policy check is
|
|
895
|
+
* single-attempt — and not overridable.
|
|
896
|
+
*/
|
|
897
|
+
export const guardValidate = (
|
|
898
|
+
rules: string,
|
|
899
|
+
opts?: WithStepRefs<Omit<GuardValidateArgs, "rules">> & { id?: string },
|
|
900
|
+
): NamedActivityStep => {
|
|
901
|
+
const { id, ...rest } = (opts ?? {}) as Omit<GuardValidateArgs, "rules"> & { id?: string };
|
|
902
|
+
return activity("guardValidate", { rules, ...rest }, { profile: "policyCheck", ...(id ? { id } : {}) });
|
|
903
|
+
};
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ApplyOp composite — the code → cloud workflow as an Op.
|
|
3
|
+
*
|
|
4
|
+
* Compute the plan, then apply via the target's native mechanism. Authority
|
|
5
|
+
* stays with the platform (the CloudFormation stack, the Kubernetes API
|
|
6
|
+
* server, the ARM resource group) — chant never hosts a state file.
|
|
7
|
+
*
|
|
8
|
+
* Phases: build → plan → [approve] → apply. Deletes ride the native
|
|
9
|
+
* prune path, whose bound is per target: the ownership marker on `kubectl`,
|
|
10
|
+
* the ownership tag on `arm` (chant #1448 — previously `--mode Complete`, which
|
|
11
|
+
* removed resources chant never applied), the ownership label on `gcp`
|
|
12
|
+
* (chant #1449), the metadata marker (machines) and managed app
|
|
13
|
+
* (volumes/ips/certs/secrets) on `fly` (chant #1449), and the stack itself on
|
|
14
|
+
* `cloudformation`, which a resource CFN did not create is not in. All of
|
|
15
|
+
* them are owned-only. See {@link DeleteMode}.
|
|
16
|
+
*
|
|
17
|
+
* A gate is a fact, not a wait (#2119): the local executor reads the gate
|
|
18
|
+
* ledger, and a run that finds no resolution ends `gated` with the `chant
|
|
19
|
+
* approve <op> <gate>` line to run. Approve, run again, and the same Op
|
|
20
|
+
* converges — no durable workflow engine is involved.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // additive, local executor
|
|
25
|
+
* export const { op } = ApplyOp({ name: "prod-apply", env: "prod", target: "kubectl" });
|
|
26
|
+
*
|
|
27
|
+
* // gated destructive apply — `chant approve prod-apply approve-apply`, then re-run
|
|
28
|
+
* export const { op } = ApplyOp({
|
|
29
|
+
* name: "prod-apply",
|
|
30
|
+
* env: "prod",
|
|
31
|
+
* target: "kubectl",
|
|
32
|
+
* delete: "gated",
|
|
33
|
+
* gate: { signalName: "approve-apply", description: "Approve prod apply with deletes" },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @see #112 — stateless-authoritative state model + live import
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { Op, phase, activity, gate } from "../builders";
|
|
41
|
+
import type { OpResource } from "../resource";
|
|
42
|
+
import { defaultOutput, hasNativeRollback, type ApplyTarget, type DeleteMode } from "../activities/apply";
|
|
43
|
+
|
|
44
|
+
export interface ApplyOpConfig {
|
|
45
|
+
/** Op name (kebab-case). */
|
|
46
|
+
name: string;
|
|
47
|
+
/** Environment — CFN stack name / ARM resource group / kube context env;
|
|
48
|
+
* a log label on `gcp` and `fly`. */
|
|
49
|
+
env: string;
|
|
50
|
+
/** Native apply mechanism. Default: "kubectl". */
|
|
51
|
+
target?: ApplyTarget;
|
|
52
|
+
/** Built manifest/template path. Default per target: `dist` (dir) for kubectl,
|
|
53
|
+
* `template.json` (file) for CloudFormation/ARM, `dist/gcp.yaml` for gcp,
|
|
54
|
+
* `dist/fly.json` for fly. Must match your build output. */
|
|
55
|
+
output?: string;
|
|
56
|
+
/** Project directory to build. Default: ".". */
|
|
57
|
+
path?: string;
|
|
58
|
+
/** Delete handling. Default: "never". */
|
|
59
|
+
delete?: DeleteMode;
|
|
60
|
+
/**
|
|
61
|
+
* Effect handling (#1834, epic #1703 decision 6). `"gated"` routes the run
|
|
62
|
+
* through the approval gate whenever the plan proposes an effect, so the Plan
|
|
63
|
+
* phase's effect-will-fire rows (#1832) are reviewed before any effect
|
|
64
|
+
* runs. A run that reaches the gate unapproved ends `gated` and is answered
|
|
65
|
+
* by `chant approve`, the same shape `delete: "gated"` has. The generic
|
|
66
|
+
* apply itself never writes a receipt regardless (#1832); only an
|
|
67
|
+
* `effect()` step does, on success, last.
|
|
68
|
+
*/
|
|
69
|
+
effects?: "gated";
|
|
70
|
+
/**
|
|
71
|
+
* Approval gate before the apply. Implied when `delete: "gated"`; may also be
|
|
72
|
+
* set explicitly. Omit `signalName` to default to `approve-<name>`. The gate
|
|
73
|
+
* is resolved by `chant approve` on the ledger (#2119), which the next run
|
|
74
|
+
* reads; nothing waits in the meantime.
|
|
75
|
+
*/
|
|
76
|
+
gate?: { signalName?: string; timeout?: string; description?: string };
|
|
77
|
+
/**
|
|
78
|
+
* Saga-style rollback on partial apply failure, run as an `onFailure` phase.
|
|
79
|
+
*
|
|
80
|
+
* Compensation is total or refused (#1449): it only builds when the target
|
|
81
|
+
* has a rollback to run — a mapped native one (`cloudformation`, the aws
|
|
82
|
+
* lexicon's `rollbackStack`) or an explicit `{ command }`. Asking for it
|
|
83
|
+
* (`true`, or an object without a `command`) on any other target fails at
|
|
84
|
+
* build time rather than warning at rollback time.
|
|
85
|
+
*
|
|
86
|
+
* Defaults on for a destructive apply (`delete !== "never"`) when the target
|
|
87
|
+
* has a native rollback; a destructive apply on a target without one gets no
|
|
88
|
+
* compensation phase unless a `{ command }` supplies the rollback. Pass
|
|
89
|
+
* `false` to disable.
|
|
90
|
+
*/
|
|
91
|
+
compensate?: boolean | { command?: string };
|
|
92
|
+
/**
|
|
93
|
+
* kubectl target only (chant #1075). Let the server-side apply take
|
|
94
|
+
* ownership of fields another field manager already owns, instead of failing
|
|
95
|
+
* with a conflict naming them.
|
|
96
|
+
*
|
|
97
|
+
* Off unless set, and chant never turns it on by itself — a conflict means
|
|
98
|
+
* something else in the cluster believes it owns that field, and deciding
|
|
99
|
+
* otherwise is a deliberate act. Set it when chant is meant to be the
|
|
100
|
+
* authority for those fields (adopting objects a previous `kubectl apply`
|
|
101
|
+
* created is the usual case).
|
|
102
|
+
*/
|
|
103
|
+
forceConflicts?: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ApplyOpResources {
|
|
107
|
+
/** Op resource — the build→plan→[approve]→apply Op. */
|
|
108
|
+
op: InstanceType<typeof OpResource>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function ApplyOp(config: ApplyOpConfig): ApplyOpResources {
|
|
112
|
+
const target = config.target ?? "kubectl";
|
|
113
|
+
const output = config.output ?? defaultOutput(target);
|
|
114
|
+
const deleteMode = config.delete ?? "never";
|
|
115
|
+
const gated = deleteMode === "gated" || config.effects === "gated" || config.gate !== undefined;
|
|
116
|
+
|
|
117
|
+
const phases = [
|
|
118
|
+
phase("Build", [activity("chantBuild", { path: config.path ?? "." })]),
|
|
119
|
+
phase("Plan", [
|
|
120
|
+
{
|
|
121
|
+
kind: "activity" as const,
|
|
122
|
+
fn: "lifecycleDiff",
|
|
123
|
+
args: { env: config.env, live: true },
|
|
124
|
+
outcomeAttribute: { name: "Drift", from: "drifted" },
|
|
125
|
+
},
|
|
126
|
+
]),
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
if (gated) {
|
|
130
|
+
phases.push(
|
|
131
|
+
phase("Approve", [
|
|
132
|
+
gate(config.gate?.signalName ?? `approve-${config.name}`, {
|
|
133
|
+
...(config.gate?.timeout ? { timeout: config.gate.timeout } : {}),
|
|
134
|
+
description:
|
|
135
|
+
config.gate?.description ??
|
|
136
|
+
`Approve apply to ${config.env} (delete mode: ${deleteMode}` +
|
|
137
|
+
`${config.effects === "gated" ? ", effects: gated" : ""})`,
|
|
138
|
+
}),
|
|
139
|
+
]),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
phases.push(
|
|
144
|
+
phase("Apply", [
|
|
145
|
+
activity(
|
|
146
|
+
"nativeApply",
|
|
147
|
+
{
|
|
148
|
+
target,
|
|
149
|
+
env: config.env,
|
|
150
|
+
output,
|
|
151
|
+
deleteMode,
|
|
152
|
+
// Only present when the author asked for it, so an Op that does not
|
|
153
|
+
// mention conflicts serializes exactly as it always has.
|
|
154
|
+
...(config.forceConflicts !== undefined ? { forceConflicts: config.forceConflicts } : {}),
|
|
155
|
+
},
|
|
156
|
+
"longInfra",
|
|
157
|
+
),
|
|
158
|
+
]),
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
// Compensation is total or refused (#1449). A rollback path is either the
|
|
162
|
+
// target's mapped native rollback (cloudformation's rollbackStack) or an
|
|
163
|
+
// explicit command; without one there is nothing a Rollback phase could run,
|
|
164
|
+
// so asking for one is refused here — at build time, with the op named —
|
|
165
|
+
// rather than surfacing as a warn when the rollback is already needed.
|
|
166
|
+
const compensateCommand =
|
|
167
|
+
typeof config.compensate === "object" ? config.compensate.command : undefined;
|
|
168
|
+
const rollbackAvailable = hasNativeRollback(target) || compensateCommand !== undefined;
|
|
169
|
+
if (config.compensate !== undefined && config.compensate !== false && !rollbackAvailable) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`ApplyOp "${config.name}": compensate is enabled, but target "${target}" has no automatic ` +
|
|
172
|
+
`rollback — the only mapped one today is cloudformation's rollbackStack. Either supply ` +
|
|
173
|
+
`compensate: { command: "..." } with a rollback of your own, or set compensate: false.`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Compensation defaults on for destructive applies — a partial failure should
|
|
178
|
+
// unwind rather than leave the cloud half-applied — but only where a rollback
|
|
179
|
+
// path exists; a destructive apply on a rollback-less target gets no
|
|
180
|
+
// compensation phase rather than one that could only warn.
|
|
181
|
+
const compensateDefault = deleteMode !== "never" && rollbackAvailable;
|
|
182
|
+
const compensateEnabled = config.compensate === undefined ? compensateDefault : config.compensate !== false;
|
|
183
|
+
|
|
184
|
+
const op = Op({
|
|
185
|
+
name: config.name,
|
|
186
|
+
overview: `Apply declared source to the ${config.env} environment (code → cloud)`,
|
|
187
|
+
labels: {
|
|
188
|
+
Apply: "true",
|
|
189
|
+
Env: config.env,
|
|
190
|
+
},
|
|
191
|
+
phases,
|
|
192
|
+
...(compensateEnabled
|
|
193
|
+
? {
|
|
194
|
+
onFailure: [
|
|
195
|
+
phase("Rollback", [
|
|
196
|
+
activity("compensateApply", {
|
|
197
|
+
target,
|
|
198
|
+
env: config.env,
|
|
199
|
+
...(compensateCommand ? { command: compensateCommand } : {}),
|
|
200
|
+
}),
|
|
201
|
+
]),
|
|
202
|
+
],
|
|
203
|
+
}
|
|
204
|
+
: {}),
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return { op };
|
|
208
|
+
}
|