@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
package/src/cli/mcp/server.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { searchTool, createSearchHandler } from "./tools/search";
|
|
|
9
9
|
import type { LexiconPlugin } from "../../lexicon";
|
|
10
10
|
import type { McpRequest, McpResponse, McpRequestMeta, ToolDefinition, ToolHandler, ResourceDefinition } from "./types";
|
|
11
11
|
import { createSnapshotTool, createDiffTool } from "./lifecycle-tools";
|
|
12
|
-
import { createOpListTool, createOpRunTool, createOpStatusTool,
|
|
12
|
+
import { createOpListTool, createOpRunTool, createOpStatusTool, createOpApproveTool, createOpReportTool } from "./op-tools";
|
|
13
13
|
import { buildResourcesList, handleResourcesRead } from "./resource-handlers";
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -103,7 +103,7 @@ export class McpServer {
|
|
|
103
103
|
this.registerTool(diff.definition, diff.handler);
|
|
104
104
|
|
|
105
105
|
// Register Op tools
|
|
106
|
-
for (const factory of [createOpListTool, createOpRunTool, createOpStatusTool,
|
|
106
|
+
for (const factory of [createOpListTool, createOpRunTool, createOpStatusTool, createOpApproveTool, createOpReportTool]) {
|
|
107
107
|
const t = factory();
|
|
108
108
|
this.registerTool(t.definition, t.handler);
|
|
109
109
|
}
|
package/src/cli/registry.ts
CHANGED
|
@@ -18,12 +18,26 @@ export interface ParsedArgs {
|
|
|
18
18
|
watch: boolean;
|
|
19
19
|
verbose: boolean;
|
|
20
20
|
help: boolean;
|
|
21
|
-
profile?: string;
|
|
22
21
|
report?: boolean;
|
|
23
22
|
/** `chant run` — force the local in-process executor (the default). */
|
|
24
23
|
local?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
|
|
24
|
+
/**
|
|
25
|
+
* `chant run <op> --on <lexicon>` (#2121) — which runtime hosts the run.
|
|
26
|
+
* The named lexicon's `opRuntime` (`../lexicon.ts`) takes it; omitted, core's
|
|
27
|
+
* built-in `local` provider does. Applies to every `run` subcommand, so
|
|
28
|
+
* `run status`/`log`/`list`/`cancel`/`approve` all address the same runtime
|
|
29
|
+
* the run started on.
|
|
30
|
+
*/
|
|
31
|
+
on?: string;
|
|
32
|
+
/**
|
|
33
|
+
* `-p, --profile <name>` (#2124, restored in #2192) — which named connection
|
|
34
|
+
* profile the hosting runtime targets, handed to it as
|
|
35
|
+
* {@link OpRunStartOptions.profile}. Only a runtime that declares profiles
|
|
36
|
+
* reads it: fountain resolves it through `fountain.profiles` in
|
|
37
|
+
* `chant.config.ts` and refuses a name it does not find. Omitted, each
|
|
38
|
+
* runtime keeps its own default (fountain's `defaultProfile`).
|
|
39
|
+
*/
|
|
40
|
+
profile?: string;
|
|
27
41
|
/** `chant run` — emit the structured OpRunResult as JSON on stdout. */
|
|
28
42
|
json?: boolean;
|
|
29
43
|
/**
|
|
@@ -32,10 +46,9 @@ export interface ParsedArgs {
|
|
|
32
46
|
* per line to stdout while the run executes, so a consumer can render live
|
|
33
47
|
* wave/component/phase/step progress instead of tailing raw logs.
|
|
34
48
|
*
|
|
35
|
-
* `chant run <name> --
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* ../handlers/op-progress.ts) per settled step instead.
|
|
49
|
+
* `chant run <name> --progress-json` streams one NDJSON `StepRecord`
|
|
50
|
+
* (../../op/local-executor.ts) per settled step instead, fed by whatever
|
|
51
|
+
* the resolved runtime reports through its `progress` hook (#2121).
|
|
39
52
|
*
|
|
40
53
|
* Both are purely additive: run semantics, ordering, and exit code are
|
|
41
54
|
* unchanged; omitted (undefined, not false) when the flag isn't passed.
|
|
@@ -173,7 +186,7 @@ export interface ParsedArgs {
|
|
|
173
186
|
* registered in `~/.claude.json`, not just the path argument.
|
|
174
187
|
*/
|
|
175
188
|
allProjects?: boolean;
|
|
176
|
-
/** `chant audit --fail-on merge-worthy|warning|none` */
|
|
189
|
+
/** `chant audit --fail-on merge-worthy|warning|error|none` */
|
|
177
190
|
failOn?: string;
|
|
178
191
|
/** `chant audit --theme <file>` — JSON theme knobs for the HTML report */
|
|
179
192
|
theme?: string;
|
|
@@ -251,8 +264,10 @@ export interface ParsedArgs {
|
|
|
251
264
|
runId?: string;
|
|
252
265
|
/** `chant components release record --actor <name>` (#568) — who/what triggered the deploy. */
|
|
253
266
|
actor?: string;
|
|
254
|
-
/** `--approver <name>` (#1035) — who approved a gated change.
|
|
267
|
+
/** `--approver <name>` (#1035) — who approved a gated change. Read by `chant approve` and `chant run approve` (recorded as `resolvedBy` on the gate-resolution fact, taking precedence over `--actor`) and by `chant components release` (recorded on the release ledger). Optional; absent for ungated changes. */
|
|
255
268
|
approver?: string;
|
|
269
|
+
/** `chant run approve <op> <gate> --on <lexicon> --durable-requests` (#2126) — reserved. It would resolve the gate by answering the hosting runtime's own pending request instead of posting a follow-up prompt. No runtime implements it: fountain's needs the request-answer path from BinaryBourbon/fountain#1635, which has not shipped, and refuses by name rather than reporting a resolution it did not make. */
|
|
270
|
+
durableRequests?: boolean;
|
|
256
271
|
/** `chant components status <env> --compare-to <env>` (#568) — a second environment to cross-check the same component's recorded digest against. */
|
|
257
272
|
compareTo?: string;
|
|
258
273
|
/** `chant run --components <name> --env <env> --no-release-record` (#597) — opt out of auto-emitting a release-ledger record after a successful component deploy. Default (flag omitted): recording is ON. Also settable project-wide via `chant.config.ts`'s `release.autoRecord: false`. */
|
|
@@ -287,6 +302,8 @@ export interface ParsedArgs {
|
|
|
287
302
|
once?: boolean;
|
|
288
303
|
/** `chant approve <op> <gate> --note <text>` (#1485) — optional free-text prose recorded on the gate-resolution fact. The PR link belongs in `--url` since #2028; this is for everything that isn't the link. */
|
|
289
304
|
note?: string;
|
|
305
|
+
/** `chant approve <op> <gate> --expire` (#2119) — clear the gate's standing pending fact instead of approving it, so the next run decides the gate from scratch and records a fresh one. Writes no resolution: nothing is approved, the wait is only restarted. */
|
|
306
|
+
expire?: boolean;
|
|
290
307
|
/** `chant operator log --op <name>` (#2029) — restrict the tick history to one ConvergeOp by name. Omitted, every discovered ConvergeOp's ticks are merged into one timeline. */
|
|
291
308
|
op?: string;
|
|
292
309
|
/** `chant operator log --since <iso>` (#2029) — only entries at or after this ISO-8601 instant. */
|
package/src/codegen/docs.ts
CHANGED
|
@@ -325,7 +325,7 @@ export function writeDocsSite(config: DocsConfig, result: DocsResult): void {
|
|
|
325
325
|
// Starlight does not auto-discover pages, so a page absent from the sidebar
|
|
326
326
|
// is reachable only by typing its URL. The pipeline deliberately preserves
|
|
327
327
|
// hand-written pages it did not emit (above), which makes it easy to add one
|
|
328
|
-
// and never wire it up — azure,
|
|
328
|
+
// and never wire it up — azure, helm and github each accumulated
|
|
329
329
|
// several that way (#1312). Report them; `chant dev check-lexicon` gates on
|
|
330
330
|
// the same condition.
|
|
331
331
|
const unreachable = unreachablePages(contentDir, sidebar);
|
|
@@ -12,7 +12,7 @@ describe("generatePostSynthBarrel", () => {
|
|
|
12
12
|
|
|
13
13
|
expect(out).toContain("// Code generated by chant generate. DO NOT EDIT.");
|
|
14
14
|
expect(out).toContain('import type { PostSynthCheck } from "@intentius/chant/lint/post-synth";');
|
|
15
|
-
// Export name may differ from the module name (docker/helm
|
|
15
|
+
// Export name may differ from the module name (docker/helm).
|
|
16
16
|
expect(out).toContain('import { dkrd010 } from "./apt-no-recommends";');
|
|
17
17
|
// Array is ordered by id, not insertion order.
|
|
18
18
|
const arrayBody = out.slice(out.indexOf("postSynthChecks: PostSynthCheck[] = ["));
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Detection reuses the runtime's own `isPostSynthCheck`, so the barrel contains
|
|
11
11
|
* exactly the checks discovery would — including files whose export name differs
|
|
12
|
-
* from the filename (docker/helm
|
|
12
|
+
* from the filename (docker/helm) and excluding helper modules
|
|
13
13
|
* (cf-refs, arm-refs, …) that export no check.
|
|
14
14
|
*/
|
|
15
15
|
|
package/src/components/README.md
CHANGED
|
@@ -50,8 +50,9 @@ adopting chant.
|
|
|
50
50
|
be a nested `Phase`, which is how fan-out (e.g. a Neo4j cluster seeding one
|
|
51
51
|
node then rolling through the rest) is expressed as composition rather than
|
|
52
52
|
orchestrator knowledge.
|
|
53
|
-
- **Gates** — a distinct step shape (`kind: "gate"`, `signalName`) for a
|
|
54
|
-
|
|
53
|
+
- **Gates** — a distinct step shape (`kind: "gate"`, `signalName`) for a human
|
|
54
|
+
approval, decided against the gate ledger: a run that reaches one with no
|
|
55
|
+
resolution stops there with status `gated` and the pending fact recorded.
|
|
55
56
|
- **Wiring reference forms**, all resolved by the graph, never by orchestrator
|
|
56
57
|
code:
|
|
57
58
|
- `$env.<path>` — environment config (e.g. `$env.registry`).
|
|
@@ -22,7 +22,6 @@ vi.mock("../lifecycle/release-ledger", async () => {
|
|
|
22
22
|
const {
|
|
23
23
|
maybeRecordAutoRelease,
|
|
24
24
|
extractRunDigest,
|
|
25
|
-
extractRunDigestFromPhaseOutputs,
|
|
26
25
|
} = await import("./auto-release");
|
|
27
26
|
|
|
28
27
|
function publishRecord(digest: string): DriverStepRecord {
|
|
@@ -64,21 +63,6 @@ describe("extractRunDigest", () => {
|
|
|
64
63
|
});
|
|
65
64
|
});
|
|
66
65
|
|
|
67
|
-
describe("extractRunDigestFromPhaseOutputs", () => {
|
|
68
|
-
test("finds the digest across phase outputs (Temporal workflow result shape)", () => {
|
|
69
|
-
expect(extractRunDigestFromPhaseOutputs({ Publish: { digest: "sha256:abc", uri: "repo@sha256:abc" }, Apply: { ok: true } })).toBe("sha256:abc");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test("returns undefined for undefined/empty phaseOutputs", () => {
|
|
73
|
-
expect(extractRunDigestFromPhaseOutputs(undefined)).toBeUndefined();
|
|
74
|
-
expect(extractRunDigestFromPhaseOutputs({})).toBeUndefined();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test("ignores a phase output carrying only a content digest (SBOM, #665)", () => {
|
|
78
|
-
expect(extractRunDigestFromPhaseOutputs({ Sbom: { digest: "sha256:sbombytes" } })).toBeUndefined();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
66
|
describe("maybeRecordAutoRelease", () => {
|
|
83
67
|
beforeEach(() => {
|
|
84
68
|
getHeadCommitMock.mockReset().mockResolvedValue("abc123headsha");
|
|
@@ -111,19 +95,19 @@ describe("maybeRecordAutoRelease", () => {
|
|
|
111
95
|
expect(pushLifecycleMock).toHaveBeenCalledTimes(1);
|
|
112
96
|
});
|
|
113
97
|
|
|
114
|
-
test("a pre-resolved digest
|
|
98
|
+
test("a pre-resolved digest takes precedence and is used directly", async () => {
|
|
115
99
|
appendReleaseRecordMock.mockResolvedValue({
|
|
116
100
|
commit: "b".repeat(40),
|
|
117
|
-
record: { version: 1, component: "svc", env: "prod", digest: "sha256:
|
|
101
|
+
record: { version: 1, component: "svc", env: "prod", digest: "sha256:preresolved", gitSha: "x", runId: "r", timestamp: "t", actor: "a" },
|
|
118
102
|
});
|
|
119
103
|
|
|
120
104
|
await maybeRecordAutoRelease(
|
|
121
|
-
{ component: "svc", env: "prod", success: true, digest: "sha256:
|
|
105
|
+
{ component: "svc", env: "prod", success: true, digest: "sha256:preresolved", records: [publishRecord("sha256:ignored")], runId: "run-1" },
|
|
122
106
|
{ actor: "alice" },
|
|
123
107
|
);
|
|
124
108
|
|
|
125
109
|
const [input] = appendReleaseRecordMock.mock.calls[0];
|
|
126
|
-
expect(input.digest).toBe("sha256:
|
|
110
|
+
expect(input.digest).toBe("sha256:preresolved");
|
|
127
111
|
});
|
|
128
112
|
|
|
129
113
|
test("failure (run.success = false) -> writes nothing", async () => {
|
|
@@ -4,23 +4,19 @@
|
|
|
4
4
|
* release ledger (../lifecycle/release-ledger.ts) was only populated by the
|
|
5
5
|
* standalone `chant components release <env>` command — a deploy that never
|
|
6
6
|
* called it left the ledger silently empty. This module makes recording
|
|
7
|
-
* happen *by construction*: the CLI post-run step
|
|
8
|
-
*
|
|
9
|
-
* (`runComponentTemporal`) calls `maybeRecordAutoRelease` after the run
|
|
10
|
-
* reports success.
|
|
7
|
+
* happen *by construction*: the CLI's post-run step (`runOpComponents`)
|
|
8
|
+
* calls `maybeRecordAutoRelease` after the run reports success.
|
|
11
9
|
*
|
|
12
10
|
* Deliberately CLI-side, not driver-side or workflow-side:
|
|
13
11
|
* - `../components/driver.ts` stays capability-agnostic — it already
|
|
14
12
|
* resists per-component/per-capability branching, and "write to git"
|
|
15
13
|
* is exactly the kind of side effect that doesn't belong in a step
|
|
16
14
|
* dispatcher tests exercise against a bare `CapabilityRegistry`.
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* reports a terminal COMPLETED status, the same place `runOpTemporal`
|
|
23
|
-
* already writes its deployment report post-run.
|
|
15
|
+
* - A ledger write is a non-idempotent git push with real-world side
|
|
16
|
+
* effects (network, `Date.now()`, file writes) — the kind of thing that
|
|
17
|
+
* belongs at the edge of a run rather than inside a step a retry may run
|
|
18
|
+
* a second time. It happens in the CLI, once the run has reported a
|
|
19
|
+
* terminal outcome.
|
|
24
20
|
*
|
|
25
21
|
* Reuses ../lifecycle/release-ledger.ts's `appendReleaseRecord` verbatim —
|
|
26
22
|
* this module only decides *whether* to call it and *what digest* to record,
|
|
@@ -72,27 +68,6 @@ export function extractRunDigest(records: DriverStepRecord[]): string | undefine
|
|
|
72
68
|
return found;
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
/**
|
|
76
|
-
* Same digest extraction as `extractRunDigest`, but over a component
|
|
77
|
-
* Temporal workflow's returned `phaseOutputs` (`{ [phase]: output }`) instead
|
|
78
|
-
* of a `DriverStepRecord[]` — the shape `handle.result()` resolves to for a
|
|
79
|
-
* COMPLETED component workflow (see lexicons/temporal/src/component-op/
|
|
80
|
-
* serializer.ts's generated `return { phaseOutputs, componentOutputs }`).
|
|
81
|
-
* Used by the `--temporal` CLI path, which never sees individual step
|
|
82
|
-
* records (those exist only inside the workflow/activities).
|
|
83
|
-
*/
|
|
84
|
-
export function extractRunDigestFromPhaseOutputs(
|
|
85
|
-
phaseOutputs: Record<string, Record<string, unknown>> | undefined,
|
|
86
|
-
): string | undefined {
|
|
87
|
-
let found: string | undefined;
|
|
88
|
-
for (const output of Object.values(phaseOutputs ?? {})) {
|
|
89
|
-
if (isPromotedArtifact(output) && typeof output.digest === "string") {
|
|
90
|
-
found = output.digest;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return found;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
71
|
/** Explicit reasons `maybeRecordAutoRelease` declined to write a record — never a thrown error, since "nothing to record" (or "opted out") is an expected, common outcome. */
|
|
97
72
|
export type AutoReleaseSkipReason =
|
|
98
73
|
| "opted-out"
|
|
@@ -105,19 +80,19 @@ export type AutoReleaseResult =
|
|
|
105
80
|
| { recorded: false; reason: AutoReleaseSkipReason; detail?: string }
|
|
106
81
|
| { recorded: false; reason: "error"; error: string };
|
|
107
82
|
|
|
108
|
-
/** Input describing one component's completed run
|
|
83
|
+
/** Input describing one component's completed run. */
|
|
109
84
|
export interface AutoReleaseRunInfo {
|
|
110
85
|
component: string;
|
|
111
86
|
env: string;
|
|
112
|
-
/** Whether the run reported overall success
|
|
87
|
+
/** Whether the run reported overall success (`DriverRunResult.ok`). A caller must not call this for a non-terminal/in-progress run. */
|
|
113
88
|
success: boolean;
|
|
114
89
|
/** The component's step records (local executor), used to locate the published digest via `extractRunDigest`. Mutually exclusive with `digest` — pass whichever the caller already has. */
|
|
115
90
|
records?: DriverStepRecord[];
|
|
116
|
-
/** A digest
|
|
91
|
+
/** A digest the caller already resolved by its own means. Takes precedence over `records` when both are given. */
|
|
117
92
|
digest?: string;
|
|
118
|
-
/** Orchestrator run identifier — a
|
|
93
|
+
/** Orchestrator run identifier — a hosting runtime's own run id, or a locally generated one (mirrors `runComponentsReleaseRecord`'s `--run-id` default). */
|
|
119
94
|
runId: string;
|
|
120
|
-
/** The id space `runId` lives in (#2045) — `{ forge: "op" }` for a
|
|
95
|
+
/** The id space `runId` lives in (#2045) — `{ forge: "op" }` for a hosted run, `{ forge: "local" }` for a local-executor mint. Recorded verbatim as the release record's `runOrigin`. */
|
|
121
96
|
runOrigin?: RunOrigin;
|
|
122
97
|
/** The bypassed capability-profile divergences, when the caller deliberately overrode a deploy-time profile assertion (chant #1244) — recorded verbatim as the release record's `profileOverride`. */
|
|
123
98
|
profileOverride?: string;
|
|
@@ -142,11 +117,11 @@ function resolveActor(override?: string): string | undefined {
|
|
|
142
117
|
}
|
|
143
118
|
|
|
144
119
|
/**
|
|
145
|
-
* After a successful `chant run --components <name> --env <env
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
120
|
+
* After a successful `chant run --components <name> --env <env>`, append
|
|
121
|
+
* exactly one immutable release record to the ledger and push it — or
|
|
122
|
+
* explain, without throwing, why it didn't. Never called for a failed run
|
|
123
|
+
* (`run.success` must be true before the caller invokes this at all; see
|
|
124
|
+
* `runOpComponents`) — a failed
|
|
150
125
|
* deploy writes nothing, by construction, since this function is simply
|
|
151
126
|
* never reached on that path.
|
|
152
127
|
*
|
|
@@ -50,10 +50,10 @@ export interface Capability<In = unknown, Out = unknown> {
|
|
|
50
50
|
* returned (#1944, epic #1564 phase 4) — a serializable identity channel a
|
|
51
51
|
* capability can use to recover state `rollback` needs when it cannot rely
|
|
52
52
|
* on in-process object identity between its `run`/`rollback` calls. The
|
|
53
|
-
* local interpret driver (../driver.ts) always threads it through;
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
53
|
+
* local interpret driver (../driver.ts) always threads it through; a
|
|
54
|
+
* hosting runtime that splits a run across process boundaries threads it
|
|
55
|
+
* across as plain JSON, which is exactly the case this exists for — see
|
|
56
|
+
* ./verbs/run-agent.ts's "Rollback identity" doc
|
|
57
57
|
* comment for the motivating gap (a fresh sprite's checkpoint id, recorded
|
|
58
58
|
* only in an in-process `WeakMap` keyed by `run()`'s `input` object, never
|
|
59
59
|
* survives to a `rollback()` call that runs as a separate Activity with its
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
generateComponentsPipeline,
|
|
26
26
|
} from "./cli-support";
|
|
27
27
|
import { CapabilityRegistry, type DeployContext } from "./capability";
|
|
28
|
+
import { memoryGateLedgerPort } from "../op/gate";
|
|
28
29
|
import type { DriverComponent, RunProgressEvent } from "./driver";
|
|
29
30
|
|
|
30
31
|
// A minimal stand-in for the real gitlab lexicon plugin, satisfying
|
|
@@ -587,7 +588,7 @@ describe("runComponents", () => {
|
|
|
587
588
|
expect(result.error).toContain("svc");
|
|
588
589
|
});
|
|
589
590
|
|
|
590
|
-
test("a gate in the selected component
|
|
591
|
+
test("a gate in the selected component ends the run pending approval (#2119)", async () => {
|
|
591
592
|
await writeFile(
|
|
592
593
|
join(testDir, "svc.component.ts"),
|
|
593
594
|
`export const svc = { name: "svc", dependsOn: [], deploy: [
|
|
@@ -600,11 +601,15 @@ describe("runComponents", () => {
|
|
|
600
601
|
const registry = new CapabilityRegistry();
|
|
601
602
|
registry.register(capability);
|
|
602
603
|
|
|
603
|
-
const
|
|
604
|
+
const gates = memoryGateLedgerPort();
|
|
605
|
+
const result = await runComponents(testDir, "svc", { registry, gates });
|
|
604
606
|
|
|
605
607
|
expect(result.success).toBe(false);
|
|
606
|
-
expect(result.
|
|
607
|
-
|
|
608
|
+
expect(result.gated?.component).toBe("svc");
|
|
609
|
+
expect(result.gated?.gate.gate).toBe("release-approval");
|
|
610
|
+
expect(result.run?.status).toBe("gated");
|
|
611
|
+
expect(gates.appended).toHaveLength(1);
|
|
612
|
+
// Nothing after the gate ran.
|
|
608
613
|
expect(capability.calls).toHaveLength(0);
|
|
609
614
|
});
|
|
610
615
|
|
|
@@ -844,7 +849,7 @@ describe("resolveComponentTargets — buildParams (chant #1108)", () => {
|
|
|
844
849
|
await rm(testDir, { recursive: true, force: true });
|
|
845
850
|
});
|
|
846
851
|
|
|
847
|
-
test("forwards buildParams into discovery — the
|
|
852
|
+
test("forwards buildParams into discovery — the selector-resolution entrypoint", async () => {
|
|
848
853
|
await writeFile(
|
|
849
854
|
join(testDir, "svc.component.ts"),
|
|
850
855
|
`
|
|
@@ -31,12 +31,13 @@ import {
|
|
|
31
31
|
runComponentDeploy,
|
|
32
32
|
UnknownDependencyError,
|
|
33
33
|
DependencyCycleError,
|
|
34
|
-
DriverGateUnsupportedError,
|
|
35
34
|
DriverRunFailure,
|
|
36
35
|
type DriverComponent,
|
|
37
36
|
type DriverPhase,
|
|
38
37
|
type DriverRunResult,
|
|
39
38
|
} from "./driver";
|
|
39
|
+
import type { PendingGateRecord } from "../lifecycle/gate-ledger";
|
|
40
|
+
import type { GateLedgerPort } from "../op/gate";
|
|
40
41
|
import { isLexiconPlugin, type LexiconPlugin, type ComponentPipelineOptions } from "../lexicon";
|
|
41
42
|
import type { RunProgressEvent } from "./run-progress";
|
|
42
43
|
import { relative } from "node:path";
|
|
@@ -313,11 +314,11 @@ function toDriverComponent(component: { name: string; dependsOn: string[]; deplo
|
|
|
313
314
|
|
|
314
315
|
/**
|
|
315
316
|
* Find the first `gate` step anywhere in a component's `deploy`/`rollback`
|
|
316
|
-
* composition (including nested fan-out phases)
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
317
|
+
* composition (including nested fan-out phases).
|
|
318
|
+
*
|
|
319
|
+
* A declaration-time question, not a pre-flight refusal: since #2119 the
|
|
320
|
+
* driver decides a gate against the ledger when it reaches one, so nothing
|
|
321
|
+
* needs to know up front that a component has one.
|
|
321
322
|
*/
|
|
322
323
|
export function findComponentGate(component: DriverComponent): { signalName: string } | undefined {
|
|
323
324
|
const search = (phases: DriverPhase[] | undefined): { signalName: string } | undefined => {
|
|
@@ -406,6 +407,8 @@ export interface RunComponentsOptions {
|
|
|
406
407
|
* every test in `cli-support.test.ts`) that doesn't supply this.
|
|
407
408
|
*/
|
|
408
409
|
buildParams?: BuildParamProvenance[];
|
|
410
|
+
/** Where a `gate` step's facts are read and written (#2119). Defaults to the `chant/lifecycle` orphan branch; a test passes `memoryGateLedgerPort()` from `../op/gate.ts`. */
|
|
411
|
+
gates?: GateLedgerPort;
|
|
409
412
|
}
|
|
410
413
|
|
|
411
414
|
/** Result of `chant run --components <name|all>`. */
|
|
@@ -416,8 +419,8 @@ export interface RunComponentsResult {
|
|
|
416
419
|
/** Component names actually dispatched to the driver, in run order. */
|
|
417
420
|
selected: string[];
|
|
418
421
|
error?: string;
|
|
419
|
-
/** Set when
|
|
420
|
-
|
|
422
|
+
/** Set when the run stopped at a `gate` nobody has approved (#2119): the component it stopped at and the pending fact recorded for it. */
|
|
423
|
+
gated?: { component: string; gate: PendingGateRecord };
|
|
421
424
|
/** This run's resolved build-time parameters (chant #1108) — the component-driver counterpart of `../cli/commands/build.ts`'s `BuildResult.buildParams`. Present only once the run actually reached dispatch (mirrors `BuildResult.buildParams`, which is likewise absent on an early-error return). */
|
|
422
425
|
buildParams?: BuildParamProvenance[];
|
|
423
426
|
}
|
|
@@ -428,8 +431,7 @@ export interface RunComponentsResult {
|
|
|
428
431
|
* local in-process executor — the CLI entrypoint the driver never had (#585,
|
|
429
432
|
* follow-up to #556). Discovers the full component set first, then either:
|
|
430
433
|
* - `selector === "all"`: resolves the whole set's dependency order/waves
|
|
431
|
-
* and dispatches every component through `runInterpretDriver`,
|
|
432
|
-
* what the generated orchestrator Op will eventually do — the same
|
|
434
|
+
* and dispatches every component through `runInterpretDriver`, in the same
|
|
433
435
|
* order `chant graph --components` reports.
|
|
434
436
|
* - a single name: dispatches just that component via `runComponentDeploy`,
|
|
435
437
|
* without requiring the rest of its `dependsOn` graph to be present in
|
|
@@ -441,14 +443,12 @@ export interface RunComponentsResult {
|
|
|
441
443
|
* infra outside the discovered set (e.g. a shared stack, per the
|
|
442
444
|
* `search-service` pilot), which is exactly the common case.
|
|
443
445
|
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* `
|
|
447
|
-
*
|
|
448
|
-
* component execution to what already exists for Ops; the epic tracks
|
|
449
|
-
* graduating a gated component to `--temporal` separately).
|
|
446
|
+
* A `gate` no longer refuses the run up front (#2119). The driver decides each
|
|
447
|
+
* one against the gate ledger as it reaches it; a gate nobody has approved
|
|
448
|
+
* stops the run there with `gated` set, which the CLI turns into exit code 3
|
|
449
|
+
* and the `chant approve` line.
|
|
450
450
|
*/
|
|
451
|
-
/** Result of resolving a `<name|all>` selector against discovered components
|
|
451
|
+
/** Result of resolving a `<name|all>` selector against discovered components. */
|
|
452
452
|
export interface ResolvedComponentTargets {
|
|
453
453
|
success: boolean;
|
|
454
454
|
targets: DriverComponent[];
|
|
@@ -459,10 +459,8 @@ export interface ResolvedComponentTargets {
|
|
|
459
459
|
* Discover every component under `path` and resolve `selector` (`"all"` or a
|
|
460
460
|
* single component name) to the `DriverComponent`(s) to run, with no gate
|
|
461
461
|
* check and no dispatch — just discovery + selection, factored out of
|
|
462
|
-
* `runComponents` so
|
|
463
|
-
*
|
|
464
|
-
* without also inheriting the local executor's pre-flight gate rejection
|
|
465
|
-
* (gates are exactly what the durable path exists to support).
|
|
462
|
+
* `runComponents` so another entrypoint can reuse the exact same selection
|
|
463
|
+
* semantics without inheriting the run itself.
|
|
466
464
|
*/
|
|
467
465
|
export async function resolveComponentTargets(
|
|
468
466
|
path: string,
|
|
@@ -526,17 +524,6 @@ export async function runComponents(
|
|
|
526
524
|
}
|
|
527
525
|
const targets = resolved.targets;
|
|
528
526
|
|
|
529
|
-
for (const component of targets) {
|
|
530
|
-
const gate = findComponentGate(component);
|
|
531
|
-
if (gate) {
|
|
532
|
-
return {
|
|
533
|
-
success: false,
|
|
534
|
-
selected: targets.map((c) => c.name),
|
|
535
|
-
gateUnsupported: { component: component.name, signalName: gate.signalName },
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
527
|
// (#629) Resolve `chant.config.ts`'s `sbom`/`signing`/`vulnPolicy` sections
|
|
541
528
|
// and fill their defaults into every recognized step (`generate-sbom`,
|
|
542
529
|
// `sign`/`attest-provenance`, `verify`, `vuln-gate`) that didn't already
|
|
@@ -563,10 +550,25 @@ export async function runComponents(
|
|
|
563
550
|
const seedOutputs = options.componentOutputs ?? {};
|
|
564
551
|
const { onProgress } = options;
|
|
565
552
|
|
|
553
|
+
const gates = options.gates;
|
|
554
|
+
|
|
566
555
|
try {
|
|
567
556
|
if (selector === "all") {
|
|
568
|
-
const run = await runInterpretDriver(resolvedTargets, registry, {
|
|
569
|
-
|
|
557
|
+
const run = await runInterpretDriver(resolvedTargets, registry, {
|
|
558
|
+
env,
|
|
559
|
+
componentOutputs: seedOutputs,
|
|
560
|
+
onProgress,
|
|
561
|
+
...(gates ? { gates } : {}),
|
|
562
|
+
});
|
|
563
|
+
return {
|
|
564
|
+
success: run.status === "ok",
|
|
565
|
+
run,
|
|
566
|
+
selected,
|
|
567
|
+
buildParams: options.buildParams,
|
|
568
|
+
...(run.status === "gated" && run.gate
|
|
569
|
+
? { gated: { component: run.gatedComponent ?? selected[0], gate: run.gate } }
|
|
570
|
+
: {}),
|
|
571
|
+
};
|
|
570
572
|
}
|
|
571
573
|
|
|
572
574
|
// Single-component invocation: run just this component, bypassing
|
|
@@ -592,8 +594,9 @@ export async function runComponents(
|
|
|
592
594
|
registry,
|
|
593
595
|
componentOutputs,
|
|
594
596
|
onProgress,
|
|
597
|
+
gates ? { port: gates } : undefined,
|
|
595
598
|
);
|
|
596
|
-
const status
|
|
599
|
+
const status = componentResult.status === "fail" ? "failed" : componentResult.status;
|
|
597
600
|
onProgress?.({ type: "component-done", wave: 1, component: componentName, status });
|
|
598
601
|
onProgress?.({ type: "wave-done", wave: 1, status });
|
|
599
602
|
onProgress?.({ type: "run-done", status });
|
|
@@ -602,21 +605,26 @@ export async function runComponents(
|
|
|
602
605
|
waves: [selected],
|
|
603
606
|
results: [componentResult],
|
|
604
607
|
ok: componentResult.ok,
|
|
605
|
-
|
|
608
|
+
status: componentResult.status,
|
|
609
|
+
failedComponent: componentResult.status === "fail" ? componentResult.component : undefined,
|
|
610
|
+
...(componentResult.status === "gated"
|
|
611
|
+
? { gatedComponent: componentResult.component, gate: componentResult.gate }
|
|
612
|
+
: {}),
|
|
606
613
|
componentOutputs,
|
|
607
614
|
};
|
|
608
|
-
return {
|
|
615
|
+
return {
|
|
616
|
+
success: componentResult.ok,
|
|
617
|
+
run,
|
|
618
|
+
selected,
|
|
619
|
+
buildParams: options.buildParams,
|
|
620
|
+
...(componentResult.status === "gated" && componentResult.gate
|
|
621
|
+
? { gated: { component: componentResult.component, gate: componentResult.gate } }
|
|
622
|
+
: {}),
|
|
623
|
+
};
|
|
609
624
|
} catch (err) {
|
|
610
625
|
if (err instanceof DriverRunFailure) {
|
|
611
626
|
return { success: false, run: err.result, selected, error: err.message };
|
|
612
627
|
}
|
|
613
|
-
if (err instanceof DriverGateUnsupportedError) {
|
|
614
|
-
return {
|
|
615
|
-
success: false,
|
|
616
|
-
selected,
|
|
617
|
-
gateUnsupported: { component: err.component, signalName: err.signalName },
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
628
|
if (err instanceof UnknownDependencyError || err instanceof DependencyCycleError) {
|
|
621
629
|
return { success: false, selected, error: err.message };
|
|
622
630
|
}
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
|
|
163
163
|
"Gate": {
|
|
164
164
|
"type": "object",
|
|
165
|
-
"description": "
|
|
165
|
+
"description": "Ends the run pending human approval. The driver decides a gate against the gate ledger when it reaches one; a gate nobody has approved stops the run there, and `chant approve <component> <gate>` records the resolution the next run reads.",
|
|
166
166
|
"required": ["kind", "signalName"],
|
|
167
167
|
"additionalProperties": false,
|
|
168
168
|
"properties": {
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
"signalName": {
|
|
171
171
|
"type": "string",
|
|
172
172
|
"minLength": 1,
|
|
173
|
-
"description": "
|
|
173
|
+
"description": "The gate's name — what `chant approve <component> <gate>` resolves."
|
|
174
174
|
},
|
|
175
175
|
"timeout": {
|
|
176
176
|
"type": "string",
|
|
@@ -77,11 +77,11 @@ export interface Step {
|
|
|
77
77
|
[param: string]: unknown;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
/** Mirrors `$defs.Gate` —
|
|
80
|
+
/** Mirrors `$defs.Gate` — a human approval decided against the gate ledger; the run stops here with status `gated` until `chant approve` has answered it. */
|
|
81
81
|
export interface Gate {
|
|
82
82
|
kind: "gate";
|
|
83
83
|
signalName: string;
|
|
84
|
-
/**
|
|
84
|
+
/** How long a recorded pending gate stays valid, as a duration string. Default: "48h". */
|
|
85
85
|
timeout?: string;
|
|
86
86
|
/** Human-readable description of the action required to unblock this gate. */
|
|
87
87
|
description?: string;
|
|
@@ -170,7 +170,7 @@ export function phase(name: string, steps: Array<Step | Gate | Phase>, opts?: {
|
|
|
170
170
|
return { phase: name, steps, ...(opts?.parallel ? { parallel: true } : {}) };
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
/** Author a gate step —
|
|
173
|
+
/** Author a gate step — a human approval the driver decides against the gate ledger, stopping the run `gated` when nothing has answered it. */
|
|
174
174
|
export function gate(signalName: string, opts?: { timeout?: string; description?: string }): Gate {
|
|
175
175
|
return { kind: "gate", signalName, ...opts };
|
|
176
176
|
}
|
|
@@ -51,15 +51,27 @@ export function renderDriverHuman(result: DriverRunResult, write: Writer = stder
|
|
|
51
51
|
} else {
|
|
52
52
|
write(` ${mark} ${record.kind} ${formatDuration(record.durationMs)}`);
|
|
53
53
|
}
|
|
54
|
+
if (record.approval) {
|
|
55
|
+
write(` [approved] ${record.approval.resolvedBy} at ${record.approval.timestamp}` +
|
|
56
|
+
(record.approval.url ? ` (${record.approval.url})` : ""));
|
|
57
|
+
}
|
|
54
58
|
if (record.error) {
|
|
55
59
|
write(` ${record.error}`);
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
|
-
write(
|
|
62
|
+
write(
|
|
63
|
+
componentResult.status === "ok"
|
|
64
|
+
? ` component "${componentResult.component}" completed`
|
|
65
|
+
: componentResult.status === "gated"
|
|
66
|
+
? ` component "${componentResult.component}" gated on "${componentResult.gate?.gate ?? "?"}"`
|
|
67
|
+
: ` component "${componentResult.component}" failed`,
|
|
68
|
+
);
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
if (result.ok) {
|
|
71
|
+
if (result.status === "ok") {
|
|
62
72
|
write(`interpret run completed (${result.order.length} component(s))`);
|
|
73
|
+
} else if (result.status === "gated") {
|
|
74
|
+
write(`interpret run is gated at component "${result.gatedComponent}"`);
|
|
63
75
|
} else {
|
|
64
76
|
write(`interpret run failed at component "${result.failedComponent}"`);
|
|
65
77
|
}
|