@intentius/chant 0.57.0 → 0.59.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 +36 -1
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +26 -9
- 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/carve-bridge.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/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 +13 -0
- 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 +12 -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/plugins.d.ts +22 -0
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +40 -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 +24 -22
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +21 -6
- 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 +73 -37
- 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 +10 -22
- 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/detectLexicon.d.ts +13 -0
- package/dist/detectLexicon.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/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 +273 -16
- 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 +79 -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 +149 -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 +85 -30
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/change-signal.d.ts +91 -0
- package/dist/op/change-signal.d.ts.map +1 -0
- package/dist/op/composites/apply-op.d.ts +118 -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-name.d.ts +40 -0
- package/dist/op/gate-name.d.ts.map +1 -0
- package/dist/op/gate-summary.d.ts +43 -0
- package/dist/op/gate-summary.d.ts.map +1 -0
- 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 +29 -9
- 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 +185 -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 +93 -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 +96 -29
- 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/terraform/bridge.d.ts +26 -7
- package/dist/terraform/bridge.d.ts.map +1 -1
- package/dist/terraform/carve-provider.d.ts +28 -2
- package/dist/terraform/carve-provider.d.ts.map +1 -1
- package/dist/terraform/data-source-shape.d.ts +77 -0
- package/dist/terraform/data-source-shape.d.ts.map +1 -0
- package/dist/terraform/graph.d.ts.map +1 -1
- package/dist/terraform/providers/kubernetes.d.ts +5 -0
- package/dist/terraform/providers/kubernetes.d.ts.map +1 -1
- package/dist/terraform/tier-map.d.ts +16 -4
- package/dist/terraform/tier-map.d.ts.map +1 -1
- package/dist/terraform/types.d.ts +8 -0
- package/dist/terraform/types.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 +84 -18
- package/src/audit/discover.test.ts +39 -0
- package/src/audit/discover.ts +202 -18
- 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 +191 -11
- package/src/cli/commands/audit.ts +78 -28
- package/src/cli/commands/build.test.ts +330 -9
- package/src/cli/commands/build.ts +170 -24
- package/src/cli/commands/carve-bridge.test.ts +237 -14
- package/src/cli/commands/carve-bridge.ts +21 -17
- package/src/cli/commands/carve-emit-k8s.test.ts +17 -10
- 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/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 +194 -1
- package/src/cli/commands/lint.ts +205 -7
- 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 +341 -55
- package/src/cli/handlers/run.test.ts +568 -1295
- package/src/cli/handlers/run.ts +446 -912
- package/src/cli/main.test.ts +22 -16
- package/src/cli/main.ts +66 -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/plugins.test.ts +68 -2
- package/src/cli/plugins.ts +39 -0
- package/src/cli/registry.ts +40 -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 +4 -3
- package/src/components/__fixtures__/neo4j-fanout.json +1 -1
- 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 +28 -12
- package/src/components/cli-support.ts +60 -47
- package/src/components/component-schema.test.ts +18 -2
- package/src/components/component.schema.json +18 -5
- package/src/components/component.test.ts +2 -2
- package/src/components/component.ts +27 -7
- package/src/components/config-defaults.test.ts +2 -2
- package/src/components/driver-output.ts +14 -2
- package/src/components/driver.test.ts +109 -20
- package/src/components/driver.ts +201 -84
- 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/neo4j-fanout.pilot.ts +3 -3
- 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.test.ts +19 -0
- package/src/components/verbs/run-agent.ts +12 -24
- 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/detectLexicon.ts +18 -1
- package/src/discovery/collect.test.ts +3 -3
- package/src/discovery/files.ts +4 -4
- package/src/discovery/fold-import.test.ts +1 -1
- 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 +82 -2
- 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 +3 -3
- package/src/graph-ops.ts +1 -1
- package/src/held-elsewhere.test.ts +102 -0
- package/src/held-elsewhere.ts +114 -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 +296 -16
- 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 +154 -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/pipeline-change-gate.test.ts +2 -2
- 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 +27 -1
- package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +76 -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 +161 -0
- package/src/op/activities/reconcile.ts +354 -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 +125 -41
- package/src/op/change-signal.test.ts +117 -0
- package/src/op/change-signal.ts +169 -0
- package/src/op/composites/apply-op.ts +218 -0
- package/src/op/composites/composites.test.ts +379 -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 +110 -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 +29 -14
- package/src/op/emulator-lifecycle.ts +1 -2
- package/src/op/gate-name.test.ts +65 -0
- package/src/op/gate-name.ts +60 -0
- package/src/op/gate-summary.ts +84 -0
- 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 +48 -8
- package/src/op/local-executor.test.ts +178 -34
- package/src/op/local-executor.ts +371 -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 +292 -0
- package/src/op/op-ir.ts +419 -0
- package/src/op/op-verb-class.test.ts +2 -2
- package/src/op/op-verb-class.ts +19 -5
- package/src/op/op.test.ts +28 -7
- package/src/op/operator.test.ts +543 -6
- package/src/op/operator.ts +203 -20
- 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 +106 -26
- 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/terraform/aws-resources.test.ts +13 -4
- package/src/terraform/bridge.test.ts +22 -9
- package/src/terraform/bridge.ts +89 -28
- package/src/terraform/carve-provider.ts +38 -2
- package/src/terraform/data-source-shape.ts +95 -0
- package/src/terraform/graph.ts +35 -7
- package/src/terraform/providers/kubernetes.ts +48 -2
- package/src/terraform/tier-map.ts +21 -6
- package/src/terraform/types.ts +8 -0
- 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,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity timeout and retry profiles.
|
|
3
|
+
*
|
|
4
|
+
* A profile is a named retry/timeout shape an Op step opts into
|
|
5
|
+
* (`activity("chantBuild", …, "fastIdempotent")`), so tuning lives in one table
|
|
6
|
+
* instead of inline at every call site. The six names cover the shapes infra
|
|
7
|
+
* steps actually take: fast idempotent work, long infra, K8s wait loops, a
|
|
8
|
+
* human gate, an Argo sync wait, and a deterministic policy check.
|
|
9
|
+
*
|
|
10
|
+
* These lived in a hosting lexicon, under its own prefixed name, until chant
|
|
11
|
+
* #2114 moved the base activities into core. Nothing about a timeout or a
|
|
12
|
+
* backoff coefficient belonged to that runtime, so the table came with them and
|
|
13
|
+
* lost the prefix. `heartbeatTimeout` did not come along: it configured a
|
|
14
|
+
* liveness protocol between a worker and a server, and no in-process step
|
|
15
|
+
* heartbeats to anything.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export interface ActivityProfile {
|
|
19
|
+
/** Maximum time allowed for a single activity execution attempt (e.g. `"20m"`). */
|
|
20
|
+
timeout: string;
|
|
21
|
+
/** Retry policy for failed activity attempts. */
|
|
22
|
+
retry?: {
|
|
23
|
+
/** Initial wait before the first retry (e.g. "5s"). */
|
|
24
|
+
initialInterval?: string;
|
|
25
|
+
/** Multiplier applied to the interval on each retry (e.g. 2). */
|
|
26
|
+
backoffCoefficient?: number;
|
|
27
|
+
/** Maximum number of attempts including the first (0 = unlimited). */
|
|
28
|
+
maximumAttempts?: number;
|
|
29
|
+
/** Cap on retry intervals (e.g. "5m"). */
|
|
30
|
+
maximumInterval?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Error names (`Error.name`) that fail immediately without retry — the
|
|
33
|
+
* executor short-circuits its retry loop on a match.
|
|
34
|
+
*/
|
|
35
|
+
nonRetryableErrorTypes?: string[];
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Named activity profiles for common infrastructure step patterns. */
|
|
40
|
+
export const ACTIVITY_PROFILES = {
|
|
41
|
+
/**
|
|
42
|
+
* Fast, idempotent operations: `chant build`, `kubectl apply` without `--wait`,
|
|
43
|
+
* fetching nameservers, reading cluster status.
|
|
44
|
+
*/
|
|
45
|
+
fastIdempotent: {
|
|
46
|
+
timeout: "5m",
|
|
47
|
+
retry: { maximumAttempts: 3, initialInterval: "5s", backoffCoefficient: 2 },
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Long-running infra: GKE cluster creation via Config Connector (~10-20 min),
|
|
52
|
+
* `kubectl apply --wait` for large resource sets, Helm installs.
|
|
53
|
+
*/
|
|
54
|
+
longInfra: {
|
|
55
|
+
timeout: "20m",
|
|
56
|
+
retry: { maximumAttempts: 3, initialInterval: "30s", backoffCoefficient: 2 },
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* K8s wait loops: polling for StatefulSet rollout, ExternalDNS A-records,
|
|
61
|
+
* DNS propagation.
|
|
62
|
+
*/
|
|
63
|
+
k8sWait: {
|
|
64
|
+
timeout: "15m",
|
|
65
|
+
// A terminal-state resource (waitForReady's ReadinessFailedError) will never
|
|
66
|
+
// become ready — fail fast instead of exhausting retries.
|
|
67
|
+
retry: {
|
|
68
|
+
maximumAttempts: 3,
|
|
69
|
+
initialInterval: "10s",
|
|
70
|
+
backoffCoefficient: 2,
|
|
71
|
+
nonRetryableErrorTypes: ["ReadinessFailedError"],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Human-gate steps: waiting for an operator action (DNS delegation, approval).
|
|
77
|
+
* Very long timeout, single attempt — no retry on human-gate timeouts.
|
|
78
|
+
*/
|
|
79
|
+
humanGate: {
|
|
80
|
+
timeout: "48h",
|
|
81
|
+
retry: { maximumAttempts: 1 },
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Argo CD sync waits: poll an Application until `health=Healthy && sync=Synced`
|
|
86
|
+
* (`waitForArgoSync`). Long timeout for slow first syncs, cheap idempotent
|
|
87
|
+
* retries — re-polling is free. A terminal-unhealthy Application fails fast
|
|
88
|
+
* via `ArgoSyncFailedError` (non-retryable).
|
|
89
|
+
*/
|
|
90
|
+
argoSync: {
|
|
91
|
+
timeout: "30m",
|
|
92
|
+
retry: {
|
|
93
|
+
maximumAttempts: 5,
|
|
94
|
+
initialInterval: "10s",
|
|
95
|
+
backoffCoefficient: 2,
|
|
96
|
+
maximumInterval: "1m",
|
|
97
|
+
nonRetryableErrorTypes: ["ArgoSyncFailedError"],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Organizational policy gate (`policyGate`): build the project and evaluate
|
|
103
|
+
* `lint.policies`. Deterministic — a violation is the same on every attempt —
|
|
104
|
+
* so a single attempt, short timeout, no retry.
|
|
105
|
+
*/
|
|
106
|
+
policyCheck: {
|
|
107
|
+
timeout: "5m",
|
|
108
|
+
retry: { maximumAttempts: 1 },
|
|
109
|
+
},
|
|
110
|
+
} as const satisfies Record<string, ActivityProfile>;
|
|
111
|
+
|
|
112
|
+
/** The name of a built-in activity profile — the union `ActivityStep.profile` admits. */
|
|
113
|
+
export type ActivityProfileName = keyof typeof ACTIVITY_PROFILES;
|
|
114
|
+
|
|
115
|
+
/** Every profile name, as a runtime list (`KNOWN_ACTIVITY_PROFILES`'s source). */
|
|
116
|
+
export const ACTIVITY_PROFILE_NAMES = Object.keys(ACTIVITY_PROFILES) as ActivityProfileName[];
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { describe, test, expect
|
|
2
|
-
import { loadActivities, resolveActivity, type ActivityFn } from "./activity-registry";
|
|
1
|
+
import { describe, test, expect } from "vitest";
|
|
2
|
+
import { loadActivities, loadProfiles, resolveActivity, type ActivityFn } from "./activity-registry";
|
|
3
|
+
import { ACTIVITY_PROFILES } from "./activity-profiles";
|
|
3
4
|
|
|
4
5
|
describe("loadActivities", () => {
|
|
5
|
-
|
|
6
|
-
vi.resetModules();
|
|
7
|
-
vi.doUnmock("@intentius/chant-lexicon-temporal/op/activities");
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test("loads the lexicon activity library keyed by export name", async () => {
|
|
6
|
+
test("loads core's own activity library keyed by export name", async () => {
|
|
11
7
|
const activities = await loadActivities();
|
|
12
|
-
// Real export names from
|
|
8
|
+
// Real export names from packages/core/src/op/activities.
|
|
13
9
|
expect(activities.has("shellCmd")).toBe(true);
|
|
14
10
|
expect(activities.has("chantBuild")).toBe(true);
|
|
15
11
|
expect(activities.has("waitForStack")).toBe(true);
|
|
@@ -17,15 +13,27 @@ describe("loadActivities", () => {
|
|
|
17
13
|
expect(typeof activities.get("shellCmd")).toBe("function");
|
|
18
14
|
});
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
);
|
|
16
|
+
/**
|
|
17
|
+
* chant #2114 — the base library used to live in a hosting lexicon,
|
|
18
|
+
* dynamically imported, and `loadActivities` threw "no activities
|
|
19
|
+
* registered" without it. The activities are core's own now and the
|
|
20
|
+
* import is static, so an empty lexicon list resolves the whole base surface in
|
|
21
|
+
* a project that has installed nothing but chant.
|
|
22
|
+
*/
|
|
23
|
+
test("every base activity resolves with no lexicons configured", async () => {
|
|
24
|
+
const a = await loadActivities([]);
|
|
25
|
+
for (const fn of [
|
|
26
|
+
"shellCmd", "chantBuild", "waitForStack", "lifecycleSnapshot", "lifecycleDiff",
|
|
27
|
+
"httpCheck", "chantTeardown", "envTeardown", "convergeTick", "reconcilePr",
|
|
28
|
+
"guardValidate", "policyGate", "workflowSupplyChainAudit", "pipelineSupplyChainAudit",
|
|
29
|
+
"lexiconUpgrade", "nativeApply",
|
|
30
|
+
]) {
|
|
31
|
+
expect(typeof a.get(fn), `${fn} should resolve from the base library`).toBe("function");
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("loadProfiles returns core's table", async () => {
|
|
36
|
+
expect(await loadProfiles()).toBe(ACTIVITY_PROFILES);
|
|
29
37
|
});
|
|
30
38
|
});
|
|
31
39
|
|
|
@@ -47,25 +55,26 @@ describe("resolveActivity", () => {
|
|
|
47
55
|
});
|
|
48
56
|
});
|
|
49
57
|
|
|
50
|
-
describe("loadActivities —
|
|
51
|
-
test("the activity library loads
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
// import would throw
|
|
58
|
+
describe("loadActivities — no runtime SDK on the path", () => {
|
|
59
|
+
test("the activity library loads with no orchestrator SDK installed", async () => {
|
|
60
|
+
// The base activities used to reach an orchestrator SDK for heartbeats and
|
|
61
|
+
// its non-retryable failure type. Neither is a core dependency, and this
|
|
62
|
+
// import would throw if one crept back in.
|
|
55
63
|
const activities = await loadActivities();
|
|
56
64
|
expect(activities.has("waitForStack")).toBe(true);
|
|
57
65
|
expect(activities.has("chantBuild")).toBe(true);
|
|
66
|
+
expect(activities.has("policyGate")).toBe(true);
|
|
58
67
|
});
|
|
59
68
|
});
|
|
60
69
|
|
|
61
|
-
// Cloud appliers were relocated out of
|
|
70
|
+
// Cloud appliers were relocated out of a single lexicon into their own
|
|
62
71
|
// lexicons (#706); the loader pulls them in per the project's configured
|
|
63
72
|
// `lexicons`. Proves the relocation resolves end-to-end.
|
|
64
73
|
describe("loadActivities — multi-lexicon (#706)", () => {
|
|
65
|
-
test("base (no lexicons):
|
|
74
|
+
test("base (no lexicons): core activities present, product activities absent", async () => {
|
|
66
75
|
const a = await loadActivities();
|
|
67
|
-
expect(a.has("waitForStack")).toBe(true); //
|
|
68
|
-
expect(a.has("shellCmd")).toBe(true); //
|
|
76
|
+
expect(a.has("waitForStack")).toBe(true); // core base
|
|
77
|
+
expect(a.has("shellCmd")).toBe(true); // core base
|
|
69
78
|
expect(a.has("kubectlApply")).toBe(false); // relocated to k8s (#809)
|
|
70
79
|
expect(a.has("k3dUp")).toBe(false); // relocated to k8s (#809), then k3d (#1410)
|
|
71
80
|
expect(a.has("gcpApply")).toBe(false); // relocated to gcp
|
|
@@ -117,6 +126,6 @@ describe("loadActivities — multi-lexicon (#706)", () => {
|
|
|
117
126
|
|
|
118
127
|
test("unknown lexicon is skipped without throwing", async () => {
|
|
119
128
|
const a = await loadActivities(["definitely-not-a-lexicon"]);
|
|
120
|
-
expect(a.has("waitForStack")).toBe(true); //
|
|
129
|
+
expect(a.has("waitForStack")).toBe(true); // core base still loads
|
|
121
130
|
});
|
|
122
131
|
});
|
|
@@ -2,17 +2,24 @@
|
|
|
2
2
|
* Activity registry — resolves an Op step's `fn` name to a callable activity
|
|
3
3
|
* implementation for local execution.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The base activities are core's own (`./activities`): plain async functions
|
|
6
|
+
* taking a single args object, with no workflow engine anywhere in the call
|
|
7
|
+
* path. They are imported statically, so `loadActivities([])` works in a
|
|
8
|
+
* project that has installed nothing but chant. Product-specific appliers stay
|
|
9
|
+
* in their owning lexicon (#809) and are pulled in dynamically per the
|
|
10
|
+
* project's configured lexicon list.
|
|
8
11
|
*/
|
|
9
12
|
|
|
13
|
+
import * as baseActivities from "./activities";
|
|
14
|
+
import { ACTIVITY_PROFILES, type ActivityProfile } from "./activity-profiles";
|
|
15
|
+
|
|
16
|
+
export type { ActivityProfile } from "./activity-profiles";
|
|
17
|
+
|
|
10
18
|
/**
|
|
11
19
|
* An activity is an async function taking a single args object and an optional
|
|
12
20
|
* `AbortSignal`. Local execution passes a signal that fires on timeout or
|
|
13
|
-
* Ctrl-C so the activity can kill in-flight child processes;
|
|
14
|
-
*
|
|
15
|
-
* `Context`), so the signal is always optional.
|
|
21
|
+
* Ctrl-C so the activity can kill in-flight child processes; a hosted runtime
|
|
22
|
+
* may invoke activities with args only, so the signal is always optional.
|
|
16
23
|
*/
|
|
17
24
|
export type ActivityFn = (args: Record<string, unknown>, signal?: AbortSignal) => Promise<unknown>;
|
|
18
25
|
|
|
@@ -26,33 +33,24 @@ function collectActivities(mod: Record<string, unknown>, into: Map<string, Activ
|
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
/**
|
|
29
|
-
* Build the activity map for local execution
|
|
30
|
-
*
|
|
36
|
+
* Build the activity map for local execution: core's base activities plus every
|
|
37
|
+
* activity module the project's configured lexicons contribute, keyed by export
|
|
38
|
+
* name (`shellCmd`, `kubectlApply`, `gcpApply`, …).
|
|
31
39
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* that ships no `op/activities` module is skipped.
|
|
40
|
+
* Cloud-specific appliers live in their own lexicon (aws → `flociUp`/`flociDown`,
|
|
41
|
+
* gcp → `gcpApply`, azure → `azGroupEnsure`/`azGroupDelete`), so `lexicons` —
|
|
42
|
+
* the project's configured lexicon list — is consulted to pull those in. A
|
|
43
|
+
* lexicon that ships no `op/activities` module is skipped.
|
|
37
44
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
45
|
+
* Never throws: the base library is a static import, so there is no "no
|
|
46
|
+
* activities registered" state to report.
|
|
40
47
|
*/
|
|
41
48
|
export async function loadActivities(lexicons: string[] = []): Promise<Map<string, ActivityFn>> {
|
|
42
49
|
const activities = new Map<string, ActivityFn>();
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
// Variable specifier so tsc does not statically resolve the optional dep.
|
|
46
|
-
const spec = "@intentius/chant-lexicon-temporal/op/activities";
|
|
47
|
-
collectActivities((await import(spec)) as Record<string, unknown>, activities);
|
|
48
|
-
} catch {
|
|
49
|
-
throw new Error(
|
|
50
|
-
"no activities registered — install `@intentius/chant-lexicon-temporal`",
|
|
51
|
-
);
|
|
52
|
-
}
|
|
51
|
+
collectActivities(baseActivities as unknown as Record<string, unknown>, activities);
|
|
53
52
|
|
|
54
53
|
for (const name of lexicons) {
|
|
55
|
-
if (name === "temporal") continue;
|
|
56
54
|
try {
|
|
57
55
|
const spec = `@intentius/chant-lexicon-${name}/op/activities`;
|
|
58
56
|
collectActivities((await import(spec)) as Record<string, unknown>, activities);
|
|
@@ -64,40 +62,13 @@ export async function loadActivities(lexicons: string[] = []): Promise<Map<strin
|
|
|
64
62
|
return activities;
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
/** Structural shape of a TEMPORAL_ACTIVITY_PROFILES entry (timeout + retry). */
|
|
68
|
-
export interface ActivityProfile {
|
|
69
|
-
startToCloseTimeout?: string;
|
|
70
|
-
heartbeatTimeout?: string;
|
|
71
|
-
retry?: {
|
|
72
|
-
initialInterval?: string;
|
|
73
|
-
backoffCoefficient?: number;
|
|
74
|
-
maximumAttempts?: number;
|
|
75
|
-
maximumInterval?: string;
|
|
76
|
-
/** Error names (`Error.name`) that should fail immediately without retry. */
|
|
77
|
-
nonRetryableErrorTypes?: string[];
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
65
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* Imports the lexicon's `/config` entry, not its root index. `/config` is a
|
|
87
|
-
* side-effect-free data module; the root index pulls in the plugin, serializer,
|
|
88
|
-
* composites, and re-exported Op machinery, any of which could throw on load
|
|
89
|
-
* and make this silently return `{}` — which would drop every profiled step to
|
|
90
|
-
* the 5-minute default while the Temporal path (reading the same table) kept the
|
|
91
|
-
* declared timeout. Importing the narrow module keeps the two executors agreed.
|
|
66
|
+
* The built-in profile table. Kept async because it is awaited on the CLI's
|
|
67
|
+
* run path alongside {@link loadActivities}, and because a hosted runtime may
|
|
68
|
+
* one day resolve profiles from somewhere less immediate.
|
|
92
69
|
*/
|
|
93
70
|
export async function loadProfiles(): Promise<Record<string, ActivityProfile>> {
|
|
94
|
-
|
|
95
|
-
const spec = "@intentius/chant-lexicon-temporal/config";
|
|
96
|
-
const mod = (await import(spec)) as { TEMPORAL_ACTIVITY_PROFILES?: Record<string, ActivityProfile> };
|
|
97
|
-
return mod.TEMPORAL_ACTIVITY_PROFILES ?? {};
|
|
98
|
-
} catch {
|
|
99
|
-
return {};
|
|
100
|
-
}
|
|
71
|
+
return ACTIVITY_PROFILES as unknown as Record<string, ActivityProfile>;
|
|
101
72
|
}
|
|
102
73
|
|
|
103
74
|
/**
|
|
@@ -1,54 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Activity runtime helpers shared by every Op activity implementation, wherever
|
|
3
|
-
* it lives — the base activities in
|
|
4
|
-
* appliers
|
|
5
|
-
*
|
|
6
|
-
* heartbeat or sleep.
|
|
3
|
+
* it lives — the base activities in `./activities` and the product-specific
|
|
4
|
+
* appliers in the aws/gcp/azure/k8s/fly lexicons. Hosting them in core keeps a
|
|
5
|
+
* lexicon from depending on another lexicon just to sleep between polls.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
|
-
interface ActivityContext {
|
|
10
|
-
current(): { heartbeat(details?: unknown): void };
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// undefined = not yet attempted; null = unavailable; object = resolved Context.
|
|
14
|
-
let cachedContext: ActivityContext | null | undefined;
|
|
15
|
-
let loading: Promise<void> | undefined;
|
|
16
|
-
|
|
17
|
-
function ensureContext(): void {
|
|
18
|
-
if (cachedContext !== undefined || loading) return;
|
|
19
|
-
// Variable specifier so bundlers/tsc do not statically require the optional dep.
|
|
20
|
-
const spec = "@temporalio/activity";
|
|
21
|
-
loading = import(spec)
|
|
22
|
-
.then((mod: unknown) => {
|
|
23
|
-
cachedContext = (mod as { Context?: ActivityContext }).Context ?? null;
|
|
24
|
-
})
|
|
25
|
-
.catch(() => {
|
|
26
|
-
cachedContext = null;
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Emit an activity heartbeat if running under a Temporal worker; otherwise no-op.
|
|
32
|
-
*
|
|
33
|
-
* The first call kicks off a one-time lazy load of `@temporalio/activity` and
|
|
34
|
-
* returns immediately; once resolved, subsequent calls heartbeat. Heartbeats
|
|
35
|
-
* are periodic (every ~15s, well inside the 60s heartbeat timeout), so the
|
|
36
|
-
* single missed first tick is harmless. Under chant's local executor (no
|
|
37
|
-
* Temporal SDK present) it no-ops, and the module imports cleanly without the SDK.
|
|
38
|
-
*/
|
|
39
|
-
export function safeHeartbeat(details?: unknown): void {
|
|
40
|
-
if (cachedContext === undefined) {
|
|
41
|
-
ensureContext();
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (cachedContext === null) return;
|
|
45
|
-
try {
|
|
46
|
-
cachedContext.current().heartbeat(details);
|
|
47
|
-
} catch {
|
|
48
|
-
// Not inside an activity execution context — nothing to do.
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
8
|
/**
|
|
53
9
|
* Sleep for `ms`, rejecting early if `signal` aborts. Polling activities use
|
|
54
10
|
* this between attempts so a local-executor timeout or Ctrl-C interrupts the
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
2
|
import * as opIndex from "./index";
|
|
5
3
|
import * as builders from "./builders";
|
|
6
4
|
|
|
@@ -26,51 +24,4 @@ describe("op builders are all reachable (#1715)", () => {
|
|
|
26
24
|
`export list at the top of op/index.ts, or a project cannot use them:\n ${missing.join("\n ")}`,
|
|
27
25
|
).toEqual([]);
|
|
28
26
|
});
|
|
29
|
-
|
|
30
|
-
test("the temporal lexicon re-exports the same set", () => {
|
|
31
|
-
// The lexicon is what a project actually imports from
|
|
32
|
-
// (`@intentius/chant-lexicon-temporal`), and it re-states the list a third
|
|
33
|
-
// time rather than re-exporting wholesale — so it can drift independently.
|
|
34
|
-
const src = readFileSync(
|
|
35
|
-
join(import.meta.dirname, "../../../../lexicons/temporal/src/index.ts"),
|
|
36
|
-
"utf-8",
|
|
37
|
-
);
|
|
38
|
-
const block = src.match(/export \{([^}]*)\} from "@intentius\/chant\/op";/)?.[1] ?? "";
|
|
39
|
-
const reExported = new Set(
|
|
40
|
-
block.split(",").map((s) => s.trim()).filter(Boolean),
|
|
41
|
-
);
|
|
42
|
-
// The sprites family reaches projects through the fly lexicon, not this
|
|
43
|
-
// one. Named rather than prefix-matched, because `listCheckpoints` is one
|
|
44
|
-
// of them and does not look like one — which this test caught on its
|
|
45
|
-
// first run.
|
|
46
|
-
const FLY_SURFACE = new Set([
|
|
47
|
-
"spriteCreate", "spriteExec", "spriteCheckpoint", "spriteRestore",
|
|
48
|
-
"listCheckpoints", "spriteDestroy", "spriteWriteFile", "spriteReadFile",
|
|
49
|
-
"spriteListDir", "spriteRemove", "spriteApplyNetworkPolicy",
|
|
50
|
-
"spriteApplyServices", "spriteTaskCreate", "spriteTaskRefresh",
|
|
51
|
-
"spriteTaskRelease", "spritesUp", "spritesDown",
|
|
52
|
-
]);
|
|
53
|
-
// chant #1288 Stage 2 — these are the temporal lexicon's OWN activities
|
|
54
|
-
// (build.ts, shell.ts, wait.ts, ...), so its barrel re-exports a fully
|
|
55
|
-
// typed twin from its own `./op/builders` instead of core's untyped
|
|
56
|
-
// original — same name, same import path, deliberately not sourced from
|
|
57
|
-
// `@intentius/chant/op` any more. See `lexicons/temporal/src/index.ts`
|
|
58
|
-
// and `lexicons/temporal/src/op/builders.ts`.
|
|
59
|
-
const TEMPORAL_TYPED_SURFACE = new Set([
|
|
60
|
-
"build", "shell", "waitForStack", "lifecycleSnapshot", "teardown", "envTeardown", "httpCheck", "policyGate",
|
|
61
|
-
]);
|
|
62
|
-
// chant #1288 Stage 2 — an internal helper (`takeProfile`'s sibling) for
|
|
63
|
-
// the lexicon-owned typed step-builder wrappers to reuse, not an
|
|
64
|
-
// Op-authoring primitive itself; nothing authors an Op with it directly,
|
|
65
|
-
// so it has no place in the Op-authoring barrel.
|
|
66
|
-
const INTERNAL_HELPERS = new Set(["takeProfileAndId"]);
|
|
67
|
-
const expected = Object.keys(builders).filter(
|
|
68
|
-
(n) => !FLY_SURFACE.has(n) && !TEMPORAL_TYPED_SURFACE.has(n) && !INTERNAL_HELPERS.has(n),
|
|
69
|
-
);
|
|
70
|
-
const missing = expected.filter((name) => !reExported.has(name));
|
|
71
|
-
expect(
|
|
72
|
-
missing,
|
|
73
|
-
`lexicons/temporal/src/index.ts does not re-export these builders:\n ${missing.join("\n ")}`,
|
|
74
|
-
).toEqual([]);
|
|
75
|
-
});
|
|
76
27
|
});
|
|
@@ -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;
|